openscad-cpp-evaluator 1.40.0__tar.gz → 1.42.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/bindings/module.cpp +1 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/bytecode.hpp +14 -46
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +3 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/colored_body.hpp +32 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/evaluator.hpp +26 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/export.hpp +8 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/segments.hpp +6 -2
- openscad_cpp_evaluator-1.42.0/include/openscad_cpp_evaluator/surface_load.hpp +23 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/value.hpp +3 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/python/openscad_cpp_evaluator/__init__.py +3 -2
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/booleans.cpp +44 -12
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/builtins.hpp +13 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/control.cpp +31 -42
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/extrude.cpp +93 -55
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/function_builtins.cpp +188 -77
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/import.cpp +33 -2
- openscad_cpp_evaluator-1.42.0/src/builtins/primitives_2d.cpp +242 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/primitives_3d.cpp +130 -48
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/segments.cpp +38 -10
- openscad_cpp_evaluator-1.42.0/src/builtins/surface.cpp +118 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/topology.cpp +34 -3
- openscad_cpp_evaluator-1.42.0/src/builtins/transforms.cpp +443 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/bytecode_compiler.cpp +77 -119
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/bytecode_vm.cpp +14 -30
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/colored_body.cpp +25 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/csg_generate.cpp +44 -17
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/csg_resolve.cpp +2 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/eval_context.cpp +2 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/export.cpp +61 -14
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/expr_eval.cpp +51 -25
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/import/scene_import.cpp +5 -14
- openscad_cpp_evaluator-1.42.0/src/import/surface_load.cpp +132 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/stmt_eval.cpp +36 -15
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/text/freetype_font_provider.cpp +18 -3
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/user_calls.cpp +38 -29
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/value.cpp +94 -39
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/CMakeLists.txt +1 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_booleans.cpp +18 -14
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_bytecode_compiler.cpp +10 -7
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_control_flow.cpp +19 -7
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_eval_context.cpp +2 -1
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_expr_eval.cpp +3 -6
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_import_export.cpp +8 -4
- openscad_cpp_evaluator-1.42.0/tests/test_openscad_parity.cpp +483 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_primitives.cpp +29 -5
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_python_bindings.py +9 -6
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_render_expr.cpp +7 -3
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_surface.cpp +49 -18
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_transforms.cpp +12 -5
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/uv.lock +1 -1
- openscad_cpp_evaluator-1.40.0/include/openscad_cpp_evaluator/surface_load.hpp +0 -16
- openscad_cpp_evaluator-1.40.0/src/builtins/primitives_2d.cpp +0 -152
- openscad_cpp_evaluator-1.40.0/src/builtins/surface.cpp +0 -134
- openscad_cpp_evaluator-1.40.0/src/builtins/transforms.cpp +0 -417
- openscad_cpp_evaluator-1.40.0/src/import/surface_load.cpp +0 -76
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/cmake/patch_manifold.cmake +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_undef_args.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.40.0 → openscad_cpp_evaluator-1.42.0}/tools/cli/main.cpp +0 -0
|
@@ -134,6 +134,7 @@ const char* roleToString(oscadeval::BodyRole role) {
|
|
|
134
134
|
case oscadeval::BodyRole::Highlight: return "highlight";
|
|
135
135
|
case oscadeval::BodyRole::Background: return "background";
|
|
136
136
|
case oscadeval::BodyRole::ShowOnly: return "show_only";
|
|
137
|
+
case oscadeval::BodyRole::HighlightGhost: return "highlight_ghost";
|
|
137
138
|
case oscadeval::BodyRole::Normal:
|
|
138
139
|
default: return "normal";
|
|
139
140
|
}
|
|
@@ -43,6 +43,7 @@ enum class Op {
|
|
|
43
43
|
StoreLocal, // a = slot index (pops)
|
|
44
44
|
LoadDyn, // a = name pool index ($-prefixed)
|
|
45
45
|
StoreDyn, // a = name pool index (pops; also marks dynExplicit)
|
|
46
|
+
WarnDuplicateLet, // a = name pool index (pops; warns, binds nothing -- see Evaluator::warnDuplicateLet)
|
|
46
47
|
LoadFree, // a = name pool index -- Evaluator::evalIdentifier fallback (warnIfUndef=true)
|
|
47
48
|
// Same as LoadFree, but Evaluator::evalIdentifier's warnIfUndef=false --
|
|
48
49
|
// only ever emitted for a PrimaryCall's own callee probe (bytecode_
|
|
@@ -240,20 +241,6 @@ enum class Op {
|
|
|
240
241
|
// there's no branch to emit here).
|
|
241
242
|
Echo,
|
|
242
243
|
|
|
243
|
-
// Only ever emitted for a non-empty-argument AssertOp (see
|
|
244
|
-
// bytecode_compiler.cpp's own AssertOp case -- a zero-argument
|
|
245
|
-
// assert() is unconditionally true and compiles straight through with
|
|
246
|
-
// no check at all). Reached only on the condition-false path (guarded
|
|
247
|
-
// by a JumpIfTrue the compiler emits around it, mirroring LogicalOrOp's
|
|
248
|
-
// own jump-then-patch shape) -- always throws via Evaluator::error(),
|
|
249
|
-
// i.e. [[noreturn]] at runtime. a = 1 if a message Value was compiled
|
|
250
|
-
// and pushed (pop it), else 0. b = constant-pool index of condText
|
|
251
|
-
// (the condition expression's own source text, interned ONCE at
|
|
252
|
-
// compile time via its toString() -- cheaper than the interpreter,
|
|
253
|
-
// which recomputes this on every failing call). pos/node: same
|
|
254
|
-
// Evaluator::error() TRACE-walk need CheckIterLimit already has.
|
|
255
|
-
AssertFail,
|
|
256
|
-
|
|
257
244
|
// -- Module-body compilation (Stage 2) --------------------------------
|
|
258
245
|
// A call to a user module resolved to a specific ModuleDeclaration AT
|
|
259
246
|
// COMPILE TIME (see CompiledChunk::ModuleCallSite) -- the module-side
|
|
@@ -717,16 +704,10 @@ enum class Op {
|
|
|
717
704
|
StoreLetVar,
|
|
718
705
|
|
|
719
706
|
// a = index into CompiledChunk::assertSites. Pops site.argCount values
|
|
720
|
-
// (
|
|
721
|
-
// source order
|
|
722
|
-
//
|
|
723
|
-
//
|
|
724
|
-
// Evaluator::evalAssertStatement exactly: named "condition"/"message"
|
|
725
|
-
// win over positional 0/1 (resolved at COMPILE time into
|
|
726
|
-
// AssertSite::conditionArgIndex/messageArgIndex -- the argument SHAPE
|
|
727
|
-
// is static, only values vary per call), throws via Evaluator::error()
|
|
728
|
-
// on failure, otherwise runs any chained node.children natively (rare;
|
|
729
|
-
// not worth its own compiled path -- see AssertSite's own doc comment).
|
|
707
|
+
// (every argument of an assert() statement or expression, pushed in
|
|
708
|
+
// source order) and hands them to Evaluator::checkAssert; a statement
|
|
709
|
+
// then runs any chained children natively (rare; not worth its own
|
|
710
|
+
// compiled path).
|
|
730
711
|
AssertStatement,
|
|
731
712
|
// a = nativeStatements index of the AST node whose arm this is. Emitted
|
|
732
713
|
// only when the Evaluator was built with coverage on (compile-time
|
|
@@ -763,6 +744,10 @@ struct Instruction {
|
|
|
763
744
|
// applyDefaults()'s existing sibling-isolated defaultCtx; empty if that
|
|
764
745
|
// parameter has no default. `bodyCode` is the function's own expression body.
|
|
765
746
|
struct CompiledChunk {
|
|
747
|
+
// String literals whose text holds an escape OpenSCAD calls undefined,
|
|
748
|
+
// with how many: the Evaluator warns for them once, when the chunk is
|
|
749
|
+
// compiled (it has the warning channel; the compiler does not).
|
|
750
|
+
std::vector<std::pair<const oscad::StringLiteral*, int>> undefinedEscapeLiterals;
|
|
766
751
|
struct Param {
|
|
767
752
|
std::string name;
|
|
768
753
|
int slot = 0; // unused when isDyn is true -- $-params are never slot-addressed
|
|
@@ -1036,30 +1021,13 @@ struct CompiledChunk {
|
|
|
1036
1021
|
const oscad::ASTNode* node = nullptr;
|
|
1037
1022
|
};
|
|
1038
1023
|
|
|
1039
|
-
// One Op::AssertStatement site
|
|
1040
|
-
//
|
|
1041
|
-
// into the site's own argCount-sized popped-argument array (source
|
|
1042
|
-
// order), resolved at COMPILE time via the same "named wins over
|
|
1043
|
-
// positional 0/1" priority Evaluator::getArg applies at runtime --
|
|
1044
|
-
// nullopt means "no argument supplies this logical parameter" (mirrors
|
|
1045
|
-
// getArg's own defaultValue fallback: absent condition reads as
|
|
1046
|
-
// `Value{true}`, absent message means no ": ..." suffix).
|
|
1047
|
-
// `condTextConstIdx`: constants[] index of the condition argument's own
|
|
1048
|
-
// source text (or "false" when no condition argument exists, matching
|
|
1049
|
-
// evalAssertStatement's `node.arguments.empty() ? "false" : ...`),
|
|
1050
|
-
// interned once at compile time. `node`: for both Evaluator::error()'s
|
|
1051
|
-
// TRACE walk and the (rare) chained-children fallback below.
|
|
1052
|
-
//
|
|
1053
|
-
// ponytail: a script with TWO named args of the SAME name (e.g.
|
|
1054
|
-
// `assert(condition=true, condition=false)`) would resolve to the
|
|
1055
|
-
// LAST one here, not getArg's own first-match; not worth the extra
|
|
1056
|
-
// bookkeeping to fix for input that's already nonsensical.
|
|
1024
|
+
// One Op::AssertStatement site. `statement` is null for the expression
|
|
1025
|
+
// form, which has no children.
|
|
1057
1026
|
struct AssertSite {
|
|
1058
1027
|
int argCount = 0;
|
|
1059
|
-
std::
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const oscad::ModularAssert* node = nullptr;
|
|
1028
|
+
const std::vector<std::unique_ptr<oscad::Argument>>* arguments = nullptr;
|
|
1029
|
+
const oscad::ASTNode* node = nullptr;
|
|
1030
|
+
const oscad::ModularAssert* statement = nullptr;
|
|
1063
1031
|
};
|
|
1064
1032
|
|
|
1065
1033
|
// Every distinct chunk this SPECIFIC CompiledChunk owns is either a
|
|
@@ -71,6 +71,9 @@ struct PendingCsgWrap {
|
|
|
71
71
|
// Parallel to groupSizes: whether a group that came out EMPTY is still
|
|
72
72
|
// an operand. See Op::CsgGroupEnd's `a`.
|
|
73
73
|
std::vector<Value> emptyIsAGroup;
|
|
74
|
+
// Parallel too: whether the statement was a `%` one, which is never an
|
|
75
|
+
// operand. See Op::CsgGroupEnd's `a` (bit 2).
|
|
76
|
+
std::vector<Value> backgroundStmt;
|
|
74
77
|
size_t groupStartSize = 0;
|
|
75
78
|
};
|
|
76
79
|
|
|
@@ -12,7 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
namespace oscadeval {
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// HighlightGhost is the see-through copy of a `#` operand that an operation
|
|
16
|
+
// (difference, intersection, hull, ...) emits beside its result so the
|
|
17
|
+
// viewport can still show the operand. The operand itself was merged into
|
|
18
|
+
// the result; the ghost is drawing only. It is never an operand again and
|
|
19
|
+
// never exported -- it used to be a plain Highlight body, so an outer
|
|
20
|
+
// boolean used it twice and export wrote it as real geometry:
|
|
21
|
+
// difference(){ cube(2); #translate([1,1,1]) cube(2); } exported volume 15
|
|
22
|
+
// where OpenSCAD writes 7. A `#` with nothing merging it stays Highlight,
|
|
23
|
+
// and exports like any other geometry, as it does upstream.
|
|
24
|
+
enum class BodyRole { Normal, Highlight, Background, ShowOnly, HighlightGhost };
|
|
16
25
|
|
|
17
26
|
// A single piece of evaluated geometry: exactly one of `body` (3D) or
|
|
18
27
|
// `section` (2D) is set, never both -- mirrors the Python reference's
|
|
@@ -178,4 +187,26 @@ inline constexpr double kTopLevel2dHeight = 1.0;
|
|
|
178
187
|
std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies,
|
|
179
188
|
double flatHeight = kTopLevel2dHeight);
|
|
180
189
|
|
|
190
|
+
// A 3D affine transform as it acts on the XY plane: rows x and y, columns
|
|
191
|
+
// x, y and translation -- what OpenSCAD's GeometryEvaluator applies to 2D
|
|
192
|
+
// geometry (z, and everything out of the plane, simply drops away).
|
|
193
|
+
manifold::mat2x3 projectTo2d(const manifold::mat3x4& m);
|
|
194
|
+
|
|
195
|
+
// Moves a section's carried transform (ColoredBody::sectionXform) into the
|
|
196
|
+
// CrossSection itself, projected onto the plane, and resets it. Every 2D
|
|
197
|
+
// operation does this to its children before it reads them: OpenSCAD's F6
|
|
198
|
+
// has already projected each transform by then, and an operation that
|
|
199
|
+
// ignored the carried one -- union, offset, hull, linear_extrude -- used the
|
|
200
|
+
// shape as if the transform had never happened. False if the projection
|
|
201
|
+
// was singular and the shape was removed (the caller warns).
|
|
202
|
+
bool projectSectionXform(ColoredBody& b);
|
|
203
|
+
|
|
204
|
+
// Applies `m`, projected onto the plane, to a CrossSection. A singular
|
|
205
|
+
// projection -- scale([0,1]), a quarter turn about X -- empties it, as
|
|
206
|
+
// upstream's Polygon2d::transform does, and returns false.
|
|
207
|
+
bool transformSection(manifold::CrossSection& cs, const manifold::mat3x4& m);
|
|
208
|
+
|
|
209
|
+
// Upstream's warning for that case, word for word.
|
|
210
|
+
inline constexpr const char* kZeroScale2dWarning = "Scaling a 2D object with 0 - removing object";
|
|
211
|
+
|
|
181
212
|
} // namespace oscadeval
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
#include "openscad_cpp_evaluator/bound_args.hpp"
|
|
4
4
|
#include "openscad_cpp_evaluator/bytecode.hpp"
|
|
5
|
+
|
|
6
|
+
#include <unordered_set>
|
|
5
7
|
#include "openscad_cpp_evaluator/bytecode_vm.hpp"
|
|
6
8
|
#include "openscad_cpp_evaluator/call_args.hpp"
|
|
7
9
|
#include "openscad_cpp_evaluator/csg_node.hpp"
|
|
@@ -557,6 +559,30 @@ public:
|
|
|
557
559
|
// Public: builtins/import.cpp's not-manifold warning is emitted from a
|
|
558
560
|
// free function, same reasoning as tagGenerated()/builtinChildren().
|
|
559
561
|
void warn(const std::string& message, const oscad::Position* position);
|
|
562
|
+
// OpenSCAD's lexer warns "Undefined escape sequence" once per bad escape
|
|
563
|
+
// in the source. This warns for a literal the first time it is
|
|
564
|
+
// evaluated or compiled, and never again for that literal.
|
|
565
|
+
void warnUndefinedEscapes(const oscad::StringLiteral& lit, int count);
|
|
566
|
+
// let() keeps the FIRST binding of a repeated name: OpenSCAD evaluates
|
|
567
|
+
// the later right-hand side, warns with its value, and discards it.
|
|
568
|
+
// OpenSCAD's Assert::performAssert, given every argument's value in
|
|
569
|
+
// source order -- it evaluates them all, pass or fail, so a passing
|
|
570
|
+
// `assert(true, nosuch)` still warns. Warns about unexpected arguments;
|
|
571
|
+
// throws via error() when the condition is false or missing (`assert()`
|
|
572
|
+
// fails). The message prints as echo() would print it.
|
|
573
|
+
void checkAssert(const std::vector<std::unique_ptr<oscad::Argument>>& arguments, const std::vector<Value>& values,
|
|
574
|
+
const oscad::ASTNode& node);
|
|
575
|
+
void warnDuplicateLet(const std::string& name, const Value& v, const oscad::Position* position);
|
|
576
|
+
template <typename Assignments>
|
|
577
|
+
static bool repeatsEarlierLetName(const Assignments& assignments, size_t i) {
|
|
578
|
+
for (size_t j = 0; j < i; ++j)
|
|
579
|
+
if (assignments[j]->name->name == assignments[i]->name->name) return true;
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
std::unordered_set<const oscad::StringLiteral*> undefinedEscapesWarned_;
|
|
583
|
+
void warnUndefinedEscapes(const CompiledChunk& chunk) {
|
|
584
|
+
for (const auto& [lit, n] : chunk.undefinedEscapeLiterals) warnUndefinedEscapes(*lit, n);
|
|
585
|
+
}
|
|
560
586
|
// Hands one already-formatted warning line to echoFn_, recording it in
|
|
561
587
|
// warnCapture first when one is active. Every warning path goes through
|
|
562
588
|
// here, including a ManifoldCache hit replaying a cached line.
|
|
@@ -52,6 +52,14 @@ struct ExportObject {
|
|
|
52
52
|
// A body Manifold rejected (an open shell is not a solid) can take part in
|
|
53
53
|
// none of that: it keeps its own triangles and its own object, and its
|
|
54
54
|
// 1-based index is appended to `openParts` for the caller to warn about.
|
|
55
|
+
// The dimension OpenSCAD's render gives these top-level bodies: that of the
|
|
56
|
+
// first one with geometry (2 or 3), or 0 for none.
|
|
57
|
+
int topLevelDimension(const std::vector<ColoredBody>& bodies);
|
|
58
|
+
|
|
59
|
+
// OpenSCAD's render warnings for a top level that mixes 2D and 3D; export
|
|
60
|
+
// writes only the first object's dimension.
|
|
61
|
+
std::vector<std::string> mixedDimensionWarnings(const std::vector<ColoredBody>& bodies);
|
|
62
|
+
|
|
55
63
|
std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& bodies,
|
|
56
64
|
std::vector<int>* openParts = nullptr,
|
|
57
65
|
bool splitComponents = false,
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
#include <manifold/common.h>
|
|
7
7
|
|
|
8
|
+
#include <functional>
|
|
8
9
|
#include <optional>
|
|
10
|
+
#include <string>
|
|
9
11
|
|
|
10
12
|
namespace oscadeval {
|
|
11
13
|
|
|
@@ -27,7 +29,8 @@ struct Discretizer {
|
|
|
27
29
|
double fa = 12.0;
|
|
28
30
|
double fs = 2.0;
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
// `warn`, when given, receives upstream's clamping warnings.
|
|
33
|
+
static Discretizer fromCtx(const EvalContext& ctx, const std::function<void(const std::string&)>& warn = {});
|
|
31
34
|
// Stored in, and read back from, a node's params -- they are part of its
|
|
32
35
|
// cache key, and generate has only the params to go on.
|
|
33
36
|
static Discretizer fromParams(const CSGParams& params);
|
|
@@ -53,6 +56,7 @@ struct Discretizer {
|
|
|
53
56
|
|
|
54
57
|
// Full-circle segment count from ctx's $fn/$fe/$fa/$fs at radius r;
|
|
55
58
|
// upstream's primitives fall back to 3.
|
|
56
|
-
int fnSegmentsFromCtx(const EvalContext& ctx, double r = 0.0
|
|
59
|
+
int fnSegmentsFromCtx(const EvalContext& ctx, double r = 0.0,
|
|
60
|
+
const std::function<void(const std::string&)>& warn = {});
|
|
57
61
|
|
|
58
62
|
} // namespace oscadeval
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
#include <vector>
|
|
5
|
+
|
|
6
|
+
namespace oscadeval {
|
|
7
|
+
|
|
8
|
+
// Height data for surface(), read as upstream's SurfaceNode reads it: a
|
|
9
|
+
// PNG (by its signature) as 16-bit luminance scaled to 0-100, negated by
|
|
10
|
+
// `invert`, bottom image row at y = 0; anything else as a .dat grid, first
|
|
11
|
+
// line at y = 0, short rows padded with 0. Never throws: a file that cannot
|
|
12
|
+
// be read gives no heights and upstream's warning, and the script carries
|
|
13
|
+
// on. `heights[row * cols + col]`; `minVal` is what the base sits 1 below.
|
|
14
|
+
struct SurfaceData {
|
|
15
|
+
std::vector<double> heights;
|
|
16
|
+
int rows = 0;
|
|
17
|
+
int cols = 0;
|
|
18
|
+
double minVal = 0;
|
|
19
|
+
std::vector<std::string> warnings;
|
|
20
|
+
};
|
|
21
|
+
SurfaceData loadSurface(const std::string& path, bool invert);
|
|
22
|
+
|
|
23
|
+
} // namespace oscadeval
|
|
@@ -306,7 +306,9 @@ std::string formatNumber(double v);
|
|
|
306
306
|
//
|
|
307
307
|
// A trailing lone backslash is kept as itself. It can only occur in an
|
|
308
308
|
// unterminated literal, which is a parse error long before this runs.
|
|
309
|
-
|
|
309
|
+
// `undefinedEscapes`, when given, counts the escapes OpenSCAD's lexer calls
|
|
310
|
+
// undefined (it warns once for each).
|
|
311
|
+
std::string unescapeStringLiteral(const std::string& raw, int* undefinedEscapes = nullptr);
|
|
310
312
|
|
|
311
313
|
// echo()/str()/assert-message display format: "undef" | "true"/"false" |
|
|
312
314
|
// "[start : step : end]" (range) | formatNumber() (number) | "[e1, e2, ...]"
|
|
@@ -249,7 +249,8 @@ def _summarize_param(value, max_items: int = 6, max_len: int = 40) -> str:
|
|
|
249
249
|
# of kind -- pure internal bookkeeping or already represented structurally
|
|
250
250
|
# elsewhere in the tree. Mirrors the reference's _DUMP_HIDDEN_PARAM_KEYS.
|
|
251
251
|
_DUMP_HIDDEN_PARAM_KEYS = frozenset(
|
|
252
|
-
{"color", "op", "name", "group_sizes", "empty_is_a_group"
|
|
252
|
+
{"color", "op", "name", "group_sizes", "empty_is_a_group", "background_stmt",
|
|
253
|
+
"m", "remove"})
|
|
253
254
|
|
|
254
255
|
# Auto-generated tessellation data (not user-authored) for every kind except
|
|
255
256
|
# polyhedron, where the equivalent data *is* the user's own points/faces.
|
|
@@ -520,7 +521,7 @@ class ColoredBody:
|
|
|
520
521
|
section: object = None # kept for API parity (always None here)
|
|
521
522
|
flat_preview: bool = False
|
|
522
523
|
tri_colors: Optional[object] = None # (numTri, 4) float32 ndarray, real multi-color CSG merges only
|
|
523
|
-
role: str = "normal" # "normal" | "highlight" | "background" | "show_only"
|
|
524
|
+
role: str = "normal" # "normal" | "highlight" | "highlight_ghost" | "background" | "show_only"
|
|
524
525
|
|
|
525
526
|
|
|
526
527
|
def bodies_from_dicts(body_dicts) -> list:
|
|
@@ -33,17 +33,28 @@ RoleSplit splitByRole(const std::vector<ColoredBody>& bodies) {
|
|
|
33
33
|
// boolean would silently zero the whole operation (the same failure
|
|
34
34
|
// mode invalid operands caused before they were filtered out).
|
|
35
35
|
for (const ColoredBody& c : bodies) {
|
|
36
|
-
if (c.isDisplayOnly() && c.role != BodyRole::Background && c.role != BodyRole::ShowOnly
|
|
36
|
+
if (c.isDisplayOnly() && c.role != BodyRole::Background && c.role != BodyRole::ShowOnly &&
|
|
37
|
+
c.role != BodyRole::HighlightGhost) {
|
|
37
38
|
r.displayOnly.push_back(c);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
for (const ColoredBody& c : bodies) {
|
|
41
|
-
if (c.role != BodyRole::Background && c.role != BodyRole::ShowOnly &&
|
|
42
|
+
if (c.role != BodyRole::Background && c.role != BodyRole::ShowOnly && c.role != BodyRole::HighlightGhost &&
|
|
43
|
+
!c.isDisplayOnly()) {
|
|
42
44
|
r.foreground.push_back(c);
|
|
43
45
|
}
|
|
44
46
|
}
|
|
47
|
+
// A `#` operand is merged like any other (it is in `foreground` above)
|
|
48
|
+
// AND drawn again as a ghost; a ghost from deeper down just rides along.
|
|
45
49
|
for (const ColoredBody& c : r.foreground) {
|
|
46
|
-
if (c.role == BodyRole::Highlight)
|
|
50
|
+
if (c.role == BodyRole::Highlight) {
|
|
51
|
+
ColoredBody ghost = c;
|
|
52
|
+
ghost.role = BodyRole::HighlightGhost;
|
|
53
|
+
r.highlight.push_back(std::move(ghost));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const ColoredBody& c : bodies) {
|
|
57
|
+
if (c.role == BodyRole::HighlightGhost) r.highlight.push_back(c);
|
|
47
58
|
}
|
|
48
59
|
for (const ColoredBody& c : bodies) {
|
|
49
60
|
if (c.role == BodyRole::ShowOnly) r.showOnly.push_back(c);
|
|
@@ -82,6 +93,13 @@ std::optional<manifold::CrossSection> toCrossSection(const std::vector<ColoredBo
|
|
|
82
93
|
// alongside real ManifoldCache/provenance work if per-triangle color
|
|
83
94
|
// through a merge is needed).
|
|
84
95
|
|
|
96
|
+
bool emptyStatementIsAnOperand(const oscad::ASTNode& stmt) {
|
|
97
|
+
const oscad::NodeKind k = stmt.kind();
|
|
98
|
+
return k == oscad::NodeKind::ModularCall || k == oscad::NodeKind::ModularFor ||
|
|
99
|
+
k == oscad::NodeKind::ModularIntersectionFor || k == oscad::NodeKind::ModularLet ||
|
|
100
|
+
k == oscad::NodeKind::ModularModifierShowOnly || k == oscad::NodeKind::ModularModifierHighlight;
|
|
101
|
+
}
|
|
102
|
+
|
|
85
103
|
CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
|
|
86
104
|
const std::string& op = node.name->name;
|
|
87
105
|
// union/difference/intersection take no positional arguments in real
|
|
@@ -110,6 +128,7 @@ CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
110
128
|
|
|
111
129
|
std::vector<Value> groupSizes;
|
|
112
130
|
std::vector<Value> emptyIsAGroup;
|
|
131
|
+
std::vector<Value> backgroundStmt;
|
|
113
132
|
groupSizes.reserve(geoNodes.size());
|
|
114
133
|
emptyIsAGroup.reserve(geoNodes.size());
|
|
115
134
|
for (const oscad::ASTNode* geoNode : geoNodes) {
|
|
@@ -130,15 +149,8 @@ CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
130
149
|
// for `if(false) sphere(6)`, `{ }` and `*cube(1)`, and comes out
|
|
131
150
|
// empty for `for(i=[1:0]) sphere(6)`, `union(){}`, `group(){}` and
|
|
132
151
|
// a call to an empty user module.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
k == oscad::NodeKind::ModularCall ||
|
|
136
|
-
k == oscad::NodeKind::ModularFor ||
|
|
137
|
-
k == oscad::NodeKind::ModularIntersectionFor ||
|
|
138
|
-
k == oscad::NodeKind::ModularLet ||
|
|
139
|
-
k == oscad::NodeKind::ModularModifierShowOnly ||
|
|
140
|
-
k == oscad::NodeKind::ModularModifierHighlight ||
|
|
141
|
-
k == oscad::NodeKind::ModularModifierBackground});
|
|
152
|
+
emptyIsAGroup.push_back(Value{emptyStatementIsAnOperand(*geoNode)});
|
|
153
|
+
backgroundStmt.push_back(Value{geoNode->kind() == oscad::NodeKind::ModularModifierBackground});
|
|
142
154
|
}
|
|
143
155
|
|
|
144
156
|
CSGParams params;
|
|
@@ -146,6 +158,7 @@ CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
146
158
|
params["group_sizes"] = Value{makeList(std::move(groupSizes))};
|
|
147
159
|
params["empty_is_a_group"] =
|
|
148
160
|
Value{makeList(std::move(emptyIsAGroup))};
|
|
161
|
+
params["background_stmt"] = Value{makeList(std::move(backgroundStmt))};
|
|
149
162
|
return params;
|
|
150
163
|
}
|
|
151
164
|
|
|
@@ -314,6 +327,11 @@ std::vector<ColoredBody> generateCsg(Evaluator& ev, const CSGParams& params, con
|
|
|
314
327
|
const std::string& op = std::get<std::string>(params.at("op"));
|
|
315
328
|
const auto& groupSizes = std::get<ListPtr>(params.at("group_sizes"))->items;
|
|
316
329
|
const auto emptyIsAGroupIt = params.find("empty_is_a_group");
|
|
330
|
+
const auto backgroundStmtIt = params.find("background_stmt");
|
|
331
|
+
const auto* backgroundStmt =
|
|
332
|
+
backgroundStmtIt != params.end() && std::holds_alternative<ListPtr>(backgroundStmtIt->second)
|
|
333
|
+
? &std::get<ListPtr>(backgroundStmtIt->second)->items
|
|
334
|
+
: nullptr;
|
|
317
335
|
const ListItems* emptyIsAGroup =
|
|
318
336
|
emptyIsAGroupIt == params.end()
|
|
319
337
|
? nullptr
|
|
@@ -374,6 +392,20 @@ std::vector<ColoredBody> generateCsg(Evaluator& ev, const CSGParams& params, con
|
|
|
374
392
|
}
|
|
375
393
|
|
|
376
394
|
RoleSplit split = splitByRole(stmtBodies);
|
|
395
|
+
// A `%` statement is scenery, not an operand: upstream leaves it out
|
|
396
|
+
// of the CSG entirely (collectChildren skips isBackground()), so the
|
|
397
|
+
// NEXT statement is the minuend of a difference(), and an
|
|
398
|
+
// intersection() is not cancelled by it. It was taken as an empty
|
|
399
|
+
// operand, which emptied both. Only the `%` statement itself: a
|
|
400
|
+
// module or union() holding nothing but `%` is still an (empty)
|
|
401
|
+
// operand there.
|
|
402
|
+
const bool isBackgroundStmt = backgroundStmt && thisStmt < backgroundStmt->size() &&
|
|
403
|
+
std::holds_alternative<bool>((*backgroundStmt)[thisStmt]) &&
|
|
404
|
+
std::get<bool>((*backgroundStmt)[thisStmt]);
|
|
405
|
+
if (isBackgroundStmt) {
|
|
406
|
+
allBg.insert(allBg.end(), split.background.begin(), split.background.end());
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
377
409
|
allBg.insert(allBg.end(), split.background.begin(), split.background.end());
|
|
378
410
|
allHi.insert(allHi.end(), split.highlight.begin(), split.highlight.end());
|
|
379
411
|
allSo.insert(allSo.end(), split.showOnly.begin(), split.showOnly.end());
|
|
@@ -267,6 +267,19 @@ std::vector<ColoredBody> generateSurface(Evaluator& ev, const CSGParams& params,
|
|
|
267
267
|
const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
|
|
268
268
|
|
|
269
269
|
// text() -- text.cpp.
|
|
270
|
+
// Whether a statement that produced no geometry still counts as a boolean
|
|
271
|
+
// operand (and so empties an intersection) -- see resolveCsg.
|
|
272
|
+
bool emptyStatementIsAnOperand(const oscad::ASTNode& stmt);
|
|
273
|
+
|
|
274
|
+
// OpenSCAD's sin_degrees/cos_degrees: exact at multiples of 30 and 45 degrees.
|
|
275
|
+
double sinDeg(double x);
|
|
276
|
+
double cosDeg(double x);
|
|
277
|
+
|
|
278
|
+
// OpenSCAD's lookup_radius() (primitives_2d.cpp): `d` beats `r`, numbers only.
|
|
279
|
+
std::optional<double> lookupRadius(Evaluator& ev, const CallArgs& args, std::optional<int> rPos,
|
|
280
|
+
std::optional<int> dPos, const std::string& rName, const std::string& dName,
|
|
281
|
+
const oscad::Position* where);
|
|
282
|
+
|
|
270
283
|
CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
271
284
|
|
|
272
285
|
// The font size text()/textmetrics()/fontmetrics() draw at: `size`
|
|
@@ -106,6 +106,8 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
106
106
|
const std::vector<const oscad::ASTNode*> bodyNodes = ev.expandChildStatements(node.body, ctx);
|
|
107
107
|
|
|
108
108
|
std::vector<Value> groupSizes;
|
|
109
|
+
std::vector<Value> emptyIsAGroup;
|
|
110
|
+
std::vector<Value> backgroundStmt;
|
|
109
111
|
|
|
110
112
|
// Each dimension's own RHS is evaluated against `parentCtx` (not
|
|
111
113
|
// upfront against the original `ctx`), re-evaluated on every entry
|
|
@@ -116,14 +118,31 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
116
118
|
// needs `i` visible in `j`'s own range expression).
|
|
117
119
|
std::function<void(size_t, EvalContext&)> recurse = [&](size_t depth, EvalContext& parentCtx) {
|
|
118
120
|
if (depth == node.assignments.size()) {
|
|
121
|
+
if (depth == 0) return; // for() with no loop variables iterates zero times in OpenSCAD, not once.
|
|
119
122
|
// One body-entry marker per full cartesian-product iteration
|
|
120
123
|
// and nothing per individual variable binding (unlike
|
|
121
124
|
// evalFor) -- mirrors _resolve_intersection_for's single
|
|
122
125
|
// `_check_debug(body_node[0], loop_ctx, expr_level=True)`.
|
|
123
126
|
if (!bodyNodes.empty()) ev.checkDebug(*bodyNodes.front(), parentCtx, /*forced=*/false, /*exprLevel=*/true);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
// One operand per child STATEMENT of every iteration: upstream
|
|
128
|
+
// instantiates the children straight into the intersection
|
|
129
|
+
// node (control.cc), so they are intersected flat, not
|
|
130
|
+
// unioned per iteration first.
|
|
131
|
+
std::vector<const oscad::ASTNode*> assigns, stmts;
|
|
132
|
+
for (const oscad::ASTNode* stmt : bodyNodes) {
|
|
133
|
+
if (stmt->kind() == oscad::NodeKind::Assignment) assigns.push_back(stmt);
|
|
134
|
+
else if (stmt->kind() != oscad::NodeKind::ModuleDeclaration &&
|
|
135
|
+
stmt->kind() != oscad::NodeKind::FunctionDeclaration)
|
|
136
|
+
stmts.push_back(stmt);
|
|
137
|
+
}
|
|
138
|
+
if (!assigns.empty()) ev.evalChildren(assigns, parentCtx);
|
|
139
|
+
for (const oscad::ASTNode* stmt : stmts) {
|
|
140
|
+
const size_t before = ev.currentTreeFrameSize();
|
|
141
|
+
ev.evalChildren(std::vector<const oscad::ASTNode*>{stmt}, parentCtx);
|
|
142
|
+
groupSizes.push_back(Value{static_cast<double>(ev.currentTreeFrameSize() - before)});
|
|
143
|
+
emptyIsAGroup.push_back(Value{emptyStatementIsAnOperand(*stmt)});
|
|
144
|
+
backgroundStmt.push_back(Value{stmt->kind() == oscad::NodeKind::ModularModifierBackground});
|
|
145
|
+
}
|
|
127
146
|
return;
|
|
128
147
|
}
|
|
129
148
|
const auto& assign = node.assignments[depth];
|
|
@@ -142,49 +161,19 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
142
161
|
|
|
143
162
|
CSGParams params;
|
|
144
163
|
params["group_sizes"] = Value{makeList(std::move(groupSizes))};
|
|
164
|
+
params["empty_is_a_group"] = Value{makeList(std::move(emptyIsAGroup))};
|
|
165
|
+
params["background_stmt"] = Value{makeList(std::move(backgroundStmt))};
|
|
145
166
|
return params;
|
|
146
167
|
}
|
|
147
168
|
|
|
148
|
-
std::vector<ColoredBody> generateIntersectionFor(Evaluator
|
|
169
|
+
std::vector<ColoredBody> generateIntersectionFor(Evaluator& ev, const CSGParams& params,
|
|
149
170
|
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
150
|
-
const oscad::ASTNode&) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
std::vector<ColoredBody> stmtBodies = flattenCsgTree(children, idx, size);
|
|
157
|
-
idx += size;
|
|
158
|
-
if (!stmtBodies.empty()) iterations.push_back(combineBodies(stmtBodies));
|
|
159
|
-
}
|
|
160
|
-
if (iterations.empty()) return {};
|
|
161
|
-
|
|
162
|
-
std::vector<ColoredBody> bodies3d;
|
|
163
|
-
for (const ColoredBody& c : iterations) {
|
|
164
|
-
if (c.body) bodies3d.push_back(c);
|
|
165
|
-
}
|
|
166
|
-
if (!bodies3d.empty()) {
|
|
167
|
-
manifold::Manifold result = *bodies3d.front().body;
|
|
168
|
-
for (size_t i = 1; i < bodies3d.size(); ++i) result = result ^ *bodies3d[i].body;
|
|
169
|
-
ColoredBody cb;
|
|
170
|
-
cb.body = std::move(result);
|
|
171
|
-
cb.color = bodies3d.front().color;
|
|
172
|
-
return {cb};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
std::vector<ColoredBody> sections;
|
|
176
|
-
for (const ColoredBody& c : iterations) {
|
|
177
|
-
if (c.section) sections.push_back(c);
|
|
178
|
-
}
|
|
179
|
-
if (!sections.empty()) {
|
|
180
|
-
manifold::CrossSection result = *sections.front().section;
|
|
181
|
-
for (size_t i = 1; i < sections.size(); ++i) result = result ^ *sections[i].section;
|
|
182
|
-
ColoredBody cb;
|
|
183
|
-
cb.section = std::move(result);
|
|
184
|
-
cb.color = iterations.front().color;
|
|
185
|
-
return {cb};
|
|
186
|
-
}
|
|
187
|
-
return {};
|
|
171
|
+
const oscad::ASTNode& node) {
|
|
172
|
+
// The same operand rules as intersection() itself -- empty statements,
|
|
173
|
+
// `%` scenery, `#` ghosts, 2D vs 3D -- over the flat statement list.
|
|
174
|
+
CSGParams p = params;
|
|
175
|
+
p["op"] = Value{std::string("intersection")};
|
|
176
|
+
return generateCsg(ev, p, children, node);
|
|
188
177
|
}
|
|
189
178
|
|
|
190
179
|
} // namespace oscadeval
|