openscad-cpp-evaluator 1.31.0__tar.gz → 1.32.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.31.0 → openscad_cpp_evaluator-1.32.0}/.github/workflows/wheels.yml +9 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/CLAUDE.md +12 -2
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/export.hpp +11 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/export.cpp +108 -1
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_export.cpp +125 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_python_bindings.py +87 -26
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/uv.lock +1 -1
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tools/cli/main.cpp +0 -0
{openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/.github/workflows/wheels.yml
RENAMED
|
@@ -119,6 +119,9 @@ jobs:
|
|
|
119
119
|
# C:\msys64 (not on PATH); its bison/flex satisfy the parser
|
|
120
120
|
# submodule's grammar version requirement.
|
|
121
121
|
CIBW_BEFORE_ALL_WINDOWS: 'C:\msys64\usr\bin\bash.exe -lc "pacman -Sy --noconfirm bison flex"'
|
|
122
|
+
# The binding tests run under pytest (the file's own entry point
|
|
123
|
+
# hands over to it): most of them take tmp_path or use pytest.raises.
|
|
124
|
+
CIBW_TEST_REQUIRES: "pytest"
|
|
122
125
|
CIBW_TEST_COMMAND: "python {package}/tests/test_python_bindings.py"
|
|
123
126
|
|
|
124
127
|
- uses: actions/upload-artifact@v7
|
|
@@ -128,6 +131,9 @@ jobs:
|
|
|
128
131
|
|
|
129
132
|
publish-testpypi:
|
|
130
133
|
needs: [sdist, build_wheels]
|
|
134
|
+
# Tags only: a manual dispatch builds and tests every wheel, and must
|
|
135
|
+
# never publish whatever branch it was run on.
|
|
136
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
131
137
|
runs-on: ubuntu-latest
|
|
132
138
|
environment: testpypi
|
|
133
139
|
steps:
|
|
@@ -164,6 +170,9 @@ jobs:
|
|
|
164
170
|
|
|
165
171
|
publish-pypi:
|
|
166
172
|
needs: [publish-testpypi]
|
|
173
|
+
# Tags only: a manual dispatch builds and tests every wheel, and must
|
|
174
|
+
# never publish whatever branch it was run on.
|
|
175
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
167
176
|
runs-on: ubuntu-latest
|
|
168
177
|
# The "pypi" environment carries no protection rules, so a tag runs
|
|
169
178
|
# straight through TestPyPI to PyPI with nothing to stop it -- and a
|
|
@@ -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, PDF, STL, OBJ, OFF, PLY, SVG, VRML, X3D (3MF via
|
|
1094
|
+
- `include/openscad_cpp_evaluator/export.hpp`, `src/export.cpp` — the writers for all eleven
|
|
1095
|
+
formats `exportExtensions()` lists: 3MF, AMF, DXF, PDF, STL, OBJ, OFF, PLY, 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,16 @@ 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
|
+
**`writeDxf` is the third 2D writer**, also on `collect2d()`: OpenSCAD's own `export_dxf.cc`
|
|
1124
|
+
layout verbatim (AC1006 header with the extents, one CONTINUOUS linetype, layer 0, every contour
|
|
1125
|
+
a closed `LWPOLYLINE` on layer 0 with holes as ordinary contours; 1- and 2-vertex contours as
|
|
1126
|
+
`POINT`/`LINE`), pinned byte-for-byte by `ExportDxf.MatchesRealOpenscadByteForByte`. Two
|
|
1127
|
+
deliberate differences: coordinates are the **shortest text that round-trips the double**
|
|
1128
|
+
(`dxfNum`), not OpenSCAD's 6 significant digits -- a DXF feeds a cutter, and its circles do not
|
|
1129
|
+
survive a re-import otherwise; and `$EXTMAX` is right for a model below zero (OpenSCAD seeds its
|
|
1130
|
+
maxima with `numeric_limits<double>::min()`, the smallest POSITIVE double). Every number goes
|
|
1131
|
+
through the classic locale, the file stream included: Qt sets the process locale, and a grouping
|
|
1132
|
+
locale writes a 1500-vertex count as `1.500`.
|
|
1123
1133
|
**`writePdf` is the other 2D writer**, and shares `collect2d()` with `writeSvg` so the all-2D
|
|
1124
1134
|
rule and its refusal have one implementation. Everything else differs from SVG: the drawing is
|
|
1125
1135
|
**centred on a fixed paper size** rather than the page being cut to fit, and **PDF user space is
|
|
@@ -158,6 +158,17 @@ struct ExportSvgOptions {
|
|
|
158
158
|
void writeSvg(const std::string& path, const std::vector<ColoredBody>& bodies,
|
|
159
159
|
const ExportSvgOptions& opts = {});
|
|
160
160
|
|
|
161
|
+
// DXF, the third 2D writer: OpenSCAD's own export_dxf.cc layout (an AC1006
|
|
162
|
+
// header with the model's extents, one CONTINUOUS linetype, layer 0) and
|
|
163
|
+
// every contour of every body a closed LWPOLYLINE on layer 0 -- holes are
|
|
164
|
+
// contours like any other, as in OpenSCAD. A 1-vertex contour is a POINT
|
|
165
|
+
// and a 2-vertex one a LINE, again as OpenSCAD writes them. Shares
|
|
166
|
+
// collect2d() with writeSvg/writePdf, so a 3D model is refused the same
|
|
167
|
+
// way. Coordinates are written at full round-trip precision, NOT OpenSCAD's
|
|
168
|
+
// 6 significant digits: a DXF goes to a cutter, where 1234.567 written as
|
|
169
|
+
// 1234.57 is a real error.
|
|
170
|
+
void writeDxf(const std::string& path, const std::vector<ColoredBody>& bodies);
|
|
171
|
+
|
|
161
172
|
// Options for the PDF writer, named and defaulted after OpenSCAD's own
|
|
162
173
|
// `-O export-pdf/...` set.
|
|
163
174
|
struct ExportPdfOptions {
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
#include <cstdio>
|
|
14
14
|
#include <ctime>
|
|
15
15
|
#include <fstream>
|
|
16
|
+
#include <locale>
|
|
17
|
+
#include <sstream>
|
|
16
18
|
#include <optional>
|
|
17
19
|
#include <stdexcept>
|
|
18
20
|
|
|
@@ -1155,6 +1157,105 @@ void writeSvg(const std::string& path, const std::vector<ColoredBody>& bodies, c
|
|
|
1155
1157
|
|
|
1156
1158
|
namespace {
|
|
1157
1159
|
|
|
1160
|
+
// The shortest decimal that reads back as exactly `v`, in the classic
|
|
1161
|
+
// locale (Qt sets the process locale from the environment, so printf could
|
|
1162
|
+
// write "1,5" on a German system and no DXF reader would take it). -0 is
|
|
1163
|
+
// written as 0, and a non-finite value -- which no contour should hold --
|
|
1164
|
+
// as 0 rather than as text a reader would choke on.
|
|
1165
|
+
std::string dxfNum(double v) {
|
|
1166
|
+
if (!std::isfinite(v) || v == 0.0) return "0";
|
|
1167
|
+
for (int digits = 6; digits <= 17; ++digits) {
|
|
1168
|
+
std::ostringstream o;
|
|
1169
|
+
o.imbue(std::locale::classic());
|
|
1170
|
+
o.precision(digits);
|
|
1171
|
+
o << v;
|
|
1172
|
+
std::istringstream in(o.str());
|
|
1173
|
+
in.imbue(std::locale::classic());
|
|
1174
|
+
double back = 0.0;
|
|
1175
|
+
in >> back;
|
|
1176
|
+
if (back == v) return o.str();
|
|
1177
|
+
}
|
|
1178
|
+
std::ostringstream o; // unreachable: 17 digits always round-trips a double
|
|
1179
|
+
o.imbue(std::locale::classic());
|
|
1180
|
+
o.precision(17);
|
|
1181
|
+
o << v;
|
|
1182
|
+
return o.str();
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
// The header, tables and (empty) blocks sections, verbatim from OpenSCAD's
|
|
1186
|
+
// export_dxf.cc -- its comments record which readers each piece was needed
|
|
1187
|
+
// for (Inkscape, LibreCAD, Illustrator, sharecad.org, generic cutters).
|
|
1188
|
+
void writeDxfHeader(std::ostream& out, double xMin, double yMin, double xMax, double yMax) {
|
|
1189
|
+
out << "999\nDXF from OpenSCAD\n"
|
|
1190
|
+
<< " 0\nSECTION\n 2\nHEADER\n"
|
|
1191
|
+
<< " 9\n$ACADVER\n 1\nAC1006\n"
|
|
1192
|
+
<< " 9\n$INSBASE\n 10\n0.0\n 20\n0.0\n 30\n0.0\n";
|
|
1193
|
+
for (const char* name : {"$EXTMIN", "$EXTMAX", "$LINMIN", "$LINMAX"}) {
|
|
1194
|
+
const bool isMin = std::string(name).find("MIN") != std::string::npos;
|
|
1195
|
+
out << " 9\n" << name << "\n 10\n" << dxfNum(isMin ? xMin : xMax) << "\n 20\n"
|
|
1196
|
+
<< dxfNum(isMin ? yMin : yMax) << "\n";
|
|
1197
|
+
}
|
|
1198
|
+
out << " 0\nENDSEC\n"
|
|
1199
|
+
<< " 0\nSECTION\n 2\nTABLES\n"
|
|
1200
|
+
<< " 0\nTABLE\n 2\nLTYPE\n 70\n1\n"
|
|
1201
|
+
<< " 0\nLTYPE\n 2\nCONTINUOUS\n 70\n64\n 3\nSolid line\n 72\n65\n 73\n0\n 40\n0.000000\n"
|
|
1202
|
+
<< " 0\nENDTAB\n"
|
|
1203
|
+
<< " 0\nTABLE\n 2\nLAYER\n 70\n6\n"
|
|
1204
|
+
<< " 0\nLAYER\n 2\n0\n 70\n64\n 62\n7\n 6\nCONTINUOUS\n"
|
|
1205
|
+
<< " 0\nENDTAB\n"
|
|
1206
|
+
<< " 0\nTABLE\n 2\nSTYLE\n 70\n0\n 0\nENDTAB\n"
|
|
1207
|
+
<< " 0\nENDSEC\n"
|
|
1208
|
+
<< " 0\nSECTION\n 2\nBLOCKS\n 0\nENDSEC\n";
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
} // namespace
|
|
1212
|
+
|
|
1213
|
+
void writeDxf(const std::string& path, const std::vector<ColoredBody>& bodies) {
|
|
1214
|
+
const Flat2d flat = collect2d(bodies);
|
|
1215
|
+
|
|
1216
|
+
std::ofstream out(path);
|
|
1217
|
+
if (!out) throw std::runtime_error("Could not open '" + path + "' for writing");
|
|
1218
|
+
// The vertex counts go through the stream itself, which otherwise takes
|
|
1219
|
+
// the global C++ locale -- one with digit grouping writes 1500 as "1.500".
|
|
1220
|
+
out.imbue(std::locale::classic());
|
|
1221
|
+
|
|
1222
|
+
// Extents from collect2d's own bounding box. OpenSCAD starts its maxima
|
|
1223
|
+
// at numeric_limits<double>::min() -- the smallest POSITIVE double, not
|
|
1224
|
+
// the most negative -- so a model lying entirely at negative x or y gets
|
|
1225
|
+
// a wrong $EXTMAX there. That is a bug, not a format rule.
|
|
1226
|
+
writeDxfHeader(out, flat.minx, flat.miny, flat.maxx, flat.maxy);
|
|
1227
|
+
|
|
1228
|
+
out << " 0\nSECTION\n 2\nENTITIES\n";
|
|
1229
|
+
for (const manifold::Polygons& polys : flat.perBody) {
|
|
1230
|
+
for (const manifold::SimplePolygon& contour : polys) {
|
|
1231
|
+
const auto xy = [&](const char* xCode, const char* yCode, const manifold::vec2& p) {
|
|
1232
|
+
out << xCode << "\n" << dxfNum(p.x) << "\n" << yCode << "\n" << dxfNum(p.y) << "\n";
|
|
1233
|
+
};
|
|
1234
|
+
switch (contour.size()) {
|
|
1235
|
+
case 0:
|
|
1236
|
+
break;
|
|
1237
|
+
case 1:
|
|
1238
|
+
out << " 0\nPOINT\n100\nAcDbEntity\n 8\n0\n100\nAcDbPoint\n";
|
|
1239
|
+
xy(" 10", " 20", contour[0]);
|
|
1240
|
+
break;
|
|
1241
|
+
case 2:
|
|
1242
|
+
// [X1 Y1 X2 Y2]: the order ezdxf and dxfgrabber can read.
|
|
1243
|
+
out << " 0\nLINE\n100\nAcDbEntity\n 8\n0\n100\nAcDbLine\n";
|
|
1244
|
+
xy(" 10", " 20", contour[0]);
|
|
1245
|
+
xy(" 11", " 21", contour[1]);
|
|
1246
|
+
break;
|
|
1247
|
+
default:
|
|
1248
|
+
out << " 0\nLWPOLYLINE\n100\nAcDbEntity\n 8\n0\n100\nAcDbPolyline\n"
|
|
1249
|
+
<< " 90\n" << contour.size() << "\n 70\n1\n"; // 70 = 1: closed
|
|
1250
|
+
for (const manifold::vec2& p : contour) xy(" 10", " 20", p);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
out << " 0\nENDSEC\n 0\nEOF\n";
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
namespace {
|
|
1258
|
+
|
|
1158
1259
|
// PDF's own unit is 1/72 inch; models are millimetres.
|
|
1159
1260
|
constexpr double kPtPerMm = 72.0 / 25.4;
|
|
1160
1261
|
// Page margin the ruler is drawn on, in points. OpenSCAD's own MARGIN.
|
|
@@ -1497,7 +1598,7 @@ std::vector<std::string> writePdf(const std::string& path, const std::vector<Col
|
|
|
1497
1598
|
}
|
|
1498
1599
|
|
|
1499
1600
|
const std::vector<std::string>& exportExtensions() {
|
|
1500
|
-
static const std::vector<std::string> exts = {".3mf", ".amf", ".pdf", ".stl", ".obj",
|
|
1601
|
+
static const std::vector<std::string> exts = {".3mf", ".amf", ".dxf", ".pdf", ".stl", ".obj",
|
|
1501
1602
|
".off", ".ply", ".svg", ".wrl", ".x3d"};
|
|
1502
1603
|
return exts;
|
|
1503
1604
|
}
|
|
@@ -1524,6 +1625,12 @@ std::vector<std::string> exportModel(const std::string& path, const std::vector<
|
|
|
1524
1625
|
return writePdf(path, bodies, opts.pdf);
|
|
1525
1626
|
}
|
|
1526
1627
|
|
|
1628
|
+
if (ext == ".dxf") {
|
|
1629
|
+
// 2D, outside the mesh pipeline like SVG and PDF.
|
|
1630
|
+
writeDxf(path, bodies);
|
|
1631
|
+
return warnings;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1527
1634
|
if (ext == ".svg") {
|
|
1528
1635
|
// 2D, and nothing the mesh pipeline below does applies: no merge,
|
|
1529
1636
|
// no sliver strip, no manifoldness check. Contours are what they
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include <cstdio>
|
|
11
11
|
#include <filesystem>
|
|
12
12
|
#include <fstream>
|
|
13
|
+
#include <locale>
|
|
13
14
|
#include <gtest/gtest.h>
|
|
14
15
|
#include <sstream>
|
|
15
16
|
#include <stb_image.h>
|
|
@@ -444,6 +445,130 @@ M 18.0866,-7.3806 L 16.4645,-8.46447 L 15.3806,-10.0866 L 15,-12 L 15.3806,-13.9
|
|
|
444
445
|
expected);
|
|
445
446
|
}
|
|
446
447
|
|
|
448
|
+
// -- DXF (2D) --------------------------------------------------------------
|
|
449
|
+
|
|
450
|
+
namespace {
|
|
451
|
+
|
|
452
|
+
std::string dxfOf(const std::string& code, const std::string& name) {
|
|
453
|
+
const std::string path = tempPath(name).string();
|
|
454
|
+
writeDxf(path, evalToBodies(code));
|
|
455
|
+
const std::string text = readText(path);
|
|
456
|
+
std::remove(path.c_str());
|
|
457
|
+
return text;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// The value on the line after the first `code` line following `header`
|
|
461
|
+
// (DXF is group-code / value pairs, one per line).
|
|
462
|
+
std::string dxfValueAfter(const std::string& text, const std::string& header, const std::string& code) {
|
|
463
|
+
size_t at = text.find("\n" + header + "\n");
|
|
464
|
+
if (at == std::string::npos) return "";
|
|
465
|
+
at = text.find("\n" + code + "\n", at + 1);
|
|
466
|
+
if (at == std::string::npos) return "";
|
|
467
|
+
const size_t start = at + code.size() + 2;
|
|
468
|
+
return text.substr(start, text.find('\n', start) - start);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
} // namespace
|
|
472
|
+
|
|
473
|
+
// Byte-for-byte against real OpenSCAD 2026.02.01's `-o out.dxf` for the same
|
|
474
|
+
// script: header, tables, entity layout, contour order and vertex order. The
|
|
475
|
+
// coordinates are chosen to need no more than 6 significant digits, the only
|
|
476
|
+
// place ours deliberately differs (see FullPrecisionNotSixDigits).
|
|
477
|
+
TEST(ExportDxf, MatchesRealOpenscadByteForByte) {
|
|
478
|
+
const std::string expected =
|
|
479
|
+
"999\nDXF from OpenSCAD\n 0\nSECTION\n 2\nHEADER\n 9\n$ACADVER\n 1\nAC1006\n"
|
|
480
|
+
" 9\n$INSBASE\n 10\n0.0\n 20\n0.0\n 30\n0.0\n"
|
|
481
|
+
" 9\n$EXTMIN\n 10\n0\n 20\n0\n 9\n$EXTMAX\n 10\n40\n 20\n25\n"
|
|
482
|
+
" 9\n$LINMIN\n 10\n0\n 20\n0\n 9\n$LINMAX\n 10\n40\n 20\n25\n"
|
|
483
|
+
" 0\nENDSEC\n 0\nSECTION\n 2\nTABLES\n 0\nTABLE\n 2\nLTYPE\n 70\n1\n"
|
|
484
|
+
" 0\nLTYPE\n 2\nCONTINUOUS\n 70\n64\n 3\nSolid line\n 72\n65\n 73\n0\n 40\n0.000000\n"
|
|
485
|
+
" 0\nENDTAB\n 0\nTABLE\n 2\nLAYER\n 70\n6\n 0\nLAYER\n 2\n0\n 70\n64\n 62\n7\n 6\nCONTINUOUS\n"
|
|
486
|
+
" 0\nENDTAB\n 0\nTABLE\n 2\nSTYLE\n 70\n0\n 0\nENDTAB\n 0\nENDSEC\n"
|
|
487
|
+
" 0\nSECTION\n 2\nBLOCKS\n 0\nENDSEC\n 0\nSECTION\n 2\nENTITIES\n"
|
|
488
|
+
" 0\nLWPOLYLINE\n100\nAcDbEntity\n 8\n0\n100\nAcDbPolyline\n 90\n4\n 70\n1\n"
|
|
489
|
+
" 10\n40\n 20\n25\n 10\n0\n 20\n25\n 10\n0\n 20\n0\n 10\n40\n 20\n0\n"
|
|
490
|
+
" 0\nLWPOLYLINE\n100\nAcDbEntity\n 8\n0\n100\nAcDbPolyline\n 90\n4\n 70\n1\n"
|
|
491
|
+
" 10\n10\n 20\n5\n 10\n10\n 20\n17.5\n 10\n30\n 20\n17.5\n 10\n30\n 20\n5\n"
|
|
492
|
+
" 0\nENDSEC\n 0\nEOF\n";
|
|
493
|
+
EXPECT_EQ(dxfOf("difference() { square([40,25]); translate([10,5]) square([20,12.5]); }", "parity.dxf"),
|
|
494
|
+
expected);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// OpenSCAD streams doubles at the default 6 significant digits, so 1234.5678
|
|
498
|
+
// reaches the file as 1234.57 -- a 2 micron error on a cut part, from the
|
|
499
|
+
// file format alone. Ours writes the shortest text that reads back exactly.
|
|
500
|
+
TEST(ExportDxf, FullPrecisionNotSixDigits) {
|
|
501
|
+
const std::string text = dxfOf("square([1234.5678, 0.1]);", "precise.dxf");
|
|
502
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMAX", " 10"), "1234.5678");
|
|
503
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMAX", " 20"), "0.1");
|
|
504
|
+
EXPECT_EQ(countOf(text, "\n1234.5678\n"), 4u); // $EXTMAX, $LINMAX and two vertices
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// OpenSCAD starts its maxima at numeric_limits<double>::min(), the smallest
|
|
508
|
+
// POSITIVE double, so a model entirely below zero reports $EXTMAX of ~0.
|
|
509
|
+
TEST(ExportDxf, ExtentsOfAModelBelowZero) {
|
|
510
|
+
const std::string text = dxfOf("translate([-50,-30]) square(10);", "negative.dxf");
|
|
511
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMIN", " 10"), "-50");
|
|
512
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMIN", " 20"), "-30");
|
|
513
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMAX", " 10"), "-40");
|
|
514
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMAX", " 20"), "-20");
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
TEST(ExportDxf, EveryContourIsAClosedPolylineHolesIncluded) {
|
|
518
|
+
const std::string text =
|
|
519
|
+
dxfOf("difference() { circle(10, $fn=12); circle(5, $fn=12); } translate([30,0]) square(4);", "multi.dxf");
|
|
520
|
+
EXPECT_EQ(countOf(text, "LWPOLYLINE"), 3u); // outer, hole, and the separate square
|
|
521
|
+
EXPECT_EQ(countOf(text, " 90\n12\n 70\n1\n"), 2u); // both circles: 12 vertices, closed
|
|
522
|
+
EXPECT_EQ(countOf(text, " 90\n4\n 70\n1\n"), 1u);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
namespace {
|
|
526
|
+
// A locale that writes 1500.5 as "1.500,5" -- what a German global locale
|
|
527
|
+
// would do to any number that reaches a stream without the classic locale.
|
|
528
|
+
struct GermanishPunct : std::numpunct<char> {
|
|
529
|
+
char do_decimal_point() const override { return ','; }
|
|
530
|
+
char do_thousands_sep() const override { return '.'; }
|
|
531
|
+
std::string do_grouping() const override { return "\3"; }
|
|
532
|
+
};
|
|
533
|
+
} // namespace
|
|
534
|
+
|
|
535
|
+
TEST(ExportDxf, NumbersIgnoreTheGlobalLocale) {
|
|
536
|
+
const std::locale previous = std::locale::global(std::locale(std::locale::classic(), new GermanishPunct));
|
|
537
|
+
std::string text;
|
|
538
|
+
try {
|
|
539
|
+
text = dxfOf("translate([0.5,0]) circle(1000, $fn=1500);", "locale.dxf");
|
|
540
|
+
} catch (...) {
|
|
541
|
+
std::locale::global(previous);
|
|
542
|
+
throw;
|
|
543
|
+
}
|
|
544
|
+
std::locale::global(previous);
|
|
545
|
+
EXPECT_NE(text.find(" 90\n1500\n"), std::string::npos);
|
|
546
|
+
EXPECT_EQ(dxfValueAfter(text, "$EXTMAX", " 10"), "1000.5");
|
|
547
|
+
EXPECT_EQ(text.find(','), std::string::npos);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
TEST(ExportDxf, RefusesA3dModel) {
|
|
551
|
+
std::vector<ColoredBody> bodies = evalToBodies("cube(10);");
|
|
552
|
+
EXPECT_THROW(writeDxf(tempPath("solid.dxf").string(), bodies), std::runtime_error);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
TEST(ExportDxf, NoGeometryThrows) {
|
|
556
|
+
std::vector<ColoredBody> empty;
|
|
557
|
+
EXPECT_THROW(writeDxf(tempPath("empty.dxf").string(), empty), std::runtime_error);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
TEST(ExportDxf, ReachableThroughExportModelAndListedAsAnExtension) {
|
|
561
|
+
const std::vector<std::string>& exts = exportExtensions();
|
|
562
|
+
EXPECT_NE(std::find(exts.begin(), exts.end(), ".dxf"), exts.end());
|
|
563
|
+
const std::string path = tempPath("via_export_model.dxf").string();
|
|
564
|
+
const std::vector<std::string> warnings = exportModel(path, evalToBodies("square(5);"), ExportOptions{});
|
|
565
|
+
EXPECT_TRUE(warnings.empty());
|
|
566
|
+
const std::string text = readText(path);
|
|
567
|
+
EXPECT_EQ(countOf(text, "LWPOLYLINE"), 1u);
|
|
568
|
+
EXPECT_NE(text.find(" 0\nEOF\n"), std::string::npos);
|
|
569
|
+
std::remove(path.c_str());
|
|
570
|
+
}
|
|
571
|
+
|
|
447
572
|
// -- PDF (2D) --------------------------------------------------------------
|
|
448
573
|
|
|
449
574
|
namespace {
|
{openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/tests/test_python_bindings.py
RENAMED
|
@@ -6,12 +6,12 @@ test_debug_hooks.cpp, test_viewport_params.cpp); this file only exercises the
|
|
|
6
6
|
nanobind plumbing that exposes them to Python, which has no coverage of its
|
|
7
7
|
own otherwise.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
Run with `python tests/test_python_bindings.py` (what wheels.yml's
|
|
10
|
+
CIBW_TEST_COMMAND does on every release platform) or pytest directly; the
|
|
11
|
+
entry point hands the file to pytest. It started as plain functions with a
|
|
12
|
+
hand-rolled runner, but the file outgrew that: most tests now take tmp_path
|
|
13
|
+
or use pytest.raises, and the runner, sitting part-way down, never reached
|
|
14
|
+
them in a wheel build at all.
|
|
15
15
|
"""
|
|
16
16
|
import os
|
|
17
17
|
import sys
|
|
@@ -20,6 +20,25 @@ from pathlib import Path
|
|
|
20
20
|
|
|
21
21
|
from openscad_cpp_evaluator import Evaluator, ManifoldCache, format_csg_tree
|
|
22
22
|
|
|
23
|
+
import pytest
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture(autouse=True)
|
|
27
|
+
def _scripts_are_utf8_with_lf(monkeypatch):
|
|
28
|
+
"""Every .scad these tests write is UTF-8 with \\n line endings, as any
|
|
29
|
+
editor saves one. Path.write_text's own defaults are the platform's:
|
|
30
|
+
cp1252 and CRLF on Windows, which made "aé—z" undecodable and shifted
|
|
31
|
+
every source span after a line break by one character per line against
|
|
32
|
+
the test's own string -- failures of the test, not of the evaluator. An
|
|
33
|
+
explicit encoding or newline still wins."""
|
|
34
|
+
orig = Path.write_text
|
|
35
|
+
|
|
36
|
+
def write_text(self, data, encoding=None, errors=None, newline=None):
|
|
37
|
+
return orig(self, data, encoding=encoding or "utf-8", errors=errors,
|
|
38
|
+
newline="\n" if newline is None else newline)
|
|
39
|
+
|
|
40
|
+
monkeypatch.setattr(Path, "write_text", write_text)
|
|
41
|
+
|
|
23
42
|
|
|
24
43
|
def _write(src: str) -> str:
|
|
25
44
|
f = tempfile.NamedTemporaryFile(suffix=".scad", mode="w", encoding="utf-8", delete=False)
|
|
@@ -389,25 +408,6 @@ def test_format_source_raises_parse_error_on_bad_input():
|
|
|
389
408
|
raise AssertionError("expected ParseError")
|
|
390
409
|
|
|
391
410
|
|
|
392
|
-
def main():
|
|
393
|
-
tests = [v for k, v in sorted(globals().items()) if k.startswith("test_") and callable(v)]
|
|
394
|
-
failures = []
|
|
395
|
-
for t in tests:
|
|
396
|
-
try:
|
|
397
|
-
t()
|
|
398
|
-
print(f"PASS {t.__name__}")
|
|
399
|
-
except Exception as e:
|
|
400
|
-
failures.append((t.__name__, e))
|
|
401
|
-
print(f"FAIL {t.__name__}: {e}")
|
|
402
|
-
print(f"\n{len(tests) - len(failures)}/{len(tests)} passed")
|
|
403
|
-
if failures:
|
|
404
|
-
sys.exit(1)
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
if __name__ == "__main__":
|
|
408
|
-
main()
|
|
409
|
-
|
|
410
|
-
|
|
411
411
|
def test_evaluate_generate_false_skips_geometry(tmp_path):
|
|
412
412
|
"""generate=False runs the script but builds no Manifold geometry.
|
|
413
413
|
|
|
@@ -702,6 +702,51 @@ def test_export_model_svg_refuses_a_3d_model(tmp_path):
|
|
|
702
702
|
export_model(str(tmp_path / "solid.svg"), ev.geometry)
|
|
703
703
|
|
|
704
704
|
|
|
705
|
+
def test_export_model_writes_dxf_that_imports_back_unchanged(tmp_path):
|
|
706
|
+
""".dxf through the facade, then back in through import(): exporting what
|
|
707
|
+
was imported must give the same file, which only holds if every
|
|
708
|
+
coordinate survived at full precision (OpenSCAD's own writer keeps 6
|
|
709
|
+
significant digits, so its circles do not round-trip)."""
|
|
710
|
+
from openscad_cpp_evaluator import Evaluator, export_extensions, export_model
|
|
711
|
+
|
|
712
|
+
assert ".dxf" in export_extensions()
|
|
713
|
+
|
|
714
|
+
def export(script, name):
|
|
715
|
+
src = tmp_path / (name + ".scad")
|
|
716
|
+
src.write_text(script)
|
|
717
|
+
ev = Evaluator()
|
|
718
|
+
ev.evaluate(str(src), {})
|
|
719
|
+
out = tmp_path / (name + ".dxf")
|
|
720
|
+
assert export_model(str(out), ev.geometry) == []
|
|
721
|
+
return out
|
|
722
|
+
|
|
723
|
+
first = export("difference() { square([40,25]); translate([20,12]) circle(5, $fn=16); }", "first")
|
|
724
|
+
text = first.read_text()
|
|
725
|
+
assert text.startswith("999\nDXF from OpenSCAD\n") and text.endswith(" 0\nEOF\n")
|
|
726
|
+
assert text.count("LWPOLYLINE") == 2
|
|
727
|
+
# The circle's vertices carry more than 6 significant digits -- the ones
|
|
728
|
+
# OpenSCAD's writer would cut them to. (Their exact values are whatever
|
|
729
|
+
# Manifold's 2D kernel rounded them to, so no literal is pinned here.)
|
|
730
|
+
lines = text.split("\n")
|
|
731
|
+
coords = [lines[i + 1] for i, code in enumerate(lines[:-1]) if code in (" 10", " 20")]
|
|
732
|
+
assert max(len(c.lstrip("-").replace(".", "").lstrip("0")) for c in coords) > 6
|
|
733
|
+
|
|
734
|
+
second = export(f'import("{first.as_posix()}");', "second")
|
|
735
|
+
assert second.read_text() == text
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
def test_export_model_dxf_refuses_a_3d_model(tmp_path):
|
|
739
|
+
import pytest
|
|
740
|
+
from openscad_cpp_evaluator import Evaluator, EvalError, export_model
|
|
741
|
+
|
|
742
|
+
src = tmp_path / "solid.scad"
|
|
743
|
+
src.write_text("cube(10);")
|
|
744
|
+
ev = Evaluator()
|
|
745
|
+
ev.evaluate(str(src), {})
|
|
746
|
+
with pytest.raises(EvalError, match="not a 2D object"):
|
|
747
|
+
export_model(str(tmp_path / "solid.dxf"), ev.geometry)
|
|
748
|
+
|
|
749
|
+
|
|
705
750
|
def test_export_model_writes_pdf_and_takes_its_options(tmp_path):
|
|
706
751
|
""".pdf through the facade, plus the option dict. Same
|
|
707
752
|
two-parameter-list trap as split_components and the svg_* set."""
|
|
@@ -1011,7 +1056,8 @@ def _svg_counts(tmp_path, args):
|
|
|
1011
1056
|
svg = tmp_path / "f.svg"
|
|
1012
1057
|
svg.write_text(SVG_FILTER)
|
|
1013
1058
|
scad = tmp_path / "f.scad"
|
|
1014
|
-
|
|
1059
|
+
# as_posix: a Windows path's backslashes would be escapes in a .scad string.
|
|
1060
|
+
scad.write_text(f'echo(n = len(import("{svg.as_posix()}"{args})));\n')
|
|
1015
1061
|
msgs = []
|
|
1016
1062
|
Evaluator(echo_fn=msgs.append).evaluate(str(scad), generate=False)
|
|
1017
1063
|
echoes = [m for m in msgs if m.startswith("ECHO:")]
|
|
@@ -1177,3 +1223,18 @@ def test_a_cancel_signal_stops_a_silent_script_from_another_thread(tmp_path):
|
|
|
1177
1223
|
except EvalError as e:
|
|
1178
1224
|
assert "Render cancelled" in str(e), e
|
|
1179
1225
|
assert time.perf_counter() - t0 < 5
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
def main():
|
|
1229
|
+
"""`python tests/test_python_bindings.py` -- how cibuildwheel runs this
|
|
1230
|
+
file -- runs the whole file under pytest. It used to loop over the test_
|
|
1231
|
+
functions itself, from a main() placed part-way down: every test defined
|
|
1232
|
+
below that point (37 of them, every export test included) never ran in a
|
|
1233
|
+
wheel build, and the ones that take tmp_path could not have."""
|
|
1234
|
+
import pytest
|
|
1235
|
+
|
|
1236
|
+
sys.exit(pytest.main([__file__, "-q"]))
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
if __name__ == "__main__":
|
|
1240
|
+
main()
|
|
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.31.0 → openscad_cpp_evaluator-1.32.0}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.31.0 → openscad_cpp_evaluator-1.32.0}/examples/minimal_debugger.cpp
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|