openscad-cpp-evaluator 1.42.0__tar.gz → 1.44.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.42.0 → openscad_cpp_evaluator-1.44.0}/CLAUDE.md +60 -23
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/PKG-INFO +3 -2
- openscad_cpp_evaluator-1.44.0/external/openscad_cpp_parser/LICENSE +21 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/bytecode.hpp +9 -16
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -9
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/colored_body.hpp +3 -3
- openscad_cpp_evaluator-1.44.0/include/openscad_cpp_evaluator/dxf_svg_import.hpp +67 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/evaluator.hpp +5 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/export.hpp +5 -8
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/format_closure.hpp +4 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/import_builtin.hpp +3 -1
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/segments.hpp +9 -18
- openscad_cpp_evaluator-1.44.0/include/openscad_cpp_evaluator/surface_load.hpp +20 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/value.hpp +3 -6
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/pyproject.toml +3 -3
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/CMakeLists.txt +1 -1
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/booleans.cpp +2 -2
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/builtins.hpp +20 -13
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/control.cpp +2 -4
- openscad_cpp_evaluator-1.44.0/src/builtins/dxf_dim.cpp +220 -0
- openscad_cpp_evaluator-1.44.0/src/builtins/extrude.cpp +561 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/function_builtins.cpp +295 -395
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/import.cpp +150 -80
- openscad_cpp_evaluator-1.44.0/src/builtins/primitives_2d.cpp +266 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/primitives_3d.cpp +122 -173
- openscad_cpp_evaluator-1.44.0/src/builtins/roof.cpp +1162 -0
- openscad_cpp_evaluator-1.44.0/src/builtins/segments.cpp +253 -0
- openscad_cpp_evaluator-1.44.0/src/builtins/surface.cpp +114 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/text.cpp +7 -1
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/transforms.cpp +206 -190
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/bytecode_compiler.cpp +2 -2
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/bytecode_vm.cpp +4 -20
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/colored_body.cpp +1 -1
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/export.cpp +100 -46
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/expr_eval.cpp +5 -6
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/format_closure.cpp +2 -0
- openscad_cpp_evaluator-1.44.0/src/import/dxf_import.cpp +370 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/import/mesh_import.cpp +56 -18
- openscad_cpp_evaluator-1.44.0/src/import/surface_load.cpp +124 -0
- openscad_cpp_evaluator-1.44.0/src/import/svg_import.cpp +1017 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/stmt_eval.cpp +2 -1
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/user_calls.cpp +11 -6
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/value.cpp +140 -120
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_bytecode_compiler.cpp +19 -19
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_control_flow.cpp +3 -3
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_csg_tree.cpp +2 -2
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_dxf_svg_import.cpp +314 -51
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_export.cpp +18 -5
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_expr_eval.cpp +2 -2
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_extrude_roof.cpp +153 -10
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_helpers.hpp +24 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_import_export.cpp +56 -54
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_openscad_parity.cpp +31 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_python_bindings.py +28 -2
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_transforms.cpp +1 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_use.cpp +1 -1
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_value.cpp +6 -7
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/uv.lock +1 -1
- openscad_cpp_evaluator-1.42.0/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -46
- openscad_cpp_evaluator-1.42.0/include/openscad_cpp_evaluator/surface_load.hpp +0 -23
- openscad_cpp_evaluator-1.42.0/src/builtins/dxf_dim.cpp +0 -244
- openscad_cpp_evaluator-1.42.0/src/builtins/extrude.cpp +0 -549
- openscad_cpp_evaluator-1.42.0/src/builtins/primitives_2d.cpp +0 -242
- openscad_cpp_evaluator-1.42.0/src/builtins/roof.cpp +0 -489
- openscad_cpp_evaluator-1.42.0/src/builtins/segments.cpp +0 -284
- openscad_cpp_evaluator-1.42.0/src/builtins/surface.cpp +0 -118
- openscad_cpp_evaluator-1.42.0/src/import/dxf_import.cpp +0 -115
- openscad_cpp_evaluator-1.42.0/src/import/surface_load.cpp +0 -132
- openscad_cpp_evaluator-1.42.0/src/import/svg_import.cpp +0 -628
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/cmake/patch_manifold.cmake +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_undef_args.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.44.0}/tools/cli/main.cpp +0 -0
|
@@ -63,7 +63,7 @@ plus gating the silent `is_undef` probe on the call actually resolving to the bu
|
|
|
63
63
|
CSG-tree shape like union/difference/intersection, role-split via the shared `splitByRole`),
|
|
64
64
|
`linear_extrude()`/`rotate_extrude()`/`projection(cut=)`, and `roof()`; and (Phase 7) `offset()`,
|
|
65
65
|
`surface()` (`.dat` text + PNG/JPEG/BMP/GIF via `stb_image`), hand-rolled DXF (`LWPOLYLINE`/2D
|
|
66
|
-
`POLYLINE`) and SVG (
|
|
66
|
+
`POLYLINE`) and SVG (a port of upstream's libsvg: shapes, strokes, `<use>`, layers, nested
|
|
67
67
|
`transform=`, all path commands including elliptical arcs) 2D contour import in both module
|
|
68
68
|
(Region geometry) and expression (Region value) contexts, and the `FontProvider` abstraction
|
|
69
69
|
(`font_provider.hpp`) + built-in FreeType/HarfBuzz backend + `text()`/`textmetrics()`/
|
|
@@ -211,8 +211,23 @@ Challenges and Experiences"), `roof.cpp` was rewritten from scratch as a close p
|
|
|
211
211
|
`roof_vd.cc`'s `voronoi_diagram_roof`/`vd_inner_faces`/`discretize_arc` (CGAL/Eigen/Clipper2Lib
|
|
212
212
|
swapped for `manifold::vec2` arithmetic and `manifold::Triangulate`), on top of Boost.Polygon's
|
|
213
213
|
Voronoi builder (fetched as just `boostorg/polygon` + `boostorg/config`, confirmed to need nothing
|
|
214
|
-
else from Boost).
|
|
215
|
-
|
|
214
|
+
else from Boost). **`method="straight"` is its own construction** (`StraightSkeletonRoof` in
|
|
215
|
+
`roof.cpp`), a true straight-skeleton roof written from the literature (Aichholzer et al. 1995;
|
|
216
|
+
Felkel & Obdržálek 1998's event-driven wavefront) and the reference binary's black-box output --
|
|
217
|
+
no CGAL, and no OpenSCAD roof source read. It simulates the shrinking wavefront event by event
|
|
218
|
+
(edge, split and vertex events; a vertex event reconnects every wavefront edge at the meeting point
|
|
219
|
+
by angle), O(n^2 log n): 5000 vertices in ~0.5 s. Its input is welded first (`weldContours`: corners
|
|
220
|
+
within 2^-19 of the extent snapped together or onto edges, then a Clipper2 union), because a 2D
|
|
221
|
+
union often hands back pieces sharing an edge as separate outlines a hairline apart, and spikes
|
|
222
|
+
are cut away (`dropSpikes`). It matches OpenSCAD 2026.02.01 (`--enable=roof`) in volume, height and
|
|
223
|
+
vertex set on every shape compared that the reference does not crash on -- the reference segfaults
|
|
224
|
+
on many unions of rectangles/triangles that touch along edges, so those were checked only for being
|
|
225
|
+
valid 45-degree roofs (roof area = floor area x sqrt 2). Until this landed both methods built the
|
|
226
|
+
Voronoi roof, wrong for any concave outline. **Warnings**: `$fs`/`$fa` clamping (via the shared
|
|
227
|
+
`Discretizer::fromCtx`) and `Unknown roof method '...'` (a non-string shown as str() shows it) are
|
|
228
|
+
printed BEFORE the children run, as the reference does -- `computeRoofParams` therefore runs at
|
|
229
|
+
`Op::PushBuiltinWrap` time like every other wrap kind (it used to be deferred to Pop on the belief
|
|
230
|
+
that the warning followed the children). **Verified independently**, not just "it compiles": a brute-force
|
|
216
231
|
distance-transform grid search over a square-frame-with-a-hole test case found the same ridge height
|
|
217
232
|
(≈1.756) this implementation produces — the Python reference's own SDF fallback gets this case
|
|
218
233
|
measurably wrong (≈1.5, ~15% low) since it was never more than a documented approximation for
|
|
@@ -1115,9 +1130,10 @@ grep for `ponytail:`.
|
|
|
1115
1130
|
`toCrossSection`; no children/generate-time-bounds dependency, so its resolve/generate split is
|
|
1116
1131
|
the simple kind (segment count for `r=` IS resolvable early here, unlike `rotate_extrude`'s,
|
|
1117
1132
|
since `offset`'s own radius argument is already known at resolve time).
|
|
1118
|
-
- `src/builtins/roof.cpp` — `roof()
|
|
1119
|
-
`roof()` note above for the full story of why this replaced an
|
|
1120
|
-
approximation mid-Phase-6)
|
|
1133
|
+
- `src/builtins/roof.cpp` — `roof()`: the default `method="voronoi"` built on Boost.Polygon's
|
|
1134
|
+
segment Voronoi diagram (see the `roof()` note above for the full story of why this replaced an
|
|
1135
|
+
earlier straight-skeleton approximation mid-Phase-6), and `method="straight"`'s straight-skeleton
|
|
1136
|
+
wavefront simulation (`StraightSkeletonRoof`, same note). `voronoiRoof` scales the merged cross-section's polygons into signed
|
|
1121
1137
|
32-bit integer coordinates (`chooseScale`, headroom below 2^31 for Boost.Polygon's own internal
|
|
1122
1138
|
robustness margin), constructs the Voronoi diagram over the resulting segments, walks it
|
|
1123
1139
|
(`vdInnerFaces`, discretizing parabolic point-vs-segment bisector edges via `discretizeArc`) to get
|
|
@@ -1248,9 +1264,13 @@ grep for `ponytail:`.
|
|
|
1248
1264
|
the module *and* expression forms, enclosing transforms still apply to a selected element (it
|
|
1249
1265
|
has to land where it does in the drawing), and **a filter that matches nothing imports nothing
|
|
1250
1266
|
and warns** rather than falling back to the whole file — a cut layer that quietly became every
|
|
1251
|
-
layer is the worst answer available. `layer=`
|
|
1252
|
-
|
|
1253
|
-
|
|
1267
|
+
layer is the worst answer available. `layer=` (and deprecated `layername=`) also selects in
|
|
1268
|
+
SVG, as upstream does: an Inkscape layer (`inkscape:groupmode="layer"` with an
|
|
1269
|
+
`inkscape:label`). Alone it takes that layer's own group; with `id=`/`class=` it restricts them
|
|
1270
|
+
to elements inside the named layer at any depth. The selection rules were read off the binary:
|
|
1271
|
+
the nearest selected or `display:none` ancestor-or-self decides whether a shape is drawn, so an
|
|
1272
|
+
id selects an element even under a hidden layer, while `layer=` alone does not reach into a
|
|
1273
|
+
hidden sublayer. The miss warning names `id`, `layer`, `class` in that order. `id` had been in
|
|
1254
1274
|
`registry.cpp`'s declared parameter list since long before anything read it, so a script
|
|
1255
1275
|
filtering by id was accepted in full and silently handed the whole drawing.
|
|
1256
1276
|
`resolveFilePath()` (also declared here, defined in import.cpp) — resolves a file argument
|
|
@@ -1281,20 +1301,37 @@ grep for `ponytail:`.
|
|
|
1281
1301
|
triangle-count parity.
|
|
1282
1302
|
- `include/openscad_cpp_evaluator/dxf_svg_import.hpp`, `src/import/dxf_import.cpp`,
|
|
1283
1303
|
`src/import/svg_import.cpp` — hand-rolled, dependency-free 2D-contour loaders (no XML/DXF library
|
|
1284
|
-
pulled in, matching the plan's §9 dependency table). `
|
|
1285
|
-
text format directly
|
|
1286
|
-
|
|
1304
|
+
pulled in, matching the plan's §9 dependency table). `loadDxf()` reads DXF's group-code
|
|
1305
|
+
text format directly and matches OpenSCAD 2026.02.01's import, established black-box (its DXF
|
|
1306
|
+
source is GPL; do not read or port it): `LINE`/`CIRCLE`/`ARC`/`ELLIPSE`/`LWPOLYLINE`/`INSERT`
|
|
1307
|
+
become segments (arcs by the circle fragment rules), points snap to a 1/1024 grid, segments chain
|
|
1308
|
+
into paths that are ALL closed (an open chain gets a straight closing edge), filled even-odd;
|
|
1309
|
+
`origin=`/`scale=`/`layer=` and its warnings ("Illegal value", "Not enough input values",
|
|
1310
|
+
"Unsupported DXF Entity") as OpenSCAD has them. The notes atop `dxf_import.cpp` list the rules,
|
|
1311
|
+
the two ellipse bugs deliberately not copied, and the `POLYLINE` extension.
|
|
1287
1312
|
`loadSvgContours()` pairs a minimal recursive-descent XML tree parser (open/close/self-closing
|
|
1288
|
-
tags, quoted attributes, comments/CDATA/prolog skipping, entity
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
`
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1313
|
+
tags, quoted attributes, comments/CDATA/prolog skipping, entity and character-reference
|
|
1314
|
+
decoding, attribute whitespace normalisation; a tag keeps its `prefix:`, as libxml2 reports it,
|
|
1315
|
+
so `<svg:rect>` is not a rect -- in OpenSCAD either) with **a port of upstream's MIT-licensed
|
|
1316
|
+
`src/libsvg`** (its copyright notice is in the file): its `d` tokenizer with every quirk (a `-`
|
|
1317
|
+
is a token, `1.5.5` is two numbers, a number with trailing junk is 0), Beziers in `max($fn, 20)`
|
|
1318
|
+
segments, arcs and circles/ellipses through `Discretizer::circular` (circles at least 40),
|
|
1319
|
+
rounded `rect`s rebuilt as path data printed at 6 digits, `transform` with `skewX`/`skewY` and
|
|
1320
|
+
libsvg's argument-count checks, `<use>` of a shape in an earlier `<defs>` only, unknown
|
|
1321
|
+
elements (`<a>`, `<symbol>`, `<switch>`) see-through with their transform ignored, and
|
|
1322
|
+
**strokes**: an open subpath, `<line>` and `<polyline>` become their stroke's outline via
|
|
1323
|
+
Clipper2's `ClipperOffset` at 2^27 per user unit (measured), with `stroke-width` (below 0.01 is
|
|
1324
|
+
1), `stroke-linecap` and `stroke-linejoin` (`bevel` maps to Clipper's Square, as libsvg has it).
|
|
1325
|
+
Each element then fills even-odd on its own and the elements union (`fill()`), which is what
|
|
1326
|
+
the reference does: separate overlapping rects union, one path's overlapping subpaths cancel.
|
|
1327
|
+
Two departures: an arc with a zero radius or coincident endpoints is a line or nothing, as the
|
|
1328
|
+
SVG spec says, where libsvg divides by zero and draws NaN vertices at the origin; and
|
|
1329
|
+
OpenSCAD's 2D pipeline drops vertices within ~1.1e-8 mm of collinear, which ours (any 2D
|
|
1330
|
+
shape, not just SVG) does not -- spec `paths-cubic02` keeps two such vertices at an S-curve's
|
|
1331
|
+
inflection. **Placement is `pageMap()`, matching the reference's `import_svg.cc` by its
|
|
1332
|
+
output**: the page's `width`/`height` to mm (a unitless length at `dpi=`,
|
|
1333
|
+
72 by default; `px` at 96; a `dpi` below 0.001 warns and is 72), the `viewBox` scaled onto the
|
|
1334
|
+
page under `preserveAspectRatio`
|
|
1298
1335
|
(default `xMidYMid meet`), and Y flipped about the page HEIGHT -- or about the drawing's centre
|
|
1299
1336
|
with `center=true`. Negating Y alone, as this did before, put a unitless 100-unit drawing in 2.8x
|
|
1300
1337
|
too large and below the X axis. Bounds match OpenSCAD 2026.02.01 (`SvgPlacement` tests).
|
|
@@ -1670,7 +1707,7 @@ the side-quad diagonal choice changes a twisted solid without changing its trian
|
|
|
1670
1707
|
default below 3, so these are an extrude warped round Z. The warp inverts the solid for a positive
|
|
1671
1708
|
angle, hence the mirror-in-Y dance.
|
|
1672
1709
|
- Kept departure: `$fa`/`$fs` <= 0 fall back to 12/2 rather than upstream's clamp-to-0.01 with a warning.
|
|
1673
|
-
- Not ported: `linear_extrude(v=)` (accepted, ignored); DXF
|
|
1710
|
+
- Not ported: `linear_extrude(v=)` (accepted, ignored); DXF import arcs don't read the discretizer.
|
|
1674
1711
|
|
|
1675
1712
|
## Cancel and the module recursion limit (#554)
|
|
1676
1713
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openscad_cpp_evaluator
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.44.0
|
|
4
4
|
Summary: C++ OpenSCAD evaluator with Python bindings
|
|
5
5
|
Author: NeuSCAD Contributors
|
|
6
|
-
License-Expression: MIT
|
|
6
|
+
License-Expression: MIT AND OFL-1.1
|
|
7
7
|
License-File: LICENSE
|
|
8
|
+
License-File: resources/fonts/LICENSE
|
|
8
9
|
Classifier: Development Status :: 3 - Alpha
|
|
9
10
|
Classifier: Intended Audience :: Developers
|
|
10
11
|
Classifier: Operating System :: OS Independent
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 BelfrySCAD Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -287,14 +287,13 @@ enum class Op {
|
|
|
287
287
|
// this AFTER would silently drop uncacheable/ManifoldCache taint
|
|
288
288
|
// tracking for a rands() call embedded in the wrapper's own
|
|
289
289
|
// arguments), computes this site's own params for every kind except
|
|
290
|
-
// Modifier (empty, no ctx push)
|
|
291
|
-
// BuiltinWrapSite's own doc comment) via that kind's own native
|
|
290
|
+
// Modifier (empty, no ctx push) via that kind's own native
|
|
292
291
|
// compute function (computeTransformParams/computeColorParams/etc.,
|
|
293
292
|
// builtins.hpp) -- always a possibly-$-scoped child EvalContext,
|
|
294
293
|
// pushed onto f.ctxChain unconditionally for every non-Modifier kind
|
|
295
|
-
//
|
|
296
|
-
// frame, and stashes {params, randsBefore, siteIdx
|
|
297
|
-
//
|
|
294
|
+
// -- pushes a fresh ev.treeStack_
|
|
295
|
+
// frame, and stashes {params, randsBefore, siteIdx} onto
|
|
296
|
+
// VmFrame::builtinWrapStack (a real per-frame LIFO
|
|
298
297
|
// stack, not a single slot: Push/PopBuiltinWrap pairs can nest or
|
|
299
298
|
// sequence within one frame's own instruction stream, e.g.
|
|
300
299
|
// `translate(a) translate(b) recur();`). The compiler always emits a
|
|
@@ -311,12 +310,7 @@ enum class Op {
|
|
|
311
310
|
// VmFrame::builtinWrapStack's own top entry FIRST (before anything
|
|
312
311
|
// that can itself throw, e.g. Evaluator::setTreeDepthOrThrow below --
|
|
313
312
|
// so the exception-teardown path's own pending count is already
|
|
314
|
-
// correct if THIS throws);
|
|
315
|
-
// HERE via computeRoofParams(ev, pending.deferredArgs, ctx) -- the one
|
|
316
|
-
// kind whose params computation has an observable side effect
|
|
317
|
-
// (ev.warn()) that must stay ordered AFTER children, unlike every
|
|
318
|
-
// other kind's params (computed at Push, before children, since
|
|
319
|
-
// nothing else in this group has an order-sensitive side effect); pops
|
|
313
|
+
// correct if THIS throws); pops
|
|
320
314
|
// the ctx Push made (every kind except Modifier); pops ev.treeStack_
|
|
321
315
|
// to retrieve the children this bracket's own body produced, and
|
|
322
316
|
// builds the tagged CSGNode exactly like Evaluator::buildTreeNode's
|
|
@@ -956,10 +950,9 @@ struct CompiledChunk {
|
|
|
956
950
|
// rotate_extrude()/projection()/offset()/roof()) share Transform/
|
|
957
951
|
// Color's exact push-time-computed-params shape, just via a different
|
|
958
952
|
// native compute function each (Op::PushBuiltinWrap's own runtime
|
|
959
|
-
// handler switches on `kind` to pick it)
|
|
960
|
-
//
|
|
961
|
-
//
|
|
962
|
-
// observable warn() ordering).
|
|
953
|
+
// handler switches on `kind` to pick it). Roof's warnings ($fs/$fa
|
|
954
|
+
// clamping, unknown method) therefore come before its children's
|
|
955
|
+
// output, as in OpenSCAD 2026.02.01.
|
|
963
956
|
struct BuiltinWrapSite {
|
|
964
957
|
enum class Kind {
|
|
965
958
|
Transform,
|
|
@@ -977,7 +970,7 @@ struct CompiledChunk {
|
|
|
977
970
|
RotateExtrude,
|
|
978
971
|
Projection,
|
|
979
972
|
Offset,
|
|
980
|
-
Roof,
|
|
973
|
+
Roof,
|
|
981
974
|
};
|
|
982
975
|
Kind kind;
|
|
983
976
|
std::string tagName; // "translate"/"rotate"/.../"color"/"highlight"/"background"/"show_only"/"hull"/...
|
|
@@ -30,15 +30,6 @@ struct PendingBuiltinWrap {
|
|
|
30
30
|
CSGParams params;
|
|
31
31
|
std::uint64_t randsBefore = 0;
|
|
32
32
|
int siteIdx = -1;
|
|
33
|
-
// Only populated for BuiltinWrapSite::Kind::Roof -- the already-
|
|
34
|
-
// resolved call arguments, retained across the whole bracket so
|
|
35
|
-
// Op::PopBuiltinWrap's handler can compute roof()'s own params AFTER
|
|
36
|
-
// children finish (computeRoofParams needs them; re-running
|
|
37
|
-
// resolveCallArgs at Pop time instead would re-evaluate every argument
|
|
38
|
-
// expression a second time -- double rands()/side effects). Every
|
|
39
|
-
// other kind computes its params at Push time and leaves this default-
|
|
40
|
-
// empty.
|
|
41
|
-
CallArgs deferredArgs;
|
|
42
33
|
|
|
43
34
|
// ev.measuring_ as it stood immediately BEFORE this bracket opened.
|
|
44
35
|
// Recorded for EVERY kind, not just Measure, so the exception teardown
|
|
@@ -188,7 +188,7 @@ std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodi
|
|
|
188
188
|
double flatHeight = kTopLevel2dHeight);
|
|
189
189
|
|
|
190
190
|
// A 3D affine transform as it acts on the XY plane: rows x and y, columns
|
|
191
|
-
// x, y and translation -- what OpenSCAD
|
|
191
|
+
// x, y and translation -- what OpenSCAD applies to 2D
|
|
192
192
|
// geometry (z, and everything out of the plane, simply drops away).
|
|
193
193
|
manifold::mat2x3 projectTo2d(const manifold::mat3x4& m);
|
|
194
194
|
|
|
@@ -203,10 +203,10 @@ bool projectSectionXform(ColoredBody& b);
|
|
|
203
203
|
|
|
204
204
|
// Applies `m`, projected onto the plane, to a CrossSection. A singular
|
|
205
205
|
// projection -- scale([0,1]), a quarter turn about X -- empties it, as
|
|
206
|
-
//
|
|
206
|
+
// OpenSCAD does, and returns false.
|
|
207
207
|
bool transformSection(manifold::CrossSection& cs, const manifold::mat3x4& m);
|
|
208
208
|
|
|
209
|
-
//
|
|
209
|
+
// OpenSCAD's warning for that case, word for word.
|
|
210
210
|
inline constexpr const char* kZeroScale2dWarning = "Scaling a 2D object with 0 - removing object";
|
|
211
211
|
|
|
212
212
|
} // namespace oscadeval
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "openscad_cpp_evaluator/segments.hpp"
|
|
4
|
+
|
|
5
|
+
#include <array>
|
|
6
|
+
#include <optional>
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
10
|
+
namespace oscadeval {
|
|
11
|
+
|
|
12
|
+
using Contour2d = std::vector<std::array<double, 2>>;
|
|
13
|
+
|
|
14
|
+
// import()'s DXF arguments. `disc` carries $fn/$fa/$fs/$fe for arcs.
|
|
15
|
+
struct DxfOptions {
|
|
16
|
+
std::optional<std::string> layer;
|
|
17
|
+
double xorigin = 0.0, yorigin = 0.0, scale = 1.0;
|
|
18
|
+
Discretizer disc;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// The outlines, to be filled even-odd, and OpenSCAD's warnings about the
|
|
22
|
+
// file, in the order it prints them.
|
|
23
|
+
struct DxfImport {
|
|
24
|
+
std::vector<Contour2d> contours;
|
|
25
|
+
std::vector<std::string> warnings;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Hand-rolled DXF reader matching OpenSCAD 2026.02.01's import (see the
|
|
29
|
+
// notes atop dxf_import.cpp): LINE, CIRCLE, ARC, ELLIPSE, LWPOLYLINE,
|
|
30
|
+
// POLYLINE and INSERT, chained into closed outlines. Throws
|
|
31
|
+
// std::runtime_error on I/O failure.
|
|
32
|
+
DxfImport loadDxf(const std::string& path, const DxfOptions& opts = {});
|
|
33
|
+
|
|
34
|
+
// SVG reader, as OpenSCAD 2026.02.01 reads it (a port of its MIT-licensed
|
|
35
|
+
// libsvg): <path>, <rect>, <circle>, <ellipse>, <line>, <polygon>,
|
|
36
|
+
// <polyline> and <use>, with transforms, display:none, and strokes -- an
|
|
37
|
+
// open path, <line> or <polyline> is drawn as its stroke's outline. Curves
|
|
38
|
+
// split by `disc`. Y is flipped (SVG's is down, OpenSCAD's is up). Throws
|
|
39
|
+
// std::runtime_error on I/O/parse failure.
|
|
40
|
+
//: Which part of the drawing to import. All unset means the whole file.
|
|
41
|
+
//: `id` matches an element's `id` attribute; `cls` (not an OpenSCAD
|
|
42
|
+
//: parameter) one entry of its space-separated `class` list; either takes
|
|
43
|
+
//: everything under the element, so naming a <g> means "that group".
|
|
44
|
+
//: `layer` names an Inkscape layer (inkscape:groupmode="layer", by its
|
|
45
|
+
//: inkscape:label): alone it takes that layer, with id/cls it restricts
|
|
46
|
+
//: them to elements inside it.
|
|
47
|
+
struct SvgFilter {
|
|
48
|
+
std::optional<std::string> id;
|
|
49
|
+
std::optional<std::string> cls;
|
|
50
|
+
std::optional<std::string> layer;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// `matched`, when given, reports whether the filter found anything. A miss
|
|
54
|
+
// imports nothing rather than falling back to the whole drawing; the caller
|
|
55
|
+
// warns. Always true when no filter was set.
|
|
56
|
+
// Placed as OpenSCAD places them: page units to mm (a unitless length at
|
|
57
|
+
// `dpi`), the viewBox under preserveAspectRatio, Y flipped about the page
|
|
58
|
+
// height -- or about the drawing's centre with `center`. The result is
|
|
59
|
+
// filled: overlapping contours have already been combined.
|
|
60
|
+
std::vector<Contour2d> loadSvgContours(const std::string& path,
|
|
61
|
+
const SvgFilter& filter = {},
|
|
62
|
+
bool* matched = nullptr,
|
|
63
|
+
double dpi = 72.0,
|
|
64
|
+
bool center = false,
|
|
65
|
+
const Discretizer& disc = {});
|
|
66
|
+
|
|
67
|
+
} // namespace oscadeval
|
|
@@ -587,6 +587,11 @@ public:
|
|
|
587
587
|
// warnCapture first when one is active. Every warning path goes through
|
|
588
588
|
// here, including a ManifoldCache hit replaying a cached line.
|
|
589
589
|
void emitWarning(const std::string& formatted);
|
|
590
|
+
// "ERROR: {message}{locSuffix(position)}" that does NOT stop the run:
|
|
591
|
+
// OpenSCAD logs several of its errors this way and carries on.
|
|
592
|
+
void nonFatalError(const std::string& message, const oscad::Position* position) {
|
|
593
|
+
emitWarning("ERROR: " + message + locSuffix(position));
|
|
594
|
+
}
|
|
590
595
|
|
|
591
596
|
// Applies OpenSCAD's mixed-2D/3D rules to a node's children just
|
|
592
597
|
// before its GenerateFn runs -- see csg_generate.cpp.
|
|
@@ -167,7 +167,7 @@ struct ExportSvgOptions {
|
|
|
167
167
|
void writeSvg(const std::string& path, const std::vector<ColoredBody>& bodies,
|
|
168
168
|
const ExportSvgOptions& opts = {});
|
|
169
169
|
|
|
170
|
-
// DXF, the third 2D writer: OpenSCAD's
|
|
170
|
+
// DXF, the third 2D writer: byte-compatible with OpenSCAD's layout (an AC1006
|
|
171
171
|
// header with the model's extents, one CONTINUOUS linetype, layer 0) and
|
|
172
172
|
// every contour of every body a closed LWPOLYLINE on layer 0 -- holes are
|
|
173
173
|
// contours like any other, as in OpenSCAD. A 1-vertex contour is a POINT
|
|
@@ -259,13 +259,10 @@ struct ExportPovOptions {
|
|
|
259
259
|
// POV-Ray scene description. Every object splitBodiesForExport produces is
|
|
260
260
|
// one mesh2 -- a welded vertex list, a texture per colour, and a texture
|
|
261
261
|
// index per triangle, so per-triangle colour needs no unwelding -- with
|
|
262
|
-
// inside_vector, which makes it a SOLID to POV-Ray (refraction, CSG).
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
// bounding box, its camera, and radiosity from rad_def.inc. Colour is rgbf
|
|
267
|
-
// with filter = 1 - alpha, as OpenSCAD writes it. Numbers are the shortest
|
|
268
|
-
// text that round-trips, in the classic locale.
|
|
262
|
+
// inside_vector, which makes it a SOLID to POV-Ray (refraction, CSG). The
|
|
263
|
+
// rest of the scene (material, lights, default camera) is spec section F2.
|
|
264
|
+
// Colour is rgbf with filter = 1 - alpha. Numbers are the shortest text that
|
|
265
|
+
// round-trips, in the classic locale.
|
|
269
266
|
void writePov(const std::string& path, const std::vector<ExportObject>& objects,
|
|
270
267
|
const ExportPovOptions& opts = {});
|
|
271
268
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#include <string>
|
|
4
4
|
|
|
5
5
|
namespace oscad {
|
|
6
|
+
class ASTNode;
|
|
6
7
|
class FunctionLiteral;
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -16,5 +17,8 @@ namespace oscadeval {
|
|
|
16
17
|
// precedence-minimal and which 94 places inside the parser depend on. See
|
|
17
18
|
// format_closure.cpp for where each rule came from.
|
|
18
19
|
std::string formatFunctionLiteral(const oscad::FunctionLiteral& fn);
|
|
20
|
+
// Any expression, spelled the same way: what assert() quotes as its
|
|
21
|
+
// condition ("Assertion '(a > 1)' failed").
|
|
22
|
+
std::string formatExpression(const oscad::ASTNode& expr);
|
|
19
23
|
|
|
20
24
|
} // namespace oscadeval
|
|
@@ -9,12 +9,14 @@ class ASTNode;
|
|
|
9
9
|
namespace oscadeval {
|
|
10
10
|
|
|
11
11
|
class Evaluator;
|
|
12
|
+
struct EvalContext;
|
|
12
13
|
|
|
13
14
|
// import() used as an expression (not a geometry statement): returns a VNF
|
|
14
15
|
// ([[verts],[faces]]) for a mesh file (.stl/.obj/.off/.3mf), or the JSON
|
|
15
16
|
// file's content converted to native values (.json). DXF/SVG-as-Region
|
|
16
17
|
// import lands alongside their module-context counterparts in a later
|
|
17
18
|
// phase. Mirrors Evaluator._import_as_value (minus the dxf/svg branch).
|
|
18
|
-
|
|
19
|
+
// `ctx` supplies $fn/$fa/$fs/$fe for an SVG's curves.
|
|
20
|
+
Value importAsValue(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node, const EvalContext& ctx);
|
|
19
21
|
|
|
20
22
|
} // namespace oscadeval
|
|
@@ -11,34 +11,25 @@
|
|
|
11
11
|
|
|
12
12
|
namespace oscadeval {
|
|
13
13
|
|
|
14
|
-
// How curves become polygons:
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
// $fn > $fe > $fa/$fs. $fe is the most a curve's polygon may stray from the
|
|
19
|
-
// true circle, measured along a radius to an edge's midpoint; when set (>=
|
|
20
|
-
// 2^-20) it replaces $fa/$fs entirely. Upstream reads $fe only behind
|
|
21
|
-
// --enable=discretization-by-error; this evaluator always honours it, and
|
|
22
|
-
// advertises that as supported_feature("discretization-by-error").
|
|
23
|
-
//
|
|
24
|
-
// Departures from upstream, kept from before this port: $fa/$fs <= 0 fall
|
|
25
|
-
// back to their defaults (12/2) rather than clamping to 0.01 with a warning.
|
|
14
|
+
// How curves become polygons: segment and slice counts from $fn/$fe/$fa/$fs
|
|
15
|
+
// (spec sections B7 and C6). $fe is always honoured here (OpenSCAD reads it
|
|
16
|
+
// only behind --enable=discretization-by-error), advertised as
|
|
17
|
+
// supported_feature("discretization-by-error").
|
|
26
18
|
struct Discretizer {
|
|
27
19
|
double fn = 0.0;
|
|
28
20
|
double fe = 0.0;
|
|
29
21
|
double fa = 12.0;
|
|
30
22
|
double fs = 2.0;
|
|
31
23
|
|
|
32
|
-
// `warn`, when given, receives
|
|
24
|
+
// `warn`, when given, receives the clamping warnings (spec section B7).
|
|
33
25
|
static Discretizer fromCtx(const EvalContext& ctx, const std::function<void(const std::string&)>& warn = {});
|
|
34
26
|
// Stored in, and read back from, a node's params -- they are part of its
|
|
35
27
|
// cache key, and generate has only the params to go on.
|
|
36
28
|
static Discretizer fromParams(const CSGParams& params);
|
|
37
29
|
void store(CSGParams& params) const;
|
|
38
30
|
|
|
39
|
-
// Segments for `angle` degrees of arc at radius r. nullopt where
|
|
40
|
-
//
|
|
41
|
-
// caller supplies its own fallback, as upstream's value_or() does.
|
|
31
|
+
// Segments for `angle` degrees of arc at radius r. nullopt where there is
|
|
32
|
+
// no count (spec section B7); every caller supplies its own fallback.
|
|
42
33
|
std::optional<int> circular(double r, double angleDegrees = 360.0) const;
|
|
43
34
|
|
|
44
35
|
// linear_extrude slice counts: twist without scale, twist with uniform
|
|
@@ -54,8 +45,8 @@ struct Discretizer {
|
|
|
54
45
|
double scaleX, double scaleY, unsigned slices, unsigned segments) const;
|
|
55
46
|
};
|
|
56
47
|
|
|
57
|
-
// Full-circle segment count from ctx's $fn/$fe/$fa/$fs at radius r
|
|
58
|
-
//
|
|
48
|
+
// Full-circle segment count from ctx's $fn/$fe/$fa/$fs at radius r, or 3
|
|
49
|
+
// when there is none.
|
|
59
50
|
int fnSegmentsFromCtx(const EvalContext& ctx, double r = 0.0,
|
|
60
51
|
const std::function<void(const std::string&)>& warn = {});
|
|
61
52
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
#include <vector>
|
|
5
|
+
|
|
6
|
+
namespace oscadeval {
|
|
7
|
+
|
|
8
|
+
// Height data for surface() (spec section D3). Never throws: a file that
|
|
9
|
+
// cannot be read gives no heights and a warning, and the script carries on.
|
|
10
|
+
// `heights[row * cols + col]`; `minVal` is what the base sits 1 below.
|
|
11
|
+
struct SurfaceData {
|
|
12
|
+
std::vector<double> heights;
|
|
13
|
+
int rows = 0;
|
|
14
|
+
int cols = 0;
|
|
15
|
+
double minVal = 0;
|
|
16
|
+
std::vector<std::string> warnings;
|
|
17
|
+
};
|
|
18
|
+
SurfaceData loadSurface(const std::string& path, bool invert);
|
|
19
|
+
|
|
20
|
+
} // namespace oscadeval
|
|
@@ -268,12 +268,9 @@ Value vecSub(const Value& a, const Value& b);
|
|
|
268
268
|
// behavior in the reference implementation -- revisit only if a real
|
|
269
269
|
// script's `*` on a bool-containing vector is shown to need it.
|
|
270
270
|
//
|
|
271
|
-
// `error`, when non-null, receives the
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
// requires matching lengths (2 != 3)", "Matrix must be rectangular. Problem
|
|
275
|
-
// at row 1", and so on. applyBinaryOp warns with it; a caller that only
|
|
276
|
-
// wants the value can leave it null. It is only written on an undef result.
|
|
271
|
+
// `error`, when non-null, receives the diagnostic for whichever undefined
|
|
272
|
+
// case was hit (spec section A6); applyBinaryOp warns with it. It is only
|
|
273
|
+
// written on an undef result.
|
|
277
274
|
Value matmul(const Value& a, const Value& b, std::string* error = nullptr);
|
|
278
275
|
|
|
279
276
|
// OpenSCAD's echo()/str() number formatting: at most 6 significant digits,
|
|
@@ -4,12 +4,12 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openscad_cpp_evaluator"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.44.0"
|
|
8
8
|
description = "C++ OpenSCAD evaluator with Python bindings"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
11
|
-
license = "MIT"
|
|
12
|
-
license-files = ["LICENSE"]
|
|
11
|
+
license = "MIT AND OFL-1.1"
|
|
12
|
+
license-files = ["LICENSE", "resources/fonts/LICENSE"]
|
|
13
13
|
authors = [{ name = "NeuSCAD Contributors" }]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Development Status :: 3 - Alpha",
|
|
@@ -68,7 +68,7 @@ target_include_directories(openscad_cpp_evaluator PRIVATE ${stb_SOURCE_DIR} ${CM
|
|
|
68
68
|
add_dependencies(openscad_cpp_evaluator generate_bundled_font)
|
|
69
69
|
|
|
70
70
|
target_link_libraries(openscad_cpp_evaluator PUBLIC openscad_cpp_parser manifold Boost::polygon)
|
|
71
|
-
target_link_libraries(openscad_cpp_evaluator PRIVATE linenoise freetype harfbuzz)
|
|
71
|
+
target_link_libraries(openscad_cpp_evaluator PRIVATE linenoise freetype harfbuzz Clipper2)
|
|
72
72
|
target_compile_options(openscad_cpp_evaluator PRIVATE
|
|
73
73
|
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall;-Wextra>
|
|
74
74
|
)
|
|
@@ -392,8 +392,8 @@ std::vector<ColoredBody> generateCsg(Evaluator& ev, const CSGParams& params, con
|
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
RoleSplit split = splitByRole(stmtBodies);
|
|
395
|
-
// A `%` statement is scenery, not an operand:
|
|
396
|
-
// of the CSG entirely
|
|
395
|
+
// A `%` statement is scenery, not an operand: OpenSCAD leaves it out
|
|
396
|
+
// of the CSG entirely, so the
|
|
397
397
|
// NEXT statement is the minuend of a difference(), and an
|
|
398
398
|
// intersection() is not cancelled by it. It was taken as an empty
|
|
399
399
|
// operand, which emptied both. Only the `%` statement itself: a
|
|
@@ -246,17 +246,11 @@ CSGParams resolveOffset(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
246
246
|
std::vector<ColoredBody> generateOffset(Evaluator& ev, const CSGParams& params,
|
|
247
247
|
const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
|
|
248
248
|
|
|
249
|
-
// roof() -- roof.cpp.
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
// this is the params-computation half taken from AFTER evalChildren (it
|
|
255
|
-
// calls ev.warn(), an observable side effect that must stay ordered after
|
|
256
|
-
// any child's own echo/warn output) -- takes already-resolved CallArgs,
|
|
257
|
-
// not a raw node+ctx, since Op::PushBuiltinWrap's own runtime handler
|
|
258
|
-
// calls this at POP time. See its own doc comment (roof.cpp).
|
|
259
|
-
CSGParams computeRoofParams(Evaluator& ev, const CallArgs& args, EvalContext& effCtx);
|
|
249
|
+
// roof() -- roof.cpp. method="voronoi" (the default) is the Voronoi-diagram
|
|
250
|
+
// roof, method="straight" the straight-skeleton one.
|
|
251
|
+
// computeRoofParams: the params half, from already-resolved arguments;
|
|
252
|
+
// it warns ($fs/$fa clamping, unknown method), before the children run.
|
|
253
|
+
CSGParams computeRoofParams(Evaluator& ev, const CallArgs& args, EvalContext& effCtx, const oscad::Position* where);
|
|
260
254
|
CSGParams resolveRoof(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
261
255
|
std::vector<ColoredBody> generateRoof(Evaluator& ev, const CSGParams& params,
|
|
262
256
|
const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
|
|
@@ -271,15 +265,28 @@ std::vector<ColoredBody> generateSurface(Evaluator& ev, const CSGParams& params,
|
|
|
271
265
|
// operand (and so empties an intersection) -- see resolveCsg.
|
|
272
266
|
bool emptyStatementIsAnOperand(const oscad::ASTNode& stmt);
|
|
273
267
|
|
|
274
|
-
// OpenSCAD's sin_degrees/cos_degrees: exact at
|
|
268
|
+
// OpenSCAD's sin_degrees/cos_degrees/tan_degrees/atan2_degrees: exact at
|
|
269
|
+
// multiples of 30 and 45 degrees.
|
|
275
270
|
double sinDeg(double x);
|
|
276
271
|
double cosDeg(double x);
|
|
272
|
+
double tanDeg(double x);
|
|
273
|
+
double atan2Deg(double y, double x);
|
|
277
274
|
|
|
278
|
-
//
|
|
275
|
+
// A radius/diameter argument pair: a numeric `d` beats `r`, numbers only.
|
|
279
276
|
std::optional<double> lookupRadius(Evaluator& ev, const CallArgs& args, std::optional<int> rPos,
|
|
280
277
|
std::optional<int> dPos, const std::string& rName, const std::string& dName,
|
|
281
278
|
const oscad::Position* where);
|
|
282
279
|
|
|
280
|
+
// "ERROR: <text>" at `where`, for input a primitive repairs and carries on with.
|
|
281
|
+
void emitInputError(Evaluator& ev, const std::string& text, const oscad::Position* where);
|
|
282
|
+
|
|
283
|
+
// Reads polygon() paths or polyhedron() faces (`listName`): each entry a
|
|
284
|
+
// list of point indices. Entries that are not lists and indices that are not
|
|
285
|
+
// numbers are reported as ERRORs and skipped; out-of-range indices are
|
|
286
|
+
// WARNINGs and skipped. Every surviving entry is returned, however short.
|
|
287
|
+
std::vector<std::vector<size_t>> readIndexLists(Evaluator& ev, const ValueList& lists, const std::string& listName,
|
|
288
|
+
size_t pointCount, const oscad::Position* where);
|
|
289
|
+
|
|
283
290
|
CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
284
291
|
|
|
285
292
|
// The font size text()/textmetrics()/fontmetrics() draw at: `size`
|
|
@@ -124,10 +124,8 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
124
124
|
// evalFor) -- mirrors _resolve_intersection_for's single
|
|
125
125
|
// `_check_debug(body_node[0], loop_ctx, expr_level=True)`.
|
|
126
126
|
if (!bodyNodes.empty()) ev.checkDebug(*bodyNodes.front(), parentCtx, /*forced=*/false, /*exprLevel=*/true);
|
|
127
|
-
// One operand per child STATEMENT of every iteration:
|
|
128
|
-
//
|
|
129
|
-
// node (control.cc), so they are intersected flat, not
|
|
130
|
-
// unioned per iteration first.
|
|
127
|
+
// One operand per child STATEMENT of every iteration: OpenSCAD
|
|
128
|
+
// intersects them flat, not unioned per iteration first.
|
|
131
129
|
std::vector<const oscad::ASTNode*> assigns, stmts;
|
|
132
130
|
for (const oscad::ASTNode* stmt : bodyNodes) {
|
|
133
131
|
if (stmt->kind() == oscad::NodeKind::Assignment) assigns.push_back(stmt);
|