openscad-cpp-evaluator 1.51.0__tar.gz → 1.52.0__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.
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/CLAUDE.md +76 -10
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/CMakeLists.txt +9 -3
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/bindings/module.cpp +28 -0
- openscad_cpp_evaluator-1.52.0/include/openscad_cpp_evaluator/offset3d.hpp +16 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/python/openscad_cpp_evaluator/__init__.py +7 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/CMakeLists.txt +1 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/extrude.cpp +36 -6
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/function_builtins.cpp +1 -0
- openscad_cpp_evaluator-1.52.0/src/builtins/offset3d.cpp +1141 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/csg_generate.cpp +3 -1
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/CMakeLists.txt +1 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_booleans.cpp +3 -2
- openscad_cpp_evaluator-1.52.0/tests/test_offset3d.cpp +128 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_python_bindings.py +16 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/cmake/patch_manifold.cmake +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/LICENSE +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/reassign.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/alpha_wrap.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/export_as.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_alpha_wrap.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_export_as.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_openscad_parity.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_undef_args.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/third_party/predicates/predicates.c +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/third_party/predicates/predicates.h +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/uv.lock +0 -0
|
@@ -535,11 +535,12 @@ cmake -S . -B build -DFETCHCONTENT_FULLY_DISCONNECTED=ON -DBUILD_TESTING=OFF \
|
|
|
535
535
|
-DFETCHCONTENT_SOURCE_DIR_BOOST_CONFIG=... -DFETCHCONTENT_SOURCE_DIR_BOOST_POLYGON=... \
|
|
536
536
|
-DFETCHCONTENT_SOURCE_DIR_FREETYPE=... -DFETCHCONTENT_SOURCE_DIR_HARFBUZZ=... \
|
|
537
537
|
-DFETCHCONTENT_SOURCE_DIR_STB=... -DFETCHCONTENT_SOURCE_DIR_CPP_LINENOISE=... \
|
|
538
|
-
-DFETCHCONTENT_SOURCE_DIR_NLOHMANN_JSON=...
|
|
538
|
+
-DFETCHCONTENT_SOURCE_DIR_NLOHMANN_JSON=... -DFETCHCONTENT_SOURCE_DIR_TBB=...
|
|
539
539
|
```
|
|
540
540
|
|
|
541
|
-
That is the whole list for a wheel build (tests off; GoogleTest is the only other download
|
|
542
|
-
|
|
541
|
+
That is the whole list for a wheel build (tests off; GoogleTest is the only other download).
|
|
542
|
+
Clipper2 and oneTBB (v2022.3.0, for `MANIFOLD_PAR`, which the root `CMakeLists.txt` forces on
|
|
543
|
+
with Manifold's builtin static TBB) are Manifold's own downloads, pinned in Manifold's
|
|
543
544
|
`cmake/manifoldDeps.cmake`; nlohmann_json is the parser's. FetchContent skips `PATCH_COMMAND` for a
|
|
544
545
|
supplied source, so the root `CMakeLists.txt` runs `cmake/patch_manifold.cmake` itself when
|
|
545
546
|
`FETCHCONTENT_SOURCE_DIR_MANIFOLD` is set -- otherwise an offline build would quietly ship the heap
|
|
@@ -1070,9 +1071,10 @@ grep for `ponytail:`.
|
|
|
1070
1071
|
reference's `isValidDim` + `collectChildren2D`/`collectChildren3D`: a node's dimension is fixed by
|
|
1071
1072
|
its first non-background, non-empty child, and every child of the other dimension is dropped with
|
|
1072
1073
|
`Mixing 2D and 3D objects is not supported` followed by `Ignoring {N}D child object for {M}D
|
|
1073
|
-
operation`. `linear_extrude`/`rotate_extrude
|
|
1074
|
+
operation`. `linear_extrude`/`rotate_extrude` are always-2D and `projection` always-3D, so
|
|
1074
1075
|
they skip the "mixing" line and emit only the second; `roof()` emits neither, matching the
|
|
1075
|
-
reference.
|
|
1076
|
+
reference. `offset()` takes either dimension (the solid offset of `offset3d.cpp`), so it follows
|
|
1077
|
+
the boolean rule: the first real child decides. Background (`%`) children are exempt.
|
|
1076
1078
|
**The emptiness test is cached on the body (`ColoredBody::knownEmpty`, v1.17.0).** It used to
|
|
1077
1079
|
call `Manifold::NumTri()` on every child at every level, and every Manifold accessor goes through
|
|
1078
1080
|
`GetImpl()`, which materialises a lazy transform (a full mesh + collider copy) and runs a lazy
|
|
@@ -1123,10 +1125,8 @@ grep for `ponytail:`.
|
|
|
1123
1125
|
(`Manifold::MinkowskiDifference`). 3D only, matching `minkowski()`'s own 3D-wins dispatch, since
|
|
1124
1126
|
Manifold has no CrossSection erosion and 2D already has one in `offset(r=-N)`.
|
|
1125
1127
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
been pure sugar. Erosion is the half that is genuinely unavailable, and naming it after the
|
|
1129
|
-
operation beats borrowing a 2D name for it. Eroding a cube by a cube is exact (no curved tool to
|
|
1128
|
+
It predates the 3D `offset()` (see `## offset() in 3D`), which now erodes a solid too, and is kept
|
|
1129
|
+
because it erodes by any tool, not only a ball, cube or octahedron. Eroding a cube by a cube is exact (no curved tool to
|
|
1130
1130
|
tessellate), which is what the tests assert on; a sphere tool lands a little large, and that gap
|
|
1131
1131
|
is the sphere's tessellation rather than an error in the erosion.
|
|
1132
1132
|
- `src/builtins/extrude.cpp` — `linear_extrude()`/`rotate_extrude()`/`projection(cut=)`. All three
|
|
@@ -1140,7 +1140,9 @@ grep for `ponytail:`.
|
|
|
1140
1140
|
`generateOffset`, also in this file) is the other CrossSection-transform-shaped builtin sharing
|
|
1141
1141
|
`toCrossSection`; no children/generate-time-bounds dependency, so its resolve/generate split is
|
|
1142
1142
|
the simple kind (segment count for `r=` IS resolvable early here, unlike `rotate_extrude`'s,
|
|
1143
|
-
since `offset`'s own radius argument is already known at resolve time).
|
|
1143
|
+
since `offset`'s own radius argument is already known at resolve time). A 3D child takes
|
|
1144
|
+
`offset3d()` instead (`## offset() in 3D`): the foreground solids are unioned and offset as one,
|
|
1145
|
+
`join` round/miter/square selecting r/delta/chamfer, and the result tagged as generated.
|
|
1144
1146
|
- `src/builtins/roof.cpp` — `roof()`: the default `method="voronoi"` built on Boost.Polygon's
|
|
1145
1147
|
segment Voronoi diagram (see the `roof()` note above for the full story of why this replaced an
|
|
1146
1148
|
earlier straight-skeleton approximation mid-Phase-6), and `method="straight"`'s straight-skeleton
|
|
@@ -2037,3 +2039,67 @@ formats have no object names and ignore it. Geometry outside any `export_as()` i
|
|
|
2037
2039
|
`export_as()` and drops an unknown module's children, so a portable script guards on
|
|
2038
2040
|
`supported_feature("export-as")`.
|
|
2039
2041
|
- `src/builtins/export_as.cpp`; tests in `tests/test_export_as.cpp`.
|
|
2042
|
+
|
|
2043
|
+
## `offset()` in 3D
|
|
2044
|
+
|
|
2045
|
+
`offset(r=)`, `offset(delta=)` and `offset(delta=, chamfer=true)` of a solid, outward and inward
|
|
2046
|
+
(`src/builtins/offset3d.cpp`, entry `offset3d()` in `include/openscad_cpp_evaluator/offset3d.hpp`;
|
|
2047
|
+
`supported_feature("offset-3d")` is 1). Upstream OpenSCAD's `offset()` is 2D only and drops a 3D
|
|
2048
|
+
child, so a portable script guards it. The modes mean what they mean in 2D: every face moves `d`
|
|
2049
|
+
along its normal; `delta=` keeps edges and corners sharp (**no miter limit**, as Clipper's 1e6 is
|
|
2050
|
+
none, so a sharp edge's miter reaches `d/sin(half its angle)`); `chamfer=true` cuts them flat
|
|
2051
|
+
(exactly `minkowski()` with an octahedron on an axis-aligned part); `r=` rounds them with a faceted
|
|
2052
|
+
ball **inscribed** in the true sphere (every vertex on it), `$fn`/`$fa`/`$fs` counted from `|r|` as
|
|
2053
|
+
in 2D -- so the default gives `r=1` five sides, and `$fn` is usually wanted. No published method
|
|
2054
|
+
covers all three modes (Cao 2024's mitered offset needs exact rationals; Zint 2023 and PCO round
|
|
2055
|
+
only), so the construction is our own, worked out in a Python prototype and checked by suites of
|
|
2056
|
+
exact volumes, topology, fuzzing, refine invariance and pathological meshes before the port.
|
|
2057
|
+
|
|
2058
|
+
**Construction.** Outward is `A ∪ pieces`: a slab per triangle (the face swept by `d`), a wedge per
|
|
2059
|
+
convex edge (hull of the two faces' offset points; plus the miter points for `delta=`; a capsule
|
|
2060
|
+
for `r=`) and a cap per vertex (the same at a corner). Inward builds the same pieces on A with
|
|
2061
|
+
every triangle flipped and subtracts their union from A -- no bounding box, and a feature thinner
|
|
2062
|
+
than `2d` vanishes by construction. Outward `r=` is Manifold's `MinkowskiSum` with the inscribed
|
|
2063
|
+
ball, which is this construction and faster. Each piece is convex, made by `hullChecked` (hull in a
|
|
2064
|
+
PCA-whitened frame, since Manifold's hull dropped corners of long thin point sets, then every input
|
|
2065
|
+
point verified against the hull's planes). Mitered pieces are trimmed by the shifted half-spaces
|
|
2066
|
+
of the faces at their end vertices -- the ends of the whole straight edge (`chainEnds`), not of the
|
|
2067
|
+
triangle edge, or `refine()`'s midpoints left a 0.6 spike -- and by far faces only within their
|
|
2068
|
+
own convex patch (faces joined through convex or flat edges), which keeps separate parts apart.
|
|
2069
|
+
|
|
2070
|
+
**Robustness rules, each from a failure:**
|
|
2071
|
+
- Pieces start `e = min(d, max(1e-5·d, 1e-9·scale))` behind the surface, so none shares a plane
|
|
2072
|
+
with A (coincident faces left a rounding-thin skin); slabs widen by `e` past concave and flat
|
|
2073
|
+
edges (otherwise zero-thickness fins, genus -87); wedges reach `1e-3·d` into both slabs and caps
|
|
2074
|
+
along their edges, as absolute distances (fractions of an edge made `refine(2)` change the result).
|
|
2075
|
+
- Every piece is grown by `1e-9·scale`, so offsets meeting exactly overlap rather than touch
|
|
2076
|
+
(touching counts as joined, as in Minkowski). Expect volumes ~1e-9 relative off exact.
|
|
2077
|
+
- The work runs at the origin (Manifold's union lost 0.35 of a chamfered cube at 1e5 from it), and
|
|
2078
|
+
the result is moved back as a bare mesh: `Translate()` of a lazy CSG result re-runs its booleans
|
|
2079
|
+
out there.
|
|
2080
|
+
- **`bare()` everywhere**: pieces and intermediate leaves are rebuilt from vertices and triangles
|
|
2081
|
+
alone. A Manifold rebuilt from `GetMeshGL64()` keeps face IDs and the like, and unions of such
|
|
2082
|
+
pieces lost whole wedges (adding six pieces once made the volume smaller). Manifold 3.5.4 does
|
|
2083
|
+
the same, so a bump does not help.
|
|
2084
|
+
- **`lostPieces()` checks the union against its pieces.** Manifold's union is order- and
|
|
2085
|
+
thread-dependent (TBB lost 0.045 of one piece where the single-threaded build did not). Pieces are
|
|
2086
|
+
coloured so that no two of a colour have overlapping boxes, each colour `Compose`d (exact for
|
|
2087
|
+
disjoint pieces) and tested with one boolean against the bare result -- against a lazy one,
|
|
2088
|
+
Manifold flattened `G - (A + pieces)` into `G - A - pieces` and hid every loss. A remnant thicker
|
|
2089
|
+
than `10e` (`2V/A`) marks its pieces lost; they are added again onto the bare result, up to 3 rounds.
|
|
2090
|
+
- `Simplify()` is not shape-safe (it moved 0.063 of a volume at 9e-12): each simplify is kept only
|
|
2091
|
+
if the volume and the count and genus of non-empty shells are unchanged. The last one, at
|
|
2092
|
+
`1e-9·scale` before moving back, collapses Manifold's own boolean slivers (vertices 1e-12 apart)
|
|
2093
|
+
while that is safe -- off the origin, Manifold collapsed them itself and once lost 0.114.
|
|
2094
|
+
- `cleanShells`: zero-volume shells are dropped, and each remaining shell is probed against the
|
|
2095
|
+
definition (in A, in a piece) so a spurious solid or void goes and a real one stays. A void is
|
|
2096
|
+
never `Compose`d back (Compose ignores an inside-out shell): solids minus voids turned right side
|
|
2097
|
+
out.
|
|
2098
|
+
- `|d|` below `1e-7` of the part's size returns the input: double precision cannot place it.
|
|
2099
|
+
|
|
2100
|
+
**Known limits.** Exact-contact chamfer cases (two faces meeting at precisely the distance where a
|
|
2101
|
+
chamfer closes) can come out with the wrong genus, 4 of the 96 in the review suite. Speed is about
|
|
2102
|
+
2 s for a 32-segment sphere's `delta=1` (pieces built single-threaded 1.1 s, union 0.85 s, lost
|
|
2103
|
+
check 0.4 s), so it is a tool for parts, not for dense scans. `OFFSET3D_TIMING=1` prints each phase's
|
|
2104
|
+
wall time to stderr. `_offset3d(verts, tris, d, mode, segs)` in the Python facade is the test hook
|
|
2105
|
+
the prototype's suites run against; not public API. Tests: `tests/test_offset3d.cpp`.
|
|
@@ -120,9 +120,13 @@ target_include_directories(openscad_cpp_parser PUBLIC
|
|
|
120
120
|
include(FetchContent)
|
|
121
121
|
|
|
122
122
|
# MANIFOLD_TEST off: we don't want Manifold's own (large) test/sample/extras
|
|
123
|
-
# suite built as part of this project. MANIFOLD_PAR
|
|
124
|
-
#
|
|
125
|
-
#
|
|
123
|
+
# suite built as part of this project. MANIFOLD_PAR on: Manifold's TBB
|
|
124
|
+
# backend made 3D offset() 2.1-3.3x faster (sphere(10,32) delta=1: 3.6 s ->
|
|
125
|
+
# 1.7 s), and big booleans with it. TBB is always Manifold's own pinned copy
|
|
126
|
+
# (oneTBB v2022.3.0, fetched and linked statically): a system TBB found by
|
|
127
|
+
# find_package would make the wheel depend on a library it does not ship.
|
|
128
|
+
# Booleans are not order-independent under it -- the same pieces unioned
|
|
129
|
+
# differently -- which offset3d.cpp's lostPieces() checks for. MANIFOLD_CROSS_SECTION
|
|
126
130
|
# stays at its own default (ON) -- 2D CrossSection support is needed from
|
|
127
131
|
# Phase 3 onward.
|
|
128
132
|
#
|
|
@@ -137,6 +141,8 @@ include(FetchContent)
|
|
|
137
141
|
# fixes Windows and is a no-op everywhere else this project already worked.
|
|
138
142
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
|
139
143
|
set(MANIFOLD_TEST OFF CACHE BOOL "" FORCE)
|
|
144
|
+
set(MANIFOLD_PAR ON CACHE BOOL "" FORCE)
|
|
145
|
+
set(MANIFOLD_USE_BUILTIN_TBB ON CACHE BOOL "" FORCE)
|
|
140
146
|
FetchContent_Declare(
|
|
141
147
|
manifold
|
|
142
148
|
GIT_REPOSITORY https://github.com/elalish/manifold.git
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
#include "openscad_cpp_evaluator/export.hpp"
|
|
26
26
|
#include "openscad_cpp_evaluator/freetype_font_provider.hpp"
|
|
27
27
|
#include "openscad_cpp_evaluator/mesh_check.hpp"
|
|
28
|
+
#include "openscad_cpp_evaluator/offset3d.hpp"
|
|
28
29
|
#include "openscad_cpp_evaluator/manifold_cache.hpp"
|
|
29
30
|
#include "openscad_cpp_evaluator/coverage.hpp"
|
|
30
31
|
#include "openscad_cpp_evaluator/profile.hpp"
|
|
@@ -306,6 +307,30 @@ nb::tuple stripSliversPy(const std::vector<float>& verts, const std::vector<uint
|
|
|
306
307
|
return nb::make_tuple(out.vertProperties, out.triVerts, rep);
|
|
307
308
|
}
|
|
308
309
|
|
|
310
|
+
// offset() on one closed mesh, without a script round trip: what the 3D
|
|
311
|
+
// offset's test suites drive. Double precision both ways -- the float32
|
|
312
|
+
// MeshGL is ~0.008 of resolution at 1e5. mode is "r", "delta" or "chamfer".
|
|
313
|
+
nb::tuple offset3dPy(const std::vector<double>& verts, const std::vector<uint64_t>& tris, double d,
|
|
314
|
+
const std::string& mode, int segs) {
|
|
315
|
+
manifold::MeshGL64 m;
|
|
316
|
+
m.numProp = 3;
|
|
317
|
+
m.vertProperties = verts;
|
|
318
|
+
m.triVerts = tris;
|
|
319
|
+
const oscadeval::Offset3DMode md = mode == "r" ? oscadeval::Offset3DMode::Round
|
|
320
|
+
: mode == "chamfer" ? oscadeval::Offset3DMode::Chamfer
|
|
321
|
+
: oscadeval::Offset3DMode::Delta;
|
|
322
|
+
manifold::MeshGL64 out;
|
|
323
|
+
std::vector<double> ov;
|
|
324
|
+
{
|
|
325
|
+
nb::gil_scoped_release rel;
|
|
326
|
+
out = oscadeval::offset3d(manifold::Manifold(m), d, md, segs).GetMeshGL64();
|
|
327
|
+
ov.reserve(out.NumVert() * 3);
|
|
328
|
+
for (size_t i = 0; i < out.NumVert(); ++i)
|
|
329
|
+
for (size_t k = 0; k < 3; ++k) ov.push_back(out.vertProperties[i * out.numProp + k]);
|
|
330
|
+
}
|
|
331
|
+
return nb::make_tuple(ov, out.triVerts);
|
|
332
|
+
}
|
|
333
|
+
|
|
309
334
|
nb::dict checkMeshPy(const std::vector<float>& verts, const std::vector<uint32_t>& tris) {
|
|
310
335
|
manifold::MeshGL m;
|
|
311
336
|
m.numProp = 3;
|
|
@@ -1052,6 +1077,9 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
|
|
|
1052
1077
|
m.def("strip_slivers", &stripSliversPy, nb::arg("verts"), nb::arg("tris"),
|
|
1053
1078
|
"Remove zero-area faces and repair the T-joints their removal "
|
|
1054
1079
|
"exposes. Returns (verts, tris, report).");
|
|
1080
|
+
m.def("offset3d", &offset3dPy, nb::arg("verts"), nb::arg("tris"), nb::arg("d"), nb::arg("mode"),
|
|
1081
|
+
nb::arg("segs"),
|
|
1082
|
+
"3D offset of one closed mesh: returns (verts, tris) as flat lists.");
|
|
1055
1083
|
m.def("check_mesh", &checkMeshPy, nb::arg("verts"), nb::arg("tris"),
|
|
1056
1084
|
"Diagnose a triangle mesh against the manifoldness conditions. "
|
|
1057
1085
|
"verts is a flat [x,y,z,...] list, tris a flat index list. Returns "
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// offset() on a 3D solid: r= (rounded, an inscribed faceted ball), delta=
|
|
4
|
+
// (mitered, no limit, as 2D) and chamfer= (corners cut flat), outward for
|
|
5
|
+
// d > 0 and inward for d < 0. Pure geometry: no evaluator state. See
|
|
6
|
+
// offset3d.cpp for the construction and CLAUDE.md "offset() in 3D".
|
|
7
|
+
|
|
8
|
+
#include <manifold/manifold.h>
|
|
9
|
+
|
|
10
|
+
namespace oscadeval {
|
|
11
|
+
|
|
12
|
+
enum class Offset3DMode { Round, Delta, Chamfer };
|
|
13
|
+
|
|
14
|
+
manifold::Manifold offset3d(const manifold::Manifold& m, double d, Offset3DMode mode, int segs);
|
|
15
|
+
|
|
16
|
+
} // namespace oscadeval
|
|
@@ -419,6 +419,13 @@ def export_extensions() -> list:
|
|
|
419
419
|
return list(_ext.export_extensions())
|
|
420
420
|
|
|
421
421
|
|
|
422
|
+
def _offset3d(verts, tris, d, mode="delta", segs=24):
|
|
423
|
+
"""3D offset of one closed mesh, as offset() does it for a solid: flat
|
|
424
|
+
vertex/triangle lists in, flat lists out. mode is "r", "delta" or
|
|
425
|
+
"chamfer". A test hook for the offset's suites, not public API."""
|
|
426
|
+
return _ext.offset3d([float(v) for v in verts], [int(t) for t in tris], float(d), mode, int(segs))
|
|
427
|
+
|
|
428
|
+
|
|
422
429
|
def check_mesh(verts, tris) -> dict:
|
|
423
430
|
"""Diagnose a triangle mesh against the manifoldness conditions.
|
|
424
431
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "builtins.hpp"
|
|
2
|
+
#include "openscad_cpp_evaluator/offset3d.hpp"
|
|
2
3
|
|
|
3
4
|
#include "openscad_cpp_evaluator/call_args.hpp"
|
|
4
5
|
#include "openscad_cpp_evaluator/evaluator.hpp"
|
|
@@ -542,17 +543,46 @@ CSGParams resolveOffset(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
542
543
|
return std::move(result.params);
|
|
543
544
|
}
|
|
544
545
|
|
|
545
|
-
std::vector<ColoredBody> generateOffset(Evaluator
|
|
546
|
-
const
|
|
546
|
+
std::vector<ColoredBody> generateOffset(Evaluator& ev, const CSGParams& params,
|
|
547
|
+
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
548
|
+
const oscad::ASTNode& node) {
|
|
547
549
|
const std::vector<ColoredBody> bodies = flattenCsgTree(children);
|
|
550
|
+
const double delta = std::get<double>(params.at("delta"));
|
|
551
|
+
const std::string& join = std::get<std::string>(params.at("join"));
|
|
552
|
+
const int segs = static_cast<int>(std::get<double>(params.at("segs")));
|
|
553
|
+
|
|
554
|
+
// 3D children (the dimension rule has already settled on one dimension
|
|
555
|
+
// and warned about the rest): the solid offset of offset3d.cpp.
|
|
556
|
+
const RoleSplit split = splitByRole(bodies);
|
|
557
|
+
std::vector<const ColoredBody*> solids;
|
|
558
|
+
for (const ColoredBody& b : split.foreground)
|
|
559
|
+
if (b.body && !b.body->IsEmpty()) solids.push_back(&b);
|
|
560
|
+
if (!solids.empty()) {
|
|
561
|
+
std::vector<ColoredBody> out;
|
|
562
|
+
if (std::isfinite(delta)) {
|
|
563
|
+
std::vector<manifold::Manifold> ms;
|
|
564
|
+
for (const ColoredBody* b : solids) ms.push_back(*b->body);
|
|
565
|
+
const manifold::Manifold a =
|
|
566
|
+
ms.size() == 1 ? ms[0] : manifold::Manifold::BatchBoolean(ms, manifold::OpType::Add);
|
|
567
|
+
const Offset3DMode mode = join == "round" ? Offset3DMode::Round
|
|
568
|
+
: join == "square" ? Offset3DMode::Chamfer
|
|
569
|
+
: Offset3DMode::Delta;
|
|
570
|
+
manifold::Manifold result = offset3d(a, delta, mode, segs);
|
|
571
|
+
if (!result.IsEmpty()) {
|
|
572
|
+
ColoredBody cb = ev.tagGenerated(std::move(result), node, Value{});
|
|
573
|
+
cb.color = valueToColor(params.at("color"));
|
|
574
|
+
out.push_back(std::move(cb));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
for (const auto* group : {&split.background, &split.highlight, &split.showOnly, &split.displayOnly})
|
|
578
|
+
out.insert(out.end(), group->begin(), group->end());
|
|
579
|
+
return out;
|
|
580
|
+
}
|
|
581
|
+
|
|
548
582
|
const std::optional<manifold::CrossSection> cs = toCrossSection(bodies);
|
|
549
583
|
if (!cs) return {};
|
|
550
|
-
|
|
551
|
-
const double delta = std::get<double>(params.at("delta"));
|
|
552
584
|
// An infinite (or NaN) distance has no shape to give.
|
|
553
585
|
if (!std::isfinite(delta)) return {};
|
|
554
|
-
const std::string& join = std::get<std::string>(params.at("join"));
|
|
555
|
-
const int segs = static_cast<int>(std::get<double>(params.at("segs")));
|
|
556
586
|
using JT = manifold::CrossSection::JoinType;
|
|
557
587
|
const JT jt = join == "round" ? JT::Round : join == "square" ? JT::Square : JT::Miter;
|
|
558
588
|
// "miter" joins stay sharp however acute the corner: no realistic
|
{openscad_cpp_evaluator-1.51.0 → openscad_cpp_evaluator-1.52.0}/src/builtins/function_builtins.cpp
RENAMED
|
@@ -1003,6 +1003,7 @@ const std::unordered_map<std::string, double>& featureLevels() {
|
|
|
1003
1003
|
{"profile-time", 1.0}, // profile_time(label) { ... } and profile_time(label) expr
|
|
1004
1004
|
{"alpha-wrap", 1.0}, // alpha_wrap(alpha, offset)
|
|
1005
1005
|
{"export-as", 1.0}, // export_as(name) { ... }
|
|
1006
|
+
{"offset-3d", 1.0}, // offset(r=|delta=, chamfer=) on a solid, in and out
|
|
1006
1007
|
};
|
|
1007
1008
|
return levels;
|
|
1008
1009
|
}
|