openscad-cpp-evaluator 0.27.1__tar.gz → 0.28.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.27.1 → openscad_cpp_evaluator-0.28.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/grammar/lexer.l +9 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +37 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/value.hpp +20 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/bytecode_compiler.cpp +4 -1
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/expr_eval.cpp +1 -1
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/value.cpp +34 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_bytecode_compiler.cpp +2 -2
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_dxf_svg_import.cpp +29 -29
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_import_export.cpp +13 -13
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_surface.cpp +8 -8
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_value.cpp +62 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/README.md +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/text/stb_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/uv.lock +0 -0
|
@@ -99,6 +99,15 @@ NUMLIT 0[xX][0-9A-Fa-f]+|[0-9]+([.][0-9]*)?([eE][+-]?[0-9]+)?|[.][0-9]+([eE][+-
|
|
|
99
99
|
driver.stringStart = driver.tokenStart;
|
|
100
100
|
BEGIN(STR);
|
|
101
101
|
}
|
|
102
|
+
/* A backslash escaping the end of the line. Flex's `.` never matches a
|
|
103
|
+
newline, so without this rule the backslash matched nothing, fell to
|
|
104
|
+
flex's default ECHO and was printed to stdout -- a stray `\` on every
|
|
105
|
+
parse of such a file -- while the newline was picked up as ordinary
|
|
106
|
+
content by the run rule below and ended up inside the string.
|
|
107
|
+
Kept verbatim rather than dropped here: the value is cooked when the
|
|
108
|
+
literal is evaluated, so the AST keeps text that reproduces the
|
|
109
|
+
source exactly, which is what the pretty-printer round-trips. */
|
|
110
|
+
<STR>\\\r?\n { driver.stringBuffer.append(yytext, yyleng); }
|
|
102
111
|
<STR>\\. { driver.stringBuffer.append(yytext, yyleng); }
|
|
103
112
|
<STR>[^"\\]+ { driver.stringBuffer.append(yytext, yyleng); }
|
|
104
113
|
<STR>\" {
|
|
@@ -436,3 +436,40 @@ TEST(SourceSpans, MultiLineStringReportsItsStartingLine) {
|
|
|
436
436
|
EXPECT_EQ(assign->expr->position().line, 2);
|
|
437
437
|
EXPECT_EQ(spanned(src, *assign->expr), "\"one\ntwo\"");
|
|
438
438
|
}
|
|
439
|
+
|
|
440
|
+
// -- Backslash at end of line inside a string ---------------------------
|
|
441
|
+
|
|
442
|
+
// The lexer had no rule for a backslash followed by a newline: flex's `.`
|
|
443
|
+
// never matches a newline, so `\\.` could not, and the backslash fell
|
|
444
|
+
// through to flex's DEFAULT ECHO rule -- printed straight to stdout, a
|
|
445
|
+
// stray `\` on every parse of such a file. The newline was then swallowed
|
|
446
|
+
// by the content-run rule and became part of the string.
|
|
447
|
+
//
|
|
448
|
+
// The literal keeps both characters. Cooking happens where the literal is
|
|
449
|
+
// evaluated, not here, so a StringLiteral's text still reproduces the
|
|
450
|
+
// source it was parsed from -- which is what pretty-printing relies on.
|
|
451
|
+
TEST(LexicalStrings, BackslashNewlineIsKeptVerbatimInTheLiteral) {
|
|
452
|
+
struct Case { std::string src; std::string want; const char* what; };
|
|
453
|
+
const Case cases[] = {
|
|
454
|
+
{"a = \"x \\\ny\";", "x \\\ny", "LF"},
|
|
455
|
+
{"a = \"x \\\r\ny\";", "x \\\r\ny", "CRLF"},
|
|
456
|
+
};
|
|
457
|
+
for (const Case& c : cases) {
|
|
458
|
+
auto ast = parseSrc(c.src);
|
|
459
|
+
ASSERT_EQ(ast.size(), 1u) << c.what;
|
|
460
|
+
auto* assign = dynamic_cast<Assignment*>(ast[0].get());
|
|
461
|
+
ASSERT_NE(assign, nullptr) << c.what;
|
|
462
|
+
auto* str = dynamic_cast<StringLiteral*>(assign->expr.get());
|
|
463
|
+
ASSERT_NE(str, nullptr) << c.what;
|
|
464
|
+
EXPECT_EQ(str->val, c.want) << c.what;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// The continued line still counts, or every position after a multi-line
|
|
469
|
+
// string would be reported one line short.
|
|
470
|
+
TEST(LexicalStrings, BackslashNewlineStillAdvancesTheLineNumber) {
|
|
471
|
+
auto ast = parseSrc("a = \"x \\\ny\";\nb = 2;\n");
|
|
472
|
+
ASSERT_EQ(ast.size(), 2u);
|
|
473
|
+
EXPECT_EQ(ast[0]->position().line, 1);
|
|
474
|
+
EXPECT_EQ(ast[1]->position().line, 3) << "the continuation consumed a line";
|
|
475
|
+
}
|
|
@@ -181,6 +181,26 @@ Value matmul(const Value& a, const Value& b);
|
|
|
181
181
|
// script's output is shown to land on one.
|
|
182
182
|
std::string formatNumber(double v);
|
|
183
183
|
|
|
184
|
+
// Resolve the escape sequences in a string literal's source text.
|
|
185
|
+
//
|
|
186
|
+
// The parser stores a StringLiteral's text exactly as written, backslashes
|
|
187
|
+
// and all, so that a literal still reproduces the source it came from and
|
|
188
|
+
// pretty-printing round-trips. Cooking is therefore this side's job, and
|
|
189
|
+
// until this existed every escape reached scripts intact: "a\nb" was four
|
|
190
|
+
// characters, a backslash and an 'n' among them, rather than three.
|
|
191
|
+
//
|
|
192
|
+
// \\ \" \n \t \r the character they name
|
|
193
|
+
// \<newline> nothing at all -- a line continuation, so the string
|
|
194
|
+
// carries on with no break in it. A CRLF goes whole:
|
|
195
|
+
// leaving the CR behind, as the reference
|
|
196
|
+
// implementation does, puts a stray control character
|
|
197
|
+
// into the value of any script written on Windows.
|
|
198
|
+
// \<anything else> that character, with the backslash dropped
|
|
199
|
+
//
|
|
200
|
+
// A trailing lone backslash is kept as itself. It can only occur in an
|
|
201
|
+
// unterminated literal, which is a parse error long before this runs.
|
|
202
|
+
std::string unescapeStringLiteral(const std::string& raw);
|
|
203
|
+
|
|
184
204
|
// echo()/str()/assert-message display format: "undef" | "true"/"false" |
|
|
185
205
|
// "[start : step : end]" (range) | formatNumber() (number) | "[e1, e2, ...]"
|
|
186
206
|
// (list, recursive) | "object(k1 = v1, ...)" ("object()" if empty) |
|
|
@@ -324,7 +324,10 @@ public:
|
|
|
324
324
|
out.push_back({Op::PushBool, static_cast<const oscad::BooleanLiteral&>(node).val ? 1 : 0, 0, nullptr});
|
|
325
325
|
return;
|
|
326
326
|
case NodeKind::StringLiteral:
|
|
327
|
-
out.push_back({Op::PushConst,
|
|
327
|
+
out.push_back({Op::PushConst,
|
|
328
|
+
internConst(Value{unescapeStringLiteral(
|
|
329
|
+
static_cast<const oscad::StringLiteral&>(node).val)}),
|
|
330
|
+
0,
|
|
328
331
|
nullptr});
|
|
329
332
|
return;
|
|
330
333
|
case NodeKind::UndefinedLiteral:
|
|
@@ -396,7 +396,7 @@ Value Evaluator::evalExpr(const oscad::Expression& node, EvalContext& ctx) {
|
|
|
396
396
|
case NodeKind::BooleanLiteral:
|
|
397
397
|
return Value{static_cast<const oscad::BooleanLiteral&>(node).val};
|
|
398
398
|
case NodeKind::StringLiteral:
|
|
399
|
-
return Value{static_cast<const oscad::StringLiteral&>(node).val};
|
|
399
|
+
return Value{unescapeStringLiteral(static_cast<const oscad::StringLiteral&>(node).val)};
|
|
400
400
|
case NodeKind::UndefinedLiteral:
|
|
401
401
|
return Value{};
|
|
402
402
|
case NodeKind::CommentedExpr:
|
|
@@ -268,6 +268,40 @@ Value matmul(const Value& a, const Value& b) {
|
|
|
268
268
|
return makeList(std::move(out));
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
std::string unescapeStringLiteral(const std::string& raw) {
|
|
272
|
+
// Most strings carry no escape at all, and this runs on every
|
|
273
|
+
// evaluation of a literal on the tree-walking path -- so don't build a
|
|
274
|
+
// second copy of the string unless there is something to change.
|
|
275
|
+
const size_t first = raw.find('\\');
|
|
276
|
+
if (first == std::string::npos) return raw;
|
|
277
|
+
|
|
278
|
+
std::string out;
|
|
279
|
+
out.reserve(raw.size());
|
|
280
|
+
out.append(raw, 0, first);
|
|
281
|
+
for (size_t i = first; i < raw.size(); ++i) {
|
|
282
|
+
if (raw[i] != '\\' || i + 1 >= raw.size()) {
|
|
283
|
+
out.push_back(raw[i]); // a trailing lone backslash stands for itself
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const char next = raw[i + 1];
|
|
287
|
+
switch (next) {
|
|
288
|
+
case 'n': out.push_back('\n'); ++i; break;
|
|
289
|
+
case 't': out.push_back('\t'); ++i; break;
|
|
290
|
+
case 'r': out.push_back('\r'); ++i; break;
|
|
291
|
+
case '\n': ++i; break; // line continuation: contributes nothing
|
|
292
|
+
case '\r':
|
|
293
|
+
// Only a CRLF pair is a line continuation; a lone CR is an
|
|
294
|
+
// ordinary escaped character like any other.
|
|
295
|
+
if (i + 2 < raw.size() && raw[i + 2] == '\n') { i += 2; break; }
|
|
296
|
+
out.push_back('\r');
|
|
297
|
+
++i;
|
|
298
|
+
break;
|
|
299
|
+
default: out.push_back(next); ++i; break; // \\ and \" land here too
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
|
|
271
305
|
std::string formatNumber(double v) {
|
|
272
306
|
if (std::isnan(v)) return "nan";
|
|
273
307
|
if (std::isinf(v)) return v > 0 ? "inf" : "-inf";
|
{openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_bytecode_compiler.cpp
RENAMED
|
@@ -1044,7 +1044,7 @@ TEST(BytecodeCompiler, ImportCompilesAsTailPositionBody) {
|
|
|
1044
1044
|
std::ofstream out(path);
|
|
1045
1045
|
out << R"({"a": 1, "b": 2})";
|
|
1046
1046
|
}
|
|
1047
|
-
EXPECT_EQ(runCapturingEcho("function f() = import(\"" + path.
|
|
1047
|
+
EXPECT_EQ(runCapturingEcho("function f() = import(\"" + path.generic_string() + "\");\necho(f());"),
|
|
1048
1048
|
"ECHO: object(a = 1, b = 2)");
|
|
1049
1049
|
std::filesystem::remove(path);
|
|
1050
1050
|
}
|
|
@@ -1073,7 +1073,7 @@ TEST(BytecodeCompiler, VmOffAndVmOnAgreeOnEchoAssertImportObjectCases) {
|
|
|
1073
1073
|
const std::string script = "function withEcho(x) = echo(\"trace\", x) x + 1;\n"
|
|
1074
1074
|
"function withAssert(x) = assert(x >= 0, \"must be non-negative\") x * 2;\n"
|
|
1075
1075
|
"function withImport() = import(\"" +
|
|
1076
|
-
path.
|
|
1076
|
+
path.generic_string() +
|
|
1077
1077
|
"\");\n"
|
|
1078
1078
|
"existing = object(m = 1);\n"
|
|
1079
1079
|
"function withObject() = object(n = 2, existing, m = 3);\n"
|
{openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_dxf_svg_import.cpp
RENAMED
|
@@ -38,7 +38,7 @@ const char* kMinimalDxfSquare =
|
|
|
38
38
|
TEST(DxfImport, ClosedLwpolylineProducesExpectedBoundingBox) {
|
|
39
39
|
const auto path = tempPath("square.dxf");
|
|
40
40
|
writeFile(path, kMinimalDxfSquare);
|
|
41
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
41
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
42
42
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
43
43
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
44
44
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6); // 4x3 square
|
|
@@ -49,7 +49,7 @@ TEST(DxfImport, ExpressionContextReturnsRegion) {
|
|
|
49
49
|
const auto path = tempPath("square_expr.dxf");
|
|
50
50
|
writeFile(path, kMinimalDxfSquare);
|
|
51
51
|
Evaluator ev;
|
|
52
|
-
Value v = asExpr("import(\"" + path.
|
|
52
|
+
Value v = asExpr("import(\"" + path.generic_string() + "\")", ev);
|
|
53
53
|
const auto& contours = std::get<ListPtr>(v)->items;
|
|
54
54
|
ASSERT_EQ(contours.size(), 1u);
|
|
55
55
|
const auto& pts = std::get<ListPtr>(contours[0])->items;
|
|
@@ -68,7 +68,7 @@ TEST(DxfImport, LayerFilterExcludesOtherLayers) {
|
|
|
68
68
|
"0\nENDSEC\n0\nEOF\n";
|
|
69
69
|
const auto path = tempPath("layered.dxf");
|
|
70
70
|
writeFile(path, dxf);
|
|
71
|
-
Evaluated e = evalSrc("import(file=\"" + path.
|
|
71
|
+
Evaluated e = evalSrc("import(file=\"" + path.generic_string() + "\", layer=\"keep\");");
|
|
72
72
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
73
73
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
74
74
|
EXPECT_NEAR(e.bodies[0].section->Area(), 1.0, 1e-6);
|
|
@@ -90,7 +90,7 @@ TEST(DxfImport, ClosedPolylineVertexEntityProducesExpectedArea) {
|
|
|
90
90
|
"0\nENDSEC\n0\nEOF\n";
|
|
91
91
|
const auto path = tempPath("polyline.dxf");
|
|
92
92
|
writeFile(path, dxf);
|
|
93
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
93
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
94
94
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
95
95
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
96
96
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
@@ -111,7 +111,7 @@ TEST(DxfImport, OpenPolylineIsIgnored) {
|
|
|
111
111
|
const auto path = tempPath("open_polyline.dxf");
|
|
112
112
|
writeFile(path, dxf);
|
|
113
113
|
Evaluator ev;
|
|
114
|
-
auto ast = parseSrc("import(\"" + path.
|
|
114
|
+
auto ast = parseSrc("import(\"" + path.generic_string() + "\");");
|
|
115
115
|
auto scope = oscad::buildScopes(ast);
|
|
116
116
|
EvalContext ctx = EvalContext::makeRoot(scope.get());
|
|
117
117
|
EXPECT_THROW(ev.resolveTree(ast, ctx), EvalError);
|
|
@@ -131,7 +131,7 @@ TEST(DxfImport, UnrecognizedEntityIsSkipped) {
|
|
|
131
131
|
"0\nENDSEC\n0\nEOF\n";
|
|
132
132
|
const auto path = tempPath("unrecognized.dxf");
|
|
133
133
|
writeFile(path, dxf);
|
|
134
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
134
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
135
135
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
136
136
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
137
137
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
@@ -143,7 +143,7 @@ TEST(DxfImport, NoClosedContoursErrors) {
|
|
|
143
143
|
const auto path = tempPath("empty.dxf");
|
|
144
144
|
writeFile(path, dxf);
|
|
145
145
|
Evaluator ev;
|
|
146
|
-
auto ast = parseSrc("import(\"" + path.
|
|
146
|
+
auto ast = parseSrc("import(\"" + path.generic_string() + "\");");
|
|
147
147
|
auto scope = oscad::buildScopes(ast);
|
|
148
148
|
EvalContext ctx = EvalContext::makeRoot(scope.get());
|
|
149
149
|
EXPECT_THROW(ev.resolveTree(ast, ctx), EvalError);
|
|
@@ -155,7 +155,7 @@ TEST(DxfImport, NoClosedContoursErrors) {
|
|
|
155
155
|
TEST(SvgImport, RectProducesExpectedArea) {
|
|
156
156
|
const auto path = tempPath("rect.svg");
|
|
157
157
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="4" height="3"/></svg>)");
|
|
158
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
158
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
159
159
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
160
160
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
161
161
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
@@ -167,7 +167,7 @@ TEST(SvgImport, PathWithGroupTransformIsTranslatedAndYFlipped) {
|
|
|
167
167
|
writeFile(path, R"svg(<svg xmlns="http://www.w3.org/2000/svg">
|
|
168
168
|
<g transform="translate(10,0)"><path d="M0,0 L4,0 L4,3 L0,3 Z"/></g>
|
|
169
169
|
</svg>)svg");
|
|
170
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
170
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
171
171
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
172
172
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
173
173
|
manifold::Rect bounds = e.bodies[0].section->Bounds();
|
|
@@ -183,7 +183,7 @@ TEST(SvgImport, PathWithGroupTransformIsTranslatedAndYFlipped) {
|
|
|
183
183
|
TEST(SvgImport, CircleApproximatesAnalyticArea) {
|
|
184
184
|
const auto path = tempPath("circle.svg");
|
|
185
185
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><circle cx="0" cy="0" r="5"/></svg>)");
|
|
186
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
186
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
187
187
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
188
188
|
EXPECT_NEAR(e.bodies[0].section->Area(), 3.14159265 * 25.0, 1.0); // 32-segment approximation
|
|
189
189
|
std::filesystem::remove(path);
|
|
@@ -192,7 +192,7 @@ TEST(SvgImport, CircleApproximatesAnalyticArea) {
|
|
|
192
192
|
TEST(SvgImport, CubicBezierPathIsWatertight) {
|
|
193
193
|
const auto path = tempPath("bezier.svg");
|
|
194
194
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 C2,5 8,5 10,0 L10,-5 L0,-5 Z"/></svg>)");
|
|
195
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
195
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
196
196
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
197
197
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
198
198
|
EXPECT_GT(e.bodies[0].section->Area(), 0.0);
|
|
@@ -203,7 +203,7 @@ TEST(SvgImport, NoShapesErrors) {
|
|
|
203
203
|
const auto path = tempPath("noshapes.svg");
|
|
204
204
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><defs><rect x="0" y="0" width="1" height="1"/></defs></svg>)");
|
|
205
205
|
Evaluator ev;
|
|
206
|
-
auto ast = parseSrc("import(\"" + path.
|
|
206
|
+
auto ast = parseSrc("import(\"" + path.generic_string() + "\");");
|
|
207
207
|
auto scope = oscad::buildScopes(ast);
|
|
208
208
|
EvalContext ctx = EvalContext::makeRoot(scope.get());
|
|
209
209
|
EXPECT_THROW(ev.resolveTree(ast, ctx), EvalError);
|
|
@@ -220,7 +220,7 @@ TEST(SvgImport, EntityReferencesInAttributeValueDecodedWithoutCorruptingParse) {
|
|
|
220
220
|
// area would come out wrong (or parsing would throw).
|
|
221
221
|
const auto path = tempPath("entities.svg");
|
|
222
222
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><rect id="a&b<c>d"e'f" x="0" y="0" width="4" height="3"/></svg>)");
|
|
223
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
223
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
224
224
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
225
225
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
226
226
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
@@ -241,7 +241,7 @@ TEST(SvgImport, CommentCdataPrologAndDoctypeAreSkipped) {
|
|
|
241
241
|
<rect x="0" y="0" width="4" height="3"/>
|
|
242
242
|
</svg>
|
|
243
243
|
)");
|
|
244
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
244
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
245
245
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
246
246
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
247
247
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
@@ -253,7 +253,7 @@ TEST(SvgImport, TransformMatrixIsApplied) {
|
|
|
253
253
|
writeFile(path, R"svg(<svg xmlns="http://www.w3.org/2000/svg">
|
|
254
254
|
<g transform="matrix(2,0,0,2,5,0)"><rect x="0" y="0" width="4" height="3"/></g>
|
|
255
255
|
</svg>)svg");
|
|
256
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
256
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
257
257
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
258
258
|
EXPECT_NEAR(e.bodies[0].section->Area(), 48.0, 1e-6); // 2x scale in both axes -> 4x area
|
|
259
259
|
manifold::Rect bounds = e.bodies[0].section->Bounds();
|
|
@@ -267,7 +267,7 @@ TEST(SvgImport, TransformScaleWithSeparateXyIsApplied) {
|
|
|
267
267
|
writeFile(path, R"svg(<svg xmlns="http://www.w3.org/2000/svg">
|
|
268
268
|
<g transform="scale(2,3)"><rect x="0" y="0" width="4" height="3"/></g>
|
|
269
269
|
</svg>)svg");
|
|
270
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
270
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
271
271
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
272
272
|
EXPECT_NEAR(e.bodies[0].section->Area(), 72.0, 1e-6); // 2x * 3x -> 6x area
|
|
273
273
|
std::filesystem::remove(path);
|
|
@@ -278,7 +278,7 @@ TEST(SvgImport, TransformRotateAboutOriginIsApplied) {
|
|
|
278
278
|
writeFile(path, R"svg(<svg xmlns="http://www.w3.org/2000/svg">
|
|
279
279
|
<g transform="rotate(90)"><rect x="0" y="0" width="4" height="3"/></g>
|
|
280
280
|
</svg>)svg");
|
|
281
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
281
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
282
282
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
283
283
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6); // rotation preserves area
|
|
284
284
|
manifold::Rect bounds = e.bodies[0].section->Bounds();
|
|
@@ -294,7 +294,7 @@ TEST(SvgImport, TransformRotateAboutOriginIsApplied) {
|
|
|
294
294
|
TEST(SvgImport, HorizontalAndVerticalLineCommands) {
|
|
295
295
|
const auto path = tempPath("hv.svg");
|
|
296
296
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 H4 V3 H0 Z"/></svg>)");
|
|
297
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
297
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
298
298
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
299
299
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
300
300
|
std::filesystem::remove(path);
|
|
@@ -303,7 +303,7 @@ TEST(SvgImport, HorizontalAndVerticalLineCommands) {
|
|
|
303
303
|
TEST(SvgImport, SmoothCubicCommandFollowsCubic) {
|
|
304
304
|
const auto path = tempPath("smoothcubic.svg");
|
|
305
305
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 C1,4 3,4 4,0 S7,-4 8,0 L8,-6 L0,-6 Z"/></svg>)");
|
|
306
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
306
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
307
307
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
308
308
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
309
309
|
EXPECT_GT(e.bodies[0].section->Area(), 0.0);
|
|
@@ -313,7 +313,7 @@ TEST(SvgImport, SmoothCubicCommandFollowsCubic) {
|
|
|
313
313
|
TEST(SvgImport, SmoothQuadraticCommandFollowsQuadratic) {
|
|
314
314
|
const auto path = tempPath("smoothquad.svg");
|
|
315
315
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 Q2,4 4,0 T8,0 L8,-4 L0,-4 Z"/></svg>)");
|
|
316
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
316
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
317
317
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
318
318
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
319
319
|
EXPECT_GT(e.bodies[0].section->Area(), 0.0);
|
|
@@ -323,7 +323,7 @@ TEST(SvgImport, SmoothQuadraticCommandFollowsQuadratic) {
|
|
|
323
323
|
TEST(SvgImport, EllipticalArcCommand) {
|
|
324
324
|
const auto path = tempPath("arc.svg");
|
|
325
325
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 A5,5 0 0,1 10,0 L10,-10 L0,-10 Z"/></svg>)");
|
|
326
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
326
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
327
327
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
328
328
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
329
329
|
EXPECT_GT(e.bodies[0].section->Area(), 0.0);
|
|
@@ -333,7 +333,7 @@ TEST(SvgImport, EllipticalArcCommand) {
|
|
|
333
333
|
TEST(SvgImport, PolygonPointsAttribute) {
|
|
334
334
|
const auto path = tempPath("polygon.svg");
|
|
335
335
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 4,0 4,3 0,3"/></svg>)");
|
|
336
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
336
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
337
337
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
338
338
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
339
339
|
std::filesystem::remove(path);
|
|
@@ -342,7 +342,7 @@ TEST(SvgImport, PolygonPointsAttribute) {
|
|
|
342
342
|
TEST(SvgImport, PolylinePointsAttribute) {
|
|
343
343
|
const auto path = tempPath("polyline.svg");
|
|
344
344
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><polyline points="0,0 4,0 4,3 0,3"/></svg>)");
|
|
345
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
345
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
346
346
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
347
347
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
348
348
|
std::filesystem::remove(path);
|
|
@@ -351,7 +351,7 @@ TEST(SvgImport, PolylinePointsAttribute) {
|
|
|
351
351
|
TEST(SvgImport, StrayCharacterInPointsListIsSkipped) {
|
|
352
352
|
const auto path = tempPath("straypoints.svg");
|
|
353
353
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 x 4,0 4,3 0,3"/></svg>)");
|
|
354
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
354
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
355
355
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
356
356
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
357
357
|
std::filesystem::remove(path);
|
|
@@ -360,7 +360,7 @@ TEST(SvgImport, StrayCharacterInPointsListIsSkipped) {
|
|
|
360
360
|
TEST(SvgImport, StrayCharacterInPathDataIsSkipped) {
|
|
361
361
|
const auto path = tempPath("straypath.svg");
|
|
362
362
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 L4,0 @ L4,3 L0,3 Z"/></svg>)");
|
|
363
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
363
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
364
364
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
365
365
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
366
366
|
std::filesystem::remove(path);
|
|
@@ -374,7 +374,7 @@ TEST(SvgImport, TransformNumberWithExponentIsParsed) {
|
|
|
374
374
|
writeFile(path, R"svg(<svg xmlns="http://www.w3.org/2000/svg">
|
|
375
375
|
<g transform="translate(1e1,0)"><rect x="0" y="0" width="4" height="3"/></g>
|
|
376
376
|
</svg>)svg");
|
|
377
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
377
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
378
378
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
379
379
|
manifold::Rect bounds = e.bodies[0].section->Bounds();
|
|
380
380
|
EXPECT_NEAR(bounds.min.x, 10.0, 1e-6);
|
|
@@ -386,7 +386,7 @@ TEST(SvgImport, PathNumberWithExponentIsParsed) {
|
|
|
386
386
|
// path `d` attribute rather than a transform argument list.
|
|
387
387
|
const auto path = tempPath("exponent_path.svg");
|
|
388
388
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 L4e0,0 L4,3 L0,3 Z"/></svg>)");
|
|
389
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
389
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
390
390
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
391
391
|
EXPECT_NEAR(e.bodies[0].section->Area(), 12.0, 1e-6);
|
|
392
392
|
std::filesystem::remove(path);
|
|
@@ -400,7 +400,7 @@ TEST(SvgImport, EllipticalArcWithOutOfRangeRadiiIsScaledUp) {
|
|
|
400
400
|
// never hit this path.
|
|
401
401
|
const auto path = tempPath("arc_scaled.svg");
|
|
402
402
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 A1,1 0 0,1 10,0 L10,-10 L0,-10 Z"/></svg>)");
|
|
403
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
403
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
404
404
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
405
405
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
406
406
|
EXPECT_GT(e.bodies[0].section->Area(), 0.0);
|
|
@@ -413,7 +413,7 @@ TEST(SvgImport, MultipleSubpathsInOnePathProduceMultipleContours) {
|
|
|
413
413
|
// starting a new one, distinct from an explicit `Z`.
|
|
414
414
|
const auto path = tempPath("multisubpath.svg");
|
|
415
415
|
writeFile(path, R"(<svg xmlns="http://www.w3.org/2000/svg"><path d="M0,0 L4,0 L4,3 L0,3 Z M10,0 L14,0 L14,3 L10,3 Z"/></svg>)");
|
|
416
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
416
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
417
417
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
418
418
|
ASSERT_TRUE(e.bodies[0].section.has_value());
|
|
419
419
|
EXPECT_NEAR(e.bodies[0].section->Area(), 24.0, 1e-6); // two disjoint 4x3 squares
|
{openscad_cpp_evaluator-0.27.1 → openscad_cpp_evaluator-0.28.0}/tests/test_import_export.cpp
RENAMED
|
@@ -40,7 +40,7 @@ Value asExpr(const std::string& code, Evaluator& ev) {
|
|
|
40
40
|
TEST(ImportModuleContext, StlRoundTripPreservesVolume) {
|
|
41
41
|
const auto path = tempPath("cube.stl");
|
|
42
42
|
writeCubeAs(path, &writeStl);
|
|
43
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
43
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
44
44
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
45
45
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
46
46
|
EXPECT_NEAR(e.bodies[0].body->Volume(), 8.0, 1e-6);
|
|
@@ -50,7 +50,7 @@ TEST(ImportModuleContext, StlRoundTripPreservesVolume) {
|
|
|
50
50
|
TEST(ImportModuleContext, ObjRoundTripPreservesVolume) {
|
|
51
51
|
const auto path = tempPath("cube.obj");
|
|
52
52
|
writeCubeAs(path, &writeObj);
|
|
53
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
53
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
54
54
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
55
55
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
56
56
|
EXPECT_NEAR(e.bodies[0].body->Volume(), 8.0, 1e-6);
|
|
@@ -60,7 +60,7 @@ TEST(ImportModuleContext, ObjRoundTripPreservesVolume) {
|
|
|
60
60
|
TEST(ImportModuleContext, OffRoundTripPreservesVolume) {
|
|
61
61
|
const auto path = tempPath("cube.off");
|
|
62
62
|
writeCubeAs(path, &writeOff);
|
|
63
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
63
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
64
64
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
65
65
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
66
66
|
EXPECT_NEAR(e.bodies[0].body->Volume(), 8.0, 1e-6);
|
|
@@ -70,7 +70,7 @@ TEST(ImportModuleContext, OffRoundTripPreservesVolume) {
|
|
|
70
70
|
TEST(ImportModuleContext, ThreeMfRoundTripPreservesVolume) {
|
|
71
71
|
const auto path = tempPath("cube.3mf");
|
|
72
72
|
writeCubeAs(path, &writeThreeMf);
|
|
73
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
73
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");");
|
|
74
74
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
75
75
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
76
76
|
EXPECT_NEAR(e.bodies[0].body->Volume(), 8.0, 1e-6);
|
|
@@ -100,7 +100,7 @@ TEST(ImportModuleContext, JsonExtensionErrorsAsGeometryStatement) {
|
|
|
100
100
|
out << R"({"a": 1})";
|
|
101
101
|
}
|
|
102
102
|
Evaluator ev;
|
|
103
|
-
auto ast = parseSrc("import(\"" + path.
|
|
103
|
+
auto ast = parseSrc("import(\"" + path.generic_string() + "\");");
|
|
104
104
|
auto scope = oscad::buildScopes(ast);
|
|
105
105
|
EvalContext ctx = EvalContext::makeRoot(scope.get());
|
|
106
106
|
EXPECT_THROW(ev.resolveTree(ast, ctx), EvalError);
|
|
@@ -118,7 +118,7 @@ TEST(ImportModuleContext, MalformedMeshFileErrors) {
|
|
|
118
118
|
out << "this is not a valid STL file at all";
|
|
119
119
|
}
|
|
120
120
|
Evaluator ev;
|
|
121
|
-
auto ast = parseSrc("import(\"" + path.
|
|
121
|
+
auto ast = parseSrc("import(\"" + path.generic_string() + "\");");
|
|
122
122
|
auto scope = oscad::buildScopes(ast);
|
|
123
123
|
EvalContext ctx = EvalContext::makeRoot(scope.get());
|
|
124
124
|
EXPECT_THROW(ev.resolveTree(ast, ctx), EvalError);
|
|
@@ -136,7 +136,7 @@ TEST(ImportModuleContext, NonManifoldMeshWarns) {
|
|
|
136
136
|
out << "OFF\n3 1 0\n0 0 0\n1 0 0\n0 1 0\n3 0 1 2\n";
|
|
137
137
|
}
|
|
138
138
|
std::string lastWarning;
|
|
139
|
-
Evaluated e = evalSrc("import(\"" + path.
|
|
139
|
+
Evaluated e = evalSrc("import(\"" + path.generic_string() + "\");", [&](const std::string& msg) { lastWarning = msg; });
|
|
140
140
|
EXPECT_NE(lastWarning.find("import: mesh is not a closed solid"), std::string::npos);
|
|
141
141
|
// The triangle is now handed back for display rather than dropped: a
|
|
142
142
|
// file that warns once and then shows nothing gives no way to see what
|
|
@@ -158,7 +158,7 @@ TEST(ImportModuleContext, EmptyMeshHasNoTrianglesErrors) {
|
|
|
158
158
|
std::ofstream out(path);
|
|
159
159
|
out << "OFF\n0 0 0\n";
|
|
160
160
|
}
|
|
161
|
-
EXPECT_THROW(evalSrc("import(\"" + path.
|
|
161
|
+
EXPECT_THROW(evalSrc("import(\"" + path.generic_string() + "\");"), EvalError);
|
|
162
162
|
std::filesystem::remove(path);
|
|
163
163
|
}
|
|
164
164
|
|
|
@@ -168,7 +168,7 @@ TEST(ImportExpressionContext, StlReturnsVnfShape) {
|
|
|
168
168
|
const auto path = tempPath("cube_vnf.stl");
|
|
169
169
|
writeCubeAs(path, &writeStl);
|
|
170
170
|
Evaluator ev;
|
|
171
|
-
Value v = asExpr("import(\"" + path.
|
|
171
|
+
Value v = asExpr("import(\"" + path.generic_string() + "\")", ev);
|
|
172
172
|
const auto& outer = std::get<ListPtr>(v)->items;
|
|
173
173
|
ASSERT_EQ(outer.size(), 2u);
|
|
174
174
|
const auto& verts = std::get<ListPtr>(outer[0])->items;
|
|
@@ -185,7 +185,7 @@ TEST(ImportExpressionContext, JsonReturnsNativeValues) {
|
|
|
185
185
|
out << R"({"name": "x", "n": 3, "nested": {"a": 1, "b": 2}, "list": [1, 2, 3]})";
|
|
186
186
|
}
|
|
187
187
|
Evaluator ev;
|
|
188
|
-
Value v = asExpr("import(\"" + path.
|
|
188
|
+
Value v = asExpr("import(\"" + path.generic_string() + "\")", ev);
|
|
189
189
|
const auto& obj = std::get<ObjectPtr>(v)->items;
|
|
190
190
|
ASSERT_EQ(obj.size(), 4u);
|
|
191
191
|
EXPECT_EQ(obj[0].first, "name");
|
|
@@ -211,7 +211,7 @@ TEST(ImportExpressionContext, JsonNullValueBecomesUndef) {
|
|
|
211
211
|
out << R"({"x": null})";
|
|
212
212
|
}
|
|
213
213
|
Evaluator ev;
|
|
214
|
-
Value v = asExpr("import(\"" + path.
|
|
214
|
+
Value v = asExpr("import(\"" + path.generic_string() + "\")", ev);
|
|
215
215
|
const auto& obj = std::get<ObjectPtr>(v)->items;
|
|
216
216
|
ASSERT_EQ(obj.size(), 1u);
|
|
217
217
|
EXPECT_TRUE(std::holds_alternative<std::monostate>(obj[0].second));
|
|
@@ -227,7 +227,7 @@ TEST(ImportExpressionContext, DxfReturnsRegionContours) {
|
|
|
227
227
|
"0\nENDSEC\n0\nEOF\n";
|
|
228
228
|
}
|
|
229
229
|
Evaluator ev;
|
|
230
|
-
Value v = asExpr("import(\"" + path.
|
|
230
|
+
Value v = asExpr("import(\"" + path.generic_string() + "\")", ev);
|
|
231
231
|
const auto& contours = std::get<ListPtr>(v)->items;
|
|
232
232
|
ASSERT_EQ(contours.size(), 1u);
|
|
233
233
|
std::filesystem::remove(path);
|
|
@@ -250,7 +250,7 @@ TEST(ImportExpressionContext, MalformedMeshFileErrors) {
|
|
|
250
250
|
out << "not a valid STL file";
|
|
251
251
|
}
|
|
252
252
|
Evaluator ev;
|
|
253
|
-
EXPECT_THROW(asExpr("import(\"" + path.
|
|
253
|
+
EXPECT_THROW(asExpr("import(\"" + path.generic_string() + "\")", ev), EvalError);
|
|
254
254
|
std::filesystem::remove(path);
|
|
255
255
|
}
|
|
256
256
|
|
|
@@ -46,7 +46,7 @@ TEST(Surface, DatFileHeightsMatchExactVertexPositions) {
|
|
|
46
46
|
// reference on this shape (12 triangles, bbox [0,0,0]-[2,2,5]).
|
|
47
47
|
const auto path = tempPath("terrain.dat");
|
|
48
48
|
writeDat(path, {{0, 0, 0}, {0, 5, 0}, {0, 0, 0}});
|
|
49
|
-
Evaluated e = evalSrc("surface(file=\"" + path.
|
|
49
|
+
Evaluated e = evalSrc("surface(file=\"" + path.generic_string() + "\", center=false);");
|
|
50
50
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
51
51
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
52
52
|
manifold::Box bbox = e.bodies[0].body->BoundingBox();
|
|
@@ -60,7 +60,7 @@ TEST(Surface, DatFileHeightsMatchExactVertexPositions) {
|
|
|
60
60
|
TEST(Surface, CenterTrueOffsetsXyAroundOrigin) {
|
|
61
61
|
const auto path = tempPath("terrain_center.dat");
|
|
62
62
|
writeDat(path, {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}});
|
|
63
|
-
Evaluated e = evalSrc("surface(file=\"" + path.
|
|
63
|
+
Evaluated e = evalSrc("surface(file=\"" + path.generic_string() + "\", center=true);");
|
|
64
64
|
manifold::Box bbox = e.bodies[0].body->BoundingBox();
|
|
65
65
|
EXPECT_NEAR(bbox.min.x, -1.0, 1e-9); // (cols-1)/2 = 1
|
|
66
66
|
EXPECT_NEAR(bbox.max.x, 1.0, 1e-9);
|
|
@@ -70,7 +70,7 @@ TEST(Surface, CenterTrueOffsetsXyAroundOrigin) {
|
|
|
70
70
|
TEST(Surface, FlatGridVolumeMatchesFootprintTimesHeight) {
|
|
71
71
|
const auto path = tempPath("flat.dat");
|
|
72
72
|
writeDat(path, {{3, 3, 3}, {3, 3, 3}, {3, 3, 3}});
|
|
73
|
-
Evaluated e = evalSrc("surface(file=\"" + path.
|
|
73
|
+
Evaluated e = evalSrc("surface(file=\"" + path.generic_string() + "\");");
|
|
74
74
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
75
75
|
EXPECT_NEAR(e.bodies[0].body->Volume(), 2.0 * 2.0 * 3.0, 1e-6); // (cols-1)*(rows-1)*height
|
|
76
76
|
std::filesystem::remove(path);
|
|
@@ -80,7 +80,7 @@ TEST(Surface, EmptyFileErrors) {
|
|
|
80
80
|
const auto path = tempPath("empty.dat");
|
|
81
81
|
writeDat(path, {});
|
|
82
82
|
Evaluator ev;
|
|
83
|
-
auto ast = parseSrc("surface(file=\"" + path.
|
|
83
|
+
auto ast = parseSrc("surface(file=\"" + path.generic_string() + "\");");
|
|
84
84
|
auto scope = oscad::buildScopes(ast);
|
|
85
85
|
EvalContext ctx = EvalContext::makeRoot(scope.get());
|
|
86
86
|
EXPECT_THROW(ev.resolveTree(ast, ctx), EvalError);
|
|
@@ -92,7 +92,7 @@ TEST(Surface, EmptyFileErrors) {
|
|
|
92
92
|
TEST(Surface, UniformGrayImageVolumeMatchesLuminanceFormula) {
|
|
93
93
|
const auto path = tempPath("flat.png");
|
|
94
94
|
writeGrayscalePng(path, 3, 3, std::vector<unsigned char>(9, 128));
|
|
95
|
-
Evaluated e = evalSrc("surface(file=\"" + path.
|
|
95
|
+
Evaluated e = evalSrc("surface(file=\"" + path.generic_string() + "\");");
|
|
96
96
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
97
97
|
// gray=128 (r=g=b, so the weighted luminance formula reduces to the
|
|
98
98
|
// input value exactly) -> height = 128/255*100.
|
|
@@ -104,8 +104,8 @@ TEST(Surface, UniformGrayImageVolumeMatchesLuminanceFormula) {
|
|
|
104
104
|
TEST(Surface, InvertFlipsTheHeightMapping) {
|
|
105
105
|
const auto path = tempPath("flat2.png");
|
|
106
106
|
writeGrayscalePng(path, 3, 3, std::vector<unsigned char>(9, 200));
|
|
107
|
-
Evaluated normal = evalSrc("surface(file=\"" + path.
|
|
108
|
-
Evaluated inverted = evalSrc("surface(file=\"" + path.
|
|
107
|
+
Evaluated normal = evalSrc("surface(file=\"" + path.generic_string() + "\", invert=false);");
|
|
108
|
+
Evaluated inverted = evalSrc("surface(file=\"" + path.generic_string() + "\", invert=true);");
|
|
109
109
|
const double heightNormal = 200.0 / 255.0 * 100.0;
|
|
110
110
|
const double heightInverted = (255.0 - 200.0) / 255.0 * 100.0;
|
|
111
111
|
EXPECT_NEAR(normal.bodies[0].body->Volume(), 2.0 * 2.0 * heightNormal, heightNormal * 2e-3);
|
|
@@ -121,7 +121,7 @@ TEST(Surface, ImageRowOrderMatchesBottomRowIsYZero) {
|
|
|
121
121
|
const auto path = tempPath("rowcheck.png");
|
|
122
122
|
std::vector<unsigned char> px = {0, 0, 255, 255}; // row0: black,black ; row1: white,white
|
|
123
123
|
writeGrayscalePng(path, 2, 2, px);
|
|
124
|
-
Evaluated e = evalSrc("surface(file=\"" + path.
|
|
124
|
+
Evaluated e = evalSrc("surface(file=\"" + path.generic_string() + "\");");
|
|
125
125
|
ASSERT_TRUE(e.bodies[0].body.has_value());
|
|
126
126
|
// Slice a thin box at low Y (y in [0,0.5]) and confirm it reaches the
|
|
127
127
|
// white row's full height (100), not the black row's height (0).
|