@@ -1477,6 +1477,53 @@ def intersect_plane(self, plane):
1477
1477
return _int_seg3d
1478
1478
return None
1479
1479
1480
+ def intersect_face (self , face , tolerance ):
1481
+ """Get the intersection between this face and another input Face3D.
1482
+
1483
+ Args:
1484
+ face: A Face3D object for which intersection will be computed.
1485
+ tolerance: The maximum difference between point values for them to be
1486
+ considered distinct from one another.
1487
+
1488
+ Returns:
1489
+ List of LineSegment3D objects for the intersection.
1490
+ Will be None if no intersection exists.
1491
+ """
1492
+ # get the intersection of this face with the other plane
1493
+ self_int = self .intersect_plane (face .plane )
1494
+ if self_int is None :
1495
+ return None
1496
+ # get the intersection of the other face with this face's plane
1497
+ other_int = face .intersect_plane (self .plane )
1498
+ if other_int is None :
1499
+ return None
1500
+ # determine the overlapping parts of the two intersections
1501
+ overlap_segs = []
1502
+ for seg1 in self_int :
1503
+ s1p1 , s1p2 = seg1 .p1 , seg1 .p2
1504
+ for seg2 in other_int :
1505
+ s2p1 , s2p2 = seg2 .p1 , seg2 .p2
1506
+ use_s1p1 = seg2 .distance_to_point (s1p1 ) <= tolerance
1507
+ use_s1p2 = seg2 .distance_to_point (s1p2 ) <= tolerance
1508
+ use_s2p1 = seg1 .distance_to_point (s2p1 ) <= tolerance
1509
+ use_s2p2 = seg1 .distance_to_point (s2p2 ) <= tolerance
1510
+ if use_s1p1 and use_s1p2 :
1511
+ overlap_segs .append (seg1 )
1512
+ elif use_s2p1 and use_s2p2 :
1513
+ overlap_segs .append (seg2 )
1514
+ elif use_s1p1 and use_s2p1 :
1515
+ overlap_segs .append (LineSegment3D .from_end_points (s1p1 , s2p1 ))
1516
+ elif use_s1p1 and use_s2p2 :
1517
+ overlap_segs .append (LineSegment3D .from_end_points (s1p1 , s2p2 ))
1518
+ elif use_s1p2 and use_s2p1 :
1519
+ overlap_segs .append (LineSegment3D .from_end_points (s1p2 , s2p1 ))
1520
+ elif use_s1p2 and use_s2p2 :
1521
+ overlap_segs .append (LineSegment3D .from_end_points (s1p2 , s2p2 ))
1522
+ overlap_segs = [seg for seg in overlap_segs if seg .length > tolerance ]
1523
+ if len (overlap_segs ) == 0 :
1524
+ return None
1525
+ return overlap_segs
1526
+
1480
1527
def project_point (self , point ):
1481
1528
"""Project a Point3D onto this face.
1482
1529
@@ -2308,9 +2355,12 @@ def coplanar_difference(self, faces, tolerance, angle_tolerance):
2308
2355
# subtract the boolean polygons
2309
2356
try :
2310
2357
b_poly1 = pb .difference (b_poly1 , b_poly2 , int_tol )
2311
- except Exception :
2312
- return [self ] # typically a tolerance issue causing failure
2313
-
2358
+ except Exception : # tiny edge caused a failure; try with small tol
2359
+ int_tol = int_tol / 100
2360
+ try :
2361
+ b_poly1 = pb .difference (b_poly1 , b_poly2 , int_tol )
2362
+ except Exception :
2363
+ return [self ] # the edge is just too tiny
2314
2364
# rebuild the Face3D from the result of the subtraction
2315
2365
return Face3D ._from_bool_poly (b_poly1 , prim_pl , tolerance )
2316
2366
@@ -2362,8 +2412,12 @@ def coplanar_union(face1, face2, tolerance, angle_tolerance):
2362
2412
int_tol = tolerance / 1000
2363
2413
try :
2364
2414
poly_result = pb .union (b_poly1 , b_poly2 , int_tol )
2365
- except Exception :
2366
- return None # typically a tolerance issue causing failure
2415
+ except Exception : # tiny edge caused a failure; try with small tol
2416
+ int_tol = int_tol / 100
2417
+ try :
2418
+ poly_result = pb .union (b_poly1 , b_poly2 , int_tol )
2419
+ except Exception :
2420
+ return None # the edge is just too tiny
2367
2421
# rebuild the Face3D from the results and return them
2368
2422
union_faces = Face3D ._from_bool_poly (poly_result , prim_pl , tolerance )
2369
2423
return union_faces [0 ]
@@ -2419,8 +2473,12 @@ def coplanar_intersection(face1, face2, tolerance, angle_tolerance):
2419
2473
int_tol = tolerance / 1000
2420
2474
try :
2421
2475
poly_result = pb .intersect (b_poly1 , b_poly2 , int_tol )
2422
- except Exception :
2423
- return None # typically a tolerance issue causing failure
2476
+ except Exception : # tiny edge caused a failure; try with small tol
2477
+ int_tol = int_tol / 100
2478
+ try :
2479
+ poly_result = pb .intersect (b_poly1 , b_poly2 , int_tol )
2480
+ except Exception :
2481
+ return None # the edge is just too tiny
2424
2482
# rebuild the Face3D from the results and return them
2425
2483
int_faces = Face3D ._from_bool_poly (poly_result , prim_pl , tolerance )
2426
2484
return int_faces
@@ -2491,8 +2549,13 @@ def coplanar_split(face1, face2, tolerance, angle_tolerance):
2491
2549
int_tol = tolerance / 1000
2492
2550
try :
2493
2551
int_result , poly1_result , poly2_result = pb .split (b_poly1 , b_poly2 , int_tol )
2494
- except Exception :
2495
- return [face1 ], [face2 ] # typically a tolerance issue causing failure
2552
+ except Exception : # tiny edge caused a failure; try one more time with small tol
2553
+ int_tol = int_tol / 100
2554
+ try :
2555
+ int_result , poly1_result , poly2_result = \
2556
+ pb .split (b_poly1 , b_poly2 , int_tol )
2557
+ except Exception :
2558
+ return [face1 ], [face2 ] # the edge is just too tiny
2496
2559
# rebuild the Face3D from the results and return them
2497
2560
int_faces = Face3D ._from_bool_poly (int_result , prim_pl , tolerance )
2498
2561
poly1_faces = Face3D ._from_bool_poly (poly1_result , prim_pl , tolerance )
@@ -2561,11 +2624,15 @@ def coplanar_union_all(faces, tolerance, angle_tolerance):
2561
2624
prev_poly .append (bool_pts )
2562
2625
bool_polys .append (pb .BooleanPolygon (prev_poly ))
2563
2626
# union the boolean polygons with one another
2564
- int_tol = tolerance / 100
2627
+ int_tol = tolerance / 1000
2565
2628
try :
2566
2629
poly_result = pb .union_all (bool_polys , int_tol )
2567
- except Exception :
2568
- return None # typically a tolerance issue causing failure
2630
+ except Exception : # tiny edge caused a failure; try with small tol
2631
+ int_tol = int_tol / 100
2632
+ try :
2633
+ poly_result = pb .union_all (bool_polys , int_tol )
2634
+ except Exception :
2635
+ return None # the edge is just too tiny
2569
2636
# rebuild the Face3D from the results and return them
2570
2637
union_faces = Face3D ._from_bool_poly (poly_result , prim_pl , tolerance )
2571
2638
return union_faces
0 commit comments