Architecture
A Python runner rebuilds scanned drawings as editable 2D CAD, connecting visual interpretation, native construction and comparison with the source.
The model decides what the drawing means. FreeCAD or QCAD creates the objects. The runner decides whether to request another candidate or finish the job. This separation makes an interpretation error correctable without allowing the model to execute arbitrary code.
The reconstruction loop
The diagram shows one drawing job in the full-sheet campaigns. Reading the source and planning happen once. Generation, construction and evaluation can repeat up to four times.
Python runner / local job control. The runner dispatches the steps below, records each attempt and enforces the stop conditions. Model requests send the relevant images and JSON to the configured inference endpoint; CAD processes and native files remain on the workstation.
PDF or image
Render the pages and select the drawing area. Keep the source hash, pixel size and transform so every candidate uses the same reference.
Interpret and plan
Identify views, bodies, fittings, axes and sections. Return a component plan and uncertain readings, not drawing commands.
Generate candidate
Use the scan and plan to describe components, curves and hatch regions as structured JSON. After an evaluation, the drafter either edits a saved candidate with component operations or regenerates the full model.
Validate and compile
Check IDs, coordinate limits, shape counts and hatch boundaries. Convert valid component data into the selected backend's native entity description.
Build, reopen, render
Create native objects in FreeCAD or QCAD, or apply component edits to a copy of the chosen candidate's native file. Save and reopen the document, check the stored geometry, then render it as the evaluator's input.
Compare with source
The evaluator receives the scan and CAD rendering, not the generator's reasoning. It returns an acceptance decision, score and defects located by view or component.
Build or validation error: 4 or 5 returns to 3. Send the actual error to the generator. Skip visual evaluation because no valid new CAD candidate exists.
Visual rejection: 6 returns to 3. The drafter receives the candidate history and defect reports, then edits a saved candidate, keeping untouched components, or regenerates. Build or edit, then evaluate again; changing JSON alone does not complete a correction.
Finish the job
Accepted: stop the loop and retain the CAD, rendering, native checks and evaluation. Four candidates exhausted: stop with a not-accepted result and retain the last valid CAD for review. Request error or deadline: record the failure and preserve completed artifacts; if no build succeeded, there is no CAD output.
Why each component exists
- Python runner
Owns job state, request order, attempt limits and process timeouts. It supplies the next request with the plan, previous model and feedback rather than relying on a persistent chat. It records checkpoints after analysis, model generation, native construction and evaluation.
Runner: quality_campaign.py- Generator
Interprets damaged drawing conventions that a geometric tracer would miss: a chamfer is not a separate lobe, and a section hatch describes material rather than a set of diagonal edges. It proposes the geometric data; it does not operate the CAD application.
- Validator and compiler
Turn a flexible model proposal into a restricted CAD input. Invalid points or open/self-intersecting hatch regions are rejected before they reach QCAD. The compiler maps raster coordinates into provisional drawing coordinates; readable dimensions still need a separate confirmation step.
QCAD schema, geometry validation and compilation- CAD executor
Creates editable geometry and checks what was actually stored. QCAD uses component blocks, layers, polylines and native hatches. FreeCAD uses component sketches, selected constraints and splines, directly or through MCP. MCP changes the execution connection, not the interpretation loop.
Native build and saved-document checks- Evaluator
Checks a different question from the validator: does the result depict the same mechanical features? Valid CAD can still omit a view, invert material and voids, or give a union nut the wrong contour. A separate request reduces dependence on the generator's explanation, but using the same model family can still produce shared judgment errors.
- Artifact directory
Retains each candidate's JSON, compiled entities, native document, image, geometry report and evaluation. A final result points to the last valid CAD. This lets an operator compare revisions and investigate a rejected or interrupted job without overwriting earlier evidence.
A correction in drawing 05
The assembly example took four candidates in the QCAD/Astra campaign. The first evaluation found that adjacent components used the same hatch direction and that the spacing was too coarse. Those defects were fed back with the previous model. Later checks identified missing interface details and a wrongly opened passage in the upper boss. Candidate four restored the terminating boundary and passed the internal evaluation.
This is why both kinds of checks are needed: the earlier DXFs already contained valid native hatches, but their material interpretation and mechanical details still needed correction.
When does the loop stop?
The automatic evaluator must return acceptance and a score of at least 85/100. Otherwise the runner uses another candidate, up to four total, including the first. A deadline or unrecoverable request error can end the route earlier. Limits are enforced by the runner, not left to the model.
An accepted result is ready for technical review, not for manufacture. The operator checks ambiguous features and confirms physical dimensions. The site can show a visually selected draft even when the automatic evaluator rejected it; the recorded result remains unchanged.
What is complete today?
| Part | Current implementation | Still needed |
|---|---|---|
| Local reconstruction loop | Source preparation, analysis, JSON generation, native construction, rendering, evaluation and bounded retries have run end to end. | Better evaluation calibration. Retries can edit individual components of a saved candidate or regenerate. Matched tests on three drawings, two backends and two drafters found only small differences; editing remains the default because it preserved verified components and used fewer output tokens. |
| Failure handling | Separate run directories, progressive checkpoints, 120-second progress reports, deadlines and cleanup of owned processes. | Automatic continuation from an interrupted mid-route checkpoint. Saving a checkpoint is not the same as being able to resume it. |
| Engineering handoff | Native 2D geometry, preview and reports are retained for manual inspection. Dimension text, labels and title blocks are not reconstructed. | Confirmed physical dimensions, drawing annotations and a formal approval workflow. Current coordinates describe the scan, not certified part measurements. |
| Remote service | No hosted CAD worker or public upload/conversion application. The website documents local experiments. | Job submission, storage, queue, worker ownership, durable recovery and delivery controls before unattended hosting. |
The local loop is implemented; a production conversion service is not. FreeCAD and QCAD remain experimental alternatives, and neither has been selected as the final backend.