openscad-cpp-evaluator 1.50.2__tar.gz → 1.51.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/CLAUDE.md +25 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/colored_body.hpp +5 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/evaluator.hpp +6 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/export.hpp +4 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/CMakeLists.txt +1 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/builtins.hpp +5 -0
- openscad_cpp_evaluator-1.51.0/src/builtins/export_as.cpp +87 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/function_builtins.cpp +1 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/registry.cpp +3 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/colored_body.cpp +1 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/csg_resolve.cpp +1 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/export.cpp +63 -8
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/CMakeLists.txt +1 -0
- openscad_cpp_evaluator-1.51.0/tests/test_export_as.cpp +108 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/cmake/patch_manifold.cmake +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/LICENSE +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/reassign.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/alpha_wrap.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_alpha_wrap.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_openscad_parity.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_undef_args.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/third_party/predicates/predicates.c +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/third_party/predicates/predicates.h +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/uv.lock +0 -0
|
@@ -2012,3 +2012,28 @@ warning). A non-positive or non-numeric `alpha`/`offset` warns and leaves the ch
|
|
|
2012
2012
|
faces). Time follows OUTPUT size. Not done: CGAL's manifold post-pass for very thin features
|
|
2013
2013
|
(no failure seen yet), and the same input scaled can differ by a near-tie or two (same shape,
|
|
2014
2014
|
volume within 0.2%), which is why `DefaultsScaleWithTheModel` compares within tolerances.
|
|
2015
|
+
|
|
2016
|
+
## `export_as()`
|
|
2017
|
+
|
|
2018
|
+
`export_as("name") { ... }` names its children's geometry as one object in a file that holds several
|
|
2019
|
+
(BelfrySCAD #918; `supported_feature("export-as")` is 1). In 3MF it is the `<object name="...">`
|
|
2020
|
+
attribute, in OBJ the `o` line (whitespace becomes `_`), in AMF `<metadata type="name">`; the other
|
|
2021
|
+
formats have no object names and ignore it. Geometry outside any `export_as()` is named as before.
|
|
2022
|
+
|
|
2023
|
+
- **The name rides on the body** (`ColoredBody::exportName`), so everything that copies its
|
|
2024
|
+
children's bodies carries it: transforms, `color()`, the modifiers, `render()`, `profile_time()`,
|
|
2025
|
+
user modules. An op that **builds** a new body (any boolean, hull, extrude, ...) drops it, and
|
|
2026
|
+
`checkExportNames` warns about an `export_as()` inside one, read off the resolved tree so a
|
|
2027
|
+
ManifoldCache hit warns the same. An inner `export_as()` keeps its name; the outer one names only
|
|
2028
|
+
what is still unnamed.
|
|
2029
|
+
- **Export** (`splitBodiesForExport`): the name is part of the object key, so a named part is its own
|
|
2030
|
+
object whatever the colour options say, and two touching same-coloured parts no longer weld. With
|
|
2031
|
+
colours split, colour still keys inside a name. A named part is **always** split into its connected
|
|
2032
|
+
pieces, whatever `splitComponents` says, and a name that ends up as several objects (pieces,
|
|
2033
|
+
colours, an open shell beside a solid) is numbered `name_1`, `name_2`, ... so every object stays
|
|
2034
|
+
told apart. The same name on two `export_as()` calls warns and merges them into one part, so
|
|
2035
|
+
touching uses weld and disjoint ones are numbered pieces.
|
|
2036
|
+
- A missing or empty name warns and leaves the children unnamed. Not upstream: OpenSCAD has no
|
|
2037
|
+
`export_as()` and drops an unknown module's children, so a portable script guards on
|
|
2038
|
+
`supported_feature("export-as")`.
|
|
2039
|
+
- `src/builtins/export_as.cpp`; tests in `tests/test_export_as.cpp`.
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <array>
|
|
9
9
|
#include <memory>
|
|
10
10
|
#include <optional>
|
|
11
|
+
#include <string>
|
|
11
12
|
#include <vector>
|
|
12
13
|
|
|
13
14
|
namespace oscadeval {
|
|
@@ -92,6 +93,10 @@ struct ColoredBody {
|
|
|
92
93
|
manifold::mat3x4 sectionXform{manifold::vec3(1, 0, 0), manifold::vec3(0, 1, 0),
|
|
93
94
|
manifold::vec3(0, 0, 1), manifold::vec3(0, 0, 0)};
|
|
94
95
|
BodyRole role = BodyRole::Normal;
|
|
96
|
+
// The name export_as() gave this body: the object it becomes in a file
|
|
97
|
+
// that holds several (splitBodiesForExport). Copied along by everything
|
|
98
|
+
// that copies the body; an op that builds a new body drops it.
|
|
99
|
+
std::optional<std::string> exportName;
|
|
95
100
|
std::optional<std::vector<std::array<float, 4>>> triColors; // per-triangle RGBA, multi-color CSG merges only
|
|
96
101
|
|
|
97
102
|
// The operands a union() merged into this body, kept unmerged, each as
|
|
@@ -620,6 +620,12 @@ public:
|
|
|
620
620
|
// definition for why this cannot be done by tagging bodies.
|
|
621
621
|
void rerootAtShowOnly(std::vector<std::unique_ptr<CSGNode>>& tree);
|
|
622
622
|
|
|
623
|
+
// Warns about an export_as() whose name cannot reach the file: one
|
|
624
|
+
// inside an operation that merges it with its siblings, or a name used
|
|
625
|
+
// by more than one export_as(). Read off the resolved tree, so a
|
|
626
|
+
// ManifoldCache hit says the same as a fresh build. See export_as.cpp.
|
|
627
|
+
void checkExportNames(const std::vector<std::unique_ptr<CSGNode>>& tree);
|
|
628
|
+
|
|
623
629
|
// parent_module(idx) support: walks the live module-call stack
|
|
624
630
|
// (innermost last) and returns the name `idx` levels up from the
|
|
625
631
|
// current module, or undef if out of range. Public because
|
|
@@ -22,6 +22,10 @@ struct ExportObject {
|
|
|
22
22
|
std::vector<uint32_t> tris; // vertex-index triples
|
|
23
23
|
std::array<float, 4> color = kDefaultExportColor;
|
|
24
24
|
std::vector<std::array<float, 4>> triColors;
|
|
25
|
+
// export_as()'s name, numbered "name_1", "name_2", ... when the part
|
|
26
|
+
// comes out as several objects. Empty for geometry no export_as()
|
|
27
|
+
// named; each writer then names it as it always has.
|
|
28
|
+
std::string name;
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
// The implicit top-level union, cut into objects that never overlap.
|
|
@@ -203,6 +203,11 @@ CSGParams resolveAlphaWrap(Evaluator& ev, const oscad::ModularCall& node, EvalCo
|
|
|
203
203
|
std::vector<ColoredBody> generateAlphaWrap(Evaluator& ev, const CSGParams& params,
|
|
204
204
|
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
205
205
|
const oscad::ASTNode& node);
|
|
206
|
+
// export_as(name) -- names its children's object in an export (export_as.cpp).
|
|
207
|
+
CSGParams resolveExportAs(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
208
|
+
std::vector<ColoredBody> generateExportAs(Evaluator& ev, const CSGParams& params,
|
|
209
|
+
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
210
|
+
const oscad::ASTNode& node);
|
|
206
211
|
CSGParams resolveSimplify(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
|
|
207
212
|
std::vector<ColoredBody> generateSimplify(Evaluator& ev, const CSGParams& params,
|
|
208
213
|
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#include "builtins.hpp"
|
|
2
|
+
|
|
3
|
+
#include "openscad_cpp_evaluator/call_args.hpp"
|
|
4
|
+
#include "openscad_cpp_evaluator/evaluator.hpp"
|
|
5
|
+
|
|
6
|
+
#include <map>
|
|
7
|
+
#include <set>
|
|
8
|
+
|
|
9
|
+
namespace oscadeval {
|
|
10
|
+
|
|
11
|
+
// export_as("name") { ... } -- names the geometry of its children as one
|
|
12
|
+
// object in a file that holds several (3MF, OBJ, AMF); see
|
|
13
|
+
// splitBodiesForExport. The name rides on ColoredBody::exportName, which
|
|
14
|
+
// every transform, color() and modifier carries along because they copy the
|
|
15
|
+
// body. An inner export_as() keeps its own name: only unnamed bodies take
|
|
16
|
+
// this one.
|
|
17
|
+
CSGParams resolveExportAs(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
|
|
18
|
+
auto [args, effCtx] = resolveCallArgs(ev, node.arguments, ctx);
|
|
19
|
+
CSGParams params;
|
|
20
|
+
const Value name = getArg(args, 0, "name");
|
|
21
|
+
const std::string* s = std::get_if<std::string>(&name);
|
|
22
|
+
if (s && !s->empty()) params["name"] = *s;
|
|
23
|
+
else ev.warn("export_as() needs a non-empty name string; its children are exported unnamed", &node.position());
|
|
24
|
+
EvalContext blockCtx = ev.blockScope(effCtx);
|
|
25
|
+
ev.evalChildren(node.children, blockCtx);
|
|
26
|
+
return params;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
std::vector<ColoredBody> generateExportAs(Evaluator&, const CSGParams& params,
|
|
30
|
+
const std::vector<std::unique_ptr<CSGNode>>& children,
|
|
31
|
+
const oscad::ASTNode&) {
|
|
32
|
+
std::vector<ColoredBody> result = flattenCsgTree(children);
|
|
33
|
+
auto it = params.find("name");
|
|
34
|
+
if (it == params.end()) return result;
|
|
35
|
+
const std::string& name = std::get<std::string>(it->second);
|
|
36
|
+
for (ColoredBody& b : result) {
|
|
37
|
+
if (!b.exportName) b.exportName = name;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
namespace {
|
|
43
|
+
|
|
44
|
+
// The builtins whose result is their children's own bodies, copied (so an
|
|
45
|
+
// exportName survives them). Every other builtin builds new bodies from its
|
|
46
|
+
// children and drops the name.
|
|
47
|
+
bool keepsChildBodies(const CSGNode& n) {
|
|
48
|
+
static const std::set<std::string, std::less<>> kinds = {
|
|
49
|
+
"translate", "rotate", "scale", "mirror", "multmatrix", "resize", "color", "highlight",
|
|
50
|
+
"background", "show_only", "render", "profile_time", "export_as", "children",
|
|
51
|
+
};
|
|
52
|
+
return !n.isBuiltin || kinds.count(n.kind) > 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void walkExportAs(Evaluator& ev, const std::vector<std::unique_ptr<CSGNode>>& nodes, const CSGNode* merger,
|
|
56
|
+
std::map<std::string, int>& uses) {
|
|
57
|
+
for (const std::unique_ptr<CSGNode>& c : nodes) {
|
|
58
|
+
const CSGNode* childMerger = merger;
|
|
59
|
+
if (c->isBuiltin && c->kind == "export_as") {
|
|
60
|
+
auto it = c->params.find("name");
|
|
61
|
+
if (it != c->params.end() && c->node) {
|
|
62
|
+
const std::string& name = std::get<std::string>(it->second);
|
|
63
|
+
if (merger) {
|
|
64
|
+
ev.warn("export_as(\"" + name + "\") is inside " + merger->kind + "(), which merges it with " +
|
|
65
|
+
"its siblings, so the name is lost",
|
|
66
|
+
&c->node->position());
|
|
67
|
+
} else if (++uses[name] == 2) {
|
|
68
|
+
ev.warn("export_as(\"" + name + "\") is used more than once; those parts are merged into one " +
|
|
69
|
+
"part named \"" + name + "\"",
|
|
70
|
+
&c->node->position());
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else if (!merger && !keepsChildBodies(*c)) {
|
|
74
|
+
childMerger = c.get();
|
|
75
|
+
}
|
|
76
|
+
walkExportAs(ev, c->children, childMerger, uses);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
} // namespace
|
|
81
|
+
|
|
82
|
+
void Evaluator::checkExportNames(const std::vector<std::unique_ptr<CSGNode>>& tree) {
|
|
83
|
+
std::map<std::string, int> uses;
|
|
84
|
+
walkExportAs(*this, tree, nullptr, uses);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
} // namespace oscadeval
|
{openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/src/builtins/function_builtins.cpp
RENAMED
|
@@ -1002,6 +1002,7 @@ const std::unordered_map<std::string, double>& featureLevels() {
|
|
|
1002
1002
|
{"discretization-by-error", 1.0}, // $fe, always on (upstream: behind --enable)
|
|
1003
1003
|
{"profile-time", 1.0}, // profile_time(label) { ... } and profile_time(label) expr
|
|
1004
1004
|
{"alpha-wrap", 1.0}, // alpha_wrap(alpha, offset)
|
|
1005
|
+
{"export-as", 1.0}, // export_as(name) { ... }
|
|
1005
1006
|
};
|
|
1006
1007
|
return levels;
|
|
1007
1008
|
}
|
|
@@ -40,6 +40,7 @@ const std::unordered_map<std::string_view, ResolveFn>& resolveDispatch() {
|
|
|
40
40
|
{"simplify", &resolveSimplify},
|
|
41
41
|
{"mesh_repair", &resolveMeshRepair},
|
|
42
42
|
{"alpha_wrap", &resolveAlphaWrap},
|
|
43
|
+
{"export_as", &resolveExportAs},
|
|
43
44
|
{"levelset", &resolveLevelSet},
|
|
44
45
|
{"offset", &resolveOffset},
|
|
45
46
|
{"surface", &resolveSurface},
|
|
@@ -84,6 +85,7 @@ const std::unordered_map<std::string_view, GenerateFn>& generateDispatch() {
|
|
|
84
85
|
{"simplify", &generateSimplify},
|
|
85
86
|
{"mesh_repair", &generateMeshRepair},
|
|
86
87
|
{"alpha_wrap", &generateAlphaWrap},
|
|
88
|
+
{"export_as", &generateExportAs},
|
|
87
89
|
{"levelset", &generateLevelSet},
|
|
88
90
|
{"offset", &generateOffset},
|
|
89
91
|
{"surface", &generateSurface},
|
|
@@ -138,6 +140,7 @@ const std::vector<std::string>* builtinParamNames(const std::string& name) {
|
|
|
138
140
|
{"simplify", {"tolerance"}},
|
|
139
141
|
{"mesh_repair", {"tolerance"}},
|
|
140
142
|
{"alpha_wrap", {"alpha", "offset"}},
|
|
143
|
+
{"export_as", {"name"}},
|
|
141
144
|
{"levelset", {"field", "bounds", "isovalue", "invert", "edge"}},
|
|
142
145
|
{"offset", {"r", "delta", "chamfer"}},
|
|
143
146
|
{"surface", {"file", "center", "convexity", "invert"}},
|
|
@@ -62,6 +62,7 @@ std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodi
|
|
|
62
62
|
flat.section = cb.section;
|
|
63
63
|
flat.sectionXform = cb.sectionXform;
|
|
64
64
|
flat.role = cb.role;
|
|
65
|
+
flat.exportName = cb.exportName;
|
|
65
66
|
out.push_back(std::move(flat));
|
|
66
67
|
} else {
|
|
67
68
|
out.push_back(cb);
|
|
@@ -293,6 +293,7 @@ std::vector<ColoredBody> Evaluator::evaluateImpl(const NodeList& nodes, EvalCont
|
|
|
293
293
|
} generateRequestedGuard{generateRequested_};
|
|
294
294
|
std::vector<std::unique_ptr<CSGNode>> tree = resolveTreeImpl(nodes, ctx);
|
|
295
295
|
rerootAtShowOnly(tree);
|
|
296
|
+
checkExportNames(tree);
|
|
296
297
|
const Clock::time_point resolveEnd = profiling_ ? Clock::now() : Clock::time_point{};
|
|
297
298
|
// generate = false is the resolve-only path: the language has run and
|
|
298
299
|
// the tree is built, so anything the script itself gets wrong has already
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
#include <manifold/manifold.h>
|
|
9
9
|
|
|
10
10
|
#include <algorithm>
|
|
11
|
+
#include <cctype>
|
|
11
12
|
#include <cmath>
|
|
12
13
|
#include <cstdint>
|
|
13
14
|
#include <cstdio>
|
|
14
15
|
#include <ctime>
|
|
15
16
|
#include <fstream>
|
|
16
17
|
#include <locale>
|
|
18
|
+
#include <map>
|
|
17
19
|
#include <sstream>
|
|
18
20
|
#include <optional>
|
|
19
21
|
#include <stdexcept>
|
|
@@ -103,6 +105,21 @@ void writeStl(const std::string& path, const std::vector<ColoredBody>& bodies) {
|
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
// An export_as() name as XML attribute or element text.
|
|
109
|
+
static std::string xmlEscape(const std::string& s) {
|
|
110
|
+
std::string out;
|
|
111
|
+
for (char c : s) {
|
|
112
|
+
switch (c) {
|
|
113
|
+
case '&': out += "&"; break;
|
|
114
|
+
case '<': out += "<"; break;
|
|
115
|
+
case '>': out += ">"; break;
|
|
116
|
+
case '"': out += """; break;
|
|
117
|
+
default: out += c;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
|
|
106
123
|
void writeObj(const std::string& path, const std::vector<ExportObject>& objects) {
|
|
107
124
|
// OBJ carries no colour of its own: `usemtl` names an entry in a .mtl
|
|
108
125
|
// sitting next to the .obj, so an OBJ export writes TWO files. A reader
|
|
@@ -140,7 +157,16 @@ void writeObj(const std::string& path, const std::vector<ExportObject>& objects)
|
|
|
140
157
|
size_t objIndex = 0;
|
|
141
158
|
for (const ExportObject& o : objects) {
|
|
142
159
|
++objIndex;
|
|
143
|
-
|
|
160
|
+
if (o.name.empty()) {
|
|
161
|
+
out << "o object_" << objIndex << "\n";
|
|
162
|
+
} else {
|
|
163
|
+
// An OBJ name runs to the end of the line, and readers split it
|
|
164
|
+
// at whitespace.
|
|
165
|
+
std::string name = o.name;
|
|
166
|
+
for (char& c : name)
|
|
167
|
+
if (std::isspace(static_cast<unsigned char>(c))) c = '_';
|
|
168
|
+
out << "o " << name << "\n";
|
|
169
|
+
}
|
|
144
170
|
const size_t vertCount = o.verts.size() / 3;
|
|
145
171
|
for (size_t v = 0; v < vertCount; ++v) {
|
|
146
172
|
out << "v " << formatG6(o.verts[v * 3]) << " " << formatG6(o.verts[v * 3 + 1]) << " "
|
|
@@ -265,7 +291,9 @@ void writeThreeMf(const std::string& path, const std::vector<ExportObject>& obje
|
|
|
265
291
|
resources += "</m:colorgroup>";
|
|
266
292
|
|
|
267
293
|
const int objectId = nextId++;
|
|
268
|
-
resources += "<object id=\"" + std::to_string(objectId) + "\" type=\"model\"
|
|
294
|
+
resources += "<object id=\"" + std::to_string(objectId) + "\" type=\"model\"";
|
|
295
|
+
if (!o.name.empty()) resources += " name=\"" + xmlEscape(o.name) + "\"";
|
|
296
|
+
resources += " pid=\"" +
|
|
269
297
|
std::to_string(colorGroupId) + "\" pindex=\"0\"><mesh><vertices>";
|
|
270
298
|
const size_t vertCount = o.verts.size() / 3;
|
|
271
299
|
for (size_t v = 0; v < vertCount; ++v) {
|
|
@@ -374,13 +402,21 @@ bool boxesOverlap(const manifold::Box& ba, const manifold::Box& bb) {
|
|
|
374
402
|
// A colour key that keeps per-triangle-coloured bodies apart from
|
|
375
403
|
// everything, including each other. Their colours index their own triangle
|
|
376
404
|
// list, and a union would rewrite that list and lose them.
|
|
405
|
+
//
|
|
406
|
+
// An export_as() name keys too: a named part is its own object whatever
|
|
407
|
+
// the colour options say. With colours not split (`byColor` false), the
|
|
408
|
+
// name is all that keys.
|
|
377
409
|
struct ColorKey {
|
|
378
410
|
bool perTriangle = false;
|
|
379
411
|
size_t index = 0; // position in `solids`, for the per-triangle case
|
|
380
412
|
bool hasColor = false;
|
|
381
413
|
std::array<float, 4> color{};
|
|
414
|
+
std::optional<std::string> name;
|
|
415
|
+
bool byColor = true;
|
|
382
416
|
|
|
383
417
|
bool operator==(const ColorKey& o) const {
|
|
418
|
+
if (name != o.name) return false;
|
|
419
|
+
if (!byColor) return true;
|
|
384
420
|
if (perTriangle != o.perTriangle) return false;
|
|
385
421
|
if (perTriangle) return index == o.index;
|
|
386
422
|
if (hasColor != o.hasColor) return false;
|
|
@@ -476,6 +512,7 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
476
512
|
std::optional<std::array<float, 4>> color;
|
|
477
513
|
std::vector<std::array<float, 4>> triColors;
|
|
478
514
|
std::vector<uint32_t> tris;
|
|
515
|
+
std::optional<std::string> name;
|
|
479
516
|
};
|
|
480
517
|
|
|
481
518
|
std::vector<Solid> solids;
|
|
@@ -503,6 +540,7 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
503
540
|
if (obj.tris.empty()) continue;
|
|
504
541
|
obj.color = cb.color.value_or(kDefaultExportColor);
|
|
505
542
|
if (cb.triColors) obj.triColors = resolveThemeColors(*cb.triColors);
|
|
543
|
+
obj.name = cb.exportName.value_or("");
|
|
506
544
|
loose.push_back(std::move(obj));
|
|
507
545
|
if (openParts) openParts->push_back(index);
|
|
508
546
|
continue;
|
|
@@ -511,6 +549,7 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
511
549
|
Solid s;
|
|
512
550
|
s.man = *cb.body;
|
|
513
551
|
s.color = cb.color;
|
|
552
|
+
s.name = cb.exportName;
|
|
514
553
|
if (cb.triColors) s.triColors = resolveThemeColors(*cb.triColors);
|
|
515
554
|
s.tris = s.man.GetMeshGL().triVerts;
|
|
516
555
|
if (s.tris.empty()) continue;
|
|
@@ -527,6 +566,8 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
527
566
|
k.index = i;
|
|
528
567
|
k.hasColor = solids[i].color.has_value();
|
|
529
568
|
if (k.hasColor) k.color = *solids[i].color;
|
|
569
|
+
k.name = solids[i].name;
|
|
570
|
+
k.byColor = splitColors;
|
|
530
571
|
keys.push_back(k);
|
|
531
572
|
}
|
|
532
573
|
// Splitting by colour is for a MULTI-MATERIAL print, where each
|
|
@@ -536,7 +577,7 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
536
577
|
// separate walls. Unioning everything here (rather than
|
|
537
578
|
// concatenating the per-colour objects afterwards) is what makes
|
|
538
579
|
// touching regions weld instead of leaving coincident faces.
|
|
539
|
-
const bool allSame =
|
|
580
|
+
const bool allSame =
|
|
540
581
|
std::all_of(keys.begin(), keys.end(), [&](const ColorKey& k) { return k == keys[0]; });
|
|
541
582
|
|
|
542
583
|
if (allSame) {
|
|
@@ -597,7 +638,7 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
597
638
|
Claimed c;
|
|
598
639
|
c.man = std::move(piece);
|
|
599
640
|
c.color = s.color;
|
|
600
|
-
c.triColors = s.triColors;
|
|
641
|
+
if (splitColors) c.triColors = s.triColors;
|
|
601
642
|
c.sourceTris = s.tris;
|
|
602
643
|
c.key = keys[n];
|
|
603
644
|
owned.push_back(std::move(c));
|
|
@@ -623,10 +664,12 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
623
664
|
for (const Claimed& g : claimedGroups) {
|
|
624
665
|
// Decompose() is the rule-3 split, and it is opt-in: without it this
|
|
625
666
|
// colour group stays one object however many disjoint pieces it is
|
|
626
|
-
// in, which is what OpenSCAD writes. A
|
|
627
|
-
//
|
|
667
|
+
// in, which is what OpenSCAD writes. A named part always splits: its
|
|
668
|
+
// pieces are numbered below, so they stay one part by name. A
|
|
669
|
+
// single-component solid comes back as a one-element list either
|
|
670
|
+
// way, so there is no special case.
|
|
628
671
|
std::vector<manifold::Manifold> parts;
|
|
629
|
-
if (splitComponents) parts = g.man.Decompose();
|
|
672
|
+
if (splitComponents || g.key.name) parts = g.man.Decompose();
|
|
630
673
|
if (parts.empty()) parts.push_back(g.man);
|
|
631
674
|
for (const manifold::Manifold& part : parts) {
|
|
632
675
|
if (part.IsEmpty()) continue;
|
|
@@ -635,10 +678,20 @@ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& b
|
|
|
635
678
|
if (obj.tris.empty()) continue;
|
|
636
679
|
obj.color = g.color.value_or(kDefaultExportColor);
|
|
637
680
|
obj.triColors = carryTriColors(g.triColors, g.sourceTris, obj.tris);
|
|
681
|
+
obj.name = g.key.name.value_or("");
|
|
638
682
|
out.push_back(std::move(obj));
|
|
639
683
|
}
|
|
640
684
|
}
|
|
641
685
|
out.insert(out.end(), std::make_move_iterator(loose.begin()), std::make_move_iterator(loose.end()));
|
|
686
|
+
|
|
687
|
+
// A name that came out as several objects -- disconnected pieces,
|
|
688
|
+
// colours, an open shell beside a solid -- is numbered, so every object
|
|
689
|
+
// in the file is still told apart by name.
|
|
690
|
+
std::map<std::string, int> total, seen;
|
|
691
|
+
for (const ExportObject& o : out)
|
|
692
|
+
if (!o.name.empty()) ++total[o.name];
|
|
693
|
+
for (ExportObject& o : out)
|
|
694
|
+
if (!o.name.empty() && total[o.name] > 1) o.name += "_" + std::to_string(++seen[o.name]);
|
|
642
695
|
return out;
|
|
643
696
|
}
|
|
644
697
|
|
|
@@ -924,7 +977,9 @@ void writeAmf(const std::string& path, const std::vector<ExportObject>& objects)
|
|
|
924
977
|
}
|
|
925
978
|
for (size_t oi = 0; oi < objects.size(); ++oi) {
|
|
926
979
|
const ExportObject& o = objects[oi];
|
|
927
|
-
out << " <object id=\"" << (oi + 1) << "\">\n
|
|
980
|
+
out << " <object id=\"" << (oi + 1) << "\">\n";
|
|
981
|
+
if (!o.name.empty()) out << " <metadata type=\"name\">" << xmlEscape(o.name) << "</metadata>\n";
|
|
982
|
+
out << " <mesh>\n <vertices>\n";
|
|
928
983
|
for (size_t v = 0; v < o.verts.size() / 3; ++v) {
|
|
929
984
|
out << " <vertex><coordinates><x>" << formatG6(o.verts[v * 3]) << "</x><y>"
|
|
930
985
|
<< formatG6(o.verts[v * 3 + 1]) << "</y><z>" << formatG6(o.verts[v * 3 + 2])
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#include "openscad_cpp_evaluator/export.hpp"
|
|
2
|
+
|
|
3
|
+
#include "test_helpers.hpp"
|
|
4
|
+
|
|
5
|
+
#include <filesystem>
|
|
6
|
+
#include <fstream>
|
|
7
|
+
#include <gtest/gtest.h>
|
|
8
|
+
#include <sstream>
|
|
9
|
+
|
|
10
|
+
using namespace oscadeval;
|
|
11
|
+
using namespace oscadeval::test;
|
|
12
|
+
|
|
13
|
+
namespace {
|
|
14
|
+
|
|
15
|
+
std::vector<std::string> namesOf(const std::vector<ExportObject>& objs) {
|
|
16
|
+
std::vector<std::string> out;
|
|
17
|
+
for (const ExportObject& o : objs) out.push_back(o.name);
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
std::vector<std::string> split(const std::string& code, bool components = false, bool colors = true) {
|
|
22
|
+
Evaluated e = evaluateSrc(code);
|
|
23
|
+
return namesOf(splitBodiesForExport(e.bodies, nullptr, components, colors));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
std::vector<std::string> warningsOf(const std::string& code) {
|
|
27
|
+
std::vector<std::string> log;
|
|
28
|
+
evaluateSrc(code, [&](const std::string& m) { log.push_back(m); });
|
|
29
|
+
return log;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
std::string slurp(const std::filesystem::path& p) {
|
|
33
|
+
std::ifstream in(p);
|
|
34
|
+
std::stringstream ss;
|
|
35
|
+
ss << in.rdbuf();
|
|
36
|
+
return ss.str();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
} // namespace
|
|
40
|
+
|
|
41
|
+
TEST(ExportAs, TouchingNamedPartsStaySeparate) {
|
|
42
|
+
// Same colour, sharing a face: without names these weld into one object.
|
|
43
|
+
EXPECT_EQ(split(R"(export_as("jar") cube(10); export_as("lid") translate([10,0,0]) cube(10);)"),
|
|
44
|
+
(std::vector<std::string>{"jar", "lid"}));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
TEST(ExportAs, NameSurvivesTransformsAndColor) {
|
|
48
|
+
EXPECT_EQ(split(R"(translate([5,0,0]) color("red") export_as("jar") rotate(10) cube(10);)"),
|
|
49
|
+
(std::vector<std::string>{"jar"}));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
TEST(ExportAs, UnnamedGeometryKeepsAutomaticNaming) {
|
|
53
|
+
EXPECT_EQ(split(R"(export_as("jar") cube(10); translate([20,0,0]) cube(10);)"),
|
|
54
|
+
(std::vector<std::string>{"jar", ""}));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
TEST(ExportAs, NamedPartIsOneObjectEvenWithColorsNotSplit) {
|
|
58
|
+
EXPECT_EQ(split(R"(export_as("jar") cube(10); export_as("lid") translate([10,0,0]) cube(10);)", false, false),
|
|
59
|
+
(std::vector<std::string>{"jar", "lid"}));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
TEST(ExportAs, PiecesOfOnePartAreNumbered) {
|
|
63
|
+
const std::string code = R"(export_as("leg") { cube(1); translate([5,0,0]) cube(1); })";
|
|
64
|
+
// Whatever the components option says: a named part always splits.
|
|
65
|
+
EXPECT_EQ(split(code), (std::vector<std::string>{"leg_1", "leg_2"}));
|
|
66
|
+
EXPECT_EQ(split(code, /*components=*/true), (std::vector<std::string>{"leg_1", "leg_2"}));
|
|
67
|
+
EXPECT_EQ(split(R"(export_as("leg") cube(1);)"), (std::vector<std::string>{"leg"}));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
TEST(ExportAs, InnerNameWins) {
|
|
71
|
+
EXPECT_EQ(split(R"(export_as("kit") { export_as("jar") cube(1); translate([5,0,0]) cube(1); })"),
|
|
72
|
+
(std::vector<std::string>{"jar", "kit"}));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
TEST(ExportAs, NameInsideAMergingOperationWarns) {
|
|
76
|
+
const auto log = warningsOf(R"(union() { export_as("jar") cube(1); cube(2); })");
|
|
77
|
+
EXPECT_TRUE(anyContains(log, "export_as(\"jar\") is inside union()"));
|
|
78
|
+
// Through a user module too: the module is not the merger, union() is.
|
|
79
|
+
EXPECT_TRUE(anyContains(warningsOf(R"(module m() export_as("a") cube(1); difference() { m(); cube(0.5); })"),
|
|
80
|
+
"export_as(\"a\") is inside difference()"));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
TEST(ExportAs, DuplicateNameWarnsAndMerges) {
|
|
84
|
+
const std::string code = R"(export_as("jar") cube(1); export_as("jar") translate([5,0,0]) cube(1);)";
|
|
85
|
+
EXPECT_TRUE(anyContains(warningsOf(code), "export_as(\"jar\") is used more than once"));
|
|
86
|
+
// One name, two disjoint pieces: numbered.
|
|
87
|
+
EXPECT_EQ(split(code), (std::vector<std::string>{"jar_1", "jar_2"}));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
TEST(ExportAs, MissingNameWarns) {
|
|
91
|
+
EXPECT_TRUE(anyContains(warningsOf("export_as() cube(1);"), "export_as() needs a non-empty name string"));
|
|
92
|
+
EXPECT_EQ(split("export_as() cube(1);"), (std::vector<std::string>{""}));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
TEST(ExportAs, WritersCarryTheName) {
|
|
96
|
+
Evaluated e = evaluateSrc(R"(export_as("big jar") cube(10); export_as("a&b") translate([20,0,0]) cube(1);)");
|
|
97
|
+
const auto dir = std::filesystem::temp_directory_path();
|
|
98
|
+
exportModel((dir / "oscad_eval_test_export_as.obj").string(), e.bodies);
|
|
99
|
+
const std::string obj = slurp(dir / "oscad_eval_test_export_as.obj");
|
|
100
|
+
EXPECT_NE(obj.find("o big_jar\n"), std::string::npos);
|
|
101
|
+
exportModel((dir / "oscad_eval_test_export_as.amf").string(), e.bodies);
|
|
102
|
+
const std::string amf = slurp(dir / "oscad_eval_test_export_as.amf");
|
|
103
|
+
EXPECT_NE(amf.find("<metadata type=\"name\">a&b</metadata>"), std::string::npos);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
TEST(ExportAs, FeatureIsAdvertised) {
|
|
107
|
+
EXPECT_TRUE(anyContains(warningsOf(R"(echo(supported_feature("export-as"));)"), "ECHO: 1"));
|
|
108
|
+
}
|
|
File without changes
|
{openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/.github/workflows/wheels.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.50.2 → openscad_cpp_evaluator-1.51.0}/external/openscad_cpp_parser/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|