openscad-cpp-evaluator 1.32.0__tar.gz → 1.34.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/CLAUDE.md +28 -3
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/bindings/module.cpp +22 -3
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/export.hpp +30 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/mesh_import.hpp +9 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/python/openscad_cpp_evaluator/__init__.py +8 -2
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/CMakeLists.txt +1 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/import.cpp +18 -4
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/export.cpp +158 -2
- openscad_cpp_evaluator-1.34.0/src/import/scene_import.cpp +714 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/import/svg_import.cpp +8 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_dxf_svg_import.cpp +44 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_export.cpp +118 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_import_export.cpp +158 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_python_bindings.py +34 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/uv.lock +1 -1
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.32.0 → openscad_cpp_evaluator-1.34.0}/tools/cli/main.cpp +0 -0
|
@@ -1091,8 +1091,8 @@ grep for `ponytail:`.
|
|
|
1091
1091
|
— skip it and the mesh comes out non-manifold at the seam). Self-contained 2D geometry math here
|
|
1092
1092
|
(`dot2`/`len2`/`norm2`, the parabola-canonical-frame rotation in `discretizeArc`) exists nowhere
|
|
1093
1093
|
else in this codebase.
|
|
1094
|
-
- `include/openscad_cpp_evaluator/export.hpp`, `src/export.cpp` — the writers for all
|
|
1095
|
-
formats `exportExtensions()` lists: 3MF, AMF, DXF, PDF, STL, OBJ, OFF, PLY, SVG, VRML, X3D (3MF via
|
|
1094
|
+
- `include/openscad_cpp_evaluator/export.hpp`, `src/export.cpp` — the writers for all twelve
|
|
1095
|
+
formats `exportExtensions()` lists: 3MF, AMF, DXF, PDF, STL, OBJ, OFF, PLY, POV, SVG, VRML, X3D (3MF via
|
|
1096
1096
|
`zip_stored.hpp`'s `writeDeflateZip`). **`exportExtensions()` is the one source of truth for
|
|
1097
1097
|
which formats exist** — the Python facade and BelfrySCAD's dialog/CLI all ask it rather than
|
|
1098
1098
|
restating the list, because three hand-written copies had already drifted far enough that `.off`
|
|
@@ -1120,6 +1120,20 @@ grep for `ponytail:`.
|
|
|
1120
1120
|
binary's, vertex order and 6-vertex line wrap included. A 3D body in the list throws
|
|
1121
1121
|
("Current top level object is not a 2D object"), as OpenSCAD refuses too: there is no projection
|
|
1122
1122
|
to fall back on. `ExportOptions::svg` carries OpenSCAD's five `-O export-svg/...` settings.
|
|
1123
|
+
**`writePov` writes POV-Ray, as `mesh2`** — one per object `splitBodiesForExport` produces, with
|
|
1124
|
+
a welded vertex list, a `texture_list` of the object's colours and a texture index per triangle
|
|
1125
|
+
(so per-triangle colour needs no unwelding, unlike PLY), and `inside_vector` so POV-Ray treats it
|
|
1126
|
+
as a SOLID (the `ior 1.32` interior refracts; CSG works). OpenSCAD's `export_pov.cc` writes every
|
|
1127
|
+
face as its own flat `polygon` object instead. The rest of the scene is OpenSCAD's: header,
|
|
1128
|
+
MATERIAL finish, 27 lights around the bounding box, radiosity from `rad_def.inc`, colour as
|
|
1129
|
+
`rgbf` with filter = 1 − alpha. `ExportPovOptions::camera` ($vpt, $vpr, distance, fov; Python
|
|
1130
|
+
`pov_camera`, 8 numbers) writes OpenSCAD's camera block with **two fixes, both found by rendering
|
|
1131
|
+
in POV-Ray 3.7 and comparing with BelfrySCAD's PNG of the same camera** (they now agree to a
|
|
1132
|
+
pixel): `rotate` comes before `translate`, since the eye orbits `$vpt` (OpenSCAD translates first
|
|
1133
|
+
and frames the wrong place when a view both pans and turns); and the viewport's **vertical** fov
|
|
1134
|
+
becomes POV-Ray's **horizontal** `angle` through an expression on `image_width/image_height`
|
|
1135
|
+
(OpenSCAD writes it across unchanged, zooming its renders in by the aspect ratio). No camera frames
|
|
1136
|
+
the bounding box, as OpenSCAD does without one.
|
|
1123
1137
|
**`writeDxf` is the third 2D writer**, also on `collect2d()`: OpenSCAD's own `export_dxf.cc`
|
|
1124
1138
|
layout verbatim (AC1006 header with the extents, one CONTINUOUS linetype, layer 0, every contour
|
|
1125
1139
|
a closed `LWPOLYLINE` on layer 0 with holes as ordinary contours; 1- and 2-vertex contours as
|
|
@@ -1171,10 +1185,21 @@ grep for `ponytail:`.
|
|
|
1171
1185
|
- `include/openscad_cpp_evaluator/mesh_import.hpp`, `src/import/mesh_import.cpp` — STL (ASCII +
|
|
1172
1186
|
binary, exact-match vertex welding)/OBJ/OFF/3MF mesh loaders, returning plain `(verts, tris)` —
|
|
1173
1187
|
no `Evaluator`/`Value` dependency, so these are reusable from both `import()` contexts below.
|
|
1188
|
+
- `src/import/scene_import.cpp` — AMF, X3D and VRML97 import, the three multi-object formats export
|
|
1189
|
+
writes that nothing could read back (current upstream OpenSCAD removed its AMF importer, so all
|
|
1190
|
+
three go beyond it). Geometry only, like the loaders above, but each format's scene structure is
|
|
1191
|
+
honoured: X3D/VRML `Transform`s nest and apply in full (`T·C·R·SR·S·SR⁻¹·C⁻¹`), `DEF`/`USE`
|
|
1192
|
+
resolves, `ccw FALSE` flips winding, `IndexedFaceSet` polygons fan-triangulate (a last polygon
|
|
1193
|
+
without `-1` counts), and X3D's `IndexedTriangleSet`/`TriangleSet` are read. X3D goes through a
|
|
1194
|
+
small real XML parser (comments, CDATA, DOCTYPE, entities); VRML through a tokenizer + generic
|
|
1195
|
+
node parser that steps over `PROTO`/`EXTERNPROTO`/`ROUTE` (VRML 1.0 is refused by name). AMF's
|
|
1196
|
+
`unit` scales to mm, and a zipped AMF (`PK` header) is read through `readStoredZipEntryBySuffix`.
|
|
1197
|
+
What is not a mesh — primitives (Box, Sphere, ...), `Inline`, AMF constellations — lands in
|
|
1198
|
+
`LoadedMesh::warnings`, which both `import()` faces emit as `import: '<file>': ...`.
|
|
1174
1199
|
- `include/openscad_cpp_evaluator/import_builtin.hpp`, `include/openscad_cpp_evaluator/
|
|
1175
1200
|
zip_stored.hpp` (+ `src/zip_stored.cpp`), `src/builtins/import.cpp` — `import()`'s two faces:
|
|
1176
1201
|
`resolveImport`/`generateImport` (registered in `registry.cpp` like any other builtin *module* —
|
|
1177
|
-
a geometry statement, STL/OBJ/OFF/3MF/DXF/SVG) and `importAsValue` (called directly from
|
|
1202
|
+
a geometry statement, STL/OBJ/OFF/3MF/AMF/X3D/VRML/DXF/SVG) and `importAsValue` (called directly from
|
|
1178
1203
|
`user_calls.cpp`'s `evalFunctionCall`, special-cased *before* the `isBuiltinFunctionName` gate
|
|
1179
1204
|
since `import` isn't in that table — returns a VNF `[[verts],[faces]]` for a mesh file, a Region
|
|
1180
1205
|
`[[[x,y],...],...]` for DXF/SVG, or the JSON file's content as native values).
|
|
@@ -436,14 +436,30 @@ nb::list exportModelPy(const std::string& path, const Geometry& geom, const std:
|
|
|
436
436
|
bool stripSlivers, bool splitComponents, bool splitColors, bool svgFill,
|
|
437
437
|
const std::string& svgFillColor,
|
|
438
438
|
bool svgStroke, const std::string& svgStrokeColor, double svgStrokeWidth,
|
|
439
|
-
nb::object pdfOptions) {
|
|
439
|
+
nb::object pdfOptions, nb::object povCamera) {
|
|
440
440
|
oscadeval::ExportPdfOptions pdf;
|
|
441
441
|
if (!pdfOptions.is_none()) applyPdfOptions(nb::cast<nb::dict>(pdfOptions), pdf);
|
|
442
|
+
oscadeval::ExportPovOptions pov;
|
|
443
|
+
if (!povCamera.is_none()) {
|
|
444
|
+
const std::vector<double> c = nb::cast<std::vector<double>>(povCamera);
|
|
445
|
+
if (c.size() != 8) {
|
|
446
|
+
throw std::runtime_error("pov_camera takes 8 numbers: $vpt x, y, z, $vpr x, y, z, distance, fov");
|
|
447
|
+
}
|
|
448
|
+
oscadeval::ExportPovCamera cam;
|
|
449
|
+
for (int k = 0; k < 3; ++k) {
|
|
450
|
+
cam.vpt[k] = c[k];
|
|
451
|
+
cam.vpr[k] = c[3 + k];
|
|
452
|
+
}
|
|
453
|
+
cam.distance = c[6];
|
|
454
|
+
cam.fov = c[7];
|
|
455
|
+
pov.camera = cam;
|
|
456
|
+
}
|
|
442
457
|
std::vector<std::string> warnings;
|
|
443
458
|
{
|
|
444
459
|
nb::gil_scoped_release rel;
|
|
445
460
|
oscadeval::ExportOptions opts;
|
|
446
461
|
opts.pdf = pdf;
|
|
462
|
+
opts.pov = pov;
|
|
447
463
|
opts.format = format;
|
|
448
464
|
opts.asciiStl = asciiStl;
|
|
449
465
|
opts.stripSlivers = stripSlivers;
|
|
@@ -957,7 +973,7 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
|
|
|
957
973
|
nb::arg("svg_fill") = false,
|
|
958
974
|
nb::arg("svg_fill_color") = std::string("white"), nb::arg("svg_stroke") = true,
|
|
959
975
|
nb::arg("svg_stroke_color") = std::string("black"), nb::arg("svg_stroke_width") = 0.35,
|
|
960
|
-
nb::arg("pdf_options") = nb::none(),
|
|
976
|
+
nb::arg("pdf_options") = nb::none(), nb::arg("pov_camera") = nb::none(),
|
|
961
977
|
"Write `geometry` to `path`, format taken from the extension unless `format` says otherwise. "
|
|
962
978
|
"Returns the warnings to surface (open shells, mesh problems, slivers removed) rather than "
|
|
963
979
|
"logging them. Raises RuntimeError when there is no geometry, the format is unknown, or the "
|
|
@@ -976,7 +992,10 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
|
|
|
976
992
|
"(paper-size, orientation, show-scale, show-scale-message, show-grid, grid-size, "
|
|
977
993
|
"show-filename, design-filename, fill, fill-color, stroke, stroke-color, stroke-width, "
|
|
978
994
|
"add-meta-data, title, author, subject, keywords). An unknown key raises rather than "
|
|
979
|
-
"being ignored. .pdf is 2D-only too, and centres the drawing on a fixed paper size
|
|
995
|
+
"being ignored. .pdf is 2D-only too, and centres the drawing on a fixed paper size.\n\n"
|
|
996
|
+
"pov_camera is .pov's camera as 8 numbers -- $vpt x, y, z, $vpr x, y, z, distance, fov -- "
|
|
997
|
+
"so a POV-Ray render frames what the viewport showed. None frames the model from its "
|
|
998
|
+
"bounding box, as OpenSCAD does without a camera.");
|
|
980
999
|
|
|
981
1000
|
m.def("list_fonts", []() {
|
|
982
1001
|
nb::list out;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
#include <array>
|
|
6
6
|
#include <cstdint>
|
|
7
|
+
#include <optional>
|
|
7
8
|
#include <string>
|
|
8
9
|
#include <vector>
|
|
9
10
|
|
|
@@ -233,6 +234,33 @@ std::vector<std::string> writePdf(const std::string& path, const std::vector<Col
|
|
|
233
234
|
|
|
234
235
|
// -- one entry point ------------------------------------------------------
|
|
235
236
|
|
|
237
|
+
// POV-Ray's camera, as OpenSCAD's viewport states it: $vpt, $vpr, $vpd and
|
|
238
|
+
// the field of view. Without one the scene is framed from the model's
|
|
239
|
+
// bounding box, as OpenSCAD frames it when it has no camera to pass.
|
|
240
|
+
struct ExportPovCamera {
|
|
241
|
+
double vpt[3] = {0, 0, 0};
|
|
242
|
+
double vpr[3] = {0, 0, 0};
|
|
243
|
+
double distance = 0;
|
|
244
|
+
double fov = 22.5;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
struct ExportPovOptions {
|
|
248
|
+
std::optional<ExportPovCamera> camera;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// POV-Ray scene description. Every object splitBodiesForExport produces is
|
|
252
|
+
// one mesh2 -- a welded vertex list, a texture per colour, and a texture
|
|
253
|
+
// index per triangle, so per-triangle colour needs no unwelding -- with
|
|
254
|
+
// inside_vector, which makes it a SOLID to POV-Ray (refraction, CSG). That
|
|
255
|
+
// is the difference from OpenSCAD's export_pov.cc, which writes every face
|
|
256
|
+
// as its own flat polygon object. The rest of the scene is OpenSCAD's: its
|
|
257
|
+
// header, MATERIAL finish and ior 1.32 interior, 27 lights around the
|
|
258
|
+
// bounding box, its camera, and radiosity from rad_def.inc. Colour is rgbf
|
|
259
|
+
// with filter = 1 - alpha, as OpenSCAD writes it. Numbers are the shortest
|
|
260
|
+
// text that round-trips, in the classic locale.
|
|
261
|
+
void writePov(const std::string& path, const std::vector<ExportObject>& objects,
|
|
262
|
+
const ExportPovOptions& opts = {});
|
|
263
|
+
|
|
236
264
|
struct ExportOptions {
|
|
237
265
|
// Empty means "decide from the path's extension".
|
|
238
266
|
std::string format;
|
|
@@ -258,6 +286,8 @@ struct ExportOptions {
|
|
|
258
286
|
ExportSvgOptions svg;
|
|
259
287
|
// .pdf only.
|
|
260
288
|
ExportPdfOptions pdf;
|
|
289
|
+
// .pov only.
|
|
290
|
+
ExportPovOptions pov;
|
|
261
291
|
};
|
|
262
292
|
|
|
263
293
|
// Writes `bodies` to `path`, choosing the writer from the extension (or
|
|
@@ -13,6 +13,9 @@ namespace oscadeval {
|
|
|
13
13
|
struct LoadedMesh {
|
|
14
14
|
std::vector<std::array<double, 3>> verts;
|
|
15
15
|
std::vector<std::array<int, 3>> tris;
|
|
16
|
+
// What the loader read but could not turn into mesh (X3D/VRML primitives,
|
|
17
|
+
// Inline, AMF constellations), for import() to warn about.
|
|
18
|
+
std::vector<std::string> warnings;
|
|
16
19
|
};
|
|
17
20
|
|
|
18
21
|
// Each throws std::runtime_error with a message suitable for wrapping into
|
|
@@ -23,5 +26,11 @@ LoadedMesh loadStl(const std::string& path);
|
|
|
23
26
|
LoadedMesh loadObj(const std::string& path);
|
|
24
27
|
LoadedMesh loadOff(const std::string& path);
|
|
25
28
|
LoadedMesh loadThreeMf(const std::string& path);
|
|
29
|
+
// scene_import.cpp: the three multi-object formats export writes. AMF (plain
|
|
30
|
+
// or zipped, `unit` scaled to mm), X3D and VRML97 (Transforms applied,
|
|
31
|
+
// DEF/USE resolved, polygons fan-triangulated). Geometry only, like the rest.
|
|
32
|
+
LoadedMesh loadAmf(const std::string& path);
|
|
33
|
+
LoadedMesh loadX3d(const std::string& path);
|
|
34
|
+
LoadedMesh loadVrml(const std::string& path);
|
|
26
35
|
|
|
27
36
|
} // namespace oscadeval
|
|
@@ -331,7 +331,8 @@ def export_model(path: str, geometry, format: str = "", ascii_stl: bool = False,
|
|
|
331
331
|
split_colors: bool = True,
|
|
332
332
|
svg_fill: bool = False, svg_fill_color: str = "white",
|
|
333
333
|
svg_stroke: bool = True, svg_stroke_color: str = "black",
|
|
334
|
-
svg_stroke_width: float = 0.35, pdf_options: dict | None = None
|
|
334
|
+
svg_stroke_width: float = 0.35, pdf_options: dict | None = None,
|
|
335
|
+
pov_camera=None) -> list:
|
|
335
336
|
"""Write `geometry` to `path`. Returns the warnings to surface.
|
|
336
337
|
|
|
337
338
|
`geometry` is the handle an Evaluator stashes on itself as
|
|
@@ -374,12 +375,17 @@ def export_model(path: str, geometry, format: str = "", ascii_stl: bool = False,
|
|
|
374
375
|
size with nothing to explain it. `.pdf` is 2D-only like `.svg`, and
|
|
375
376
|
centres the drawing on a fixed paper size instead of cutting the page
|
|
376
377
|
to fit.
|
|
378
|
+
|
|
379
|
+
`pov_camera` is `.pov`'s camera as eight numbers -- `$vpt` x, y, z,
|
|
380
|
+
`$vpr` x, y, z, distance, field of view -- so a POV-Ray render frames
|
|
381
|
+
what the viewport showed. None frames the model from its bounding box,
|
|
382
|
+
as OpenSCAD does when it has no camera to pass.
|
|
377
383
|
"""
|
|
378
384
|
try:
|
|
379
385
|
return list(_ext.export_model(path, geometry, format, ascii_stl, strip_slivers,
|
|
380
386
|
split_components, split_colors, svg_fill, svg_fill_color,
|
|
381
387
|
svg_stroke, svg_stroke_color, svg_stroke_width,
|
|
382
|
-
pdf_options))
|
|
388
|
+
pdf_options, pov_camera))
|
|
383
389
|
except Exception as e:
|
|
384
390
|
raise EvalError(str(e)) from e
|
|
385
391
|
|
|
@@ -46,10 +46,16 @@ LoadedMesh loadMeshByExt(const std::string& path, const std::string& ext) {
|
|
|
46
46
|
if (ext == ".stl") return loadStl(path);
|
|
47
47
|
if (ext == ".obj") return loadObj(path);
|
|
48
48
|
if (ext == ".off") return loadOff(path);
|
|
49
|
+
if (ext == ".amf") return loadAmf(path);
|
|
50
|
+
if (ext == ".x3d") return loadX3d(path);
|
|
51
|
+
if (ext == ".wrl") return loadVrml(path);
|
|
49
52
|
return loadThreeMf(path);
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
bool isMeshExt(const std::string& ext) {
|
|
55
|
+
bool isMeshExt(const std::string& ext) {
|
|
56
|
+
return ext == ".stl" || ext == ".obj" || ext == ".off" || ext == ".3mf" || ext == ".amf" || ext == ".x3d" ||
|
|
57
|
+
ext == ".wrl";
|
|
58
|
+
}
|
|
53
59
|
|
|
54
60
|
|
|
55
61
|
Value jsonToValue(const nlohmann::ordered_json& j) {
|
|
@@ -208,7 +214,10 @@ CSGParams resolveImport(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
208
214
|
params["dxf"] = Value{ext == ".dxf"};
|
|
209
215
|
return params;
|
|
210
216
|
}
|
|
211
|
-
|
|
217
|
+
// .pdf is not here: it used to be, handed to the SVG parser, which hung on
|
|
218
|
+
// a PDF's bytes. Nothing reads PDF (OpenSCAD does not either), so it takes
|
|
219
|
+
// the ordinary "unsupported file type" error below.
|
|
220
|
+
if (ext == ".dxf" || ext == ".svg") {
|
|
212
221
|
std::vector<Contour2d> contours;
|
|
213
222
|
bool filteredMiss = false;
|
|
214
223
|
try {
|
|
@@ -257,6 +266,7 @@ CSGParams resolveImport(Evaluator& ev, const oscad::ModularCall& node, EvalConte
|
|
|
257
266
|
} catch (const std::exception& e) {
|
|
258
267
|
ev.error(std::string("import: ") + e.what(), node);
|
|
259
268
|
}
|
|
269
|
+
for (const std::string& w : mesh.warnings) ev.warn("import: '" + path + "': " + w, &node.position());
|
|
260
270
|
std::vector<Value> vertsFlat;
|
|
261
271
|
vertsFlat.reserve(mesh.verts.size() * 3);
|
|
262
272
|
for (const auto& v : mesh.verts) {
|
|
@@ -428,8 +438,12 @@ Value importAsValue(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& n
|
|
|
428
438
|
|
|
429
439
|
try {
|
|
430
440
|
if (ext == ".json") return loadJsonAsValue(path);
|
|
431
|
-
if (isMeshExt(ext))
|
|
432
|
-
|
|
441
|
+
if (isMeshExt(ext)) {
|
|
442
|
+
const LoadedMesh mesh = loadMeshByExt(path, ext);
|
|
443
|
+
for (const std::string& w : mesh.warnings) ev.warn("import: '" + path + "': " + w, &node.position());
|
|
444
|
+
return meshToVnf(mesh);
|
|
445
|
+
}
|
|
446
|
+
if (ext == ".dxf" || ext == ".svg") {
|
|
433
447
|
std::vector<Contour2d> contours;
|
|
434
448
|
if (ext == ".dxf") {
|
|
435
449
|
std::optional<std::string> layer;
|
|
@@ -915,7 +915,8 @@ std::string lowerExtension(const std::string& path) {
|
|
|
915
915
|
}
|
|
916
916
|
|
|
917
917
|
bool isMultiObject(const std::string& ext) {
|
|
918
|
-
return ext == ".3mf" || ext == ".amf" || ext == ".obj" || ext == ".ply" || ext == ".
|
|
918
|
+
return ext == ".3mf" || ext == ".amf" || ext == ".obj" || ext == ".ply" || ext == ".pov" || ext == ".wrl" ||
|
|
919
|
+
ext == ".x3d";
|
|
919
920
|
}
|
|
920
921
|
|
|
921
922
|
// The merged single mesh STL/OFF write, with the open shells kept.
|
|
@@ -1256,6 +1257,159 @@ void writeDxf(const std::string& path, const std::vector<ColoredBody>& bodies) {
|
|
|
1256
1257
|
|
|
1257
1258
|
namespace {
|
|
1258
1259
|
|
|
1260
|
+
// dxfNum's rule for a float: the shortest text that reads back as the same
|
|
1261
|
+
// float. Mesh vertices and colours are floats, and printing them as doubles
|
|
1262
|
+
// would turn 0.1f into 0.100000001490116.
|
|
1263
|
+
std::string floatNum(float v) {
|
|
1264
|
+
if (!std::isfinite(v) || v == 0.0f) return "0";
|
|
1265
|
+
for (int digits = 6; digits <= 9; ++digits) {
|
|
1266
|
+
std::ostringstream o;
|
|
1267
|
+
o.imbue(std::locale::classic());
|
|
1268
|
+
o.precision(digits);
|
|
1269
|
+
o << v;
|
|
1270
|
+
std::istringstream in(o.str());
|
|
1271
|
+
in.imbue(std::locale::classic());
|
|
1272
|
+
float back = 0.0f;
|
|
1273
|
+
in >> back;
|
|
1274
|
+
if (back == v) return o.str();
|
|
1275
|
+
}
|
|
1276
|
+
std::ostringstream o; // unreachable: 9 digits always round-trips a float
|
|
1277
|
+
o.imbue(std::locale::classic());
|
|
1278
|
+
o.precision(9);
|
|
1279
|
+
o << v;
|
|
1280
|
+
return o.str();
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
std::string povVec(double x, double y, double z) {
|
|
1284
|
+
return "<" + dxfNum(x) + ", " + dxfNum(y) + ", " + dxfNum(z) + ">";
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
} // namespace
|
|
1288
|
+
|
|
1289
|
+
void writePov(const std::string& path, const std::vector<ExportObject>& objects, const ExportPovOptions& opts) {
|
|
1290
|
+
std::ofstream out(path);
|
|
1291
|
+
if (!out) throw std::runtime_error("Could not open '" + path + "' for writing");
|
|
1292
|
+
out.imbue(std::locale::classic());
|
|
1293
|
+
|
|
1294
|
+
out << "// Generated by BelfrySCAD (openscad_cpp_evaluator)\n\n"
|
|
1295
|
+
<< "// Camera settings are at the bottom of this script\n\n"
|
|
1296
|
+
<< "#version 3.7;\n"
|
|
1297
|
+
<< "global_settings { assumed_gamma 1.0 }\n"
|
|
1298
|
+
<< "#declare MATERIAL=finish { specular 0.5 roughness 0.001 reflection{0 0.63 fresnel} ambient 0 "
|
|
1299
|
+
"diffuse 0.6 conserve_energy }\n"
|
|
1300
|
+
<< "#declare MATERIAL_INT=interior{ior 1.32}\n";
|
|
1301
|
+
|
|
1302
|
+
const auto rgbf = [](const std::array<float, 4>& c) {
|
|
1303
|
+
return "<" + floatNum(c[0]) + ", " + floatNum(c[1]) + ", " + floatNum(c[2]) + ", " +
|
|
1304
|
+
floatNum(1.0f - c[3]) + ">";
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
bool any = false;
|
|
1308
|
+
double lo[3] = {0, 0, 0}, hi[3] = {0, 0, 0};
|
|
1309
|
+
for (const ExportObject& o : objects) {
|
|
1310
|
+
const size_t vertCount = o.verts.size() / 3;
|
|
1311
|
+
const size_t triCount = o.tris.size() / 3;
|
|
1312
|
+
if (vertCount == 0 || triCount == 0) continue;
|
|
1313
|
+
for (size_t v = 0; v < vertCount; ++v) {
|
|
1314
|
+
for (int k = 0; k < 3; ++k) {
|
|
1315
|
+
const double c = o.verts[v * 3 + k];
|
|
1316
|
+
if (!any) {
|
|
1317
|
+
lo[k] = hi[k] = c;
|
|
1318
|
+
} else {
|
|
1319
|
+
lo[k] = std::min(lo[k], c);
|
|
1320
|
+
hi[k] = std::max(hi[k], c);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
any = true;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// One texture per distinct colour, in order of first use.
|
|
1327
|
+
std::vector<std::array<float, 4>> palette;
|
|
1328
|
+
std::vector<size_t> triTexture(triCount, 0);
|
|
1329
|
+
const auto textureOf = [&](const std::array<float, 4>& c) {
|
|
1330
|
+
for (size_t i = 0; i < palette.size(); ++i) {
|
|
1331
|
+
if (palette[i] == c) return i;
|
|
1332
|
+
}
|
|
1333
|
+
palette.push_back(c);
|
|
1334
|
+
return palette.size() - 1;
|
|
1335
|
+
};
|
|
1336
|
+
for (size_t t = 0; t < triCount; ++t) {
|
|
1337
|
+
triTexture[t] = textureOf(o.triColors.empty() ? o.color : o.triColors[t]);
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
out << "mesh2 {\n vertex_vectors { " << vertCount;
|
|
1341
|
+
for (size_t v = 0; v < vertCount; ++v) {
|
|
1342
|
+
out << ",\n <" << floatNum(o.verts[v * 3]) << ", " << floatNum(o.verts[v * 3 + 1]) << ", "
|
|
1343
|
+
<< floatNum(o.verts[v * 3 + 2]) << ">";
|
|
1344
|
+
}
|
|
1345
|
+
out << "\n }\n texture_list { " << palette.size();
|
|
1346
|
+
for (const std::array<float, 4>& c : palette) {
|
|
1347
|
+
out << "\n texture { pigment { color rgbf " << rgbf(c) << " } finish { MATERIAL } }";
|
|
1348
|
+
}
|
|
1349
|
+
out << "\n }\n face_indices { " << triCount;
|
|
1350
|
+
for (size_t t = 0; t < triCount; ++t) {
|
|
1351
|
+
out << ",\n <" << o.tris[t * 3] << ", " << o.tris[t * 3 + 1] << ", " << o.tris[t * 3 + 2] << ">, "
|
|
1352
|
+
<< triTexture[t];
|
|
1353
|
+
}
|
|
1354
|
+
// inside_vector: without it POV-Ray treats a mesh as a bare surface,
|
|
1355
|
+
// with no inside for the interior (and its ior) or CSG to act on.
|
|
1356
|
+
out << "\n }\n inside_vector <0, 0, 1>\n interior { MATERIAL_INT }\n}\n";
|
|
1357
|
+
}
|
|
1358
|
+
if (!any) throw std::runtime_error("No geometry to export");
|
|
1359
|
+
|
|
1360
|
+
// 27 lights: every combination of {below, centre, above} on each axis,
|
|
1361
|
+
// twice the model's size out, at OpenSCAD's brightness.
|
|
1362
|
+
const double move = 2.0;
|
|
1363
|
+
double at[3][3];
|
|
1364
|
+
for (int k = 0; k < 3; ++k) {
|
|
1365
|
+
const double d = hi[k] - lo[k];
|
|
1366
|
+
at[k][0] = lo[k] - d * move;
|
|
1367
|
+
at[k][1] = (lo[k] + hi[k]) / 2.0;
|
|
1368
|
+
at[k][2] = hi[k] + d * move;
|
|
1369
|
+
}
|
|
1370
|
+
for (double x : at[0]) {
|
|
1371
|
+
for (double y : at[1]) {
|
|
1372
|
+
for (double z : at[2]) {
|
|
1373
|
+
out << "light_source { " << povVec(x, y, z) << " color rgb <0.2, 0.2, 0.2> }\n";
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
if (opts.camera) {
|
|
1379
|
+
// OpenSCAD's camera block, with two fixes, both checked by rendering
|
|
1380
|
+
// in POV-Ray against BelfrySCAD's own image of the same camera:
|
|
1381
|
+
// - rotate BEFORE translate. The eye orbits $vpt, so it is rotated
|
|
1382
|
+
// about the origin and then moved; OpenSCAD translates first,
|
|
1383
|
+
// which rotates $vpt itself away and frames the wrong place
|
|
1384
|
+
// whenever a view both pans and turns.
|
|
1385
|
+
// - the field of view is VERTICAL in the viewport and HORIZONTAL to
|
|
1386
|
+
// POV-Ray's `angle`. OpenSCAD writes it straight across, so its
|
|
1387
|
+
// renders come out zoomed in by the aspect ratio (1.33x at 4:3).
|
|
1388
|
+
// The horizontal angle is left to POV-Ray to work out from the
|
|
1389
|
+
// image it is asked for, so any size frames the same.
|
|
1390
|
+
const ExportPovCamera& c = *opts.camera;
|
|
1391
|
+
out << "camera { look_at <0, 0, 0>\n"
|
|
1392
|
+
<< " location <0, 0, " << dxfNum(c.distance) << ">\n"
|
|
1393
|
+
<< " angle degrees(2 * atan(tan(radians(" << dxfNum(c.fov) << " / 2)) * image_width / image_height))"
|
|
1394
|
+
<< " up <0, 1, 0> right <1, 0, 0> sky <0, 1, 0> right -x*image_width/image_height\n"
|
|
1395
|
+
<< "rotate <" << dxfNum(c.vpr[0]) << ", " << dxfNum(c.vpr[1]) << " + clock * 3, " << dxfNum(c.vpr[2])
|
|
1396
|
+
<< " + clock>\n"
|
|
1397
|
+
<< "translate " << povVec(c.vpt[0], c.vpt[1], c.vpt[2]) << "\n"
|
|
1398
|
+
<< "}\n";
|
|
1399
|
+
} else {
|
|
1400
|
+
const double dx = hi[0] - lo[0], dy = hi[1] - lo[1], dz = hi[2] - lo[2];
|
|
1401
|
+
out << "camera { look_at " << povVec((lo[0] + hi[0]) / 2, (lo[1] + hi[1]) / 2, (lo[2] + hi[2]) / 2)
|
|
1402
|
+
<< " location " << povVec(lo[0] + dx * move, lo[1] - dy * move, lo[2] + dz * move)
|
|
1403
|
+
<< " up <0, 0, 1> right <1, 0, 0> sky <0, 0, 1> rotate <-55, clock * 3, clock + 25> right "
|
|
1404
|
+
"x*image_width/image_height }\n";
|
|
1405
|
+
}
|
|
1406
|
+
out << "#include \"rad_def.inc\"\n"
|
|
1407
|
+
<< "global_settings { photons { count 20000 autostop 0 jitter .4 } radiosity { "
|
|
1408
|
+
"Rad_Settings(Radiosity_Normal, off, off) } }\n";
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
namespace {
|
|
1412
|
+
|
|
1259
1413
|
// PDF's own unit is 1/72 inch; models are millimetres.
|
|
1260
1414
|
constexpr double kPtPerMm = 72.0 / 25.4;
|
|
1261
1415
|
// Page margin the ruler is drawn on, in points. OpenSCAD's own MARGIN.
|
|
@@ -1599,7 +1753,7 @@ std::vector<std::string> writePdf(const std::string& path, const std::vector<Col
|
|
|
1599
1753
|
|
|
1600
1754
|
const std::vector<std::string>& exportExtensions() {
|
|
1601
1755
|
static const std::vector<std::string> exts = {".3mf", ".amf", ".dxf", ".pdf", ".stl", ".obj",
|
|
1602
|
-
".off", ".ply", ".svg", ".wrl", ".x3d"};
|
|
1756
|
+
".off", ".ply", ".pov", ".svg", ".wrl", ".x3d"};
|
|
1603
1757
|
return exts;
|
|
1604
1758
|
}
|
|
1605
1759
|
|
|
@@ -1656,6 +1810,8 @@ std::vector<std::string> exportModel(const std::string& path, const std::vector<
|
|
|
1656
1810
|
writeObj(path, objects);
|
|
1657
1811
|
} else if (ext == ".ply") {
|
|
1658
1812
|
writePly(path, objects);
|
|
1813
|
+
} else if (ext == ".pov") {
|
|
1814
|
+
writePov(path, objects, opts.pov);
|
|
1659
1815
|
} else if (ext == ".wrl") {
|
|
1660
1816
|
writeVrml(path, objects);
|
|
1661
1817
|
} else {
|