draftwright 0.4.23__tar.gz → 0.4.25__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.
Files changed (568) hide show
  1. {draftwright-0.4.23 → draftwright-0.4.25}/CHANGELOG.md +4 -0
  2. {draftwright-0.4.23 → draftwright-0.4.25}/PKG-INFO +2 -2
  3. {draftwright-0.4.23 → draftwright-0.4.25}/docs/reference/sheet.md +95 -1
  4. {draftwright-0.4.23 → draftwright-0.4.25}/pyproject.toml +2 -2
  5. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/_core.py +77 -12
  6. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/_geometry.py +3 -0
  7. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/analysis.py +58 -15
  8. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/angular_geometry.py +34 -8
  9. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/_common.py +76 -0
  10. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/angular.py +1 -1
  11. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/balloons.py +42 -30
  12. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/from_model.py +116 -25
  13. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/holes.py +172 -110
  14. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/orchestrator.py +4 -3
  15. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/sections.py +2 -2
  16. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/audit.py +1 -1
  17. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/builder.py +129 -72
  18. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/cli.py +19 -1
  19. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/compose.py +247 -17
  20. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/drawing.py +60 -21
  21. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/coverage.py +33 -26
  22. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/hole_coverage.py +23 -7
  23. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/structural.py +5 -4
  24. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/callout.py +110 -0
  25. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/compiled.py +145 -15
  26. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/declare.py +4 -0
  27. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/ir.py +17 -1
  28. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/planner.py +132 -31
  29. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/registry.py +19 -1
  30. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/sheet.py +25 -13
  31. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/sheet_emit.py +26 -2
  32. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/view_plan.py +55 -10
  33. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_adr0018_view_selection.py +4 -4
  34. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_balloon_ring_standoff.py +7 -3
  35. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_compiled_plan_boundary.py +10 -3
  36. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_declared_recognition_gate.py +2 -3
  37. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1144_transactional_hole_table.py +185 -79
  38. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1154_one_owner_per_measurement.py +4 -4
  39. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1215_envelope_tolerance.py +19 -31
  40. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1260_view_constraints.py +1 -1
  41. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1372_pocket_pattern_completeness_evidence.py +2 -0
  42. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1378_diameter_leader_targets.py +26 -4
  43. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1466_dimension_options.py +3 -0
  44. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1479_radius_leader_targets.py +1 -1
  45. draftwright-0.4.25/tests/test_issue_1511_turned_boss_heights.py +340 -0
  46. draftwright-0.4.25/tests/test_issue_1514_projection_safeguard.py +74 -0
  47. draftwright-0.4.25/tests/test_issue_1515_first_angle.py +267 -0
  48. draftwright-0.4.25/tests/test_issue_1516_dimension_text.py +213 -0
  49. draftwright-0.4.25/tests/test_issue_1517_through_indicator.py +473 -0
  50. draftwright-0.4.25/tests/test_issue_1518_explicit_rear.py +673 -0
  51. draftwright-0.4.25/tests/test_issue_1524_tolerance_magnitude.py +58 -0
  52. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_740_leader_assignment.py +6 -0
  53. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_make_drawing.py +76 -27
  54. draftwright-0.4.25/tests/test_overall_height_coverage.py +199 -0
  55. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_suppression_marks.py +2 -2
  56. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_tolerances.py +8 -8
  57. {draftwright-0.4.23 → draftwright-0.4.25}/.gitignore +0 -0
  58. {draftwright-0.4.23 → draftwright-0.4.25}/LICENSE +0 -0
  59. {draftwright-0.4.23 → draftwright-0.4.25}/README.md +0 -0
  60. {draftwright-0.4.23 → draftwright-0.4.25}/docs/adr/README.md +0 -0
  61. {draftwright-0.4.23 → draftwright-0.4.25}/docs/reference/recogniser-capabilities.md +0 -0
  62. {draftwright-0.4.23 → draftwright-0.4.25}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
  63. {draftwright-0.4.23 → draftwright-0.4.25}/skills/SKILL.md +0 -0
  64. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/__init__.py +0 -0
  65. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/_build_profile.py +0 -0
  66. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/_pmi_part21.py +0 -0
  67. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/_warnings.py +0 -0
  68. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotate.py +0 -0
  69. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/__init__.py +0 -0
  70. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/gears.py +0 -0
  71. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/annotations/leaders.py +0 -0
  72. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/blend_contract.py +0 -0
  73. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/evaluation/__init__.py +0 -0
  74. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/evaluation/step_analysis.py +0 -0
  75. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/export.py +0 -0
  76. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/feature_identity.py +0 -0
  77. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/fits.py +0 -0
  78. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  79. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  80. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  81. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  82. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/fonts/__init__.py +0 -0
  83. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/inspection.py +0 -0
  84. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/inspection_contract.py +0 -0
  85. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/intents.py +0 -0
  86. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/layout.py +0 -0
  87. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/__init__.py +0 -0
  88. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/_registry.py +0 -0
  89. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/angled_step_coverage.py +0 -0
  90. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/angular.py +0 -0
  91. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/blend_coverage.py +0 -0
  92. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/chamfer_coverage.py +0 -0
  93. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/channel_coverage.py +0 -0
  94. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/circular_blind_step_coverage.py +0 -0
  95. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/evidence.py +0 -0
  96. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/fillet_coverage.py +0 -0
  97. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/flat_coverage.py +0 -0
  98. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/gear_coverage.py +0 -0
  99. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/groove_coverage.py +0 -0
  100. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/ink_overlap.py +0 -0
  101. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/issues.py +0 -0
  102. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/oriented_slot_coverage.py +0 -0
  103. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/pad_coverage.py +0 -0
  104. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/paired_ramp_step_coverage.py +0 -0
  105. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/passage_coverage.py +0 -0
  106. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/plate_coverage.py +0 -0
  107. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/pmi_coverage.py +0 -0
  108. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/pocket_coverage.py +0 -0
  109. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/pocket_pattern_coverage.py +0 -0
  110. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/polygonal_boss_coverage.py +0 -0
  111. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
  112. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  113. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  114. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/quality.py +0 -0
  115. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/rectangular_blind_slot_coverage.py +0 -0
  116. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/requirements.py +0 -0
  117. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +0 -0
  118. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/section_recess_coverage.py +0 -0
  119. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/slot_coverage.py +0 -0
  120. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/suggest.py +0 -0
  121. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/through_step_coverage.py +0 -0
  122. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/linting/turned_step_coverage.py +0 -0
  123. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/make_drawing.py +0 -0
  124. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/__init__.py +0 -0
  125. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/detect.py +0 -0
  126. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/model/pmi_lowering.py +0 -0
  127. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/oriented_slot_contract.py +0 -0
  128. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/plate_correspondence.py +0 -0
  129. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/pmi.py +0 -0
  130. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/profile_angles.py +0 -0
  131. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/projection.py +0 -0
  132. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/py.typed +0 -0
  133. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recogniser_contract.py +0 -0
  134. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recogniser_policy.py +0 -0
  135. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recogniser_schema.py +0 -0
  136. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recognition/__init__.py +0 -0
  137. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recognition_cache.py +0 -0
  138. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recognition_frame.py +0 -0
  139. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/recognition_ownership.py +0 -0
  140. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/repair.py +0 -0
  141. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/reporting.py +0 -0
  142. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/score.py +0 -0
  143. {draftwright-0.4.23 → draftwright-0.4.25}/src/draftwright/section_recess_contract.py +0 -0
  144. {draftwright-0.4.23 → draftwright-0.4.25}/tests/_evidence_contract.py +0 -0
  145. {draftwright-0.4.23 → draftwright-0.4.25}/tests/_kernel.py +0 -0
  146. {draftwright-0.4.23 → draftwright-0.4.25}/tests/_layout_sig.py +0 -0
  147. {draftwright-0.4.23 → draftwright-0.4.25}/tests/_mutation_corpus.py +0 -0
  148. {draftwright-0.4.23 → draftwright-0.4.25}/tests/_recogniser_public_contract.py +0 -0
  149. {draftwright-0.4.23 → draftwright-0.4.25}/tests/_section_recess_cases.py +0 -0
  150. {draftwright-0.4.23 → draftwright-0.4.25}/tests/conftest.py +0 -0
  151. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  152. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/README.md +0 -0
  153. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  154. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/blind-hole.step +0 -0
  155. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  156. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  157. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  158. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  159. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  160. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  161. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  162. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  163. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  164. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  165. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  166. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  167. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  168. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  169. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  170. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  171. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  172. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  173. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  174. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  175. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  176. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  177. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  178. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  179. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  180. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  181. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  182. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  183. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/countersink-single.step +0 -0
  184. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  185. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  186. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  187. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  188. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  189. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  190. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  191. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  192. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  193. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  194. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  195. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  196. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  197. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  198. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  199. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  200. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  201. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  202. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  203. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  204. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  205. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  206. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  207. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  208. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  209. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  210. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  211. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  212. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  213. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-compound.step +0 -0
  214. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  215. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  216. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  217. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  218. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  219. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  220. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  221. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  222. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  223. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  224. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  225. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  226. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  227. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  228. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  229. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  230. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  231. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  232. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  233. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  234. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  235. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  236. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  237. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plain-block.step +0 -0
  238. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  239. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  240. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  241. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  242. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  243. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  244. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  245. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  246. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  247. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  248. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  249. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  250. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  251. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  252. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  253. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  254. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  255. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  256. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  257. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  258. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  259. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  260. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-side.step +0 -0
  261. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  262. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  263. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  264. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  265. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  266. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  267. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  268. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  269. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  270. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  271. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  272. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  273. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  274. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  275. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  276. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  277. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  278. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  279. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  280. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  281. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  282. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  283. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  284. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  285. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  286. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  287. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/topology-a.step +0 -0
  288. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/topology-b.step +0 -0
  289. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  290. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  291. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  292. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  293. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  294. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  295. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  296. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  297. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  298. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  299. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  300. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/grm04_drive_plate.step +0 -0
  301. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  302. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  303. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  304. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  305. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/issue_915_case_study_2.step +0 -0
  306. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  307. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  308. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  309. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  310. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  311. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  312. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  313. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  314. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  315. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  316. {draftwright-0.4.23 → draftwright-0.4.25}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  317. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/bracket_section.json +0 -0
  318. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/centered_rebate.json +0 -0
  319. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/chamfered.json +0 -0
  320. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/filleted.json +0 -0
  321. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/flange_dense.json +0 -0
  322. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/grid_plate.json +0 -0
  323. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/grooved_shaft.json +0 -0
  324. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/hex_bar.json +0 -0
  325. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/holed_slot.json +0 -0
  326. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/pocketed.json +0 -0
  327. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/prismatic_ladder.json +0 -0
  328. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/scattered_plate.json +0 -0
  329. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/side_drilled.json +0 -0
  330. {draftwright-0.4.23 → draftwright-0.4.25}/tests/refactor_golden/turned_stepped.json +0 -0
  331. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_add_dimension.py +0 -0
  332. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_adr0018_arrangement_gate.py +0 -0
  333. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_adr0018_view_routing.py +0 -0
  334. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_adr_corpus.py +0 -0
  335. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_agents_guide.py +0 -0
  336. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_api_docs.py +0 -0
  337. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_architecture_docs.py +0 -0
  338. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_audit_differential.py +0 -0
  339. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_build_profile_harness.py +0 -0
  340. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_carve_free_position_callers.py +0 -0
  341. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_clone_budget.py +0 -0
  342. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_counting_calls.py +0 -0
  343. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_declare.py +0 -0
  344. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_dense_sheet_canary.py +0 -0
  345. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_deprecation_dates.py +0 -0
  346. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_detect_once.py +0 -0
  347. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_detect_registry.py +0 -0
  348. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_dimension_role_vocabulary.py +0 -0
  349. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_drawing_encapsulation.py +0 -0
  350. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_e2e_slice.py +0 -0
  351. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_e2e_standards.py +0 -0
  352. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_export_dxf_curves.py +0 -0
  353. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_export_dxf_zoom.py +0 -0
  354. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_export_reproducible.py +0 -0
  355. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_external_recognition_boundary.py +0 -0
  356. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_fillets_adjacency.py +0 -0
  357. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_fits.py +0 -0
  358. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_flat_completeness.py +0 -0
  359. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_flat_stock_identity.py +0 -0
  360. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_flat_stock_opposition.py +0 -0
  361. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_gdt_placement.py +0 -0
  362. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_geometry_graph_spike.py +0 -0
  363. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_grid_lattice_convention.py +0 -0
  364. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_import_boundaries.py +0 -0
  365. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_inspection_contract.py +0 -0
  366. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_iso_nts_caption_placement.py +0 -0
  367. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1000_envelope_reuse.py +0 -0
  368. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1006_measurement_comparison.py +0 -0
  369. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1058_wheel_profile.py +0 -0
  370. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  371. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1082_polygonal_stock.py +0 -0
  372. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1086_declared_gears.py +0 -0
  373. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  374. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1130_view_planning_evidence.py +0 -0
  375. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1142_hole_leader_labels.py +0 -0
  376. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1143_hole_completeness.py +0 -0
  377. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1146_scale_completeness.py +0 -0
  378. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  379. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
  380. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  381. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  382. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1176_quality_fidelity.py +0 -0
  383. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1177_angular_dimensions.py +0 -0
  384. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  385. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1188_per_view_assignment.py +0 -0
  386. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1190_section_decision.py +0 -0
  387. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1196_deterministic_view_names.py +0 -0
  388. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
  389. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  390. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  391. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +0 -0
  392. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1216_callout_reservation_measures_ink.py +0 -0
  393. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  394. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1217_claimed_representations.py +0 -0
  395. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1217_the_facility_is_shared.py +0 -0
  396. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  397. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  398. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  399. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1245_passage_disposition.py +0 -0
  400. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  401. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  402. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1254_turned_chamfers.py +0 -0
  403. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  404. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  405. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1281_turned_fillets.py +0 -0
  406. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
  407. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
  408. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1299_page_escalation.py +0 -0
  409. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1308_machined_leader_analytics.py +0 -0
  410. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1312_engine_costs.py +0 -0
  411. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1325_nominal_agreement.py +0 -0
  412. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1332_overlap_remedy.py +0 -0
  413. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1332_zone_labels.py +0 -0
  414. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1333_bounded_ink_repair.py +0 -0
  415. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1334_prevent_ink.py +0 -0
  416. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  417. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  418. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1349_precision_display.py +0 -0
  419. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1350_detected_takeover.py +0 -0
  420. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  421. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  422. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  423. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1357_framed_activation.py +0 -0
  424. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1357_framed_boundary.py +0 -0
  425. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1357_plural_turned_profiles.py +0 -0
  426. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1357_pmi_frame.py +0 -0
  427. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1360_thread_depth.py +0 -0
  428. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1369_hole_completeness_evidence.py +0 -0
  429. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1370_countersink_completeness_evidence.py +0 -0
  430. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1370_double_d_completeness_evidence.py +0 -0
  431. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +0 -0
  432. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1371_flat_completeness_evidence.py +0 -0
  433. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +0 -0
  434. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1372_groove_completeness_evidence.py +0 -0
  435. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1372_pad_completeness_evidence.py +0 -0
  436. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1372_pocket_completeness_evidence.py +0 -0
  437. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1372_polygonal_boss_completeness_evidence.py +0 -0
  438. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1373_plate_completeness_evidence.py +0 -0
  439. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1374_chamfer_completeness_evidence.py +0 -0
  440. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1374_fillet_completeness_evidence.py +0 -0
  441. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1374_turned_step_completeness_evidence.py +0 -0
  442. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1382_046_step_inventory.py +0 -0
  443. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1382_circular_blind_step_semantics.py +0 -0
  444. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1382_framed_step_family_evidence.py +0 -0
  445. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1382_paired_ramp_semantics.py +0 -0
  446. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1382_through_step_semantics.py +0 -0
  447. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1390_sheet_registration.py +0 -0
  448. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1392_recognisers_048.py +0 -0
  449. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1395_degenerate_iso_region.py +0 -0
  450. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1396_layout_advisories.py +0 -0
  451. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1397_unverifiable_requirement_message.py +0 -0
  452. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  453. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +0 -0
  454. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  455. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  456. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1432_adoption.py +0 -0
  457. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1432_boundary_failures.py +0 -0
  458. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1432_oriented_slot_semantics.py +0 -0
  459. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1433_blend_semantics.py +0 -0
  460. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_boss_ownership.py +0 -0
  461. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_channel_ownership.py +0 -0
  462. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_cli_report_sidecar.py +0 -0
  463. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_generation_snapshot.py +0 -0
  464. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_nested_ownership.py +0 -0
  465. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_occurrence_ownership.py +0 -0
  466. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_pattern_ownership.py +0 -0
  467. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_plate_ownership.py +0 -0
  468. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_policy_dispositions.py +0 -0
  469. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_report_projection.py +0 -0
  470. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_report_writer.py +0 -0
  471. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_through_step_ownership.py +0 -0
  472. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1438_turned_step_ownership.py +0 -0
  473. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1450_boss_blend_ownership.py +0 -0
  474. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1460_step_inspection.py +0 -0
  475. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1466_semantic_sides.py +0 -0
  476. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1471_boundary_failures.py +0 -0
  477. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1471_evidence_schema.py +0 -0
  478. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1471_groove_profile.py +0 -0
  479. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1471_section_recess_contract.py +0 -0
  480. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1471_section_recess_pockets.py +0 -0
  481. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1485_curved_pockets.py +0 -0
  482. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1485_quiddity_024_boundary.py +0 -0
  483. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1485_rounded_pockets.py +0 -0
  484. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1504_angle_patterns.py +0 -0
  485. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1504_angular_references.py +0 -0
  486. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1504_angular_rendering.py +0 -0
  487. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1504_canonical_angles.py +0 -0
  488. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1504_profile_angles.py +0 -0
  489. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1505_diameter_coverage.py +0 -0
  490. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_1505_short_axial_chains.py +0 -0
  491. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_367_leader_ink.py +0 -0
  492. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  493. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_563_placement_intent.py +0 -0
  494. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_676_polygonal_boss.py +0 -0
  495. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  496. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_798_floor_cardinality.py +0 -0
  497. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_798_material_field.py +0 -0
  498. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_798_silhouette_lint.py +0 -0
  499. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_827_real_part_canary.py +0 -0
  500. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_883_location_identity.py +0 -0
  501. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_885_prismatic_coverage.py +0 -0
  502. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_909_sloped_profile.py +0 -0
  503. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_915_dense_case.py +0 -0
  504. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_916_pocket_leader.py +0 -0
  505. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_917_open_channel.py +0 -0
  506. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  507. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_955_height_contingency.py +0 -0
  508. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  509. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_label_provenance.py +0 -0
  510. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_layout.py +0 -0
  511. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_layout_cleanliness.py +0 -0
  512. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_layout_hypothesis.py +0 -0
  513. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_layout_property.py +0 -0
  514. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_leader_footprint.py +0 -0
  515. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_lint_box_cache.py +0 -0
  516. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_lint_ink_overlap.py +0 -0
  517. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_lint_reconciliation.py +0 -0
  518. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_lint_structural.py +0 -0
  519. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_linting.py +0 -0
  520. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_location_vocabulary.py +0 -0
  521. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_note_verb.py +0 -0
  522. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_object_aspects.py +0 -0
  523. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_occupancy_boxes.py +0 -0
  524. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_parameter_id.py +0 -0
  525. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_part_model.py +0 -0
  526. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pitch_dim_footprint.py +0 -0
  527. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pmi.py +0 -0
  528. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pmi_datum_lowering.py +0 -0
  529. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pmi_gtol_lowering.py +0 -0
  530. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pmi_part21.py +0 -0
  531. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pocket_pattern.py +0 -0
  532. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_pocket_pattern_recognition.py +0 -0
  533. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_principal_profile_classifier.py +0 -0
  534. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_private_test_attr_reads.py +0 -0
  535. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_private_test_imports.py +0 -0
  536. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_quality_components.py +0 -0
  537. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_recogniser_adoption.py +0 -0
  538. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_recogniser_capabilities.py +0 -0
  539. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_recogniser_contract.py +0 -0
  540. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_recognition_result.py +0 -0
  541. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_refactor_golden.py +0 -0
  542. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_registry.py +0 -0
  543. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_render_seam.py +0 -0
  544. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_repack_geometry_seam.py +0 -0
  545. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_score.py +0 -0
  546. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_script_detail_parity.py +0 -0
  547. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_shared_box_memo.py +0 -0
  548. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_emit.py +0 -0
  549. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_gdt.py +0 -0
  550. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_identity_invariant.py +0 -0
  551. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_notes.py +0 -0
  552. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_of.py +0 -0
  553. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_section.py +0 -0
  554. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_sheet_tables.py +0 -0
  555. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_slanted_blind_step.py +0 -0
  556. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_slot_completeness.py +0 -0
  557. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_slot_pattern.py +0 -0
  558. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_slot_pattern_recognition.py +0 -0
  559. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_soft_deprecation.py +0 -0
  560. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_solve_trace.py +0 -0
  561. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_step_analysis_evaluation.py +0 -0
  562. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_strip_layout.py +0 -0
  563. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_suppression_ledger.py +0 -0
  564. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_turned_steps.py +0 -0
  565. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_version_bump_ci.py +0 -0
  566. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_view_plan.py +0 -0
  567. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_witness_label_reconciliation.py +0 -0
  568. {draftwright-0.4.23 → draftwright-0.4.25}/tests/test_workflows.py +0 -0
@@ -478,6 +478,10 @@
478
478
 
479
479
  ### Fixed
480
480
 
481
+ - Overall height and envelope width remain dimensioned when approved turned-step lengths
482
+ cover only part of the respective extent. Redundancy suppression now requires adjoining
483
+ measurements on one profile to reach both overall endpoints; STC618 retains its missing
484
+ 62 mm height (#1509).
481
485
  - Non-1:1 orthographic and isometric projection now scales extracted solids about the world
482
486
  origin, matching the view-coordinate mapper and solver zones. Solids carrying a non-zero
483
487
  build123d `Location` no longer shift their silhouette away from dimensions and callouts.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.23
3
+ Version: 0.4.25
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: build123d-drafting-helpers>=0.14.2
687
+ Requires-Dist: build123d-drafting-helpers>=0.15.1
688
688
  Requires-Dist: build123d<0.11,>=0.9.0; python_full_version < '3.13'
689
689
  Requires-Dist: build123d<0.12,>=0.11; python_full_version >= '3.13'
690
690
  Requires-Dist: cadquery-ocp-novtk!=7.9.3.1.1; python_full_version >= '3.13'
@@ -4,6 +4,76 @@
4
4
  are documented here because they are part of normal use even though their Python names begin
5
5
  with an underscore.
6
6
 
7
+ ## Projection convention
8
+
9
+ Use `Sheet(part, projection="first")` or `build_drawing(part, projection="first")`
10
+ for first-angle layout and its matching projection symbol. The CLI equivalent is
11
+ `--projection first`. Explicit `"third"` selects third-angle layout and its symbol;
12
+ omitting `projection` keeps third-angle layout without a symbol.
13
+
14
+ View names retain their physical viewing directions in the working part frame. Changing
15
+ convention changes sheet relationships, not which side of the part a name shows:
16
+
17
+ | View | Viewed from | Page directions | Third-angle position | First-angle position |
18
+ |---|---|---|---|---|
19
+ | `front` | Negative Y | X right, Z up | Reference | Reference |
20
+ | `plan` | Positive Z | X right, Y up | Above front | Below front |
21
+ | `side` | Positive X | Y right, Z up | Right of front | Left of front |
22
+
23
+ The resolved convention is available as `drawing.view_plan.convention`. Generated scripts
24
+ retain the requested convention. Annotation footprints, scale/page selection and measured
25
+ repacking use the same convention. An authored relation contradicting the principal layout
26
+ fails before projection; a whole-view pin must preserve the convention's relationships.
27
+
28
+ ## Dimension text style
29
+
30
+ Position and reading direction are independent drawing-wide settings:
31
+
32
+ ```python
33
+ sheet = Sheet(part, text_position="above", text_orientation="horizontal")
34
+ # Declare features and dimensions as usual, then build.
35
+ drawing = sheet.build()
36
+ ```
37
+
38
+ `text_position="inline"` (the default) leaves a gap for the value in the dimension
39
+ line; `"above"` keeps the line continuous and offsets the full value and tolerance.
40
+ For angular dimensions, above means outside the arc. `text_orientation="aligned"`
41
+ (the default) follows the dimension line or arc tangent; `"horizontal"` keeps text
42
+ horizontal on the sheet. An aligned vertical value reads from the right. Short
43
+ spans use outside arrows while retaining their complete text.
44
+
45
+ The same options are accepted by `build_drawing()`, `make_drawing()`,
46
+ `emit_sheet_script()` and `generate_sheet_script()`. The CLI flags are
47
+ `--text-position` and `--text-orientation`. Generated scripts retain these settings;
48
+ SVG, PDF and DXF export the same resolved ink. Unsupported values raise `ValueError`.
49
+ The choices affect rendering and its placement footprint, not feature measurements
50
+ or tolerances. These are explicit rendering choices, not a claim of standards conformity.
51
+
52
+ ## Through-hole wording
53
+
54
+ The optional argument to a hole handle's `through()` controls its printed indicator:
55
+
56
+ ```python
57
+ hole.through() # default THRU
58
+ hole.through("THRU") # explicit wording
59
+ hole.through("") # omit the printed indicator
60
+ hole.through("THROUGH ALL") # alternative wording
61
+ ```
62
+
63
+ Each declares a through hole and clears any blind depth. Diameter, tolerances, fits and
64
+ measurement identities remain unchanged. The empty string is an explicit display omission;
65
+ it remains visible in the suppression ledger and does not count as a printed through
66
+ qualifier. `.depth(4)` makes the hole blind and clears the override; a later `.through()`
67
+ returns to the default.
68
+
69
+ The override is also accepted as `through_indicator=` by `Sheet.hole()` and the IR `hole()`
70
+ constructor, including pattern members. Generated scripts preserve the difference between
71
+ no override, explicit default wording and an empty string. Callouts and hole tables measure
72
+ the selected wording before placement. Compatible holes can share a callout when their
73
+ resolved wording, machining specifications and placement constraints agree; original feature
74
+ owners and measurement identities remain separate. Removing one owner of a shared callout
75
+ rebuilds the survivors through the placement solver.
76
+
7
77
  ## Grooves on coaxial bodies
8
78
 
9
79
  When different turned bodies share an axis line, give their steps distinct `profile_group`
@@ -245,6 +315,30 @@ detail = s.detail_view("B", around=hole).scale(2)
245
315
  dwg = s.build()
246
316
  ```
247
317
 
318
+ Rear views are explicitly requested. `s.view("rear")` includes rear in an authored
319
+ view set; `s.auto_views().add_view("rear")` adds it to the automatic baseline.
320
+ Rear looks toward the part from +Y with Z upward, so increasing world X runs left
321
+ on the page. This physical direction is the same under both projection conventions.
322
+ When side is also present, rear sits beyond side in the unfolding direction: left
323
+ for first-angle, right for third-angle.
324
+
325
+ Y-axis hole and hole-pattern callouts, locations and pitch dimensions can use rear,
326
+ as can overall width and height. For example:
327
+
328
+ ```python
329
+ s = Sheet(part, projection="first").authored_dimensions()
330
+ hole = s.hole(diameter=6, at=(10, 20, 5), axis="y").through("THRU")
331
+ s.dimension(hole, "bore.diameter")
332
+ s.dimension(hole, "location")
333
+ s.view("rear")
334
+ drawing = s.build()
335
+ ```
336
+
337
+ Dimensions still use the shared placement solve. An unsupported measurement/view
338
+ combination is refused; a required depth extent, for example, needs side. Rear is
339
+ never added automatically to improve visibility, coverage or hidden lines. Generated
340
+ scripts preserve an explicit rear request.
341
+
248
342
  `view(...)`, `section_view(...)` and `detail_view(...)` define complete authored sets;
249
343
  omission suppresses a view. `add_view(...)`, `add_section_view(...)` and
250
344
  `add_detail_view(...)` augment an explicitly selected `auto_views()` source. `row(...)` and
@@ -403,7 +497,7 @@ geometry cannot prove a complete chain or the provider aggregate's Fillet preced
403
497
  referential `DimensionIntent`. The handle never carries a replacement nominal and never chooses
404
498
  page coordinates. Use `format(decimals=n)` to preserve between 0 and 15 decimal places in the
405
499
  printed nominal while reconciliation, tolerance, suppression and provenance continue to read the
406
- numeric parameter from the feature. Optional `view="front|plan|side"` and
500
+ numeric parameter from the feature. Optional `view="front|plan|side|rear"` and
407
501
  `side="above|below|left|right"` arguments select a supported semantic corridor when authored
408
502
  routing must override the derived default; the normal placement solve still chooses coordinates
409
503
  and reports capacity/crossing failures. Trailing zeroes are intentional manufacturing display text:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.23"
7
+ version = "0.4.25"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -22,7 +22,7 @@ dependencies = [
22
22
  # This novtk release lacks OCP.GccEnt on macOS. The exclusion must reach
23
23
  # published wheels, not only uv's development resolver constraints.
24
24
  "cadquery-ocp-novtk!=7.9.3.1.1 ; python_full_version >= '3.13'",
25
- "build123d-drafting-helpers>=0.14.2",
25
+ "build123d-drafting-helpers>=0.15.1",
26
26
  "quiddity==0.2.6",
27
27
  "numpy>=1.24",
28
28
  # PNG raster export (SVG→PDF→PNG). Both permissively licensed (Pillow HPND; pypdfium2
@@ -20,6 +20,7 @@ import re
20
20
  from bisect import bisect_left, bisect_right
21
21
  from collections.abc import Callable
22
22
  from dataclasses import dataclass
23
+ from decimal import Decimal
23
24
  from pathlib import Path
24
25
  from types import SimpleNamespace
25
26
  from typing import TYPE_CHECKING, Literal
@@ -33,6 +34,7 @@ if TYPE_CHECKING:
33
34
 
34
35
  from build123d import (
35
36
  Align,
37
+ ArrowHead,
36
38
  BoundBox,
37
39
  Compound,
38
40
  Edge,
@@ -174,6 +176,24 @@ _TB_CLEAR = _MARGIN + 1.0 # title-block inset: one extra mm over _MARGIN for cl
174
176
  _FONT_SIZE = 3.0 # annotation text height (page-mm); the draft preset is built with this
175
177
 
176
178
 
179
+ def _dimension_draft(text_position="inline", text_orientation="aligned"):
180
+ """One fixed typography preset, with helper-owned validation of text style."""
181
+ return draft_preset(
182
+ font_size=_FONT_SIZE,
183
+ decimal_precision=1,
184
+ font_path=PLEX_MONO,
185
+ text_position=text_position,
186
+ text_orientation=text_orientation,
187
+ )
188
+
189
+
190
+ @functools.lru_cache(maxsize=128)
191
+ def _dimension_head_bounds(arrow_length, head_type):
192
+ """Measure each fixed-size arrow style once, before candidate evaluation."""
193
+ box = ArrowHead(arrow_length, head_type=head_type, mode=Mode.PRIVATE).bounding_box()
194
+ return box.min.X, box.min.Y, box.max.X, box.max.Y
195
+
196
+
177
197
  _TB_H = 35.0
178
198
 
179
199
 
@@ -321,9 +341,9 @@ def _build_table(rows, draft, block_cols=None):
321
341
 
322
342
  def _tol_suffix(tolerance, draft) -> str:
323
343
  """The ``±`` / limit tolerance suffix to append to a **callout** label (a ø leader
324
- or a hole callout), matching byte-for-byte what ``Dimension(tolerance=…)`` renders
325
- on a linear dim (helpers ``_format_label``): a symmetric ``float`` → ``" ±t"``; an
326
- ``(lower, upper)`` pair ``" +upper -lower"`` — all rounded to the draft precision.
344
+ or a hole callout): a symmetric ``float`` ``" ±t"``; an ``(lower, upper)`` pair
345
+ ``" +upper -lower"``. Draft precision is a minimum; supplied tolerance
346
+ magnitudes must never be rounded into different engineering requirements.
327
347
 
328
348
  draftwright owns this suffix ONLY because the pinned helpers' ``Leader`` /
329
349
  ``HoleCallout`` take no ``tolerance=`` yet, so we bake it into the label string
@@ -336,11 +356,16 @@ def _tol_suffix(tolerance, draft) -> str:
336
356
  return ""
337
357
  if isinstance(tolerance, FitClass):
338
358
  return tolerance.suffix()
339
- prec = draft.decimal_precision
359
+
360
+ def magnitude(value):
361
+ decimal = Decimal(str(value))
362
+ precision = max(draft.decimal_precision, -int(decimal.as_tuple().exponent))
363
+ return f"{decimal:.{precision}f}"
364
+
340
365
  if isinstance(tolerance, (int, float)):
341
- return f" ±{round(tolerance, prec):.{prec}f}"
366
+ return f" ±{magnitude(tolerance)}"
342
367
  lo, hi = tolerance
343
- return f" +{round(hi, prec):.{prec}f} -{round(lo, prec):.{prec}f}"
368
+ return f" +{magnitude(hi)} -{magnitude(lo)}"
344
369
 
345
370
 
346
371
  def _tag_sequence(n):
@@ -963,14 +988,14 @@ class DetailRequest:
963
988
  class _Projector:
964
989
  """Model → page coordinate projection for the orthographic views.
965
990
 
966
- Each in-plane view axis projects as ``origin + (value - centroid) * scale``.
991
+ Each in-plane view axis projects from its centroid and page origin. Rear
992
+ reverses model X while keeping Z up, matching its camera from positive Y.
967
993
  Built once in :func:`_analyse` and hung off the analysis namespace as
968
994
  ``a.proj`` so the annotation passes share one projector instead of each
969
995
  re-deriving the ``FX``/``FZ``/``SX``/``SZ``/``PX``/``PY`` closures.
970
996
 
971
- This deliberately mirrors those analysis-phase closures byte-for-byte (an
972
- unsigned ``+1`` projection), so the consolidation is provably
973
- behaviour-preserving. The helpers library's ``ViewCoordinates.px``/``.py``
997
+ The original three views retain their analysis-phase ``+1`` closures.
998
+ The helpers library's ``ViewCoordinates.px``/``.py``
974
999
  (already built per view as ``dwg._coords``) computes a *signed* projection
975
1000
  from ``view_axes()``; routing through it would couple the annotation passes
976
1001
  to render-order ``_coords`` population and could change output where a view
@@ -992,6 +1017,8 @@ class _Projector:
992
1017
  cy: float
993
1018
  cz: float
994
1019
  scale: float
1020
+ rv_x: float = 0.0
1021
+ rv_y: float = 0.0
995
1022
 
996
1023
  def front_x(self, x: float) -> float:
997
1024
  return self.fv_x + (x - self.cx) * self.scale
@@ -1011,6 +1038,12 @@ class _Projector:
1011
1038
  def plan_y(self, y: float) -> float:
1012
1039
  return self.pv_y + (y - self.cy) * self.scale
1013
1040
 
1041
+ def rear_x(self, x: float) -> float:
1042
+ return self.rv_x - (x - self.cx) * self.scale
1043
+
1044
+ def rear_z(self, z: float) -> float:
1045
+ return self.rv_y + (z - self.cz) * self.scale
1046
+
1014
1047
 
1015
1048
  @dataclass(frozen=True)
1016
1049
  class LayoutFrame:
@@ -1042,6 +1075,8 @@ class LayoutFrame:
1042
1075
  fv_zones: ViewZones
1043
1076
  pv_zones: ViewZones
1044
1077
  sv_zones: ViewZones
1078
+ rear: tuple[float, float, float, float] | None = None
1079
+ rv_zones: ViewZones | None = None
1045
1080
 
1046
1081
  def project(self, view: str, point) -> tuple[float, float]:
1047
1082
  """A part-space *point* in *view*'s page coordinates."""
@@ -1052,6 +1087,8 @@ class LayoutFrame:
1052
1087
  return self.proj.side_x(y), self.proj.side_z(z)
1053
1088
  if view == "plan":
1054
1089
  return self.proj.plan_x(x), self.proj.plan_y(y)
1090
+ if view == "rear" and self.rear is not None:
1091
+ return self.proj.rear_x(x), self.proj.rear_z(z)
1055
1092
  raise ValueError(f"unknown view {view!r}")
1056
1093
 
1057
1094
  def edges(self, view: str) -> tuple[float, float, float, float]:
@@ -1060,11 +1097,24 @@ class LayoutFrame:
1060
1097
  The stored endpoints come from projected world minima/maxima, whose handedness
1061
1098
  need not match page left/right. Normalise here so callers can rely on the names
1062
1099
  this API exposes rather than knowing projector orientation."""
1063
- x0, x1, y0, y1 = {"front": self.front, "plan": self.plan, "side": self.side}[view]
1100
+ bounds = {"front": self.front, "plan": self.plan, "side": self.side, "rear": self.rear}[
1101
+ view
1102
+ ]
1103
+ if bounds is None:
1104
+ raise ValueError(f"view {view!r} has no planned layout frame")
1105
+ x0, x1, y0, y1 = bounds
1064
1106
  return min(x0, x1), max(x0, x1), min(y0, y1), max(y0, y1)
1065
1107
 
1066
1108
  def zones(self, view: str) -> ViewZones:
1067
- return {"front": self.fv_zones, "plan": self.pv_zones, "side": self.sv_zones}[view]
1109
+ zones = {
1110
+ "front": self.fv_zones,
1111
+ "plan": self.pv_zones,
1112
+ "side": self.sv_zones,
1113
+ "rear": self.rv_zones,
1114
+ }[view]
1115
+ if zones is None:
1116
+ raise ValueError(f"view {view!r} has no planned annotation zones")
1117
+ return zones
1068
1118
 
1069
1119
 
1070
1120
  def layout_frame(a: Analysis) -> LayoutFrame:
@@ -1099,6 +1149,15 @@ def layout_frame(a: Analysis) -> LayoutFrame:
1099
1149
  fv_zones=a.fv_zones,
1100
1150
  pv_zones=a.pv_zones,
1101
1151
  sv_zones=a.sv_zones,
1152
+ rear=(
1153
+ a.proj.rear_x(a.bb.min.X),
1154
+ a.proj.rear_x(a.bb.max.X),
1155
+ a.proj.rear_z(a.bb.min.Z),
1156
+ a.proj.rear_z(a.bb.max.Z),
1157
+ )
1158
+ if a.rv_zones is not None
1159
+ else None,
1160
+ rv_zones=a.rv_zones,
1102
1161
  )
1103
1162
 
1104
1163
 
@@ -1210,6 +1269,9 @@ class Analysis:
1210
1269
  frame: bool = False
1211
1270
  # Projection-method symbol (#769): "third" / "first" (ISO 5456-2) or None (omit).
1212
1271
  projection: str | None = None
1272
+ projection_convention: str = "third"
1273
+ text_position: str = "inline"
1274
+ text_orientation: str = "aligned"
1213
1275
  # Draw the ISO 5457 zone-grid border ruler (#768). Implies a frame (the ticks sit on it).
1214
1276
  zones: bool = False
1215
1277
  # The PartModel built by _analyse's pre-scale sizing pass (#584 WP1 A) — stored so
@@ -1260,6 +1322,9 @@ class Analysis:
1260
1322
  #: Coordinate-coherent PMI projection used by the compiler. ``None`` means the source
1261
1323
  #: report's records are already in working coordinates (raw and declared builds).
1262
1324
  pmi_working_records: tuple[object, ...] | None = None
1325
+ RV_X: float = 0.0
1326
+ RV_Y: float = 0.0
1327
+ rv_zones: ViewZones | None = None
1263
1328
 
1264
1329
  @property
1265
1330
  def pmi(self) -> list:
@@ -23,6 +23,9 @@ from quiddity import full_cylinders
23
23
 
24
24
  _log = logging.getLogger(__name__)
25
25
 
26
+ # Ignore floating-point noise at rectangle boundaries, never visible overflow.
27
+ BOUNDS_ROUNDOFF = 1e-9
28
+
26
29
  # Axis letter -> the orthographic view a feature on that axis reads end-on in: a z-hole is
27
30
  # a circle in plan, an x-channel is a cross-section in side.
28
31
  #
@@ -18,7 +18,6 @@ from dataclasses import dataclass, replace
18
18
  from typing import cast
19
19
 
20
20
  from build123d import Compound, Shape
21
- from build123d_drafting.helpers import draft_preset
22
21
  from OCP.IFSelect import IFSelect_ReturnStatus
23
22
  from OCP.STEPControl import STEPControl_Reader
24
23
  from quiddity import (
@@ -41,6 +40,7 @@ from draftwright._core import (
41
40
  _MIN_VIEW_MM,
42
41
  Analysis,
43
42
  _content_margin,
43
+ _dimension_draft,
44
44
  _legible_steps,
45
45
  _Projector,
46
46
  )
@@ -53,6 +53,7 @@ from draftwright._geometry import (
53
53
  )
54
54
  from draftwright.compose import (
55
55
  StripDepths,
56
+ _build_rear_zones,
56
57
  _build_zones,
57
58
  _est_hole_table_sizes,
58
59
  _est_planned_bore_callout_width,
@@ -71,7 +72,12 @@ from draftwright.recognition_frame import (
71
72
  require_unambiguous_groove_owner,
72
73
  )
73
74
  from draftwright.recognition_ownership import RecognitionOwnershipBuilder
74
- from draftwright.view_plan import ViewConstraints, arrangement_of
75
+ from draftwright.view_plan import (
76
+ ViewConstraints,
77
+ arrangement_of,
78
+ principal_placements,
79
+ third_angle_view_names,
80
+ )
75
81
 
76
82
  _log = logging.getLogger(__name__)
77
83
 
@@ -132,15 +138,18 @@ def _apply_principal_view_pins(
132
138
  "plan": (geometry.PV_X, geometry.PV_Y),
133
139
  "side": (geometry.SV_X, geometry.SV_Y),
134
140
  }
141
+ if "rear" in planned:
142
+ centres["rear"] = (geometry.RV_X, geometry.RV_Y)
135
143
  cx, cy, cz = centre
136
144
  projected_centre = {
137
145
  "front": (cx * scale, cz * scale),
138
146
  "plan": (cx * scale, cy * scale),
139
147
  "side": (cy * scale, cz * scale),
148
+ "rear": (-cx * scale, cz * scale),
140
149
  }
141
150
  translations = []
142
151
  for pin in constraints.pins:
143
- if pin.view not in centres:
152
+ if pin.view not in projected_centre:
144
153
  where = f" at {pin.source}" if pin.source is not None else ""
145
154
  raise ValueError(
146
155
  f"whole-view pin{where} targets {pin.view!r}; this slice can anchor principal "
@@ -159,7 +168,7 @@ def _apply_principal_view_pins(
159
168
  if max(abs(other_dx - dx), abs(other_dy - dy)) > 0.05:
160
169
  raise ValueError(
161
170
  f"whole-view pins at {first.source} and {pin.source} contradict the fixed "
162
- "third-angle relationships; they imply different group translations"
171
+ f"{geometry.convention}-angle relationships; they imply different group translations"
163
172
  )
164
173
 
165
174
  geometry.FV_X += dx
@@ -168,9 +177,13 @@ def _apply_principal_view_pins(
168
177
  geometry.PV_Y += dy
169
178
  geometry.SV_X += dx
170
179
  geometry.SV_Y += dy
180
+ if "rear" in planned:
181
+ geometry.RV_X += dx
182
+ geometry.RV_Y += dy
171
183
  geometry.sv_geometry_right += dx
172
184
  geometry.sv_right += dx
173
185
  geometry.sv_right_wall += dx
186
+ geometry.front_plan_wall += dy
174
187
  # Geometry bounds are the minimum pre-projection feasibility gate. Annotation bands use
175
188
  # the shifted anchors below and remain subject to the ordinary completeness/lint gates.
176
189
  extents = {
@@ -178,6 +191,8 @@ def _apply_principal_view_pins(
178
191
  "plan": (geometry.PV_X, geometry.PV_Y, geometry.fv_hw, geometry.pv_hh),
179
192
  "side": (geometry.SV_X, geometry.SV_Y, geometry.sv_hw, geometry.fv_hh),
180
193
  }
194
+ if "rear" in planned:
195
+ extents["rear"] = (geometry.RV_X, geometry.RV_Y, geometry.fv_hw, geometry.fv_hh)
181
196
  page_w, page_h = page
182
197
  for name in planned:
183
198
  x, y, hw, hh = extents[name]
@@ -680,6 +695,7 @@ def _validate_explicit_scale(
680
695
  views: tuple[str, ...] | None = None,
681
696
  include_iso: bool = True,
682
697
  iso_scale_factor: float | None = None,
698
+ convention: str = "third",
683
699
  ) -> None:
684
700
  """Enforce the two scale floors when the caller pinned an explicit *scale* (#489, #590 split
685
701
  of :func:`_analyse`). An explicit scale is the user's call — honour it, subject to:
@@ -719,6 +735,7 @@ def _validate_explicit_scale(
719
735
  views=views,
720
736
  include_iso=include_iso,
721
737
  iso_scale_factor=iso_scale_factor,
738
+ convention=convention,
722
739
  )
723
740
  # Warn only when omitting the scale would truly give a legible fit (auto scale itself is
724
741
  # legible) but the requested scale is below the floor. A part illegible at every
@@ -753,12 +770,15 @@ def _analyse(
753
770
  model=None,
754
771
  decorations=None,
755
772
  authored=None,
773
+ requested=None,
756
774
  material="",
757
775
  date="",
758
776
  revision="A",
759
777
  company="",
760
778
  frame: bool = False,
761
779
  projection: str | None = None,
780
+ text_position: str = "inline",
781
+ text_orientation: str = "aligned",
762
782
  zones: bool = False,
763
783
  _reuse: Analysis | None = None,
764
784
  _required_tables=(),
@@ -772,6 +792,7 @@ def _analyse(
772
792
 
773
793
  Returns an :class:`Analysis`.
774
794
  """
795
+ convention = projection or "third"
775
796
  # The zone-grid ruler (#768) draws its ticks on the frame, so it implies one.
776
797
  frame = frame or zones
777
798
  # The content margin — raised by the sheet-frame band (#767) so scale/page selection and
@@ -986,7 +1007,7 @@ def _analyse(
986
1007
  # Construct the same draft preset used later in build_drawing() to read
987
1008
  # arrow_length and pad_around_text from their authoritative source rather
988
1009
  # than re-stating them as magic literals in the estimators.
989
- _draft_est = draft_preset(font_size=_FONT_SIZE, decimal_precision=1)
1010
+ _draft_est = _dimension_draft(text_position, text_orientation)
990
1011
  _arrow_length = _draft_est.arrow_length
991
1012
  _pad_around_text = _draft_est.pad_around_text
992
1013
  # Empty on the declared path — NOT "this part has no holes", but "nothing was detected".
@@ -1078,21 +1099,23 @@ def _analyse(
1078
1099
  if ownership_builder is not None
1079
1100
  else None
1080
1101
  )
1081
- # Authored omission affects annotation FOOTPRINT sizing, but the analysis model retains
1082
- # its historical automatic requirement inventory for view-feasibility preflight. The
1083
- # builder applies the same authored tuple to the render model later. Keeping this as a
1084
- # strip-only copy avoids letting a sparse authored dimension set erase semantic view
1085
- # requirements (for example the parent view needed by an authored detail), while ensuring
1086
- # suppressed pad bands cannot reduce the selected scale (#1392).
1087
- strip_sizing_model = (
1088
- replace(sizing_model, authored_dimensions=tuple(authored))
1102
+ # Dimension feasibility and annotation footprints consume the authored set.
1103
+ # Derived-view dependencies still use sizing_model below; omitting an unrelated
1104
+ # envelope extent must not force its view back onto an authored sheet.
1105
+ strip_sizing_model = replace(
1106
+ sizing_model,
1107
+ authored_dimensions=tuple(authored)
1089
1108
  if authored is not None
1090
- else sizing_model
1109
+ else sizing_model.authored_dimensions,
1110
+ requested_dimensions=tuple(requested) if requested else sizing_model.requested_dimensions,
1091
1111
  )
1092
1112
  # ADR 2 (was 0018) Phase 5.5: prove the chosen principal set can carry every approved
1093
1113
  # dimension before scale selection or projection. A reduced view set is therefore a
1094
1114
  # re-plan, not the fixed three-view plan rendered into fewer views.
1095
- sizing_groups = plan_dimensions(sizing_model, planned_views=_views)
1115
+ sizing_groups = plan_dimensions(
1116
+ strip_sizing_model,
1117
+ planned_views=third_angle_view_names() if _views is None else _views,
1118
+ )
1096
1119
  bore_callout_width = _est_planned_bore_callout_width(
1097
1120
  sizing_groups, _draft_est, font_size=_FONT_SIZE, pad_around_text=_pad_around_text
1098
1121
  )
@@ -1126,6 +1149,8 @@ def _analyse(
1126
1149
  arrow_length=_arrow_length,
1127
1150
  pad_around_text=_pad_around_text,
1128
1151
  bore_callout_width=bore_callout_width,
1152
+ text_position=text_position,
1153
+ text_orientation=text_orientation,
1129
1154
  )
1130
1155
 
1131
1156
  layout_advisories: list[tuple[str, str]] = []
@@ -1149,6 +1174,7 @@ def _analyse(
1149
1174
  views=_views,
1150
1175
  include_iso=_include_iso,
1151
1176
  iso_scale_factor=planned_iso_scale,
1177
+ convention=convention,
1152
1178
  )
1153
1179
 
1154
1180
  scale_pick, strips_i, n_for_sizing = _converge_step_sizing(
@@ -1181,6 +1207,7 @@ def _analyse(
1181
1207
  views=_views,
1182
1208
  include_iso=_include_iso,
1183
1209
  iso_scale_factor=planned_iso_scale,
1210
+ convention=convention,
1184
1211
  )
1185
1212
  DIM_PAD = _DIM_PAD
1186
1213
  # margin was computed up front (_content_margin(frame)) so scale selection already saw it.
@@ -1215,6 +1242,7 @@ def _analyse(
1215
1242
  views=_views,
1216
1243
  include_iso=_include_iso,
1217
1244
  iso_scale_factor=planned_iso_scale,
1245
+ convention=convention,
1218
1246
  )
1219
1247
  _apply_principal_view_pins(
1220
1248
  _g,
@@ -1225,6 +1253,13 @@ def _analyse(
1225
1253
  margin=margin,
1226
1254
  views=_views,
1227
1255
  )
1256
+ if isinstance(_view_constraints, ViewConstraints):
1257
+ places = principal_placements(_g)
1258
+ for relation in _view_constraints.relations:
1259
+ if relation.subject in _g.planned_views and relation.reference in _g.planned_views:
1260
+ relation.validate(
1261
+ places[relation.subject].bounds, places[relation.reference].bounds
1262
+ )
1228
1263
  fv_hw = _g.fv_hw
1229
1264
  fv_hh = _g.fv_hh
1230
1265
  pv_hh = _g.pv_hh
@@ -1275,6 +1310,9 @@ def _analyse(
1275
1310
  arrangement=ARRANGEMENT,
1276
1311
  planned_views=_views,
1277
1312
  planned_iso=_include_iso,
1313
+ RV_X=_g.RV_X,
1314
+ RV_Y=_g.RV_Y,
1315
+ rv_zones=_build_rear_zones(_g, margin, PAGE_H),
1278
1316
  planned_iso_scale=planned_iso_scale,
1279
1317
  view_constraints=_view_constraints,
1280
1318
  part=part,
@@ -1336,6 +1374,8 @@ def _analyse(
1336
1374
  sv_y=SV_Y,
1337
1375
  pv_x=PV_X,
1338
1376
  pv_y=PV_Y,
1377
+ rv_x=_g.RV_X,
1378
+ rv_y=_g.RV_Y,
1339
1379
  cx=cx,
1340
1380
  cy=cy,
1341
1381
  cz=cz,
@@ -1366,6 +1406,9 @@ def _analyse(
1366
1406
  company=company,
1367
1407
  frame=frame,
1368
1408
  projection=projection,
1409
+ text_position=text_position,
1410
+ text_orientation=text_orientation,
1411
+ projection_convention=convention,
1369
1412
  zones=zones,
1370
1413
  out=out,
1371
1414
  pmi_report=pmi_report,