openscad-cpp-evaluator 1.7.0__tar.gz → 1.7.2__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.7.0 → openscad_cpp_evaluator-1.7.2}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/bytecode.hpp +9 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/bytecode_compiler.cpp +24 -11
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/bytecode_vm.cpp +11 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/mesh_check.cpp +99 -28
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_bytecode_compiler.cpp +32 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_mesh_check.cpp +27 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/README.md +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/uv.lock +0 -0
|
@@ -816,6 +816,15 @@ struct CompiledChunk {
|
|
|
816
816
|
// and copying it back out.
|
|
817
817
|
struct ArgBind {
|
|
818
818
|
int paramIndex = -1; // >=0: this argument binds that parameter
|
|
819
|
+
// Any FURTHER parameters of the same name. Normally empty, but a
|
|
820
|
+
// declaration may repeat a parameter name -- BOSL2's
|
|
821
|
+
// regular_prism() declares both `length` and `height` twice --
|
|
822
|
+
// and the name-matching path this replaced bound every one of
|
|
823
|
+
// them, because it walked the parameter list asking "is there a
|
|
824
|
+
// bound argument called this?" rather than the other way round.
|
|
825
|
+
// Binding only the first silently left the body reading undef
|
|
826
|
+
// from whichever slot the duplicate name finally resolved to.
|
|
827
|
+
std::vector<int> alsoParams;
|
|
819
828
|
bool toDyn = false; // instead bind by name into ctx.dyn ($-named, undeclared)
|
|
820
829
|
bool warnUnexpectedNamed = false;
|
|
821
830
|
bool warnTooManyPositional = false;
|
|
@@ -20,6 +20,22 @@
|
|
|
20
20
|
namespace oscadeval {
|
|
21
21
|
|
|
22
22
|
namespace {
|
|
23
|
+
// Records every parameter called `name`, not just the first. See
|
|
24
|
+
// CompiledChunk::CallSite::ArgBind::alsoParams for why there can be more
|
|
25
|
+
// than one.
|
|
26
|
+
void bindEveryParamNamed(CompiledChunk::CallSite::ArgBind& b,
|
|
27
|
+
const std::vector<std::unique_ptr<oscad::ParameterDeclaration>>& params,
|
|
28
|
+
const std::string& name) {
|
|
29
|
+
for (size_t p = 0; p < params.size(); ++p) {
|
|
30
|
+
if (params[p]->name->name != name) continue;
|
|
31
|
+
if (b.paramIndex < 0) {
|
|
32
|
+
b.paramIndex = static_cast<int>(p);
|
|
33
|
+
} else {
|
|
34
|
+
b.alsoParams.push_back(static_cast<int>(p));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
// Replays buildBoundArgs' own positional/named matching rule (bytecode_vm.cpp)
|
|
24
40
|
// against a parameter list known at compile time, recording the answer per
|
|
25
41
|
// argument instead of recomputing it per call. The rule, unchanged: a named
|
|
@@ -38,19 +54,16 @@ void planCallSiteArgs(CompiledChunk::CallSite& site,
|
|
|
38
54
|
CompiledChunk::CallSite::ArgBind& b = site.argBinds[i];
|
|
39
55
|
if (site.argNames[i]) {
|
|
40
56
|
const std::string& name = *site.argNames[i];
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
b.paramIndex = found;
|
|
49
|
-
b.warnUnexpectedNamed = (found < 0) && !isConfigVariable(name);
|
|
50
|
-
b.toDyn = (found < 0) && !name.empty() && name[0] == '$';
|
|
57
|
+
bindEveryParamNamed(b, params, name);
|
|
58
|
+
const bool found = b.paramIndex >= 0;
|
|
59
|
+
b.warnUnexpectedNamed = !found && !isConfigVariable(name);
|
|
60
|
+
b.toDyn = !found && !name.empty() && name[0] == '$';
|
|
51
61
|
} else {
|
|
52
62
|
if (positionalIdx < nparams) {
|
|
53
|
-
|
|
63
|
+
// By NAME, not just by index: a positional argument landing on
|
|
64
|
+
// a repeated name filled every parameter of that name too,
|
|
65
|
+
// because the old path keyed its bound arguments by name.
|
|
66
|
+
bindEveryParamNamed(b, params, params[positionalIdx]->name->name);
|
|
54
67
|
} else if (positionalIdx == nparams) {
|
|
55
68
|
b.warnTooManyPositional = true;
|
|
56
69
|
}
|
|
@@ -151,6 +151,17 @@ void bindPlannedArgsIntoFrame(const CompiledChunk& chunk, const CompiledChunk::C
|
|
|
151
151
|
for (size_t i = 0; i < argCount; ++i) {
|
|
152
152
|
const CompiledChunk::CallSite::ArgBind& b = site.argBinds[i];
|
|
153
153
|
if (b.paramIndex >= 0) {
|
|
154
|
+
// The duplicate-name case (alsoParams) needs the value more than
|
|
155
|
+
// once, so it is copied there and only the last one moves.
|
|
156
|
+
for (const int extra : b.alsoParams) {
|
|
157
|
+
const CompiledChunk::Param& e = chunk.params[static_cast<size_t>(extra)];
|
|
158
|
+
if (e.isDyn) {
|
|
159
|
+
ctx.dyn->set(e.name, args[i]);
|
|
160
|
+
} else {
|
|
161
|
+
frame.slots[static_cast<size_t>(e.slot)] = args[i];
|
|
162
|
+
}
|
|
163
|
+
frame.bound[static_cast<size_t>(extra)] = true;
|
|
164
|
+
}
|
|
154
165
|
const CompiledChunk::Param& p = chunk.params[static_cast<size_t>(b.paramIndex)];
|
|
155
166
|
if (p.isDyn) {
|
|
156
167
|
ctx.dyn->set(p.name, std::move(args[i]));
|
|
@@ -257,16 +257,40 @@ template <typename M>
|
|
|
257
257
|
std::vector<Vert> weldMap(const M& m, size_t& welded) {
|
|
258
258
|
const size_t stride = m.numProp ? m.numProp : 3;
|
|
259
259
|
const size_t n = stride ? m.vertProperties.size() / stride : 0;
|
|
260
|
-
std::map<std::tuple<long long, long long, long long>, Vert> first;
|
|
261
260
|
std::vector<Vert> remap(n);
|
|
262
261
|
welded = 0;
|
|
262
|
+
|
|
263
|
+
// Grid key plus the vertex it came from, sorted so that equal positions
|
|
264
|
+
// land in a run. This was a std::map keyed by the tuple -- one tree node
|
|
265
|
+
// per VERTEX, ~885,000 of them for a 295K-triangle import -- and sorting
|
|
266
|
+
// gets the same answer with one allocation. Sorting by (key, vertex)
|
|
267
|
+
// puts the LOWEST-numbered vertex first in its run, which is the one
|
|
268
|
+
// emplace() kept as the representative, so the remap is unchanged.
|
|
269
|
+
struct Keyed {
|
|
270
|
+
long long x, y, z;
|
|
271
|
+
Vert v;
|
|
272
|
+
bool operator<(const Keyed& o) const {
|
|
273
|
+
if (x != o.x) return x < o.x;
|
|
274
|
+
if (y != o.y) return y < o.y;
|
|
275
|
+
if (z != o.z) return z < o.z;
|
|
276
|
+
return v < o.v;
|
|
277
|
+
}
|
|
278
|
+
bool samePos(const Keyed& o) const { return x == o.x && y == o.y && z == o.z; }
|
|
279
|
+
};
|
|
280
|
+
std::vector<Keyed> keyed;
|
|
281
|
+
keyed.reserve(n);
|
|
263
282
|
for (size_t v = 0; v < n; ++v) {
|
|
264
283
|
double p[3];
|
|
265
284
|
pos(m, static_cast<Vert>(v), p);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
285
|
+
keyed.push_back({llround(p[0] * 1e6), llround(p[1] * 1e6), llround(p[2] * 1e6), static_cast<Vert>(v)});
|
|
286
|
+
}
|
|
287
|
+
std::sort(keyed.begin(), keyed.end());
|
|
288
|
+
for (size_t i = 0; i < keyed.size();) {
|
|
289
|
+
size_t j = i + 1;
|
|
290
|
+
while (j < keyed.size() && keyed[j].samePos(keyed[i])) ++j;
|
|
291
|
+
for (size_t k = i; k < j; ++k) remap[keyed[k].v] = keyed[i].v;
|
|
292
|
+
welded += j - i - 1;
|
|
293
|
+
i = j;
|
|
270
294
|
}
|
|
271
295
|
return remap;
|
|
272
296
|
}
|
|
@@ -274,17 +298,28 @@ std::vector<Vert> weldMap(const M& m, size_t& welded) {
|
|
|
274
298
|
// Boundary loops, as ordered vertex rings. Each boundary edge belongs to
|
|
275
299
|
// exactly one, so following them from any start returns to it.
|
|
276
300
|
std::vector<std::vector<Vert>> boundaryLoops(const std::vector<std::array<Vert, 3>>& tris) {
|
|
277
|
-
|
|
278
|
-
std::
|
|
301
|
+
// Every edge, sorted, so "used exactly once" is a run of length one --
|
|
302
|
+
// the same answer the std::map<Edge,int> gave, without a tree node per
|
|
303
|
+
// edge. `next` stays a multimap: boundary edges are a handful even on a
|
|
304
|
+
// badly broken mesh, and it is erased from while being traversed.
|
|
305
|
+
std::vector<uint64_t> edges;
|
|
306
|
+
edges.reserve(tris.size() * 3);
|
|
279
307
|
for (const auto& t : tris) {
|
|
280
|
-
for (int i = 0; i < 3; ++i)
|
|
308
|
+
for (int i = 0; i < 3; ++i) edges.push_back(edgeKey(undirected(t[i], t[(i + 1) % 3])));
|
|
281
309
|
}
|
|
310
|
+
std::sort(edges.begin(), edges.end());
|
|
311
|
+
const auto usedOnce = [&edges](uint64_t key) {
|
|
312
|
+
const auto lo = std::lower_bound(edges.begin(), edges.end(), key);
|
|
313
|
+
return lo != edges.end() && *lo == key && (lo + 1 == edges.end() || *(lo + 1) != key);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
std::multimap<Vert, Vert> next; // directed, along the boundary
|
|
282
317
|
for (const auto& t : tris) {
|
|
283
318
|
for (int i = 0; i < 3; ++i) {
|
|
284
319
|
const Vert a = t[i], b = t[(i + 1) % 3];
|
|
285
320
|
// A boundary edge is walked backwards to close the hole: the
|
|
286
321
|
// filling faces must wind against the face that owns the edge.
|
|
287
|
-
if (
|
|
322
|
+
if (usedOnce(edgeKey(undirected(a, b)))) next.emplace(b, a);
|
|
288
323
|
}
|
|
289
324
|
}
|
|
290
325
|
std::vector<std::vector<Vert>> loops;
|
|
@@ -320,25 +355,45 @@ M repairMesh(const M& mesh, MeshRepairReport& report) {
|
|
|
320
355
|
const std::vector<Vert> remap = weldMap(mesh, welded);
|
|
321
356
|
report.weldedVertices = welded;
|
|
322
357
|
|
|
323
|
-
|
|
324
|
-
std::set
|
|
325
|
-
|
|
358
|
+
// Remap every face, then find the duplicates by sorting rather than by
|
|
359
|
+
// inserting each into a std::set -- one tree node per face otherwise.
|
|
360
|
+
// "First occurrence wins" survives because the sort carries the face
|
|
361
|
+
// index and every later member of a run is what gets marked.
|
|
362
|
+
const size_t nTris = triCount(mesh);
|
|
363
|
+
std::vector<std::array<Vert, 3>> remapped(nTris);
|
|
364
|
+
std::vector<char> isDegenerate(nTris, 0), isDuplicate(nTris, 0);
|
|
365
|
+
std::vector<std::pair<std::array<Vert, 3>, size_t>> byShape;
|
|
366
|
+
byShape.reserve(nTris);
|
|
367
|
+
for (size_t t = 0; t < nTris; ++t) {
|
|
326
368
|
Vert v[3];
|
|
327
369
|
triVerts(mesh, t, v);
|
|
328
370
|
std::array<Vert, 3> f{remap[v[0]], remap[v[1]], remap[v[2]]};
|
|
371
|
+
remapped[t] = f;
|
|
329
372
|
// 2. Degenerate faces, now that welding has collapsed slivers into
|
|
330
373
|
// repeated indices.
|
|
331
374
|
if (f[0] == f[1] || f[1] == f[2] || f[0] == f[2]) {
|
|
332
|
-
|
|
375
|
+
isDegenerate[t] = 1;
|
|
333
376
|
continue;
|
|
334
377
|
}
|
|
335
378
|
std::array<Vert, 3> sorted = f;
|
|
336
379
|
std::sort(sorted.begin(), sorted.end());
|
|
337
|
-
|
|
380
|
+
byShape.emplace_back(sorted, t);
|
|
381
|
+
}
|
|
382
|
+
std::sort(byShape.begin(), byShape.end());
|
|
383
|
+
for (size_t i = 1; i < byShape.size(); ++i) {
|
|
384
|
+
if (byShape[i].first == byShape[i - 1].first) isDuplicate[byShape[i].second] = 1;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
std::vector<std::array<Vert, 3>> tris;
|
|
388
|
+
tris.reserve(nTris);
|
|
389
|
+
for (size_t t = 0; t < nTris; ++t) {
|
|
390
|
+
if (isDegenerate[t]) {
|
|
391
|
+
++report.droppedDegenerate;
|
|
392
|
+
} else if (isDuplicate[t]) {
|
|
338
393
|
++report.droppedDuplicate;
|
|
339
|
-
|
|
394
|
+
} else {
|
|
395
|
+
tris.push_back(remapped[t]);
|
|
340
396
|
}
|
|
341
|
-
tris.push_back(f);
|
|
342
397
|
}
|
|
343
398
|
|
|
344
399
|
std::vector<size_t> component;
|
|
@@ -349,12 +404,19 @@ M repairMesh(const M& mesh, MeshRepairReport& report) {
|
|
|
349
404
|
// Before filling, so the new faces are wound against a settled
|
|
350
405
|
// surface rather than a mixed one.
|
|
351
406
|
{
|
|
352
|
-
|
|
407
|
+
// Every edge really is needed here (the flood fill walks all of
|
|
408
|
+
// them), so unlike stripSlivers' index this cannot be narrowed --
|
|
409
|
+
// but it can stop allocating a tree node per edge. Sorted flat, then
|
|
410
|
+
// searched by equal_range. Faces still come back in ascending index
|
|
411
|
+
// order within an edge, which the fill's traversal order depends on.
|
|
412
|
+
std::vector<std::pair<uint64_t, size_t>> edgeTris;
|
|
413
|
+
edgeTris.reserve(tris.size() * 3);
|
|
353
414
|
for (size_t i = 0; i < tris.size(); ++i) {
|
|
354
415
|
for (int e = 0; e < 3; ++e) {
|
|
355
|
-
edgeTris
|
|
416
|
+
edgeTris.emplace_back(edgeKey(undirected(tris[i][e], tris[i][(e + 1) % 3])), i);
|
|
356
417
|
}
|
|
357
418
|
}
|
|
419
|
+
std::sort(edgeTris.begin(), edgeTris.end());
|
|
358
420
|
component.assign(tris.size(), SIZE_MAX);
|
|
359
421
|
std::vector<char> done(tris.size(), 0);
|
|
360
422
|
for (size_t seed = 0; seed < tris.size(); ++seed) {
|
|
@@ -368,7 +430,11 @@ M repairMesh(const M& mesh, MeshRepairReport& report) {
|
|
|
368
430
|
stack.pop_back();
|
|
369
431
|
for (int e = 0; e < 3; ++e) {
|
|
370
432
|
const Vert a = tris[i][e], b = tris[i][(e + 1) % 3];
|
|
371
|
-
|
|
433
|
+
const uint64_t key = edgeKey(undirected(a, b));
|
|
434
|
+
const auto lo = std::lower_bound(edgeTris.begin(), edgeTris.end(),
|
|
435
|
+
std::make_pair(key, size_t{0}));
|
|
436
|
+
for (auto it = lo; it != edgeTris.end() && it->first == key; ++it) {
|
|
437
|
+
const size_t j = it->second;
|
|
372
438
|
if (j == i || done[j]) continue;
|
|
373
439
|
bool sameDir = false;
|
|
374
440
|
for (int f = 0; f < 3; ++f) {
|
|
@@ -427,22 +493,27 @@ M repairMesh(const M& mesh, MeshRepairReport& report) {
|
|
|
427
493
|
// component that was turned inside out and then back reports nothing,
|
|
428
494
|
// which is what the user sees.
|
|
429
495
|
{
|
|
430
|
-
std::set<std::array<Vert, 3>> before;
|
|
431
|
-
for (size_t t = 0; t < triCount(mesh); ++t) {
|
|
432
|
-
Vert v[3];
|
|
433
|
-
triVerts(mesh, t, v);
|
|
434
|
-
before.insert({remap[v[0]], remap[v[1]], remap[v[2]]});
|
|
435
|
-
}
|
|
436
496
|
auto rotated = [](std::array<Vert, 3> f) {
|
|
437
497
|
// Winding is defined up to rotation, so compare canonically.
|
|
438
498
|
if (f[1] < f[0] && f[1] <= f[2]) return std::array<Vert, 3>{f[1], f[2], f[0]};
|
|
439
499
|
if (f[2] < f[0] && f[2] <= f[1]) return std::array<Vert, 3>{f[2], f[0], f[1]};
|
|
440
500
|
return f;
|
|
441
501
|
};
|
|
442
|
-
std::
|
|
443
|
-
|
|
502
|
+
// Was two std::sets over every face -- the incoming windings and
|
|
503
|
+
// their canonical rotations. One sorted, deduplicated vector answers
|
|
504
|
+
// the same membership questions with no node allocations. Built from
|
|
505
|
+
// `remapped`, which is every ORIGINAL face including the degenerate
|
|
506
|
+
// ones the set also held.
|
|
507
|
+
std::vector<std::array<Vert, 3>> canon;
|
|
508
|
+
canon.reserve(remapped.size());
|
|
509
|
+
for (const auto& f : remapped) canon.push_back(rotated(f));
|
|
510
|
+
std::sort(canon.begin(), canon.end());
|
|
511
|
+
canon.erase(std::unique(canon.begin(), canon.end()), canon.end());
|
|
512
|
+
const auto known = [&canon](const std::array<Vert, 3>& f) {
|
|
513
|
+
return std::binary_search(canon.begin(), canon.end(), f);
|
|
514
|
+
};
|
|
444
515
|
for (const auto& f : tris) {
|
|
445
|
-
if (!
|
|
516
|
+
if (!known(rotated(f)) && known(rotated({f[0], f[2], f[1]}))) {
|
|
446
517
|
++report.reversedFaces;
|
|
447
518
|
}
|
|
448
519
|
}
|
{openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/tests/test_bytecode_compiler.cpp
RENAMED
|
@@ -2159,3 +2159,35 @@ TEST(BytecodeCompiler, CompileTimeArgumentPlanMatchesTheNameMatchingRules) {
|
|
|
2159
2159
|
"echo(count(100));"),
|
|
2160
2160
|
"ECHO: 5050");
|
|
2161
2161
|
}
|
|
2162
|
+
|
|
2163
|
+
// A declaration may repeat a parameter name. BOSL2's regular_prism() declares
|
|
2164
|
+
// both `length` and `height` twice, and three of its own documentation
|
|
2165
|
+
// examples stopped rendering when the compile-time argument plan bound only
|
|
2166
|
+
// the first of them -- the body read undef from whichever slot the repeated
|
|
2167
|
+
// name finally resolved to, and asserted. The name-matching path this
|
|
2168
|
+
// replaced filled every parameter of that name, because it walked the
|
|
2169
|
+
// PARAMETERS asking which argument matched, not the other way round.
|
|
2170
|
+
TEST(BytecodeCompiler, ARepeatedParameterNameIsBoundEveryTimeItAppears) {
|
|
2171
|
+
const std::string f = "function f(a, height, b, height) = str(a, \"/\", height, \"/\", b);\n";
|
|
2172
|
+
const std::string g = "function g(height, b, height) = str(height, \"/\", b);\n";
|
|
2173
|
+
|
|
2174
|
+
for (const auto& [src, call] : std::vector<std::pair<std::string, std::string>>{
|
|
2175
|
+
{f, "f(a = 1, height = 20, b = 2)"}, // named
|
|
2176
|
+
{f, "f(1, 20, 2)"}, // positional landing on the first copy
|
|
2177
|
+
{g, "g(20, 2)"}, // repeated name in first position
|
|
2178
|
+
{f, "f(a = 1, b = 2, height = 20)"}, // named, out of order
|
|
2179
|
+
}) {
|
|
2180
|
+
std::string compiled, interpreted;
|
|
2181
|
+
{
|
|
2182
|
+
ScopedVm on(true);
|
|
2183
|
+
compiled = runCapturingEcho(src + "echo(" + call + ");");
|
|
2184
|
+
}
|
|
2185
|
+
{
|
|
2186
|
+
ScopedVm off(false);
|
|
2187
|
+
interpreted = runCapturingEcho(src + "echo(" + call + ");");
|
|
2188
|
+
}
|
|
2189
|
+
EXPECT_EQ(compiled, interpreted) << "VM and interpreter disagree for: " << call;
|
|
2190
|
+
EXPECT_NE(compiled.find("20"), std::string::npos)
|
|
2191
|
+
<< call << " lost its repeated-name argument: " << compiled;
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
@@ -358,6 +358,33 @@ TEST(SliverStrip, ANeedleIsRemovedWithoutSplittingAnything) {
|
|
|
358
358
|
EXPECT_TRUE(d.manifold()) << d.summary();
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
+
// Three copies of one position is TWO welds, not one, and the survivor is the
|
|
362
|
+
// lowest-numbered of them. Both facts used to fall out of inserting into a
|
|
363
|
+
// std::map and keeping whatever was already there; they now come from run
|
|
364
|
+
// lengths in a sorted list, where an off-by-one or a wrong representative
|
|
365
|
+
// would be silent -- the geometry is identical either way, only the indices
|
|
366
|
+
// differ.
|
|
367
|
+
TEST(MeshCheck, ThreeCoincidentVerticesAreTwoWeldsOntoTheLowestIndex) {
|
|
368
|
+
manifold::MeshGL m = tetra();
|
|
369
|
+
const uint32_t a = 4, b = 5;
|
|
370
|
+
m.vertProperties.insert(m.vertProperties.end(), {0, 0, 0}); // == vertex 0
|
|
371
|
+
m.vertProperties.insert(m.vertProperties.end(), {0, 0, 0}); // == vertex 0 again
|
|
372
|
+
bool usedA = false;
|
|
373
|
+
for (size_t i = 0; i < m.triVerts.size(); ++i) {
|
|
374
|
+
if (m.triVerts[i] != 0 || i < 6) continue;
|
|
375
|
+
m.triVerts[i] = usedA ? b : a; // spread over both copies
|
|
376
|
+
usedA = !usedA;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
MeshRepairReport r;
|
|
380
|
+
const manifold::MeshGL fixed = repairMesh(m, r);
|
|
381
|
+
EXPECT_EQ(r.weldedVertices, 2u) << r.summary();
|
|
382
|
+
for (uint32_t v : fixed.triVerts) {
|
|
383
|
+
EXPECT_NE(v, a) << "welded away, so no face may still name it";
|
|
384
|
+
EXPECT_NE(v, b) << "welded away, so no face may still name it";
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
361
388
|
// import(repair=true) goes through repairMesh, so it has to deal with
|
|
362
389
|
// slivers too -- an imported STL is exactly where they turn up.
|
|
363
390
|
TEST(MeshRepair, StripsSliversAndRestitchesThem) {
|
|
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.7.0 → openscad_cpp_evaluator-1.7.2}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.7.0 → openscad_cpp_evaluator-1.7.2}/external/openscad_cpp_parser/README.md
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
|
|
File without changes
|