simplecadapi 2.0.7__tar.gz → 2.0.8__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 (246) hide show
  1. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/PKG-INFO +3 -3
  2. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/README.md +2 -2
  3. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/union_rsolidlist.md +26 -4
  4. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/pyproject.toml +1 -1
  5. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/SKILL.md +3 -3
  6. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/PROJECT_OVERVIEW.md +2 -2
  7. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/PROJECT_README.md +2 -2
  8. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/RUNTIME_INSTALL.md +1 -1
  9. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/union_rsolidlist.md +26 -4
  10. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/install.sh +2 -2
  11. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/repl_bootstrap.py +1 -1
  12. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/skill_pack.py +6 -3
  13. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/operations.py +135 -55
  14. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_all_features.py +41 -2
  15. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/uv.lock +1 -1
  16. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/.gitignore +0 -0
  17. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/.python-version +0 -0
  18. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/LICENSE +0 -0
  19. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/MANIFEST.in +0 -0
  20. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/README.md +0 -0
  21. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/add_part_rassembly.md +0 -0
  22. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/and_.md +0 -0
  23. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/bounds_rbbox.md +0 -0
  24. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/chamfer_rsolid.md +0 -0
  25. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/clear_constraints_rassembly.md +0 -0
  26. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/clone_assembly_rassembly.md +0 -0
  27. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_coincident_rassembly.md +0 -0
  28. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_concentric_rassembly.md +0 -0
  29. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_distance_rassembly.md +0 -0
  30. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_offset_rassembly.md +0 -0
  31. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/cut_rsolidlist.md +0 -0
  32. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/eval_rarray.md +0 -0
  33. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/eval_rscalar.md +0 -0
  34. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/export_step.md +0 -0
  35. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/export_stl.md +0 -0
  36. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/extrude_rsolid.md +0 -0
  37. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/fillet_rsolid.md +0 -0
  38. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/geo.md +0 -0
  39. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/helical_sweep_rsolid.md +0 -0
  40. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/intersect_rscalarfield.md +0 -0
  41. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/intersect_rsolidlist.md +0 -0
  42. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/linear_pattern_rsolidlist.md +0 -0
  43. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/loft_rsolid.md +0 -0
  44. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_angle_arc_redge.md +0 -0
  45. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_angle_arc_rwire.md +0 -0
  46. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_assembly_rassembly.md +0 -0
  47. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_box_rscalarfield.md +0 -0
  48. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_box_rsolid.md +0 -0
  49. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_capsule_rscalarfield.md +0 -0
  50. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_circle_redge.md +0 -0
  51. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_circle_rface.md +0 -0
  52. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_circle_rwire.md +0 -0
  53. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_cone_rsolid.md +0 -0
  54. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_cylinder_rsolid.md +0 -0
  55. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_ellipsoid_rscalarfield.md +0 -0
  56. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_face_from_wire_rface.md +0 -0
  57. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_field_surface_rsolid.md +0 -0
  58. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_helix_redge.md +0 -0
  59. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_helix_rwire.md +0 -0
  60. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_line_redge.md +0 -0
  61. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_n_hole_flange_rsolid.md +0 -0
  62. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_naca_propeller_blade_rsolid.md +0 -0
  63. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_point_rvertex.md +0 -0
  64. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_polyline_rwire.md +0 -0
  65. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_rectangle_rface.md +0 -0
  66. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_rectangle_rwire.md +0 -0
  67. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_segment_redge.md +0 -0
  68. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_segment_rwire.md +0 -0
  69. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_sphere_rscalarfield.md +0 -0
  70. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_sphere_rsolid.md +0 -0
  71. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_spline_redge.md +0 -0
  72. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_spline_rwire.md +0 -0
  73. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_threaded_rod_rsolid.md +0 -0
  74. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_three_point_arc_redge.md +0 -0
  75. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_three_point_arc_rwire.md +0 -0
  76. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_wire_from_edges_rwire.md +0 -0
  77. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/meta.md +0 -0
  78. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/mirror_shape.md +0 -0
  79. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/not_.md +0 -0
  80. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/or_.md +0 -0
  81. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/radial_pattern_rsolidlist.md +0 -0
  82. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/render_screenshot_rpath.md +0 -0
  83. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/revolve_rsolid.md +0 -0
  84. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/rotate_part_rassembly.md +0 -0
  85. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/rotate_rscalarfield.md +0 -0
  86. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/rotate_shape.md +0 -0
  87. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/scale_rscalarfield.md +0 -0
  88. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/select.md +0 -0
  89. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/select_edges_by_tag.md +0 -0
  90. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/select_faces_by_tag.md +0 -0
  91. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/set_tag.md +0 -0
  92. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/shell_rsolid.md +0 -0
  93. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/smooth_subtract_rscalarfield.md +0 -0
  94. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/smooth_union_rscalarfield.md +0 -0
  95. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/solve_assembly_rresult.md +0 -0
  96. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/stack.md +0 -0
  97. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/stack_rassembly.md +0 -0
  98. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/subtract_rscalarfield.md +0 -0
  99. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/sweep_rsolid.md +0 -0
  100. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/tag.md +0 -0
  101. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/translate_part_rassembly.md +0 -0
  102. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/translate_rscalarfield.md +0 -0
  103. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/translate_shape.md +0 -0
  104. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/union_rscalarfield.md +0 -0
  105. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/value.md +0 -0
  106. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/README.md +0 -0
  107. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/compound.md +0 -0
  108. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/coordinate_system.md +0 -0
  109. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/declarative_constraints.md +0 -0
  110. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/edge.md +0 -0
  111. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/face.md +0 -0
  112. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/shell.md +0 -0
  113. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/simple_workplane.md +0 -0
  114. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/solid.md +0 -0
  115. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/tagged_mixin.md +0 -0
  116. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/vertex.md +0 -0
  117. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/wire.md +0 -0
  118. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/examples.py +0 -0
  119. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/refactor-plan/tagging.md +0 -0
  120. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/scripts/publish.sh +0 -0
  121. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/scripts/sync_ragflow_docs.py +0 -0
  122. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/cases/simplecad_self_evolve_cases/__init__.py +0 -0
  123. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/cases/simplecad_self_evolve_cases/evolve.py +0 -0
  124. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/EVOLVE_WORKFLOW.md +0 -0
  125. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/LICENSE.txt +0 -0
  126. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/README.md +0 -0
  127. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/add_part_rassembly.md +0 -0
  128. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/and_.md +0 -0
  129. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/bounds_rbbox.md +0 -0
  130. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/chamfer_rsolid.md +0 -0
  131. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/clear_constraints_rassembly.md +0 -0
  132. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/clone_assembly_rassembly.md +0 -0
  133. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_coincident_rassembly.md +0 -0
  134. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_concentric_rassembly.md +0 -0
  135. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_distance_rassembly.md +0 -0
  136. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_offset_rassembly.md +0 -0
  137. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/cut_rsolidlist.md +0 -0
  138. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/eval_rarray.md +0 -0
  139. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/eval_rscalar.md +0 -0
  140. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/export_step.md +0 -0
  141. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/export_stl.md +0 -0
  142. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/extrude_rsolid.md +0 -0
  143. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/fillet_rsolid.md +0 -0
  144. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/geo.md +0 -0
  145. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/helical_sweep_rsolid.md +0 -0
  146. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/intersect_rscalarfield.md +0 -0
  147. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/intersect_rsolidlist.md +0 -0
  148. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/linear_pattern_rsolidlist.md +0 -0
  149. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/loft_rsolid.md +0 -0
  150. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_angle_arc_redge.md +0 -0
  151. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_angle_arc_rwire.md +0 -0
  152. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_assembly_rassembly.md +0 -0
  153. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_box_rscalarfield.md +0 -0
  154. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_box_rsolid.md +0 -0
  155. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_capsule_rscalarfield.md +0 -0
  156. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_circle_redge.md +0 -0
  157. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_circle_rface.md +0 -0
  158. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_circle_rwire.md +0 -0
  159. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_cone_rsolid.md +0 -0
  160. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_cylinder_rsolid.md +0 -0
  161. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_ellipsoid_rscalarfield.md +0 -0
  162. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_face_from_wire_rface.md +0 -0
  163. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_field_surface_rsolid.md +0 -0
  164. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_helix_redge.md +0 -0
  165. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_helix_rwire.md +0 -0
  166. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_line_redge.md +0 -0
  167. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_n_hole_flange_rsolid.md +0 -0
  168. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_naca_propeller_blade_rsolid.md +0 -0
  169. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_point_rvertex.md +0 -0
  170. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_polyline_rwire.md +0 -0
  171. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_rectangle_rface.md +0 -0
  172. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_rectangle_rwire.md +0 -0
  173. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_segment_redge.md +0 -0
  174. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_segment_rwire.md +0 -0
  175. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_sphere_rscalarfield.md +0 -0
  176. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_sphere_rsolid.md +0 -0
  177. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_spline_redge.md +0 -0
  178. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_spline_rwire.md +0 -0
  179. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_threaded_rod_rsolid.md +0 -0
  180. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_three_point_arc_redge.md +0 -0
  181. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_three_point_arc_rwire.md +0 -0
  182. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_wire_from_edges_rwire.md +0 -0
  183. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/meta.md +0 -0
  184. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/mirror_shape.md +0 -0
  185. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/not_.md +0 -0
  186. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/or_.md +0 -0
  187. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/radial_pattern_rsolidlist.md +0 -0
  188. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/render_screenshot_rpath.md +0 -0
  189. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/revolve_rsolid.md +0 -0
  190. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/rotate_part_rassembly.md +0 -0
  191. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/rotate_rscalarfield.md +0 -0
  192. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/rotate_shape.md +0 -0
  193. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/scale_rscalarfield.md +0 -0
  194. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/select.md +0 -0
  195. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/select_edges_by_tag.md +0 -0
  196. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/select_faces_by_tag.md +0 -0
  197. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/set_tag.md +0 -0
  198. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/shell_rsolid.md +0 -0
  199. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/smooth_subtract_rscalarfield.md +0 -0
  200. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/smooth_union_rscalarfield.md +0 -0
  201. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/solve_assembly_rresult.md +0 -0
  202. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/stack.md +0 -0
  203. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/stack_rassembly.md +0 -0
  204. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/subtract_rscalarfield.md +0 -0
  205. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/sweep_rsolid.md +0 -0
  206. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/tag.md +0 -0
  207. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/translate_part_rassembly.md +0 -0
  208. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/translate_rscalarfield.md +0 -0
  209. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/translate_shape.md +0 -0
  210. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/union_rscalarfield.md +0 -0
  211. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/value.md +0 -0
  212. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/README.md +0 -0
  213. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/compound.md +0 -0
  214. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/coordinate_system.md +0 -0
  215. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/declarative_constraints.md +0 -0
  216. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/edge.md +0 -0
  217. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/face.md +0 -0
  218. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/shell.md +0 -0
  219. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/simple_workplane.md +0 -0
  220. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/solid.md +0 -0
  221. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/tagged_mixin.md +0 -0
  222. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/vertex.md +0 -0
  223. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/wire.md +0 -0
  224. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/add_new_case.sh +0 -0
  225. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/evolve_case.py +0 -0
  226. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/jupyter_with_skill.sh +0 -0
  227. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/validate_skill.sh +0 -0
  228. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/with_skill.sh +0 -0
  229. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/__init__.py +0 -0
  230. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/__init__.py +0 -0
  231. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/auto_docs_gen.py +0 -0
  232. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/evolution.py +0 -0
  233. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/make_export.py +0 -0
  234. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/constraints.py +0 -0
  235. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/core.py +0 -0
  236. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/evolve.py +0 -0
  237. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/field.py +0 -0
  238. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/py.typed +0 -0
  239. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/ql.py +0 -0
  240. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/tagging.py +0 -0
  241. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_auto_docs_gen.py +0 -0
  242. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_field_surface.py +0 -0
  243. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_make_export.py +0 -0
  244. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_ql.py +0 -0
  245. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_skill_pack.py +0 -0
  246. {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_tagging_refactor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simplecadapi
3
- Version: 2.0.7
3
+ Version: 2.0.8
4
4
  Summary: A simplified CAD modeling Python API based on CADQuery
5
5
  Project-URL: Homepage, https://github.com/NiJingzhe/SimpleCADAPI
6
6
  Project-URL: Repository, https://github.com/NiJingzhe/SimpleCADAPI
@@ -385,7 +385,7 @@ Experimental scripts and temporary modeling examples are not included as formal
385
385
 
386
386
  ## Package Installation (Python Package Managers)
387
387
 
388
- Current package name: `simplecadapi`, version: `2.0.7` (see `pyproject.toml`).
388
+ Current package name: `simplecadapi`, version: `2.0.8` (see `pyproject.toml`).
389
389
 
390
390
  ### Method A: Install from package repository with pip
391
391
 
@@ -418,7 +418,7 @@ uv add simplecadapi
418
418
  The repository already contains example build artifacts (`dist/`):
419
419
 
420
420
  ```bash
421
- pip install dist/simplecadapi-2.0.7-py3-none-any.whl
421
+ pip install dist/simplecadapi-2.0.8-py3-none-any.whl
422
422
  ```
423
423
 
424
424
  If you need to rebuild:
@@ -9,7 +9,7 @@ Experimental scripts and temporary modeling examples are not included as formal
9
9
 
10
10
  ## Package Installation (Python Package Managers)
11
11
 
12
- Current package name: `simplecadapi`, version: `2.0.7` (see `pyproject.toml`).
12
+ Current package name: `simplecadapi`, version: `2.0.8` (see `pyproject.toml`).
13
13
 
14
14
  ### Method A: Install from package repository with pip
15
15
 
@@ -42,7 +42,7 @@ uv add simplecadapi
42
42
  The repository already contains example build artifacts (`dist/`):
43
43
 
44
44
  ```bash
45
- pip install dist/simplecadapi-2.0.7-py3-none-any.whl
45
+ pip install dist/simplecadapi-2.0.8-py3-none-any.whl
46
46
  ```
47
47
 
48
48
  If you need to rebuild:
@@ -3,7 +3,12 @@
3
3
  ## API Definition
4
4
 
5
5
  ```python
6
- def union_rsolidlist(*solids: Union[Solid, Sequence[Solid]]) -> List[Solid]
6
+ def union_rsolidlist(
7
+ *solids: Union[Solid, Sequence[Solid]],
8
+ clean: bool = True,
9
+ glue: bool = True,
10
+ tol: Optional[float] = None,
11
+ ) -> List[Solid]
7
12
  ```
8
13
 
9
14
  *Source: operations.py*
@@ -15,13 +20,18 @@ Compute the boolean union of one or more solids.
15
20
  All boolean operations (union/cut/intersect) accept a mix of Solid and
16
21
  sequences; results are always returned as a list of Solid.
17
22
  Keep the list result unless you have explicitly verified `len(result) == 1`.
23
+ SimpleCAD enables glue mode by default and applies a conservative internal fuzzy
24
+ tolerance, so normal modeling code does not need to tune boolean parameters.
25
+ By default this follows CadQuery's union flow: perform one OCC fuse across the
26
+ input solids, then call `clean()` to unify same-domain faces when possible.
18
27
  Touching-but-not-intersecting inputs can legitimately return multiple solids.
19
28
  If that happens, keep using the list: pass it directly into later union calls,
20
29
  or iterate over the solids for later cut/intersect steps.
30
+ When the returned solids are still separated by more than the active tolerance,
31
+ SimpleCAD prints a stdout warning explaining that the objects do not touch and
32
+ that their gap exceeds `tol`.
21
33
  If you truly need exactly one merged solid, you must check the list length
22
- before using `result[0]`. When the length is not 1, do not pick an element
23
- arbitrarily; instead, adjust part placement so the solids overlap slightly,
24
- then run the union again.
34
+ before using `result[0]`.
25
35
 
26
36
  ## Parameters
27
37
 
@@ -29,6 +39,18 @@ then run the union again.
29
39
 
30
40
  - **Description**: One or more Solid objects or sequences of Solid. Nested sequences are flattened before processing.
31
41
 
42
+ ### clean
43
+
44
+ - **Description**: Call CadQuery's `clean()` after the union to remove splitter edges and unify same-domain faces when possible.
45
+
46
+ ### glue
47
+
48
+ - **Description**: Enable OCC glue mode for touching or partially overlapping inputs. Defaults to `True` for SimpleCAD's standard union behavior.
49
+
50
+ ### tol
51
+
52
+ - **Description**: Optional fuzzy-boolean tolerance passed to the OCC union kernel. When omitted, SimpleCAD derives a conservative scale-aware value automatically.
53
+
32
54
  ## Returns
33
55
 
34
56
  List[Solid]: Resulting solids after union attempts. Solids that can be fused
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "simplecadapi"
3
- version = "2.0.7"
3
+ version = "2.0.8"
4
4
  description = "A simplified CAD modeling Python API based on CADQuery"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -5,9 +5,9 @@ license: MIT
5
5
  compatibility: Requires Python 3.10+, active virtual environment, and network access for package installation.
6
6
  metadata:
7
7
  project: simplecadapi
8
- version: 2.0.7
8
+ version: 2.0.8
9
9
  runtime-package: simplecadapi
10
- runtime-spec: simplecadapi==2.0.7
10
+ runtime-spec: simplecadapi==2.0.8
11
11
  cases-module: simplecad_self_evolve_cases
12
12
  ---
13
13
 
@@ -53,7 +53,7 @@ metadata:
53
53
  ## Install behavior
54
54
  - Preferred: run `scripts/install.sh` once when skill is installed/activated.
55
55
  - Runtime wrappers auto-install on demand if `simplecadapi` is missing.
56
- - Package installed by default: `simplecadapi==2.0.7`
56
+ - Package installed by default: `simplecadapi==2.0.8`
57
57
  - Wrappers install only into a virtual environment interpreter (set `PYTHON_BIN` when needed).
58
58
 
59
59
  ## Interpreter selection
@@ -1,8 +1,8 @@
1
1
  # Project Overview
2
2
 
3
3
  - Project: `simplecadapi`
4
- - Version: `2.0.7`
5
- - Runtime package: `simplecadapi==2.0.7`
4
+ - Version: `2.0.8`
5
+ - Runtime package: `simplecadapi==2.0.8`
6
6
  - Skill cases module: `simplecad_self_evolve_cases`
7
7
 
8
8
  ## What this skill bundles
@@ -9,7 +9,7 @@ Experimental scripts and temporary modeling examples are not included as formal
9
9
 
10
10
  ## Package Installation (Python Package Managers)
11
11
 
12
- Current package name: `simplecadapi`, version: `2.0.7` (see `pyproject.toml`).
12
+ Current package name: `simplecadapi`, version: `2.0.8` (see `pyproject.toml`).
13
13
 
14
14
  ### Method A: Install from package repository with pip
15
15
 
@@ -42,7 +42,7 @@ uv add simplecadapi
42
42
  The repository already contains example build artifacts (`dist/`):
43
43
 
44
44
  ```bash
45
- pip install dist/simplecadapi-2.0.7-py3-none-any.whl
45
+ pip install dist/simplecadapi-2.0.8-py3-none-any.whl
46
46
  ```
47
47
 
48
48
  If you need to rebuild:
@@ -6,7 +6,7 @@
6
6
  PYTHON_BIN=.venv/bin/python scripts/install.sh
7
7
  ```
8
8
 
9
- This installs `simplecadapi==2.0.7` to the active Python environment.
9
+ This installs `simplecadapi==2.0.8` to the active Python environment.
10
10
  If `PYTHON_BIN` is not set, wrappers default to `python3` (fallback `python`).
11
11
  Installation is intentionally blocked for non-venv/system interpreters.
12
12
 
@@ -3,7 +3,12 @@
3
3
  ## API Definition
4
4
 
5
5
  ```python
6
- def union_rsolidlist(*solids: Union[Solid, Sequence[Solid]]) -> List[Solid]
6
+ def union_rsolidlist(
7
+ *solids: Union[Solid, Sequence[Solid]],
8
+ clean: bool = True,
9
+ glue: bool = True,
10
+ tol: Optional[float] = None,
11
+ ) -> List[Solid]
7
12
  ```
8
13
 
9
14
  *Source: operations.py*
@@ -15,13 +20,18 @@ Compute the boolean union of one or more solids.
15
20
  All boolean operations (union/cut/intersect) accept a mix of Solid and
16
21
  sequences; results are always returned as a list of Solid.
17
22
  Keep the list result unless you have explicitly verified `len(result) == 1`.
23
+ SimpleCAD enables glue mode by default and applies a conservative internal fuzzy
24
+ tolerance, so normal modeling code does not need to tune boolean parameters.
25
+ By default this follows CadQuery's union flow: perform one OCC fuse across the
26
+ input solids, then call `clean()` to unify same-domain faces when possible.
18
27
  Touching-but-not-intersecting inputs can legitimately return multiple solids.
19
28
  If that happens, keep using the list: pass it directly into later union calls,
20
29
  or iterate over the solids for later cut/intersect steps.
30
+ When the returned solids are still separated by more than the active tolerance,
31
+ SimpleCAD prints a stdout warning explaining that the objects do not touch and
32
+ that their gap exceeds `tol`.
21
33
  If you truly need exactly one merged solid, you must check the list length
22
- before using `result[0]`. When the length is not 1, do not pick an element
23
- arbitrarily; instead, adjust part placement so the solids overlap slightly,
24
- then run the union again.
34
+ before using `result[0]`.
25
35
 
26
36
  ## Parameters
27
37
 
@@ -29,6 +39,18 @@ then run the union again.
29
39
 
30
40
  - **Description**: One or more Solid objects or sequences of Solid. Nested sequences are flattened before processing.
31
41
 
42
+ ### clean
43
+
44
+ - **Description**: Call CadQuery's `clean()` after the union to remove splitter edges and unify same-domain faces when possible.
45
+
46
+ ### glue
47
+
48
+ - **Description**: Enable OCC glue mode for touching or partially overlapping inputs. Defaults to `True` for SimpleCAD's standard union behavior.
49
+
50
+ ### tol
51
+
52
+ - **Description**: Optional fuzzy-boolean tolerance passed to the OCC union kernel. When omitted, SimpleCAD derives a conservative scale-aware value automatically.
53
+
32
54
  ## Returns
33
55
 
34
56
  List[Solid]: Resulting solids after union attempts. Solids that can be fused
@@ -32,7 +32,7 @@ export SIMPLECAD_RUNTIME_PACKAGE="simplecadapi"
32
32
  export SIMPLECAD_CASES_ROOT="${SKILL_ROOT}/cases"
33
33
  export SIMPLECAD_CASES_MODULE="simplecad_self_evolve_cases"
34
34
 
35
- PACKAGE_SPEC="simplecadapi==2.0.7"
35
+ PACKAGE_SPEC="simplecadapi==2.0.8"
36
36
  JUPYTER_DEPS=("jupyterlab>=4.5.5" "ipykernel>=6.29.5")
37
37
  INSTALL_JUPYTER=0
38
38
  INSTALL_ARGS=()
@@ -85,4 +85,4 @@ print("simplecadapi import OK")
85
85
  print(getattr(scad, "__description__", ""))
86
86
  PY
87
87
 
88
- echo "Runtime install completed for simplecadapi 2.0.7."
88
+ echo "Runtime install completed for simplecadapi 2.0.8."
@@ -10,7 +10,7 @@ import sys
10
10
  from pathlib import Path
11
11
 
12
12
 
13
- PACKAGE_SPEC = "simplecadapi==2.0.7"
13
+ PACKAGE_SPEC = "simplecadapi==2.0.8"
14
14
  CASES_MODULE = "simplecad_self_evolve_cases"
15
15
 
16
16
 
@@ -565,13 +565,16 @@ class SkillPackager:
565
565
  7. Build and validate incrementally. Each step MUST include a small grounding `print`, and grounding MUST use QL where possible.
566
566
  8. For inspection/debugging, query geometry with QL and print only the queried facts you need; do not print whole solids, assemblies, or full model objects.
567
567
  9. Boolean operations always return `List[Solid]`. You MUST check `len(results)` before using `results[0]`.
568
- 10. If tangent-only contact leaves multiple solids after `union_rsolidlist(...)`, that is often acceptable. Keep the list and continue operating on the list or iterate over its solids.
569
- 11. If the design explicitly requires exactly one merged solid and `len(results) != 1`, you MUST NOT silently pick one item. Instead, slightly adjust part placement so the intended bodies overlap/embed, run the union again, and only then unwrap the single result.
570
- 12. After model construction, ask the user whether the result is satisfactory and whether any modifications are needed. Only after explicit user confirmation may you add the script to evolve cases.
568
+ 10. `union_rsolidlist(...)` already uses SimpleCAD's tuned default boolean settings internally. Do not add manual boolean tuning unless you are debugging a stubborn edge case.
569
+ 11. If tangent-only contact leaves multiple solids after `union_rsolidlist(...)`, that is often acceptable. Keep the list and continue operating on the list or iterate over its solids.
570
+ 12. If the design explicitly requires exactly one merged solid and `len(results) != 1`, you MUST NOT silently pick one item. Instead, slightly adjust part placement so the intended bodies overlap/embed, run the union again, and only then unwrap the single result.
571
+ 13. After model construction, ask the user whether the result is satisfactory and whether any modifications are needed. Only after explicit user confirmation may you add the script to evolve cases.
571
572
 
572
573
  ## Boolean result discipline
573
574
  - `union_rsolidlist(...)`, `cut_rsolidlist(...)`, and `intersect_rsolidlist(...)` accept mixed inputs: standalone `Solid`, lists of `Solid`, and nested sequences.
574
575
  - They always return `List[Solid]`.
576
+ - `union_rsolidlist(...)` already applies the package's default glue mode and a conservative internal tolerance.
577
+ - If a union still returns multiple solids that remain separated beyond tolerance, the API prints a stdout warning automatically.
575
578
  - Default behavior: keep the list result and pass it forward or iterate over it.
576
579
  - Only unwrap to a single solid after an explicit `len(results) == 1` check.
577
580
  - If a single merged solid is required but a union still returns multiple solids, slightly move the parts so they overlap instead of merely touching, then recompute the union.
@@ -26,7 +26,83 @@ from .field import (
26
26
  intersect_rscalarfield,
27
27
  )
28
28
 
29
- from cadquery.occ_impl.shapes import fuse, cut, intersect, revolve
29
+ from cadquery.occ_impl.shapes import cut, intersect, revolve
30
+
31
+
32
+ _DEFAULT_UNION_GLUE = True
33
+ _DEFAULT_UNION_TOL_FACTOR = 1e-7
34
+ _DEFAULT_UNION_TOL_MIN = 1e-7
35
+ _DEFAULT_UNION_TOL_MAX = 1e-5
36
+
37
+
38
+ def _resolve_union_tol(
39
+ solids: Sequence[Solid], tol: Optional[float]
40
+ ) -> Optional[float]:
41
+ """Resolve a conservative fuzzy tolerance for boolean union.
42
+
43
+ When callers do not specify `tol`, use a scale-aware value that is large enough
44
+ to absorb small numerical noise but not aggressive enough to close meaningful
45
+ modeling gaps by default.
46
+ """
47
+
48
+ if tol is not None:
49
+ return tol
50
+
51
+ bbox_min = np.array([np.inf, np.inf, np.inf], dtype=float)
52
+ bbox_max = np.array([-np.inf, -np.inf, -np.inf], dtype=float)
53
+
54
+ for solid in solids:
55
+ bb = solid.cq_solid.BoundingBox()
56
+ bbox_min = np.minimum(bbox_min, np.array([bb.xmin, bb.ymin, bb.zmin]))
57
+ bbox_max = np.maximum(bbox_max, np.array([bb.xmax, bb.ymax, bb.zmax]))
58
+
59
+ span = float(np.linalg.norm(bbox_max - bbox_min))
60
+ if not np.isfinite(span) or span <= 0:
61
+ return _DEFAULT_UNION_TOL_MIN
62
+
63
+ return min(
64
+ max(span * _DEFAULT_UNION_TOL_FACTOR, _DEFAULT_UNION_TOL_MIN),
65
+ _DEFAULT_UNION_TOL_MAX,
66
+ )
67
+
68
+
69
+ def _warn_if_union_results_remain_separated(
70
+ results: Sequence[Solid], tol: Optional[float]
71
+ ) -> None:
72
+ """Print a clear stdout warning when union results remain separated beyond tol."""
73
+
74
+ if len(results) < 2:
75
+ return
76
+
77
+ effective_tol = float(tol or 0.0)
78
+ nearest_gap_above_tol: Optional[float] = None
79
+
80
+ for i in range(len(results)):
81
+ for j in range(i + 1, len(results)):
82
+ gap = float(results[i].cq_solid.distance(results[j].cq_solid))
83
+ if gap > effective_tol:
84
+ if nearest_gap_above_tol is None or gap < nearest_gap_above_tol:
85
+ nearest_gap_above_tol = gap
86
+
87
+ if nearest_gap_above_tol is None:
88
+ return
89
+
90
+ if len(results) == 2:
91
+ print(
92
+ "[WARNING] union_rsolidlist returned 2 separated solids: the two objects do not touch, "
93
+ f"and the gap between them is about {nearest_gap_above_tol:.6g}, which exceeds tol={effective_tol:.6g}. "
94
+ "Please check the relationship between the two objects and decide whether to adjust them so they connect, "
95
+ "or accept them as two separate solids."
96
+ )
97
+ return
98
+
99
+ print(
100
+ f"[WARNING] union_rsolidlist returned {len(results)} separated solids: "
101
+ "at least one pair of objects does not touch, "
102
+ f"and the smallest detected separation gap is about {nearest_gap_above_tol:.6g}, which exceeds tol={effective_tol:.6g}. "
103
+ "Please check the relationship between these objects and decide whether to adjust them so they connect, "
104
+ "or accept them as separate solids."
105
+ )
30
106
 
31
107
 
32
108
  # =============================================================================
@@ -1239,29 +1315,41 @@ def select_edges_by_tag(shape: Union[Face, Solid], tag: str) -> List[Edge]:
1239
1315
  # =============================================================================
1240
1316
 
1241
1317
 
1242
- def union_rsolidlist(*solids: Union[Solid, Sequence[Solid]]) -> List[Solid]:
1318
+ def union_rsolidlist(
1319
+ *solids: Union[Solid, Sequence[Solid]],
1320
+ clean: bool = True,
1321
+ glue: bool = _DEFAULT_UNION_GLUE,
1322
+ tol: Optional[float] = None,
1323
+ ) -> List[Solid]:
1243
1324
  """Compute the boolean union of one or more solids.
1244
1325
 
1245
1326
  Args:
1246
1327
  solids: One or more Solid objects or sequences of Solid. Nested sequences are
1247
1328
  flattened before processing.
1329
+ clean: Call CadQuery's `clean()` after the union to unify same-domain faces
1330
+ and remove splitter edges when possible.
1331
+ glue: Enable OCC glue mode for touching or partially overlapping inputs.
1332
+ Defaults to True for SimpleCAD's standard union behavior.
1333
+ tol: Optional fuzzy-boolean tolerance used by the OCC union kernel. When
1334
+ omitted, SimpleCAD chooses a conservative scale-aware tolerance.
1248
1335
 
1249
1336
  Returns:
1250
1337
  List[Solid]: Resulting solids after union attempts. Solids that can be fused
1251
- are merged; disjoint or tangent-only contacts remain separate, so the
1252
- list may contain multiple solids.
1338
+ are merged; disjoint or tangent-only contacts remain separate, so the
1339
+ list may contain multiple solids.
1253
1340
 
1254
1341
  Usage:
1255
1342
  All boolean operations (union/cut/intersect) accept a mix of Solid and
1256
1343
  sequences; results are always returned as a list of Solid.
1257
1344
  Keep the list result unless you have explicitly verified `len(result) == 1`.
1345
+ SimpleCAD enables glue mode by default and applies a conservative internal
1346
+ fuzzy tolerance so normal code does not need to tune boolean parameters.
1258
1347
  Touching-but-not-intersecting inputs can legitimately return multiple solids.
1259
1348
  If that happens, keep using the list: pass it directly into later union calls,
1260
- or iterate over the solids for later cut/intersect steps.
1261
- If you truly need exactly one merged solid, you must check the list length
1262
- before using `result[0]`. When the length is not 1, do not pick an element
1263
- arbitrarily; instead, adjust part placement so the solids overlap slightly,
1264
- then run the union again.
1349
+ or iterate over the solids for later cut/intersect steps. When returned
1350
+ solids remain separated by more than the active tolerance, SimpleCAD prints
1351
+ a stdout warning describing the detected gap. If you truly need exactly one
1352
+ merged solid, you must check the list length before using `result[0]`.
1265
1353
 
1266
1354
  Examples:
1267
1355
  # Rounded-bar style input: end caps only touch the center body.
@@ -1292,33 +1380,6 @@ def union_rsolidlist(*solids: Union[Solid, Sequence[Solid]]) -> List[Solid]:
1292
1380
  final_body = merged[0]
1293
1381
  """
1294
1382
 
1295
- def _attempt_fuse(base: Solid, candidate: Solid) -> Optional[Solid]:
1296
- s1 = base.cq_solid
1297
- s2 = candidate.cq_solid
1298
-
1299
- if s1.isNull() or s2.isNull():
1300
- raise ValueError("输入实体无效,无法进行并集运算。")
1301
-
1302
- fused_shape = fuse(s1, s2)
1303
- if hasattr(fused_shape, "Solids") and fused_shape.Solids():
1304
- cq_result = fused_shape.Solids()[0]
1305
- else:
1306
- cq_result = fused_shape
1307
-
1308
- fused_solid = Solid(cq_result)
1309
- if math.isclose(
1310
- fused_solid.get_volume(),
1311
- base.get_volume(),
1312
- rel_tol=1e-9,
1313
- abs_tol=1e-12,
1314
- ):
1315
- return None
1316
-
1317
- fused_solid._tags = base._tags.union(candidate._tags)
1318
- fused_solid._metadata = {**base._metadata, **candidate._metadata}
1319
-
1320
- return fused_solid
1321
-
1322
1383
  try:
1323
1384
  # 递归展开所有参数:将Solid直接添加,将序列展开
1324
1385
  def _flatten_solids(args):
@@ -1340,30 +1401,49 @@ def union_rsolidlist(*solids: Union[Solid, Sequence[Solid]]) -> List[Solid]:
1340
1401
  for solid in remaining:
1341
1402
  if not isinstance(solid, Solid):
1342
1403
  raise ValueError("union_rsolidlist函数只接受Solid类型的对象")
1404
+ if solid.cq_solid.isNull():
1405
+ raise ValueError("输入实体无效,无法进行并集运算。")
1343
1406
 
1344
- result: List[Solid] = []
1407
+ if len(remaining) == 1 and not clean:
1408
+ return [remaining[0]]
1345
1409
 
1346
- while remaining:
1347
- base = remaining.pop(0)
1348
- merged = True
1349
-
1350
- while merged:
1351
- merged = False
1352
- idx = 0
1353
- while idx < len(remaining):
1354
- candidate = remaining[idx]
1355
- fused = _attempt_fuse(base, candidate)
1356
- if fused is None:
1357
- idx += 1
1358
- continue
1410
+ effective_tol = _resolve_union_tol(remaining, tol)
1411
+ cq_shapes = [solid.cq_solid for solid in remaining]
1412
+
1413
+ if len(cq_shapes) == 1:
1414
+ fused_shape = cq_shapes[0]
1415
+ else:
1416
+ fused_shape = cq_shapes[0].fuse(
1417
+ *cq_shapes[1:], glue=glue, tol=effective_tol
1418
+ )
1419
+
1420
+ if clean:
1421
+ fused_shape = fused_shape.clean()
1359
1422
 
1360
- base = fused
1361
- remaining.pop(idx)
1362
- merged = True
1423
+ if hasattr(fused_shape, "Solids"):
1424
+ cq_results = list(fused_shape.Solids())
1425
+ elif hasattr(fused_shape, "ShapeType") and fused_shape.ShapeType() == "Solid":
1426
+ cq_results = [fused_shape]
1427
+ else:
1428
+ cq_results = []
1429
+
1430
+ if not cq_results:
1431
+ raise ValueError("并集结果中未找到有效实体。")
1363
1432
 
1364
- # 如果在本轮中没有融合发生,则跳出内循环
1433
+ all_tags = set()
1434
+ all_metadata = {}
1435
+ for solid in remaining:
1436
+ all_tags.update(solid._tags)
1437
+ all_metadata.update(solid._metadata)
1438
+
1439
+ result: List[Solid] = []
1440
+ for cq_result in cq_results:
1441
+ fused_solid = Solid(cq_result)
1442
+ fused_solid._tags = all_tags.copy()
1443
+ fused_solid._metadata = all_metadata.copy()
1444
+ result.append(fused_solid)
1365
1445
 
1366
- result.append(base)
1446
+ _warn_if_union_results_remain_separated(result, effective_tol)
1367
1447
 
1368
1448
  return result
1369
1449
  except Exception as e:
@@ -2,10 +2,12 @@
2
2
 
3
3
  import sys
4
4
  import os
5
+ import io
5
6
  import unittest
6
7
  import numpy as np
7
8
  import tempfile
8
9
  import shutil
10
+ from contextlib import redirect_stdout
9
11
 
10
12
  # 添加项目路径到Python路径
11
13
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
@@ -271,12 +273,49 @@ class TestBooleanOperations(unittest.TestCase):
271
273
  box_far_3 = scad.make_box_rsolid(1.0, 1.0, 1.0, bottom_face_center=(0, 5, 0))
272
274
 
273
275
  solids = [box_far_1, box_far_2, box_far_3]
274
- results = scad.union_rsolidlist(solids)
276
+ stdout_buffer = io.StringIO()
277
+ with redirect_stdout(stdout_buffer):
278
+ results = scad.union_rsolidlist(solids)
279
+ warning_text = stdout_buffer.getvalue()
275
280
 
276
281
  self.assertIsInstance(results, list)
277
282
  self.assertEqual(len(results), len(solids))
278
283
  for solid in results:
279
284
  self.assertIsInstance(solid, scad.Solid)
285
+ self.assertIn("[WARNING]", warning_text)
286
+ self.assertIn("does not touch", warning_text)
287
+ self.assertIn("exceeds tol", warning_text)
288
+
289
+ def test_union_touching_boxes_cleans_splitter_faces(self):
290
+ """Test union of face-touching boxes follows CadQuery-style clean behavior."""
291
+
292
+ box_left = scad.make_box_rsolid(1.0, 1.0, 1.0, bottom_face_center=(0, 0, 0))
293
+ box_right = scad.make_box_rsolid(1.0, 1.0, 1.0, bottom_face_center=(1.0, 0, 0))
294
+
295
+ stdout_buffer = io.StringIO()
296
+ with redirect_stdout(stdout_buffer):
297
+ results = scad.union_rsolidlist(box_left, box_right)
298
+
299
+ self.assertEqual(len(results), 1)
300
+ self.assertAlmostEqual(results[0].get_volume(), 2.0, places=6)
301
+ self.assertEqual(len(results[0].get_faces()), 6)
302
+ self.assertEqual(stdout_buffer.getvalue(), "")
303
+
304
+ def test_union_supports_fuzzy_tolerance(self):
305
+ """Test union forwards CadQuery fuzzy tolerance to the OCC kernel."""
306
+
307
+ box_left = scad.make_box_rsolid(1.0, 1.0, 1.0, bottom_face_center=(0, 0, 0))
308
+ box_right = scad.make_box_rsolid(
309
+ 1.0, 1.0, 1.0, bottom_face_center=(1.001, 0, 0)
310
+ )
311
+
312
+ without_tol = scad.union_rsolidlist(box_left, box_right)
313
+ with_tol = scad.union_rsolidlist(box_left, box_right, tol=1e-3)
314
+
315
+ self.assertEqual(len(without_tol), 2)
316
+ self.assertEqual(len(with_tol), 1)
317
+ self.assertGreater(with_tol[0].get_volume(), 2.0)
318
+ self.assertLess(with_tol[0].get_volume(), 2.01)
280
319
 
281
320
  def test_cut(self):
282
321
  """Test cut."""
@@ -609,7 +648,7 @@ class TestComplexExamples(unittest.TestCase):
609
648
  gear_base = gear_base_list[0]
610
649
 
611
650
  # 创建齿(简化版本)
612
- tooth_profile = scad.make_rectangle_rface(0.5, 0.3, center=(4.5, 0, 0))
651
+ tooth_profile = scad.make_rectangle_rface(0.5, 0.3, center=(5.0, 0, 0))
613
652
  tooth = scad.extrude_rsolid(tooth_profile, (0, 0, 1), 1.2)
614
653
 
615
654
  # 合并一个齿到基础上
@@ -3546,7 +3546,7 @@ wheels = [
3546
3546
 
3547
3547
  [[package]]
3548
3548
  name = "simplecadapi"
3549
- version = "2.0.7"
3549
+ version = "2.0.8"
3550
3550
  source = { editable = "." }
3551
3551
  dependencies = [
3552
3552
  { name = "cadquery" },
File without changes
File without changes
File without changes