openscad-cpp-evaluator 1.34.0__tar.gz → 1.36.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.34.0 → openscad_cpp_evaluator-1.36.0}/.github/workflows/ci.yml +14 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/.github/workflows/wheels.yml +9 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/CLAUDE.md +8 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/CMakeLists.txt +12 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/bindings/module.cpp +4 -3
- openscad_cpp_evaluator-1.36.0/cmake/patch_manifold.cmake +31 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/value.hpp +89 -4
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/booleans.cpp +3 -3
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/call_args.cpp +2 -2
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/control.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/dxf_dim.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/function_builtins.cpp +16 -9
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/import.cpp +11 -12
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/primitives_2d.cpp +4 -4
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/primitives_3d.cpp +8 -8
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/surface.cpp +2 -2
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/text.cpp +2 -3
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/bytecode_vm.cpp +9 -10
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/colored_body.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/eval_context.cpp +2 -2
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/expr_eval.cpp +16 -5
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/measure_geometry.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/value.cpp +94 -19
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/CMakeLists.txt +16 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_control_flow.cpp +91 -24
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_expr_eval.cpp +26 -13
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_function_builtins.cpp +9 -9
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_value.cpp +98 -15
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_viewport_params.cpp +2 -2
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/uv.lock +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/tools/cli/main.cpp +0 -0
|
@@ -50,8 +50,21 @@ jobs:
|
|
|
50
50
|
# Linux/macOS use (CMAKE_BUILD_TYPE already picked the config), but
|
|
51
51
|
# required on Windows's default multi-config Visual Studio
|
|
52
52
|
# generator, which ignores CMAKE_BUILD_TYPE entirely.
|
|
53
|
+
# A bounded job count on the Unix runners. A bare `-j` becomes `make -j`,
|
|
54
|
+
# which starts EVERY compile at once; on macos-latest (3 vCPU, 7 GB) a
|
|
55
|
+
# pile of template-heavy translation units that size ran the build at
|
|
56
|
+
# 852-2000 s against Linux's ~300 s. Windows keeps the bare -j: MSBuild
|
|
57
|
+
# reads it as "use the cores", which is already bounded.
|
|
53
58
|
- name: Build
|
|
54
|
-
|
|
59
|
+
shell: bash
|
|
60
|
+
run: |
|
|
61
|
+
case "$RUNNER_OS" in
|
|
62
|
+
macOS) JOBS=$(sysctl -n hw.ncpu) ;;
|
|
63
|
+
Linux) JOBS=$(nproc) ;;
|
|
64
|
+
*) JOBS= ;;
|
|
65
|
+
esac
|
|
66
|
+
echo "building with -j ${JOBS:-<unbounded: MSBuild>}"
|
|
67
|
+
cmake --build build --config Release -j $JOBS
|
|
55
68
|
|
|
56
69
|
# Bytecode VM on (the default as of the Phase 5 rollout decision --
|
|
57
70
|
# see evaluator.hpp's own bytecodeVmEnabled() comment) and off
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/.github/workflows/wheels.yml
RENAMED
|
@@ -38,8 +38,16 @@ jobs:
|
|
|
38
38
|
name: macos-arm64
|
|
39
39
|
- runner: macos-15-intel
|
|
40
40
|
name: macos-x86_64
|
|
41
|
+
# Two Windows jobs, one per architecture, both on the x86_64 runner
|
|
42
|
+
# (ARM64 is cross-compiled; see CIBW_ARCHS_WINDOWS). As one job they
|
|
43
|
+
# built one after the other -- 7 min each, 14.5 min for the job,
|
|
44
|
+
# the slowest in the release -- when neither needs the other.
|
|
41
45
|
- runner: windows-latest
|
|
42
46
|
name: windows-x86_64
|
|
47
|
+
archs: AMD64
|
|
48
|
+
- runner: windows-latest
|
|
49
|
+
name: windows-arm64
|
|
50
|
+
archs: ARM64
|
|
43
51
|
runs-on: ${{ matrix.runner }}
|
|
44
52
|
steps:
|
|
45
53
|
- uses: actions/checkout@v7
|
|
@@ -65,7 +73,7 @@ jobs:
|
|
|
65
73
|
# ARM64 build at all, so building on an ARM runner would have to
|
|
66
74
|
# emulate it. cibuildwheel skips CIBW_TEST_COMMAND for the
|
|
67
75
|
# cross-compiled wheel, since an x86_64 host cannot run it.
|
|
68
|
-
CIBW_ARCHS_WINDOWS:
|
|
76
|
+
CIBW_ARCHS_WINDOWS: ${{ matrix.archs }}
|
|
69
77
|
# delvewheel vendors the MSVC runtime into the wheel, but on an
|
|
70
78
|
# x86_64 host it can only find the x86_64 copy -- repairing the
|
|
71
79
|
# cross-built ARM64 wheel died with "Unable to find library:
|
|
@@ -9,7 +9,14 @@ OpenSCAD AST and produces Manifold CSG geometry. This port builds on two depende
|
|
|
9
9
|
|
|
10
10
|
- `openscad_cpp_parser` (git submodule, `external/openscad_cpp_parser`) for lexing/parsing/AST/scope
|
|
11
11
|
- Manifold (https://github.com/elalish/manifold) v3.5.2, pulled in via CMake `FetchContent` (pinned
|
|
12
|
-
tag, not vendored) — wired in as of Phase 2
|
|
12
|
+
tag, not vendored) — wired in as of Phase 2. **Patched at fetch time** by
|
|
13
|
+
`cmake/patch_manifold.cmake`: it deletes the `combined.RemoveDegenerates()` call in
|
|
14
|
+
`CsgLeafNode::Compose`, which on some inputs leaves the face data inconsistent so the sort after
|
|
15
|
+
it reads past an array (heap-buffer-overflow under ASan, reached by
|
|
16
|
+
`MinkowskiDifference.ShrinksANonConvexBodyOnEverySide`). Bisected with a Manifold-only repro to
|
|
17
|
+
upstream #1789 (969b1417), which fixes it by deleting the same call; unreleased as of 3.5.4.
|
|
18
|
+
The script fails the configure if the source around the call has changed, so **drop the patch
|
|
19
|
+
when bumping past #1789** rather than letting it rot
|
|
13
20
|
- Boost.Polygon (`boostorg/polygon` + `boostorg/config`, fetched individually — not the full Boost
|
|
14
21
|
superproject) for `roof()`'s Voronoi-diagram construction — wired in as of Phase 6, see below
|
|
15
22
|
- `nothings/stb` (`stb_image.h`; header-only, no build step) for `surface()`'s PNG loader — wired
|
|
@@ -79,6 +79,15 @@ if(MSVC)
|
|
|
79
79
|
# unconditionally (a POSIX extension our code already relies on), so no
|
|
80
80
|
# equivalent is needed there.
|
|
81
81
|
add_compile_definitions(_USE_MATH_DEFINES)
|
|
82
|
+
# /MP: compile a target's source files in parallel. MSBuild's own /m (what
|
|
83
|
+
# `cmake --build -j` passes) runs PROJECTS in parallel but each project's
|
|
84
|
+
# files one at a time, and nearly everything here is one big library, so a
|
|
85
|
+
# Windows build was close to serial (CI's Build step ~665 s against Linux's
|
|
86
|
+
# ~250). Visual Studio generators only: under Ninja every compiler call is
|
|
87
|
+
# already one file, and Ninja does the parallelism itself.
|
|
88
|
+
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
|
89
|
+
add_compile_options(/MP)
|
|
90
|
+
endif()
|
|
82
91
|
endif()
|
|
83
92
|
|
|
84
93
|
# The nanobind Python extension (bindings/) links the static evaluator lib
|
|
@@ -128,6 +137,9 @@ FetchContent_Declare(
|
|
|
128
137
|
GIT_REPOSITORY https://github.com/elalish/manifold.git
|
|
129
138
|
GIT_TAG v3.5.2
|
|
130
139
|
GIT_SHALLOW TRUE
|
|
140
|
+
# Backports the one line of upstream #1789 that fixes a heap overflow in
|
|
141
|
+
# CsgLeafNode::Compose -- see cmake/patch_manifold.cmake.
|
|
142
|
+
PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/patch_manifold.cmake
|
|
131
143
|
)
|
|
132
144
|
FetchContent_MakeAvailable(manifold)
|
|
133
145
|
|
|
@@ -73,9 +73,10 @@ oscadeval::Value pyToValue(nb::handle v) {
|
|
|
73
73
|
if (nb::isinstance<nb::int_>(v) || nb::isinstance<nb::float_>(v)) return oscadeval::Value{nb::cast<double>(v)};
|
|
74
74
|
if (nb::isinstance<nb::str>(v)) return oscadeval::Value{nb::cast<std::string>(v)};
|
|
75
75
|
if (nb::isinstance<nb::list>(v) || nb::isinstance<nb::tuple>(v)) {
|
|
76
|
-
oscadeval::
|
|
77
|
-
for (nb::handle item : nb::borrow<nb::sequence>(v))
|
|
78
|
-
return oscadeval::Value{oscadeval::ListPtr(
|
|
76
|
+
std::vector<oscadeval::Value> items;
|
|
77
|
+
for (nb::handle item : nb::borrow<nb::sequence>(v)) items.push_back(pyToValue(item));
|
|
78
|
+
return oscadeval::Value{oscadeval::ListPtr(
|
|
79
|
+
oscadeval::makeList(std::move(items)))};
|
|
79
80
|
}
|
|
80
81
|
return oscadeval::Value{}; // monostate = undef
|
|
81
82
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Patches the fetched Manifold v3.5.2 source; run as its FetchContent
|
|
2
|
+
# PATCH_COMMAND, in the source directory.
|
|
3
|
+
#
|
|
4
|
+
# CsgLeafNode::Compose calls RemoveDegenerates() on the combined mesh and
|
|
5
|
+
# then sorts it, and on some inputs the cleanup leaves the face data
|
|
6
|
+
# inconsistent: SortGeometry -> GatherFaces then reads past the end of an
|
|
7
|
+
# array (a heap-buffer-overflow under AddressSanitizer). Our
|
|
8
|
+
# MinkowskiDifference.ShrinksANonConvexBodyOnEverySide test reaches it;
|
|
9
|
+
# reproduced with Manifold alone, and bisected upstream to elalish/manifold
|
|
10
|
+
# #1789 ("Improved decimation", 969b1417), which fixes it by deleting this
|
|
11
|
+
# same call -- the only part of that commit the fix needs. Not in any
|
|
12
|
+
# release yet; drop this patch when Manifold is bumped past it.
|
|
13
|
+
#
|
|
14
|
+
# Idempotent: a re-run on already-patched source changes nothing. Anything
|
|
15
|
+
# else -- the call or its surroundings changed -- is an error, so a version
|
|
16
|
+
# bump can never silently skip the patch.
|
|
17
|
+
set(file src/csg_tree.cpp)
|
|
18
|
+
file(READ ${file} src)
|
|
19
|
+
set(call " // required to remove parts that are smaller than the tolerance\n combined.RemoveDegenerates();\n")
|
|
20
|
+
string(FIND "${src}" "${call}" at)
|
|
21
|
+
if(at EQUAL -1)
|
|
22
|
+
string(FIND "${src}" "combined.RemoveDegenerates();" any)
|
|
23
|
+
if(NOT any EQUAL -1)
|
|
24
|
+
message(FATAL_ERROR "patch_manifold.cmake: ${file} changed around RemoveDegenerates(); update the patch")
|
|
25
|
+
endif()
|
|
26
|
+
message(STATUS "patch_manifold.cmake: already applied")
|
|
27
|
+
return()
|
|
28
|
+
endif()
|
|
29
|
+
string(REPLACE "${call}" "" src "${src}")
|
|
30
|
+
file(WRITE ${file} "${src}")
|
|
31
|
+
message(STATUS "patch_manifold.cmake: removed RemoveDegenerates() from CsgLeafNode::Compose")
|
|
@@ -170,7 +170,7 @@ struct VmFrame {
|
|
|
170
170
|
std::vector<Value> slots;
|
|
171
171
|
std::vector<Value> stack;
|
|
172
172
|
std::vector<bool> bound;
|
|
173
|
-
std::vector<
|
|
173
|
+
std::vector<ListBuilder> accumStack;
|
|
174
174
|
std::vector<IterList> iterLists;
|
|
175
175
|
// std::deque, NOT vector: Evaluator::enterUserCall stores
|
|
176
176
|
// CallStackFrame::bodyCtx as a pointer to ctxChain.back() (see
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
#include "openscad_cpp_evaluator/osc_range.hpp"
|
|
4
4
|
|
|
5
|
+
#include <atomic>
|
|
6
|
+
#include <cstdint>
|
|
5
7
|
#include <functional>
|
|
8
|
+
#include <initializer_list>
|
|
6
9
|
#include <memory>
|
|
7
10
|
#include <optional>
|
|
8
11
|
#include <string>
|
|
@@ -98,11 +101,93 @@ inline std::shared_ptr<TrailView<Value>> capturedLetTrail(const Closure& c) {
|
|
|
98
101
|
return std::static_pointer_cast<TrailView<Value>>(c.capturedLet);
|
|
99
102
|
}
|
|
100
103
|
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
+
// A list's elements: a read-only view of the first `size()` elements of a
|
|
105
|
+
// buffer that other lists may share. Lists that are prefixes of one another
|
|
106
|
+
// share one buffer, which is what makes repeated appending cheap: `acc`
|
|
107
|
+
// and `concat(acc, [x])` are the same buffer, the second one element
|
|
108
|
+
// longer (listAppend). Defined after Value so both can hold Value by value
|
|
109
|
+
// -- the standard recursive-variant pattern.
|
|
110
|
+
//
|
|
111
|
+
// The buffer only ever grows within the capacity it was given, so element
|
|
112
|
+
// addresses never move while any view of it is alive, and an element, once
|
|
113
|
+
// written, is never changed. `used` is how far the longest view reaches;
|
|
114
|
+
// only a list ending exactly there may extend it, claiming the new slots
|
|
115
|
+
// with one compare-and-swap, so two lists sharing a prefix can never write
|
|
116
|
+
// the same slot (the loser copies).
|
|
117
|
+
struct ListBuffer {
|
|
118
|
+
std::vector<Value> v; // never reallocated once a list views it
|
|
119
|
+
std::atomic<uint32_t> used{0}; // with fromAppend, packs into one word
|
|
120
|
+
// Set when this buffer came from appending: a list that was appended
|
|
121
|
+
// to once is likely to be again, so ITS copies grow geometrically,
|
|
122
|
+
// while a one-off concat's result is allocated at exactly its size.
|
|
123
|
+
bool fromAppend = false;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// A list's elements: the first `size()` of a buffer. A list made by
|
|
127
|
+
// makeList keeps its buffer in its own allocation (keep_ empty); one made by
|
|
128
|
+
// appending in place views the buffer of the list it extends, and keep_
|
|
129
|
+
// holds that list's allocation alive. The element pointer is cached, so a
|
|
130
|
+
// read is one hop, as with a plain vector. Neither copyable nor movable:
|
|
131
|
+
// an own-buffer view must never outlive the allocation it sits in.
|
|
132
|
+
class ListItems {
|
|
133
|
+
public:
|
|
134
|
+
ListItems() = default;
|
|
135
|
+
ListItems(const ListItems&) = delete;
|
|
136
|
+
ListItems& operator=(const ListItems&) = delete;
|
|
137
|
+
|
|
138
|
+
size_t size() const { return n_; }
|
|
139
|
+
bool empty() const { return n_ == 0; }
|
|
140
|
+
const Value* data() const { return data_; }
|
|
141
|
+
const Value* begin() const { return data_; }
|
|
142
|
+
const Value* end() const { return data_ + n_; }
|
|
143
|
+
const Value& operator[](size_t i) const { return data_[i]; }
|
|
144
|
+
const Value& at(size_t i) const;
|
|
145
|
+
const Value& front() const { return data_[0]; }
|
|
146
|
+
const Value& back() const { return data_[n_ - 1]; }
|
|
147
|
+
// A copy as a plain vector, for the few callers that build on one.
|
|
148
|
+
// Explicit, so a copy is never made by accident binding a reference.
|
|
149
|
+
explicit operator std::vector<Value>() const { return std::vector<Value>(begin(), end()); }
|
|
150
|
+
std::vector<Value> toVector() const { return std::vector<Value>(begin(), end()); }
|
|
151
|
+
|
|
152
|
+
private:
|
|
153
|
+
std::shared_ptr<const void> keep_;
|
|
154
|
+
ListBuffer* buf_ = nullptr;
|
|
155
|
+
const Value* data_ = nullptr;
|
|
156
|
+
size_t n_ = 0;
|
|
157
|
+
friend ListPtr makeList(std::vector<Value> items);
|
|
158
|
+
friend ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra);
|
|
159
|
+
};
|
|
160
|
+
|
|
104
161
|
struct ValueList {
|
|
105
|
-
|
|
162
|
+
ListItems items;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// A new list holding `items` (adopted, not copied): one allocation for the
|
|
166
|
+
// list and its buffer together, plus the elements' own -- as many as a list
|
|
167
|
+
// that was a plain vector cost.
|
|
168
|
+
ListPtr makeList(std::vector<Value> items);
|
|
169
|
+
inline ListPtr makeList() { return makeList(std::vector<Value>{}); }
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
// `base` followed by `extra`, sharing base's buffer whenever base is the
|
|
173
|
+
// longest list using it and the buffer has room: amortized O(|extra|)
|
|
174
|
+
// rather than O(|base| + |extra|), which is what turns the idiomatic
|
|
175
|
+
// tail-recursive accumulator, f(i, concat(acc, [x])), from quadratic into
|
|
176
|
+
// linear. Safe whatever else still holds `base`: base keeps seeing only
|
|
177
|
+
// its own elements.
|
|
178
|
+
ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra);
|
|
179
|
+
|
|
180
|
+
// Builds a list literal or comprehension result from its contributions. When
|
|
181
|
+
// the first contribution is `each <a list>`, the result starts AS that list
|
|
182
|
+
// and everything after it is appended with listAppend -- so the other
|
|
183
|
+
// accumulator idiom, f(i, [each acc, x]), extends acc in place just as
|
|
184
|
+
// concat(acc, [x]) does, instead of copying it.
|
|
185
|
+
struct ListBuilder {
|
|
186
|
+
ListPtr seed; // the list an `each` started from, if any
|
|
187
|
+
std::vector<Value> rest; // everything contributed after it
|
|
188
|
+
void push(Value v) { rest.push_back(std::move(v)); }
|
|
189
|
+
void appendEach(const Value& v); // as appendEachInto
|
|
190
|
+
ListPtr finish();
|
|
106
191
|
};
|
|
107
192
|
|
|
108
193
|
// Insertion-ordered key/value pairs, not a map: object()'s iteration order
|
|
@@ -143,9 +143,9 @@ CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
143
143
|
|
|
144
144
|
CSGParams params;
|
|
145
145
|
params["op"] = Value{op};
|
|
146
|
-
params["group_sizes"] = Value{
|
|
146
|
+
params["group_sizes"] = Value{makeList(std::move(groupSizes))};
|
|
147
147
|
params["empty_is_a_group"] =
|
|
148
|
-
Value{
|
|
148
|
+
Value{makeList(std::move(emptyIsAGroup))};
|
|
149
149
|
return params;
|
|
150
150
|
}
|
|
151
151
|
|
|
@@ -313,7 +313,7 @@ std::vector<ColoredBody> generateCsg(Evaluator& ev, const CSGParams& params, con
|
|
|
313
313
|
const std::string& op = std::get<std::string>(params.at("op"));
|
|
314
314
|
const auto& groupSizes = std::get<ListPtr>(params.at("group_sizes"))->items;
|
|
315
315
|
const auto emptyIsAGroupIt = params.find("empty_is_a_group");
|
|
316
|
-
const
|
|
316
|
+
const ListItems* emptyIsAGroup =
|
|
317
317
|
emptyIsAGroupIt == params.end()
|
|
318
318
|
? nullptr
|
|
319
319
|
: &std::get<ListPtr>(emptyIsAGroupIt->second)->items;
|
|
@@ -93,10 +93,10 @@ Value callArgsToValue(const CallArgs& args) {
|
|
|
93
93
|
std::vector<std::pair<std::string, Value>> namedVec(args.named.begin(), args.named.end());
|
|
94
94
|
|
|
95
95
|
std::vector<Value> outer = {
|
|
96
|
-
Value{
|
|
96
|
+
Value{makeList(std::move(posVec))},
|
|
97
97
|
Value{std::make_shared<const ValueObject>(ValueObject{std::move(namedVec)})},
|
|
98
98
|
};
|
|
99
|
-
return Value{
|
|
99
|
+
return Value{makeList(std::move(outer))};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
const oscad::Expression* argExpr(const oscad::Argument& arg) {
|
|
@@ -141,7 +141,7 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
141
141
|
recurse(0, ctx);
|
|
142
142
|
|
|
143
143
|
CSGParams params;
|
|
144
|
-
params["group_sizes"] = Value{
|
|
144
|
+
params["group_sizes"] = Value{makeList(std::move(groupSizes))};
|
|
145
145
|
return params;
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -234,7 +234,7 @@ Value builtinDxfCross(Evaluator& ev, const CallArgs& args, const oscad::ASTNode&
|
|
|
234
234
|
if (dem == 0.0) break; // parallel: no cross, same as the reference
|
|
235
235
|
const double ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / dem;
|
|
236
236
|
std::vector<Value> xy{Value{x1 + ua * (x2 - x1)}, Value{y1 + ua * (y2 - y1)}};
|
|
237
|
-
return Value{
|
|
237
|
+
return Value{makeList(std::move(xy))};
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
ev.warn("Can't find cross in '" + c.rawFile + "', layer '" + c.layer + "'!", &node.position());
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/function_builtins.cpp
RENAMED
|
@@ -48,7 +48,7 @@ std::optional<std::vector<double>> allNumericList(const Value& v) {
|
|
|
48
48
|
return out;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
Value listOf(std::vector<Value> items) { return Value{
|
|
51
|
+
Value listOf(std::vector<Value> items) { return Value{makeList(std::move(items))}; }
|
|
52
52
|
Value numList(const std::vector<double>& xs) {
|
|
53
53
|
std::vector<Value> items;
|
|
54
54
|
items.reserve(xs.size());
|
|
@@ -616,11 +616,11 @@ Value builtinSearch(const CallArgs& args, Evaluator& ev, const oscad::Position*
|
|
|
616
616
|
const unsigned numReturns = static_cast<unsigned>(static_cast<long long>(nrRaw));
|
|
617
617
|
const unsigned indexCol = static_cast<unsigned>(static_cast<long long>(icRaw));
|
|
618
618
|
|
|
619
|
-
static const
|
|
619
|
+
static const ListItems kNoItems;
|
|
620
620
|
const ListPtr* tablePtr = std::get_if<ListPtr>(&tableArg);
|
|
621
|
-
const
|
|
621
|
+
const ListItems& table = (tablePtr && *tablePtr) ? (*tablePtr)->items : kNoItems;
|
|
622
622
|
|
|
623
|
-
const auto itemsOf = [](const Value& v) -> const
|
|
623
|
+
const auto itemsOf = [](const Value& v) -> const ListItems& {
|
|
624
624
|
const ListPtr* l = std::get_if<ListPtr>(&v);
|
|
625
625
|
return (l && *l) ? (*l)->items : kNoItems;
|
|
626
626
|
};
|
|
@@ -629,7 +629,7 @@ Value builtinSearch(const CallArgs& args, Evaluator& ev, const oscad::Position*
|
|
|
629
629
|
// only when the entry really is a long enough vector.
|
|
630
630
|
const auto hits = [&](const Value& needle, const Value& entry) {
|
|
631
631
|
if (indexCol == 0 && oscEqual(needle, entry)) return true;
|
|
632
|
-
const
|
|
632
|
+
const ListItems& ev2 = itemsOf(entry);
|
|
633
633
|
return indexCol < ev2.size() && oscEqual(needle, ev2[indexCol]);
|
|
634
634
|
};
|
|
635
635
|
const auto num = [](size_t j) { return Value{static_cast<double>(j)}; };
|
|
@@ -682,7 +682,7 @@ Value builtinSearch(const CallArgs& args, Evaluator& ev, const oscad::Position*
|
|
|
682
682
|
unsigned matchCount = 0;
|
|
683
683
|
std::vector<Value> resultvec;
|
|
684
684
|
for (size_t j = 0; j < table.size(); ++j) {
|
|
685
|
-
const
|
|
685
|
+
const ListItems& entryVec = itemsOf(table[j]);
|
|
686
686
|
if (entryVec.size() <= indexCol) {
|
|
687
687
|
ev.warn("Invalid entry in search vector at index " + std::to_string(j) +
|
|
688
688
|
", required number of values in the entry: " + std::to_string(indexCol + 1) +
|
|
@@ -1162,9 +1162,9 @@ bool checkMinMax(Evaluator& ev, const std::string& name, const CallArgs& args, c
|
|
|
1162
1162
|
return false;
|
|
1163
1163
|
}
|
|
1164
1164
|
if (nPos == 1 && std::holds_alternative<ListPtr>(positionalAt(args, 0))) {
|
|
1165
|
-
static const
|
|
1165
|
+
static const ListItems kEmptyItems;
|
|
1166
1166
|
const ListPtr& l = std::get<ListPtr>(positionalAt(args, 0));
|
|
1167
|
-
const
|
|
1167
|
+
const ListItems& items = l ? l->items : kEmptyItems;
|
|
1168
1168
|
if (items.empty()) {
|
|
1169
1169
|
warnArity(ev, name, "at least 1 vector element", 0, pos);
|
|
1170
1170
|
return false;
|
|
@@ -1346,14 +1346,21 @@ Value evalBuiltinFunctionResolved(Evaluator& ev, BuiltinFnId id, const std::vect
|
|
|
1346
1346
|
toDoubleLenient(getArg(args, 2, "value_count", Value{})), getArg(args, 3, "seed", Value{}));
|
|
1347
1347
|
}
|
|
1348
1348
|
case BuiltinFnId::Concat: {
|
|
1349
|
+
// Everything after the first argument, appended to the first
|
|
1350
|
+
// when it is a list: listAppend extends its buffer in place when
|
|
1351
|
+
// it can, so an accumulator loop is linear, not quadratic.
|
|
1352
|
+
const size_t count = positionalCount(args);
|
|
1353
|
+
const ListPtr* first = count ? std::get_if<ListPtr>(&positionalAt(args, 0)) : nullptr;
|
|
1349
1354
|
std::vector<Value> out;
|
|
1350
|
-
for (
|
|
1355
|
+
for (size_t i = (first && *first) ? 1 : 0; i < count; ++i) {
|
|
1356
|
+
const Value& a = positionalAt(args, i);
|
|
1351
1357
|
if (const ListPtr* l = std::get_if<ListPtr>(&a); l && *l) {
|
|
1352
1358
|
out.insert(out.end(), (*l)->items.begin(), (*l)->items.end());
|
|
1353
1359
|
} else {
|
|
1354
1360
|
out.push_back(a);
|
|
1355
1361
|
}
|
|
1356
1362
|
}
|
|
1363
|
+
if (first && *first) return Value{listAppend(*first, std::move(out))};
|
|
1357
1364
|
return listOf(std::move(out));
|
|
1358
1365
|
}
|
|
1359
1366
|
case BuiltinFnId::Len: {
|
|
@@ -66,7 +66,7 @@ Value jsonToValue(const nlohmann::ordered_json& j) {
|
|
|
66
66
|
std::vector<Value> items;
|
|
67
67
|
items.reserve(j.size());
|
|
68
68
|
for (const auto& el : j) items.push_back(jsonToValue(el));
|
|
69
|
-
return Value{
|
|
69
|
+
return Value{makeList(std::move(items))};
|
|
70
70
|
}
|
|
71
71
|
if (j.is_object()) {
|
|
72
72
|
std::vector<std::pair<std::string, Value>> items;
|
|
@@ -102,20 +102,19 @@ Value meshToVnf(const LoadedMesh& mesh) {
|
|
|
102
102
|
if (it == vertMap.end()) {
|
|
103
103
|
idx = static_cast<int>(vertsOut.size());
|
|
104
104
|
vertMap.emplace(v, idx);
|
|
105
|
-
vertsOut.push_back(Value{
|
|
106
|
-
ValueList{{Value{v[0]}, Value{v[1]}, Value{v[2]}}})});
|
|
105
|
+
vertsOut.push_back(Value{makeList({Value{v[0]}, Value{v[1]}, Value{v[2]}})});
|
|
107
106
|
} else {
|
|
108
107
|
idx = it->second;
|
|
109
108
|
}
|
|
110
109
|
face.push_back(Value{static_cast<double>(idx)});
|
|
111
110
|
}
|
|
112
|
-
facesOut.push_back(Value{
|
|
111
|
+
facesOut.push_back(Value{makeList(std::move(face))});
|
|
113
112
|
}
|
|
114
113
|
std::vector<Value> outer = {
|
|
115
|
-
Value{
|
|
116
|
-
Value{
|
|
114
|
+
Value{makeList(std::move(vertsOut))},
|
|
115
|
+
Value{makeList(std::move(facesOut))},
|
|
117
116
|
};
|
|
118
|
-
return Value{
|
|
117
|
+
return Value{makeList(std::move(outer))};
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
} // namespace
|
|
@@ -152,10 +151,10 @@ Value contoursToValue(const std::vector<Contour2d>& contours) {
|
|
|
152
151
|
for (const auto& c : contours) {
|
|
153
152
|
std::vector<Value> pts;
|
|
154
153
|
pts.reserve(c.size());
|
|
155
|
-
for (const auto& p : c) pts.push_back(Value{
|
|
156
|
-
outer.push_back(Value{
|
|
154
|
+
for (const auto& p : c) pts.push_back(Value{makeList({Value{p[0]}, Value{p[1]}})});
|
|
155
|
+
outer.push_back(Value{makeList(std::move(pts))});
|
|
157
156
|
}
|
|
158
|
-
return Value{
|
|
157
|
+
return Value{makeList(std::move(outer))};
|
|
159
158
|
}
|
|
160
159
|
|
|
161
160
|
std::vector<Contour2d> valueToContours(const Value& v) {
|
|
@@ -284,8 +283,8 @@ CSGParams resolveImport(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
284
283
|
params["kind"] = Value{std::string("mesh")};
|
|
285
284
|
params["repair"] = Value{repair};
|
|
286
285
|
params["tolerance"] = toleranceArg;
|
|
287
|
-
params["verts"] = Value{
|
|
288
|
-
params["tris"] = Value{
|
|
286
|
+
params["verts"] = Value{makeList(std::move(vertsFlat))};
|
|
287
|
+
params["tris"] = Value{makeList(std::move(trisFlat))};
|
|
289
288
|
return params;
|
|
290
289
|
}
|
|
291
290
|
if (ext == ".json") {
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/primitives_2d.cpp
RENAMED
|
@@ -79,9 +79,9 @@ CSGParams resolve2d(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
79
79
|
const double x = (pl && *pl && !(*pl)->items.empty()) ? toDoubleLenient((*pl)->items[0]) : 0.0;
|
|
80
80
|
const double y = (pl && *pl && (*pl)->items.size() > 1) ? toDoubleLenient((*pl)->items[1]) : 0.0;
|
|
81
81
|
std::vector<Value> xy = {Value{x}, Value{y}};
|
|
82
|
-
pts.push_back(Value{
|
|
82
|
+
pts.push_back(Value{makeList(std::move(xy))});
|
|
83
83
|
}
|
|
84
|
-
params["pts"] = Value{
|
|
84
|
+
params["pts"] = Value{makeList(std::move(pts))};
|
|
85
85
|
|
|
86
86
|
if (const ListPtr* pathsList = std::get_if<ListPtr>(&pathsArg); pathsList && *pathsList) {
|
|
87
87
|
std::vector<Value> paths;
|
|
@@ -91,9 +91,9 @@ CSGParams resolve2d(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
91
91
|
if (pathIdxList && *pathIdxList) {
|
|
92
92
|
for (const Value& idx : (*pathIdxList)->items) idxVals.push_back(Value{toDoubleLenient(idx)});
|
|
93
93
|
}
|
|
94
|
-
paths.push_back(Value{
|
|
94
|
+
paths.push_back(Value{makeList(std::move(idxVals))});
|
|
95
95
|
}
|
|
96
|
-
params["paths"] = Value{
|
|
96
|
+
params["paths"] = Value{makeList(std::move(paths))};
|
|
97
97
|
} else {
|
|
98
98
|
params["paths"] = Value{}; // undef == "no paths given" -- pts is one single contour
|
|
99
99
|
}
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.36.0}/src/builtins/primitives_3d.cpp
RENAMED
|
@@ -133,7 +133,7 @@ CSGParams resolveCube(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
133
133
|
} else if (l && *l && (*l)->items.size() == 3 &&
|
|
134
134
|
std::all_of((*l)->items.begin(), (*l)->items.end(),
|
|
135
135
|
[](const Value& v) { return std::holds_alternative<double>(v); })) {
|
|
136
|
-
sizeVec = (*l)->items;
|
|
136
|
+
sizeVec = (*l)->items.toVector();
|
|
137
137
|
} else if (!std::holds_alternative<std::monostate>(sizeArg)) {
|
|
138
138
|
ev.warn("Unable to convert cube(size=" + fmtValue(sizeArg) +
|
|
139
139
|
", ...) parameter to a number or a vec3 of numbers",
|
|
@@ -141,7 +141,7 @@ CSGParams resolveCube(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
CSGParams params;
|
|
144
|
-
params["size"] = Value{
|
|
144
|
+
params["size"] = Value{makeList(std::move(sizeVec))};
|
|
145
145
|
params["center"] = Value{center};
|
|
146
146
|
params["color"] = colorToValue(effCtx.color);
|
|
147
147
|
return params;
|
|
@@ -402,8 +402,8 @@ CSGParams resolveSphere(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
402
402
|
// Manifold::Sphere IS a subdivided octahedron (Shape::Octahedron,
|
|
403
403
|
// then Subdivide), so this needs no mesh of our own -- generate
|
|
404
404
|
// calls it directly.
|
|
405
|
-
params["verts"] = Value{
|
|
406
|
-
params["tris"] = Value{
|
|
405
|
+
params["verts"] = Value{makeList()};
|
|
406
|
+
params["tris"] = Value{makeList()};
|
|
407
407
|
return params;
|
|
408
408
|
}
|
|
409
409
|
|
|
@@ -418,8 +418,8 @@ CSGParams resolveSphere(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
418
418
|
std::vector<Value> trisValues;
|
|
419
419
|
trisValues.reserve(m.tris.size());
|
|
420
420
|
for (int t : m.tris) trisValues.push_back(Value{static_cast<double>(t)});
|
|
421
|
-
params["verts"] = Value{
|
|
422
|
-
params["tris"] = Value{
|
|
421
|
+
params["verts"] = Value{makeList(std::move(vertsValues))};
|
|
422
|
+
params["tris"] = Value{makeList(std::move(trisValues))};
|
|
423
423
|
return params;
|
|
424
424
|
}
|
|
425
425
|
|
|
@@ -832,8 +832,8 @@ CSGParams resolvePolyhedron(Evaluator& ev, const oscad::ModularCall& node, EvalC
|
|
|
832
832
|
for (uint32_t t : tris) trisValues.push_back(Value{static_cast<double>(t)});
|
|
833
833
|
|
|
834
834
|
CSGParams params;
|
|
835
|
-
params["verts"] = Value{
|
|
836
|
-
params["tris"] = Value{
|
|
835
|
+
params["verts"] = Value{makeList(std::move(vertsValues))};
|
|
836
|
+
params["tris"] = Value{makeList(std::move(trisValues))};
|
|
837
837
|
params["color"] = colorToValue(effCtx.color);
|
|
838
838
|
return params;
|
|
839
839
|
}
|
|
@@ -44,9 +44,9 @@ CSGParams resolveSurface(Evaluator& ev, const oscad::ModularCall& node, EvalCont
|
|
|
44
44
|
std::vector<Value> rowVals;
|
|
45
45
|
rowVals.reserve(row.size());
|
|
46
46
|
for (double v : row) rowVals.push_back(Value{v});
|
|
47
|
-
rows.push_back(Value{
|
|
47
|
+
rows.push_back(Value{makeList(std::move(rowVals))});
|
|
48
48
|
}
|
|
49
|
-
params["heights"] = Value{
|
|
49
|
+
params["heights"] = Value{makeList(std::move(rows))};
|
|
50
50
|
return params;
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -69,8 +69,7 @@ CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
69
69
|
std::vector<Value> glyphs;
|
|
70
70
|
glyphs.reserve(m.glyphs.size());
|
|
71
71
|
for (const TextMeasurement::Placed& g : m.glyphs) {
|
|
72
|
-
glyphs.push_back(Value{
|
|
73
|
-
ValueList{{Value{static_cast<double>(g.glyph)}, Value{g.x}, Value{g.y}}})});
|
|
72
|
+
glyphs.push_back(Value{makeList({Value{static_cast<double>(g.glyph)}, Value{g.x}, Value{g.y}})});
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
CSGParams params;
|
|
@@ -89,7 +88,7 @@ CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
89
88
|
params["segs"] = Value{static_cast<double>(segs)};
|
|
90
89
|
params["offset_x"] = Value{offsetX};
|
|
91
90
|
params["offset_y"] = Value{offsetY};
|
|
92
|
-
params["glyphs"] = Value{
|
|
91
|
+
params["glyphs"] = Value{makeList(std::move(glyphs))};
|
|
93
92
|
params["color"] = colorToValue(effCtx.color);
|
|
94
93
|
return params;
|
|
95
94
|
}
|
|
@@ -792,7 +792,7 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
792
792
|
items[count - 1 - i] = std::move(f.stack.back());
|
|
793
793
|
f.stack.pop_back();
|
|
794
794
|
}
|
|
795
|
-
f.stack.push_back(Value{
|
|
795
|
+
f.stack.push_back(Value{makeList(std::move(items))});
|
|
796
796
|
++f.pc;
|
|
797
797
|
break;
|
|
798
798
|
}
|
|
@@ -803,28 +803,28 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
803
803
|
case Op::AccumAppendOne: {
|
|
804
804
|
Value v = std::move(f.stack.back());
|
|
805
805
|
f.stack.pop_back();
|
|
806
|
-
f.accumStack.back().
|
|
806
|
+
f.accumStack.back().push(std::move(v));
|
|
807
807
|
++f.pc;
|
|
808
808
|
break;
|
|
809
809
|
}
|
|
810
810
|
case Op::AccumAppendEach: {
|
|
811
811
|
Value v = std::move(f.stack.back());
|
|
812
812
|
f.stack.pop_back();
|
|
813
|
-
|
|
813
|
+
f.accumStack.back().appendEach(v);
|
|
814
814
|
++f.pc;
|
|
815
815
|
break;
|
|
816
816
|
}
|
|
817
817
|
case Op::AccumClose: {
|
|
818
|
-
|
|
818
|
+
ListPtr list = f.accumStack.back().finish();
|
|
819
819
|
f.accumStack.pop_back();
|
|
820
|
-
f.stack.push_back(Value{std::
|
|
820
|
+
f.stack.push_back(Value{std::move(list)});
|
|
821
821
|
++f.pc;
|
|
822
822
|
break;
|
|
823
823
|
}
|
|
824
824
|
case Op::AccumMergeEach: {
|
|
825
|
-
|
|
825
|
+
const ListPtr inner = f.accumStack.back().finish();
|
|
826
826
|
f.accumStack.pop_back();
|
|
827
|
-
for (const Value& item : inner)
|
|
827
|
+
for (const Value& item : inner->items) f.accumStack.back().appendEach(item);
|
|
828
828
|
++f.pc;
|
|
829
829
|
break;
|
|
830
830
|
}
|
|
@@ -1492,9 +1492,8 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1492
1492
|
CSGParams params;
|
|
1493
1493
|
if (site.includeOpParam) params["op"] = Value{pending.op};
|
|
1494
1494
|
params["group_sizes"] =
|
|
1495
|
-
Value{
|
|
1496
|
-
params["empty_is_a_group"] = Value{std::
|
|
1497
|
-
ValueList{std::move(pending.emptyIsAGroup)})};
|
|
1495
|
+
Value{makeList(std::move(pending.groupSizes))};
|
|
1496
|
+
params["empty_is_a_group"] = Value{makeList(std::move(pending.emptyIsAGroup))};
|
|
1498
1497
|
// Mirrors Evaluator::buildTreeNode's own post-
|
|
1499
1498
|
// resolveBody() half exactly (csg_resolve.cpp).
|
|
1500
1499
|
const bool uncacheable =
|