topologicpy 0.4.94__py3-none-any.whl → 0.4.96__py3-none-any.whl

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.
topologicpy/Face.py CHANGED
@@ -427,19 +427,13 @@ class Face(Topology):
427
427
  planar_shell = Shell.Planarize(shell)
428
428
  normal = Face.Normal(Topology.Faces(planar_shell)[0])
429
429
  planar_shell = Topology.Flatten(planar_shell, origin=origin, direction=normal)
430
- d = Topology.Dictionary(planar_shell)
431
- phi = Dictionary.ValueAtKey(d, 'phi')
432
- theta = Dictionary.ValueAtKey(d, 'theta')
433
- x_tran = Dictionary.ValueAtKey(d, 'x')
434
- y_tran = Dictionary.ValueAtKey(d, 'y')
435
- z_tran = Dictionary.ValueAtKey(d, 'z')
436
430
  vertices = Shell.Vertices(planar_shell)
437
431
  new_vertices = []
438
432
  for v in vertices:
439
433
  x, y, z = Vertex.Coordinates(v)
440
434
  new_v = Vertex.ByCoordinates(x,y,0)
441
435
  new_vertices.append(new_v)
442
- planar_shell = Topology.SelfMerge(Topology.ReplaceVertices(planar_shell, verticesA=vertices, verticesB=new_vertices))
436
+ planar_shell = Topology.SelfMerge(Topology.ReplaceVertices(planar_shell, verticesA=vertices, verticesB=new_vertices), tolerance=tolerance)
443
437
  ext_boundary = Shell.ExternalBoundary(planar_shell, tolerance=tolerance)
444
438
  ext_boundary = Topology.RemoveCollinearEdges(ext_boundary, angTolerance)
445
439
  if not isinstance(ext_boundary, topologic.Topology):
@@ -452,9 +446,7 @@ class Face(Topology):
452
446
  ext_boundary = Topology.RemoveCollinearEdges(ext_boundary, angTolerance)
453
447
  try:
454
448
  face = Face.ByWire(ext_boundary)
455
- face = Topology.Rotate(face, world_origin, 0, 1, 0, theta)
456
- face = Topology.Rotate(face, world_origin, 0, 0, 1, phi)
457
- face = Topology.Translate(face, x_tran, y_tran, z_tran)
449
+ face = Topology.Unflatten(face, origin=origin, direction=normal)
458
450
  return face
459
451
  except:
460
452
  print("Face.ByShell - Error: The operation failed. Returning None.")
@@ -485,9 +477,7 @@ class Face(Topology):
485
477
  ext_wire = Topology.RemoveCollinearEdges(temp_wires[0], angTolerance)
486
478
  face = Face.ByWires(ext_wire, int_wires)
487
479
 
488
- face = Topology.Rotate(face, world_origin, 0, 1, 0, theta)
489
- face = Topology.Rotate(face, world_origin, 0, 0, 1, phi)
490
- face = Topology.Translate(face, x_tran, y_tran, z_tran)
480
+ face = Topology.Unflatten(face, origin=origin, direction=normal)
491
481
  return face
492
482
  else:
493
483
  return None
@@ -545,7 +535,7 @@ class Face(Topology):
545
535
  return Face.ByVertices(vertices)
546
536
 
547
537
  @staticmethod
548
- def ByWire(wire: topologic.Wire, tolerance: float = 0.0001) -> topologic.Face:
538
+ def ByWire(wire: topologic.Wire, tolerance: float = 0.0001, silent=False) -> topologic.Face:
549
539
  """
550
540
  Creates a face from the input closed wire.
551
541
 
@@ -553,6 +543,10 @@ class Face(Topology):
553
543
  ----------
554
544
  wire : topologic.Wire
555
545
  The input wire.
546
+ tolerance : float , optional
547
+ The desired tolerance. The default is 0.0001.
548
+ silent : bool , optional
549
+ If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
556
550
 
557
551
  Returns
558
552
  -------
@@ -577,21 +571,24 @@ class Face(Topology):
577
571
  else:
578
572
  return []
579
573
  if not isinstance(wire, topologic.Wire):
580
- print("Face.ByWire - Error: The input wire parameter is not a valid topologic wire. Returning None.")
574
+ if not silent:
575
+ print("Face.ByWire - Error: The input wire parameter is not a valid topologic wire. Returning None.")
581
576
  return None
582
577
  if not Wire.IsClosed(wire):
583
- print("Face.ByWire - Error: The input wire parameter is not a closed topologic wire. Returning None.")
578
+ if not silent:
579
+ print("Face.ByWire - Error: The input wire parameter is not a closed topologic wire. Returning None.")
584
580
  return None
585
581
 
586
582
  edges = Wire.Edges(wire)
587
- wire = Topology.SelfMerge(Cluster.ByTopologies(edges))
588
- vertices = Wire.Vertices(wire)
583
+ wire = Topology.SelfMerge(Cluster.ByTopologies(edges), tolerance=tolerance)
584
+ vertices = Topology.Vertices(wire)
589
585
  fList = []
590
586
  if isinstance(wire, topologic.Wire):
591
587
  try:
592
588
  fList = topologic.Face.ByExternalBoundary(wire)
593
589
  except:
594
- print("Face.ByWire - Warning: Could not create face by external boundary. Trying other methods.")
590
+ if not silent:
591
+ print("Face.ByWire - Warning: Could not create face by external boundary. Trying other methods.")
595
592
  if len(vertices) > 3:
596
593
  fList = triangulateWire(wire)
597
594
  else:
@@ -613,11 +610,14 @@ class Face(Topology):
613
610
  else:
614
611
  returnList.append(f)
615
612
  if len(returnList) == 0:
616
- print("Face.ByWire - Error: Could not build a face from the input wire parameter. Returning None.")
613
+ if not silent:
614
+ print("Face.ByWire - Error: Could not build a face from the input wire parameter. Returning None.")
617
615
  return None
618
616
  elif len(returnList) == 1:
619
617
  return returnList[0]
620
618
  else:
619
+ if not silent:
620
+ print("Face.ByWire - Warning: Could not build a single face from the input wire parameter. Returning a list of faces.")
621
621
  return returnList
622
622
 
623
623
  @staticmethod
@@ -750,23 +750,8 @@ class Face(Topology):
750
750
  arrow = Topology.Translate(arrow, -radius, radius, 0)
751
751
  elif placement.lower() == "upperright":
752
752
  arrow = Topology.Translate(arrow, -radius, -radius, 0)
753
- x1 = origin.X()
754
- y1 = origin.Y()
755
- z1 = origin.Z()
756
- x2 = origin.X() + direction[0]
757
- y2 = origin.Y() + direction[1]
758
- z2 = origin.Z() + direction[2]
759
- dx = x2 - x1
760
- dy = y2 - y1
761
- dz = z2 - z1
762
- dist = math.sqrt(dx**2 + dy**2 + dz**2)
763
- phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
764
- if dist < 0.0001:
765
- theta = 0
766
- else:
767
- theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
768
- arrow = Topology.Rotate(arrow, origin, 0, 1, 0, theta)
769
- arrow = Topology.Rotate(arrow, origin, 0, 0, 1, phi)
753
+ arrow = Topology.Place(arrow, originA=Vertex.Origin(), originB=origin)
754
+ arrow = Topology.Orient(arrow, orign=origin, direction=direction)
770
755
  return arrow
771
756
 
772
757
  @staticmethod
@@ -1025,129 +1010,6 @@ class Face(Topology):
1025
1010
  if dot < tolerance:
1026
1011
  return False
1027
1012
  return True
1028
-
1029
- @staticmethod
1030
- def Flatten(face: topologic.Face, originA: topologic.Vertex = None,
1031
- originB: topologic.Vertex = None, direction: list = None, tolerance: float = 0.0001) -> topologic.Face:
1032
- """
1033
- Flattens the input face such that its center of mass is located at the origin and its normal is pointed in the positive Z axis.
1034
-
1035
- Parameters
1036
- ----------
1037
- face : topologic.Face
1038
- The input face.
1039
- originA : topologic.Vertex , optional
1040
- The old location to use as the origin of the movement. If set to None, the center of mass of the input topology is used. The default is None.
1041
- originB : topologic.Vertex , optional
1042
- The new location at which to place the topology. If set to None, the world origin (0,0,0) is used. The default is None.
1043
- direction : list , optional
1044
- The direction, expressed as a list of [X,Y,Z] that signifies the direction of the face. If set to None, the normal at *u* 0.5 and *v* 0.5 is considered the direction of the face. The deafult is None.
1045
- tolerance : float , optional
1046
- The desired tolerance. The default is 0.0001.
1047
- Returns
1048
- -------
1049
- topologic.Face
1050
- The flattened face.
1051
-
1052
- """
1053
-
1054
- from topologicpy.Vertex import Vertex
1055
-
1056
- def leftMost(vertices, tolerance = 0.0001):
1057
- xCoords = []
1058
- for v in vertices:
1059
- xCoords.append(Vertex.Coordinates(vertices[0])[0])
1060
- minX = min(xCoords)
1061
- lmVertices = []
1062
- for v in vertices:
1063
- if abs(Vertex.Coordinates(vertices[0])[0] - minX) <= tolerance:
1064
- lmVertices.append(v)
1065
- return lmVertices
1066
-
1067
- def bottomMost(vertices, tolerance = 0.0001):
1068
- yCoords = []
1069
- for v in vertices:
1070
- yCoords.append(Vertex.Coordinates(vertices[0])[1])
1071
- minY = min(yCoords)
1072
- bmVertices = []
1073
- for v in vertices:
1074
- if abs(Vertex.Coordinates(vertices[0])[1] - minY) <= tolerance:
1075
- bmVertices.append(v)
1076
- return bmVertices
1077
-
1078
- def vIndex(v, vList, tolerance):
1079
- for i in range(len(vList)):
1080
- if Vertex.Distance(v, vList[i]) < tolerance:
1081
- return i+1
1082
- return None
1083
-
1084
- # rotate cycle path such that it begins with the smallest node
1085
- def rotate_to_smallest(path):
1086
- n = path.index(min(path))
1087
- return path[n:]+path[:n]
1088
-
1089
- # rotate vertices list so that it begins with the input vertex
1090
- def rotate_vertices(vertices, vertex):
1091
- n = vertices.index(vertex)
1092
- return vertices[n:]+vertices[:n]
1093
-
1094
- from topologicpy.Vertex import Vertex
1095
- from topologicpy.Topology import Topology
1096
- from topologicpy.Dictionary import Dictionary
1097
- if not isinstance(face, topologic.Face):
1098
- return None
1099
- if not isinstance(originA, topologic.Vertex):
1100
- originA = Topology.CenterOfMass(face)
1101
- if not isinstance(originB, topologic.Vertex):
1102
- originB = Vertex.ByCoordinates(0,0,0)
1103
- cm = originA
1104
- world_origin = originB
1105
- if not direction or len(direction) < 3:
1106
- direction = Face.NormalAtParameters(face, 0.5, 0.5)
1107
- x1 = Vertex.X(cm)
1108
- y1 = Vertex.Y(cm)
1109
- z1 = Vertex.Z(cm)
1110
- x2 = Vertex.X(cm) + direction[0]
1111
- y2 = Vertex.Y(cm) + direction[1]
1112
- z2 = Vertex.Z(cm) + direction[2]
1113
- dx = x2 - x1
1114
- dy = y2 - y1
1115
- dz = z2 - z1
1116
- dist = math.sqrt(dx**2 + dy**2 + dz**2)
1117
- phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
1118
- if dist < 0.0001:
1119
- theta = 0
1120
- else:
1121
- theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
1122
- flatFace = Topology.Translate(face, -cm.X(), -cm.Y(), -cm.Z())
1123
- flatFace = Topology.Rotate(flatFace, world_origin, 0, 0, 1, -phi)
1124
- flatFace = Topology.Rotate(flatFace, world_origin, 0, 1, 0, -theta)
1125
- # Ensure flatness. Force Z to be zero
1126
- flatExternalBoundary = Face.ExternalBoundary(flatFace)
1127
- flatFaceVertices = Topology.SubTopologies(flatExternalBoundary, subTopologyType="vertex")
1128
-
1129
- tempVertices = []
1130
- for ffv in flatFaceVertices:
1131
- tempVertices.append(Vertex.ByCoordinates(ffv.X(), ffv.Y(), 0))
1132
-
1133
- temp_v = bottomMost(leftMost(tempVertices))[0]
1134
- tempVertices = rotate_vertices(tempVertices, temp_v)
1135
- flatExternalBoundary = Wire.ByVertices(tempVertices)
1136
-
1137
- internalBoundaries = Face.InternalBoundaries(flatFace)
1138
- flatInternalBoundaries = []
1139
- for internalBoundary in internalBoundaries:
1140
- ibVertices = Wire.Vertices(internalBoundary)
1141
- tempVertices = []
1142
- for ibVertex in ibVertices:
1143
- tempVertices.append(Vertex.ByCoordinates(ibVertex.X(), ibVertex.Y(), 0))
1144
- temp_v = bottomMost(leftMost(tempVertices))[0]
1145
- tempVertices = rotate_vertices(tempVertices, temp_v)
1146
- flatInternalBoundaries.append(Wire.ByVertices(tempVertices))
1147
- flatFace = Face.ByWires(flatExternalBoundary, flatInternalBoundaries, tolerance=tolerance)
1148
- dictionary = Dictionary.ByKeysValues(["x", "y", "z", "phi", "theta"], [cm.X(), cm.Y(), cm.Z(), phi, theta])
1149
- flatFace = Topology.SetDictionary(flatFace, dictionary)
1150
- return flatFace
1151
1013
 
1152
1014
  @staticmethod
1153
1015
  def Harmonize(face: topologic.Face, tolerance: float = 0.0001) -> topologic.Face:
@@ -1179,13 +1041,6 @@ class Face(Topology):
1179
1041
  origin = Topology.Centroid(face)
1180
1042
  flatFace = Topology.Flatten(face, origin=origin, direction=normal)
1181
1043
  world_origin = Vertex.Origin()
1182
- # Retrieve the needed transformations
1183
- dictionary = Topology.Dictionary(flatFace)
1184
- xTran = Dictionary.ValueAtKey(dictionary,"x")
1185
- yTran = Dictionary.ValueAtKey(dictionary,"y")
1186
- zTran = Dictionary.ValueAtKey(dictionary,"z")
1187
- phi = Dictionary.ValueAtKey(dictionary,"phi")
1188
- theta = Dictionary.ValueAtKey(dictionary,"theta")
1189
1044
  vertices = Wire.Vertices(Face.ExternalBoundary(flatFace))
1190
1045
  harmonizedEB = Wire.ByVertices(vertices)
1191
1046
  internalBoundaries = Face.InternalBoundaries(flatFace)
@@ -1194,9 +1049,7 @@ class Face(Topology):
1194
1049
  ibVertices = Wire.Vertices(ib)
1195
1050
  harmonizedIB.append(Wire.ByVertices(ibVertices))
1196
1051
  harmonizedFace = Face.ByWires(harmonizedEB, harmonizedIB, tolerance=tolerance)
1197
- harmonizedFace = Topology.Rotate(harmonizedFace, origin=world_origin, x=0, y=1, z=0, degree=theta)
1198
- harmonizedFace = Topology.Rotate(harmonizedFace, origin=world_origin, x=0, y=0, z=1, degree=phi)
1199
- harmonizedFace = Topology.Translate(harmonizedFace, xTran, yTran, zTran)
1052
+ harmonizedFace = Topology.Unflatten(harmonizedFace, origin=origin, direction=normal)
1200
1053
  return harmonizedFace
1201
1054
 
1202
1055
  @staticmethod
@@ -1279,17 +1132,18 @@ class Face(Topology):
1279
1132
  The created vertex.
1280
1133
 
1281
1134
  """
1135
+ from topologicpy.Vertex import Vertex
1282
1136
  from topologicpy.Topology import Topology
1283
1137
  if not isinstance(face, topologic.Face):
1284
1138
  return None
1285
1139
  v = Topology.Centroid(face)
1286
- if Face.IsInternal(face, v):
1140
+ if Vertex.IsInternal(v, face, tolerance=tolerance):
1287
1141
  return v
1288
1142
  l = [0.4,0.6,0.3,0.7,0.2,0.8,0.1,0.9]
1289
1143
  for u in l:
1290
1144
  for v in l:
1291
1145
  v = Face.VertexByParameters(face, u, v)
1292
- if Face.IsInternal(face, v):
1146
+ if Vertex.IsInternal(v, face, tolerance=tolerance):
1293
1147
  return v
1294
1148
  v = topologic.FaceUtility.InternalVertex(face, tolerance)
1295
1149
  return v
@@ -1360,59 +1214,7 @@ class Face(Topology):
1360
1214
  return None
1361
1215
  dirA = Face.NormalAtParameters(faceA, 0.5, 0.5, "xyz", 3)
1362
1216
  dirB = Face.NormalAtParameters(faceB, 0.5, 0.5, "xyz", 3)
1363
- return Vector.IsCollinear(dirA, dirB, tolerance)
1364
-
1365
- @staticmethod
1366
- def IsInside(face: topologic.Face, vertex: topologic.Vertex, tolerance: float = 0.0001) -> bool:
1367
- """
1368
- DEPRECATED METHOD. DO NOT USE. INSTEAD USE Face.IsInternal.
1369
- """
1370
- print("Face.IsInside - Warning: Deprecated method. This method will be removed in the future. Instead, use Face.IsInternal.")
1371
- return Face.IsInternal(face=face, vertex=vertex, tolerance=tolerance)
1372
-
1373
- @staticmethod
1374
- def IsInternal(face: topologic.Face, vertex: topologic.Vertex, tolerance: float = 0.0001) -> bool:
1375
- """
1376
- Returns True if the input vertex is an internal vertex of the input face. Returns False otherwise.
1377
-
1378
- Parameters
1379
- ----------
1380
- face : topologic.Face
1381
- The input face.
1382
- vertex : topologic.Vertex
1383
- The input vertex.
1384
- tolerance : float , optional
1385
- The desired tolerance. The default is 0.0001.
1386
-
1387
- Returns
1388
- -------
1389
- bool
1390
- True if the input vertex is inside the input face. False otherwise.
1391
-
1392
- """
1393
- from topologicpy.Vertex import Vertex
1394
- from topologicpy.Cell import Cell
1395
- from topologicpy.Cluster import Cluster
1396
- from topologicpy.Topology import Topology
1397
- from topologicpy.Dictionary import Dictionary
1398
-
1399
- if not isinstance(face, topologic.Face):
1400
- print("Face.IsInternal - Error: The input face parameter is not a valid topologic face. Returning None.")
1401
- return None
1402
- if not isinstance(vertex, topologic.Vertex):
1403
- print("Face.IsInternal - Error: The input vertex parameter is not a valid topologic vertex. Returning None.")
1404
- return None
1405
- # Test the distance first
1406
- if Vertex.PerpendicularDistance(vertex, face) > tolerance:
1407
- return False
1408
- status = False
1409
- try:
1410
- status = topologic.FaceUtility.IsInside(face, vertex, tolerance)
1411
- except:
1412
- print("Face.IsInternal - Warning: Could not determine if vertex is inside face. Returning False.")
1413
- clus = Cluster.ByTopologies([vertex, face])
1414
- status = False
1415
- return status
1217
+ return Vector.IsCollinear(dirA, dirB)
1416
1218
 
1417
1219
  @staticmethod
1418
1220
  def MedialAxis(face: topologic.Face, resolution: int = 0, externalVertices: bool = False, internalVertices: bool = False, toLeavesOnly: bool = False, angTolerance: float = 0.1, tolerance: float = 0.0001) -> topologic.Wire:
@@ -1465,13 +1267,6 @@ class Face(Topology):
1465
1267
  origin = Topology.Centroid(face)
1466
1268
  normal = Face.Normal(face)
1467
1269
  flatFace = Topology.Flatten(face, origin=origin, direction=normal)
1468
- # Retrieve the needed transformations
1469
- dictionary = Topology.Dictionary(flatFace)
1470
- xTran = Dictionary.ValueAtKey(dictionary,"x")
1471
- yTran = Dictionary.ValueAtKey(dictionary,"y")
1472
- zTran = Dictionary.ValueAtKey(dictionary,"z")
1473
- phi = Dictionary.ValueAtKey(dictionary,"phi")
1474
- theta = Dictionary.ValueAtKey(dictionary,"theta")
1475
1270
 
1476
1271
  # Create a Vertex at the world's origin (0,0,0)
1477
1272
  world_origin = Vertex.Origin()
@@ -1493,8 +1288,6 @@ class Face(Topology):
1493
1288
  ev = Edge.EndVertex(e)
1494
1289
  svTouchesEdge = touchesEdge(sv, faceEdges, tolerance=tolerance)
1495
1290
  evTouchesEdge = touchesEdge(ev, faceEdges, tolerance=tolerance)
1496
- #connectsToCorners = (Vertex.Index(sv, faceVertices) != None) or (Vertex.Index(ev, faceVertices) != None)
1497
- #if Face.IsInternal(flatFace, sv, tolerance=tolerance) and Face.IsInternal(flatFace, ev, tolerance=tolerance):
1498
1291
  if not svTouchesEdge and not evTouchesEdge:
1499
1292
  medialAxisEdges.append(e)
1500
1293
 
@@ -1529,9 +1322,7 @@ class Face(Topology):
1529
1322
  medialAxis = Topology.SelfMerge(Cluster.ByTopologies(medialAxisEdges), tolerance=tolerance)
1530
1323
  if isinstance(medialAxis, topologic.Wire) and angTolerance > 0:
1531
1324
  medialAxis = Topology.RemoveCollinearEdges(medialAxis, angTolerance=angTolerance)
1532
- medialAxis = Topology.Rotate(medialAxis, origin=world_origin, x=0, y=1, z=0, degree=theta)
1533
- medialAxis = Topology.Rotate(medialAxis, origin=world_origin, x=0, y=0, z=1, degree=phi)
1534
- medialAxis = Topology.Translate(medialAxis, xTran, yTran, zTran)
1325
+ medialAxis = Topology.Unflatten(medialAxis, origin=origin,direction=normal)
1535
1326
  return medialAxis
1536
1327
 
1537
1328
  @staticmethod
@@ -1683,7 +1474,7 @@ class Face(Topology):
1683
1474
 
1684
1475
  @staticmethod
1685
1476
  def Planarize(face: topologic.Face, origin: topologic.Vertex = None,
1686
- direction: list = None, tolerance: float = 0.0001) -> topologic.Face:
1477
+ tolerance: float = 0.0001) -> topologic.Face:
1687
1478
  """
1688
1479
  Planarizes the input face such that its center of mass is located at the input origin and its normal is pointed in the input direction.
1689
1480
 
@@ -1692,9 +1483,7 @@ class Face(Topology):
1692
1483
  face : topologic.Face
1693
1484
  The input face.
1694
1485
  origin : topologic.Vertex , optional
1695
- The old location to use as the origin of the movement. If set to None, the center of mass of the input face is used. The default is None.
1696
- direction : list , optional
1697
- The direction, expressed as a list of [X,Y,Z] that signifies the direction of the face. If set to None, the normal at *u* 0.5 and *v* 0.5 is considered the direction of the face. The deafult is None.
1486
+ The desired vertex to use as the origin of the plane to project the face unto. If set to None, the centroidof the input face is used. The default is None.
1698
1487
  tolerance : float , optional
1699
1488
  The desired tolerance. The default is 0.0001.
1700
1489
 
@@ -1705,32 +1494,21 @@ class Face(Topology):
1705
1494
 
1706
1495
  """
1707
1496
 
1708
- from topologicpy.Vertex import Vertex
1709
1497
  from topologicpy.Wire import Wire
1710
1498
  from topologicpy.Topology import Topology
1711
- from topologicpy.Dictionary import Dictionary
1712
1499
 
1713
1500
  if not isinstance(face, topologic.Face):
1714
1501
  return None
1715
1502
  if not isinstance(origin, topologic.Vertex):
1716
1503
  origin = Topology.Centroid(face)
1717
- if not isinstance(direction, list):
1718
- normal = Face.Normal(face)
1719
- flatFace = Topology.Flatten(face, origin=origin, direction=normal)
1720
-
1721
- world_origin = Vertex.ByCoordinates(0,0,0)
1722
- # Retrieve the needed transformations
1723
- dictionary = Topology.Dictionary(flatFace)
1724
- xTran = Dictionary.ValueAtKey(dictionary,"x")
1725
- yTran = Dictionary.ValueAtKey(dictionary,"y")
1726
- zTran = Dictionary.ValueAtKey(dictionary,"z")
1727
- phi = Dictionary.ValueAtKey(dictionary,"phi")
1728
- theta = Dictionary.ValueAtKey(dictionary,"theta")
1729
-
1730
- planarizedFace = Topology.Rotate(flatFace, origin=world_origin, x=0, y=1, z=0, degree=theta)
1731
- planarizedFace = Topology.Rotate(planarizedFace, origin=world_origin, x=0, y=0, z=1, degree=phi)
1732
- planarizedFace = Topology.Translate(planarizedFace, xTran, yTran, zTran)
1733
- return planarizedFace
1504
+ eb = Face.ExternalBoundary(face)
1505
+ plan_eb = Wire.Planarize(eb, origin=origin)
1506
+ ib_list = Face.InternalBoundaries(face)
1507
+ plan_ib_list = []
1508
+ for ib in ib_list:
1509
+ plan_ib_list.append(Wire.Planarize(ib, origin=origin))
1510
+ plan_face = Face.ByWires(plan_eb, plan_ib_list)
1511
+ return plan_face
1734
1512
 
1735
1513
  @staticmethod
1736
1514
  def Project(faceA: topologic.Face, faceB: topologic.Face, direction : list = None,
@@ -2014,16 +1792,9 @@ class Face(Topology):
2014
1792
  vertices = Topology.Vertices(face)
2015
1793
  if len(vertices) == 3: # Already a triangle
2016
1794
  return [face]
2017
- flatFace = Face.Flatten(face)
2018
-
2019
- world_origin = Vertex.ByCoordinates(0,0,0)
2020
- # Retrieve the needed transformations
2021
- dictionary = Topology.Dictionary(flatFace)
2022
- xTran = Dictionary.ValueAtKey(dictionary,"x")
2023
- yTran = Dictionary.ValueAtKey(dictionary,"y")
2024
- zTran = Dictionary.ValueAtKey(dictionary,"z")
2025
- phi = Dictionary.ValueAtKey(dictionary,"phi")
2026
- theta = Dictionary.ValueAtKey(dictionary,"theta")
1795
+ origin = Topology.Centroid(face)
1796
+ normal = Face.Normal(face)
1797
+ flatFace = Topology.Flatten(face, origin=origin, direction=normal)
2027
1798
 
2028
1799
  shell_faces = []
2029
1800
  for i in range(0,5,1):
@@ -2037,9 +1808,7 @@ class Face(Topology):
2037
1808
  return []
2038
1809
  finalFaces = []
2039
1810
  for f in shell_faces:
2040
- f = Topology.Rotate(f, origin=world_origin, x=0, y=1, z=0, degree=theta)
2041
- f = Topology.Rotate(f, origin=world_origin, x=0, y=0, z=1, degree=phi)
2042
- f = Topology.Translate(f, xTran, yTran, zTran)
1811
+ f = Topology.Unflatten(f, origin=origin, direction=normal)
2043
1812
  if Face.Angle(face, f) > 90:
2044
1813
  wire = Face.ExternalBoundary(f)
2045
1814
  wire = Wire.Invert(wire)
@@ -2078,21 +1847,6 @@ class Face(Topology):
2078
1847
  trimmed_face = face.Difference(trimmed_face)
2079
1848
  return trimmed_face
2080
1849
 
2081
- @staticmethod
2082
- def UnFlatten(face: topologic.Face, dictionary: topologic.Dictionary):
2083
- from topologicpy.Vertex import Vertex
2084
- from topologicpy.Topology import Topology
2085
- from topologicpy.Dictionary import Dictionary
2086
- theta = Dictionary.ValueAtKey(dictionary, "theta")
2087
- phi = Dictionary.ValueAtKey(dictionary, "phi")
2088
- xTran = Dictionary.ValueAtKey(dictionary, "xTran")
2089
- yTran = Dictionary.ValueAtKey(dictionary, "yTran")
2090
- zTran = Dictionary.ValueAtKey(dictionary, "zTran")
2091
- newFace = Topology.Rotate(face, origin=Vertex.Origin(), x=0, y=1, z=0, degree=theta)
2092
- newFace = Topology.Rotate(newFace, origin=Vertex.Origin(), x=0, y=0, z=1, degree=phi)
2093
- newFace = Topology.Translate(newFace, xTran, yTran, zTran)
2094
- return newFace
2095
-
2096
1850
  @staticmethod
2097
1851
  def VertexByParameters(face: topologic.Face, u: float = 0.5, v: float = 0.5) -> topologic.Vertex:
2098
1852
  """