openscad-cpp-evaluator 1.20.2__tar.gz → 1.20.5__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.20.2 → openscad_cpp_evaluator-1.20.5}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/text.cpp +10 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/export.cpp +33 -18
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/mesh_check.cpp +81 -26
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_export.cpp +64 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_manifold_cache.cpp +22 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_mesh_check.cpp +20 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_text.cpp +27 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/README.md +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/uv.lock +0 -0
|
@@ -70,6 +70,16 @@ CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
CSGParams params;
|
|
73
|
+
// The handle is what generateText looks the face up by, but it is an
|
|
74
|
+
// index into THIS evaluator's FontProvider -- the first font resolved
|
|
75
|
+
// is handle 0 whatever it is. Two evaluators sharing a ManifoldCache
|
|
76
|
+
// (two tabs in a GUI, say) therefore agreed on "font_handle=0" for
|
|
77
|
+
// entirely different fonts, and the second render was served the
|
|
78
|
+
// first one's glyphs. The spec goes in the params too, so the cache
|
|
79
|
+
// key tells them apart: the same spec always resolves to the same
|
|
80
|
+
// face, and two specs that happen to resolve alike merely miss the
|
|
81
|
+
// cache rather than collide.
|
|
82
|
+
params["font_spec"] = Value{fontSpec};
|
|
73
83
|
params["font_handle"] = Value{static_cast<double>(handle)};
|
|
74
84
|
params["scale"] = Value{scale};
|
|
75
85
|
params["segs"] = Value{static_cast<double>(segs)};
|
|
@@ -362,9 +362,7 @@ void meshToArrays(const manifold::MeshGL& mesh, std::vector<float>& verts, std::
|
|
|
362
362
|
tris = mesh.triVerts;
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
bool boxesOverlap(const manifold::
|
|
366
|
-
const manifold::Box ba = a.BoundingBox();
|
|
367
|
-
const manifold::Box bb = b.BoundingBox();
|
|
365
|
+
bool boxesOverlap(const manifold::Box& ba, const manifold::Box& bb) {
|
|
368
366
|
return !(ba.max.x < bb.min.x || bb.max.x < ba.min.x || ba.max.y < bb.min.y || bb.max.y < ba.min.y ||
|
|
369
367
|
ba.max.z < bb.min.z || bb.max.z < ba.min.z);
|
|
370
368
|
}
|
|
@@ -512,25 +510,42 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
512
510
|
c.key = keys[0];
|
|
513
511
|
claimedGroups.push_back(std::move(c));
|
|
514
512
|
} else {
|
|
515
|
-
// Reverse order
|
|
516
|
-
//
|
|
517
|
-
//
|
|
518
|
-
|
|
513
|
+
// Reverse order is what makes the LATER body win: by the time
|
|
514
|
+
// an earlier one is reached, everything after it has already
|
|
515
|
+
// taken its volume.
|
|
516
|
+
//
|
|
517
|
+
// Each body is cut by the later ones that actually REACH it, not
|
|
518
|
+
// by a running union of all of them. The running union was
|
|
519
|
+
// quadratic -- it grows to span the whole model, so every one of
|
|
520
|
+
// n subtractions faced O(n) geometry however little the parts
|
|
521
|
+
// really touched, and a 100-body 3MF spent 6.6s on it (#177).
|
|
522
|
+
//
|
|
523
|
+
// The result is identical: a later body whose bounding box is
|
|
524
|
+
// disjoint from this one cannot intersect it, and subtracting a
|
|
525
|
+
// disjoint solid removes no volume. Bounding boxes settle that in
|
|
526
|
+
// nanoseconds, so what is left is proportional to how much the
|
|
527
|
+
// model overlaps rather than to how many parts it has.
|
|
528
|
+
//
|
|
529
|
+
// Skipping the subtraction entirely when nothing overlaps is not
|
|
530
|
+
// just a shortcut: `A - disjoint B` returns A's volume but
|
|
531
|
+
// REORDERS its triangle list, which throws away any per-triangle
|
|
532
|
+
// colours A carried. Most models are mostly disjoint parts, so
|
|
533
|
+
// without this a two-tone body lost its colours the moment any
|
|
534
|
+
// other differently-coloured body existed.
|
|
535
|
+
std::vector<manifold::Box> boxes;
|
|
536
|
+
boxes.reserve(solids.size());
|
|
537
|
+
for (const Solid& s : solids) boxes.push_back(s.man.BoundingBox());
|
|
538
|
+
|
|
519
539
|
std::vector<Claimed> owned;
|
|
540
|
+
std::vector<manifold::Manifold> blockers;
|
|
520
541
|
for (size_t n = solids.size(); n-- > 0;) {
|
|
521
542
|
Solid& s = solids[n];
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
// cannot overlap is not just a shortcut: `A - disjoint
|
|
526
|
-
// B` returns A's volume but REORDERS its triangle list,
|
|
527
|
-
// which throws away any per-triangle colours A carried.
|
|
528
|
-
// Most models are mostly disjoint parts, so without this
|
|
529
|
-
// a two-tone body lost its colours the moment any other
|
|
530
|
-
// differently-coloured body existed.
|
|
531
|
-
if (boxesOverlap(s.man, *claimed)) piece = s.man - *claimed;
|
|
543
|
+
blockers.clear();
|
|
544
|
+
for (size_t m = n + 1; m < solids.size(); ++m) {
|
|
545
|
+
if (boxesOverlap(boxes[n], boxes[m])) blockers.push_back(solids[m].man);
|
|
532
546
|
}
|
|
533
|
-
|
|
547
|
+
manifold::Manifold piece = s.man;
|
|
548
|
+
if (!blockers.empty()) piece = s.man - addAll(blockers);
|
|
534
549
|
if (piece.IsEmpty()) continue;
|
|
535
550
|
Claimed c;
|
|
536
551
|
c.man = std::move(piece);
|
|
@@ -79,20 +79,56 @@ size_t countUnwelded(const M& m) {
|
|
|
79
79
|
// The faces around `v`, as (prev, next) pairs on the opposite edge. The link
|
|
80
80
|
// is one cycle when following those pairs from any starting corner visits
|
|
81
81
|
// all of them; more than one walk means the surface pinches at v.
|
|
82
|
+
//
|
|
83
|
+
// `vertTris` is CSR: the triangles around vertex v are
|
|
84
|
+
// vertTriList[vertTriStart[v] .. vertTriStart[v+1]).
|
|
85
|
+
//
|
|
86
|
+
// Every buffer here is hoisted out of the loop and cleared per vertex. The
|
|
87
|
+
// straightforward spelling -- an unordered_map of vectors for the link and a
|
|
88
|
+
// std::set for the walk, both built fresh per vertex -- allocated on the
|
|
89
|
+
// order of a dozen blocks for each of a mesh's vertices, millions of them on
|
|
90
|
+
// a 200K-triangle model, to answer a question about roughly six neighbours.
|
|
91
|
+
// Same reason the edge and face counts below collect flat and sort; see
|
|
92
|
+
// their comment.
|
|
82
93
|
template <typename M>
|
|
83
94
|
size_t countPinched(const M& m,
|
|
84
|
-
const std::vector<
|
|
95
|
+
const std::vector<size_t>& vertTriStart,
|
|
96
|
+
const std::vector<size_t>& vertTriList) {
|
|
85
97
|
size_t pinched = 0;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
const size_t nVerts = vertTriStart.empty() ? 0 : vertTriStart.size() - 1;
|
|
99
|
+
|
|
100
|
+
std::vector<Vert> nodes; // the distinct neighbours of v
|
|
101
|
+
std::vector<size_t> parent; // union-find over indices into `nodes`
|
|
102
|
+
std::vector<std::pair<uint32_t, uint32_t>> edges;
|
|
103
|
+
|
|
104
|
+
// Linear search, not a map: a vertex has a handful of neighbours, and at
|
|
105
|
+
// that size a scan beats hashing outright -- no allocation, no hashing,
|
|
106
|
+
// and the whole thing stays in cache.
|
|
107
|
+
const auto indexOf = [&](Vert w) -> uint32_t {
|
|
108
|
+
for (size_t i = 0; i < nodes.size(); ++i) {
|
|
109
|
+
if (nodes[i] == w) return static_cast<uint32_t>(i);
|
|
110
|
+
}
|
|
111
|
+
nodes.push_back(w);
|
|
112
|
+
parent.push_back(parent.size());
|
|
113
|
+
return static_cast<uint32_t>(nodes.size() - 1);
|
|
114
|
+
};
|
|
115
|
+
const auto find = [&](size_t i) {
|
|
116
|
+
while (parent[i] != i) {
|
|
117
|
+
parent[i] = parent[parent[i]]; // path halving
|
|
118
|
+
i = parent[i];
|
|
119
|
+
}
|
|
120
|
+
return i;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
for (Vert v = 0; v < nVerts; ++v) {
|
|
124
|
+
const size_t begin = vertTriStart[v], end = vertTriStart[v + 1];
|
|
125
|
+
if (end - begin < 2) continue;
|
|
126
|
+
nodes.clear();
|
|
127
|
+
parent.clear();
|
|
128
|
+
edges.clear();
|
|
129
|
+
for (size_t k = begin; k < end; ++k) {
|
|
94
130
|
Vert w[3];
|
|
95
|
-
triVerts(m,
|
|
131
|
+
triVerts(m, vertTriList[k], w);
|
|
96
132
|
Vert a = 0, b = 0;
|
|
97
133
|
int found = 0;
|
|
98
134
|
for (int i = 0; i < 3; ++i) {
|
|
@@ -100,21 +136,20 @@ size_t countPinched(const M& m,
|
|
|
100
136
|
(found++ == 0 ? a : b) = w[i];
|
|
101
137
|
}
|
|
102
138
|
if (found < 2) continue; // degenerate; counted elsewhere
|
|
103
|
-
|
|
104
|
-
link[b].push_back(a);
|
|
139
|
+
edges.emplace_back(indexOf(a), indexOf(b));
|
|
105
140
|
}
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
141
|
+
if (nodes.empty()) continue;
|
|
142
|
+
// Undirected, so a reversed neighbour still links up -- winding is
|
|
143
|
+
// checked separately and should not show up as a pinch too.
|
|
144
|
+
for (const auto& e : edges) {
|
|
145
|
+
const size_t ra = find(e.first), rb = find(e.second);
|
|
146
|
+
if (ra != rb) parent[ra] = rb;
|
|
147
|
+
}
|
|
148
|
+
size_t components = 0;
|
|
149
|
+
for (size_t i = 0; i < parent.size(); ++i) {
|
|
150
|
+
if (find(i) == i) ++components;
|
|
116
151
|
}
|
|
117
|
-
if (
|
|
152
|
+
if (components > 1) ++pinched;
|
|
118
153
|
}
|
|
119
154
|
return pinched;
|
|
120
155
|
}
|
|
@@ -158,10 +193,16 @@ MeshDiagnosis checkMesh(const M& mesh) {
|
|
|
158
193
|
// index below; see its comment for the measurement.
|
|
159
194
|
std::vector<std::pair<uint64_t, bool>> uses; // {undirected edge, traversed a->b}
|
|
160
195
|
uses.reserve(tris * 3);
|
|
161
|
-
std::vector<std::vector<size_t>> vertTris(nVerts);
|
|
162
196
|
std::vector<std::array<Vert, 3>> seenFaces; // sorted-corner triples, deduplicated below
|
|
163
197
|
seenFaces.reserve(tris);
|
|
164
198
|
|
|
199
|
+
// The triangles around each vertex, CSR rather than a vector per vertex:
|
|
200
|
+
// one inner vector per vertex is an allocation per vertex, and they are
|
|
201
|
+
// only ever read back as a flat run. Counted here, filled after the scan.
|
|
202
|
+
std::vector<size_t> vertTriStart(nVerts + 1, 0);
|
|
203
|
+
std::vector<size_t> vertTriList;
|
|
204
|
+
vertTriList.reserve(tris * 3);
|
|
205
|
+
|
|
165
206
|
for (size_t t = 0; t < tris; ++t) {
|
|
166
207
|
if (degenerate(mesh, t)) ++d.degenerateFaces;
|
|
167
208
|
// Counted, but NOT removed from the topology. A zero-area triangle
|
|
@@ -181,12 +222,26 @@ MeshDiagnosis checkMesh(const M& mesh) {
|
|
|
181
222
|
seenFaces.push_back(sorted);
|
|
182
223
|
|
|
183
224
|
for (int i = 0; i < 3; ++i) {
|
|
184
|
-
if (v[i] < nVerts)
|
|
225
|
+
if (v[i] < nVerts) ++vertTriStart[v[i] + 1];
|
|
185
226
|
const Vert a = v[i], b = v[(i + 1) % 3];
|
|
186
227
|
uses.emplace_back(edgeKey(undirected(a, b)), a < b);
|
|
187
228
|
}
|
|
188
229
|
}
|
|
189
230
|
|
|
231
|
+
for (size_t i = 0; i < nVerts; ++i) vertTriStart[i + 1] += vertTriStart[i];
|
|
232
|
+
vertTriList.resize(vertTriStart[nVerts]);
|
|
233
|
+
{
|
|
234
|
+
std::vector<size_t> fill(vertTriStart.begin(), vertTriStart.end() - 1);
|
|
235
|
+
for (size_t t = 0; t < tris; ++t) {
|
|
236
|
+
if (repeatsAVertex(mesh, t)) continue; // skipped above too
|
|
237
|
+
Vert v[3];
|
|
238
|
+
triVerts(mesh, t, v);
|
|
239
|
+
for (int i = 0; i < 3; ++i) {
|
|
240
|
+
if (v[i] < nVerts) vertTriList[fill[v[i]]++] = t;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
190
245
|
// A face seen N times is N-1 duplicates, which is what insert().second
|
|
191
246
|
// counted one at a time.
|
|
192
247
|
std::sort(seenFaces.begin(), seenFaces.end());
|
|
@@ -214,7 +269,7 @@ MeshDiagnosis checkMesh(const M& mesh) {
|
|
|
214
269
|
i = j;
|
|
215
270
|
}
|
|
216
271
|
|
|
217
|
-
d.pinchedVertices = countPinched(mesh,
|
|
272
|
+
d.pinchedVertices = countPinched(mesh, vertTriStart, vertTriList);
|
|
218
273
|
d.unweldedVertices = countUnwelded(mesh);
|
|
219
274
|
return d;
|
|
220
275
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include "test_helpers.hpp"
|
|
6
6
|
|
|
7
7
|
#include <algorithm>
|
|
8
|
+
#include <array>
|
|
8
9
|
#include <cstdint>
|
|
9
10
|
#include <cstdio>
|
|
10
11
|
#include <filesystem>
|
|
@@ -755,6 +756,69 @@ TEST(SplitColors, SingleMaterialGivesOneObject) {
|
|
|
755
756
|
EXPECT_TRUE(objs[0].triColors.empty()); // no per-triangle colour to carry
|
|
756
757
|
}
|
|
757
758
|
|
|
759
|
+
// Each body is cut only by the later bodies that actually reach it, rather
|
|
760
|
+
// than by a running union of all of them (#177). These pin the two things
|
|
761
|
+
// that rewrite must not change.
|
|
762
|
+
|
|
763
|
+
TEST(SplitColors, AFarAwayBodyChangesNothing) {
|
|
764
|
+
// A body nowhere near the others cannot take volume from them, so adding
|
|
765
|
+
// one must leave every other object exactly as it was. The old code
|
|
766
|
+
// subtracted the union of ALL later bodies and leaned on a bounding-box
|
|
767
|
+
// test against that union to stay correct -- once the union spanned the
|
|
768
|
+
// model, the test stopped discriminating.
|
|
769
|
+
const std::string pair =
|
|
770
|
+
"color(\"red\") cube(10); color(\"blue\") translate([5,0,0]) cube(10);";
|
|
771
|
+
std::vector<ColoredBody> without = evalToBodies(pair);
|
|
772
|
+
std::vector<ColoredBody> with =
|
|
773
|
+
evalToBodies(pair + " color(\"green\") translate([500,0,0]) cube(10);");
|
|
774
|
+
|
|
775
|
+
const std::vector<ExportObject> a = splitBodiesForExport(without, nullptr, false, true);
|
|
776
|
+
const std::vector<ExportObject> b = splitBodiesForExport(with, nullptr, false, true);
|
|
777
|
+
ASSERT_EQ(a.size(), 2u);
|
|
778
|
+
ASSERT_EQ(b.size(), 3u);
|
|
779
|
+
for (size_t i = 0; i < a.size(); ++i) {
|
|
780
|
+
EXPECT_EQ(a[i].tris.size(), b[i].tris.size()) << "object " << i << " was re-cut";
|
|
781
|
+
EXPECT_EQ(a[i].verts.size(), b[i].verts.size()) << "object " << i << " was re-cut";
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
TEST(SplitColors, LaterWinsAcrossAnInterveningColour) {
|
|
786
|
+
// red, blue, red -- all overlapping, in that order. The later body wins,
|
|
787
|
+
// so the second red takes its volume whole, blue keeps only what that
|
|
788
|
+
// red does not cover, and the first red keeps only what neither does.
|
|
789
|
+
//
|
|
790
|
+
// Worth pinning because the obvious way to make this cheaper -- union
|
|
791
|
+
// the same-coloured bodies first, then subtract per colour -- gets it
|
|
792
|
+
// wrong: it would let the first red beat the blue that comes after it.
|
|
793
|
+
std::vector<ColoredBody> bodies = evalToBodies(
|
|
794
|
+
"color(\"red\") cube(10);"
|
|
795
|
+
"color(\"blue\") translate([5,0,0]) cube(10);"
|
|
796
|
+
"color(\"red\") translate([10,0,0]) cube(10);");
|
|
797
|
+
const std::vector<ExportObject> objs = splitBodiesForExport(bodies, nullptr, false, true);
|
|
798
|
+
ASSERT_EQ(objs.size(), 2u); // one per colour, the two reds merged
|
|
799
|
+
|
|
800
|
+
const auto volumeOf = [](const ExportObject& o) {
|
|
801
|
+
double v = 0.0;
|
|
802
|
+
for (size_t t = 0; t + 2 < o.tris.size(); t += 3) {
|
|
803
|
+
const auto at = [&](size_t k) {
|
|
804
|
+
const size_t b = static_cast<size_t>(o.tris[t + k]) * 3;
|
|
805
|
+
return std::array<double, 3>{o.verts[b], o.verts[b + 1], o.verts[b + 2]};
|
|
806
|
+
};
|
|
807
|
+
const std::array<double, 3> p = at(0), q = at(1), r = at(2);
|
|
808
|
+
v += (p[0] * (q[1] * r[2] - q[2] * r[1]) - p[1] * (q[0] * r[2] - q[2] * r[0]) +
|
|
809
|
+
p[2] * (q[0] * r[1] - q[1] * r[0])) / 6.0;
|
|
810
|
+
}
|
|
811
|
+
return v;
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
// Blue spans x 5..15 and the later red takes x 10..20, leaving x 5..10:
|
|
815
|
+
// 5 x 10 x 10. The reds keep everything else: 2000 - 500.
|
|
816
|
+
double red = 0.0, blue = 0.0;
|
|
817
|
+
for (const ExportObject& o : objs) (o.color[2] > o.color[0] ? blue : red) += volumeOf(o);
|
|
818
|
+
EXPECT_NEAR(blue, 500.0, 1e-6);
|
|
819
|
+
EXPECT_NEAR(red, 1500.0, 1e-6);
|
|
820
|
+
}
|
|
821
|
+
|
|
758
822
|
TEST(SplitColors, SingleMaterialWeldsTouchingColourRegions) {
|
|
759
823
|
// Unioned, not concatenated: two touching cubes of different colours
|
|
760
824
|
// must come out as one solid without the coincident interior faces
|
{openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/tests/test_manifold_cache.cpp
RENAMED
|
@@ -36,6 +36,28 @@ TEST(ManifoldCacheKey, BoolAndNumberParamsProduceDifferentCacheKeys) {
|
|
|
36
36
|
EXPECT_NE(cacheKey(a), cacheKey(b));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
TEST(ManifoldCacheKey, TwoFontsWithTheSameHandleDoNotShareAKey) {
|
|
40
|
+
// A FontHandle indexes the EVALUATOR's own FontProvider, so the first
|
|
41
|
+
// font any evaluator resolves is handle 0 whatever it is. Two
|
|
42
|
+
// evaluators sharing one ManifoldCache -- two tabs in a GUI -- agreed
|
|
43
|
+
// on "font_handle=0" for entirely different fonts, and the second was
|
|
44
|
+
// served the first one's glyphs. text() puts the SPEC in the params
|
|
45
|
+
// too, so the key tells them apart.
|
|
46
|
+
CSGNode a;
|
|
47
|
+
a.kind = "text";
|
|
48
|
+
a.isBuiltin = true;
|
|
49
|
+
a.params["font_handle"] = Value{0.0};
|
|
50
|
+
a.params["font_spec"] = Value{std::string("Arial:style=Regular")};
|
|
51
|
+
|
|
52
|
+
CSGNode b;
|
|
53
|
+
b.kind = "text";
|
|
54
|
+
b.isBuiltin = true;
|
|
55
|
+
b.params["font_handle"] = Value{0.0}; // same handle, different font
|
|
56
|
+
b.params["font_spec"] = Value{std::string("Arial:style=Bold")};
|
|
57
|
+
|
|
58
|
+
EXPECT_NE(cacheKey(a), cacheKey(b));
|
|
59
|
+
}
|
|
60
|
+
|
|
39
61
|
TEST(ManifoldCacheKey, IdenticalStructureProducesIdenticalKeyRegardlessOfParamInsertionOrder) {
|
|
40
62
|
CSGNode a;
|
|
41
63
|
a.kind = "cube";
|
|
@@ -76,6 +76,26 @@ TEST(MeshCheck, TwoTetrahedraSharingOneVertexPinchThere) {
|
|
|
76
76
|
EXPECT_FALSE(d.manifold());
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
TEST(MeshCheck, ThreeTetrahedraOnOneVertexAreStillOnePinchedVertex) {
|
|
80
|
+
// The link at vertex 0 falls into THREE pieces, not two. The count is of
|
|
81
|
+
// pinched VERTICES, so this is still 1 -- worth pinning because the walk
|
|
82
|
+
// only has to notice that the link is not one piece, and an
|
|
83
|
+
// implementation that counts pieces instead would say 2 here and agree
|
|
84
|
+
// with the two-tetrahedron case by luck.
|
|
85
|
+
manifold::MeshGL m = tetra();
|
|
86
|
+
for (int k = 0; k < 2; ++k) {
|
|
87
|
+
const uint32_t base = static_cast<uint32_t>(m.vertProperties.size() / 3);
|
|
88
|
+
const float z = -1.0f - static_cast<float>(k) * 2.0f;
|
|
89
|
+
m.vertProperties.insert(m.vertProperties.end(),
|
|
90
|
+
{0, 0, z, 1, 0, z, 0, 1, z});
|
|
91
|
+
m.triVerts.insert(m.triVerts.end(), {
|
|
92
|
+
0u, base + 1, base, 0u, base, base + 2,
|
|
93
|
+
0u, base + 2, base + 1, base, base + 1, base + 2});
|
|
94
|
+
}
|
|
95
|
+
const MeshDiagnosis d = checkMesh(m);
|
|
96
|
+
EXPECT_EQ(d.pinchedVertices, 1u) << d.summary();
|
|
97
|
+
}
|
|
98
|
+
|
|
79
99
|
TEST(MeshCheck, AReversedFaceIsCaughtAsInconsistentWinding) {
|
|
80
100
|
manifold::MeshGL m = tetra();
|
|
81
101
|
std::swap(m.triVerts[1], m.triVerts[2]); // flip one face
|
|
@@ -422,3 +422,30 @@ TEST(TextArgs, FontIsPositionalButTheRestAreNot) {
|
|
|
422
422
|
// NOTHING, and halign by name does move it.
|
|
423
423
|
EXPECT_EQ(echoes[0], "ECHO: true, false, true, false");
|
|
424
424
|
}
|
|
425
|
+
|
|
426
|
+
namespace oscadeval {
|
|
427
|
+
|
|
428
|
+
// Why text() must put the font SPEC in its CSG params and not just the
|
|
429
|
+
// handle: a handle numbers faces WITHIN one provider, and every Evaluator
|
|
430
|
+
// makes its own. Two evaluators sharing a ManifoldCache -- two GUI tabs --
|
|
431
|
+
// hand the cache the same number for different fonts (BelfrySCAD#434).
|
|
432
|
+
TEST(FontHandles, AreOnlyMeaningfulWithinOneProvider) {
|
|
433
|
+
FreetypeFontProvider a, b;
|
|
434
|
+
const FontHandle aReg = a.resolveFont("Arial:style=Regular");
|
|
435
|
+
const FontHandle aBold = a.resolveFont("Arial:style=Bold");
|
|
436
|
+
if (aReg == aBold) {
|
|
437
|
+
GTEST_SKIP() << "this machine resolves both specs to one face";
|
|
438
|
+
}
|
|
439
|
+
EXPECT_NE(aReg, aBold) << "within one provider, two fonts get two handles";
|
|
440
|
+
// What a second provider numbers them is NOT asserted: it depends on
|
|
441
|
+
// which faces that machine has and the order they are opened in. On
|
|
442
|
+
// macOS a fresh provider resolving Bold first returns 4 -- the same
|
|
443
|
+
// number the first provider gave REGULAR, which is the collision this
|
|
444
|
+
// whole change is about. On a Linux runner with only the bundled faces
|
|
445
|
+
// the numbering happens to line up instead (0 and 1 either way). That
|
|
446
|
+
// it CAN collide is the point, and it is not a property to pin to a
|
|
447
|
+
// number here; the end-to-end regression test lives in BelfrySCAD,
|
|
448
|
+
// where the collision reproduces in both directions.
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
} // namespace oscadeval
|
|
File without changes
|
{openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/.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
|
{openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.20.2 → openscad_cpp_evaluator-1.20.5}/examples/minimal_debugger.cpp
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
|