openscad-cpp-evaluator 1.25.0__tar.gz → 1.27.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.25.0 → openscad_cpp_evaluator-1.27.0}/CLAUDE.md +21 -1
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/bindings/module.cpp +16 -6
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/colored_body.hpp +17 -1
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/evaluator.hpp +3 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/python/openscad_cpp_evaluator/__init__.py +11 -3
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/colored_body.cpp +16 -6
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/csg_generate.cpp +24 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_python_bindings.py +75 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/uv.lock +0 -0
|
@@ -1135,6 +1135,12 @@ grep for `ponytail:`.
|
|
|
1135
1135
|
`writeSvg`, which needs the sections that step throws away, and which says so rather than writing
|
|
1136
1136
|
the slab's outline. `tools/cli/cli_lib.cpp` is the only current caller; a future GUI/renderer
|
|
1137
1137
|
caller needs the same call before passing results to its own mesh consumer.
|
|
1138
|
+
**The slab height is a parameter** (`flatHeight`, default `kTopLevel2dHeight` = 1.0, the
|
|
1139
|
+
reference's measured preview height that docs images and `--viewall` framing depend on). Python
|
|
1140
|
+
reaches it as `Evaluator(flat_preview_height=...)`, which thins only the DISPLAYED bodies:
|
|
1141
|
+
`evaluate()` converts the raw list a second time at 1.0 for `geometry`, because a 2D-only script
|
|
1142
|
+
exports its slab and that must not become whatever a viewer found easiest to look at. BelfrySCAD's
|
|
1143
|
+
viewport asks for 0.01 so a 2D shape reads as the flat contour it is.
|
|
1138
1144
|
- `include/openscad_cpp_evaluator/function_builtins.hpp`, `src/builtins/function_builtins.cpp` —
|
|
1139
1145
|
the math/string/list/type-check builtin *function* dispatch (`isBuiltinFunctionName`/
|
|
1140
1146
|
`evalBuiltinFunction`), a completely separate namespace/table from `dispatch.hpp`'s builtin
|
|
@@ -1687,6 +1693,20 @@ the former is worth dragging.
|
|
|
1687
1693
|
A cache hit restamps to the chain reaching the geometry *now*, not the one that
|
|
1688
1694
|
first produced it: a module called twice genuinely is two call chains.
|
|
1689
1695
|
|
|
1696
|
+
**A 2D shape is picked by `ColoredBody::sectionId`.** A `CrossSection` is contours
|
|
1697
|
+
with no run IDs, so a top-level 2D shape had no `idToNode` entry at all: its preview
|
|
1698
|
+
slab got fresh IDs from `Manifold::Extrude` in `toRenderableBodies`, after the table
|
|
1699
|
+
was built, and a click on it mapped to no source (it blocked BelfrySCAD's extrude
|
|
1700
|
+
gizmo, which exists to act on exactly those). Now the generate loop calls
|
|
1701
|
+
`tagSections` after every builtin's `GenerateFn`: any 2D body without an ID gets one
|
|
1702
|
+
reserved from Manifold's counter, attributed to that node. A transform keeps the ID
|
|
1703
|
+
it was given (it edits the body in place), so a 2D shape stays its primitive, as a
|
|
1704
|
+
solid's runs do; an op that builds a *new* section -- a 2D `union()`, `offset()`,
|
|
1705
|
+
`hull()` -- claims it, so the whole union is one pick. `restampCachedIds` restamps it
|
|
1706
|
+
by the solid rule (across renders, to the reused node), `recordRunColors` records its
|
|
1707
|
+
colour, and `toRenderableBodies` rebuilds the slab from a `MeshGL` whose one run
|
|
1708
|
+
carries it. Tested in `tests/test_python_bindings.py` (`_picked_text`).
|
|
1709
|
+
|
|
1690
1710
|
No stored script path is needed to tell the user's file from a library:
|
|
1691
1711
|
`callStack_.front()` is by construction the call made from top level.
|
|
1692
1712
|
|
|
@@ -1695,7 +1715,7 @@ Exposed to Python as `node.call_sites` (innermost-first `_CallFrame`s, each a
|
|
|
1695
1715
|
|
|
1696
1716
|
`Evaluator::measuring_` is set for the whole generate. It suppresses the four
|
|
1697
1717
|
writes that exist solely to describe *drawn* geometry — `idToNode`/`idToColor`/`idToCallChain` in
|
|
1698
|
-
`tagGenerated` and `
|
|
1718
|
+
`tagGenerated`, `tagDisplayOnly` and `tagSections`, the `restampCachedIds` call on a cache hit,
|
|
1699
1719
|
and `cacheProducer_` — because those tables are cleared once per pass, so a leak
|
|
1700
1720
|
is permanent and surfaces later as wrong click-to-source. It also suppresses
|
|
1701
1721
|
`checkDebug`, which would otherwise inject stops at the paused statement's own
|
|
@@ -505,10 +505,15 @@ nb::object coverageResultToPy(const std::optional<oscadeval::CoverageResult>& cr
|
|
|
505
505
|
|
|
506
506
|
nb::object evaluate(const std::string& path, nb::dict viewportParams,
|
|
507
507
|
std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, bool profile,
|
|
508
|
-
bool generate, bool strictCommas, bool coverage, bool keepMinuendColor
|
|
508
|
+
bool generate, bool strictCommas, bool coverage, bool keepMinuendColor,
|
|
509
|
+
double flatPreviewHeight) {
|
|
509
510
|
std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
|
|
510
511
|
|
|
511
512
|
std::vector<oscadeval::ColoredBody> bodies;
|
|
513
|
+
// What export gets. The same list as `bodies` unless the caller asked
|
|
514
|
+
// for a thinner preview slab: a 2D-only script exports its slab, and
|
|
515
|
+
// that must stay the reference's 1 unit whatever the viewer shows.
|
|
516
|
+
std::vector<oscadeval::ColoredBody> exportBodies;
|
|
512
517
|
std::vector<std::string> echoes;
|
|
513
518
|
std::vector<IdSpan> idSpans;
|
|
514
519
|
std::vector<std::unique_ptr<oscadeval::CSGNode>> csgTree;
|
|
@@ -532,7 +537,10 @@ nb::object evaluate(const std::string& path, nb::dict viewportParams,
|
|
|
532
537
|
ev.keepMinuendColor = keepMinuendColor;
|
|
533
538
|
ev.setUsedFileGlobals(used.usedFileGlobals);
|
|
534
539
|
oscadeval::EvalContext ctx = oscadeval::EvalContext::makeRoot(used.rootScope.get());
|
|
535
|
-
|
|
540
|
+
std::vector<oscadeval::ColoredBody> raw = ev.evaluate(used.processedNodes, ctx, vp, generate);
|
|
541
|
+
bodies = oscadeval::toRenderableBodies(raw, flatPreviewHeight);
|
|
542
|
+
exportBodies = flatPreviewHeight == oscadeval::kTopLevel2dHeight
|
|
543
|
+
? bodies : oscadeval::toRenderableBodies(raw);
|
|
536
544
|
collectIdSpans(ev, idSpans);
|
|
537
545
|
// Only moved out when it will actually be converted below --
|
|
538
546
|
// csgTreeToPy() walks the whole tree building Python objects,
|
|
@@ -567,8 +575,8 @@ nb::object evaluate(const std::string& path, nb::dict viewportParams,
|
|
|
567
575
|
nb::list echoList;
|
|
568
576
|
for (const std::string& s : echoes) echoList.append(s);
|
|
569
577
|
auto geom = std::make_shared<Geometry>();
|
|
570
|
-
geom->bodies = std::move(
|
|
571
|
-
return nb::make_tuple(bodiesToList(
|
|
578
|
+
geom->bodies = std::move(exportBodies);
|
|
579
|
+
return nb::make_tuple(bodiesToList(bodies), echoList, idSpansToDict(idSpans), csgTreeToPy(csgTree),
|
|
572
580
|
profileResultToPy(profileResult), dyn, dynExplicit, geom, coverageResultToPy(coverageResult));
|
|
573
581
|
}
|
|
574
582
|
|
|
@@ -780,7 +788,7 @@ void callPyReturnHook(nb::handle returnHook, const std::string& name, const osca
|
|
|
780
788
|
nb::object debugEvaluate(const std::string& path, nb::dict viewportParams, nb::callable debugHook,
|
|
781
789
|
nb::callable errorBreak, nb::callable echoFn,
|
|
782
790
|
std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, nb::object returnHook,
|
|
783
|
-
FastContinueSignal* fastContinueSignal) {
|
|
791
|
+
FastContinueSignal* fastContinueSignal, double flatPreviewHeight) {
|
|
784
792
|
std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
|
|
785
793
|
|
|
786
794
|
std::vector<oscadeval::ColoredBody> bodies;
|
|
@@ -841,7 +849,7 @@ nb::object debugEvaluate(const std::string& path, nb::dict viewportParams, nb::c
|
|
|
841
849
|
if (fastContinueSignal) ev.setFastContinueInterruptFlag(fastContinueSignal->flag());
|
|
842
850
|
ev.setUsedFileGlobals(used.usedFileGlobals);
|
|
843
851
|
oscadeval::EvalContext ctx = oscadeval::EvalContext::makeRoot(used.rootScope.get());
|
|
844
|
-
bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp));
|
|
852
|
+
bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp), flatPreviewHeight);
|
|
845
853
|
collectIdSpans(ev, idSpans);
|
|
846
854
|
{
|
|
847
855
|
nb::gil_scoped_acquire g;
|
|
@@ -985,6 +993,7 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
|
|
|
985
993
|
m.def("evaluate", &evaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("manifold_cache") = nullptr,
|
|
986
994
|
nb::arg("profile") = false, nb::arg("generate") = true, nb::arg("strict_commas") = false,
|
|
987
995
|
nb::arg("coverage") = false, nb::arg("keep_minuend_color") = false,
|
|
996
|
+
nb::arg("flat_preview_height") = oscadeval::kTopLevel2dHeight,
|
|
988
997
|
"Evaluate a .scad file; return (bodies, echoes, id_to_node, csg_tree, profile_result, dyn, dyn_explicit, "
|
|
989
998
|
"geometry, coverage_result).\n"
|
|
990
999
|
"coverage=True records which statements, branch arms and bodies ran: coverage_result is a dict "
|
|
@@ -1024,5 +1033,6 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
|
|
|
1024
1033
|
m.def("debug_evaluate", &debugEvaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("debug_hook"),
|
|
1025
1034
|
nb::arg("error_break"), nb::arg("echo_fn"), nb::arg("manifold_cache") = nullptr,
|
|
1026
1035
|
nb::arg("return_hook") = nb::none(), nb::arg("fast_continue_signal") = nullptr,
|
|
1036
|
+
nb::arg("flat_preview_height") = oscadeval::kTopLevel2dHeight,
|
|
1027
1037
|
"Evaluate with the debugger wired in; returns (bodies, [], id_to_node, dyn, dyn_explicit). Callbacks fire under the GIL.");
|
|
1028
1038
|
}
|
|
@@ -42,6 +42,15 @@ struct ColoredBody {
|
|
|
42
42
|
std::optional<manifold::CrossSection> section;
|
|
43
43
|
bool flatPreview = false;
|
|
44
44
|
|
|
45
|
+
// The originalID a 2D `section` is picked by. A CrossSection is contours
|
|
46
|
+
// and carries no run IDs, so a 2D shape had no entry in idToNode and a
|
|
47
|
+
// click on its preview slab mapped to no source at all. Reserved from
|
|
48
|
+
// Manifold's own counter (so it cannot collide with a solid's ID) by the
|
|
49
|
+
// generate loop, for the node that built the section -- a primitive, or
|
|
50
|
+
// an op like union() that made a new one; a transform keeps the one it
|
|
51
|
+
// was given. toRenderableBodies() gives the slab this ID.
|
|
52
|
+
std::optional<uint32_t> sectionId;
|
|
53
|
+
|
|
45
54
|
// What a 2D `section` has been transformed BY that a CrossSection
|
|
46
55
|
// cannot itself hold: a translation along Z, a rotation out of the XY
|
|
47
56
|
// plane, anything with a Z component. Applied when
|
|
@@ -160,6 +169,13 @@ std::optional<std::array<float, 4>> valueToColor(const Value& v);
|
|
|
160
169
|
// (the CLI, any other mesh-export caller) should apply this to
|
|
161
170
|
// Evaluator::evaluate()'s result before exporting, the same way the
|
|
162
171
|
// reference's own cli.py does right before export_bodies().
|
|
163
|
-
|
|
172
|
+
// The thickness toRenderableBodies() gives a top-level 2D shape's slab by
|
|
173
|
+
// default: OpenSCAD's own preview height, measured (see colored_body.cpp).
|
|
174
|
+
// Docs images and exports use it; an interactive viewer may pass a thinner
|
|
175
|
+
// one so a 2D shape reads as the flat contour it is.
|
|
176
|
+
inline constexpr double kTopLevel2dHeight = 1.0;
|
|
177
|
+
|
|
178
|
+
std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies,
|
|
179
|
+
double flatHeight = kTopLevel2dHeight);
|
|
164
180
|
|
|
165
181
|
} // namespace oscadeval
|
|
@@ -283,6 +283,9 @@ public:
|
|
|
283
283
|
// attributes there).
|
|
284
284
|
// Give cached bodies fresh originalIDs so a second call site reusing
|
|
285
285
|
// them is not confused with the first. See its definition.
|
|
286
|
+
// Give every 2D body in `bodies` that has no sectionId yet one of its
|
|
287
|
+
// own, attributed to `node`. See ColoredBody::sectionId.
|
|
288
|
+
void tagSections(std::vector<ColoredBody>& bodies, const oscad::ASTNode& node, uint32_t callChain);
|
|
286
289
|
void restampCachedIds(std::vector<ColoredBody>& bodies, const oscad::ASTNode& node,
|
|
287
290
|
const oscad::ASTNode* producer, uint32_t callChain);
|
|
288
291
|
|
|
@@ -565,7 +565,7 @@ class Evaluator:
|
|
|
565
565
|
|
|
566
566
|
def __init__(self, echo_fn=None, debug_hook=None, error_break_fn=None, return_hook=None,
|
|
567
567
|
manifold_cache=None, profile=False, fast_continue_signal=None, coverage=False,
|
|
568
|
-
keep_minuend_color=False):
|
|
568
|
+
keep_minuend_color=False, flat_preview_height=1.0):
|
|
569
569
|
self._echo_fn = echo_fn
|
|
570
570
|
self._debug_hook = debug_hook
|
|
571
571
|
self._error_break_fn = error_break_fn
|
|
@@ -579,6 +579,12 @@ class Evaluator:
|
|
|
579
579
|
# subtrahend's (or the cut green). A viewer option; see
|
|
580
580
|
# Evaluator::keepMinuendColor in evaluator.hpp.
|
|
581
581
|
self._keep_minuend_color = keep_minuend_color
|
|
582
|
+
# How thick a top-level 2D shape's preview slab is in the returned
|
|
583
|
+
# bodies. 1.0 is OpenSCAD's preview height, which docs images and
|
|
584
|
+
# --viewall framing depend on; a viewer can pass something thin so
|
|
585
|
+
# a 2D shape reads as a flat contour. Export (`geometry`) always
|
|
586
|
+
# keeps 1.0: a 2D-only script exports its slab.
|
|
587
|
+
self._flat_preview_height = float(flat_preview_height)
|
|
582
588
|
self.csg_tree = []
|
|
583
589
|
self.profile_result = None
|
|
584
590
|
# coverage=True: after evaluate(), {"spans": [...], "files": [...],
|
|
@@ -621,7 +627,8 @@ class Evaluator:
|
|
|
621
627
|
source_path, vp, self._debug_hook,
|
|
622
628
|
self._error_break_fn or (lambda *a, **k: None),
|
|
623
629
|
self._echo_fn or (lambda _m: None),
|
|
624
|
-
self._manifold_cache, self._return_hook, self._fast_continue_signal
|
|
630
|
+
self._manifold_cache, self._return_hook, self._fast_continue_signal,
|
|
631
|
+
self._flat_preview_height)
|
|
625
632
|
self.csg_tree = []
|
|
626
633
|
self.profile_result = None
|
|
627
634
|
# The debugger path has no geometry handle: debug_evaluate
|
|
@@ -632,7 +639,8 @@ class Evaluator:
|
|
|
632
639
|
(body_dicts, echoes, id_spans, csg_tree, profile_result, dyn,
|
|
633
640
|
dyn_explicit, geometry, coverage_result) = _ext.evaluate(
|
|
634
641
|
source_path, vp, self._manifold_cache, self._profile, generate,
|
|
635
|
-
strict_commas, self._coverage, self._keep_minuend_color
|
|
642
|
+
strict_commas, self._coverage, self._keep_minuend_color,
|
|
643
|
+
self._flat_preview_height)
|
|
636
644
|
# The evaluated bodies, still on the C++ side. Stashed like
|
|
637
645
|
# csg_tree/profile_result rather than returned, so
|
|
638
646
|
# evaluate()'s own 2-tuple result is unchanged -- callers
|
|
@@ -20,23 +20,33 @@ std::optional<std::array<float, 4>> valueToColor(const Value& v) {
|
|
|
20
20
|
return c;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
//
|
|
23
|
+
// kTopLevel2dHeight (colored_body.hpp), the default slab height: the
|
|
24
|
+
// reference extrudes a 2D shape to exactly 1 unit for preview -- measured
|
|
25
25
|
// against OpenSCAD at three camera tilts (60/70/80 degrees), which put it at
|
|
26
26
|
// 0.92/1.00/0.99, the 60 being pixel-rounding on the shallowest angle. Ours
|
|
27
27
|
// was 1e-3, which reads as a flat silhouette with no visible edge and, more
|
|
28
28
|
// annoyingly, gives --viewall a different bounding box to fit, so every 2D
|
|
29
29
|
// docs image came out at a different scale from the published one.
|
|
30
|
-
constexpr double kTopLevel2dHeight = 1.0;
|
|
31
|
-
} // namespace
|
|
32
30
|
|
|
33
|
-
std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies) {
|
|
31
|
+
std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies, double flatHeight) {
|
|
34
32
|
std::vector<ColoredBody> out;
|
|
35
33
|
out.reserve(bodies.size());
|
|
36
34
|
for (const ColoredBody& cb : bodies) {
|
|
37
35
|
if (!cb.body && cb.section) {
|
|
38
36
|
ColoredBody flat;
|
|
39
|
-
flat.body = manifold::Manifold::Extrude(cb.section->ToPolygons(),
|
|
37
|
+
flat.body = manifold::Manifold::Extrude(cb.section->ToPolygons(), flatHeight);
|
|
38
|
+
if (cb.sectionId && !flat.body->IsEmpty()) {
|
|
39
|
+
// One run carrying the section's own ID, so a click on the
|
|
40
|
+
// slab finds the node that built the shape (see
|
|
41
|
+
// ColoredBody::sectionId). Manifold keeps a MeshGL's
|
|
42
|
+
// runOriginalID when it is given one.
|
|
43
|
+
manifold::MeshGL mesh = flat.body->GetMeshGL();
|
|
44
|
+
mesh.runOriginalID = {*cb.sectionId};
|
|
45
|
+
mesh.runIndex = {0, static_cast<uint32_t>(mesh.triVerts.size())};
|
|
46
|
+
mesh.runTransform.clear();
|
|
47
|
+
mesh.faceID.clear();
|
|
48
|
+
flat.body = manifold::Manifold(mesh);
|
|
49
|
+
}
|
|
40
50
|
// Put it back where the transforms a CrossSection could not
|
|
41
51
|
// hold would have placed it -- a Z offset, a rotation out of
|
|
42
52
|
// the plane. See ColoredBody::sectionXform.
|
|
@@ -124,6 +124,7 @@ std::vector<ColoredBody> Evaluator::generateTreeImpl(const std::vector<CSGNode*>
|
|
|
124
124
|
generateWarnEntry = node.warnEntry;
|
|
125
125
|
generateCallChain = node.callChain;
|
|
126
126
|
node.bodies = it->second(*this, node.params, node.children, *node.node);
|
|
127
|
+
if (!measuring_) tagSections(node.bodies, *node.node, node.callChain);
|
|
127
128
|
generateWarnEntry = savedWarnEntry;
|
|
128
129
|
generateCallChain = savedCallChain;
|
|
129
130
|
} else {
|
|
@@ -393,6 +394,16 @@ void Evaluator::restampCachedIds(std::vector<ColoredBody>& bodies, const oscad::
|
|
|
393
394
|
// its producer check keeps the first copy's descendants. They occupy
|
|
394
395
|
// the same space, so there is nothing to select apart.
|
|
395
396
|
for (ColoredBody& cb : bodies) {
|
|
397
|
+
// A 2D body's one ID, restamped by the same rule as a solid's runs.
|
|
398
|
+
if (cb.sectionId) {
|
|
399
|
+
const uint32_t fresh = manifold::Manifold::ReserveIDs(1);
|
|
400
|
+
auto old = idToNode.find(*cb.sectionId);
|
|
401
|
+
idToNode[fresh] =
|
|
402
|
+
(old != idToNode.end() && old->second != producer) ? old->second : &node;
|
|
403
|
+
idToCallChain[fresh] = callChain;
|
|
404
|
+
idToColor[fresh] = cb.color;
|
|
405
|
+
cb.sectionId = fresh;
|
|
406
|
+
}
|
|
396
407
|
if (!cb.body || cb.body->IsEmpty()) continue;
|
|
397
408
|
manifold::MeshGL mesh = cb.body->GetMeshGL();
|
|
398
409
|
if (mesh.runOriginalID.empty()) continue;
|
|
@@ -475,6 +486,7 @@ void Evaluator::restampCachedIds(std::vector<ColoredBody>& bodies, const oscad::
|
|
|
475
486
|
|
|
476
487
|
|
|
477
488
|
void Evaluator::recordRunColors(ColoredBody& b, const std::optional<std::array<float, 4>>& rgba) {
|
|
489
|
+
if (b.sectionId) idToColor[*b.sectionId] = rgba;
|
|
478
490
|
if (!b.body || bodyIsEmpty(b)) return;
|
|
479
491
|
// A body that is still one original knows its own ID without building
|
|
480
492
|
// a mesh -- the common case, and the cheap one.
|
|
@@ -486,6 +498,18 @@ void Evaluator::recordRunColors(ColoredBody& b, const std::optional<std::array<f
|
|
|
486
498
|
for (uint32_t id : b.body->GetMeshGL().runOriginalID) idToColor[id] = rgba;
|
|
487
499
|
}
|
|
488
500
|
|
|
501
|
+
void Evaluator::tagSections(std::vector<ColoredBody>& bodies, const oscad::ASTNode& node,
|
|
502
|
+
uint32_t callChain) {
|
|
503
|
+
for (ColoredBody& cb : bodies) {
|
|
504
|
+
if (!cb.section || cb.body || cb.sectionId) continue;
|
|
505
|
+
const uint32_t id = manifold::Manifold::ReserveIDs(1);
|
|
506
|
+
idToNode[id] = &node;
|
|
507
|
+
idToColor[id] = cb.color;
|
|
508
|
+
idToCallChain[id] = callChain;
|
|
509
|
+
cb.sectionId = id;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
489
513
|
ColoredBody Evaluator::tagGenerated(manifold::Manifold body, const oscad::ASTNode& node, const Value& colorValue) {
|
|
490
514
|
manifold::MeshGL mesh = body.GetMeshGL();
|
|
491
515
|
std::optional<std::array<float, 4>> color = valueToColor(colorValue);
|
{openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/tests/test_python_bindings.py
RENAMED
|
@@ -1046,3 +1046,78 @@ def test_svg_class_is_feature_detectable(tmp_path):
|
|
|
1046
1046
|
out = []
|
|
1047
1047
|
Evaluator(echo_fn=out.append).evaluate(str(scad), generate=False)
|
|
1048
1048
|
assert "1" in out[0], out
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
def _picked_text(tmp_path, src, cache=None, name="s.scad"):
|
|
1052
|
+
"""What a click on each body would select: the source text its run IDs
|
|
1053
|
+
map to, per body, in body order."""
|
|
1054
|
+
script = tmp_path / name
|
|
1055
|
+
script.write_text(src)
|
|
1056
|
+
ev = Evaluator(manifold_cache=cache) if cache else Evaluator()
|
|
1057
|
+
bodies, id_to_node = ev.evaluate(str(script), {})
|
|
1058
|
+
out = []
|
|
1059
|
+
for b in bodies:
|
|
1060
|
+
ids = [int(i) for i in b.body.to_mesh().run_original_id]
|
|
1061
|
+
out.append([src[id_to_node[i].position.start_offset:id_to_node[i].position.end_offset]
|
|
1062
|
+
if i in id_to_node else None for i in ids])
|
|
1063
|
+
return out
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def test_a_2d_shape_can_be_picked_back_to_its_source(tmp_path):
|
|
1067
|
+
"""A CrossSection carries no run IDs, so a 2D shape's preview slab used
|
|
1068
|
+
to map to no node at all and could not be selected (BelfrySCAD's
|
|
1069
|
+
extrude gizmo needs exactly that)."""
|
|
1070
|
+
picked = _picked_text(tmp_path, "square(3);\ncircle(4);\n")
|
|
1071
|
+
assert picked == [["square(3);"], ["circle(4);"]]
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
def test_a_transform_keeps_the_2d_shape_it_moved(tmp_path):
|
|
1075
|
+
picked = _picked_text(tmp_path, "translate([10, 0]) circle(4);\n")
|
|
1076
|
+
assert len(picked) == 1 and picked[0][0] is not None
|
|
1077
|
+
assert picked[0][0].startswith("circle(4)") or picked[0][0].startswith("translate")
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
def test_a_2d_union_is_its_own_shape(tmp_path):
|
|
1081
|
+
src = "union() { square(3); circle(4); }\n"
|
|
1082
|
+
assert _picked_text(tmp_path, src) == [[src.strip()]]
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
def test_a_cached_2d_shape_is_picked_as_a_solid_would_be(tmp_path):
|
|
1086
|
+
"""A cache hit restamps IDs; a 2D shape's must follow, or the second
|
|
1087
|
+
render of an unchanged script loses every 2D selection. It follows the
|
|
1088
|
+
same rule a solid's runs do: across renders the old ID is unknown, so it
|
|
1089
|
+
goes to the reused node -- here the whole translate() statement."""
|
|
1090
|
+
def two_renders(src):
|
|
1091
|
+
cache = ManifoldCache()
|
|
1092
|
+
return _picked_text(tmp_path, src, cache), _picked_text(tmp_path, src, cache)
|
|
1093
|
+
|
|
1094
|
+
flat = two_renders("square(3);\ntranslate([10, 0]) circle(4);\n")
|
|
1095
|
+
solid = two_renders("cube(3);\ntranslate([10, 0, 0]) sphere(4);\n")
|
|
1096
|
+
assert all(t is not None for render in flat for body in render for t in body)
|
|
1097
|
+
assert flat[1] == [["square(3);"], ["translate([10, 0]) circle(4);"]]
|
|
1098
|
+
assert solid[1] == [["cube(3);"], ["translate([10, 0, 0]) sphere(4);"]]
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
def test_a_viewer_can_ask_for_a_thin_2d_slab_and_export_keeps_1(tmp_path):
|
|
1102
|
+
"""flat_preview_height thins the DISPLAYED slab only: a 2D-only script
|
|
1103
|
+
exports that slab, and it has to stay the reference's 1 unit."""
|
|
1104
|
+
import openscad_cpp_evaluator as E
|
|
1105
|
+
script = tmp_path / "flat.scad"
|
|
1106
|
+
script.write_text("square(10);\n")
|
|
1107
|
+
|
|
1108
|
+
def z_extent(bodies):
|
|
1109
|
+
verts = bodies[0].body.to_mesh().vert_properties
|
|
1110
|
+
return float(verts[:, 2].max() - verts[:, 2].min())
|
|
1111
|
+
|
|
1112
|
+
default = E.Evaluator()
|
|
1113
|
+
assert abs(z_extent(default.evaluate(str(script), {})[0]) - 1.0) < 1e-9
|
|
1114
|
+
thin = E.Evaluator(flat_preview_height=0.01)
|
|
1115
|
+
bodies, id_to_node = thin.evaluate(str(script), {})
|
|
1116
|
+
assert abs(z_extent(bodies) - 0.01) < 1e-9
|
|
1117
|
+
assert id_to_node, "still pickable"
|
|
1118
|
+
out = tmp_path / "flat.off" # ASCII: header, counts, vertices
|
|
1119
|
+
E.export_model(str(out), thin.geometry)
|
|
1120
|
+
lines = [l for l in out.read_text().splitlines() if l.strip() and not l.startswith("#")]
|
|
1121
|
+
nverts = int(lines[1].split()[0])
|
|
1122
|
+
zs = [float(l.split()[2]) for l in lines[2:2 + nverts]]
|
|
1123
|
+
assert abs(max(zs) - min(zs) - 1.0) < 1e-6, "export is the 1-unit slab"
|
|
File without changes
|
{openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/.github/workflows/wheels.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.25.0 → openscad_cpp_evaluator-1.27.0}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|