openscad-cpp-evaluator 0.30.0__tar.gz → 0.31.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.
Files changed (202) hide show
  1. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/PKG-INFO +1 -1
  2. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/bindings/module.cpp +48 -2
  3. openscad_cpp_evaluator-0.31.0/include/openscad_cpp_evaluator/export.hpp +144 -0
  4. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/pyproject.toml +1 -1
  5. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/python/openscad_cpp_evaluator/__init__.py +44 -1
  6. openscad_cpp_evaluator-0.31.0/src/export.cpp +974 -0
  7. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_cli.cpp +71 -2
  8. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_import_export.cpp +12 -8
  9. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tools/cli/cli_lib.cpp +16 -15
  10. openscad_cpp_evaluator-0.30.0/include/openscad_cpp_evaluator/export.hpp +0 -51
  11. openscad_cpp_evaluator-0.30.0/src/export.cpp +0 -242
  12. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/.github/workflows/ci.yml +0 -0
  13. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/.github/workflows/wheels.yml +0 -0
  14. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/.gitignore +0 -0
  15. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/.gitmodules +0 -0
  16. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/CLAUDE.md +0 -0
  17. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/CMakeLists.txt +0 -0
  18. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/LICENSE +0 -0
  19. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/README.md +0 -0
  20. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/bindings/CMakeLists.txt +0 -0
  21. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/bindings/ast_to_py.cpp +0 -0
  22. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/cmake/embed_font.cmake +0 -0
  23. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/examples/CMakeLists.txt +0 -0
  24. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/examples/eval_perf_benchmark.cpp +0 -0
  25. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/examples/manifold_cache_reuse.cpp +0 -0
  26. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/examples/minimal_debugger.cpp +0 -0
  27. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  28. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/.gitignore +0 -0
  29. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  30. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  31. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/README.md +0 -0
  32. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  33. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  34. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  35. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  36. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  37. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  38. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  39. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  40. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  41. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  42. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  43. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  44. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  45. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  46. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  47. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  48. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  49. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  50. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  51. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  52. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  53. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  54. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  55. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  56. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  57. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  58. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  59. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  60. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  61. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  62. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  63. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  64. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  65. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  66. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  67. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  68. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  69. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  70. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  71. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  72. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  73. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  74. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  75. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  76. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  77. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  78. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  79. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  80. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  81. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  82. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  83. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  84. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  85. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  86. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  87. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  88. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  89. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  90. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  91. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  92. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  93. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  94. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
  95. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  96. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
  97. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  98. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
  99. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  100. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  101. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  102. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  103. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  104. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  105. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  106. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  107. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  108. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
  109. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  110. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  111. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  112. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  113. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  114. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  115. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  116. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  117. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  118. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  119. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
  120. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  121. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  122. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
  123. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  124. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/resources/fonts/LICENSE +0 -0
  125. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  126. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/CMakeLists.txt +0 -0
  127. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/booleans.cpp +0 -0
  128. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/builtins.hpp +0 -0
  129. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/call_args.cpp +0 -0
  130. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/color.cpp +0 -0
  131. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/control.cpp +0 -0
  132. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/extrude.cpp +0 -0
  133. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/function_builtins.cpp +0 -0
  134. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/import.cpp +0 -0
  135. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/modifiers.cpp +0 -0
  136. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/primitives_2d.cpp +0 -0
  137. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/primitives_3d.cpp +0 -0
  138. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/registry.cpp +0 -0
  139. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/roof.cpp +0 -0
  140. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/segments.cpp +0 -0
  141. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/surface.cpp +0 -0
  142. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/text.cpp +0 -0
  143. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/topology.cpp +0 -0
  144. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/builtins/transforms.cpp +0 -0
  145. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/bytecode_compiler.cpp +0 -0
  146. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/bytecode_vm.cpp +0 -0
  147. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/colored_body.cpp +0 -0
  148. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/csg_generate.cpp +0 -0
  149. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/csg_resolve.cpp +0 -0
  150. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/css_colors.cpp +0 -0
  151. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/debug/debug_repl.cpp +0 -0
  152. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/debug_profile.cpp +0 -0
  153. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/eval_context.cpp +0 -0
  154. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/eval_error.cpp +0 -0
  155. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/eval_use.cpp +0 -0
  156. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/expr_eval.cpp +0 -0
  157. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/import/dxf_import.cpp +0 -0
  158. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/import/mesh_import.cpp +0 -0
  159. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/import/surface_load.cpp +0 -0
  160. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/import/svg_import.cpp +0 -0
  161. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/manifold_cache.cpp +0 -0
  162. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/mesh_check.cpp +0 -0
  163. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/stmt_eval.cpp +0 -0
  164. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/text/stb_font_provider.cpp +0 -0
  165. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/text/text_metrics.cpp +0 -0
  166. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/user_calls.cpp +0 -0
  167. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/value.cpp +0 -0
  168. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/src/zip_stored.cpp +0 -0
  169. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/CMakeLists.txt +0 -0
  170. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_booleans.cpp +0 -0
  171. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_bytecode_compiler.cpp +0 -0
  172. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_control_flow.cpp +0 -0
  173. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_csg_tree.cpp +0 -0
  174. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_debug_hooks.cpp +0 -0
  175. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_dxf_svg_import.cpp +0 -0
  176. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_eval_context.cpp +0 -0
  177. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_export.cpp +0 -0
  178. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_expr_eval.cpp +0 -0
  179. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_extrude_roof.cpp +0 -0
  180. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_function_builtins.cpp +0 -0
  181. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_helpers.hpp +0 -0
  182. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_manifold_cache.cpp +0 -0
  183. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_mesh_check.cpp +0 -0
  184. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_multi_color_merge.cpp +0 -0
  185. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_primitives.cpp +0 -0
  186. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_profiling.cpp +0 -0
  187. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_python_bindings.py +0 -0
  188. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_scope_trail.cpp +0 -0
  189. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_scoping.cpp +0 -0
  190. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_surface.cpp +0 -0
  191. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_tail_calls.cpp +0 -0
  192. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_text.cpp +0 -0
  193. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_transforms.cpp +0 -0
  194. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_unexpected_args.cpp +0 -0
  195. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_use.cpp +0 -0
  196. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_value.cpp +0 -0
  197. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_viewport_params.cpp +0 -0
  198. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tests/test_zip_stored.cpp +0 -0
  199. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tools/cli/CMakeLists.txt +0 -0
  200. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tools/cli/cli_lib.hpp +0 -0
  201. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/tools/cli/main.cpp +0 -0
  202. {openscad_cpp_evaluator-0.30.0 → openscad_cpp_evaluator-0.31.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 0.30.0
3
+ Version: 0.31.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT
@@ -22,6 +22,7 @@
22
22
  #include "openscad_cpp_evaluator/eval_context.hpp"
23
23
  #include "openscad_cpp_evaluator/eval_use.hpp"
24
24
  #include "openscad_cpp_evaluator/evaluator.hpp"
25
+ #include "openscad_cpp_evaluator/export.hpp"
25
26
  #include "openscad_cpp_evaluator/mesh_check.hpp"
26
27
  #include "openscad_cpp_evaluator/manifold_cache.hpp"
27
28
  #include "openscad_cpp_evaluator/profile.hpp"
@@ -340,6 +341,36 @@ std::pair<nb::dict, nb::object> dynStateToPy(const oscadeval::EvalContext& ctx)
340
341
  // message as a Python exception on ParseError/EvalError (nanobind maps
341
342
  // std::exception -> RuntimeError, whose str() is the already-formatted
342
343
  // "ERROR:..."/caret diagnostic; the facade re-raises as EvalError).
344
+ // The evaluated bodies, kept on the C++ side.
345
+ //
346
+ // bodyToDict flattens every Manifold into numpy arrays for the renderer,
347
+ // which is all the renderer needs -- but export has to do real CSG (the
348
+ // union, the per-colour claim, decompose), and rebuilding Manifolds from
349
+ // those arrays to do it costs ~146ms on a 224k-triangle model and throws
350
+ // away Manifold's own provenance. Handing back an opaque handle instead
351
+ // means geometry never round-trips through Python at all.
352
+ struct Geometry {
353
+ std::vector<oscadeval::ColoredBody> bodies;
354
+ };
355
+
356
+ // exportModel, with the path/format/warnings marshalling. Releases the GIL:
357
+ // a large export is seconds of Manifold work with no Python involved.
358
+ nb::list exportModelPy(const std::string& path, const Geometry& geom, const std::string& format, bool asciiStl,
359
+ bool stripSlivers) {
360
+ std::vector<std::string> warnings;
361
+ {
362
+ nb::gil_scoped_release rel;
363
+ oscadeval::ExportOptions opts;
364
+ opts.format = format;
365
+ opts.asciiStl = asciiStl;
366
+ opts.stripSlivers = stripSlivers;
367
+ warnings = oscadeval::exportModel(path, geom.bodies, opts);
368
+ }
369
+ nb::list out;
370
+ for (const std::string& w : warnings) out.append(w);
371
+ return out;
372
+ }
373
+
343
374
  nb::object evaluate(const std::string& path, nb::dict viewportParams,
344
375
  std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, bool profile) {
345
376
  std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
@@ -370,8 +401,10 @@ nb::object evaluate(const std::string& path, nb::dict viewportParams,
370
401
 
371
402
  nb::list echoList;
372
403
  for (const std::string& s : echoes) echoList.append(s);
373
- return nb::make_tuple(bodiesToList(bodies), echoList, idSpansToDict(idSpans), csgTreeToPy(csgTree),
374
- profileResultToPy(profileResult), dyn, dynExplicit);
404
+ auto geom = std::make_shared<Geometry>();
405
+ geom->bodies = std::move(bodies);
406
+ return nb::make_tuple(bodiesToList(geom->bodies), echoList, idSpansToDict(idSpans), csgTreeToPy(csgTree),
407
+ profileResultToPy(profileResult), dyn, dynExplicit, geom);
375
408
  }
376
409
 
377
410
  // ------------------------------------------------------------------------
@@ -721,6 +754,19 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
721
754
  .def(nb::init<>())
722
755
  .def("request", &FastContinueSignal::request);
723
756
 
757
+ nb::class_<Geometry>(m, "Geometry",
758
+ "Opaque handle to the evaluated bodies, kept on the C++ side so export never has to "
759
+ "rebuild Manifolds from the renderer's flattened arrays. Hand it to export_model().")
760
+ .def("__len__", [](const Geometry& g) { return g.bodies.size(); })
761
+ .def("is_empty", [](const Geometry& g) { return g.bodies.empty(); });
762
+
763
+ m.def("export_model", &exportModelPy, nb::arg("path"), nb::arg("geometry"), nb::arg("format") = std::string(),
764
+ nb::arg("ascii_stl") = false, nb::arg("strip_slivers") = true,
765
+ "Write `geometry` to `path`, format taken from the extension unless `format` says otherwise. "
766
+ "Returns the warnings to surface (open shells, mesh problems, slivers removed) rather than "
767
+ "logging them. Raises RuntimeError when there is no geometry, the format is unknown, or the "
768
+ "file cannot be opened.");
769
+
724
770
  m.def("evaluate", &evaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("manifold_cache") = nullptr,
725
771
  nb::arg("profile") = false,
726
772
  "Evaluate a .scad file; return (bodies, echoes, id_to_node, csg_tree, profile_result, dyn, dyn_explicit).");
@@ -0,0 +1,144 @@
1
+ #pragma once
2
+
3
+ #include "openscad_cpp_evaluator/colored_body.hpp"
4
+
5
+ #include <array>
6
+ #include <cstdint>
7
+ #include <string>
8
+ #include <vector>
9
+
10
+ namespace oscadeval {
11
+
12
+ // The colour every object falls back to when the script gave none.
13
+ inline constexpr std::array<float, 4> kDefaultExportColor = {0.8f, 0.8f, 0.8f, 1.0f};
14
+
15
+ // One object in a file format that can hold more than one -- 3MF, OBJ,
16
+ // VRML, X3D. `triColors` is empty for the ordinary flat-coloured object,
17
+ // or one RGBA per triangle when the surface came out of a multi-colour CSG
18
+ // merge (see splitBodiesForExport).
19
+ struct ExportObject {
20
+ std::vector<float> verts; // xyz triples
21
+ std::vector<uint32_t> tris; // vertex-index triples
22
+ std::array<float, 4> color = kDefaultExportColor;
23
+ std::vector<std::array<float, 4>> triColors;
24
+ };
25
+
26
+ // The implicit top-level union, cut into objects that never overlap.
27
+ //
28
+ // Top level in OpenSCAD is an implicit union, so `cube(100); cube(100,
29
+ // center=true);` is ONE solid -- writing the bodies as they arrive put both
30
+ // cubes in the file separately, overlapping, with their interior faces
31
+ // intact. Three rules, in order:
32
+ //
33
+ // 1. Union, never concatenate. Concatenating is only right while the
34
+ // bodies are disjoint; where two touch, each writes its own copy of
35
+ // the shared face and the result is non-manifold.
36
+ // 2. One object per colour, and no two objects share volume. Where
37
+ // differently-coloured solids overlap the LATER one owns the shared
38
+ // volume and the earlier is notched around it -- painter's order, so
39
+ // `color("red") body(); color("blue") detail();` leaves the detail
40
+ // whole. Only the invisible interior is affected: the visible surface
41
+ // is identical either way.
42
+ // 3. One object per connected component.
43
+ //
44
+ // A body Manifold rejected (an open shell is not a solid) can take part in
45
+ // none of that: it keeps its own triangles and its own object, and its
46
+ // 1-based index is appended to `openParts` for the caller to warn about.
47
+ std::vector<ExportObject> splitBodiesForExport(const std::vector<ColoredBody>& bodies,
48
+ std::vector<int>* openParts = nullptr);
49
+
50
+ // Writes a binary STL: composes every body's mesh into one solid (bodies
51
+ // with no `.body` -- 2D-only sections -- or an empty Manifold are
52
+ // skipped), per-triangle normals computed from vertex winding. Mirrors
53
+ // export.py's write_stl exactly (80-byte zero header, uint32 LE triangle
54
+ // count, 50 bytes/triangle: 3x float32 normal, 3x3 float32 vertices,
55
+ // uint16 attr=0). Throws std::runtime_error if there's no 3D geometry to
56
+ // export, or if the file can't be opened for writing.
57
+ //
58
+ // 3MF and format-from-extension dispatch land in Phase 5 per the plan's
59
+ // phased build order.
60
+ // One message per body that is not a closed manifold solid, ready to print.
61
+ // Empty when everything is sound.
62
+ //
63
+ // Returned rather than logged so each front end can surface it its own way,
64
+ // and so export.cpp needs no logging dependency. Nothing here refuses to
65
+ // write: a deliberately open surface is a legitimate thing to export, and
66
+ // silently blocking a save would be worse than an honest warning.
67
+ std::vector<std::string> checkExportBodies(const std::vector<ColoredBody>& bodies);
68
+
69
+ void writeStl(const std::string& path, const std::vector<ColoredBody>& bodies);
70
+
71
+ // OpenSCAD-compatible ASCII STL -- "solid OpenSCAD_Model" / one "facet
72
+ // normal .. outer loop .. vertex x3 .. endloop endfacet" per triangle /
73
+ // "endsolid". Format confirmed against real OpenSCAD's own -o out.stl.
74
+ void writeStlAscii(const std::string& path, const std::vector<ColoredBody>& bodies);
75
+
76
+ // Wavefront OBJ: one `o` group per object, `usemtl` naming a material in a
77
+ // companion .mtl written alongside (so an OBJ export produces TWO files).
78
+ // A multi-coloured surface becomes runs of faces with a `usemtl` between
79
+ // them, in triangle order -- the only per-face colour OBJ has.
80
+ void writeObj(const std::string& path, const std::vector<ExportObject>& objects);
81
+
82
+ // Binary little-endian PLY, one flat mesh with per-vertex colour. PLY has
83
+ // no object concept, so the objects are concatenated; an object carrying
84
+ // per-triangle colour is unwelded (three vertices per triangle), since a
85
+ // vertex shared by two differently-coloured triangles has no single answer.
86
+ void writePly(const std::string& path, const std::vector<ExportObject>& objects);
87
+
88
+ // VRML97 ("#VRML V2.0 utf8"), one Shape per object. Per-face colour rides
89
+ // on a Color node with `colorPerVertex FALSE`. Neither this nor X3D can
90
+ // carry per-triangle alpha, so the object's base alpha applies to the whole
91
+ // shape through Material.transparency (which is 1 - alpha).
92
+ void writeVrml(const std::string& path, const std::vector<ExportObject>& objects);
93
+
94
+ // X3D 3.3, Interchange profile -- the XML encoding of what writeVrml emits,
95
+ // node for node. Interchange is the accurate claim: per Annex B it is
96
+ // Geometry3D level 2 (IndexedFaceSet), Rendering level 3 (Coordinate,
97
+ // Color) and Shape level 1 (Appearance, Material), exactly the nodes used.
98
+ void writeX3d(const std::string& path, const std::vector<ExportObject>& objects);
99
+
100
+ // OFF (Object File Format): header "OFF", "$verts $tris 0", vertex lines,
101
+ // then "3 i j k" per triangle (0-indexed, count-prefixed). Mirrors
102
+ // export.py's write_off.
103
+ void writeOff(const std::string& path, const std::vector<ColoredBody>& bodies);
104
+
105
+ // 3MF: one mesh object + a base-color colorgroup per body (skipping empty
106
+ // bodies), written as a DEFLATE-compressed ZIP (writeDeflateZip, see
107
+ // zip_stored.hpp) -- the XML is highly compressible, so storing it would
108
+ // make the file several times larger for nothing. An entry that does not
109
+ // actually shrink is stored raw, as any ZIP writer would.
110
+ // Mirrors export.py's write_3mf's XML shape exactly (core + material
111
+ // namespaces, %.6g vertex formatting); throws std::runtime_error if there's
112
+ // no geometry to export.
113
+ void writeThreeMf(const std::string& path, const std::vector<ExportObject>& objects);
114
+
115
+ // -- one entry point ------------------------------------------------------
116
+
117
+ struct ExportOptions {
118
+ // Empty means "decide from the path's extension".
119
+ std::string format;
120
+ // .stl only; binary otherwise.
121
+ bool asciiStl = false;
122
+ // Remove zero-area faces before writing the single-mesh formats. They
123
+ // break no topology, but slicers commonly discard them and are then
124
+ // left with the holes their removal opens.
125
+ bool stripSlivers = true;
126
+ };
127
+
128
+ // Writes `bodies` to `path`, choosing the writer from the extension (or
129
+ // opts.format) and applying the same repair/verification policy the GUI
130
+ // used to apply itself. Returns the warnings to surface -- open shells,
131
+ // mesh problems, sliver removal -- rather than logging them, so each front
132
+ // end can present them its own way.
133
+ //
134
+ // Nothing here refuses to write: a deliberately open surface is a
135
+ // legitimate export, and blocking a save the user asked for would be worse
136
+ // than saying so. Throws std::runtime_error only when there is no geometry
137
+ // at all, the format is unknown, or the file cannot be opened.
138
+ std::vector<std::string> exportModel(const std::string& path, const std::vector<ColoredBody>& bodies,
139
+ const ExportOptions& opts = {});
140
+
141
+ // The extensions exportModel understands, lower-case and dot-prefixed.
142
+ const std::vector<std::string>& exportExtensions();
143
+
144
+ } // namespace oscadeval
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_cpp_evaluator"
7
- version = "0.30.0"
7
+ version = "0.31.0"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -19,6 +19,7 @@ __all__ = [
19
19
  "Evaluator", "ColoredBody", "EvalError", "ParseError", "OscObject", "parse", "to_renderable_bodies",
20
20
  "ManifoldCache", "CallSiteProfile", "ProfileResult", "format_csg_tree", "bodies_from_dicts",
21
21
  "FastContinueSignal", "parse_ast", "parse_ast_string", "check_mesh", "strip_slivers",
22
+ "export_model", "export_extensions",
22
23
  ]
23
24
 
24
25
 
@@ -288,6 +289,36 @@ def strip_slivers(verts, tris):
288
289
  return _ext.strip_slivers([float(v) for v in verts], [int(t) for t in tris])
289
290
 
290
291
 
292
+ def export_model(path: str, geometry, format: str = "", ascii_stl: bool = False,
293
+ strip_slivers: bool = True) -> list:
294
+ """Write `geometry` to `path`. Returns the warnings to surface.
295
+
296
+ `geometry` is the handle an Evaluator stashes on itself as
297
+ `.geometry` -- the evaluated bodies, still on the C++ side. Export has
298
+ to do real CSG (the implicit top-level union, the per-colour volume
299
+ claim, the connected-component split), and going through the flattened
300
+ arrays the renderer gets would mean rebuilding every Manifold first:
301
+ ~146ms on a 224k-triangle model, and Manifold's own provenance lost
302
+ along the way.
303
+
304
+ Format comes from the extension unless `format` overrides it. Warnings
305
+ -- open shells, mesh problems, slivers removed -- are returned rather
306
+ than logged so each front end can present them its own way. Nothing
307
+ here refuses to write: a deliberately open surface is a legitimate
308
+ export. Raises EvalError when there is no geometry, the format is
309
+ unknown, or the file cannot be opened.
310
+ """
311
+ try:
312
+ return list(_ext.export_model(path, geometry, format, ascii_stl, strip_slivers))
313
+ except Exception as e:
314
+ raise EvalError(str(e)) from e
315
+
316
+
317
+ def export_extensions() -> list:
318
+ """The file extensions export_model understands, dot-prefixed."""
319
+ return [".3mf", ".stl", ".obj", ".off", ".ply", ".wrl", ".x3d"]
320
+
321
+
291
322
  def check_mesh(verts, tris) -> dict:
292
323
  """Diagnose a triangle mesh against the manifoldness conditions.
293
324
 
@@ -448,9 +479,21 @@ class Evaluator:
448
479
  self._manifold_cache, self._return_hook, self._fast_continue_signal)
449
480
  self.csg_tree = []
450
481
  self.profile_result = None
482
+ # The debugger path has no geometry handle: debug_evaluate
483
+ # returns bodies for display only, and a paused session is
484
+ # not something to export from.
485
+ self.geometry = None
451
486
  else:
452
- body_dicts, echoes, id_spans, csg_tree, profile_result, dyn, dyn_explicit = _ext.evaluate(
487
+ (body_dicts, echoes, id_spans, csg_tree, profile_result, dyn,
488
+ dyn_explicit, geometry) = _ext.evaluate(
453
489
  source_path, vp, self._manifold_cache, self._profile)
490
+ # The evaluated bodies, still on the C++ side. Stashed like
491
+ # csg_tree/profile_result rather than returned, so
492
+ # evaluate()'s own 2-tuple result is unchanged -- callers
493
+ # that only render never need to know this exists. Hand it
494
+ # to export_model(); see its docstring for why export does
495
+ # not just rebuild from the arrays the renderer gets.
496
+ self.geometry = geometry
454
497
  if self._echo_fn:
455
498
  for line in echoes:
456
499
  self._echo_fn(line)