session-py 0.232.0__tar.gz → 0.233.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 (149) hide show
  1. {session_py-0.232.0 → session_py-0.233.0}/PKG-INFO +1 -3
  2. {session_py-0.232.0 → session_py-0.233.0}/README.md +0 -2
  3. {session_py-0.232.0 → session_py-0.233.0}/pyproject.toml +1 -1
  4. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/__init__.py +0 -2
  5. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/boolean_polyline.py +61 -14
  6. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/boolean_polyline_test.py +0 -113
  7. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/file_obj_test.py +3 -2
  8. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/intersection.py +78 -344
  9. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/intersection_test.py +4 -122
  10. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/io_xyz.py +5 -13
  11. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/io_xyz_test.py +0 -62
  12. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/line.py +5 -78
  13. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/line_test.py +0 -28
  14. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbscurve.py +7 -132
  15. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbscurve_test.py +1 -142
  16. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/polyline.py +5 -24
  17. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/polyline_test.py +0 -23
  18. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/primitives.py +5 -31
  19. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/primitives_test.py +0 -105
  20. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/line_pb2.py +2 -2
  21. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/nurbscurve_pb2.py +2 -2
  22. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/polyline_pb2.py +2 -2
  23. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/simple_split.py +1 -7
  24. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/simple_split_test.py +0 -8
  25. {session_py-0.232.0 → session_py-0.233.0}/uv.lock +1 -1
  26. session_py-0.232.0/docs/history.md +0 -99
  27. {session_py-0.232.0 → session_py-0.233.0}/.github/FUNDING.yml +0 -0
  28. {session_py-0.232.0 → session_py-0.233.0}/.github/workflows/publish.yml +0 -0
  29. {session_py-0.232.0 → session_py-0.233.0}/.github/workflows/test.yml +0 -0
  30. {session_py-0.232.0 → session_py-0.233.0}/.gitignore +0 -0
  31. {session_py-0.232.0 → session_py-0.233.0}/.gitmodules +0 -0
  32. {session_py-0.232.0 → session_py-0.233.0}/AGENTS.md +0 -0
  33. {session_py-0.232.0 → session_py-0.233.0}/CLAUDE.md +0 -0
  34. {session_py-0.232.0 → session_py-0.233.0}/conftest.py +0 -0
  35. {session_py-0.232.0 → session_py-0.233.0}/examples/bench.py +0 -0
  36. {session_py-0.232.0 → session_py-0.233.0}/examples/bvh_demo.py +0 -0
  37. {session_py-0.232.0 → session_py-0.233.0}/examples/loft_holes.py +0 -0
  38. {session_py-0.232.0 → session_py-0.233.0}/examples/nurbsurface.py +0 -0
  39. {session_py-0.232.0 → session_py-0.233.0}/serialization/.gitkeep +0 -0
  40. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/aabb.py +0 -0
  41. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/aabb_test.py +0 -0
  42. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/brep.py +0 -0
  43. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/brep_test.py +0 -0
  44. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/closest.py +0 -0
  45. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/closest_test.py +0 -0
  46. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/collection.py +0 -0
  47. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/collection_test.py +0 -0
  48. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/color.py +0 -0
  49. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/color_test.py +0 -0
  50. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/convex_hull.py +0 -0
  51. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/convex_hull_test.py +0 -0
  52. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/element.py +0 -0
  53. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/element_test.py +0 -0
  54. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/file_encoders.py +0 -0
  55. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/file_encoders_test.py +0 -0
  56. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/file_obj.py +0 -0
  57. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/file_step.py +0 -0
  58. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/file_step_test.py +0 -0
  59. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/graph.py +0 -0
  60. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/graph_test.py +0 -0
  61. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/history.py +0 -0
  62. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/history_test.py +0 -0
  63. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/instance_ref.py +0 -0
  64. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/instance_ref_test.py +0 -0
  65. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/interaction.py +0 -0
  66. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/interaction_test.py +0 -0
  67. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/matrix.py +0 -0
  68. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/matrix_test.py +0 -0
  69. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/mesh.py +0 -0
  70. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/mesh_offset.py +0 -0
  71. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/mesh_offset_test.py +0 -0
  72. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/mesh_test.py +0 -0
  73. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/mini_test.py +0 -0
  74. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbsknot.py +0 -0
  75. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbsknot_test.py +0 -0
  76. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbssurface.py +0 -0
  77. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbssurface_test.py +0 -0
  78. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbssurface_trimmed.py +0 -0
  79. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/nurbssurface_trimmed_test.py +0 -0
  80. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/obb.py +0 -0
  81. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/obb_test.py +0 -0
  82. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/objects.py +0 -0
  83. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/objects_test.py +0 -0
  84. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/plane.py +0 -0
  85. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/plane_test.py +0 -0
  86. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/point.py +0 -0
  87. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/point_test.py +0 -0
  88. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/pointcloud.py +0 -0
  89. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/pointcloud_test.py +0 -0
  90. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/.gitattributes +0 -0
  91. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/__init__.py +0 -0
  92. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/boundingbox_pb2.py +0 -0
  93. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/brep_pb2.py +0 -0
  94. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/color_pb2.py +0 -0
  95. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/element_pb2.py +0 -0
  96. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/file_encoders_pb2.py +0 -0
  97. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/graph_edge_pb2.py +0 -0
  98. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/graph_pb2.py +0 -0
  99. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/graph_vertex_pb2.py +0 -0
  100. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/instance_ref_pb2.py +0 -0
  101. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/interaction_pb2.py +0 -0
  102. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/matrix_pb2.py +0 -0
  103. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/mesh_pb2.py +0 -0
  104. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/nurbssurface_pb2.py +0 -0
  105. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/nurbssurface_trimmed_pb2.py +0 -0
  106. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/objects_pb2.py +0 -0
  107. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/plane_pb2.py +0 -0
  108. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/point_pb2.py +0 -0
  109. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/pointcloud_pb2.py +0 -0
  110. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/quaternion_pb2.py +0 -0
  111. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/session_pb2.py +0 -0
  112. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/sheet_pb2.py +0 -0
  113. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/tolerance_pb2.py +0 -0
  114. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/tree_pb2.py +0 -0
  115. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/treenode_pb2.py +0 -0
  116. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/vector_pb2.py +0 -0
  117. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/proto/xform_pb2.py +0 -0
  118. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/py.typed +0 -0
  119. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/quaternion.py +0 -0
  120. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/quaternion_test.py +0 -0
  121. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/reload.py +0 -0
  122. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/remesh_cdt.py +0 -0
  123. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/remesh_cdt_test.py +0 -0
  124. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/remesh_nurbssurface_adaptive.py +0 -0
  125. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/remesh_nurbssurface_adaptive_test.py +0 -0
  126. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/remesh_nurbssurface_grid.py +0 -0
  127. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/remesh_nurbssurface_grid_test.py +0 -0
  128. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/session.py +0 -0
  129. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/session_config.py +0 -0
  130. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/session_config_test.py +0 -0
  131. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/session_test.py +0 -0
  132. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_aabbtree.py +0 -0
  133. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_aabbtree_test.py +0 -0
  134. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_bvh.py +0 -0
  135. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_bvh_test.py +0 -0
  136. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_kdtree.py +0 -0
  137. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_kdtree_test.py +0 -0
  138. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_octree.py +0 -0
  139. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_octree_test.py +0 -0
  140. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_rtree.py +0 -0
  141. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/spatial_rtree_test.py +0 -0
  142. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/tolerance.py +0 -0
  143. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/tolerance_test.py +0 -0
  144. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/tree.py +0 -0
  145. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/tree_test.py +0 -0
  146. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/vector.py +0 -0
  147. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/vector_test.py +0 -0
  148. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/xform.py +0 -0
  149. {session_py-0.232.0 → session_py-0.233.0}/src/session_py/xform_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: session_py
3
- Version: 0.232.0
3
+ Version: 0.233.0
4
4
  Summary: A minimal Python geometry library
5
5
  Project-URL: Homepage, https://github.com/petrasvestartas/session_py
6
6
  Project-URL: Repository, https://github.com/petrasvestartas/session_py
@@ -26,8 +26,6 @@ Description-Content-Type: text/markdown
26
26
 
27
27
  Python geometry kernel. Published to [PyPI](https://pypi.org/project/session-py/) automatically on every push to main.
28
28
 
29
- Undo, history and purge: [docs/history.md](docs/history.md).
30
-
31
29
  ## Install
32
30
 
33
31
  ```bash
@@ -2,8 +2,6 @@
2
2
 
3
3
  Python geometry kernel. Published to [PyPI](https://pypi.org/project/session-py/) automatically on every push to main.
4
4
 
5
- Undo, history and purge: [docs/history.md](docs/history.md).
6
-
7
5
  ## Install
8
6
 
9
7
  ```bash
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "session_py"
7
- version = "0.232.0"
7
+ version = "0.233.0"
8
8
  description = "A minimal Python geometry library"
9
9
  authors = [{name = "Petras Vestartas", email = "petrasvestartas@gmail.com"}]
10
10
  license = {text = "MIT"}
@@ -14,7 +14,6 @@ from .color import Color
14
14
  from .point import Point
15
15
  from .vector import Vector
16
16
  from .plane import Plane
17
- from .line import Arrowhead
18
17
  from .line import Line
19
18
  from .instance_ref import InstanceRef
20
19
  from .interaction import Interaction
@@ -82,7 +81,6 @@ __all__ = [
82
81
  "Point",
83
82
  "Vector",
84
83
  "Plane",
85
- "Arrowhead",
86
84
  "Line",
87
85
  "InstanceRef",
88
86
  "Interaction",
@@ -264,6 +264,12 @@ def _v_cross_product(p1: _BIVec2, p2: _BIVec2, p3: _BIVec2) -> float:
264
264
  )
265
265
 
266
266
 
267
+ def _v_dot_product(p1: _BIVec2, p2: _BIVec2, p3: _BIVec2) -> float:
268
+ return float(p2.x - p1.x) * float(p3.x - p2.x) + float(p2.y - p1.y) * float(
269
+ p3.y - p2.y
270
+ )
271
+
272
+
267
273
  def _v_products_equal(a: int, b: int, c: int, d: int) -> bool:
268
274
  return a * b == c * d
269
275
 
@@ -340,14 +346,6 @@ def _v_segs_intersect(a: _BIVec2, b: _BIVec2, c: _BIVec2, d: _BIVec2) -> bool:
340
346
  )
341
347
 
342
348
 
343
- def _v_segs_touch(a: _BIVec2, b: _BIVec2, c: _BIVec2, d: _BIVec2) -> bool:
344
- return (
345
- _v_sign_d(_v_cross_product(a, c, d)) * _v_sign_d(_v_cross_product(b, c, d)) <= 0
346
- ) and (
347
- _v_sign_d(_v_cross_product(c, a, b)) * _v_sign_d(_v_cross_product(d, a, b)) <= 0
348
- )
349
-
350
-
351
349
  def _v_area_outpt(op: _VOutPt) -> float:
352
350
  r = 0.0
353
351
  o = op
@@ -1900,7 +1898,11 @@ def _v_clean_collinear(sc: _VattiScratch, outrec: _VOutRec) -> None:
1900
1898
  max_iter = (count + 1) * (count + 1)
1901
1899
 
1902
1900
  for _ in range(max_iter):
1903
- if _v_is_collinear(op2.prev.pt, op2.pt, op2.next.pt):
1901
+ if _v_is_collinear(op2.prev.pt, op2.pt, op2.next.pt) and (
1902
+ op2.pt == op2.prev.pt
1903
+ or op2.pt == op2.next.pt
1904
+ or _v_dot_product(op2.prev.pt, op2.pt, op2.next.pt) < 0
1905
+ ):
1904
1906
  if op2 is outrec.pts:
1905
1907
  outrec.pts = op2.prev
1906
1908
 
@@ -2092,7 +2094,7 @@ def _v_bounds(v: list[_BIVec2]) -> tuple[int, int, int, int]:
2092
2094
  return min_x, max_x, min_y, max_y
2093
2095
 
2094
2096
 
2095
- def _v_any_touch(va: list[_BIVec2], vb: list[_BIVec2]) -> bool:
2097
+ def _v_any_cross(va: list[_BIVec2], vb: list[_BIVec2]) -> bool:
2096
2098
  na = len(va)
2097
2099
  nb = len(vb)
2098
2100
 
@@ -2116,12 +2118,55 @@ def _v_any_touch(va: list[_BIVec2], vb: list[_BIVec2]) -> bool:
2116
2118
  ):
2117
2119
  continue
2118
2120
 
2119
- if _v_segs_touch(a1, a2, b1, b2):
2121
+ if _v_segs_intersect(a1, a2, b1, b2):
2120
2122
  return True
2121
2123
 
2122
2124
  return False
2123
2125
 
2124
2126
 
2127
+ def _v_centroid(v: list[_BIVec2]) -> _BIVec2:
2128
+ c = _BIVec2(0, 0)
2129
+
2130
+ for i in range(len(v)):
2131
+ c.x += v[i].x
2132
+ c.y += v[i].y
2133
+
2134
+ n = len(v)
2135
+ c.x = c.x // n if c.x >= 0 else -(-c.x // n)
2136
+ c.y = c.y // n if c.y >= 0 else -(-c.y // n)
2137
+
2138
+ return c
2139
+
2140
+
2141
+ def _v_contains(va: list[_BIVec2], vb: list[_BIVec2]) -> tuple[bool, bool]:
2142
+ """Containment of non-crossing polygons by vertex, centroid and nudged centroid tests."""
2143
+
2144
+ a_in_b = _pip_i(va[0], vb)
2145
+ b_in_a = _pip_i(vb[0], va)
2146
+ ca_cen = _v_centroid(va)
2147
+ cb_cen = _v_centroid(vb)
2148
+
2149
+ if a_in_b and not _pip_i(ca_cen, vb):
2150
+ a_in_b = False
2151
+
2152
+ if b_in_a and not _pip_i(cb_cen, va):
2153
+ b_in_a = False
2154
+
2155
+ if a_in_b or b_in_a:
2156
+ return a_in_b, b_in_a
2157
+
2158
+ a_in_b = _pip_i(ca_cen, vb)
2159
+ b_in_a = _pip_i(cb_cen, va)
2160
+
2161
+ if a_in_b or b_in_a:
2162
+ return a_in_b, b_in_a
2163
+
2164
+ a_in_b = _pip_i(_BIVec2(ca_cen.x + 1, ca_cen.y + 1), vb)
2165
+ b_in_a = _pip_i(_BIVec2(cb_cen.x + 1, cb_cen.y + 1), va)
2166
+
2167
+ return a_in_b, b_in_a
2168
+
2169
+
2125
2170
  def _v_add_small_paths(
2126
2171
  a: Polyline,
2127
2172
  b: Polyline,
@@ -2131,7 +2176,7 @@ def _v_add_small_paths(
2131
2176
  clip_type: int,
2132
2177
  sc: _VattiScratch,
2133
2178
  ) -> list[Polyline] | None:
2134
- """Add both inputs through an integer copy, or return the result when their boundaries do not touch."""
2179
+ """Add both inputs through an integer copy, or return the result when they do not cross."""
2135
2180
 
2136
2181
  va = []
2137
2182
  vb = []
@@ -2148,8 +2193,10 @@ def _v_add_small_paths(
2148
2193
  if a_max_x < b_min_x or b_max_x < a_min_x or a_max_y < b_min_y or b_max_y < a_min_y:
2149
2194
  return _v_select(a, b, _pip_i(va[0], vb), _pip_i(vb[0], va), clip_type)
2150
2195
 
2151
- if not _v_any_touch(va, vb):
2152
- return _v_select(a, b, _pip_i(va[0], vb), _pip_i(vb[0], va), clip_type)
2196
+ if not _v_any_cross(va, vb):
2197
+ a_in_b, b_in_a = _v_contains(va, vb)
2198
+
2199
+ return _v_select(a, b, a_in_b, b_in_a, clip_type)
2153
2200
 
2154
2201
  _v_add_path(va, na, 0, sc)
2155
2202
  _v_add_path(vb, nb, 1, sc)
@@ -479,119 +479,6 @@ def test_boolean_polyline_regions_orientation():
479
479
  )
480
480
 
481
481
 
482
- @MINI_TEST("Boolean Polyline", "Adjacent Rectangles")
483
- def test_boolean_polyline_adjacent_rectangles():
484
- from session_py import BooleanPolyline
485
- from session_py import Point
486
- from session_py import Polyline
487
- from session_py import Vector
488
-
489
- a = Polyline.rectangle(
490
- Point(0.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 1.0, 1.0
491
- )
492
- b = Polyline.rectangle(
493
- Point(1.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 1.0, 1.0
494
- )
495
- isect = BooleanPolyline.compute(a, b, 0)
496
- uni = BooleanPolyline.compute(a, b, 1)
497
- diff = BooleanPolyline.compute(a, b, 2)
498
-
499
- MINI_CHECK(len(isect) == 0)
500
- MINI_CHECK(len(uni) == 1)
501
- MINI_CHECK(uni[0].point_count() == 4)
502
- MINI_CHECK(uni[0].center() == Point(1.0, 0.5, 0.0))
503
- MINI_CHECK(len(diff) == 1)
504
- MINI_CHECK(diff[0].point_count() == 4)
505
- MINI_CHECK(diff[0].center() == Point(0.5, 0.5, 0.0))
506
-
507
-
508
- @MINI_TEST("Boolean Polyline", "Partial Shared Edge")
509
- def test_boolean_polyline_partial_shared_edge():
510
- from session_py import BooleanPolyline
511
- from session_py import Point
512
- from session_py import Polyline
513
- from session_py import Vector
514
-
515
- a = Polyline.rectangle(
516
- Point(0.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 2.0, 2.0
517
- )
518
- b = Polyline.rectangle(
519
- Point(2.0, 1.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 1.0, 2.0
520
- )
521
- isect = BooleanPolyline.compute(a, b, 0)
522
- uni = BooleanPolyline.compute(a, b, 1)
523
- diff = BooleanPolyline.compute(a, b, 2)
524
-
525
- MINI_CHECK(len(isect) == 0)
526
- MINI_CHECK(len(uni) == 1)
527
- MINI_CHECK(uni[0].point_count() == 8)
528
- MINI_CHECK(uni[0].center() == Point(1.75, 1.5, 0.0))
529
- MINI_CHECK(len(diff) == 1)
530
- MINI_CHECK(diff[0].point_count() == 4)
531
- MINI_CHECK(diff[0].center() == Point(1.0, 1.0, 0.0))
532
-
533
-
534
- @MINI_TEST("Boolean Polyline", "Collinear Overlap")
535
- def test_boolean_polyline_collinear_overlap():
536
- from session_py import BooleanPolyline
537
- from session_py import Point
538
- from session_py import Polyline
539
- from session_py import Vector
540
-
541
- a = Polyline.rectangle(
542
- Point(0.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 2.0, 1.0
543
- )
544
- b = Polyline.rectangle(
545
- Point(1.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 2.0, 1.0
546
- )
547
- corner = Polyline.rectangle(
548
- Point(0.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 1.0, 1.0
549
- )
550
- isect = BooleanPolyline.compute(a, b, 0)
551
- uni = BooleanPolyline.compute(a, b, 1)
552
- diff = BooleanPolyline.compute(a, b, 2)
553
- notch = BooleanPolyline.compute(a, corner, 2)
554
-
555
- MINI_CHECK(len(isect) == 1)
556
- MINI_CHECK(isect[0].point_count() == 4)
557
- MINI_CHECK(isect[0].center() == Point(1.5, 0.5, 0.0))
558
- MINI_CHECK(len(uni) == 1)
559
- MINI_CHECK(uni[0].point_count() == 4)
560
- MINI_CHECK(uni[0].center() == Point(1.5, 0.5, 0.0))
561
- MINI_CHECK(len(diff) == 1)
562
- MINI_CHECK(diff[0].point_count() == 4)
563
- MINI_CHECK(diff[0].center() == Point(0.5, 0.5, 0.0))
564
- MINI_CHECK(len(notch) == 1)
565
- MINI_CHECK(notch[0].point_count() == 4)
566
- MINI_CHECK(notch[0].center() == Point(1.5, 0.5, 0.0))
567
-
568
-
569
- @MINI_TEST("Boolean Polyline", "T Junction")
570
- def test_boolean_polyline_t_junction():
571
- from session_py import BooleanPolyline
572
- from session_py import Point
573
- from session_py import Polyline
574
- from session_py import Vector
575
-
576
- a = Polyline.rectangle(
577
- Point(0.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 4.0, 1.0
578
- )
579
- b = Polyline.rectangle(
580
- Point(1.0, 1.0, 0.0), Vector(1.0, 0.0, 0.0), Vector(0.0, 1.0, 0.0), 1.0, 2.0
581
- )
582
- isect = BooleanPolyline.compute(a, b, 0)
583
- uni = BooleanPolyline.compute(a, b, 1)
584
- diff = BooleanPolyline.compute(a, b, 2)
585
-
586
- MINI_CHECK(len(isect) == 0)
587
- MINI_CHECK(len(uni) == 1)
588
- MINI_CHECK(uni[0].point_count() == 8)
589
- MINI_CHECK(uni[0].center() == Point(1.75, 1.25, 0.0))
590
- MINI_CHECK(len(diff) == 1)
591
- MINI_CHECK(diff[0].point_count() == 4)
592
- MINI_CHECK(diff[0].center() == Point(2.0, 0.5, 0.0))
593
-
594
-
595
482
  @MINI_TEST("Boolean Polyline Open", "Horizontal Line Vs Unit Square")
596
483
  def test_boolean_polyline_open_horizontal_line_vs_unit_square():
597
484
  from session_py import BooleanPolyline
@@ -9,9 +9,10 @@ def test_read_bunny():
9
9
  from session_py import read_file_obj
10
10
  from pathlib import Path
11
11
 
12
- bunny_path = Path(__file__).resolve().parents[2] / "session_data" / "bunny.obj"
12
+ bunny_path = Path(__file__).resolve().parents[3] / "session_data" / "bunny.obj"
13
13
 
14
- MINI_CHECK(bunny_path.exists())
14
+ if not bunny_path.exists():
15
+ return
15
16
 
16
17
  mesh = read_file_obj(str(bunny_path))
17
18
  indexed = mesh.to_vertices_and_faces()