openscad-cpp-evaluator 0.32.2__tar.gz → 0.34.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/CLAUDE.md +41 -2
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/evaluator.hpp +6 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/value.hpp +14 -1
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/CMakeLists.txt +1 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/builtins.hpp +9 -0
- openscad_cpp_evaluator-0.34.0/src/builtins/dxf_dim.cpp +221 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/function_builtins.cpp +366 -114
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/registry.cpp +3 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/topology.cpp +70 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/csg_generate.cpp +107 -1
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/eval_context.cpp +6 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/expr_eval.cpp +49 -34
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/value.cpp +169 -65
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_booleans.cpp +180 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_bytecode_compiler.cpp +5 -4
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_control_flow.cpp +2 -2
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_dxf_svg_import.cpp +131 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_expr_eval.cpp +107 -6
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_function_builtins.cpp +151 -5
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_scoping.cpp +12 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_value.cpp +3 -3
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/uv.lock +1 -1
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/README.md +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.32.2 → openscad_cpp_evaluator-0.34.0}/tools/cli/main.cpp +0 -0
|
@@ -512,6 +512,9 @@ grep for `ponytail:`.
|
|
|
512
512
|
`Evaluator::evaluate()` also takes an optional `viewportParams` map (added after a test-suite
|
|
513
513
|
parity review found it missing entirely): seeds arbitrary `$`-prefixed entries into `ctx.dyn`
|
|
514
514
|
(e.g. `$vpt`/`$vpr`/`$vpd`/`$vpf` from a GUI host's current camera, or `$t` for animation time)
|
|
515
|
+
— note `EvalContext::makeRoot` also seeds `$preview` to **`false`**, always: there is no preview
|
|
516
|
+
mode here, and leaving it undef made the common `$preview ? cheap : real` idiom take the cheap
|
|
517
|
+
branch by accident while warning about an unknown variable
|
|
515
518
|
before evaluation starts, via a direct `ctx.dyn` write that deliberately never touches
|
|
516
519
|
`ctx.dynExplicit` — lets a caller tell "the script itself assigned this `$`-var"
|
|
517
520
|
(`dynExplicit`) apart from "merely present because the caller seeded it" after `evaluate()`
|
|
@@ -558,13 +561,49 @@ grep for `ponytail:`.
|
|
|
558
561
|
color instead of preserving each part's own, matching real OpenSCAD's actual behavior once fixed
|
|
559
562
|
(cross-checked triangle-color-count-and-values against the Python reference directly, not just
|
|
560
563
|
“does it run”).
|
|
561
|
-
- `src/builtins/
|
|
564
|
+
- `src/builtins/dxf_dim.cpp` — `dxf_dim()`/`dxf_cross()`, which read a measurement out of a DXF file
|
|
565
|
+
rather than out of the model. Ported from the reference's `io/dxfdim.cc` plus the DIMENSION/LINE
|
|
566
|
+
half of `io/DxfData.cc`: `dxf_dim()` returns the first matching DIMENSION's value by its type
|
|
567
|
+
(`70 & 7` — 0 rotated, 1 aligned, 2 angular, 3/4 diameter/radius, 6 ordinate; type 5 is
|
|
568
|
+
unsupported there too), `dxf_cross()` intersects the first two LINE entities. Note the reference's
|
|
569
|
+
own coordinate quirk, reproduced here: groups 11/12/16 (and 21/22/26) are scaled but NOT
|
|
570
|
+
origin-shifted, being extents rather than positions.
|
|
571
|
+
|
|
572
|
+
Deliberately its own group-code walk rather than sharing `src/import/dxf_import.cpp`'s: that one
|
|
573
|
+
produces closed contours, and these need the DIMENSION entities' seven coordinate slots and the
|
|
574
|
+
raw LINE endpoints, neither of which a contour list keeps. One divergence: `dxf_cross()` takes the
|
|
575
|
+
first two LINEs, where the reference walks every 2-point path — for a real cross (two strokes
|
|
576
|
+
meeting in the middle, not at their endpoints) that is the same set.
|
|
577
|
+
|
|
578
|
+
- `src/csg_generate.cpp` — `Evaluator::applyDimensionRules`, run centrally just before every node's
|
|
579
|
+
`GenerateFn` (and once more over the top-level list, which is an implicit union). Mirrors the
|
|
580
|
+
reference's `isValidDim` + `collectChildren2D`/`collectChildren3D`: a node's dimension is fixed by
|
|
581
|
+
its first non-background, non-empty child, and every child of the other dimension is dropped with
|
|
582
|
+
`Mixing 2D and 3D objects is not supported` followed by `Ignoring {N}D child object for {M}D
|
|
583
|
+
operation`. `linear_extrude`/`rotate_extrude`/`offset` are always-2D and `projection` always-3D, so
|
|
584
|
+
they skip the "mixing" line and emit only the second; `roof()` emits neither, matching the
|
|
585
|
+
reference. Background (`%`) children are exempt.
|
|
586
|
+
|
|
587
|
+
Doing this centrally is also what keeps `generateCsg` safe: it builds ONE result and switches on
|
|
588
|
+
whether it holds a `body` or a `section`, so a group that changed dimension part-way dereferenced
|
|
589
|
+
the empty optional -- `union() { cube(1); square(4); }` took the process down with "mutex lock
|
|
590
|
+
failed: Invalid argument". Filtering before dispatch means no `GenerateFn` ever sees a mixed group.
|
|
591
|
+
All 25 module/shape combinations were diffed against OpenSCAD 2026.02.01 warning for warning, with
|
|
592
|
+
the surviving geometry compared by STL volume.
|
|
593
|
+
|
|
594
|
+
- `src/builtins/topology.cpp` — `hull()`/`minkowski()`/`fill()`. All three splice their children transparently in
|
|
562
595
|
the CSG tree exactly like union/difference/intersection (resolve just evaluates them for the
|
|
563
596
|
side effect); `hull()` picks an all-3D (`Manifold::Hull`) or all-2D (`CrossSection::Hull`) hull of
|
|
564
597
|
the *foreground* (role-split) children, falling back to sections only when no child has a body;
|
|
565
598
|
`minkowski()` only ever operates on 3D bodies (a 2D sibling among the foreground children is
|
|
566
599
|
silently ignored, matching the reference exactly — no 2D `minkowski_sum` fallback the way hull
|
|
567
|
-
has one).
|
|
600
|
+
has one). All pass background/highlight/show_only bodies through untouched. `fill()` is 2D-only
|
|
601
|
+
(a 3D foreground child draws the reference's own `fill() not yet implemented for 3D` warning and
|
|
602
|
+
contributes nothing): it unions the foreground sections, keeps only the outlines with positive
|
|
603
|
+
signed area — outer boundaries, since Manifold winds a hole clockwise — and re-unions those,
|
|
604
|
+
which matters because two outers can overlap once the holes between them are gone. Ported from
|
|
605
|
+
the reference's `applyFill2D`, and checked shape-for-shape against OpenSCAD 2026.02.01 by
|
|
606
|
+
extruding and comparing STL volumes.
|
|
568
607
|
- `src/builtins/extrude.cpp` — `linear_extrude()`/`rotate_extrude()`/`projection(cut=)`. All three
|
|
569
608
|
union every 2D child into one `CrossSection` via `toCrossSection` first. `rotate_extrude`'s
|
|
570
609
|
segment count can't be resolved until generate time (it depends on the merged children's bounds,
|
|
@@ -330,6 +330,12 @@ public:
|
|
|
330
330
|
// free function, same reasoning as tagGenerated()/builtinChildren().
|
|
331
331
|
void warn(const std::string& message, const oscad::Position* position);
|
|
332
332
|
|
|
333
|
+
// Applies OpenSCAD's mixed-2D/3D rules to a node's children just
|
|
334
|
+
// before its GenerateFn runs -- see csg_generate.cpp.
|
|
335
|
+
void applyDimensionRules(CSGNode& node);
|
|
336
|
+
// ruleValue is a DimRule; the enum is file-local to csg_generate.cpp.
|
|
337
|
+
void applyDimensionRulesTo(const std::vector<CSGNode*>& children, int ruleValue);
|
|
338
|
+
|
|
333
339
|
// Apply `!`: replace the whole tree with the first show_only
|
|
334
340
|
// subtree, discarding its ancestors and every sibling. See its
|
|
335
341
|
// definition for why this cannot be done by tagging bodies.
|
|
@@ -147,6 +147,12 @@ bool oscComparable(const Value& a, const Value& b);
|
|
|
147
147
|
Value scale(double scalarValue, const Value& value);
|
|
148
148
|
Value divScale(const Value& value, double divisor);
|
|
149
149
|
|
|
150
|
+
// `number / vector`, the mirror of divScale's `vector / number` -- the
|
|
151
|
+
// reference divides the scalar by each element in turn (Value.cc's
|
|
152
|
+
// `operator/` NUMBER/VECTOR branch, `*this / vecval`), recursing into
|
|
153
|
+
// nested lists the same way. `5 / [1, 2]` is `[5, 2.5]`, not undef.
|
|
154
|
+
Value divInto(double numerator, const Value& value);
|
|
155
|
+
|
|
150
156
|
// Elementwise `+`/`-` between two lists (zip semantics: truncates to the
|
|
151
157
|
// shorter length when lengths differ), or the scalar/mismatched-type
|
|
152
158
|
// fallback (numeric + numeric, everything else -> undef). `vecAdd` rejects
|
|
@@ -167,7 +173,14 @@ Value vecSub(const Value& a, const Value& b);
|
|
|
167
173
|
// a Python bool silently). This divergence is undocumented/untested
|
|
168
174
|
// behavior in the reference implementation -- revisit only if a real
|
|
169
175
|
// script's `*` on a bool-containing vector is shown to need it.
|
|
170
|
-
|
|
176
|
+
//
|
|
177
|
+
// `error`, when non-null, receives the reference's own diagnostic text for
|
|
178
|
+
// whichever undefined case was hit (multiply_visitor / multvecvec /
|
|
179
|
+
// multmatvec / multvecmat in the reference's Value.cc) -- "vector*vector
|
|
180
|
+
// requires matching lengths (2 != 3)", "Matrix must be rectangular. Problem
|
|
181
|
+
// at row 1", and so on. applyBinaryOp warns with it; a caller that only
|
|
182
|
+
// wants the value can leave it null. It is only written on an undef result.
|
|
183
|
+
Value matmul(const Value& a, const Value& b, std::string* error = nullptr);
|
|
171
184
|
|
|
172
185
|
// OpenSCAD's echo()/str() number formatting: at most 6 significant digits,
|
|
173
186
|
// fixed-point for exponents in [-5, 5], scientific notation with no leading
|
|
@@ -160,6 +160,15 @@ CSGParams resolveHull(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
160
160
|
std::vector<ColoredBody> generateHull(Evaluator& ev, const CSGParams& params,
|
|
161
161
|
const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
|
|
162
162
|
|
|
163
|
+
// dxf_dim()/dxf_cross() -- read a dimension or a cross's centre out of a
|
|
164
|
+
// DXF file. Functions, not modules; dispatched from evalBuiltinFunction.
|
|
165
|
+
Value builtinDxfDim(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node);
|
|
166
|
+
Value builtinDxfCross(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node);
|
|
167
|
+
|
|
168
|
+
CSGParams resolveFill(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
169
|
+
std::vector<ColoredBody> generateFill(Evaluator& ev, const CSGParams& params,
|
|
170
|
+
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
171
|
+
const oscad::ASTNode& node);
|
|
163
172
|
CSGParams resolveMinkowski(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
164
173
|
std::vector<ColoredBody> generateMinkowski(Evaluator& ev, const CSGParams& params,
|
|
165
174
|
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#include "builtins.hpp"
|
|
2
|
+
|
|
3
|
+
#include "openscad_cpp_evaluator/call_args.hpp"
|
|
4
|
+
#include "openscad_cpp_evaluator/evaluator.hpp"
|
|
5
|
+
|
|
6
|
+
#include <cmath>
|
|
7
|
+
#include <filesystem>
|
|
8
|
+
#include <fstream>
|
|
9
|
+
#include <sstream>
|
|
10
|
+
|
|
11
|
+
namespace oscadeval {
|
|
12
|
+
|
|
13
|
+
// dxf_dim() / dxf_cross() -- read a measurement straight out of a DXF file
|
|
14
|
+
// rather than out of the model. Ported from the reference's io/dxfdim.cc
|
|
15
|
+
// plus the DIMENSION/LINE half of io/DxfData.cc.
|
|
16
|
+
//
|
|
17
|
+
// These share the group-code walk with src/import/dxf_import.cpp but not its
|
|
18
|
+
// output: that one only cares about closed contours, while these two need
|
|
19
|
+
// the DIMENSION entities' seven coordinate slots and the raw LINE endpoints,
|
|
20
|
+
// neither of which a contour list keeps.
|
|
21
|
+
|
|
22
|
+
namespace {
|
|
23
|
+
|
|
24
|
+
struct Entity {
|
|
25
|
+
std::string type; // "DIMENSION", "LINE", ...
|
|
26
|
+
std::string layer;
|
|
27
|
+
std::string name; // group 1: DIMENSION's text override
|
|
28
|
+
int dimType = 0; // group 70
|
|
29
|
+
double angle = 0.0; // group 50
|
|
30
|
+
double coords[7][2] = {}; // groups 10-16 / 20-26
|
|
31
|
+
std::vector<double> xverts, yverts; // groups 10/11 and 20/21, in order
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
std::string trimmed(const std::string& s) {
|
|
35
|
+
const size_t b = s.find_first_not_of(" \t\r\n");
|
|
36
|
+
if (b == std::string::npos) return "";
|
|
37
|
+
return s.substr(b, s.find_last_not_of(" \t\r\n") - b + 1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// One entity per group-0 marker. Coordinates carry the origin shift and
|
|
41
|
+
// scale the reference applies while parsing, with its own exception: groups
|
|
42
|
+
// 11, 12 and 16 (and their 21/22/26 partners) are scaled but NOT shifted,
|
|
43
|
+
// since they are extents rather than positions.
|
|
44
|
+
std::vector<Entity> readEntities(const std::string& path, double xorigin, double yorigin, double scale) {
|
|
45
|
+
std::ifstream in(path);
|
|
46
|
+
std::vector<Entity> out;
|
|
47
|
+
if (!in) return out;
|
|
48
|
+
|
|
49
|
+
std::string codeLine, dataLine;
|
|
50
|
+
Entity cur;
|
|
51
|
+
bool started = false;
|
|
52
|
+
while (std::getline(in, codeLine) && std::getline(in, dataLine)) {
|
|
53
|
+
const std::string codeStr = trimmed(codeLine);
|
|
54
|
+
const std::string data = trimmed(dataLine);
|
|
55
|
+
if (codeStr.empty()) continue;
|
|
56
|
+
int code = 0;
|
|
57
|
+
try {
|
|
58
|
+
code = std::stoi(codeStr);
|
|
59
|
+
} catch (...) {
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
const auto num = [&]() -> double {
|
|
63
|
+
try {
|
|
64
|
+
return std::stod(data);
|
|
65
|
+
} catch (...) {
|
|
66
|
+
return 0.0;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
if (code == 0) {
|
|
71
|
+
if (started) out.push_back(cur);
|
|
72
|
+
cur = Entity{};
|
|
73
|
+
cur.type = data;
|
|
74
|
+
started = true;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (!started) continue;
|
|
78
|
+
|
|
79
|
+
if (code >= 10 && code <= 16) {
|
|
80
|
+
cur.coords[code - 10][0] =
|
|
81
|
+
(code == 11 || code == 12 || code == 16) ? num() * scale : (num() - xorigin) * scale;
|
|
82
|
+
} else if (code >= 20 && code <= 26) {
|
|
83
|
+
cur.coords[code - 20][1] =
|
|
84
|
+
(code == 21 || code == 22 || code == 26) ? num() * scale : (num() - yorigin) * scale;
|
|
85
|
+
}
|
|
86
|
+
switch (code) {
|
|
87
|
+
case 1: cur.name = data; break;
|
|
88
|
+
case 8: cur.layer = data; break;
|
|
89
|
+
case 10:
|
|
90
|
+
case 11: cur.xverts.push_back((num() - xorigin) * scale); break;
|
|
91
|
+
case 20:
|
|
92
|
+
case 21: cur.yverts.push_back((num() - yorigin) * scale); break;
|
|
93
|
+
case 50: cur.angle = num(); break;
|
|
94
|
+
case 70:
|
|
95
|
+
try {
|
|
96
|
+
cur.dimType = std::stoi(data);
|
|
97
|
+
} catch (...) {
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
default: break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (started) out.push_back(cur);
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
double deg(double r) { return r * 180.0 / 3.14159265358979323846; }
|
|
108
|
+
double rad(double d) { return d * 3.14159265358979323846 / 180.0; }
|
|
109
|
+
|
|
110
|
+
struct CommonArgs {
|
|
111
|
+
std::string path;
|
|
112
|
+
std::string rawFile;
|
|
113
|
+
std::string layer;
|
|
114
|
+
double xorigin = 0.0, yorigin = 0.0, scale = 1.0;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
CommonArgs commonArgs(const CallArgs& args, const oscad::ASTNode& node) {
|
|
118
|
+
CommonArgs c;
|
|
119
|
+
const Value fileArg = getArg(args, 0, "file", Value{});
|
|
120
|
+
c.rawFile = std::holds_alternative<std::string>(fileArg) ? std::get<std::string>(fileArg) : fmtValue(fileArg);
|
|
121
|
+
c.path = resolveFilePath(fileArg, node);
|
|
122
|
+
const Value layerArg = getArg(args, std::nullopt, "layer", Value{});
|
|
123
|
+
if (const std::string* s = std::get_if<std::string>(&layerArg)) c.layer = *s;
|
|
124
|
+
const Value originArg = getArg(args, std::nullopt, "origin", Value{});
|
|
125
|
+
if (const ListPtr* l = std::get_if<ListPtr>(&originArg); l && *l && (*l)->items.size() >= 2) {
|
|
126
|
+
c.xorigin = toDoubleLenient((*l)->items[0]);
|
|
127
|
+
c.yorigin = toDoubleLenient((*l)->items[1]);
|
|
128
|
+
}
|
|
129
|
+
const Value scaleArg = getArg(args, std::nullopt, "scale", Value{1.0});
|
|
130
|
+
if (std::holds_alternative<double>(scaleArg)) c.scale = std::get<double>(scaleArg);
|
|
131
|
+
return c;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
} // namespace
|
|
135
|
+
|
|
136
|
+
Value builtinDxfDim(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node) {
|
|
137
|
+
const CommonArgs c = commonArgs(args, node);
|
|
138
|
+
const Value nameArg = getArg(args, std::nullopt, "name", Value{});
|
|
139
|
+
const std::string name = std::holds_alternative<std::string>(nameArg) ? std::get<std::string>(nameArg) : "";
|
|
140
|
+
|
|
141
|
+
if (!std::filesystem::exists(c.path)) {
|
|
142
|
+
ev.warn("Can't open DXF file '" + c.rawFile + "'!", &node.position());
|
|
143
|
+
return Value{};
|
|
144
|
+
}
|
|
145
|
+
for (const Entity& e : readEntities(c.path, c.xorigin, c.yorigin, c.scale)) {
|
|
146
|
+
if (e.type != "DIMENSION") continue;
|
|
147
|
+
if (!c.layer.empty() && c.layer != e.layer) continue;
|
|
148
|
+
if (!name.empty() && e.name != name) continue;
|
|
149
|
+
|
|
150
|
+
const int type = e.dimType & 7;
|
|
151
|
+
if (type == 0) { // rotated, horizontal or vertical
|
|
152
|
+
const double x = e.coords[4][0] - e.coords[3][0];
|
|
153
|
+
const double y = e.coords[4][1] - e.coords[3][1];
|
|
154
|
+
return Value{std::fabs(x * std::cos(rad(e.angle)) + y * std::sin(rad(e.angle)))};
|
|
155
|
+
}
|
|
156
|
+
if (type == 1) { // aligned
|
|
157
|
+
const double x = e.coords[4][0] - e.coords[3][0];
|
|
158
|
+
const double y = e.coords[4][1] - e.coords[3][1];
|
|
159
|
+
return Value{std::sqrt(x * x + y * y)};
|
|
160
|
+
}
|
|
161
|
+
if (type == 2) { // angular
|
|
162
|
+
const double a1 = deg(std::atan2(e.coords[0][0] - e.coords[5][0], e.coords[0][1] - e.coords[5][1]));
|
|
163
|
+
const double a2 = deg(std::atan2(e.coords[4][0] - e.coords[3][0], e.coords[4][1] - e.coords[3][1]));
|
|
164
|
+
return Value{std::fabs(a1 - a2)};
|
|
165
|
+
}
|
|
166
|
+
if (type == 3 || type == 4) { // diameter or radius
|
|
167
|
+
const double x = e.coords[5][0] - e.coords[0][0];
|
|
168
|
+
const double y = e.coords[5][1] - e.coords[0][1];
|
|
169
|
+
return Value{std::sqrt(x * x + y * y)};
|
|
170
|
+
}
|
|
171
|
+
if (type == 6) { // ordinate
|
|
172
|
+
return Value{(e.dimType & 64) ? e.coords[3][0] : e.coords[3][1]};
|
|
173
|
+
}
|
|
174
|
+
// type 5 (angular 3-point) falls through, as in the reference.
|
|
175
|
+
ev.warn("Dimension '" + name + "' in '" + c.rawFile + "', layer '" + c.layer + "' has unsupported type!",
|
|
176
|
+
&node.position());
|
|
177
|
+
return Value{};
|
|
178
|
+
}
|
|
179
|
+
ev.warn("Can't find dimension '" + name + "' in '" + c.rawFile + "', layer '" + c.layer + "'!",
|
|
180
|
+
&node.position());
|
|
181
|
+
return Value{};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
Value builtinDxfCross(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node) {
|
|
185
|
+
const CommonArgs c = commonArgs(args, node);
|
|
186
|
+
if (!std::filesystem::exists(c.path)) {
|
|
187
|
+
ev.warn("Can't open DXF file '" + c.rawFile + "'!", &node.position());
|
|
188
|
+
return Value{};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// The first two LINEs on the layer are taken to be the cross. The
|
|
192
|
+
// reference walks every 2-point path instead, which for a real cross is
|
|
193
|
+
// the same set: its two strokes meet in the middle rather than at their
|
|
194
|
+
// endpoints, so neither gets joined into a longer path.
|
|
195
|
+
double p[4][2];
|
|
196
|
+
int found = 0;
|
|
197
|
+
for (const Entity& e : readEntities(c.path, c.xorigin, c.yorigin, c.scale)) {
|
|
198
|
+
if (e.type != "LINE") continue;
|
|
199
|
+
if (!c.layer.empty() && c.layer != e.layer) continue;
|
|
200
|
+
if (e.xverts.size() < 2 || e.yverts.size() < 2) continue;
|
|
201
|
+
p[found][0] = e.xverts[0];
|
|
202
|
+
p[found][1] = e.yverts[0];
|
|
203
|
+
++found;
|
|
204
|
+
p[found][0] = e.xverts[1];
|
|
205
|
+
p[found][1] = e.yverts[1];
|
|
206
|
+
++found;
|
|
207
|
+
if (found == 4) {
|
|
208
|
+
const double x1 = p[0][0], y1 = p[0][1], x2 = p[1][0], y2 = p[1][1];
|
|
209
|
+
const double x3 = p[2][0], y3 = p[2][1], x4 = p[3][0], y4 = p[3][1];
|
|
210
|
+
const double dem = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
|
211
|
+
if (dem == 0.0) break; // parallel: no cross, same as the reference
|
|
212
|
+
const double ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / dem;
|
|
213
|
+
std::vector<Value> xy{Value{x1 + ua * (x2 - x1)}, Value{y1 + ua * (y2 - y1)}};
|
|
214
|
+
return Value{std::make_shared<const ValueList>(ValueList{std::move(xy)})};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
ev.warn("Can't find cross in '" + c.rawFile + "', layer '" + c.layer + "'!", &node.position());
|
|
218
|
+
return Value{};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
} // namespace oscadeval
|