draftwright 0.4.6__tar.gz → 0.4.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {draftwright-0.4.6 → draftwright-0.4.7}/CHANGELOG.md +47 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/PKG-INFO +2 -2
- {draftwright-0.4.6 → draftwright-0.4.7}/docs/adr/README.md +1 -1
- draftwright-0.4.7/docs/reference/recogniser-capabilities.md +52 -0
- draftwright-0.4.7/docs/reference/sheet.md +35 -0
- draftwright-0.4.7/docs/research/1062-repeating-radial-profile-evidence.md +102 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/pyproject.toml +5 -2
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/analysis.py +1 -1
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/_common.py +14 -4
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/from_model.py +352 -74
- draftwright-0.4.7/src/draftwright/evaluation/__init__.py +1 -0
- draftwright-0.4.7/src/draftwright/evaluation/step_analysis.py +703 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/layout.py +193 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/coverage.py +3 -1
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/detect.py +1 -1
- draftwright-0.4.7/src/draftwright/recogniser_contract.py +526 -0
- draftwright-0.4.7/tests/fixtures/evaluation/README.md +20 -0
- draftwright-0.4.7/tests/fixtures/evaluation/ambiguous-open-semicircle.step +597 -0
- draftwright-0.4.7/tests/fixtures/evaluation/blind-hole.step +517 -0
- draftwright-0.4.7/tests/fixtures/evaluation/corpus-v1.json +137 -0
- draftwright-0.4.7/tests/fixtures/evaluation/plain-block.step +415 -0
- draftwright-0.4.7/tests/fixtures/evaluation/topology-a.step +607 -0
- draftwright-0.4.7/tests/fixtures/evaluation/topology-b.step +607 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/grooved_shaft.json +14 -14
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/pocketed.json +7 -7
- draftwright-0.4.7/tests/test_cross_repository_delivery_protocol.py +27 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_declared_recognition_gate.py +34 -8
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_external_recognition_boundary.py +4 -5
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_import_boundaries.py +10 -3
- draftwright-0.4.7/tests/test_issue_740_leader_assignment.py +567 -0
- draftwright-0.4.7/tests/test_recogniser_capabilities.py +531 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_recognition_result.py +4 -3
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_refactor_golden.py +5 -2
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_solve_trace.py +3 -0
- draftwright-0.4.7/tests/test_step_analysis_evaluation.py +403 -0
- draftwright-0.4.7/tests/test_two_repository_workflow.py +270 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_workflows.py +6 -1
- {draftwright-0.4.6 → draftwright-0.4.7}/.gitignore +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/LICENSE +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/README.md +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/skills/SKILL.md +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/__init__.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/_core.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/_geometry.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/_pmi_part21.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/_warnings.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotate.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/__init__.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/balloons.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/gears.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/holes.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/orchestrator.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/annotations/sections.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/audit.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/builder.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/cli.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/compose.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/drawing.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/export.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/fits.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/fonts/__init__.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/intents.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/__init__.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/channel_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/flat_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/gear_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/hole_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/issues.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/pmi_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/quality.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/slot_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/structural.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/linting/suggest.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/make_drawing.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/__init__.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/callout.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/compiled.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/declare.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/ir.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/model/planner.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/pmi.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/projection.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/py.typed +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/recognition/__init__.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/recognition_cache.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/registry.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/repair.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/score.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/sheet.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/src/draftwright/sheet_emit.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/_kernel.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/_layout_sig.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/conftest.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/issue_915_case_study_2.step +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/bracket_section.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/centered_rebate.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/chamfered.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/filleted.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/flange_dense.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/grid_plate.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/hex_bar.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/holed_slot.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/prismatic_ladder.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/scattered_plate.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/side_drilled.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/refactor_golden/turned_stepped.json +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_add_dimension.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_agents_guide.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_api_docs.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_architecture_docs.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_audit_differential.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_balloon_ring_standoff.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_carve_free_position_callers.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_compiled_plan_boundary.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_counting_calls.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_declare.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_dense_sheet_canary.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_deprecation_dates.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_detect_once.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_detect_registry.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_dimension_role_vocabulary.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_drawing_encapsulation.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_e2e_slice.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_e2e_standards.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_export_dxf_curves.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_export_dxf_zoom.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_fillets_adjacency.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_fits.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_flat_completeness.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_flat_stock_identity.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_flat_stock_opposition.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_gdt_placement.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_grid_lattice_convention.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1000_envelope_reuse.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1058_wheel_profile.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1073_cross_body_patterns.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1082_polygonal_stock.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1086_declared_gears.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1142_hole_leader_labels.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1143_hole_completeness.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1144_transactional_hole_table.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1146_scale_completeness.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_367_leader_ink.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_676_polygonal_boss.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_885_prismatic_coverage.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_909_sloped_profile.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_915_dense_case.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_916_pocket_leader.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_917_open_channel.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_955_height_contingency.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_issue_958_cross_solid_recognition.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_label_provenance.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_layout.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_layout_cleanliness.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_layout_hypothesis.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_layout_property.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_leader_footprint.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_lint_box_cache.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_lint_reconciliation.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_lint_structural.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_linting.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_location_vocabulary.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_make_drawing.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_note_verb.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_object_aspects.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_occupancy_boxes.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_parameter_id.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_part_model.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pitch_dim_footprint.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pmi.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pmi_datum_lowering.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pmi_gtol_lowering.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pmi_part21.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pocket_pattern.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_pocket_pattern_recognition.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_principal_profile_classifier.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_private_test_attr_reads.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_private_test_imports.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_quality_components.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_recogniser_contract.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_recognition.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_recognition_manifest.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_registry.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_render_seam.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_repack_geometry_seam.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_score.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_script_detail_parity.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_shared_box_memo.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_emit.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_gdt.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_identity_invariant.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_notes.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_of.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_section.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_sheet_tables.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_slanted_blind_step.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_slot_completeness.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_slot_pattern.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_slot_pattern_recognition.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_soft_deprecation.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_strip_layout.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_suppression_ledger.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_suppression_marks.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_tolerances.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_turned_steps.py +0 -0
- {draftwright-0.4.6 → draftwright-0.4.7}/tests/test_witness_label_reconciliation.py +0 -0
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Recogniser co-development now has a one-command, wheel-based two-checkout check; an exact
|
|
8
|
+
registry-release evidence record; automated dependency PR preparation; and documented landing,
|
|
9
|
+
compatibility, deprecation, rollback, ownership, and CI-budget rules. Dependency PRs retain the
|
|
10
|
+
canonical coverage/Codecov gate while avoiding four duplicate platform suites and the slow tier
|
|
11
|
+
(#1170).
|
|
12
|
+
- A versioned, independently authored STEP-analysis corpus and evaluator now report detection
|
|
13
|
+
recall/false positives, parameter fidelity, and downstream usefulness as separate evidence
|
|
14
|
+
layers. Hash-pinned positive, negative, ambiguous, compound, and topology-order-variant fixtures,
|
|
15
|
+
per-layer diagnostics, and an anti-self-validation mutation prevent recogniser output from
|
|
16
|
+
defining its own denominator (#1169).
|
|
17
|
+
- Draftwright now validates the released `b123d-recognisers` 0.2.0 capability manifest against
|
|
18
|
+
an exhaustive consumer-owned declaration of IR, DSL, generated-code, drawing, completeness,
|
|
19
|
+
and documentation states. Unknown families, stale implementations, record-schema drift, and
|
|
20
|
+
unevidenced state transitions fail closed; intentionally geometry-only repeating-profile
|
|
21
|
+
evidence remains usable without acquiring invented drafting semantics.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Updated the exact `b123d-recognisers` production lock from 0.2.0 to 0.2.1.
|
|
26
|
+
The immutable PyPI wheel/sdist hashes and capability-manifest digest
|
|
27
|
+
`383a196329ed6a3d1bf88f18ae4ff75613c032f35d40f2b53302b6744da4d19e` are
|
|
28
|
+
recorded in `.github/recogniser-release.json`; focused compatibility evidence and the
|
|
29
|
+
normal consumer gates run on the generated PR.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Stable release and TestPyPI snapshot builds now update package metadata and the independently
|
|
34
|
+
validated Draftwright consumer-contract identity atomically. This prevents stripped `.dev0`
|
|
35
|
+
and numbered development artifacts from failing their own capability-contract validation.
|
|
36
|
+
- Installed wheels validate every portable recogniser-contract property without requiring the
|
|
37
|
+
repository-only behavior-test files whose existence remains a strict source/CI gate. This keeps
|
|
38
|
+
the packaged STEP-analysis evaluator usable without weakening evidence checks in development.
|
|
39
|
+
- Post-release development-version bumps now update the consumer-contract identity on a branch,
|
|
40
|
+
open a protected PR, and dispatch the narrow maintenance gate instead of attempting a rejected
|
|
41
|
+
direct push to protected `main` (#1170).
|
|
42
|
+
- Machined-feature leader callouts now collect all clear alternatives within each
|
|
43
|
+
post-drain pass and use a bounded maximum-cardinality, minimum-leader-length
|
|
44
|
+
assignment instead of taking corners greedily in feature order (#740). If a
|
|
45
|
+
deterministic alternative-count, pass-size, candidate-pair, or search budget is
|
|
46
|
+
reached, placement retains the legacy greedy result or a result no worse than it
|
|
47
|
+
rather than losing additional callouts. Pre-drain diameter clearance ranking and
|
|
48
|
+
its Policy-B fallback remain unchanged.
|
|
49
|
+
|
|
3
50
|
## v0.4.6 — 2026-08-15
|
|
4
51
|
|
|
5
52
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: draftwright
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
4
4
|
Summary: Automated technical-drawing generation for build123d
|
|
5
5
|
Project-URL: Homepage, https://github.com/pzfreo/draftwright
|
|
6
6
|
Project-URL: Repository, https://github.com/pzfreo/draftwright
|
|
@@ -684,7 +684,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
684
684
|
Classifier: Topic :: Scientific/Engineering
|
|
685
685
|
Requires-Python: <3.15,>=3.10
|
|
686
686
|
Requires-Dist: antlr4-python3-runtime<4.10
|
|
687
|
-
Requires-Dist: b123d-recognisers==0.1
|
|
687
|
+
Requires-Dist: b123d-recognisers==0.2.1
|
|
688
688
|
Requires-Dist: build123d-drafting-helpers>=0.14.1
|
|
689
689
|
Requires-Dist: build123d<0.11,>=0.9.0; python_full_version < '3.13'
|
|
690
690
|
Requires-Dist: build123d<0.12,>=0.11; python_full_version >= '3.13'
|
|
@@ -30,7 +30,7 @@ architecture** table; open retired or superseded records only for design history
|
|
|
30
30
|
| [0011](0011-ir-as-public-input.md) | The IR as a public input: declare features, don't only detect them | Accept the feature IR as public input through declarations and the `Sheet` façade. | Accepted; core landed; #62/#462/#495 remain | `test_declare.py`, `test_object_aspects.py`, `test_sheet_gdt.py` |
|
|
31
31
|
| [0012](0012-edits-as-pinned-priority-candidates-in-the-global-solve.md) | User annotation edits are pinned, priority-ranked corridor candidates | Drain recorded semantic edits through corridor placement with pin and priority. | Accepted; partially landed; full recomposition/parity remains #426/#707 (#661 detail views landed) | `test_make_drawing.py`, `test_sheet_emit.py` |
|
|
32
32
|
| [0013](0013-uniform-recognition-and-shared-package.md) | A uniform recogniser/feature contract and shared `b123d-recognisers` deployment | Enforce the geometry-only contract in the shared package and consume it through Draftwright's record→IR boundary. | Accepted; Phases 1–2 deployed | `test_external_recognition_boundary.py`, `test_detect_registry.py`, package semantic goldens |
|
|
33
|
-
| [0014](0014-collect-then-solve-annotation-placement.md) | Collect-then-solve annotation placement (as built) | Collect, select, assign, and deterministically solve annotations per corridor before rendering. | Accepted; supersedes 0009 | `test_carve_free_position_callers.py`, `test_strip_layout.py`, `test_layout_property.py`, `test_import_boundaries.py` |
|
|
33
|
+
| [0014](0014-collect-then-solve-annotation-placement.md) | Collect-then-solve annotation placement (as built) | Collect, select, assign, and deterministically solve annotations per corridor before rendering; post-drain feature leaders also assign jointly within each pass. | Accepted; supersedes 0009; #740 Amendment 1 | `test_carve_free_position_callers.py`, `test_strip_layout.py`, `test_layout_property.py`, `test_issue_740_leader_assignment.py`, `test_import_boundaries.py` |
|
|
34
34
|
| [0015](0015-part-drawing-compiler-as-built.md) | The part-drawing compiler, as built | Use one detected-or-declared feature IR and planner-fed dimension groups as the compiler waist. | Accepted; supersedes 0008 | `test_part_model.py`, `test_detect_once.py`, `test_import_boundaries.py` |
|
|
35
35
|
| [0016](0016-declared-dimensioning-intent.md) | Declared dimensioning intent: capture what to measure, let the engine place it | Declare which measurements matter as scale-independent intent routed through the planner and corridor solve; never hardcode dimension geometry. | Accepted; epic #867 complete; phase 6 landed (#940) | `test_compiled_plan_boundary.py`, `test_label_provenance.py`, `test_sheet_emit.py`, `test_add_dimension.py` |
|
|
36
36
|
| [0017](0017-recognition-inventory-correspondence-and-measurement-provenance.md) | One recognition result per run; correspondence is evidence-gated | Produce one external immutable recognition result held by Draftwright's per-run cache; require vertical-slice evidence before generalising correspondence, identity, requirements, outcomes, or reconciliation. | Accepted; external cache ownership clarified, extensions gated by #1018 | `test_external_recognition_boundary.py`, `test_recognition_manifest.py`, `test_declared_recognition_gate.py` |
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Recogniser capability contract
|
|
2
|
+
|
|
3
|
+
Draftwright consumes the public capability manifest installed with `b123d-recognisers`; it never
|
|
4
|
+
reads a sibling checkout or a package-private file. The matching Draftwright-owned declaration is
|
|
5
|
+
implemented in `draftwright.recogniser_contract` and validated in CI.
|
|
6
|
+
|
|
7
|
+
The package manifest describes geometry evidence. Draftwright separately declares, for every
|
|
8
|
+
package family, its IR adapter, fluent `Sheet` surface, generated-Sheet behavior, drawing consumer,
|
|
9
|
+
completeness treatment, and documentation. A stage is either `supported`, `deferred`,
|
|
10
|
+
`not-applicable`, or `unsupported`, with the evidence required by that state. This separation lets
|
|
11
|
+
other CAD consumers apply different policy without making Draftwright policy part of the geometry
|
|
12
|
+
library.
|
|
13
|
+
|
|
14
|
+
## What failures mean
|
|
15
|
+
|
|
16
|
+
Validation fails closed and names the family and boundary whenever possible:
|
|
17
|
+
|
|
18
|
+
- **family inventory mismatch** — the installed package added, removed, or renamed a family.
|
|
19
|
+
Update the package pin deliberately, add or remove the Draftwright declaration, and provide the
|
|
20
|
+
downstream behavior or an explicit non-supported state.
|
|
21
|
+
- **record schema mismatch** — a consumed record schema changed. Review the record fields and
|
|
22
|
+
compatibility notes, update the relevant adapter and tests, then pin the accepted schema version.
|
|
23
|
+
- **stale implementation** — a declared adapter, `Sheet` method, emitter, renderer, or completeness
|
|
24
|
+
function no longer resolves. Repair the implementation reference and its independent behavior
|
|
25
|
+
evidence; do not merely rename the string.
|
|
26
|
+
- **evidence is missing** — a supported claim points at a deleted test or document. Restore or
|
|
27
|
+
replace the behavior evidence before changing the path.
|
|
28
|
+
- **unknown state or unsupported format** — the installed contract uses semantics this Draftwright
|
|
29
|
+
version does not understand. Upgrade the validator before accepting the package version.
|
|
30
|
+
- **geometry-only family invents semantics** — geometry used for critique was incorrectly given an
|
|
31
|
+
inferred IR/DSL/code-generation/drawing path. Keep it geometry-only unless a separately reviewed
|
|
32
|
+
Draftwright feature introduces authored semantics and compatibility evidence.
|
|
33
|
+
- **reserved family claims supported downstream semantics** — a family-level `deferred` or
|
|
34
|
+
`unsupported` disposition still advertises an implemented downstream stage. Either make the
|
|
35
|
+
family disposition supported with behavior evidence, or defer/disable every semantic stage and
|
|
36
|
+
retain its tracking issue.
|
|
37
|
+
- **state transition lacks evidence** — a capability was strengthened or weakened without a named
|
|
38
|
+
Draftwright version, release notes, and compatibility tests. Supply all three as one reviewed
|
|
39
|
+
transition.
|
|
40
|
+
|
|
41
|
+
## Adding or changing a recogniser
|
|
42
|
+
|
|
43
|
+
Land the package record, independent geometry evidence, manifest update, and compatible package
|
|
44
|
+
release first. Then update Draftwright against that immutable release. For each applicable stage,
|
|
45
|
+
add the adapter, declaration, emitted-Sheet round trip, drawing behavior, and completeness evidence;
|
|
46
|
+
for an inapplicable or deferred stage, state why and link its tracking issue. The contract test
|
|
47
|
+
derives package record outputs, converter registries, live `Sheet` methods, and emitter branches
|
|
48
|
+
independently, so copying a new name into the declaration alone cannot make CI pass.
|
|
49
|
+
|
|
50
|
+
`bosses` is the fully consumed reference family. `repeating-radial-profiles` is the opposite
|
|
51
|
+
reference: it remains geometry-only critique evidence for a separately authored gear declaration,
|
|
52
|
+
with no inferred gear feature added to fill the table.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Sheet and fluent handles
|
|
2
|
+
|
|
3
|
+
`Sheet` is the declared authoring façade. Feature verbs return fluent handles; those handles
|
|
4
|
+
are documented here because they are part of normal use even though their Python names begin
|
|
5
|
+
with an underscore.
|
|
6
|
+
|
|
7
|
+
## Sheet
|
|
8
|
+
|
|
9
|
+
::: draftwright.sheet.Sheet
|
|
10
|
+
options:
|
|
11
|
+
filters: public
|
|
12
|
+
|
|
13
|
+
## Hole handle
|
|
14
|
+
|
|
15
|
+
::: draftwright.sheet._Hole
|
|
16
|
+
options:
|
|
17
|
+
filters: public
|
|
18
|
+
|
|
19
|
+
## Diameter and step handle
|
|
20
|
+
|
|
21
|
+
::: draftwright.sheet._Dim
|
|
22
|
+
options:
|
|
23
|
+
filters: public
|
|
24
|
+
|
|
25
|
+
## Multi-parameter handle
|
|
26
|
+
|
|
27
|
+
::: draftwright.sheet._Params
|
|
28
|
+
options:
|
|
29
|
+
filters: public
|
|
30
|
+
|
|
31
|
+
## GD&T control builder
|
|
32
|
+
|
|
33
|
+
::: draftwright.sheet._Control
|
|
34
|
+
options:
|
|
35
|
+
filters: public
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Repeating Radial Profile Evidence (#1062)
|
|
2
|
+
|
|
3
|
+
> **Status:** productionised by #1087, 2026-08-09. The executable mutations remain in
|
|
4
|
+
> `tests/test_issue_1058_wheel_profile.py`; the reusable evidence is owned by
|
|
5
|
+
> `recognition/repeating_profiles.py`. No automatic gear semantics are approved by this note.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
The wheel fixture proves a **closed 13-fold repeating radial outer profile** about its Z
|
|
10
|
+
axis. It does not prove that the profile is a gear, nor does it establish module, pressure
|
|
11
|
+
angle, helix angle, backlash, tooth thickness, quality grade, or manufacturing process.
|
|
12
|
+
|
|
13
|
+
Keep `unrecognised_defining_geometry` for this part. Do not add an automatic `GearFeature`,
|
|
14
|
+
emit a gear callout, or treat outside/root diameters and repeat count as a complete
|
|
15
|
+
manufacturing definition. The useful next boundary is:
|
|
16
|
+
|
|
17
|
+
1. reusable geometry-only correspondence for a repeating radial profile; and
|
|
18
|
+
2. a separately designed, explicit declaration of gear requirements and their drawing
|
|
19
|
+
presentation.
|
|
20
|
+
|
|
21
|
+
The second may consume the first to check that declared tooth count and axis correspond to
|
|
22
|
+
the solid. Recognition must not manufacture the declaration.
|
|
23
|
+
|
|
24
|
+
## Pinned Evidence
|
|
25
|
+
|
|
26
|
+
| Item | Observed fact |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Fixture | `tests/fixtures/issue_1058_wheel_rh.step` |
|
|
29
|
+
| SHA-256 | `4911c06426f0ceeedc198416e058aabc1c1a6a65e9e766eca7efed5484a27cda` |
|
|
30
|
+
| STEP form | AP214, one solid, generic product name `SOLID` |
|
|
31
|
+
| Overall bounds | X -3.8000001..3.7733322; Y -3.8000001..3.8000001; Z -3.8500001..3.8500001 mm |
|
|
32
|
+
| Principal outer boundaries | two, at the opposed Z limits |
|
|
33
|
+
| Boundary topology | one closed 52-edge outer wire on each end face |
|
|
34
|
+
| Edge inventory | 13 circular edges and 39 B-splines |
|
|
35
|
+
| Circular edges | radius 3.8 mm, common XY centre (0, 0) |
|
|
36
|
+
| Rotational correspondence | four complete 13-edge orbits under `2*pi/13` rotation |
|
|
37
|
+
| Orbit roles | one circular-tip orbit and three B-spline orbits |
|
|
38
|
+
|
|
39
|
+
Both end faces prove the same correspondence despite different edge start and traversal.
|
|
40
|
+
The STEP header and entities contain no gear name, PMI, standard, or parameter metadata.
|
|
41
|
+
|
|
42
|
+
## What The Proof Establishes
|
|
43
|
+
|
|
44
|
+
The test samples every curve in each outer wire, then requires a one-to-one mapping of every
|
|
45
|
+
curve under one sector rotation. Curve type, length, and sampled geometry must agree within
|
|
46
|
+
the fixed tolerance. The mapping must be bijective, each orbit must contain exactly 13
|
|
47
|
+
curves, and every endpoint must belong to one connected degree-two cycle.
|
|
48
|
+
|
|
49
|
+
This is stronger than the existing lint hint. `_radial_outer_arc_count` reports 13 equal,
|
|
50
|
+
equally spaced arcs on a common circle, but explicitly does not claim that the 39 intervening
|
|
51
|
+
B-splines repeat. The complete-wire proof closes that geometric gap without widening the
|
|
52
|
+
semantic claim.
|
|
53
|
+
|
|
54
|
+
The following mutations fail:
|
|
55
|
+
|
|
56
|
+
- retaining only the 13 common-circle arcs;
|
|
57
|
+
- altering one intervening B-spline sample while leaving all arcs unchanged;
|
|
58
|
+
- breaking one endpoint so the outer wire is open;
|
|
59
|
+
- changing one sector boundary while preserving a closed cycle; and
|
|
60
|
+
- relying on the wire's original start edge or traversal direction.
|
|
61
|
+
|
|
62
|
+
The changed-intervening-curve mutation is the decisive guard: an arc-count implementation
|
|
63
|
+
would still pass it.
|
|
64
|
+
|
|
65
|
+
## Why This Is Not Gear Recognition
|
|
66
|
+
|
|
67
|
+
Many manufactured profiles can be cyclic without being gears. Even if a human recognises
|
|
68
|
+
the fixture's purpose, the B-rep alone does not uniquely identify the generating standard or
|
|
69
|
+
the requirements needed to reproduce and inspect it. Fitting a plausible standard from 13
|
|
70
|
+
tips and a diameter would turn a guess into normative drawing output.
|
|
71
|
+
|
|
72
|
+
A truthful technical drawing therefore needs explicit requirements supplied by the author,
|
|
73
|
+
usually including at least the gear system/type, tooth count, module or diametral pitch,
|
|
74
|
+
pressure angle, reference geometry, and the applicable accuracy or inspection requirement.
|
|
75
|
+
The exact public surface and table/callout form need a standards-backed design slice; this
|
|
76
|
+
discovery does not invent them.
|
|
77
|
+
|
|
78
|
+
## ADR Fit
|
|
79
|
+
|
|
80
|
+
- **ADR 0013:** the proven repeat is lower-tier, geometry-only evidence. `gear` is an
|
|
81
|
+
application semantic and must not be smuggled into the recognition record.
|
|
82
|
+
- **ADR 0015:** any future automatic record must enter through the compiler's existing
|
|
83
|
+
recognition waist. A declared gear requirement belongs on the declared path.
|
|
84
|
+
- **ADR 0017:** if productionised, one orchestration owns the correspondence evidence and
|
|
85
|
+
consumers project from it. The mutation precedes trust in the guard, and a new identity
|
|
86
|
+
scheme is not justified by this single case.
|
|
87
|
+
- **ADR 0011:** explicit author intent is the appropriate source for requirements that the
|
|
88
|
+
B-rep cannot establish.
|
|
89
|
+
|
|
90
|
+
No ADR amendment is required. No placement decision is made, so ADR 0014 is unaffected.
|
|
91
|
+
|
|
92
|
+
## Follow-up Slices
|
|
93
|
+
|
|
94
|
+
1. **Productionised in #1087.** The pure full-wire correspondence is owned by the one
|
|
95
|
+
recognition orchestration and consumed by physical critique for declared-profile
|
|
96
|
+
correspondence. It does not clear completeness merely because the repeat exists.
|
|
97
|
+
2. **Design declared gear requirements.** Start from the applicable drawing/gear standards
|
|
98
|
+
and define the minimum honest declaration, validation, IR, and table/callout output. Include
|
|
99
|
+
a mismatch diagnostic when declared count or axis disagrees with geometric evidence.
|
|
100
|
+
3. **Only then assess automatic assistance.** Recognition may prefill proven geometric facts
|
|
101
|
+
such as axis and repeat count for user confirmation. It may not infer the normative gear
|
|
102
|
+
specification.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "draftwright"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.7"
|
|
8
8
|
description = "Automated technical-drawing generation for build123d"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -18,7 +18,7 @@ dependencies = [
|
|
|
18
18
|
"build123d>=0.9.0,<0.11 ; python_full_version < '3.13'",
|
|
19
19
|
"build123d>=0.11,<0.12 ; python_full_version >= '3.13'",
|
|
20
20
|
"build123d-drafting-helpers>=0.14.1",
|
|
21
|
-
"b123d-recognisers==0.1
|
|
21
|
+
"b123d-recognisers==0.2.1",
|
|
22
22
|
"numpy>=1.24",
|
|
23
23
|
# PNG raster export (SVG→PDF→PNG). Both permissively licensed (Pillow HPND; pypdfium2
|
|
24
24
|
# Apache-2.0 wrapping Google PDFium BSD-3) and ship pre-built wheels with NO native system
|
|
@@ -69,6 +69,9 @@ include = [
|
|
|
69
69
|
"src/draftwright",
|
|
70
70
|
"tests",
|
|
71
71
|
"skills",
|
|
72
|
+
"docs/reference/recogniser-capabilities.md",
|
|
73
|
+
"docs/reference/sheet.md",
|
|
74
|
+
"docs/research/1062-repeating-radial-profile-evidence.md",
|
|
72
75
|
"README.md",
|
|
73
76
|
"LICENSE",
|
|
74
77
|
"CHANGELOG.md",
|
|
@@ -630,7 +630,7 @@ def _analyse(
|
|
|
630
630
|
# by #1025). Both callers deriving this separately let lint project over a different
|
|
631
631
|
# ladder than the model was sized from — which is exactly the divergence one waist is
|
|
632
632
|
# supposed to prevent.
|
|
633
|
-
step_zs = recognition.
|
|
633
|
+
step_zs = recognition.step_ladder_for_z_span(bb.min.Z, bb.max.Z)
|
|
634
634
|
# The aggregate owns the shared substrate from here on. Rebind the local projection so
|
|
635
635
|
# model construction, Analysis and the finished BuildState all consume the same inventory
|
|
636
636
|
# object rather than parallel list/tuple wrappers that merely happen to contain equal data.
|
|
@@ -970,6 +970,19 @@ def occupancy_boxes(o, stroke_pad=None):
|
|
|
970
970
|
_STROKE_PAD = 1.2
|
|
971
971
|
|
|
972
972
|
|
|
973
|
+
def annotation_obstacle_boxes(dwg, annotation):
|
|
974
|
+
"""One annotation's obstacle boxes under the shared strip-occupancy policy.
|
|
975
|
+
|
|
976
|
+
Candidate-based placers use this before an annotation is registered; factoring
|
|
977
|
+
the preset-aware stroke pad here keeps those candidate conflicts identical to
|
|
978
|
+
the boxes :func:`strip_obstacles` will expose after placement (#740).
|
|
979
|
+
"""
|
|
980
|
+
|
|
981
|
+
arrow_length = getattr(getattr(dwg, "draft", None), "arrow_length", None)
|
|
982
|
+
pad = max(_STROKE_PAD, arrow_length / 2) if arrow_length else _STROKE_PAD
|
|
983
|
+
return occupancy_boxes(annotation, stroke_pad=pad)
|
|
984
|
+
|
|
985
|
+
|
|
973
986
|
def strip_obstacles(dwg, view=None, *, crossable=(), named=False):
|
|
974
987
|
"""The COMPLETE occupancy for strip placement (ADR 0009): every placed
|
|
975
988
|
annotation's full rendered footprint, optionally restricted to *view*, minus
|
|
@@ -1005,9 +1018,6 @@ def strip_obstacles(dwg, view=None, *, crossable=(), named=False):
|
|
|
1005
1018
|
|
|
1006
1019
|
The occupancy source for the collect-then-solve carve — every migrated renderer's
|
|
1007
1020
|
``place_strip_candidates`` call wires this in (#321/#150/P3)."""
|
|
1008
|
-
# Preset-aware stroke pad (#688 review): arrowheads scale with font_size.
|
|
1009
|
-
al = getattr(getattr(dwg, "draft", None), "arrow_length", None)
|
|
1010
|
-
pad = max(_STROKE_PAD, al / 2) if al else _STROKE_PAD
|
|
1011
1021
|
boxes: list = []
|
|
1012
1022
|
for name, o in dwg.iter_annotations():
|
|
1013
1023
|
if view is not None:
|
|
@@ -1016,7 +1026,7 @@ def strip_obstacles(dwg, view=None, *, crossable=(), named=False):
|
|
|
1016
1026
|
continue # owned by a different ortho view → its own (disjoint) block
|
|
1017
1027
|
if type(o).__name__ in crossable:
|
|
1018
1028
|
continue # this consumer may cross it (centre lines/marks for a dim)
|
|
1019
|
-
occ =
|
|
1029
|
+
occ = annotation_obstacle_boxes(dwg, o) # decomposed, not one hull (#685/#740)
|
|
1020
1030
|
boxes.extend(((name, b) for b in occ) if named else occ)
|
|
1021
1031
|
return boxes
|
|
1022
1032
|
|