openscad-cpp-evaluator 0.1.0__tar.gz → 0.2.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-0.1.0 → openscad_cpp_evaluator-0.2.0}/.github/workflows/wheels.yml +1 -1
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/bindings/module.cpp +154 -52
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/evaluator.hpp +9 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/pyproject.toml +1 -1
- openscad_cpp_evaluator-0.2.0/python/openscad_cpp_evaluator/__init__.py +370 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/csg_resolve.cpp +1 -0
- openscad_cpp_evaluator-0.2.0/tests/test_python_bindings.py +140 -0
- openscad_cpp_evaluator-0.1.0/python/openscad_cpp_evaluator/__init__.py +0 -207
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/README.md +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/bundled_font_path.hpp.in +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/text/stb_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.1.0 → openscad_cpp_evaluator-0.2.0}/tools/cli/main.cpp +0 -0
|
@@ -82,7 +82,7 @@ jobs:
|
|
|
82
82
|
# C:\msys64 (not on PATH); its bison/flex satisfy the parser
|
|
83
83
|
# submodule's grammar version requirement.
|
|
84
84
|
CIBW_BEFORE_ALL_WINDOWS: 'C:\msys64\usr\bin\bash.exe -lc "pacman -Sy --noconfirm bison flex"'
|
|
85
|
-
CIBW_TEST_COMMAND: "python
|
|
85
|
+
CIBW_TEST_COMMAND: "python {package}/tests/test_python_bindings.py"
|
|
86
86
|
|
|
87
87
|
- uses: actions/upload-artifact@v7
|
|
88
88
|
with:
|
|
@@ -13,12 +13,16 @@
|
|
|
13
13
|
|
|
14
14
|
#include <nanobind/nanobind.h>
|
|
15
15
|
#include <nanobind/ndarray.h>
|
|
16
|
+
#include <nanobind/stl/shared_ptr.h>
|
|
16
17
|
#include <nanobind/stl/string.h>
|
|
17
18
|
|
|
18
19
|
#include "openscad_cpp_evaluator/colored_body.hpp"
|
|
20
|
+
#include "openscad_cpp_evaluator/csg_node.hpp"
|
|
19
21
|
#include "openscad_cpp_evaluator/eval_context.hpp"
|
|
20
22
|
#include "openscad_cpp_evaluator/eval_use.hpp"
|
|
21
23
|
#include "openscad_cpp_evaluator/evaluator.hpp"
|
|
24
|
+
#include "openscad_cpp_evaluator/manifold_cache.hpp"
|
|
25
|
+
#include "openscad_cpp_evaluator/profile.hpp"
|
|
22
26
|
#include "openscad_cpp_evaluator/value.hpp"
|
|
23
27
|
|
|
24
28
|
#include "openscad_cpp_parser/api.hpp"
|
|
@@ -67,6 +71,44 @@ std::unordered_map<std::string, oscadeval::Value> toViewportParams(nb::dict d) {
|
|
|
67
71
|
return out;
|
|
68
72
|
}
|
|
69
73
|
|
|
74
|
+
// A facade class handle (openscad_cpp_evaluator.<name>), imported lazily at
|
|
75
|
+
// first use and leaked deliberately -- never destroyed, so no nb::object
|
|
76
|
+
// destructor runs after Python finalization (the app exits via os._exit,
|
|
77
|
+
// which skips finalizers; a normal-shutdown consumer would otherwise crash).
|
|
78
|
+
nb::object facadeAttr(const char* name) {
|
|
79
|
+
static nb::object* mod = new nb::object(nb::module_::import_("openscad_cpp_evaluator"));
|
|
80
|
+
return mod->attr(name);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
nb::object valueToPy(const oscadeval::Value& v); // recursive
|
|
84
|
+
|
|
85
|
+
nb::object valueToPy(const oscadeval::Value& v) {
|
|
86
|
+
if (std::holds_alternative<std::monostate>(v)) return nb::none();
|
|
87
|
+
if (const bool* b = std::get_if<bool>(&v)) return nb::cast(*b);
|
|
88
|
+
if (const double* d = std::get_if<double>(&v)) return nb::cast(*d);
|
|
89
|
+
if (const std::string* s = std::get_if<std::string>(&v)) return nb::cast(*s);
|
|
90
|
+
if (const oscadeval::ListPtr* lp = std::get_if<oscadeval::ListPtr>(&v)) {
|
|
91
|
+
nb::list out;
|
|
92
|
+
if (*lp)
|
|
93
|
+
for (const oscadeval::Value& item : (*lp)->items) out.append(valueToPy(item));
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
if (const oscadeval::ObjectPtr* op = std::get_if<oscadeval::ObjectPtr>(&v)) {
|
|
97
|
+
nb::dict data;
|
|
98
|
+
if (*op)
|
|
99
|
+
for (const auto& [k, val] : (*op)->items) data[nb::str(k.c_str())] = valueToPy(val);
|
|
100
|
+
return facadeAttr("OscObject")(data);
|
|
101
|
+
}
|
|
102
|
+
// OscRange / FunctionLiteral: no direct Python analog -- wrap the
|
|
103
|
+
// OpenSCAD text so the debugger displays it cleanly (unquoted).
|
|
104
|
+
return facadeAttr("_ScadValue")(oscadeval::fmtValue(v));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
nb::object posToPy(const oscad::Position* p) {
|
|
108
|
+
if (!p) return nb::none();
|
|
109
|
+
return facadeAttr("_Position")(p->line, p->column, p->origin, p->start_offset, p->end_offset);
|
|
110
|
+
}
|
|
111
|
+
|
|
70
112
|
// One evaluated body's mesh + attributes, shaped to match what the renderer
|
|
71
113
|
// already reads off a manifold3d mesh (vert_properties (nVert, numProp),
|
|
72
114
|
// tri_verts (nTri, 3), run_original_id (nRun,), run_index (nRun+1,) -- the
|
|
@@ -124,30 +166,98 @@ nb::dict idSpansToDict(const std::vector<IdSpan>& idSpans) {
|
|
|
124
166
|
return d;
|
|
125
167
|
}
|
|
126
168
|
|
|
127
|
-
//
|
|
169
|
+
// CSGNode -> a facade `_CSGNode` (kind/params/bodies/is_builtin/children),
|
|
170
|
+
// recursively, eagerly converting every field to plain Python data. No
|
|
171
|
+
// lifetime extension needed -- CSGParams (Value-only, see csg_node.hpp) and
|
|
172
|
+
// ColoredBody never hold AST pointers, so the result is fully self-contained
|
|
173
|
+
// once built, unlike CSGNode::node itself (deliberately not exposed: the AST
|
|
174
|
+
// it points into does not outlive this binding call, and the CSG-tree dump
|
|
175
|
+
// consumer only ever needs kind/params/children/bodies -- see
|
|
176
|
+
// format_csg_tree's own doc comment).
|
|
177
|
+
nb::object csgNodeToPy(const oscadeval::CSGNode& node) {
|
|
178
|
+
nb::dict params;
|
|
179
|
+
for (const auto& [k, v] : node.params) params[nb::str(k.c_str())] = valueToPy(v);
|
|
180
|
+
nb::list bodies;
|
|
181
|
+
for (const oscadeval::ColoredBody& cb : node.bodies) {
|
|
182
|
+
if (!cb.body || cb.body->IsEmpty()) continue;
|
|
183
|
+
// ColoredBody here is const in this walk (tree ownership stays with
|
|
184
|
+
// the caller) -- GetMeshGL() itself is logically read-only, so a
|
|
185
|
+
// const_cast here is safe/local, mirroring bodyToDict's mutating
|
|
186
|
+
// signature only because manifold3d's own API isn't const-qualified.
|
|
187
|
+
bodies.append(bodyToDict(const_cast<oscadeval::ColoredBody&>(cb)));
|
|
188
|
+
}
|
|
189
|
+
nb::list children;
|
|
190
|
+
for (const std::unique_ptr<oscadeval::CSGNode>& child : node.children) children.append(csgNodeToPy(*child));
|
|
191
|
+
return facadeAttr("_CSGNode")(node.kind, params, bodies, node.isBuiltin, children);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
nb::list csgTreeToPy(const std::vector<std::unique_ptr<oscadeval::CSGNode>>& tree) {
|
|
195
|
+
nb::list out;
|
|
196
|
+
for (const std::unique_ptr<oscadeval::CSGNode>& node : tree) out.append(csgNodeToPy(*node));
|
|
197
|
+
return out;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
nb::object profileResultToPy(const std::optional<oscadeval::ProfileResult>& pr) {
|
|
201
|
+
if (!pr) return nb::none();
|
|
202
|
+
nb::list sites;
|
|
203
|
+
for (const oscadeval::CallSiteProfile& s : pr->callSites) {
|
|
204
|
+
sites.append(facadeAttr("CallSiteProfile")(s.kind, s.name, s.callerName, s.callOrigin, s.callLine, s.declOrigin,
|
|
205
|
+
s.declLine, s.callCount, s.selfTime, s.cumulativeTime));
|
|
206
|
+
}
|
|
207
|
+
return facadeAttr("ProfileResult")(sites, pr->resolveTime, pr->generateTime, pr->totalTime, pr->unattributedTime);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ctx.dyn / ctx.dynExplicit -> (dict[str, Any], set[str]) -- every currently-
|
|
211
|
+
// visible $-prefixed dynamic variable, and the subset the script itself
|
|
212
|
+
// assigned (vs. merely seeded by viewportParams). ctx is caller-owned in this
|
|
213
|
+
// port (see evaluate()'s own doc comment in evaluator.hpp), so this is a
|
|
214
|
+
// direct readback, not a separate tracking mechanism.
|
|
215
|
+
std::pair<nb::dict, nb::object> dynStateToPy(const oscadeval::EvalContext& ctx) {
|
|
216
|
+
nb::dict dyn;
|
|
217
|
+
for (const auto& [name, v] : ctx.dyn.items()) dyn[nb::str(name.c_str())] = valueToPy(v);
|
|
218
|
+
nb::set explicitNames;
|
|
219
|
+
for (const auto& [name, isExplicit] : ctx.dynExplicit.items())
|
|
220
|
+
if (isExplicit) explicitNames.add(nb::str(name.c_str()));
|
|
221
|
+
return {dyn, explicitNames};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// (list[body-dict], list[echo-str], dict[int, span], list[_CSGNode],
|
|
225
|
+
// ProfileResult|None, dict[str, Any], set[str]). Raises the C++ error
|
|
128
226
|
// message as a Python exception on ParseError/EvalError (nanobind maps
|
|
129
227
|
// std::exception -> RuntimeError, whose str() is the already-formatted
|
|
130
228
|
// "ERROR:..."/caret diagnostic; the facade re-raises as EvalError).
|
|
131
|
-
nb::object evaluate(const std::string& path, nb::dict viewportParams
|
|
229
|
+
nb::object evaluate(const std::string& path, nb::dict viewportParams,
|
|
230
|
+
std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, bool profile) {
|
|
132
231
|
std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
|
|
133
232
|
|
|
134
233
|
std::vector<oscadeval::ColoredBody> bodies;
|
|
135
234
|
std::vector<std::string> echoes;
|
|
136
235
|
std::vector<IdSpan> idSpans;
|
|
236
|
+
std::vector<std::unique_ptr<oscadeval::CSGNode>> csgTree;
|
|
237
|
+
std::optional<oscadeval::ProfileResult> profileResult;
|
|
238
|
+
nb::dict dyn;
|
|
239
|
+
nb::object dynExplicit;
|
|
137
240
|
{
|
|
138
241
|
nb::gil_scoped_release rel;
|
|
139
242
|
auto logFn = [&echoes](const std::string& m) { echoes.push_back(m); };
|
|
140
243
|
std::vector<std::unique_ptr<oscad::ASTNode>> ast = oscad::getASTFromFile(path);
|
|
141
244
|
oscadeval::ResolvedUseScopes used = oscadeval::resolveUseScopes(ast, path, logFn);
|
|
142
|
-
oscadeval::Evaluator ev(logFn);
|
|
245
|
+
oscadeval::Evaluator ev(logFn, nullptr, manifoldCache, oscadeval::DebugHooks{}, profile);
|
|
143
246
|
oscadeval::EvalContext ctx = oscadeval::EvalContext::makeRoot(used.rootScope.get());
|
|
144
247
|
bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp));
|
|
145
248
|
collectIdSpans(ev, idSpans);
|
|
249
|
+
csgTree = std::move(ev.csgTree);
|
|
250
|
+
profileResult = std::move(ev.profileResult);
|
|
251
|
+
{
|
|
252
|
+
nb::gil_scoped_acquire g; // building Python objects needs the GIL back
|
|
253
|
+
std::tie(dyn, dynExplicit) = dynStateToPy(ctx);
|
|
254
|
+
}
|
|
146
255
|
}
|
|
147
256
|
|
|
148
257
|
nb::list echoList;
|
|
149
258
|
for (const std::string& s : echoes) echoList.append(s);
|
|
150
|
-
return nb::make_tuple(bodiesToList(bodies), echoList, idSpansToDict(idSpans))
|
|
259
|
+
return nb::make_tuple(bodiesToList(bodies), echoList, idSpansToDict(idSpans), csgTreeToPy(csgTree),
|
|
260
|
+
profileResultToPy(profileResult), dyn, dynExplicit);
|
|
151
261
|
}
|
|
152
262
|
|
|
153
263
|
// ------------------------------------------------------------------------
|
|
@@ -155,44 +265,6 @@ nb::object evaluate(const std::string& path, nb::dict viewportParams) {
|
|
|
155
265
|
// Python conversion for locals inspection.
|
|
156
266
|
// ------------------------------------------------------------------------
|
|
157
267
|
|
|
158
|
-
// A facade class handle (openscad_cpp_evaluator.<name>), imported lazily at
|
|
159
|
-
// first use and leaked deliberately -- never destroyed, so no nb::object
|
|
160
|
-
// destructor runs after Python finalization (the app exits via os._exit,
|
|
161
|
-
// which skips finalizers; a normal-shutdown consumer would otherwise crash).
|
|
162
|
-
nb::object facadeAttr(const char* name) {
|
|
163
|
-
static nb::object* mod = new nb::object(nb::module_::import_("openscad_cpp_evaluator"));
|
|
164
|
-
return mod->attr(name);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
nb::object valueToPy(const oscadeval::Value& v); // recursive
|
|
168
|
-
|
|
169
|
-
nb::object valueToPy(const oscadeval::Value& v) {
|
|
170
|
-
if (std::holds_alternative<std::monostate>(v)) return nb::none();
|
|
171
|
-
if (const bool* b = std::get_if<bool>(&v)) return nb::cast(*b);
|
|
172
|
-
if (const double* d = std::get_if<double>(&v)) return nb::cast(*d);
|
|
173
|
-
if (const std::string* s = std::get_if<std::string>(&v)) return nb::cast(*s);
|
|
174
|
-
if (const oscadeval::ListPtr* lp = std::get_if<oscadeval::ListPtr>(&v)) {
|
|
175
|
-
nb::list out;
|
|
176
|
-
if (*lp)
|
|
177
|
-
for (const oscadeval::Value& item : (*lp)->items) out.append(valueToPy(item));
|
|
178
|
-
return out;
|
|
179
|
-
}
|
|
180
|
-
if (const oscadeval::ObjectPtr* op = std::get_if<oscadeval::ObjectPtr>(&v)) {
|
|
181
|
-
nb::dict data;
|
|
182
|
-
if (*op)
|
|
183
|
-
for (const auto& [k, val] : (*op)->items) data[nb::str(k.c_str())] = valueToPy(val);
|
|
184
|
-
return facadeAttr("OscObject")(data);
|
|
185
|
-
}
|
|
186
|
-
// OscRange / FunctionLiteral: no direct Python analog -- wrap the
|
|
187
|
-
// OpenSCAD text so the debugger displays it cleanly (unquoted).
|
|
188
|
-
return facadeAttr("_ScadValue")(oscadeval::fmtValue(v));
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
nb::object posToPy(const oscad::Position* p) {
|
|
192
|
-
if (!p) return nb::none();
|
|
193
|
-
return facadeAttr("_Position")(p->line, p->column, p->origin, p->start_offset, p->end_offset);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
268
|
// One debug frame -> {"local_scope", "outer_scope", "dyn_names"}, the shape
|
|
197
269
|
// the debugger pane's _filtered_vars consumes.
|
|
198
270
|
nb::dict frameToDict(const oscadeval::DebugFrame& f) {
|
|
@@ -262,18 +334,28 @@ void callPyErrorBreak(nb::handle errorBreak, int line, const std::string& header
|
|
|
262
334
|
errorBreak(line, header, allFrameLocals, callStackToPy(callStack), nb::arg("origin") = origin);
|
|
263
335
|
}
|
|
264
336
|
|
|
337
|
+
// Trampoline: C++ returnHook -> the Python DebugSession return hook. Only
|
|
338
|
+
// fires for user function/function-literal calls (never modules, never
|
|
339
|
+
// builtins -- see DebugHooks::returnHook's own doc comment).
|
|
340
|
+
void callPyReturnHook(nb::handle returnHook, const std::string& name, const oscadeval::Value& result, int depth) {
|
|
341
|
+
returnHook(name, valueToPy(result), depth);
|
|
342
|
+
}
|
|
343
|
+
|
|
265
344
|
// evaluate() with the debugger wired in. echo is delivered live via echoFn
|
|
266
345
|
// (not batched), so a paused session can still print. Returns (bodies, [],
|
|
267
|
-
// id_to_node). The GIL is released around the C++
|
|
268
|
-
// inside every callback trampoline; the actual pause
|
|
269
|
-
// side (threading.Event) so the GUI thread keeps running.
|
|
346
|
+
// id_to_node, dyn, dyn_explicit). The GIL is released around the C++
|
|
347
|
+
// evaluate and reacquired inside every callback trampoline; the actual pause
|
|
348
|
+
// blocks on the Python side (threading.Event) so the GUI thread keeps running.
|
|
270
349
|
nb::object debugEvaluate(const std::string& path, nb::dict viewportParams, nb::callable debugHook,
|
|
271
|
-
nb::callable errorBreak, nb::callable echoFn
|
|
350
|
+
nb::callable errorBreak, nb::callable echoFn,
|
|
351
|
+
std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, nb::object returnHook) {
|
|
272
352
|
std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
|
|
273
353
|
|
|
274
354
|
std::vector<oscadeval::ColoredBody> bodies;
|
|
275
355
|
std::vector<IdSpan> idSpans;
|
|
276
356
|
std::exception_ptr err;
|
|
357
|
+
nb::dict dyn;
|
|
358
|
+
nb::object dynExplicit;
|
|
277
359
|
{
|
|
278
360
|
nb::gil_scoped_release rel;
|
|
279
361
|
auto echoCpp = [&echoFn](const std::string& m) {
|
|
@@ -292,20 +374,30 @@ nb::object debugEvaluate(const std::string& path, nb::dict viewportParams, nb::c
|
|
|
292
374
|
nb::gil_scoped_acquire g;
|
|
293
375
|
callPyErrorBreak(errorBreak, line, header, origin, cs, gf);
|
|
294
376
|
};
|
|
377
|
+
if (!returnHook.is_none()) {
|
|
378
|
+
hooks.returnHook = [&](const std::string& name, const oscadeval::Value& result, int depth) {
|
|
379
|
+
nb::gil_scoped_acquire g;
|
|
380
|
+
callPyReturnHook(returnHook, name, result, depth);
|
|
381
|
+
};
|
|
382
|
+
}
|
|
295
383
|
try {
|
|
296
384
|
std::vector<std::unique_ptr<oscad::ASTNode>> ast = oscad::getASTFromFile(path);
|
|
297
385
|
oscadeval::ResolvedUseScopes used = oscadeval::resolveUseScopes(ast, path, echoCpp);
|
|
298
|
-
oscadeval::Evaluator ev(echoCpp, nullptr,
|
|
386
|
+
oscadeval::Evaluator ev(echoCpp, nullptr, manifoldCache, hooks, false);
|
|
299
387
|
oscadeval::EvalContext ctx = oscadeval::EvalContext::makeRoot(used.rootScope.get());
|
|
300
388
|
bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp));
|
|
301
389
|
collectIdSpans(ev, idSpans);
|
|
390
|
+
{
|
|
391
|
+
nb::gil_scoped_acquire g;
|
|
392
|
+
std::tie(dyn, dynExplicit) = dynStateToPy(ctx);
|
|
393
|
+
}
|
|
302
394
|
} catch (...) {
|
|
303
395
|
err = std::current_exception();
|
|
304
396
|
}
|
|
305
397
|
}
|
|
306
398
|
if (err) std::rethrow_exception(err); // re-raised with the GIL held -> Python exception
|
|
307
399
|
|
|
308
|
-
return nb::make_tuple(bodiesToList(bodies), nb::list(), idSpansToDict(idSpans));
|
|
400
|
+
return nb::make_tuple(bodiesToList(bodies), nb::list(), idSpansToDict(idSpans), dyn, dynExplicit);
|
|
309
401
|
}
|
|
310
402
|
|
|
311
403
|
// Top-level declaration names + source spans, for the editor's completion and
|
|
@@ -358,11 +450,21 @@ nb::list parseDecls(const std::string& path) {
|
|
|
358
450
|
|
|
359
451
|
NB_MODULE(_openscad_cpp_evaluator, m) {
|
|
360
452
|
m.doc() = "C++ OpenSCAD evaluator (nanobind binding)";
|
|
361
|
-
|
|
362
|
-
|
|
453
|
+
|
|
454
|
+
// Opt-in, shared across evaluate() calls -- see manifold_cache.hpp.
|
|
455
|
+
// Only a constructor and clear() are ever called from Python (get/put
|
|
456
|
+
// are internal to generateTree()'s own C++ implementation).
|
|
457
|
+
nb::class_<oscadeval::ManifoldCache>(m, "ManifoldCache")
|
|
458
|
+
.def(nb::init<>())
|
|
459
|
+
.def("clear", &oscadeval::ManifoldCache::clear);
|
|
460
|
+
|
|
461
|
+
m.def("evaluate", &evaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("manifold_cache") = nullptr,
|
|
462
|
+
nb::arg("profile") = false,
|
|
463
|
+
"Evaluate a .scad file; return (bodies, echoes, id_to_node, csg_tree, profile_result, dyn, dyn_explicit).");
|
|
363
464
|
m.def("parse_decls", &parseDecls, nb::arg("path"),
|
|
364
465
|
"Parse a .scad file; return top-level declaration (namespace, name, start, end, line, column, origin) tuples.");
|
|
365
466
|
m.def("debug_evaluate", &debugEvaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("debug_hook"),
|
|
366
|
-
nb::arg("error_break"), nb::arg("echo_fn"),
|
|
367
|
-
"
|
|
467
|
+
nb::arg("error_break"), nb::arg("echo_fn"), nb::arg("manifold_cache") = nullptr,
|
|
468
|
+
nb::arg("return_hook") = nb::none(),
|
|
469
|
+
"Evaluate with the debugger wired in; returns (bodies, [], id_to_node, dyn, dyn_explicit). Callbacks fire under the GIL.");
|
|
368
470
|
}
|
|
@@ -336,6 +336,15 @@ public:
|
|
|
336
336
|
// reference's Evaluator.profile_result.
|
|
337
337
|
std::optional<ProfileResult> profileResult;
|
|
338
338
|
|
|
339
|
+
// The resolved (and, after evaluate() runs, generated) CSG tree from the
|
|
340
|
+
// most recent evaluate() call -- moved here from evaluateImpl's local
|
|
341
|
+
// `tree` after generateTree() populates each node's own `bodies`, so a
|
|
342
|
+
// caller can inspect tree shape/params after evaluate() returns (CSG-tree
|
|
343
|
+
// dump, live partial-render). Empty for direct resolveTree()/
|
|
344
|
+
// generateTree() callers that bypass evaluate() -- same scoping as
|
|
345
|
+
// profileResult above. Mirrors the reference's Evaluator.csg_tree.
|
|
346
|
+
std::vector<std::unique_ptr<CSGNode>> csgTree;
|
|
347
|
+
|
|
339
348
|
private:
|
|
340
349
|
// Shared body for resolveTree()'s/evaluate()'s two overloads (owning vs.
|
|
341
350
|
// raw-pointer node list) -- a template rather than duplicating each
|