openscad-cpp-evaluator 1.49.4__tar.gz → 1.49.6__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.49.4 → openscad_cpp_evaluator-1.49.6}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/colored_body.hpp +6 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/mesh_check.hpp +14 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/booleans.cpp +5 -2
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/extrude.cpp +8 -2
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/primitives_3d.cpp +10 -15
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/mesh_check.cpp +96 -43
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_extrude_roof.cpp +40 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_primitives.cpp +17 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/README.md +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/cmake/patch_manifold.cmake +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/LICENSE +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/reassign.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_openscad_parity.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_undef_args.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/uv.lock +0 -0
|
@@ -132,6 +132,12 @@ struct ColoredBody {
|
|
|
132
132
|
bool isDisplayOnly() const { return rawMesh.has_value(); }
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
+
// A `%` body or a `#` operand's ghost copy: drawn, never part of the model,
|
|
136
|
+
// so an operation that consumes its children's geometry must skip it.
|
|
137
|
+
inline bool isModifierGhost(const ColoredBody& b) {
|
|
138
|
+
return b.role == BodyRole::Background || b.role == BodyRole::HighlightGhost;
|
|
139
|
+
}
|
|
140
|
+
|
|
135
141
|
// The cached questions -- see ColoredBody::knownEmpty. Ask Manifold once per
|
|
136
142
|
// body, never once per tree level.
|
|
137
143
|
inline bool bodyIsEmpty(ColoredBody& b) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <cstddef>
|
|
3
4
|
#include <cstdint>
|
|
4
5
|
#include <string>
|
|
5
6
|
#include <vector>
|
|
@@ -82,6 +83,19 @@ struct MeshRepairReport {
|
|
|
82
83
|
std::string summary() const;
|
|
83
84
|
};
|
|
84
85
|
|
|
86
|
+
// Weld points on a grid of `tolerance`: returns, for each point, the index
|
|
87
|
+
// of the lowest-numbered point it welds to (itself if none). Points in one
|
|
88
|
+
// grid cell weld, as rounding to the grid always did -- and so do points
|
|
89
|
+
// within tolerance/32 of each other across a cell boundary, which rounding
|
|
90
|
+
// alone splits however close they are: two copies of a vertex at x*1e6 ==
|
|
91
|
+
// 10454062.5, a few ULPs apart, round to different cells (BelfrySCAD #832).
|
|
92
|
+
// `data` holds `n` points, each starting `stride` values after the last.
|
|
93
|
+
// A tolerance of 0 or less welds exact duplicates only.
|
|
94
|
+
template <typename T>
|
|
95
|
+
std::vector<size_t> weldPoints(const T* data, size_t n, size_t stride, double tolerance);
|
|
96
|
+
extern template std::vector<size_t> weldPoints<float>(const float*, size_t, size_t, double);
|
|
97
|
+
extern template std::vector<size_t> weldPoints<double>(const double*, size_t, size_t, double);
|
|
98
|
+
|
|
85
99
|
//: Default welding tolerance: OpenSCAD's own GRID_FINE, 2^-20. Theirs is
|
|
86
100
|
//: the constant their Grid.h uses to decide two points are one, so a mesh
|
|
87
101
|
//: that welds there welds here. Exact in binary, so the multiply-and-round
|
|
@@ -64,11 +64,14 @@ RoleSplit splitByRole(const std::vector<ColoredBody>& bodies) {
|
|
|
64
64
|
|
|
65
65
|
// Unions every 2D child into a single CrossSection; nullopt if there are no
|
|
66
66
|
// 2D children at all. Mirrors _to_cross_section. Shared by
|
|
67
|
-
// linear_extrude/rotate_extrude/roof (extrude.cpp, roof.cpp).
|
|
67
|
+
// linear_extrude/rotate_extrude/offset/roof (extrude.cpp, roof.cpp).
|
|
68
|
+
// A `%` body and a `#` operand's ghost copy are display aids, not model:
|
|
69
|
+
// unioning them in filled a differenced-away notch back in (BelfrySCAD
|
|
70
|
+
// #866). OpenSCAD shows neither under these operations, so they are dropped.
|
|
68
71
|
std::optional<manifold::CrossSection> toCrossSection(const std::vector<ColoredBody>& bodies) {
|
|
69
72
|
std::optional<manifold::CrossSection> cs;
|
|
70
73
|
for (const ColoredBody& b : bodies) {
|
|
71
|
-
if (!b.section) continue;
|
|
74
|
+
if (!b.section || isModifierGhost(b)) continue;
|
|
72
75
|
cs = cs ? (*cs + *b.section) : *b.section;
|
|
73
76
|
}
|
|
74
77
|
return cs;
|
|
@@ -471,14 +471,20 @@ std::vector<ColoredBody> generateProjection(Evaluator&, const CSGParams& params,
|
|
|
471
471
|
const std::vector<ColoredBody> bodies = flattenCsgTree(children);
|
|
472
472
|
std::vector<ColoredBody> bodies3d;
|
|
473
473
|
for (const ColoredBody& c : bodies) {
|
|
474
|
-
|
|
474
|
+
// Not a `%` body or a `#` ghost: projecting them drew the
|
|
475
|
+
// differenced-away part's outline (BelfrySCAD #866). See toCrossSection.
|
|
476
|
+
if (c.body && !isModifierGhost(c)) bodies3d.push_back(c);
|
|
475
477
|
}
|
|
476
478
|
if (bodies3d.empty()) return {};
|
|
477
479
|
|
|
478
480
|
const ColoredBody combined = combineBodies(bodies3d);
|
|
479
481
|
manifold::CrossSection cs;
|
|
480
482
|
if (std::get<bool>(params.at("cut"))) {
|
|
481
|
-
|
|
483
|
+
// Positive, as OpenSCAD fills it. A self-overlapping polyhedron (a
|
|
484
|
+
// rope spool whose loops overlap, BelfrySCAD #831) slices to
|
|
485
|
+
// overlapping contours, and EvenOdd cut every overlap out as a hole.
|
|
486
|
+
// A clean solid slices the same either way.
|
|
487
|
+
cs = manifold::CrossSection(combined.body->Slice(0.0), manifold::CrossSection::FillRule::Positive);
|
|
482
488
|
} else {
|
|
483
489
|
const manifold::Polygons polys = combined.body->Project();
|
|
484
490
|
cs = polys.empty() ? manifold::CrossSection() : manifold::CrossSection(polys, manifold::CrossSection::FillRule::Positive);
|
{openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/src/builtins/primitives_3d.cpp
RENAMED
|
@@ -889,21 +889,16 @@ CSGParams resolvePolyhedron(Evaluator& ev, const oscad::ModularCall& node, EvalC
|
|
|
889
889
|
|
|
890
890
|
std::vector<std::array<double, 3>> uniqueVerts;
|
|
891
891
|
std::vector<size_t> remap(rawVerts.size());
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
} else {
|
|
903
|
-
const size_t newIdx = uniqueVerts.size();
|
|
904
|
-
uniqueVerts.push_back(rawVerts[i]);
|
|
905
|
-
seen[key] = newIdx;
|
|
906
|
-
remap[i] = newIdx;
|
|
892
|
+
{
|
|
893
|
+
const std::vector<size_t> rep =
|
|
894
|
+
weldPoints(rawVerts.empty() ? nullptr : rawVerts.front().data(), rawVerts.size(), 3, 1e-6);
|
|
895
|
+
for (size_t i = 0; i < rawVerts.size(); ++i) {
|
|
896
|
+
if (rep[i] == i) {
|
|
897
|
+
remap[i] = uniqueVerts.size();
|
|
898
|
+
uniqueVerts.push_back(rawVerts[i]);
|
|
899
|
+
} else {
|
|
900
|
+
remap[i] = remap[rep[i]]; // rep[i] < i, so already numbered
|
|
901
|
+
}
|
|
907
902
|
}
|
|
908
903
|
}
|
|
909
904
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#include "openscad_cpp_evaluator/mesh_check.hpp"
|
|
2
2
|
|
|
3
3
|
#include <algorithm>
|
|
4
|
+
#include <array>
|
|
5
|
+
#include <cstring>
|
|
4
6
|
#include <cmath>
|
|
5
7
|
#include <map>
|
|
6
8
|
#include <set>
|
|
@@ -65,14 +67,9 @@ template <typename M>
|
|
|
65
67
|
size_t countUnwelded(const M& m) {
|
|
66
68
|
const size_t stride = m.numProp ? m.numProp : 3;
|
|
67
69
|
const size_t n = stride ? m.vertProperties.size() / stride : 0;
|
|
68
|
-
std::
|
|
70
|
+
const std::vector<size_t> rep = weldPoints(m.vertProperties.data(), n, stride, 1e-6);
|
|
69
71
|
size_t extra = 0;
|
|
70
|
-
for (size_t v = 0; v < n; ++v)
|
|
71
|
-
double p[3];
|
|
72
|
-
pos(m, static_cast<Vert>(v), p);
|
|
73
|
-
auto key = std::make_tuple(llround(p[0] * 1e6), llround(p[1] * 1e6), llround(p[2] * 1e6));
|
|
74
|
-
if (++seen[key] > 1) ++extra;
|
|
75
|
-
}
|
|
72
|
+
for (size_t v = 0; v < n; ++v) extra += rep[v] != v;
|
|
76
73
|
return extra;
|
|
77
74
|
}
|
|
78
75
|
|
|
@@ -312,45 +309,12 @@ template <typename M>
|
|
|
312
309
|
std::vector<Vert> weldMap(const M& m, size_t& welded, double tolerance) {
|
|
313
310
|
const size_t stride = m.numProp ? m.numProp : 3;
|
|
314
311
|
const size_t n = stride ? m.vertProperties.size() / stride : 0;
|
|
312
|
+
const std::vector<size_t> rep = weldPoints(m.vertProperties.data(), n, stride, tolerance);
|
|
315
313
|
std::vector<Vert> remap(n);
|
|
316
314
|
welded = 0;
|
|
317
|
-
|
|
318
|
-
// Grid key plus the vertex it came from, sorted so that equal positions
|
|
319
|
-
// land in a run. This was a std::map keyed by the tuple -- one tree node
|
|
320
|
-
// per VERTEX, ~885,000 of them for a 295K-triangle import -- and sorting
|
|
321
|
-
// gets the same answer with one allocation. Sorting by (key, vertex)
|
|
322
|
-
// puts the LOWEST-numbered vertex first in its run, which is the one
|
|
323
|
-
// emplace() kept as the representative, so the remap is unchanged.
|
|
324
|
-
struct Keyed {
|
|
325
|
-
long long x, y, z;
|
|
326
|
-
Vert v;
|
|
327
|
-
bool operator<(const Keyed& o) const {
|
|
328
|
-
if (x != o.x) return x < o.x;
|
|
329
|
-
if (y != o.y) return y < o.y;
|
|
330
|
-
if (z != o.z) return z < o.z;
|
|
331
|
-
return v < o.v;
|
|
332
|
-
}
|
|
333
|
-
bool samePos(const Keyed& o) const { return x == o.x && y == o.y && z == o.z; }
|
|
334
|
-
};
|
|
335
|
-
// Snap to a grid of `tolerance`. Guarded because a caller can pass 0 or
|
|
336
|
-
// a negative to mean "weld only exact duplicates" -- dividing by that
|
|
337
|
-
// would give inf/NaN keys and weld the whole mesh into one point.
|
|
338
|
-
const double inv = tolerance > 0.0 ? 1.0 / tolerance : 0.0;
|
|
339
|
-
std::vector<Keyed> keyed;
|
|
340
|
-
keyed.reserve(n);
|
|
341
315
|
for (size_t v = 0; v < n; ++v) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
keyed.push_back({llround(p[0] * inv), llround(p[1] * inv), llround(p[2] * inv),
|
|
345
|
-
static_cast<Vert>(v)});
|
|
346
|
-
}
|
|
347
|
-
std::sort(keyed.begin(), keyed.end());
|
|
348
|
-
for (size_t i = 0; i < keyed.size();) {
|
|
349
|
-
size_t j = i + 1;
|
|
350
|
-
while (j < keyed.size() && keyed[j].samePos(keyed[i])) ++j;
|
|
351
|
-
for (size_t k = i; k < j; ++k) remap[keyed[k].v] = keyed[i].v;
|
|
352
|
-
welded += j - i - 1;
|
|
353
|
-
i = j;
|
|
316
|
+
remap[v] = static_cast<Vert>(rep[v]);
|
|
317
|
+
welded += rep[v] != v;
|
|
354
318
|
}
|
|
355
319
|
return remap;
|
|
356
320
|
}
|
|
@@ -849,6 +813,93 @@ M stripSlivers(const M& mesh, SliverStripReport& report) {
|
|
|
849
813
|
}
|
|
850
814
|
|
|
851
815
|
|
|
816
|
+
template <typename T>
|
|
817
|
+
std::vector<size_t> weldPoints(const T* data, size_t n, size_t stride, double tolerance) {
|
|
818
|
+
std::vector<size_t> parent(n);
|
|
819
|
+
for (size_t i = 0; i < n; ++i) parent[i] = i;
|
|
820
|
+
auto find = [&](size_t v) {
|
|
821
|
+
while (parent[v] != v) v = parent[v] = parent[parent[v]];
|
|
822
|
+
return v;
|
|
823
|
+
};
|
|
824
|
+
// The lower index stays the root, so each point maps to the lowest it welds to.
|
|
825
|
+
auto unite = [&](size_t a, size_t b) {
|
|
826
|
+
a = find(a);
|
|
827
|
+
b = find(b);
|
|
828
|
+
if (a != b) parent[std::max(a, b)] = std::min(a, b);
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
// Grid key plus the point it came from, sorted so that one cell is a
|
|
832
|
+
// run. Sorting rather than a map: one allocation, not a tree or hash
|
|
833
|
+
// node per vertex (~885,000 of them for a 295K-triangle import).
|
|
834
|
+
struct Keyed {
|
|
835
|
+
int64_t k[3];
|
|
836
|
+
size_t v;
|
|
837
|
+
bool operator<(const Keyed& o) const {
|
|
838
|
+
for (int a = 0; a < 3; ++a)
|
|
839
|
+
if (k[a] != o.k[a]) return k[a] < o.k[a];
|
|
840
|
+
return v < o.v;
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
const bool exact = !(tolerance > 0.0);
|
|
844
|
+
const double inv = exact ? 0.0 : 1.0 / tolerance;
|
|
845
|
+
// How near a cell boundary a point must be to be compared with the
|
|
846
|
+
// next cell's points. Well above rounding noise, well below a grid
|
|
847
|
+
// step, and rare enough (~6% of points) to cost nothing.
|
|
848
|
+
constexpr double kNear = 1.0 / 64;
|
|
849
|
+
std::vector<Keyed> keyed(n);
|
|
850
|
+
std::vector<std::pair<size_t, std::array<int, 3>>> leaning; // (point, which way per axis)
|
|
851
|
+
for (size_t i = 0; i < n; ++i) {
|
|
852
|
+
const T* p = data + i * stride;
|
|
853
|
+
std::array<int, 3> lean{};
|
|
854
|
+
for (int a = 0; a < 3; ++a) {
|
|
855
|
+
if (exact) {
|
|
856
|
+
const double c = static_cast<double>(p[a]) + 0.0; // -0 and 0 are one position
|
|
857
|
+
std::memcpy(&keyed[i].k[a], &c, sizeof c);
|
|
858
|
+
continue;
|
|
859
|
+
}
|
|
860
|
+
const double s = p[a] * inv;
|
|
861
|
+
keyed[i].k[a] = std::llround(s);
|
|
862
|
+
const double f = s - static_cast<double>(keyed[i].k[a]); // in [-0.5, 0.5]
|
|
863
|
+
lean[a] = f > 0.5 - kNear ? 1 : f < -0.5 + kNear ? -1 : 0;
|
|
864
|
+
}
|
|
865
|
+
keyed[i].v = i;
|
|
866
|
+
if (lean[0] || lean[1] || lean[2]) leaning.push_back({i, lean});
|
|
867
|
+
}
|
|
868
|
+
std::vector<Keyed> sorted = keyed;
|
|
869
|
+
std::sort(sorted.begin(), sorted.end());
|
|
870
|
+
for (size_t i = 1; i < n; ++i)
|
|
871
|
+
if (std::equal(sorted[i].k, sorted[i].k + 3, sorted[i - 1].k)) unite(sorted[i - 1].v, sorted[i].v);
|
|
872
|
+
|
|
873
|
+
// Across a boundary: each cell the point leans toward, by each subset
|
|
874
|
+
// of the axes it leans on, compared point by point.
|
|
875
|
+
const double reach = 2 * kNear * tolerance;
|
|
876
|
+
for (const auto& [i, lean] : leaning) {
|
|
877
|
+
const T* p = data + i * stride;
|
|
878
|
+
for (int mask = 1; mask < 8; ++mask) {
|
|
879
|
+
Keyed probe{{keyed[i].k[0], keyed[i].k[1], keyed[i].k[2]}, 0};
|
|
880
|
+
bool any = true;
|
|
881
|
+
for (int a = 0; a < 3; ++a) {
|
|
882
|
+
if (!(mask & (1 << a))) continue;
|
|
883
|
+
if (!lean[a]) { any = false; break; }
|
|
884
|
+
probe.k[a] += lean[a];
|
|
885
|
+
}
|
|
886
|
+
if (!any) continue;
|
|
887
|
+
for (auto it = std::lower_bound(sorted.begin(), sorted.end(), probe);
|
|
888
|
+
it != sorted.end() && std::equal(it->k, it->k + 3, probe.k); ++it) {
|
|
889
|
+
const T* q = data + it->v * stride;
|
|
890
|
+
if (std::abs(p[0] - q[0]) <= reach && std::abs(p[1] - q[1]) <= reach
|
|
891
|
+
&& std::abs(p[2] - q[2]) <= reach)
|
|
892
|
+
unite(i, it->v);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
std::vector<size_t> rep(n);
|
|
898
|
+
for (size_t i = 0; i < n; ++i) rep[i] = find(i);
|
|
899
|
+
return rep;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
|
|
852
903
|
// Instantiated for both precisions: MeshGL for the paths that are float by
|
|
853
904
|
// nature (STL, the renderer), MeshGL64 wherever the caller still has its
|
|
854
905
|
// real coordinates. Keeping the definitions in this file, rather than the
|
|
@@ -859,5 +910,7 @@ template manifold::MeshGL repairMesh<manifold::MeshGL>(const manifold::MeshGL&,
|
|
|
859
910
|
template manifold::MeshGL64 repairMesh<manifold::MeshGL64>(const manifold::MeshGL64&, MeshRepairReport&, double);
|
|
860
911
|
template manifold::MeshGL stripSlivers<manifold::MeshGL>(const manifold::MeshGL&, SliverStripReport&);
|
|
861
912
|
template manifold::MeshGL64 stripSlivers<manifold::MeshGL64>(const manifold::MeshGL64&, SliverStripReport&);
|
|
913
|
+
template std::vector<size_t> weldPoints<float>(const float*, size_t, size_t, double);
|
|
914
|
+
template std::vector<size_t> weldPoints<double>(const double*, size_t, size_t, double);
|
|
862
915
|
|
|
863
916
|
} // namespace oscadeval
|
|
@@ -245,6 +245,46 @@ TEST(Projection, CutSlicesAtZEqualsZero) {
|
|
|
245
245
|
EXPECT_TRUE(area < 1e-6 || std::fabs(area - 6.0) < 1e-6);
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
// One polyhedron holding two overlapping cube shells, as a self-overlapping
|
|
249
|
+
// mesh like a tightly wound rope spool is (BelfrySCAD #831). Its slice is
|
|
250
|
+
// the union of the two squares, as OpenSCAD fills it -- not the two squares
|
|
251
|
+
// with their overlap cut out.
|
|
252
|
+
TEST(Projection, CutFillsWhereAPolyhedronOverlapsItself) {
|
|
253
|
+
Evaluated e = evalSrc(
|
|
254
|
+
"function box(o) = [for (z=[-1,1], y=[0,2], x=[0,2]) [x+o, y, z]];"
|
|
255
|
+
"f = [[0,1,3,2],[4,6,7,5],[0,4,5,1],[2,3,7,6],[0,2,6,4],[1,5,7,3]];"
|
|
256
|
+
"projection(cut=true) polyhedron(concat(box(0), box(1)),"
|
|
257
|
+
" concat([for (q=f) [for (i=q) i]], [for (q=f) [for (i=q) i+8]]));");
|
|
258
|
+
ASSERT_EQ(e.bodies.size(), 1u);
|
|
259
|
+
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
260
|
+
EXPECT_NEAR(e.bodies[0].section->Area(), 6.0, 1e-6);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// A `#` operand is drawn again as a ghost and a `%` body is drawn but not
|
|
264
|
+
// modelled; neither may reach the operation. Both leaked into projection()
|
|
265
|
+
// and every 2D-consuming operation (BelfrySCAD #866): the ghost refilled
|
|
266
|
+
// the cut-away corner and the `%` cube added its square.
|
|
267
|
+
TEST(Projection, ModifierGhostsAreNotProjected) {
|
|
268
|
+
for (const char* src : {
|
|
269
|
+
"projection() difference() { cube([4,4,1]); #translate([-1,-1,-1]) cube(3); }",
|
|
270
|
+
"projection() union() { difference() { cube([4,4,1]); #translate([-1,-1,-1]) cube(3); }"
|
|
271
|
+
" %translate([10,0,0]) cube(1); }"}) {
|
|
272
|
+
Evaluated e = evalSrc(src);
|
|
273
|
+
double area = 0;
|
|
274
|
+
for (const ColoredBody& b : e.bodies)
|
|
275
|
+
if (b.section) area += b.section->Area();
|
|
276
|
+
EXPECT_NEAR(area, 12.0, 1e-6) << src;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
TEST(LinearExtrude, ModifierGhostsAreNotExtruded) {
|
|
281
|
+
Evaluated e = evalSrc("linear_extrude(1) difference() { square(4); #translate([-1,-1]) square(3); }");
|
|
282
|
+
double volume = 0;
|
|
283
|
+
for (const ColoredBody& b : e.bodies)
|
|
284
|
+
if (b.body) volume += b.body->Volume();
|
|
285
|
+
EXPECT_NEAR(volume, 12.0, 1e-6);
|
|
286
|
+
}
|
|
287
|
+
|
|
248
288
|
// -- offset -----------------------------------------------------------------
|
|
249
289
|
|
|
250
290
|
TEST(Offset, RoundGrowsAreaBySquarePerimeterPlusCircleCorners) {
|
|
@@ -153,6 +153,23 @@ TEST(Polyhedron, TetrahedronVolumeMatchesAnalyticFormula) {
|
|
|
153
153
|
EXPECT_NEAR(e.bodies[0].body->Volume(), 4.0 / 3.0, 1e-6);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// Two copies of a corner a few ULPs apart, either side of a weld-grid
|
|
157
|
+
// boundary (x*1e6 == 0.5): rounding to the grid put them in different cells,
|
|
158
|
+
// so the seam stayed open and a sound BOSL2 thread drew as an open surface
|
|
159
|
+
// (BelfrySCAD #832). They weld now, and the solid is closed.
|
|
160
|
+
TEST(Polyhedron, TwinVerticesStraddlingTheWeldGridStillWeld) {
|
|
161
|
+
std::vector<std::string> log;
|
|
162
|
+
Evaluated e = evalSrc("a = 5e-7 * (1 - 1e-12); b = 5e-7 * (1 + 1e-12);"
|
|
163
|
+
"polyhedron("
|
|
164
|
+
"points=[[a,0,0],[2,0,0],[0,2,0],[0,0,2],[b,0,0]], "
|
|
165
|
+
"faces=[[0,1,2],[0,3,1],[4,2,3],[1,3,2]]);",
|
|
166
|
+
[&](const std::string& m) { log.push_back(m); });
|
|
167
|
+
EXPECT_TRUE(log.empty()) << log[0];
|
|
168
|
+
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
169
|
+
EXPECT_EQ(e.bodies[0].body->Status(), manifold::Manifold::Error::NoError);
|
|
170
|
+
EXPECT_NEAR(e.bodies[0].body->Volume(), 4.0 / 3.0, 1e-5);
|
|
171
|
+
}
|
|
172
|
+
|
|
156
173
|
TEST(Polyhedron, MissingFacesWarnsAndDrawsNothing) {
|
|
157
174
|
// Upstream builtin_polyhedron warns and draws nothing; the rest of the
|
|
158
175
|
// script carries on (this used to stop the render).
|
|
File without changes
|
{openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/.github/workflows/wheels.yml
RENAMED
|
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
|
{openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.49.4 → openscad_cpp_evaluator-1.49.6}/external/openscad_cpp_parser/LICENSE
RENAMED
|
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
|
|
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
|
|
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
|