openscad-cpp-evaluator 1.10.0__tar.gz → 1.11.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 (215) hide show
  1. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/CLAUDE.md +18 -2
  2. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/PKG-INFO +1 -1
  3. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/bindings/module.cpp +51 -2
  4. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/export.hpp +64 -0
  5. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/zip_stored.hpp +8 -0
  6. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/pyproject.toml +1 -1
  7. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/python/openscad_cpp_evaluator/__init__.py +14 -2
  8. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/export.cpp +378 -14
  9. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/zip_stored.cpp +10 -0
  10. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_export.cpp +293 -0
  11. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_python_bindings.py +44 -0
  12. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/.github/workflows/ci.yml +0 -0
  13. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/.github/workflows/wheels.yml +0 -0
  14. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/.gitignore +0 -0
  15. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/.gitmodules +0 -0
  16. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/CMakeLists.txt +0 -0
  17. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/LICENSE +0 -0
  18. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/README.md +0 -0
  19. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/bindings/CMakeLists.txt +0 -0
  20. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/bindings/ast_to_py.cpp +0 -0
  21. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/cmake/embed_font.cmake +0 -0
  22. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/examples/CMakeLists.txt +0 -0
  23. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/examples/eval_perf_benchmark.cpp +0 -0
  24. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/examples/manifold_cache_reuse.cpp +0 -0
  25. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/examples/minimal_debugger.cpp +0 -0
  26. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  27. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/.gitignore +0 -0
  28. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  29. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  30. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/README.md +0 -0
  31. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  32. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  33. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  34. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  35. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  36. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  37. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  38. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  39. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  40. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  41. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  42. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  43. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  44. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
  45. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  46. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  47. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  48. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  49. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  50. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  51. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  52. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  53. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  54. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  55. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  56. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  57. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  58. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  59. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  60. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  61. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  62. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  63. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  64. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  65. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  66. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  67. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  68. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  69. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  70. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  71. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  72. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  73. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  74. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  75. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  76. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  77. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  78. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  79. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  80. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  81. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  82. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  83. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  84. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  85. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
  86. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  87. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  88. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  89. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  90. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
  91. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  92. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  93. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  94. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  95. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  96. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
  97. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  98. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
  99. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  100. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
  101. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  102. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  103. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  104. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  105. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  106. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  107. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  108. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  109. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  110. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
  111. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
  112. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  113. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
  114. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
  115. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  116. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  117. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  118. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  119. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  120. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  121. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  122. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  123. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  124. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  125. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  126. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
  127. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
  128. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/resources/fonts/LICENSE +0 -0
  129. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  130. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/CMakeLists.txt +0 -0
  131. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/booleans.cpp +0 -0
  132. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/builtins.hpp +0 -0
  133. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/call_args.cpp +0 -0
  134. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/color.cpp +0 -0
  135. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/control.cpp +0 -0
  136. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/dxf_dim.cpp +0 -0
  137. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/extrude.cpp +0 -0
  138. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/function_builtins.cpp +0 -0
  139. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/import.cpp +0 -0
  140. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/modifiers.cpp +0 -0
  141. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/primitives_2d.cpp +0 -0
  142. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/primitives_3d.cpp +0 -0
  143. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/registry.cpp +0 -0
  144. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/roof.cpp +0 -0
  145. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/segments.cpp +0 -0
  146. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/surface.cpp +0 -0
  147. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/text.cpp +0 -0
  148. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/topology.cpp +0 -0
  149. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/builtins/transforms.cpp +0 -0
  150. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/bytecode_compiler.cpp +0 -0
  151. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/bytecode_vm.cpp +0 -0
  152. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/colored_body.cpp +0 -0
  153. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/csg_generate.cpp +0 -0
  154. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/csg_resolve.cpp +0 -0
  155. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/css_colors.cpp +0 -0
  156. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/debug/debug_repl.cpp +0 -0
  157. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/debug_profile.cpp +0 -0
  158. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/eval_context.cpp +0 -0
  159. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/eval_error.cpp +0 -0
  160. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/eval_use.cpp +0 -0
  161. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/expr_eval.cpp +0 -0
  162. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/format_closure.cpp +0 -0
  163. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/import/dxf_import.cpp +0 -0
  164. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/import/mesh_import.cpp +0 -0
  165. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/import/surface_load.cpp +0 -0
  166. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/import/svg_import.cpp +0 -0
  167. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/manifold_cache.cpp +0 -0
  168. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/measure_geometry.cpp +0 -0
  169. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/mesh_check.cpp +0 -0
  170. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/stmt_eval.cpp +0 -0
  171. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/text/font_match.cpp +0 -0
  172. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/text/freetype_font_provider.cpp +0 -0
  173. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/text/text_metrics.cpp +0 -0
  174. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/user_calls.cpp +0 -0
  175. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/utf8.cpp +0 -0
  176. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/src/value.cpp +0 -0
  177. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/CMakeLists.txt +0 -0
  178. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_booleans.cpp +0 -0
  179. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_bytecode_compiler.cpp +0 -0
  180. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_children_separate.cpp +0 -0
  181. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_cli.cpp +0 -0
  182. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_control_flow.cpp +0 -0
  183. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_csg_tree.cpp +0 -0
  184. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_debug_hooks.cpp +0 -0
  185. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_dxf_svg_import.cpp +0 -0
  186. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_eval_context.cpp +0 -0
  187. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_expr_eval.cpp +0 -0
  188. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_extrude_roof.cpp +0 -0
  189. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_feature_detection.cpp +0 -0
  190. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_function_builtins.cpp +0 -0
  191. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_helpers.hpp +0 -0
  192. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_import_export.cpp +0 -0
  193. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_include_cache.cpp +0 -0
  194. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_manifold_cache.cpp +0 -0
  195. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_mesh_check.cpp +0 -0
  196. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_multi_color_merge.cpp +0 -0
  197. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_primitives.cpp +0 -0
  198. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_profiling.cpp +0 -0
  199. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_render_expr.cpp +0 -0
  200. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_scope_trail.cpp +0 -0
  201. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_scoping.cpp +0 -0
  202. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_surface.cpp +0 -0
  203. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_tail_calls.cpp +0 -0
  204. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_text.cpp +0 -0
  205. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_transforms.cpp +0 -0
  206. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_unexpected_args.cpp +0 -0
  207. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_use.cpp +0 -0
  208. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_value.cpp +0 -0
  209. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_viewport_params.cpp +0 -0
  210. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tests/test_zip_stored.cpp +0 -0
  211. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tools/cli/CMakeLists.txt +0 -0
  212. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tools/cli/cli_lib.cpp +0 -0
  213. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tools/cli/cli_lib.hpp +0 -0
  214. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/tools/cli/main.cpp +0 -0
  215. {openscad_cpp_evaluator-1.10.0 → openscad_cpp_evaluator-1.11.0}/uv.lock +0 -0
@@ -916,8 +916,8 @@ grep for `ponytail:`.
916
916
  — skip it and the mesh comes out non-manifold at the seam). Self-contained 2D geometry math here
917
917
  (`dot2`/`len2`/`norm2`, the parabola-canonical-frame rotation in `discretizeArc`) exists nowhere
918
918
  else in this codebase.
919
- - `include/openscad_cpp_evaluator/export.hpp`, `src/export.cpp` — the writers for all nine
920
- formats `exportExtensions()` lists: 3MF, AMF, STL, OBJ, OFF, PLY, SVG, VRML, X3D (3MF via
919
+ - `include/openscad_cpp_evaluator/export.hpp`, `src/export.cpp` — the writers for all ten
920
+ formats `exportExtensions()` lists: 3MF, AMF, PDF, STL, OBJ, OFF, PLY, SVG, VRML, X3D (3MF via
921
921
  `zip_stored.hpp`'s `writeDeflateZip`). **`exportExtensions()` is the one source of truth for
922
922
  which formats exist** — the Python facade and BelfrySCAD's dialog/CLI all ask it rather than
923
923
  restating the list, because three hand-written copies had already drifted far enough that `.off`
@@ -937,6 +937,22 @@ grep for `ponytail:`.
937
937
  binary's, vertex order and 6-vertex line wrap included. A 3D body in the list throws
938
938
  ("Current top level object is not a 2D object"), as OpenSCAD refuses too: there is no projection
939
939
  to fall back on. `ExportOptions::svg` carries OpenSCAD's five `-O export-svg/...` settings.
940
+ **`writePdf` is the other 2D writer**, and shares `collect2d()` with `writeSvg` so the all-2D
941
+ rule and its refusal have one implementation. Everything else differs from SVG: the drawing is
942
+ **centred on a fixed paper size** rather than the page being cut to fit, and **PDF user space is
943
+ Y-up like the model's, so there is NO Y negation** — `pt = mm * 72/25.4` plus a centring offset,
944
+ symmetric in both axes. (OpenSCAD's own file negates Y only because Cairo draws Y-down and then
945
+ flips the whole page; its centring is also a fraction of a point off, because it truncates the
946
+ span to an `int` — a bug, not a spec, so ours centres exactly.) With `showScale` it draws
947
+ OpenSCAD's ruler: two axes at a 30pt margin, ticks every **10mm of model space** (hard-coded —
948
+ `gridSize` drives only the optional grid), labels on every second tick, and the caption telling
949
+ you what to measure. That ruler is the point of the format: it is what lets a printed page reveal
950
+ a printer's scaling error. Text is the **base-14 `/Helvetica`** every reader supplies, so nothing
951
+ is embedded and no font metrics are needed — Cairo's subset-embedded font is a Cairo habit, not a
952
+ PDF requirement, and skipping it is what turned this from a project into a writer. The content
953
+ stream is Flate-compressed through `zip_stored.hpp`'s `zlibCompress` (PDF's `/FlateDecode` *is* a
954
+ zlib stream), falling back to raw when that would not shrink it. `writePdf` returns warnings
955
+ rather than `void`: a model too big for the page is drawn anyway and said so.
940
956
  `colored_body.hpp`/`.cpp`'s `toRenderableBodies()` (thin-extrudes any top-level 2D-only result to
941
957
  a 1-unit-tall `flatPreview` Manifold) must run on a body list before handing it to any of the
942
958
  MESH writers — none of them look at `ColoredBody::section` at all, only `.body`. Not before
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 1.10.0
3
+ Version: 1.11.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT
@@ -356,13 +356,56 @@ struct Geometry {
356
356
 
357
357
  // exportModel, with the path/format/warnings marshalling. Releases the GIL:
358
358
  // a large export is seconds of Manifold work with no Python involved.
359
+ // The PDF option set is big enough (paper size, orientation, four
360
+ // ruler switches, fill/stroke, four metadata fields) that a dict keyed the
361
+ // way OpenSCAD names its own `-O export-pdf/...` settings is kinder than
362
+ // fourteen keyword arguments. Unknown keys raise rather than being ignored
363
+ // -- a silently dropped "paper-size" would print the wrong page size with
364
+ // nothing to explain it.
365
+ void applyPdfOptions(const nb::dict& d, oscadeval::ExportPdfOptions& pdf) {
366
+ for (auto item : d) {
367
+ const std::string key = nb::cast<std::string>(item.first);
368
+ const nb::handle v = item.second;
369
+ if (key == "paper-size") {
370
+ const std::string name = nb::cast<std::string>(v);
371
+ if (!oscadeval::paperFromName(name, pdf.paper))
372
+ throw std::runtime_error("unknown paper-size '" + name +
373
+ "' (a6, a5, a4, a3, letter, legal, tabloid)");
374
+ } else if (key == "orientation") {
375
+ const std::string name = nb::cast<std::string>(v);
376
+ if (!oscadeval::orientationFromName(name, pdf.orientation))
377
+ throw std::runtime_error("unknown orientation '" + name + "' (portrait, landscape, auto)");
378
+ } else if (key == "show-scale") pdf.showScale = nb::cast<bool>(v);
379
+ else if (key == "show-scale-message") pdf.showScaleMsg = nb::cast<bool>(v);
380
+ else if (key == "show-grid") pdf.showGrid = nb::cast<bool>(v);
381
+ else if (key == "grid-size") pdf.gridSize = nb::cast<double>(v);
382
+ else if (key == "show-filename") pdf.showFilename = nb::cast<bool>(v);
383
+ else if (key == "design-filename") pdf.designFilename = nb::cast<std::string>(v);
384
+ else if (key == "fill") pdf.fill = nb::cast<bool>(v);
385
+ else if (key == "fill-color") pdf.fillColor = nb::cast<std::string>(v);
386
+ else if (key == "stroke") pdf.stroke = nb::cast<bool>(v);
387
+ else if (key == "stroke-color") pdf.strokeColor = nb::cast<std::string>(v);
388
+ else if (key == "stroke-width") pdf.strokeWidth = nb::cast<double>(v);
389
+ else if (key == "add-meta-data") pdf.addMetaData = nb::cast<bool>(v);
390
+ else if (key == "title") pdf.metaTitle = nb::cast<std::string>(v);
391
+ else if (key == "author") pdf.metaAuthor = nb::cast<std::string>(v);
392
+ else if (key == "subject") pdf.metaSubject = nb::cast<std::string>(v);
393
+ else if (key == "keywords") pdf.metaKeywords = nb::cast<std::string>(v);
394
+ else throw std::runtime_error("unknown pdf option '" + key + "'");
395
+ }
396
+ }
397
+
359
398
  nb::list exportModelPy(const std::string& path, const Geometry& geom, const std::string& format, bool asciiStl,
360
399
  bool stripSlivers, bool splitComponents, bool svgFill, const std::string& svgFillColor,
361
- bool svgStroke, const std::string& svgStrokeColor, double svgStrokeWidth) {
400
+ bool svgStroke, const std::string& svgStrokeColor, double svgStrokeWidth,
401
+ nb::object pdfOptions) {
402
+ oscadeval::ExportPdfOptions pdf;
403
+ if (!pdfOptions.is_none()) applyPdfOptions(nb::cast<nb::dict>(pdfOptions), pdf);
362
404
  std::vector<std::string> warnings;
363
405
  {
364
406
  nb::gil_scoped_release rel;
365
407
  oscadeval::ExportOptions opts;
408
+ opts.pdf = pdf;
366
409
  opts.format = format;
367
410
  opts.asciiStl = asciiStl;
368
411
  opts.stripSlivers = stripSlivers;
@@ -802,6 +845,7 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
802
845
  nb::arg("split_components") = false, nb::arg("svg_fill") = false,
803
846
  nb::arg("svg_fill_color") = std::string("white"), nb::arg("svg_stroke") = true,
804
847
  nb::arg("svg_stroke_color") = std::string("black"), nb::arg("svg_stroke_width") = 0.35,
848
+ nb::arg("pdf_options") = nb::none(),
805
849
  "Write `geometry` to `path`, format taken from the extension unless `format` says otherwise. "
806
850
  "Returns the warnings to surface (open shells, mesh problems, slivers removed) rather than "
807
851
  "logging them. Raises RuntimeError when there is no geometry, the format is unknown, or the "
@@ -811,7 +855,12 @@ NB_MODULE(_openscad_cpp_evaluator, m) {
811
855
  "per colour however many pieces it is in.\n\n"
812
856
  "The svg_* arguments are OpenSCAD's -O export-svg/... set and apply to .svg only. "
813
857
  "svg_stroke/svg_stroke_width also pad the page, so they are not purely cosmetic. An .svg "
814
- "export needs an all-2D model and raises otherwise, as OpenSCAD does.");
858
+ "export needs an all-2D model and raises otherwise, as OpenSCAD does.\n\n"
859
+ "pdf_options is a dict keyed as OpenSCAD names its -O export-pdf/... settings "
860
+ "(paper-size, orientation, show-scale, show-scale-message, show-grid, grid-size, "
861
+ "show-filename, design-filename, fill, fill-color, stroke, stroke-color, stroke-width, "
862
+ "add-meta-data, title, author, subject, keywords). An unknown key raises rather than "
863
+ "being ignored. .pdf is 2D-only too, and centres the drawing on a fixed paper size.");
815
864
 
816
865
  m.def("export_extensions", []() { return oscadeval::exportExtensions(); },
817
866
  "The file extensions export_model understands, dot-prefixed. Read from the C++ writer table "
@@ -157,6 +157,68 @@ struct ExportSvgOptions {
157
157
  void writeSvg(const std::string& path, const std::vector<ColoredBody>& bodies,
158
158
  const ExportSvgOptions& opts = {});
159
159
 
160
+ // Options for the PDF writer, named and defaulted after OpenSCAD's own
161
+ // `-O export-pdf/...` set.
162
+ struct ExportPdfOptions {
163
+ enum class Paper { A6, A5, A4, A3, Letter, Legal, Tabloid };
164
+ // AUTO picks landscape when the model is wider than it is tall.
165
+ enum class Orientation { Portrait, Landscape, Auto };
166
+
167
+ Paper paper = Paper::A4;
168
+ Orientation orientation = Orientation::Portrait;
169
+ // The ruler, its labels and the caption that explains them. This is
170
+ // what makes a printed page a measuring tool rather than a plot, and
171
+ // is why the format was asked for at all.
172
+ bool showScale = true;
173
+ bool showScaleMsg = true;
174
+ bool showGrid = false;
175
+ double gridSize = 10.0;
176
+ // Drawn bottom-left when set. The DESIGN's name -- the writer has no
177
+ // way to know it, so a caller that wants it must pass it.
178
+ bool showFilename = false;
179
+ std::string designFilename;
180
+ bool fill = false;
181
+ std::string fillColor = "black";
182
+ bool stroke = true;
183
+ std::string strokeColor = "black";
184
+ double strokeWidth = 0.35;
185
+ bool addMetaData = true;
186
+ std::string metaTitle;
187
+ std::string metaAuthor;
188
+ std::string metaSubject;
189
+ std::string metaKeywords;
190
+ };
191
+
192
+ // "a4"/"letter"/... (case-insensitive) -> Paper. Returns false for a name
193
+ // it does not know, leaving `out` untouched.
194
+ bool paperFromName(const std::string& name, ExportPdfOptions::Paper& out);
195
+ // "portrait"/"landscape"/"auto" -> Orientation, same contract.
196
+ bool orientationFromName(const std::string& name, ExportPdfOptions::Orientation& out);
197
+
198
+ // PDF 1.4 of a 2D-only model, drawn at 1:1 and CENTRED on a fixed paper
199
+ // size -- unlike SVG, where the page is cut to fit the model.
200
+ //
201
+ // PDF user space is Y-up like model space, so unlike writeSvg there is NO
202
+ // Y negation: the placement is `pt = mm * 72/25.4` plus a centring offset,
203
+ // symmetric in both axes. (OpenSCAD's own file negates Y only because
204
+ // Cairo draws Y-down and then flips the whole page.)
205
+ //
206
+ // With `showScale` on it also draws OpenSCAD's ruler: a left and bottom
207
+ // axis at a 30pt margin, ticks every 10mm of MODEL space (hard-coded --
208
+ // `gridSize` belongs to the optional grid, not to this), numeric labels on
209
+ // every second tick, and the caption explaining what to measure. That
210
+ // ruler is the point of the format: it is what lets a printed page tell
211
+ // you how far off your printer's scaling is.
212
+ //
213
+ // Text uses the base-14 Helvetica every PDF reader supplies, so nothing is
214
+ // embedded and no font metrics are needed.
215
+ //
216
+ // Returns the warnings to surface (a model too large for the page is drawn
217
+ // anyway, and said so). Throws std::runtime_error if any top-level body is
218
+ // 3D, if there is nothing to draw, or if the file cannot be opened.
219
+ std::vector<std::string> writePdf(const std::string& path, const std::vector<ColoredBody>& bodies,
220
+ const ExportPdfOptions& opts = {});
221
+
160
222
  // -- one entry point ------------------------------------------------------
161
223
 
162
224
  struct ExportOptions {
@@ -176,6 +238,8 @@ struct ExportOptions {
176
238
  bool splitComponents = false;
177
239
  // .svg only.
178
240
  ExportSvgOptions svg;
241
+ // .pdf only.
242
+ ExportPdfOptions pdf;
179
243
  };
180
244
 
181
245
  // Writes `bodies` to `path`, choosing the writer from the extension (or
@@ -28,6 +28,14 @@ void writeStoredZip(const std::string& path, const std::vector<ZipEntry>& entrie
28
28
  // std::runtime_error if the file can't be opened for writing.
29
29
  void writeDeflateZip(const std::string& path, const std::vector<ZipEntry>& entries);
30
30
 
31
+ // Compresses `data` to a zlib stream (RFC 1950: 2-byte header, DEFLATE
32
+ // data, Adler-32 trailer) -- which is exactly what PDF's /FlateDecode
33
+ // filter reads, so the PDF writer uses this rather than growing its own
34
+ // compressor. Same stb_image_write.h implementation the ZIP writer above
35
+ // deflates with, only without the wrapper stripped off. Empty if
36
+ // compression fails; the caller can always write the data uncompressed.
37
+ std::vector<uint8_t> zlibCompress(const uint8_t* data, size_t size);
38
+
31
39
  // Reads one entry (by exact name match) from a ZIP archive via its central
32
40
  // directory (authoritative regardless of how local headers were written).
33
41
  // Supports both STORED (method 0, this project's own writeStoredZip()
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_cpp_evaluator"
7
- version = "1.10.0"
7
+ version = "1.11.0"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -295,7 +295,7 @@ def export_model(path: str, geometry, format: str = "", ascii_stl: bool = False,
295
295
  strip_slivers: bool = True, split_components: bool = False,
296
296
  svg_fill: bool = False, svg_fill_color: str = "white",
297
297
  svg_stroke: bool = True, svg_stroke_color: str = "black",
298
- svg_stroke_width: float = 0.35) -> list:
298
+ svg_stroke_width: float = 0.35, pdf_options: dict | None = None) -> list:
299
299
  """Write `geometry` to `path`. Returns the warnings to surface.
300
300
 
301
301
  `geometry` is the handle an Evaluator stashes on itself as
@@ -321,11 +321,23 @@ def export_model(path: str, geometry, format: str = "", ascii_stl: bool = False,
321
321
  `svg_stroke`/`svg_stroke_width` also pad the page, so they are not
322
322
  purely cosmetic. An `.svg` export of anything 3D raises, as OpenSCAD's
323
323
  does -- there is no projection to fall back on.
324
+
325
+ `pdf_options` is a dict keyed the way OpenSCAD names its own
326
+ `-O export-pdf/...` settings: `paper-size`, `orientation`,
327
+ `show-scale`, `show-scale-message`, `show-grid`, `grid-size`,
328
+ `show-filename`, `design-filename`, `fill`, `fill-color`, `stroke`,
329
+ `stroke-color`, `stroke-width`, `add-meta-data`, `title`, `author`,
330
+ `subject`, `keywords`. An unknown key raises rather than being
331
+ ignored -- a silently dropped `paper-size` would print the wrong page
332
+ size with nothing to explain it. `.pdf` is 2D-only like `.svg`, and
333
+ centres the drawing on a fixed paper size instead of cutting the page
334
+ to fit.
324
335
  """
325
336
  try:
326
337
  return list(_ext.export_model(path, geometry, format, ascii_stl, strip_slivers,
327
338
  split_components, svg_fill, svg_fill_color,
328
- svg_stroke, svg_stroke_color, svg_stroke_width))
339
+ svg_stroke, svg_stroke_color, svg_stroke_width,
340
+ pdf_options))
329
341
  except Exception as e:
330
342
  raise EvalError(str(e)) from e
331
343