topologicpy 0.4.95__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/Vector.py CHANGED
@@ -147,6 +147,48 @@ class Vector(list):
147
147
  altitude = round(altitude, mantissa)
148
148
  return {"azimuth":azimuth, "altitude":altitude}
149
149
 
150
+ @staticmethod
151
+ def Bisect(vectorA, vectorB):
152
+ """
153
+ Compute the bisecting vector of two input vectors.
154
+
155
+ Parameters
156
+ ----------
157
+ vectorA : list
158
+ The first input vector.
159
+ vectorB : list
160
+ The second input vector.
161
+
162
+ Returns
163
+ -------
164
+ dict
165
+ The bisecting vector.
166
+
167
+ """
168
+ import numpy as np
169
+
170
+
171
+ # Ensure vectors are numpy arrays
172
+ vector1 = np.array(vectorA)
173
+ vector2 = np.array(vectorB)
174
+
175
+ # Normalize input vectors
176
+ vector1_norm = vector1 / np.linalg.norm(vector1)
177
+ vector2_norm = vector2 / np.linalg.norm(vector2)
178
+
179
+ # Check if the angle between vectors is either 0 or 180 degrees
180
+ dot_product = np.dot(vector1_norm, vector2_norm)
181
+ if np.isclose(dot_product, 1.0) or np.isclose(dot_product, -1.0):
182
+ print("Vector.Bisect - Warning: The two vectors are collinear and thus the bisecting vector is not well-defined.")
183
+ # Angle is either 0 or 180 degrees, return any perpendicular vector
184
+ bisecting_vector = np.array([vector1[1] - vector1[2], vector1[2] - vector1[0], vector1[0] - vector1[1]])
185
+ bisecting_vector /= np.linalg.norm(bisecting_vector)
186
+ else:
187
+ # Compute bisecting vector
188
+ bisecting_vector = (vector1_norm + vector2_norm) / np.linalg.norm(vector1_norm + vector2_norm)
189
+
190
+ return bisecting_vector
191
+
150
192
  @staticmethod
151
193
  def ByAzimuthAltitude(azimuth, altitude, north=0, reverse=False, tolerance=0.0001):
152
194
  """
@@ -375,27 +417,153 @@ class Vector(list):
375
417
  return [1,0,0]
376
418
 
377
419
  @staticmethod
378
- def IsCollinear(vectorA, vectorB, angTolerance=0.1):
420
+ def IsAntiParallel(vectorA, vectorB):
421
+ """
422
+ Returns True if the input vectors are anti-parallel. Returns False otherwise.
423
+
424
+ Parameters
425
+ ----------
426
+ vectorA : list
427
+ The first input vector.
428
+ vectorB : list
429
+ The second input vector.
430
+
431
+ Returns
432
+ -------
433
+ bool
434
+ True if the input vectors are anti-parallel. False otherwise.
435
+
379
436
  """
380
- Returns True if the input vectors are collinear. Returns False otherwise.
437
+ import numpy as np
381
438
 
439
+
440
+ # Ensure vectors are numpy arrays
441
+ vector1 = np.array(vectorA)
442
+ vector2 = np.array(vectorB)
443
+
444
+ # Normalize input vectors
445
+ vector1_norm = vector1 / np.linalg.norm(vector1)
446
+ vector2_norm = vector2 / np.linalg.norm(vector2)
447
+
448
+ # Check if the angle between vectors is either 0 or 180 degrees
449
+ dot_product = np.dot(vector1_norm, vector2_norm)
450
+ if np.isclose(dot_product, -1.0):
451
+ return True
452
+ else:
453
+ # Compute bisecting vector
454
+ return False
455
+
456
+ @staticmethod
457
+ def IsParallel(vectorA, vectorB):
458
+ """
459
+ Returns True if the input vectors are parallel. Returns False otherwise.
460
+
382
461
  Parameters
383
462
  ----------
384
463
  vectorA : list
385
464
  The first input vector.
386
465
  vectorB : list
387
466
  The second input vector.
388
- angTolerance : float, optional
389
- The desired angular tolerance. The default is 0.1
467
+
468
+ Returns
469
+ -------
470
+ bool
471
+ True if the input vectors are parallel. False otherwise.
472
+
473
+ """
474
+ import numpy as np
390
475
 
476
+
477
+ # Ensure vectors are numpy arrays
478
+ vector1 = np.array(vectorA)
479
+ vector2 = np.array(vectorB)
480
+
481
+ # Normalize input vectors
482
+ vector1_norm = vector1 / np.linalg.norm(vector1)
483
+ vector2_norm = vector2 / np.linalg.norm(vector2)
484
+
485
+ # Check if the angle between vectors is either 0 or 180 degrees
486
+ dot_product = np.dot(vector1_norm, vector2_norm)
487
+ if np.isclose(dot_product, 1.0):
488
+ return True
489
+ else:
490
+ # Compute bisecting vector
491
+ return False
492
+
493
+ @staticmethod
494
+ def IsCollinear(vectorA, vectorB):
495
+ """
496
+ Returns True if the input vectors are collinear (parallel or anti-parallel). Returns False otherwise.
497
+
498
+ Parameters
499
+ ----------
500
+ vectorA : list
501
+ The first input vector.
502
+ vectorB : list
503
+ The second input vector.
504
+
391
505
  Returns
392
506
  -------
393
507
  bool
394
- Returns True if the input vectors are collinear. Returns False otherwise.
508
+ True if the input vectors are collinear (parallel or anti-parallel). False otherwise.
509
+
395
510
  """
511
+ import numpy as np
396
512
 
397
- return Vector.Angle(vectorA, vectorB) < angTolerance
398
513
 
514
+ # Ensure vectors are numpy arrays
515
+ vector1 = np.array(vectorA)
516
+ vector2 = np.array(vectorB)
517
+
518
+ # Normalize input vectors
519
+ vector1_norm = vector1 / np.linalg.norm(vector1)
520
+ vector2_norm = vector2 / np.linalg.norm(vector2)
521
+
522
+ # Check if the angle between vectors is either 0 or 180 degrees
523
+ dot_product = np.dot(vector1_norm, vector2_norm)
524
+ if np.isclose(dot_product, 1.0) or np.isclose(dot_product, -1.0):
525
+ return True
526
+ else:
527
+ # Compute bisecting vector
528
+ return False
529
+
530
+ @staticmethod
531
+ def IsParallel(vectorA, vectorB):
532
+ """
533
+ Returns True if the input vectors are parallel. Returns False otherwise.
534
+
535
+ Parameters
536
+ ----------
537
+ vectorA : list
538
+ The first input vector.
539
+ vectorB : list
540
+ The second input vector.
541
+
542
+ Returns
543
+ -------
544
+ bool
545
+ True if the input vectors are parallel. False otherwise.
546
+
547
+ """
548
+ import numpy as np
549
+
550
+
551
+ # Ensure vectors are numpy arrays
552
+ vector1 = np.array(vectorA)
553
+ vector2 = np.array(vectorB)
554
+
555
+ # Normalize input vectors
556
+ vector1_norm = vector1 / np.linalg.norm(vector1)
557
+ vector2_norm = vector2 / np.linalg.norm(vector2)
558
+
559
+ # Check if the angle between vectors is either 0 or 180 degrees
560
+ dot_product = np.dot(vector1_norm, vector2_norm)
561
+ if np.isclose(dot_product, 1.0):
562
+ return True
563
+ else:
564
+ # Compute bisecting vector
565
+ return False
566
+
399
567
  @staticmethod
400
568
  def Magnitude(vector, mantissa: int = 6):
401
569
  """
@@ -606,6 +774,75 @@ class Vector(list):
606
774
 
607
775
  return sum_dimensions
608
776
 
777
+ @staticmethod
778
+ def TransformationMatrix(vectorA, vectorB):
779
+ """
780
+ Returns the transformation matrix needed to align vectorA with vectorB.
781
+
782
+ Parameters
783
+ ----------
784
+ vectorA : list
785
+ The input vector to be transformed.
786
+ vectorB : list
787
+ The desired vector with which to align vectorA.
788
+
789
+ Returns
790
+ -------
791
+ list
792
+ Transformation matrix that follows the Blender software convention (nested list)
793
+ """
794
+ import numpy as np
795
+ from topologicpy.Matrix import Matrix
796
+
797
+ import numpy as np
798
+
799
+ def transformation_matrix(vec1, vec2, translation_vector=None):
800
+ """
801
+ Compute a 4x4 transformation matrix that aligns vec1 to vec2.
802
+
803
+ :param vec1: A 3D "source" vector
804
+ :param vec2: A 3D "destination" vector
805
+ :param translation_vector: Optional translation vector (default is None)
806
+ :return: The 4x4 transformation matrix
807
+ """
808
+ vec1 = vec1 / np.linalg.norm(vec1)
809
+ vec2 = vec2 / np.linalg.norm(vec2)
810
+ dot_product = np.dot(vec1, vec2)
811
+
812
+ if np.isclose(dot_product, 1.0):
813
+ # Vectors are parallel; return the identity matrix
814
+ return np.eye(4)
815
+ elif np.isclose(dot_product, -1.0):
816
+ # Vectors are antiparallel; reflect one of the vectors about the origin
817
+ reflection_matrix = np.eye(4)
818
+ reflection_matrix[2, 2] = -1
819
+ return reflection_matrix
820
+
821
+ cross_product = np.cross(vec1, vec2)
822
+
823
+ skew_symmetric_matrix = np.array([[0, -cross_product[2], cross_product[1], 0],
824
+ [cross_product[2], 0, -cross_product[0], 0],
825
+ [-cross_product[1], cross_product[0], 0, 0],
826
+ [0, 0, 0, 1]])
827
+
828
+ rotation_matrix = np.eye(4) + skew_symmetric_matrix + \
829
+ np.dot(skew_symmetric_matrix, skew_symmetric_matrix) * \
830
+ (1 / (1 + dot_product))
831
+
832
+ if translation_vector is not None:
833
+ translation_matrix = np.eye(4)
834
+ translation_matrix[:3, 3] = translation_vector
835
+ transformation_matrix = np.dot(translation_matrix, rotation_matrix)
836
+ else:
837
+ transformation_matrix = rotation_matrix
838
+
839
+ return transformation_matrix
840
+
841
+
842
+ tran_mat = transformation_matrix(vectorA, vectorB)
843
+
844
+ return [list(tran_mat[0]), list(tran_mat[1]), list(tran_mat[2]), list(tran_mat[3])]
845
+
609
846
  @staticmethod
610
847
  def Up():
611
848
  """
topologicpy/Vertex.py CHANGED
@@ -78,7 +78,7 @@ class Vertex(Topology):
78
78
  return None
79
79
  if len(vertexList) < 3:
80
80
  return True # Any two vertices can form a line!
81
- cluster = Topology.SelfMerge(Cluster.ByTopologies(vertexList))
81
+ cluster = Topology.SelfMerge(Cluster.ByTopologies(vertexList), tolerance=tolerance)
82
82
  vertexList = Topology.Vertices(cluster)
83
83
  slices = []
84
84
  for i in range(2,len(vertexList)):
@@ -537,7 +537,7 @@ class Vertex(Topology):
537
537
 
538
538
  def distance_to_face(vertex, face, includeCentroid):
539
539
  v_proj = Vertex.Project(vertex, face, mantissa=mantissa)
540
- if not Face.IsInternal(face, v_proj):
540
+ if not Vertex.IsInternal(v_proj, face):
541
541
  vertices = Topology.Vertices(topology)
542
542
  distances = [distance_to_vertex(vertex, v) for v in vertices]
543
543
  edges = Topology.Edges(topology)
@@ -867,15 +867,70 @@ class Vertex(Topology):
867
867
  return vertex
868
868
 
869
869
  @staticmethod
870
- def IsInside(vertex: topologic.Vertex, topology: topologic.Topology, tolerance: float = 0.0001) -> bool:
870
+ def IsCoincident(vertexA: topologic.Vertex, vertexB: topologic.Vertex, tolerance: float = 0.0001, silent: bool = False) -> bool:
871
871
  """
872
- DEPRECATED. DO NOT USE. INSTEAD USE Vertex.IsInternal.
872
+ Returns True if the input vertexA is coincident with the input vertexB. Returns False otherwise.
873
+
874
+ Parameters
875
+ ----------
876
+ vertexA : topologic.Vertex
877
+ The first input vertex.
878
+ vertexB : topologic.Vertex
879
+ The second input vertex.
880
+ tolerance : float , optional
881
+ The tolerance for computing if the input vertexA is coincident with the input vertexB. The default is 0.0001.
882
+
883
+ Returns
884
+ -------
885
+ bool
886
+ True if the input vertexA is coincident with the input vertexB. False otherwise.
887
+
873
888
  """
874
- print("Vertex.IsInside - Warning: Deprecated method. This method will be removed in the future. Instead, use Vertex.IsInternal.")
875
- return Vertex.IsInternal(vertex=vertex, topology=topology, tolerance=tolerance)
889
+ if not isinstance(vertexA, topologic.Vertex):
890
+ if not silent:
891
+ print("Vertex.IsCoincident - Error: The input vertexA parameter is not a valid vertex. Returning None.")
892
+ return None
893
+ if not isinstance(vertexB, topologic.Vertex):
894
+ if not silent:
895
+ print("Vertex.IsICoincident - Error: The input vertexB parameter is not a valid vertex. Returning None.")
896
+ return None
897
+ return Vertex.IsInternal(vertexA, vertexB, tolerance=tolerance, silent=silent)
876
898
 
877
899
  @staticmethod
878
- def IsInternal(vertex: topologic.Vertex, topology: topologic.Topology, tolerance: float = 0.0001) -> bool:
900
+ def IsExternal(vertex: topologic.Vertex, topology: topologic.Topology, tolerance: float = 0.0001, silent: bool = False) -> bool:
901
+ """
902
+ Returns True if the input vertex is external to the input topology. Returns False otherwise.
903
+
904
+ Parameters
905
+ ----------
906
+ vertex : topologic.Vertex
907
+ The input vertex.
908
+ topology : topologic.Topology
909
+ The input topology.
910
+ tolerance : float , optional
911
+ The tolerance for computing if the input vertex is external to the input topology. The default is 0.0001.
912
+ silent : bool , optional
913
+ If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
914
+
915
+ Returns
916
+ -------
917
+ bool
918
+ True if the input vertex is external to the input topology. False otherwise.
919
+
920
+ """
921
+
922
+ if not isinstance(vertex, topologic.Vertex):
923
+ if not silent:
924
+ print("Vertex.IsExternal - Error: The input vertex parameter is not a valid vertex. Returning None.")
925
+ return None
926
+ if not isinstance(topology, topologic.Topology):
927
+ if not silent:
928
+ print("Vertex.IsExternal - Error: The input topology parameter is not a valid topology. Returning None.")
929
+ return None
930
+ return not (Vertex.IsPeripheral(vertex, topology, tolerance=tolerance, silent=silent) or Vertex.IsInternal(vertex, topology, tolerance=tolerance, silent=silent))
931
+
932
+ @staticmethod
933
+ def IsInternal(vertex: topologic.Vertex, topology: topologic.Topology, tolerance: float = 0.0001, silent: bool = False) -> bool:
879
934
  """
880
935
  Returns True if the input vertex is inside the input topology. Returns False otherwise.
881
936
 
@@ -886,14 +941,17 @@ class Vertex(Topology):
886
941
  topology : topologic.Topology
887
942
  The input topology.
888
943
  tolerance : float , optional
889
- The tolerance for computing if the input vertex is enclosed in a cell. The default is 0.0001.
944
+ The tolerance for computing if the input vertex is internal to the input topology. The default is 0.0001.
945
+ silent : bool , optional
946
+ If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
890
947
 
891
948
  Returns
892
949
  -------
893
950
  bool
894
- True if the input vertex is inside the input topology. False otherwise.
951
+ True if the input vertex is internal to the input topology. False otherwise.
895
952
 
896
953
  """
954
+ from topologicpy.Edge import Edge
897
955
  from topologicpy.Wire import Wire
898
956
  from topologicpy.Face import Face
899
957
  from topologicpy.Shell import Shell
@@ -901,8 +959,12 @@ class Vertex(Topology):
901
959
  from topologicpy.Cluster import Cluster
902
960
  from topologicpy.Topology import Topology
903
961
  if not isinstance(vertex, topologic.Vertex):
962
+ if not silent:
963
+ print("Vertex.IsInternal - Error: The input vertex parameter is not a valid vertex. Returning None.")
904
964
  return None
905
965
  if not isinstance(topology, topologic.Topology):
966
+ if not silent:
967
+ print("Vertex.IsInternal - Error: The input topology parameter is not a valid topology. Returning None.")
906
968
  return None
907
969
 
908
970
  if isinstance(topology, topologic.Vertex):
@@ -914,39 +976,163 @@ class Vertex(Topology):
914
976
  parameter = 400 #aribtrary large number greater than 1
915
977
  return 0 <= parameter <= 1
916
978
  elif isinstance(topology, topologic.Wire):
979
+ vertices = [v for v in Topology.Vertices(topology) if Vertex.Degree(v, topology) > 1]
917
980
  edges = Wire.Edges(topology)
918
- for edge in edges:
919
- if Vertex.IsInternal(vertex, edge, tolerance):
981
+ sub_list = vertices + edges
982
+ for sub in sub_list:
983
+ if Vertex.IsInternal(vertex, sub, tolerance=tolerance, silent=silent):
920
984
  return True
921
985
  return False
922
986
  elif isinstance(topology, topologic.Face):
923
- return Face.IsInternal(topology, vertex, tolerance)
987
+ # Test the distance first
988
+ if Vertex.PerpendicularDistance(vertex, topology) > tolerance:
989
+ return False
990
+ if Vertex.IsPeripheral(vertex, topology):
991
+ return False
992
+ normal = Face.Normal(topology)
993
+ proj_v = Vertex.Project(vertex, topology)
994
+ v1 = Topology.TranslateByDirectionDistance(proj_v, normal, 1)
995
+ v2 = Topology.TranslateByDirectionDistance(proj_v, normal, -1)
996
+ edge = Edge.ByVertices(v1, v2)
997
+ intersect = edge.Intersect(topology)
998
+ if intersect == None:
999
+ return False
1000
+ return True
924
1001
  elif isinstance(topology, topologic.Shell):
925
- faces = Shell.Faces(topology)
926
- for face in faces:
927
- if Vertex.IsInternal(vertex, face, tolerance):
1002
+ if Vertex.IsPeripheral(vertex, topology, tolerance=tolerance, silent=silent):
1003
+ return False
1004
+ else:
1005
+ edges = Topology.Edges(topology)
1006
+ for edge in edges:
1007
+ if Vertex.IsInternal(vertex, edge, tolerance=tolerance, silent=silent):
1008
+ return True
1009
+ faces = Topology.Faces(topology)
1010
+ for face in faces:
1011
+ if Vertex.IsInternal(vertex, face, tolerance=tolerance, silent=silent):
1012
+ return True
1013
+ return False
1014
+ elif isinstance(topology, topologic.Cell):
1015
+ return topologic.CellUtility.Contains(topology, vertex, tolerance) == 0
1016
+ elif isinstance(topology, topologic.CellComplex):
1017
+ ext_boundary = CellComplex.ExternalBoundary(topology)
1018
+ return Vertex.IsInternal(vertex, ext_boundary, tolerance=tolerance, silent=silent)
1019
+ elif isinstance(topology, topologic.Cluster):
1020
+ sub_list = Cluster.FreeTopologies(topology)
1021
+ for sub in sub_list:
1022
+ if Vertex.IsInternal(vertex, sub, tolerance=tolerance, silent=silent):
1023
+ return True
1024
+ return False
1025
+ return False
1026
+
1027
+
1028
+ @staticmethod
1029
+ def IsPeripheral(vertex: topologic.Vertex, topology: topologic.Topology, tolerance: float = 0.0001, silent: bool = False) -> bool:
1030
+ """
1031
+ Returns True if the input vertex is peripheral to the input topology. Returns False otherwise.
1032
+ A vertex is said to be peripheral to the input topology if:
1033
+ 01. Vertex: If it is internal to it (i.e. coincident with it).
1034
+ 02. Edge: If it is internal to its start or end vertices.
1035
+ 03. Manifold open wire: If it is internal to its start or end vertices.
1036
+ 04. Manifold closed wire: If it is internal to any of its vertices.
1037
+ 05. Non-manifold wire: If it is internal to any of its vertices that has a vertex degree of 1.
1038
+ 06. Face: If it is internal to any of its edges or vertices.
1039
+ 07. Shell: If it is internal to external boundary
1040
+ 08. Cell: If it is internal to any of its faces, edges, or vertices.
1041
+ 09. CellComplex: If it is peripheral to its external boundary.
1042
+ 10. Cluster: If it is peripheral to any of its free topologies. (See Cluster.FreeTopologies)
1043
+
1044
+ Parameters
1045
+ ----------
1046
+ vertex : topologic.Vertex
1047
+ The input vertex.
1048
+ topology : topologic.Topology
1049
+ The input topology.
1050
+ tolerance : float , optional
1051
+ The tolerance for computing if the input vertex is peripheral to the input topology. The default is 0.0001.
1052
+ silent : bool , optional
1053
+ If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
1054
+
1055
+ Returns
1056
+ -------
1057
+ bool
1058
+ True if the input vertex is peripheral to the input topology. False otherwise.
1059
+
1060
+ """
1061
+ from topologicpy.Edge import Edge
1062
+ from topologicpy.Wire import Wire
1063
+ from topologicpy.Face import Face
1064
+ from topologicpy.Shell import Shell
1065
+ from topologicpy.CellComplex import CellComplex
1066
+ from topologicpy.Cluster import Cluster
1067
+ from topologicpy.Topology import Topology
1068
+
1069
+ if not isinstance(vertex, topologic.Vertex):
1070
+ if not silent:
1071
+ print("Vertex.IsPeripheral - Error: The input vertex parameter is not a valid vertex. Returning None.")
1072
+ return None
1073
+ if not isinstance(topology, topologic.Topology):
1074
+ if not silent:
1075
+ print("Vertex.IsPeripheral - Error: The input topology parameter is not a valid topology. Returning None.")
1076
+ return None
1077
+
1078
+ if isinstance(topology, topologic.Vertex):
1079
+ return Vertex.IsInternal(vertex, topology, tolerance=tolerance, silent=silent)
1080
+ elif isinstance(topology, topologic.Edge):
1081
+ sv = Edge.StartVertex(topology)
1082
+ ev = Edge.EndVertex(topology)
1083
+ f1 = Vertex.IsInternal(vertex, sv, tolerance=tolerance, silent=silent)
1084
+ f2 = Vertex.IsInternal(vertex, ev, tolerance=tolerance, silent=silent)
1085
+ return f1 or f2
1086
+ elif isinstance(topology, topologic.Wire):
1087
+ if Wire.IsManifold(topology):
1088
+ if not Wire.IsClosed(topology):
1089
+ sv = Wire.StartVertex(topology)
1090
+ ev = Wire.EndVertex(topology)
1091
+ f1 = Vertex.IsInternal(vertex, sv, tolerance=tolerance, silent=silent)
1092
+ f2 = Vertex.IsInternal(vertex, ev, tolerance=tolerance, silent=silent)
1093
+ return f1 or f2
1094
+ else:
1095
+ sub_list = [v for v in Topology.Vertices(topology)]
1096
+ for sub in sub_list:
1097
+ if Vertex.IsPeripheral(vertex, sub, tolerance=tolerance, silent=silent):
1098
+ return True
1099
+ return False
1100
+ else:
1101
+ sub_list = [v for v in Topology.Vertices(topology) if Vertex.Degree(v, topology) == 1]
1102
+ for sub in sub_list:
1103
+ if Vertex.IsPeripheral(vertex, sub, tolerance=tolerance, silent=silent):
1104
+ return True
1105
+ return False
1106
+ elif isinstance(topology, topologic.Face):
1107
+ sub_list = Topology.Vertices(topology) + Topology.Edges(topology)
1108
+ for sub in sub_list:
1109
+ if Vertex.IsInternal(vertex, sub, tolerance=tolerance, silent=silent):
1110
+ return True
1111
+ return False
1112
+ elif isinstance(topology, topologic.Shell):
1113
+ ext_boundary = Shell.ExternalBoundary(topology)
1114
+ sub_list = Topology.Vertices(ext_boundary) + Topology.Edges(ext_boundary)
1115
+ for sub in sub_list:
1116
+ if Vertex.IsInternal(vertex, sub, tolerance=tolerance, silent=silent):
928
1117
  return True
929
1118
  return False
930
1119
  elif isinstance(topology, topologic.Cell):
931
- return topologic.CellUtility.Contains(topology, vertex, tolerance) == 0
1120
+ sub_list = Topology.Vertices(topology) + Topology.Edges(topology) + Topology.Faces(topology)
1121
+ for sub in sub_list:
1122
+ if Vertex.IsInternal(vertex, sub, tolerance=tolerance, silent=silent):
1123
+ return True
1124
+ return False
932
1125
  elif isinstance(topology, topologic.CellComplex):
933
- cells = CellComplex.Cells(topology)
934
- faces = CellComplex.Faces(topology)
935
- edges = CellComplex.Edges(topology)
936
- vertices = CellComplex.Vertices(topology)
937
- subtopologies = cells + faces + edges + vertices
938
- for subtopology in subtopologies:
939
- if Vertex.IsInternal(vertex, subtopology, tolerance):
1126
+ ext_boundary = CellComplex.ExternalBoundary(topology)
1127
+ sub_list = Topology.Vertices(ext_boundary) + Topology.Edges(ext_boundary) + Topology.Faces(ext_boundary)
1128
+ for sub in sub_list:
1129
+ if Vertex.IsInternal(vertex, sub, tolerance=tolerance, silent=silent):
940
1130
  return True
941
1131
  return False
942
1132
  elif isinstance(topology, topologic.Cluster):
943
- cells = Cluster.Cells(topology)
944
- faces = Cluster.Faces(topology)
945
- edges = Cluster.Edges(topology)
946
- vertices = Cluster.Vertices(topology)
947
- subtopologies = cells + faces + edges + vertices
948
- for subtopology in subtopologies:
949
- if Vertex.IsInternal(vertex, subtopology, tolerance):
1133
+ sub_list = Cluster.FreeTopologies(topology)
1134
+ for sub in sub_list:
1135
+ if Vertex.IsPeripheral(vertex, sub, tolerance=tolerance, silent=silent):
950
1136
  return True
951
1137
  return False
952
1138
  return False