openscad-cpp-evaluator 1.42.0__tar.gz → 1.43.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 (245) hide show
  1. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/CLAUDE.md +39 -18
  2. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/PKG-INFO +3 -2
  3. openscad_cpp_evaluator-1.43.0/external/openscad_cpp_parser/LICENSE +21 -0
  4. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/colored_body.hpp +3 -3
  5. openscad_cpp_evaluator-1.43.0/include/openscad_cpp_evaluator/dxf_svg_import.hpp +67 -0
  6. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/evaluator.hpp +5 -0
  7. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/export.hpp +5 -8
  8. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/import_builtin.hpp +3 -1
  9. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/segments.hpp +9 -18
  10. openscad_cpp_evaluator-1.43.0/include/openscad_cpp_evaluator/surface_load.hpp +20 -0
  11. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/value.hpp +3 -6
  12. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/pyproject.toml +3 -3
  13. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/CMakeLists.txt +1 -1
  14. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/booleans.cpp +2 -2
  15. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/builtins.hpp +15 -2
  16. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/control.cpp +2 -4
  17. openscad_cpp_evaluator-1.43.0/src/builtins/dxf_dim.cpp +220 -0
  18. openscad_cpp_evaluator-1.43.0/src/builtins/extrude.cpp +563 -0
  19. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/function_builtins.cpp +295 -395
  20. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/import.cpp +150 -80
  21. openscad_cpp_evaluator-1.43.0/src/builtins/primitives_2d.cpp +266 -0
  22. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/primitives_3d.cpp +122 -173
  23. openscad_cpp_evaluator-1.43.0/src/builtins/roof.cpp +485 -0
  24. openscad_cpp_evaluator-1.43.0/src/builtins/segments.cpp +253 -0
  25. openscad_cpp_evaluator-1.43.0/src/builtins/surface.cpp +114 -0
  26. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/transforms.cpp +206 -190
  27. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/bytecode_compiler.cpp +2 -2
  28. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/bytecode_vm.cpp +1 -1
  29. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/colored_body.cpp +1 -1
  30. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/export.cpp +91 -45
  31. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/expr_eval.cpp +2 -3
  32. openscad_cpp_evaluator-1.43.0/src/import/dxf_import.cpp +370 -0
  33. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/import/mesh_import.cpp +56 -18
  34. openscad_cpp_evaluator-1.43.0/src/import/surface_load.cpp +124 -0
  35. openscad_cpp_evaluator-1.43.0/src/import/svg_import.cpp +1017 -0
  36. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/user_calls.cpp +4 -5
  37. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/value.cpp +135 -119
  38. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_dxf_svg_import.cpp +314 -51
  39. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_export.cpp +18 -5
  40. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_extrude_roof.cpp +2 -2
  41. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_helpers.hpp +24 -0
  42. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_import_export.cpp +56 -54
  43. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_python_bindings.py +14 -2
  44. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_transforms.cpp +1 -0
  45. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/uv.lock +1 -1
  46. openscad_cpp_evaluator-1.42.0/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -46
  47. openscad_cpp_evaluator-1.42.0/include/openscad_cpp_evaluator/surface_load.hpp +0 -23
  48. openscad_cpp_evaluator-1.42.0/src/builtins/dxf_dim.cpp +0 -244
  49. openscad_cpp_evaluator-1.42.0/src/builtins/extrude.cpp +0 -549
  50. openscad_cpp_evaluator-1.42.0/src/builtins/primitives_2d.cpp +0 -242
  51. openscad_cpp_evaluator-1.42.0/src/builtins/roof.cpp +0 -489
  52. openscad_cpp_evaluator-1.42.0/src/builtins/segments.cpp +0 -284
  53. openscad_cpp_evaluator-1.42.0/src/builtins/surface.cpp +0 -118
  54. openscad_cpp_evaluator-1.42.0/src/import/dxf_import.cpp +0 -115
  55. openscad_cpp_evaluator-1.42.0/src/import/surface_load.cpp +0 -132
  56. openscad_cpp_evaluator-1.42.0/src/import/svg_import.cpp +0 -628
  57. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/.github/workflows/ci.yml +0 -0
  58. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/.github/workflows/wheels.yml +0 -0
  59. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/.gitignore +0 -0
  60. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/.gitmodules +0 -0
  61. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/CMakeLists.txt +0 -0
  62. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/LICENSE +0 -0
  63. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/README.md +0 -0
  64. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/bindings/CMakeLists.txt +0 -0
  65. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/bindings/ast_to_py.cpp +0 -0
  66. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/bindings/module.cpp +0 -0
  67. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/cmake/embed_font.cmake +0 -0
  68. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/cmake/patch_manifold.cmake +0 -0
  69. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/examples/CMakeLists.txt +0 -0
  70. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/examples/eval_perf_benchmark.cpp +0 -0
  71. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/examples/manifold_cache_reuse.cpp +0 -0
  72. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/examples/minimal_debugger.cpp +0 -0
  73. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  74. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/.gitignore +0 -0
  75. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  76. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  77. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/README.md +0 -0
  78. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  79. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  80. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  81. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  82. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  83. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  84. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  85. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  86. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  87. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  88. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  89. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  90. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  91. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
  92. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  93. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  94. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
  95. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  96. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  97. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  98. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  99. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  100. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  101. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  102. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  103. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  104. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  105. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  106. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  107. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  108. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  109. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  110. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  111. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  112. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  113. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  114. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  115. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  116. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  117. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  118. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  119. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  120. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  121. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  122. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  123. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
  124. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  125. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  126. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  127. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  128. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  129. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  130. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  131. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  132. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  133. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  134. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
  135. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
  136. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  137. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  138. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  139. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  140. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
  141. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  142. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  143. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  144. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  145. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  146. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
  147. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  148. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
  149. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  150. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
  151. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  152. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  153. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  154. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  155. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  156. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  157. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  158. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  159. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
  160. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  161. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
  162. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
  163. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  164. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  165. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  166. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  167. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  168. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  169. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  170. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  171. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
  172. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  173. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
  174. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/resources/fonts/LICENSE +0 -0
  175. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
  176. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
  177. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
  178. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  179. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/call_args.cpp +0 -0
  180. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/color.cpp +0 -0
  181. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/modifiers.cpp +0 -0
  182. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/profile_time.cpp +0 -0
  183. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/registry.cpp +0 -0
  184. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/text.cpp +0 -0
  185. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/builtins/topology.cpp +0 -0
  186. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/coverage.cpp +0 -0
  187. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/csg_generate.cpp +0 -0
  188. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/csg_resolve.cpp +0 -0
  189. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/css_colors.cpp +0 -0
  190. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/debug/debug_repl.cpp +0 -0
  191. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/debug_profile.cpp +0 -0
  192. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/eval_context.cpp +0 -0
  193. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/eval_error.cpp +0 -0
  194. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/eval_use.cpp +0 -0
  195. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/format_closure.cpp +0 -0
  196. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/import/scene_import.cpp +0 -0
  197. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/manifold_cache.cpp +0 -0
  198. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/measure_geometry.cpp +0 -0
  199. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/mesh_check.cpp +0 -0
  200. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/stmt_eval.cpp +0 -0
  201. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/text/font_match.cpp +0 -0
  202. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/text/freetype_font_provider.cpp +0 -0
  203. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/text/text_metrics.cpp +0 -0
  204. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/utf8.cpp +0 -0
  205. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/xkcd_colors.cpp +0 -0
  206. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/xkcd_colors.hpp +0 -0
  207. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/src/zip_stored.cpp +0 -0
  208. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/CMakeLists.txt +0 -0
  209. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_booleans.cpp +0 -0
  210. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_bytecode_compiler.cpp +0 -0
  211. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_children_separate.cpp +0 -0
  212. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_cli.cpp +0 -0
  213. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_control_flow.cpp +0 -0
  214. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_coverage.cpp +0 -0
  215. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_csg_tree.cpp +0 -0
  216. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_debug_hooks.cpp +0 -0
  217. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_discretizer.cpp +0 -0
  218. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_eval_context.cpp +0 -0
  219. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_expr_eval.cpp +0 -0
  220. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_feature_detection.cpp +0 -0
  221. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_function_builtins.cpp +0 -0
  222. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_include_cache.cpp +0 -0
  223. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_manifold_cache.cpp +0 -0
  224. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_mesh_check.cpp +0 -0
  225. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_multi_color_merge.cpp +0 -0
  226. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_openscad_parity.cpp +0 -0
  227. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_primitives.cpp +0 -0
  228. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_profile_time.cpp +0 -0
  229. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_profiling.cpp +0 -0
  230. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_render_expr.cpp +0 -0
  231. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_scope_trail.cpp +0 -0
  232. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_scoping.cpp +0 -0
  233. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_surface.cpp +0 -0
  234. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_tail_calls.cpp +0 -0
  235. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_text.cpp +0 -0
  236. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_undef_args.cpp +0 -0
  237. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_unexpected_args.cpp +0 -0
  238. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_use.cpp +0 -0
  239. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_value.cpp +0 -0
  240. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_viewport_params.cpp +0 -0
  241. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tests/test_zip_stored.cpp +0 -0
  242. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tools/cli/CMakeLists.txt +0 -0
  243. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tools/cli/cli_lib.cpp +0 -0
  244. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tools/cli/cli_lib.hpp +0 -0
  245. {openscad_cpp_evaluator-1.42.0 → openscad_cpp_evaluator-1.43.0}/tools/cli/main.cpp +0 -0
@@ -63,7 +63,7 @@ plus gating the silent `is_undef` probe on the call actually resolving to the bu
63
63
  CSG-tree shape like union/difference/intersection, role-split via the shared `splitByRole`),
64
64
  `linear_extrude()`/`rotate_extrude()`/`projection(cut=)`, and `roof()`; and (Phase 7) `offset()`,
65
65
  `surface()` (`.dat` text + PNG/JPEG/BMP/GIF via `stb_image`), hand-rolled DXF (`LWPOLYLINE`/2D
66
- `POLYLINE`) and SVG (`path`/`polygon`/`polyline`/`rect`/`circle`/`ellipse`, nested
66
+ `POLYLINE`) and SVG (a port of upstream's libsvg: shapes, strokes, `<use>`, layers, nested
67
67
  `transform=`, all path commands including elliptical arcs) 2D contour import in both module
68
68
  (Region geometry) and expression (Region value) contexts, and the `FontProvider` abstraction
69
69
  (`font_provider.hpp`) + built-in FreeType/HarfBuzz backend + `text()`/`textmetrics()`/
@@ -1248,9 +1248,13 @@ grep for `ponytail:`.
1248
1248
  the module *and* expression forms, enclosing transforms still apply to a selected element (it
1249
1249
  has to land where it does in the drawing), and **a filter that matches nothing imports nothing
1250
1250
  and warns** rather than falling back to the whole file — a cut layer that quietly became every
1251
- layer is the worst answer available. `layer=` stays DXF-only on purpose: upstream reuses the
1252
- name for SVG but reads only Inkscape's `inkscape:label`, a vendor convention rather than
1253
- anything SVG defines, so it cannot match a layer from any other tool. `id` had been in
1251
+ layer is the worst answer available. `layer=` (and deprecated `layername=`) also selects in
1252
+ SVG, as upstream does: an Inkscape layer (`inkscape:groupmode="layer"` with an
1253
+ `inkscape:label`). Alone it takes that layer's own group; with `id=`/`class=` it restricts them
1254
+ to elements inside the named layer at any depth. The selection rules were read off the binary:
1255
+ the nearest selected or `display:none` ancestor-or-self decides whether a shape is drawn, so an
1256
+ id selects an element even under a hidden layer, while `layer=` alone does not reach into a
1257
+ hidden sublayer. The miss warning names `id`, `layer`, `class` in that order. `id` had been in
1254
1258
  `registry.cpp`'s declared parameter list since long before anything read it, so a script
1255
1259
  filtering by id was accepted in full and silently handed the whole drawing.
1256
1260
  `resolveFilePath()` (also declared here, defined in import.cpp) — resolves a file argument
@@ -1281,20 +1285,37 @@ grep for `ponytail:`.
1281
1285
  triangle-count parity.
1282
1286
  - `include/openscad_cpp_evaluator/dxf_svg_import.hpp`, `src/import/dxf_import.cpp`,
1283
1287
  `src/import/svg_import.cpp` — hand-rolled, dependency-free 2D-contour loaders (no XML/DXF library
1284
- pulled in, matching the plan's §9 dependency table). `loadDxfContours()` reads DXF's group-code
1285
- text format directly (closed `LWPOLYLINE`/2D `POLYLINE` entities only, optional layer filter) --
1286
- covers the same narrow entity set the reference's own `ezdxf`-based loader does, nothing more.
1288
+ pulled in, matching the plan's §9 dependency table). `loadDxf()` reads DXF's group-code
1289
+ text format directly and matches OpenSCAD 2026.02.01's import, established black-box (its DXF
1290
+ source is GPL; do not read or port it): `LINE`/`CIRCLE`/`ARC`/`ELLIPSE`/`LWPOLYLINE`/`INSERT`
1291
+ become segments (arcs by the circle fragment rules), points snap to a 1/1024 grid, segments chain
1292
+ into paths that are ALL closed (an open chain gets a straight closing edge), filled even-odd;
1293
+ `origin=`/`scale=`/`layer=` and its warnings ("Illegal value", "Not enough input values",
1294
+ "Unsupported DXF Entity") as OpenSCAD has them. The notes atop `dxf_import.cpp` list the rules,
1295
+ the two ellipse bugs deliberately not copied, and the `POLYLINE` extension.
1287
1296
  `loadSvgContours()` pairs a minimal recursive-descent XML tree parser (open/close/self-closing
1288
- tags, quoted attributes, comments/CDATA/prolog skipping, entity decoding — no namespace URI
1289
- resolution, a tag's `prefix:` is stripped textually) with a close port of the reference's own
1290
- path-command tokenizer/flattener (`M`/`L`/`H`/`V`/`C`/`S`/`Q`/`T`/`A`, both absolute and relative,
1291
- cubic/quadratic Bezier flattening, full elliptical-arc endpoint-to-center parameterization) plus
1292
- `rect`/`circle`/`ellipse`/`polygon`/`polyline` and nested `transform="matrix()/translate()/
1293
- scale()/rotate()"` composition (including through `<g>` groups), in SVG user units at the
1294
- point-transform step, `applyMat()` (named to avoid colliding with `std::apply` in an ADL lookup
1295
- that broke the build once — see its own comment). **Placement is `pageMap()`, a port of the
1296
- reference's `import_svg.cc`**: the page's `width`/`height` to mm (a unitless length at `dpi=`,
1297
- 72 by default; `px` at 96), the `viewBox` scaled onto the page under `preserveAspectRatio`
1297
+ tags, quoted attributes, comments/CDATA/prolog skipping, entity and character-reference
1298
+ decoding, attribute whitespace normalisation; a tag keeps its `prefix:`, as libxml2 reports it,
1299
+ so `<svg:rect>` is not a rect -- in OpenSCAD either) with **a port of upstream's MIT-licensed
1300
+ `src/libsvg`** (its copyright notice is in the file): its `d` tokenizer with every quirk (a `-`
1301
+ is a token, `1.5.5` is two numbers, a number with trailing junk is 0), Beziers in `max($fn, 20)`
1302
+ segments, arcs and circles/ellipses through `Discretizer::circular` (circles at least 40),
1303
+ rounded `rect`s rebuilt as path data printed at 6 digits, `transform` with `skewX`/`skewY` and
1304
+ libsvg's argument-count checks, `<use>` of a shape in an earlier `<defs>` only, unknown
1305
+ elements (`<a>`, `<symbol>`, `<switch>`) see-through with their transform ignored, and
1306
+ **strokes**: an open subpath, `<line>` and `<polyline>` become their stroke's outline via
1307
+ Clipper2's `ClipperOffset` at 2^27 per user unit (measured), with `stroke-width` (below 0.01 is
1308
+ 1), `stroke-linecap` and `stroke-linejoin` (`bevel` maps to Clipper's Square, as libsvg has it).
1309
+ Each element then fills even-odd on its own and the elements union (`fill()`), which is what
1310
+ the reference does: separate overlapping rects union, one path's overlapping subpaths cancel.
1311
+ Two departures: an arc with a zero radius or coincident endpoints is a line or nothing, as the
1312
+ SVG spec says, where libsvg divides by zero and draws NaN vertices at the origin; and
1313
+ OpenSCAD's 2D pipeline drops vertices within ~1.1e-8 mm of collinear, which ours (any 2D
1314
+ shape, not just SVG) does not -- spec `paths-cubic02` keeps two such vertices at an S-curve's
1315
+ inflection. **Placement is `pageMap()`, matching the reference's `import_svg.cc` by its
1316
+ output**: the page's `width`/`height` to mm (a unitless length at `dpi=`,
1317
+ 72 by default; `px` at 96; a `dpi` below 0.001 warns and is 72), the `viewBox` scaled onto the
1318
+ page under `preserveAspectRatio`
1298
1319
  (default `xMidYMid meet`), and Y flipped about the page HEIGHT -- or about the drawing's centre
1299
1320
  with `center=true`. Negating Y alone, as this did before, put a unitless 100-unit drawing in 2.8x
1300
1321
  too large and below the X axis. Bounds match OpenSCAD 2026.02.01 (`SvgPlacement` tests).
@@ -1670,7 +1691,7 @@ the side-quad diagonal choice changes a twisted solid without changing its trian
1670
1691
  default below 3, so these are an extrude warped round Z. The warp inverts the solid for a positive
1671
1692
  angle, hence the mirror-in-Y dance.
1672
1693
  - Kept departure: `$fa`/`$fs` <= 0 fall back to 12/2 rather than upstream's clamp-to-0.01 with a warning.
1673
- - Not ported: `linear_extrude(v=)` (accepted, ignored); DXF/SVG import arcs don't read the discretizer.
1694
+ - Not ported: `linear_extrude(v=)` (accepted, ignored); DXF import arcs don't read the discretizer.
1674
1695
 
1675
1696
  ## Cancel and the module recursion limit (#554)
1676
1697
 
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 1.42.0
3
+ Version: 1.43.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
- License-Expression: MIT
6
+ License-Expression: MIT AND OFL-1.1
7
7
  License-File: LICENSE
8
+ License-File: resources/fonts/LICENSE
8
9
  Classifier: Development Status :: 3 - Alpha
9
10
  Classifier: Intended Audience :: Developers
10
11
  Classifier: Operating System :: OS Independent
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 BelfrySCAD Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -188,7 +188,7 @@ std::vector<ColoredBody> toRenderableBodies(const std::vector<ColoredBody>& bodi
188
188
  double flatHeight = kTopLevel2dHeight);
189
189
 
190
190
  // A 3D affine transform as it acts on the XY plane: rows x and y, columns
191
- // x, y and translation -- what OpenSCAD's GeometryEvaluator applies to 2D
191
+ // x, y and translation -- what OpenSCAD applies to 2D
192
192
  // geometry (z, and everything out of the plane, simply drops away).
193
193
  manifold::mat2x3 projectTo2d(const manifold::mat3x4& m);
194
194
 
@@ -203,10 +203,10 @@ bool projectSectionXform(ColoredBody& b);
203
203
 
204
204
  // Applies `m`, projected onto the plane, to a CrossSection. A singular
205
205
  // projection -- scale([0,1]), a quarter turn about X -- empties it, as
206
- // upstream's Polygon2d::transform does, and returns false.
206
+ // OpenSCAD does, and returns false.
207
207
  bool transformSection(manifold::CrossSection& cs, const manifold::mat3x4& m);
208
208
 
209
- // Upstream's warning for that case, word for word.
209
+ // OpenSCAD's warning for that case, word for word.
210
210
  inline constexpr const char* kZeroScale2dWarning = "Scaling a 2D object with 0 - removing object";
211
211
 
212
212
  } // namespace oscadeval
@@ -0,0 +1,67 @@
1
+ #pragma once
2
+
3
+ #include "openscad_cpp_evaluator/segments.hpp"
4
+
5
+ #include <array>
6
+ #include <optional>
7
+ #include <string>
8
+ #include <vector>
9
+
10
+ namespace oscadeval {
11
+
12
+ using Contour2d = std::vector<std::array<double, 2>>;
13
+
14
+ // import()'s DXF arguments. `disc` carries $fn/$fa/$fs/$fe for arcs.
15
+ struct DxfOptions {
16
+ std::optional<std::string> layer;
17
+ double xorigin = 0.0, yorigin = 0.0, scale = 1.0;
18
+ Discretizer disc;
19
+ };
20
+
21
+ // The outlines, to be filled even-odd, and OpenSCAD's warnings about the
22
+ // file, in the order it prints them.
23
+ struct DxfImport {
24
+ std::vector<Contour2d> contours;
25
+ std::vector<std::string> warnings;
26
+ };
27
+
28
+ // Hand-rolled DXF reader matching OpenSCAD 2026.02.01's import (see the
29
+ // notes atop dxf_import.cpp): LINE, CIRCLE, ARC, ELLIPSE, LWPOLYLINE,
30
+ // POLYLINE and INSERT, chained into closed outlines. Throws
31
+ // std::runtime_error on I/O failure.
32
+ DxfImport loadDxf(const std::string& path, const DxfOptions& opts = {});
33
+
34
+ // SVG reader, as OpenSCAD 2026.02.01 reads it (a port of its MIT-licensed
35
+ // libsvg): <path>, <rect>, <circle>, <ellipse>, <line>, <polygon>,
36
+ // <polyline> and <use>, with transforms, display:none, and strokes -- an
37
+ // open path, <line> or <polyline> is drawn as its stroke's outline. Curves
38
+ // split by `disc`. Y is flipped (SVG's is down, OpenSCAD's is up). Throws
39
+ // std::runtime_error on I/O/parse failure.
40
+ //: Which part of the drawing to import. All unset means the whole file.
41
+ //: `id` matches an element's `id` attribute; `cls` (not an OpenSCAD
42
+ //: parameter) one entry of its space-separated `class` list; either takes
43
+ //: everything under the element, so naming a <g> means "that group".
44
+ //: `layer` names an Inkscape layer (inkscape:groupmode="layer", by its
45
+ //: inkscape:label): alone it takes that layer, with id/cls it restricts
46
+ //: them to elements inside it.
47
+ struct SvgFilter {
48
+ std::optional<std::string> id;
49
+ std::optional<std::string> cls;
50
+ std::optional<std::string> layer;
51
+ };
52
+
53
+ // `matched`, when given, reports whether the filter found anything. A miss
54
+ // imports nothing rather than falling back to the whole drawing; the caller
55
+ // warns. Always true when no filter was set.
56
+ // Placed as OpenSCAD places them: page units to mm (a unitless length at
57
+ // `dpi`), the viewBox under preserveAspectRatio, Y flipped about the page
58
+ // height -- or about the drawing's centre with `center`. The result is
59
+ // filled: overlapping contours have already been combined.
60
+ std::vector<Contour2d> loadSvgContours(const std::string& path,
61
+ const SvgFilter& filter = {},
62
+ bool* matched = nullptr,
63
+ double dpi = 72.0,
64
+ bool center = false,
65
+ const Discretizer& disc = {});
66
+
67
+ } // namespace oscadeval
@@ -587,6 +587,11 @@ public:
587
587
  // warnCapture first when one is active. Every warning path goes through
588
588
  // here, including a ManifoldCache hit replaying a cached line.
589
589
  void emitWarning(const std::string& formatted);
590
+ // "ERROR: {message}{locSuffix(position)}" that does NOT stop the run:
591
+ // OpenSCAD logs several of its errors this way and carries on.
592
+ void nonFatalError(const std::string& message, const oscad::Position* position) {
593
+ emitWarning("ERROR: " + message + locSuffix(position));
594
+ }
590
595
 
591
596
  // Applies OpenSCAD's mixed-2D/3D rules to a node's children just
592
597
  // before its GenerateFn runs -- see csg_generate.cpp.
@@ -167,7 +167,7 @@ struct ExportSvgOptions {
167
167
  void writeSvg(const std::string& path, const std::vector<ColoredBody>& bodies,
168
168
  const ExportSvgOptions& opts = {});
169
169
 
170
- // DXF, the third 2D writer: OpenSCAD's own export_dxf.cc layout (an AC1006
170
+ // DXF, the third 2D writer: byte-compatible with OpenSCAD's layout (an AC1006
171
171
  // header with the model's extents, one CONTINUOUS linetype, layer 0) and
172
172
  // every contour of every body a closed LWPOLYLINE on layer 0 -- holes are
173
173
  // contours like any other, as in OpenSCAD. A 1-vertex contour is a POINT
@@ -259,13 +259,10 @@ struct ExportPovOptions {
259
259
  // POV-Ray scene description. Every object splitBodiesForExport produces is
260
260
  // one mesh2 -- a welded vertex list, a texture per colour, and a texture
261
261
  // index per triangle, so per-triangle colour needs no unwelding -- with
262
- // inside_vector, which makes it a SOLID to POV-Ray (refraction, CSG). That
263
- // is the difference from OpenSCAD's export_pov.cc, which writes every face
264
- // as its own flat polygon object. The rest of the scene is OpenSCAD's: its
265
- // header, MATERIAL finish and ior 1.32 interior, 27 lights around the
266
- // bounding box, its camera, and radiosity from rad_def.inc. Colour is rgbf
267
- // with filter = 1 - alpha, as OpenSCAD writes it. Numbers are the shortest
268
- // text that round-trips, in the classic locale.
262
+ // inside_vector, which makes it a SOLID to POV-Ray (refraction, CSG). The
263
+ // rest of the scene (material, lights, default camera) is spec section F2.
264
+ // Colour is rgbf with filter = 1 - alpha. Numbers are the shortest text that
265
+ // round-trips, in the classic locale.
269
266
  void writePov(const std::string& path, const std::vector<ExportObject>& objects,
270
267
  const ExportPovOptions& opts = {});
271
268
 
@@ -9,12 +9,14 @@ class ASTNode;
9
9
  namespace oscadeval {
10
10
 
11
11
  class Evaluator;
12
+ struct EvalContext;
12
13
 
13
14
  // import() used as an expression (not a geometry statement): returns a VNF
14
15
  // ([[verts],[faces]]) for a mesh file (.stl/.obj/.off/.3mf), or the JSON
15
16
  // file's content converted to native values (.json). DXF/SVG-as-Region
16
17
  // import lands alongside their module-context counterparts in a later
17
18
  // phase. Mirrors Evaluator._import_as_value (minus the dxf/svg branch).
18
- Value importAsValue(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node);
19
+ // `ctx` supplies $fn/$fa/$fs/$fe for an SVG's curves.
20
+ Value importAsValue(Evaluator& ev, const CallArgs& args, const oscad::ASTNode& node, const EvalContext& ctx);
19
21
 
20
22
  } // namespace oscadeval
@@ -11,34 +11,25 @@
11
11
 
12
12
  namespace oscadeval {
13
13
 
14
- // How curves become polygons: OpenSCAD's CurveDiscretizer (src/core/
15
- // CurveDiscretizer.cc, upstream master cc19000e0), ported. Every count here
16
- // matches the 2026.02.01 binary's.
17
- //
18
- // $fn > $fe > $fa/$fs. $fe is the most a curve's polygon may stray from the
19
- // true circle, measured along a radius to an edge's midpoint; when set (>=
20
- // 2^-20) it replaces $fa/$fs entirely. Upstream reads $fe only behind
21
- // --enable=discretization-by-error; this evaluator always honours it, and
22
- // advertises that as supported_feature("discretization-by-error").
23
- //
24
- // Departures from upstream, kept from before this port: $fa/$fs <= 0 fall
25
- // back to their defaults (12/2) rather than clamping to 0.01 with a warning.
14
+ // How curves become polygons: segment and slice counts from $fn/$fe/$fa/$fs
15
+ // (spec sections B7 and C6). $fe is always honoured here (OpenSCAD reads it
16
+ // only behind --enable=discretization-by-error), advertised as
17
+ // supported_feature("discretization-by-error").
26
18
  struct Discretizer {
27
19
  double fn = 0.0;
28
20
  double fe = 0.0;
29
21
  double fa = 12.0;
30
22
  double fs = 2.0;
31
23
 
32
- // `warn`, when given, receives upstream's clamping warnings.
24
+ // `warn`, when given, receives the clamping warnings (spec section B7).
33
25
  static Discretizer fromCtx(const EvalContext& ctx, const std::function<void(const std::string&)>& warn = {});
34
26
  // Stored in, and read back from, a node's params -- they are part of its
35
27
  // cache key, and generate has only the params to go on.
36
28
  static Discretizer fromParams(const CSGParams& params);
37
29
  void store(CSGParams& params) const;
38
30
 
39
- // Segments for `angle` degrees of arc at radius r. nullopt where
40
- // upstream has none (r below 2^-20, a non-finite $fn/$fe/angle): every
41
- // caller supplies its own fallback, as upstream's value_or() does.
31
+ // Segments for `angle` degrees of arc at radius r. nullopt where there is
32
+ // no count (spec section B7); every caller supplies its own fallback.
42
33
  std::optional<int> circular(double r, double angleDegrees = 360.0) const;
43
34
 
44
35
  // linear_extrude slice counts: twist without scale, twist with uniform
@@ -54,8 +45,8 @@ struct Discretizer {
54
45
  double scaleX, double scaleY, unsigned slices, unsigned segments) const;
55
46
  };
56
47
 
57
- // Full-circle segment count from ctx's $fn/$fe/$fa/$fs at radius r;
58
- // upstream's primitives fall back to 3.
48
+ // Full-circle segment count from ctx's $fn/$fe/$fa/$fs at radius r, or 3
49
+ // when there is none.
59
50
  int fnSegmentsFromCtx(const EvalContext& ctx, double r = 0.0,
60
51
  const std::function<void(const std::string&)>& warn = {});
61
52
 
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+ #include <vector>
5
+
6
+ namespace oscadeval {
7
+
8
+ // Height data for surface() (spec section D3). Never throws: a file that
9
+ // cannot be read gives no heights and a warning, and the script carries on.
10
+ // `heights[row * cols + col]`; `minVal` is what the base sits 1 below.
11
+ struct SurfaceData {
12
+ std::vector<double> heights;
13
+ int rows = 0;
14
+ int cols = 0;
15
+ double minVal = 0;
16
+ std::vector<std::string> warnings;
17
+ };
18
+ SurfaceData loadSurface(const std::string& path, bool invert);
19
+
20
+ } // namespace oscadeval
@@ -268,12 +268,9 @@ Value vecSub(const Value& a, const Value& b);
268
268
  // behavior in the reference implementation -- revisit only if a real
269
269
  // script's `*` on a bool-containing vector is shown to need it.
270
270
  //
271
- // `error`, when non-null, receives the reference's own diagnostic text for
272
- // whichever undefined case was hit (multiply_visitor / multvecvec /
273
- // multmatvec / multvecmat in the reference's Value.cc) -- "vector*vector
274
- // requires matching lengths (2 != 3)", "Matrix must be rectangular. Problem
275
- // at row 1", and so on. applyBinaryOp warns with it; a caller that only
276
- // wants the value can leave it null. It is only written on an undef result.
271
+ // `error`, when non-null, receives the diagnostic for whichever undefined
272
+ // case was hit (spec section A6); applyBinaryOp warns with it. It is only
273
+ // written on an undef result.
277
274
  Value matmul(const Value& a, const Value& b, std::string* error = nullptr);
278
275
 
279
276
  // OpenSCAD's echo()/str() number formatting: at most 6 significant digits,
@@ -4,12 +4,12 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_cpp_evaluator"
7
- version = "1.42.0"
7
+ version = "1.43.0"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
11
- license = "MIT"
12
- license-files = ["LICENSE"]
11
+ license = "MIT AND OFL-1.1"
12
+ license-files = ["LICENSE", "resources/fonts/LICENSE"]
13
13
  authors = [{ name = "NeuSCAD Contributors" }]
14
14
  classifiers = [
15
15
  "Development Status :: 3 - Alpha",
@@ -68,7 +68,7 @@ target_include_directories(openscad_cpp_evaluator PRIVATE ${stb_SOURCE_DIR} ${CM
68
68
  add_dependencies(openscad_cpp_evaluator generate_bundled_font)
69
69
 
70
70
  target_link_libraries(openscad_cpp_evaluator PUBLIC openscad_cpp_parser manifold Boost::polygon)
71
- target_link_libraries(openscad_cpp_evaluator PRIVATE linenoise freetype harfbuzz)
71
+ target_link_libraries(openscad_cpp_evaluator PRIVATE linenoise freetype harfbuzz Clipper2)
72
72
  target_compile_options(openscad_cpp_evaluator PRIVATE
73
73
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall;-Wextra>
74
74
  )
@@ -392,8 +392,8 @@ std::vector<ColoredBody> generateCsg(Evaluator& ev, const CSGParams& params, con
392
392
  }
393
393
 
394
394
  RoleSplit split = splitByRole(stmtBodies);
395
- // A `%` statement is scenery, not an operand: upstream leaves it out
396
- // of the CSG entirely (collectChildren skips isBackground()), so the
395
+ // A `%` statement is scenery, not an operand: OpenSCAD leaves it out
396
+ // of the CSG entirely, so the
397
397
  // NEXT statement is the minuend of a difference(), and an
398
398
  // intersection() is not cancelled by it. It was taken as an empty
399
399
  // operand, which emptied both. Only the `%` statement itself: a
@@ -271,15 +271,28 @@ std::vector<ColoredBody> generateSurface(Evaluator& ev, const CSGParams& params,
271
271
  // operand (and so empties an intersection) -- see resolveCsg.
272
272
  bool emptyStatementIsAnOperand(const oscad::ASTNode& stmt);
273
273
 
274
- // OpenSCAD's sin_degrees/cos_degrees: exact at multiples of 30 and 45 degrees.
274
+ // OpenSCAD's sin_degrees/cos_degrees/tan_degrees/atan2_degrees: exact at
275
+ // multiples of 30 and 45 degrees.
275
276
  double sinDeg(double x);
276
277
  double cosDeg(double x);
278
+ double tanDeg(double x);
279
+ double atan2Deg(double y, double x);
277
280
 
278
- // OpenSCAD's lookup_radius() (primitives_2d.cpp): `d` beats `r`, numbers only.
281
+ // A radius/diameter argument pair: a numeric `d` beats `r`, numbers only.
279
282
  std::optional<double> lookupRadius(Evaluator& ev, const CallArgs& args, std::optional<int> rPos,
280
283
  std::optional<int> dPos, const std::string& rName, const std::string& dName,
281
284
  const oscad::Position* where);
282
285
 
286
+ // "ERROR: <text>" at `where`, for input a primitive repairs and carries on with.
287
+ void emitInputError(Evaluator& ev, const std::string& text, const oscad::Position* where);
288
+
289
+ // Reads polygon() paths or polyhedron() faces (`listName`): each entry a
290
+ // list of point indices. Entries that are not lists and indices that are not
291
+ // numbers are reported as ERRORs and skipped; out-of-range indices are
292
+ // WARNINGs and skipped. Every surviving entry is returned, however short.
293
+ std::vector<std::vector<size_t>> readIndexLists(Evaluator& ev, const ValueList& lists, const std::string& listName,
294
+ size_t pointCount, const oscad::Position* where);
295
+
283
296
  CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
284
297
 
285
298
  // The font size text()/textmetrics()/fontmetrics() draw at: `size`
@@ -124,10 +124,8 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
124
124
  // evalFor) -- mirrors _resolve_intersection_for's single
125
125
  // `_check_debug(body_node[0], loop_ctx, expr_level=True)`.
126
126
  if (!bodyNodes.empty()) ev.checkDebug(*bodyNodes.front(), parentCtx, /*forced=*/false, /*exprLevel=*/true);
127
- // One operand per child STATEMENT of every iteration: upstream
128
- // instantiates the children straight into the intersection
129
- // node (control.cc), so they are intersected flat, not
130
- // unioned per iteration first.
127
+ // One operand per child STATEMENT of every iteration: OpenSCAD
128
+ // intersects them flat, not unioned per iteration first.
131
129
  std::vector<const oscad::ASTNode*> assigns, stmts;
132
130
  for (const oscad::ASTNode* stmt : bodyNodes) {
133
131
  if (stmt->kind() == oscad::NodeKind::Assignment) assigns.push_back(stmt);