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.
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/PKG-INFO +3 -3
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/README.md +2 -2
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/union_rsolidlist.md +26 -4
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/pyproject.toml +1 -1
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/SKILL.md +3 -3
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/PROJECT_OVERVIEW.md +2 -2
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/PROJECT_README.md +2 -2
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/RUNTIME_INSTALL.md +1 -1
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/union_rsolidlist.md +26 -4
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/install.sh +2 -2
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/repl_bootstrap.py +1 -1
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/skill_pack.py +6 -3
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/operations.py +135 -55
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_all_features.py +41 -2
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/uv.lock +1 -1
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/.gitignore +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/.python-version +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/LICENSE +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/MANIFEST.in +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/README.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/add_part_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/and_.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/bounds_rbbox.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/chamfer_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/clear_constraints_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/clone_assembly_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_coincident_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_concentric_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_distance_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/constrain_offset_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/cut_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/eval_rarray.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/eval_rscalar.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/export_step.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/export_stl.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/extrude_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/fillet_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/geo.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/helical_sweep_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/intersect_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/intersect_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/linear_pattern_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/loft_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_angle_arc_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_angle_arc_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_assembly_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_box_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_box_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_capsule_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_circle_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_circle_rface.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_circle_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_cone_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_cylinder_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_ellipsoid_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_face_from_wire_rface.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_field_surface_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_helix_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_helix_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_line_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_n_hole_flange_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_naca_propeller_blade_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_point_rvertex.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_polyline_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_rectangle_rface.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_rectangle_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_segment_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_segment_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_sphere_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_sphere_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_spline_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_spline_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_threaded_rod_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_three_point_arc_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_three_point_arc_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/make_wire_from_edges_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/meta.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/mirror_shape.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/not_.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/or_.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/radial_pattern_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/render_screenshot_rpath.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/revolve_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/rotate_part_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/rotate_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/rotate_shape.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/scale_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/select.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/select_edges_by_tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/select_faces_by_tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/set_tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/shell_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/smooth_subtract_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/smooth_union_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/solve_assembly_rresult.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/stack.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/stack_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/subtract_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/sweep_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/translate_part_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/translate_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/translate_shape.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/union_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/api/value.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/README.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/compound.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/coordinate_system.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/declarative_constraints.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/edge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/face.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/shell.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/simple_workplane.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/solid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/tagged_mixin.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/vertex.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/docs/core/wire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/examples.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/refactor-plan/tagging.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/scripts/publish.sh +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/scripts/sync_ragflow_docs.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/cases/simplecad_self_evolve_cases/__init__.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/cases/simplecad_self_evolve_cases/evolve.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/EVOLVE_WORKFLOW.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/LICENSE.txt +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/README.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/add_part_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/and_.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/bounds_rbbox.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/chamfer_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/clear_constraints_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/clone_assembly_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_coincident_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_concentric_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_distance_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/constrain_offset_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/cut_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/eval_rarray.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/eval_rscalar.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/export_step.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/export_stl.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/extrude_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/fillet_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/geo.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/helical_sweep_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/intersect_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/intersect_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/linear_pattern_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/loft_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_angle_arc_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_angle_arc_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_assembly_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_box_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_box_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_capsule_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_circle_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_circle_rface.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_circle_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_cone_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_cylinder_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_ellipsoid_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_face_from_wire_rface.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_field_surface_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_helix_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_helix_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_line_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_n_hole_flange_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_naca_propeller_blade_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_point_rvertex.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_polyline_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_rectangle_rface.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_rectangle_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_segment_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_segment_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_sphere_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_sphere_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_spline_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_spline_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_threaded_rod_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_three_point_arc_redge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_three_point_arc_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/make_wire_from_edges_rwire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/meta.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/mirror_shape.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/not_.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/or_.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/radial_pattern_rsolidlist.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/render_screenshot_rpath.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/revolve_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/rotate_part_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/rotate_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/rotate_shape.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/scale_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/select.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/select_edges_by_tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/select_faces_by_tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/set_tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/shell_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/smooth_subtract_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/smooth_union_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/solve_assembly_rresult.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/stack.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/stack_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/subtract_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/sweep_rsolid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/tag.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/translate_part_rassembly.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/translate_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/translate_shape.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/union_rscalarfield.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/api/value.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/README.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/compound.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/coordinate_system.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/declarative_constraints.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/edge.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/face.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/shell.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/simple_workplane.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/solid.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/tagged_mixin.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/vertex.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/docs/core/wire.md +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/add_new_case.sh +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/evolve_case.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/jupyter_with_skill.sh +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/validate_skill.sh +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/scripts/with_skill.sh +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/__init__.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/__init__.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/auto_docs_gen.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/evolution.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/auto_tools/make_export.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/constraints.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/core.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/evolve.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/field.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/py.typed +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/ql.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/src/simplecadapi/tagging.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_auto_docs_gen.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_field_surface.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_make_export.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_ql.py +0 -0
- {simplecadapi-2.0.7 → simplecadapi-2.0.8}/test/test_skill_pack.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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]`.
|
|
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
|
|
@@ -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.
|
|
8
|
+
version: 2.0.8
|
|
9
9
|
runtime-package: simplecadapi
|
|
10
|
-
runtime-spec: simplecadapi==2.0.
|
|
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.
|
|
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
|
{simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/PROJECT_README.md
RENAMED
|
@@ -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.
|
|
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.
|
|
45
|
+
pip install dist/simplecadapi-2.0.8-py3-none-any.whl
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
If you need to rebuild:
|
{simplecadapi-2.0.7 → simplecadapi-2.0.8}/skills/simplecad-self-evolve/references/RUNTIME_INSTALL.md
RENAMED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
PYTHON_BIN=.venv/bin/python scripts/install.sh
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
This installs `simplecadapi==2.0.
|
|
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(
|
|
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]`.
|
|
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.
|
|
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.
|
|
88
|
+
echo "Runtime install completed for simplecadapi 2.0.8."
|
|
@@ -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.
|
|
569
|
-
11. If
|
|
570
|
-
12.
|
|
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
|
|
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(
|
|
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
|
-
|
|
1252
|
-
|
|
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
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
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
|
-
|
|
1407
|
+
if len(remaining) == 1 and not clean:
|
|
1408
|
+
return [remaining[0]]
|
|
1345
1409
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
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
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=(
|
|
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
|
# 合并一个齿到基础上
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|