Skip to content

Commit

Permalink
Merge pull request #1168 from Dessia-tech/ops_bool_fx
Browse files Browse the repository at this point in the history
fix plane-plane intersections
  • Loading branch information
WirajanDASILVA authored Nov 30, 2023
2 parents f897207 + 93760f9 commit d9f3bd8
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

#### surfaces.py
- SphericalSurface3D: use circle 3d instead of polygon3D for plotting.
- add bigger precision to plane-plane intersections.

#### utils
- common_operations separate_points_by_closeness: consider more than two cluster groups.
Expand Down
217 changes: 217 additions & 0 deletions tests/faces/objects_planeface_tests/test_planef_inters291123.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
{
"object_class": "volmdlr.core.VolumeModel",
"name": "",
"primitives": [
{
"object_class": "volmdlr.faces.PlaneFace3D",
"name": "",
"surface3d": {
"object_class": "volmdlr.surfaces.Plane3D",
"name": "",
"frame": {
"object_class": "volmdlr.Frame3D",
"name": "",
"origin": {
"object_class": "volmdlr.Point3D",
"x": -0.006066296085499995,
"y": -0.00046706095649999557,
"z": 0.07196336225667499
},
"u": {
"object_class": "volmdlr.Vector3D",
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"v": {
"object_class": "volmdlr.Vector3D",
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"w": {
"object_class": "volmdlr.Vector3D",
"x": 0.0,
"y": 0.0,
"z": 1.0
}
}
},
"surface2d": {
"object_class": "volmdlr.surfaces.Surface2D",
"name": "name",
"outer_contour": {
"object_class": "volmdlr.wires.Contour2D",
"name": "",
"primitives": [
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": -0.08231778158047501,
"y": -0.063992739412875
},
"end": {
"object_class": "volmdlr.Point2D",
"x": 0.08231778158047501,
"y": -0.063992739412875
}
},
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": 0.08231778158047501,
"y": -0.063992739412875
},
"end": {
"object_class": "volmdlr.Point2D",
"x": 0.08231778158047501,
"y": 0.063992739412875
}
},
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": 0.08231778158047501,
"y": 0.063992739412875
},
"end": {
"object_class": "volmdlr.Point2D",
"x": -0.08231778158047501,
"y": 0.063992739412875
}
},
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": -0.08231778158047501,
"y": 0.063992739412875
},
"end": {
"object_class": "volmdlr.Point2D",
"x": -0.08231778158047501,
"y": -0.063992739412875
}
}
]
},
"inner_contours": []
},
"color": null,
"alpha": 1.0
},
{
"object_class": "volmdlr.faces.PlaneFace3D",
"name": "",
"surface3d": {
"object_class": "volmdlr.surfaces.Plane3D",
"name": "",
"frame": {
"object_class": "volmdlr.Frame3D",
"name": "",
"origin": {
"object_class": "volmdlr.Point3D",
"x": 0.033302871957624644,
"y": 0.02975212779047777,
"z": 0.07196864601279654
},
"u": {
"object_class": "volmdlr.Vector3D",
"x": 0.02131057692797271,
"y": -0.9997727924804454,
"z": -0.00047193945516308105
},
"v": {
"object_class": "volmdlr.Vector3D",
"x": 0.9997728099006772,
"y": 0.021310777214183903,
"z": -0.00042350659024547194
},
"w": {
"object_class": "volmdlr.Vector3D",
"x": -0.00043346776295114854,
"y": 0.0004628070654204609,
"z": -0.9999997989576392
}
}
},
"surface2d": {
"object_class": "volmdlr.surfaces.Surface2D",
"name": "copy_name",
"outer_contour": {
"object_class": "volmdlr.wires.Contour2D",
"name": "",
"primitives": [
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": 0.022,
"y": 0.000499999999999997
},
"end": {
"object_class": "volmdlr.Point2D",
"x": 0.0,
"y": 0.000499999999999997
}
},
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": 0.0,
"y": 0.000499999999999997
},
"end": {
"object_class": "volmdlr.Point2D",
"x": 0.0,
"y": 0.0040999999999999995
}
},
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": 0.0,
"y": 0.0040999999999999995
},
"end": {
"object_class": "volmdlr.Point2D",
"x": 0.022,
"y": 0.0040999999999999995
}
},
{
"object_class": "volmdlr.edges.LineSegment2D",
"name": "",
"start": {
"object_class": "volmdlr.Point2D",
"x": 0.022,
"y": 0.0040999999999999995
},
"end": {
"object_class": "volmdlr.Point2D",
"x": 0.022,
"y": 0.000499999999999997
}
}
]
},
"inner_contours": []
},
"color": null,
"alpha": 1.0
}
],
"_references": {}
}
8 changes: 8 additions & 0 deletions tests/faces/test_planeface3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ def test_plane_face_intersection(self):

self.assertEqual(1, len(face_intersections))
self.assertAlmostEqual(0.003600000000881293, face_intersections[0].length())
face1, face2 = faces.PlaneFace3D.load_from_file(
os.path.join(folder, 'test_planef_inters291123.json')).primitives
face_intersections = face1.face_intersections(face2)
line_seg = edges.LineSegment3D(
volmdlr.Point3D(0.034031786272172244, 0.019018077708099396, 0.07196336225667499),
volmdlr.Point3D(0.03756212352555941, 0.022324611455208112, 0.07196336225667499)
)
self.assertTrue(face_intersections[0].primitives[0], line_seg)

def test_face_inside(self):
face2 = self.face.frame_mapping(volmdlr.Frame3D(volmdlr.Point3D(0, 0, 0), volmdlr.Vector3D(0.5, 0, 0),
Expand Down
4 changes: 4 additions & 0 deletions volmdlr/faces.py
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,10 @@ def __init__(self,

@property
def bounding_box(self):
"""
Gets the extrusion face bounding box.
"""
if not self._bbox:
self._bbox = self.get_bounding_box()
return self._bbox
Expand Down
36 changes: 23 additions & 13 deletions volmdlr/utils/intersections.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,22 +358,11 @@ def get_plane_line_intersections(plane_frame, line, abs_tol: float = 1e-6):
return [line.point1 + intersection_abscissea * u_vector]


def get_two_planes_intersections(plane1_frame, plane2_frame):
def _helper_two_plane_intersections(plane1_frame, plane2_frame):
"""
Calculates the intersections between two planes, given their frames.
Helper function to get point 1 on two plane intersections.
:param plane1_frame: Plane's 1 frame.
:param plane2_frame: Plane's 2 frame.
:return: A list containing two points that define an infinite line if there is any intersections,
or an empty list if the planes are parallel.
"""
if plane1_frame.w.is_colinear_to(plane2_frame.w):
return []
line_direction = plane1_frame.w.cross(plane2_frame.w)

if line_direction.norm() < 1e-6:
return None

a1, b1, c1, d1 = get_plane_equation_coefficients(plane1_frame)
a2, b2, c2, d2 = get_plane_equation_coefficients(plane2_frame)
if not math.isclose(a1 * b2 - a2 * b1, 0.0, abs_tol=1e-10):
Expand All @@ -390,4 +379,25 @@ def get_two_planes_intersections(plane1_frame, plane2_frame):
point1 = volmdlr.Point3D(0, y0, z0)
else:
raise NotImplementedError
return point1


def get_two_planes_intersections(plane1_frame, plane2_frame, abs_tol=1e-8):
"""
Calculates the intersections between two planes, given their frames.
:param plane1_frame: Plane's 1 frame.
:param plane2_frame: Plane's 2 frame.
:param abs_tol: tolerance.
:return: A list containing two points that define an infinite line if there is any intersections,
or an empty list if the planes are parallel.
"""
if plane1_frame.w.is_colinear_to(plane2_frame.w, abs_tol):
return []
line_direction = plane1_frame.w.cross(plane2_frame.w)

if line_direction.norm() < abs_tol:
return None

point1 = _helper_two_plane_intersections(plane1_frame, plane2_frame)
return [point1, point1 + line_direction]

0 comments on commit d9f3bd8

Please sign in to comment.