openscad-cpp-evaluator 1.26.0__tar.gz → 1.27.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 (221) hide show
  1. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/CLAUDE.md +6 -0
  2. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/PKG-INFO +1 -1
  3. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/bindings/module.cpp +16 -6
  4. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/colored_body.hpp +8 -1
  5. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/pyproject.toml +1 -1
  6. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/python/openscad_cpp_evaluator/__init__.py +11 -3
  7. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/colored_body.cpp +4 -6
  8. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_python_bindings.py +25 -0
  9. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/.github/workflows/ci.yml +0 -0
  10. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/.github/workflows/wheels.yml +0 -0
  11. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/.gitignore +0 -0
  12. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/.gitmodules +0 -0
  13. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/CMakeLists.txt +0 -0
  14. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/LICENSE +0 -0
  15. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/README.md +0 -0
  16. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/bindings/CMakeLists.txt +0 -0
  17. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/bindings/ast_to_py.cpp +0 -0
  18. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/cmake/embed_font.cmake +0 -0
  19. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/examples/CMakeLists.txt +0 -0
  20. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/examples/eval_perf_benchmark.cpp +0 -0
  21. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/examples/manifold_cache_reuse.cpp +0 -0
  22. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/examples/minimal_debugger.cpp +0 -0
  23. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  24. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/.gitignore +0 -0
  25. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  26. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  27. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/README.md +0 -0
  28. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  29. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  30. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  31. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  32. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  33. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  34. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  35. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  36. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  37. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  38. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  39. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  40. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  41. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
  42. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  43. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  44. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  45. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  46. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  47. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  48. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  49. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  50. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  51. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  52. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  53. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  54. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  55. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  56. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  57. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  58. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  59. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  60. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  61. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  62. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  63. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  64. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  65. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  66. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  67. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  68. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  69. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  70. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  71. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  72. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  73. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  74. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  75. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  76. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  77. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  78. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  79. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  80. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  81. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  82. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
  83. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  84. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  85. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  86. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  87. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
  88. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  89. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  90. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  91. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  92. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  93. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
  94. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  95. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
  96. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  97. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
  98. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  99. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  100. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  101. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  102. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  103. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  104. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  105. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  106. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  107. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
  108. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
  109. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
  110. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  111. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
  112. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
  113. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  114. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  115. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  116. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  117. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  118. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  119. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  120. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  121. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  122. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  123. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  124. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
  125. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
  126. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  127. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LICENSE +0 -0
  128. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
  129. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
  130. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
  131. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  132. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/CMakeLists.txt +0 -0
  133. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/booleans.cpp +0 -0
  134. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/builtins.hpp +0 -0
  135. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/call_args.cpp +0 -0
  136. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/color.cpp +0 -0
  137. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/control.cpp +0 -0
  138. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/dxf_dim.cpp +0 -0
  139. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/extrude.cpp +0 -0
  140. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/function_builtins.cpp +0 -0
  141. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/import.cpp +0 -0
  142. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/modifiers.cpp +0 -0
  143. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/primitives_2d.cpp +0 -0
  144. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/primitives_3d.cpp +0 -0
  145. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/registry.cpp +0 -0
  146. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/roof.cpp +0 -0
  147. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/segments.cpp +0 -0
  148. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/surface.cpp +0 -0
  149. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/text.cpp +0 -0
  150. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/topology.cpp +0 -0
  151. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/builtins/transforms.cpp +0 -0
  152. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/bytecode_compiler.cpp +0 -0
  153. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/bytecode_vm.cpp +0 -0
  154. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/coverage.cpp +0 -0
  155. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/csg_generate.cpp +0 -0
  156. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/csg_resolve.cpp +0 -0
  157. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/css_colors.cpp +0 -0
  158. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/debug/debug_repl.cpp +0 -0
  159. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/debug_profile.cpp +0 -0
  160. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/eval_context.cpp +0 -0
  161. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/eval_error.cpp +0 -0
  162. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/eval_use.cpp +0 -0
  163. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/export.cpp +0 -0
  164. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/expr_eval.cpp +0 -0
  165. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/format_closure.cpp +0 -0
  166. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/import/dxf_import.cpp +0 -0
  167. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/import/mesh_import.cpp +0 -0
  168. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/import/surface_load.cpp +0 -0
  169. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/import/svg_import.cpp +0 -0
  170. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/manifold_cache.cpp +0 -0
  171. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/measure_geometry.cpp +0 -0
  172. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/mesh_check.cpp +0 -0
  173. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/stmt_eval.cpp +0 -0
  174. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/text/font_match.cpp +0 -0
  175. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/text/freetype_font_provider.cpp +0 -0
  176. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/text/text_metrics.cpp +0 -0
  177. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/user_calls.cpp +0 -0
  178. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/utf8.cpp +0 -0
  179. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/value.cpp +0 -0
  180. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/src/zip_stored.cpp +0 -0
  181. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/CMakeLists.txt +0 -0
  182. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_booleans.cpp +0 -0
  183. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_bytecode_compiler.cpp +0 -0
  184. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_children_separate.cpp +0 -0
  185. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_cli.cpp +0 -0
  186. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_control_flow.cpp +0 -0
  187. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_coverage.cpp +0 -0
  188. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_csg_tree.cpp +0 -0
  189. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_debug_hooks.cpp +0 -0
  190. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_dxf_svg_import.cpp +0 -0
  191. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_eval_context.cpp +0 -0
  192. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_export.cpp +0 -0
  193. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_expr_eval.cpp +0 -0
  194. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_extrude_roof.cpp +0 -0
  195. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_feature_detection.cpp +0 -0
  196. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_function_builtins.cpp +0 -0
  197. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_helpers.hpp +0 -0
  198. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_import_export.cpp +0 -0
  199. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_include_cache.cpp +0 -0
  200. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_manifold_cache.cpp +0 -0
  201. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_mesh_check.cpp +0 -0
  202. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_multi_color_merge.cpp +0 -0
  203. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_primitives.cpp +0 -0
  204. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_profiling.cpp +0 -0
  205. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_render_expr.cpp +0 -0
  206. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_scope_trail.cpp +0 -0
  207. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_scoping.cpp +0 -0
  208. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_surface.cpp +0 -0
  209. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_tail_calls.cpp +0 -0
  210. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_text.cpp +0 -0
  211. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_transforms.cpp +0 -0
  212. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_unexpected_args.cpp +0 -0
  213. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_use.cpp +0 -0
  214. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_value.cpp +0 -0
  215. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_viewport_params.cpp +0 -0
  216. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tests/test_zip_stored.cpp +0 -0
  217. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/CMakeLists.txt +0 -0
  218. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/cli_lib.cpp +0 -0
  219. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/cli_lib.hpp +0 -0
  220. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/tools/cli/main.cpp +0 -0
  221. {openscad_cpp_evaluator-1.26.0 → openscad_cpp_evaluator-1.27.0}/uv.lock +0 -0
@@ -1135,6 +1135,12 @@ grep for `ponytail:`.
1135
1135
  `writeSvg`, which needs the sections that step throws away, and which says so rather than writing
1136
1136
  the slab's outline. `tools/cli/cli_lib.cpp` is the only current caller; a future GUI/renderer
1137
1137
  caller needs the same call before passing results to its own mesh consumer.
1138
+ **The slab height is a parameter** (`flatHeight`, default `kTopLevel2dHeight` = 1.0, the
1139
+ reference's measured preview height that docs images and `--viewall` framing depend on). Python
1140
+ reaches it as `Evaluator(flat_preview_height=...)`, which thins only the DISPLAYED bodies:
1141
+ `evaluate()` converts the raw list a second time at 1.0 for `geometry`, because a 2D-only script
1142
+ exports its slab and that must not become whatever a viewer found easiest to look at. BelfrySCAD's
1143
+ viewport asks for 0.01 so a 2D shape reads as the flat contour it is.
1138
1144
  - `include/openscad_cpp_evaluator/function_builtins.hpp`, `src/builtins/function_builtins.cpp` —
1139
1145
  the math/string/list/type-check builtin *function* dispatch (`isBuiltinFunctionName`/
1140
1146
  `evalBuiltinFunction`), a completely separate namespace/table from `dispatch.hpp`'s builtin
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 1.26.0
3
+ Version: 1.27.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT
@@ -505,10 +505,15 @@ nb::object coverageResultToPy(const std::optional<oscadeval::CoverageResult>& cr
505
505
 
506
506
  nb::object evaluate(const std::string& path, nb::dict viewportParams,
507
507
  std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, bool profile,
508
- bool generate, bool strictCommas, bool coverage, bool keepMinuendColor) {
508
+ bool generate, bool strictCommas, bool coverage, bool keepMinuendColor,
509
+ double flatPreviewHeight) {
509
510
  std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
510
511
 
511
512
  std::vector<oscadeval::ColoredBody> bodies;
513
+ // What export gets. The same list as `bodies` unless the caller asked
514
+ // for a thinner preview slab: a 2D-only script exports its slab, and
515
+ // that must stay the reference's 1 unit whatever the viewer shows.
516
+ std::vector<oscadeval::ColoredBody> exportBodies;
512
517
  std::vector<std::string> echoes;
513
518
  std::vector<IdSpan> idSpans;
514
519
  std::vector<std::unique_ptr<oscadeval::CSGNode>> csgTree;
@@ -532,7 +537,10 @@ nb::object evaluate(const std::string& path, nb::dict viewportParams,
532
537
  ev.keepMinuendColor = keepMinuendColor;
533
538
  ev.setUsedFileGlobals(used.usedFileGlobals);
534
539
  oscadeval::EvalContext ctx = oscadeval::EvalContext::makeRoot(used.rootScope.get());
535
- bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp, generate));
540
+ std::vector<oscadeval::ColoredBody> raw = ev.evaluate(used.processedNodes, ctx, vp, generate);
541
+ bodies = oscadeval::toRenderableBodies(raw, flatPreviewHeight);
542
+ exportBodies = flatPreviewHeight == oscadeval::kTopLevel2dHeight
543
+ ? bodies : oscadeval::toRenderableBodies(raw);
536
544
  collectIdSpans(ev, idSpans);
537
545
  // Only moved out when it will actually be converted below --
538
546
  // csgTreeToPy() walks the whole tree building Python objects,
@@ -567,8 +575,8 @@ nb::object evaluate(const std::string& path, nb::dict viewportParams,
567
575
  nb::list echoList;
568
576
  for (const std::string& s : echoes) echoList.append(s);
569
577
  auto geom = std::make_shared<Geometry>();
570
- geom->bodies = std::move(bodies);
571
- return nb::make_tuple(bodiesToList(geom->bodies), echoList, idSpansToDict(idSpans), csgTreeToPy(csgTree),
578
+ geom->bodies = std::move(exportBodies);
579
+ return nb::make_tuple(bodiesToList(bodies), echoList, idSpansToDict(idSpans), csgTreeToPy(csgTree),
572
580
  profileResultToPy(profileResult), dyn, dynExplicit, geom, coverageResultToPy(coverageResult));
573
581
  }
574
582
 
@@ -780,7 +788,7 @@ void callPyReturnHook(nb::handle returnHook, const std::string& name, const osca
780
788
  nb::object debugEvaluate(const std::string& path, nb::dict viewportParams, nb::callable debugHook,
781
789
  nb::callable errorBreak, nb::callable echoFn,
782
790
  std::shared_ptr<oscadeval::ManifoldCache> manifoldCache, nb::object returnHook,
783
- FastContinueSignal* fastContinueSignal) {
791
+ FastContinueSignal* fastContinueSignal, double flatPreviewHeight) {
784
792
  std::unordered_map<std::string, oscadeval::Value> vp = toViewportParams(viewportParams);
785
793
 
786
794
  std::vector<oscadeval::ColoredBody> bodies;
@@ -841,7 +849,7 @@ nb::object debugEvaluate(const std::string& path, nb::dict viewportParams, nb::c
841
849
  if (fastContinueSignal) ev.setFastContinueInterruptFlag(fastContinueSignal->flag());
842
850
  ev.setUsedFileGlobals(used.usedFileGlobals);
843
851
  oscadeval::EvalContext ctx = oscadeval::EvalContext::makeRoot(used.rootScope.get());
844
- bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp));
852
+ bodies = oscadeval::toRenderableBodies(ev.evaluate(used.processedNodes, ctx, vp), flatPreviewHeight);
845
853
  collectIdSpans(ev, idSpans);
846
854
  {
847
855
  nb::gil_scoped_acquire g;
@@ -985,6 +993,7 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
985
993
  m.def("evaluate", &evaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("manifold_cache") = nullptr,
986
994
  nb::arg("profile") = false, nb::arg("generate") = true, nb::arg("strict_commas") = false,
987
995
  nb::arg("coverage") = false, nb::arg("keep_minuend_color") = false,
996
+ nb::arg("flat_preview_height") = oscadeval::kTopLevel2dHeight,
988
997
  "Evaluate a .scad file; return (bodies, echoes, id_to_node, csg_tree, profile_result, dyn, dyn_explicit, "
989
998
  "geometry, coverage_result).\n"
990
999
  "coverage=True records which statements, branch arms and bodies ran: coverage_result is a dict "
@@ -1024,5 +1033,6 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
1024
1033
  m.def("debug_evaluate", &debugEvaluate, nb::arg("path"), nb::arg("viewport_params"), nb::arg("debug_hook"),
1025
1034
  nb::arg("error_break"), nb::arg("echo_fn"), nb::arg("manifold_cache") = nullptr,
1026
1035
  nb::arg("return_hook") = nb::none(), nb::arg("fast_continue_signal") = nullptr,
1036
+ nb::arg("flat_preview_height") = oscadeval::kTopLevel2dHeight,
1027
1037
  "Evaluate with the debugger wired in; returns (bodies, [], id_to_node, dyn, dyn_explicit). Callbacks fire under the GIL.");
1028
1038
  }
@@ -169,6 +169,13 @@ std::optional<std::array<float, 4>> valueToColor(const Value& v);
169
169
  // (the CLI, any other mesh-export caller) should apply this to
170
170
  // Evaluator::evaluate()'s result before exporting, the same way the
171
171
  // reference's own cli.py does right before export_bodies().
172
- std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies);
172
+ // The thickness toRenderableBodies() gives a top-level 2D shape's slab by
173
+ // default: OpenSCAD's own preview height, measured (see colored_body.cpp).
174
+ // Docs images and exports use it; an interactive viewer may pass a thinner
175
+ // one so a 2D shape reads as the flat contour it is.
176
+ inline constexpr double kTopLevel2dHeight = 1.0;
177
+
178
+ std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies,
179
+ double flatHeight = kTopLevel2dHeight);
173
180
 
174
181
  } // 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 = "1.26.0"
7
+ version = "1.27.0"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -565,7 +565,7 @@ class Evaluator:
565
565
 
566
566
  def __init__(self, echo_fn=None, debug_hook=None, error_break_fn=None, return_hook=None,
567
567
  manifold_cache=None, profile=False, fast_continue_signal=None, coverage=False,
568
- keep_minuend_color=False):
568
+ keep_minuend_color=False, flat_preview_height=1.0):
569
569
  self._echo_fn = echo_fn
570
570
  self._debug_hook = debug_hook
571
571
  self._error_break_fn = error_break_fn
@@ -579,6 +579,12 @@ class Evaluator:
579
579
  # subtrahend's (or the cut green). A viewer option; see
580
580
  # Evaluator::keepMinuendColor in evaluator.hpp.
581
581
  self._keep_minuend_color = keep_minuend_color
582
+ # How thick a top-level 2D shape's preview slab is in the returned
583
+ # bodies. 1.0 is OpenSCAD's preview height, which docs images and
584
+ # --viewall framing depend on; a viewer can pass something thin so
585
+ # a 2D shape reads as a flat contour. Export (`geometry`) always
586
+ # keeps 1.0: a 2D-only script exports its slab.
587
+ self._flat_preview_height = float(flat_preview_height)
582
588
  self.csg_tree = []
583
589
  self.profile_result = None
584
590
  # coverage=True: after evaluate(), {"spans": [...], "files": [...],
@@ -621,7 +627,8 @@ class Evaluator:
621
627
  source_path, vp, self._debug_hook,
622
628
  self._error_break_fn or (lambda *a, **k: None),
623
629
  self._echo_fn or (lambda _m: None),
624
- self._manifold_cache, self._return_hook, self._fast_continue_signal)
630
+ self._manifold_cache, self._return_hook, self._fast_continue_signal,
631
+ self._flat_preview_height)
625
632
  self.csg_tree = []
626
633
  self.profile_result = None
627
634
  # The debugger path has no geometry handle: debug_evaluate
@@ -632,7 +639,8 @@ class Evaluator:
632
639
  (body_dicts, echoes, id_spans, csg_tree, profile_result, dyn,
633
640
  dyn_explicit, geometry, coverage_result) = _ext.evaluate(
634
641
  source_path, vp, self._manifold_cache, self._profile, generate,
635
- strict_commas, self._coverage, self._keep_minuend_color)
642
+ strict_commas, self._coverage, self._keep_minuend_color,
643
+ self._flat_preview_height)
636
644
  # The evaluated bodies, still on the C++ side. Stashed like
637
645
  # csg_tree/profile_result rather than returned, so
638
646
  # evaluate()'s own 2-tuple result is unchanged -- callers
@@ -20,23 +20,21 @@ std::optional<std::array<float, 4>> valueToColor(const Value& v) {
20
20
  return c;
21
21
  }
22
22
 
23
- namespace {
24
- // The reference extrudes a 2D shape to exactly 1 unit for preview -- measured
23
+ // kTopLevel2dHeight (colored_body.hpp), the default slab height: the
24
+ // reference extrudes a 2D shape to exactly 1 unit for preview -- measured
25
25
  // against OpenSCAD at three camera tilts (60/70/80 degrees), which put it at
26
26
  // 0.92/1.00/0.99, the 60 being pixel-rounding on the shallowest angle. Ours
27
27
  // was 1e-3, which reads as a flat silhouette with no visible edge and, more
28
28
  // annoyingly, gives --viewall a different bounding box to fit, so every 2D
29
29
  // docs image came out at a different scale from the published one.
30
- constexpr double kTopLevel2dHeight = 1.0;
31
- } // namespace
32
30
 
33
- std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies) {
31
+ std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodies, double flatHeight) {
34
32
  std::vector<ColoredBody> out;
35
33
  out.reserve(bodies.size());
36
34
  for (const ColoredBody& cb : bodies) {
37
35
  if (!cb.body && cb.section) {
38
36
  ColoredBody flat;
39
- flat.body = manifold::Manifold::Extrude(cb.section->ToPolygons(), kTopLevel2dHeight);
37
+ flat.body = manifold::Manifold::Extrude(cb.section->ToPolygons(), flatHeight);
40
38
  if (cb.sectionId && !flat.body->IsEmpty()) {
41
39
  // One run carrying the section's own ID, so a click on the
42
40
  // slab finds the node that built the shape (see
@@ -1096,3 +1096,28 @@ def test_a_cached_2d_shape_is_picked_as_a_solid_would_be(tmp_path):
1096
1096
  assert all(t is not None for render in flat for body in render for t in body)
1097
1097
  assert flat[1] == [["square(3);"], ["translate([10, 0]) circle(4);"]]
1098
1098
  assert solid[1] == [["cube(3);"], ["translate([10, 0, 0]) sphere(4);"]]
1099
+
1100
+
1101
+ def test_a_viewer_can_ask_for_a_thin_2d_slab_and_export_keeps_1(tmp_path):
1102
+ """flat_preview_height thins the DISPLAYED slab only: a 2D-only script
1103
+ exports that slab, and it has to stay the reference's 1 unit."""
1104
+ import openscad_cpp_evaluator as E
1105
+ script = tmp_path / "flat.scad"
1106
+ script.write_text("square(10);\n")
1107
+
1108
+ def z_extent(bodies):
1109
+ verts = bodies[0].body.to_mesh().vert_properties
1110
+ return float(verts[:, 2].max() - verts[:, 2].min())
1111
+
1112
+ default = E.Evaluator()
1113
+ assert abs(z_extent(default.evaluate(str(script), {})[0]) - 1.0) < 1e-9
1114
+ thin = E.Evaluator(flat_preview_height=0.01)
1115
+ bodies, id_to_node = thin.evaluate(str(script), {})
1116
+ assert abs(z_extent(bodies) - 0.01) < 1e-9
1117
+ assert id_to_node, "still pickable"
1118
+ out = tmp_path / "flat.off" # ASCII: header, counts, vertices
1119
+ E.export_model(str(out), thin.geometry)
1120
+ lines = [l for l in out.read_text().splitlines() if l.strip() and not l.startswith("#")]
1121
+ nverts = int(lines[1].split()[0])
1122
+ zs = [float(l.split()[2]) for l in lines[2:2 + nverts]]
1123
+ assert abs(max(zs) - min(zs) - 1.0) < 1e-6, "export is the 1-unit slab"