topologicpy 0.7.87__py3-none-any.whl → 0.7.90__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/Cell.py CHANGED
@@ -1471,7 +1471,7 @@ class Cell():
1471
1471
  return shells
1472
1472
 
1473
1473
  @staticmethod
1474
- def InternalVertex(cell, tolerance: float = 0.0001):
1474
+ def InternalVertex(cell, tolerance: float = 0.0001, silent: bool = False):
1475
1475
  """
1476
1476
  Creates a vertex that is guaranteed to be inside the input cell.
1477
1477
 
@@ -1481,6 +1481,8 @@ class Cell():
1481
1481
  The input cell.
1482
1482
  tolerance : float , optional
1483
1483
  The desired tolerance. The default is 0.0001.
1484
+ silent : bool , optional
1485
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
1484
1486
 
1485
1487
  Returns
1486
1488
  -------
@@ -1491,12 +1493,14 @@ class Cell():
1491
1493
  from topologicpy.Topology import Topology
1492
1494
 
1493
1495
  if not Topology.IsInstance(cell, "Cell"):
1494
- print("Cell.InternalVertex - Error: The input cell parameter is not a valid topologic cell. Returning None.")
1496
+ if not silent:
1497
+ print("Cell.InternalVertex - Error: The input cell parameter is not a valid topologic cell. Returning None.")
1495
1498
  return None
1496
1499
  try:
1497
1500
  return topologic.CellUtility.InternalVertex(cell, tolerance) # Hook to Core
1498
1501
  except:
1499
- print("Cell.InternalVertex - Error: Could not create an internal vertex. Returning None.")
1502
+ if not silent:
1503
+ print("Cell.InternalVertex - Error: Could not create an internal vertex. Returning None.")
1500
1504
  return None
1501
1505
 
1502
1506
  @staticmethod
topologicpy/Face.py CHANGED
@@ -1518,7 +1518,7 @@ class Face():
1518
1518
  return list(wires)
1519
1519
 
1520
1520
  @staticmethod
1521
- def InternalVertex(face, tolerance: float = 0.0001):
1521
+ def InternalVertex(face, tolerance: float = 0.0001, silent: bool = False):
1522
1522
  """
1523
1523
  Creates a vertex guaranteed to be inside the input face.
1524
1524
 
@@ -1528,6 +1528,8 @@ class Face():
1528
1528
  The input face.
1529
1529
  tolerance : float , optional
1530
1530
  The desired tolerance. The default is 0.0001.
1531
+ silent : bool , optional
1532
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
1531
1533
 
1532
1534
  Returns
1533
1535
  -------
@@ -1535,22 +1537,53 @@ class Face():
1535
1537
  The created vertex.
1536
1538
 
1537
1539
  """
1540
+ def get_uv_radially():
1541
+ """
1542
+ Generate the points of a grid with a given size n, sorted radially from the center to the periphery.
1543
+ n should be an odd number, ensuring that there's a center point (0, 0).
1544
+
1545
+ Args:
1546
+ n (int): The size of the grid. It should be odd for a clear center point.
1547
+
1548
+ Returns:
1549
+ list: A list of tuples (x, y) sorted by radial distance from the center (0, 0).
1550
+ """
1551
+ import math
1552
+
1553
+ points = []
1554
+ n = 100
1555
+ # Iterate over the grid, ranging from -n//2 to n//2
1556
+ for x in range(-n//2, n//2 + 1):
1557
+ for y in range(-n//2, n//2 + 1):
1558
+ points.append((x, y))
1559
+
1560
+ # Sort points by their Euclidean distance from the center (0, 0)
1561
+ points.sort(key=lambda point: math.sqrt(point[0]**2 + point[1]**2))
1562
+ return_points = []
1563
+ for p in points:
1564
+ new_p = ((p[0]+50)*0.01, (p[1]+50)*0.01)
1565
+ return_points.append(new_p)
1566
+ return return_points
1567
+
1538
1568
  from topologicpy.Vertex import Vertex
1539
1569
  from topologicpy.Topology import Topology
1540
1570
 
1541
1571
  if not Topology.IsInstance(face, "Face"):
1542
1572
  return None
1543
- v = Topology.Centroid(face)
1544
- if Vertex.IsInternal(v, face, tolerance=tolerance):
1545
- return v
1546
- l = [0.4,0.6,0.3,0.7,0.2,0.8,0.1,0.9]
1547
- for u in l:
1548
- for v in l:
1549
- v = Face.VertexByParameters(face, u, v)
1550
- if Vertex.IsInternal(v, face, tolerance=tolerance):
1551
- return v
1552
- v = topologic.FaceUtility.InternalVertex(face, tolerance) # Hook to Core
1553
- return v
1573
+ vert = Topology.Centroid(face)
1574
+ if Vertex.IsInternal(vert, face, tolerance=tolerance):
1575
+ return vert
1576
+ uv_list = get_uv_radially()
1577
+ for uv in uv_list:
1578
+ u, v = uv
1579
+ vert = Face.VertexByParameters(face, u, v)
1580
+ if Vertex.IsInternal(vert, face, tolerance=tolerance):
1581
+ return vert
1582
+ if not silent:
1583
+ print("Face.InternalVertex - Warning: Could not find an internal vertex. Returning the first vertex of the face.")
1584
+ vert = Topology.Vertices(face)[0]
1585
+ #v = topologic.FaceUtility.InternalVertex(face, tolerance) # Hook to Core
1586
+ return vert
1554
1587
 
1555
1588
  @staticmethod
1556
1589
  def Invert(face, tolerance: float = 0.0001):
@@ -2365,6 +2398,8 @@ class Face():
2365
2398
  The desired length of the normal edge. The default is 1.
2366
2399
  tolerance : float , optional
2367
2400
  The desired tolerance. The default is 0.0001.
2401
+ silent : bool , optional
2402
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
2368
2403
 
2369
2404
  Returns
2370
2405
  -------
topologicpy/Graph.py CHANGED
@@ -2160,9 +2160,14 @@ class Graph:
2160
2160
  return {'graphs':graphs, 'labels':labels}
2161
2161
 
2162
2162
  @staticmethod
2163
- def ByIFCFile(file, includeTypes: list = [], excludeTypes: list = [],
2164
- includeRels: list = [], excludeRels: list = [],
2165
- transferDictionaries: bool = False, storeBREP: bool = False,
2163
+ def ByIFCFile(file,
2164
+ includeTypes: list = [],
2165
+ excludeTypes: list = [],
2166
+ includeRels: list = [],
2167
+ excludeRels: list = [],
2168
+ transferDictionaries: bool = False,
2169
+ useInternalVertex: bool = False,
2170
+ storeBREP: bool = False,
2166
2171
  removeCoplanarFaces: bool = False,
2167
2172
  xMin: float = -0.5, yMin: float = -0.5, zMin: float = -0.5,
2168
2173
  xMax: float = 0.5, yMax: float = 0.5, zMax: float = 0.5,
@@ -2184,6 +2189,8 @@ class Graph:
2184
2189
  A list of IFC relationship types to exclude from the graph. The default is [] which mean no relationship type is excluded.
2185
2190
  transferDictionaries : bool , optional
2186
2191
  If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
2192
+ useInternalVertex : bool , optional
2193
+ If set to True, use an internal vertex to represent the subtopology. Otherwise, use its centroid. The default is False.
2187
2194
  storeBREP : bool , optional
2188
2195
  If set to True, store the BRep of the subtopology in its representative vertex. The default is False.
2189
2196
  removeCoplanarFaces : bool , optional
@@ -2466,7 +2473,7 @@ class Graph:
2466
2473
  pset_python_dict = get_psets(ifc_object)
2467
2474
  pset_dict = Dictionary.ByPythonDictionary(pset_python_dict)
2468
2475
  topology_dict = Dictionary.ByMergedDictionaries([topology_dict, pset_dict])
2469
- if storeBREP == True:
2476
+ if storeBREP == True or useInternalVertex == True:
2470
2477
  shape_topology = None
2471
2478
  if hasattr(ifc_object, "Representation") and ifc_object.Representation:
2472
2479
  for rep in ifc_object.Representation.Representations:
@@ -2484,8 +2491,10 @@ class Graph:
2484
2491
  if not shape_topology == None:
2485
2492
  if removeCoplanarFaces == True:
2486
2493
  shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
2487
- if not shape_topology == None:
2494
+ if not shape_topology == None and storeBREP:
2488
2495
  topology_dict = Dictionary.SetValuesAtKeys(topology_dict, ["brep", "brepType", "brepTypeString"], [Topology.BREPString(shape_topology), Topology.Type(shape_topology), Topology.TypeAsString(shape_topology)])
2496
+ if not shape_topology == None and useInternalVertex == True:
2497
+ centroid = Topology.InternalVertex(shape_topology)
2489
2498
  centroid = Topology.SetDictionary(centroid, topology_dict)
2490
2499
  return centroid
2491
2500
  return None
@@ -2571,7 +2580,16 @@ class Graph:
2571
2580
  return g
2572
2581
 
2573
2582
  @staticmethod
2574
- def ByIFCPath(path, includeTypes=[], excludeTypes=[], includeRels=[], excludeRels=[], transferDictionaries=False, storeBREP=False, removeCoplanarFaces=False, xMin=-0.5, yMin=-0.5, zMin=-0.5, xMax=0.5, yMax=0.5, zMax=0.5):
2583
+ def ByIFCPath(path,
2584
+ includeTypes=[],
2585
+ excludeTypes=[],
2586
+ includeRels=[],
2587
+ excludeRels=[],
2588
+ transferDictionaries=False,
2589
+ useInternalVertex=False,
2590
+ storeBREP=False,
2591
+ removeCoplanarFaces=False,
2592
+ xMin=-0.5, yMin=-0.5, zMin=-0.5, xMax=0.5, yMax=0.5, zMax=0.5):
2575
2593
  """
2576
2594
  Create a Graph from an IFC path. This code is partially based on code from Bruno Postle.
2577
2595
 
@@ -2589,6 +2607,8 @@ class Graph:
2589
2607
  A list of IFC relationship types to exclude from the graph. The default is [] which mean no relationship type is excluded.
2590
2608
  transferDictionaries : bool , optional
2591
2609
  If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
2610
+ useInternalVertex : bool , optional
2611
+ If set to True, use an internal vertex to represent the subtopology. Otherwise, use its centroid. The default is False.
2592
2612
  storeBREP : bool , optional
2593
2613
  If set to True, store the BRep of the subtopology in its representative vertex. The default is False.
2594
2614
  removeCoplanarFaces : bool , optional
@@ -2647,6 +2667,7 @@ class Graph:
2647
2667
  includeRels=includeRels,
2648
2668
  excludeRels=excludeRels,
2649
2669
  transferDictionaries=transferDictionaries,
2670
+ useInternalVertex=useInternalVertex,
2650
2671
  storeBREP=storeBREP,
2651
2672
  removeCoplanarFaces=removeCoplanarFaces,
2652
2673
  xMin=xMin, yMin=yMin, zMin=zMin, xMax=xMax, yMax=yMax, zMax=zMax)
@@ -4081,6 +4102,79 @@ class Graph:
4081
4102
  v = Topology.SetDictionary(v, d)
4082
4103
  return graph
4083
4104
 
4105
+ @staticmethod
4106
+ def ConnectedComponents(graph, tolerance: float = 0.0001, silent: bool = False):
4107
+ """
4108
+ Returns the connected components (islands) of the input graph.
4109
+
4110
+ Parameters
4111
+ ----------
4112
+ graph : topologic_core.Graph
4113
+ The input graph.
4114
+ tolerance : float , optional
4115
+ The desired tolerance. The default is 0.0001.
4116
+ silent : bool , optional
4117
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
4118
+
4119
+ Returns
4120
+ -------
4121
+ list
4122
+ The list of connected components (island graphs).
4123
+ The list is sorted by the number of vertices in each component (from highest to lowest).
4124
+
4125
+ """
4126
+ def find_connected_components(adjacency_dict):
4127
+ visited = set()
4128
+ components = []
4129
+
4130
+ for vertex_id in adjacency_dict:
4131
+ if vertex_id not in visited:
4132
+ # Perform DFS using a stack
4133
+ stack = [vertex_id]
4134
+ current_island = set()
4135
+
4136
+ while stack:
4137
+ current = stack.pop()
4138
+ if current not in visited:
4139
+ visited.add(current)
4140
+ current_island.add(current)
4141
+ stack.extend(set(adjacency_dict[current]) - visited)
4142
+
4143
+ components.append(current_island)
4144
+
4145
+ return components
4146
+
4147
+ from topologicpy.Topology import Topology
4148
+ from topologicpy.Dictionary import Dictionary
4149
+ from topologicpy.Helper import Helper
4150
+
4151
+ if not Topology.IsInstance(graph, "Graph"):
4152
+ if not silent:
4153
+ print("Graph.ConnectedComponents - Error: The input graph is not a valid graph. Returning None.")
4154
+ return None
4155
+
4156
+ labelKey = "__label__"
4157
+ lengths = [] #List of lengths to sort the list of components by number of their vertices
4158
+ vertices = Graph.Vertices(graph)
4159
+ g_dict = Graph.AdjacencyDictionary(graph, vertexLabelKey=labelKey)
4160
+ components = find_connected_components(g_dict)
4161
+ return_components = []
4162
+ for component in components:
4163
+ i_verts = []
4164
+ for v in component:
4165
+ vert = Topology.Filter(vertices, searchType="equal to", key=labelKey, value=v)['filtered'][0]
4166
+ d = Topology.Dictionary(vert)
4167
+ d = Dictionary.RemoveKey(d, labelKey)
4168
+ vert = Topology.SetDictionary(vert, d)
4169
+ i_verts.append(vert)
4170
+ i_edges = Graph.Edges(graph, i_verts)
4171
+ lengths.append(len(i_verts))
4172
+ g_component = Graph.ByVerticesEdges(i_verts, i_edges)
4173
+ return_components.append(g_component)
4174
+ return_components = Helper.Sort(return_components, lengths)
4175
+ return_components.reverse()
4176
+ return return_components
4177
+
4084
4178
  @staticmethod
4085
4179
  def ContractEdge(graph, edge, vertex=None, tolerance=0.0001):
4086
4180
  """
@@ -4184,7 +4278,7 @@ class Graph:
4184
4278
  return graph
4185
4279
 
4186
4280
  @staticmethod
4187
- def ClosenessCentrality(graph, vertices=None, key: str = "closeness_centrality", mantissa: int = 6, tolerance = 0.0001):
4281
+ def ClosenessCentrality(graph, vertices=None, key: str = "closeness_centrality", mantissa: int = 6, tolerance = 0.0001, silent = False):
4188
4282
  """
4189
4283
  Return the closeness centrality measure of the input list of vertices within the input graph. The order of the returned list is the same as the order of the input list of vertices. If no vertices are specified, the closeness centrality of all the vertices in the input graph is computed. See https://en.wikipedia.org/wiki/Closeness_centrality.
4190
4284
 
@@ -4200,6 +4294,8 @@ class Graph:
4200
4294
  The desired length of the mantissa. The default is 6.
4201
4295
  tolerance : float , optional
4202
4296
  The desired tolerance. The default is 0.0001.
4297
+ silent : bool , optional
4298
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
4203
4299
 
4204
4300
  Returns
4205
4301
  -------
@@ -4207,56 +4303,68 @@ class Graph:
4207
4303
  The closeness centrality of the input list of vertices within the input graph. The values are in the range 0 to 1.
4208
4304
 
4209
4305
  """
4306
+
4307
+ def closeness_centrality(g):
4308
+ """
4309
+ Computes the closeness centrality for each vertex in the graph.
4310
+
4311
+ Parameters:
4312
+ graph (dict): A dictionary representing the graph where keys are vertices and
4313
+ values are lists of neighboring vertices.
4314
+
4315
+ Returns:
4316
+ dict: A dictionary where keys are vertices and values are their closeness centrality.
4317
+ """
4318
+ keys = list(g.keys())
4319
+ N = len(keys)
4320
+
4321
+ centralities = []
4322
+ for v in keys:
4323
+ total_distance = 0
4324
+ reachable_count = 0
4325
+
4326
+ for u in keys:
4327
+ if v != u:
4328
+ distance = Graph._topological_distance(g, v, u)
4329
+ if distance != None:
4330
+ total_distance += distance
4331
+ reachable_count += 1
4332
+
4333
+ if reachable_count > 0: # Avoid division by zero
4334
+ centrality = (reachable_count / total_distance)
4335
+ else:
4336
+ centrality = 0.0 # Isolated vertex
4337
+
4338
+ centralities.append(centrality)
4339
+ return centralities
4340
+
4341
+ from topologicpy.Vertex import Vertex
4210
4342
  from topologicpy.Topology import Topology
4211
4343
  from topologicpy.Dictionary import Dictionary
4344
+ from topologicpy.Helper import Helper
4212
4345
 
4213
4346
  if not Topology.IsInstance(graph, "Graph"):
4214
- print("Graph.ClosenessCentrality - Error: The input graph is not a valid graph. Returning None.")
4347
+ if not silent:
4348
+ print("Graph.ClosenessCentrality - Error: The input graph is not a valid graph. Returning None.")
4215
4349
  return None
4350
+ g = Graph.AdjacencyDictionary(graph)
4351
+ centralities = closeness_centrality(g)
4216
4352
  graphVertices = Graph.Vertices(graph)
4217
- if not isinstance(vertices, list):
4218
- vertices = graphVertices
4353
+ if vertices == None:
4354
+ for i, v in enumerate(graphVertices):
4355
+ d = Topology.Dictionary(v)
4356
+ d = Dictionary.SetValueAtKey(d, key, centralities[i])
4357
+ v = Topology.SetDictionary(v, d)
4358
+ return centralities
4219
4359
  else:
4220
- vertices = [v for v in vertices if Topology.IsInstance(v, "Vertex")]
4221
- if len(vertices) < 1:
4222
- print("Graph.ClosenessCentrality - Error: The input list of vertices does not contain any valid vertices. Returning None.")
4223
- return None
4224
- n = len(graphVertices)
4225
-
4226
- scores = []
4227
- try:
4228
- for va in tqdm(vertices, desc="Computing Closeness Centrality", leave=False):
4229
- top_dist = 0
4230
- for vb in graphVertices:
4231
- if Topology.IsSame(va, vb):
4232
- d = 0
4233
- else:
4234
- d = Graph.TopologicalDistance(graph, va, vb, tolerance=tolerance)
4235
- top_dist += d
4236
- if top_dist == 0:
4237
- print("Graph.ClosenessCentrality - Warning: Topological Distance is Zero.")
4238
- scores.append(0)
4239
- else:
4240
- scores.append(round((n-1)/top_dist, mantissa))
4241
- except:
4242
- print("Graph.ClosenessCentrality - Warning: Could not use tqdm.")
4243
- for va in vertices:
4244
- top_dist = 0
4245
- for vb in graphVertices:
4246
- if Topology.IsSame(va, vb):
4247
- d = 0
4248
- else:
4249
- d = Graph.TopologicalDistance(graph, va, vb, tolerance=tolerance)
4250
- top_dist += d
4251
- if top_dist == 0:
4252
- scores.append(0)
4253
- else:
4254
- scores.append(round((n-1)/top_dist, mantissa))
4255
- for i, v in enumerate(vertices):
4256
- d = Topology.Dictionary(v)
4257
- d = Dictionary.SetValueAtKey(d, key, scores[i])
4258
- v = Topology.SetDictionary(v, d)
4259
- return scores
4360
+ return_centralities = []
4361
+ for v in vertices:
4362
+ i = Vertex.Index(v, graphVertices)
4363
+ d = Topology.Dictionary(v)
4364
+ d = Dictionary.SetValueAtKey(d, key, centralities[i])
4365
+ v = Topology.SetDictionary(v, d)
4366
+ return_centralities.append(centralities[i])
4367
+ return centralities
4260
4368
 
4261
4369
  @staticmethod
4262
4370
  def Connect(graph, verticesA, verticesB, tolerance=0.0001):
@@ -8879,6 +8987,28 @@ class Graph:
8879
8987
  return None
8880
8988
  return len(Graph.Edges(graph))
8881
8989
 
8990
+ @staticmethod
8991
+ def _topological_distance(g, start, target):
8992
+ from collections import deque
8993
+ if start == target:
8994
+ return 0
8995
+ visited = set()
8996
+ queue = deque([(start, 0)]) # Each element is a tuple (vertex, distance)
8997
+
8998
+ while queue:
8999
+ current, distance = queue.popleft()
9000
+ if current in visited:
9001
+ continue
9002
+
9003
+ visited.add(current)
9004
+ for neighbor in g.get(current, []):
9005
+ if neighbor == target:
9006
+ return distance + 1
9007
+ if neighbor not in visited:
9008
+ queue.append((neighbor, distance + 1))
9009
+
9010
+ return None # Target not reachable
9011
+
8882
9012
  @staticmethod
8883
9013
  def TopologicalDistance(graph, vertexA, vertexB, tolerance=0.0001):
8884
9014
  """
@@ -8901,6 +9031,8 @@ class Graph:
8901
9031
  The topological distance between the input vertices.
8902
9032
 
8903
9033
  """
9034
+
9035
+ from topologicpy.Vertex import Vertex
8904
9036
  from topologicpy.Topology import Topology
8905
9037
 
8906
9038
  if not Topology.IsInstance(graph, "Graph"):
@@ -8912,7 +9044,19 @@ class Graph:
8912
9044
  if not Topology.IsInstance(vertexB, "Vertex"):
8913
9045
  print("Graph.TopologicalDistance - Error: The input vertexB is not a valid vertex. Returning None.")
8914
9046
  return None
8915
- return graph.TopologicalDistance(vertexA, vertexB, tolerance) # Hook to Core
9047
+
9048
+ g = Graph.AdjacencyDictionary(graph)
9049
+ vertices = Graph.Vertices(graph)
9050
+ keys = list(g.keys())
9051
+ index_a = Vertex.Index(vertexA, vertices, tolerance=tolerance)
9052
+ if index_a == None:
9053
+ return 0
9054
+ start = keys[index_a]
9055
+ index_b = Vertex.Index(vertexB, vertices, tolerance=tolerance)
9056
+ if index_b == None:
9057
+ return 0
9058
+ target = keys[index_b]
9059
+ return Graph._topological_distance(g, start, target)
8916
9060
 
8917
9061
  @staticmethod
8918
9062
  def Topology(graph):
topologicpy/Topology.py CHANGED
@@ -6240,7 +6240,7 @@ class Topology():
6240
6240
  return Topology.Type(topology)
6241
6241
 
6242
6242
  @staticmethod
6243
- def _InternalVertex(topology, tolerance: float = 0.0001):
6243
+ def _InternalVertex(topology, tolerance: float = 0.0001, silent: bool = False):
6244
6244
  """
6245
6245
  Returns a vertex guaranteed to be inside the input topology.
6246
6246
 
@@ -6250,6 +6250,8 @@ class Topology():
6250
6250
  The input topology.
6251
6251
  tolerance : float , ptional
6252
6252
  The desired tolerance. The default is 0.0001.
6253
+ silent : bool , optional
6254
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
6253
6255
 
6254
6256
  Returns
6255
6257
  -------
@@ -6271,20 +6273,20 @@ class Topology():
6271
6273
  top = Topology.Copy(topology)
6272
6274
  if Topology.IsInstance(top, "CellComplex"): #CellComplex
6273
6275
  tempCell = Topology.Cells(top)[0]
6274
- vst = Cell.InternalVertex(tempCell, tolerance=tolerance)
6276
+ vst = Cell.InternalVertex(tempCell, tolerance=tolerance, silent=silent)
6275
6277
  elif Topology.IsInstance(top, "Cell"): #Cell
6276
- vst = Cell.InternalVertex(top, tolerance=tolerance)
6278
+ vst = Cell.InternalVertex(top, tolerance=tolerance, silent=silent)
6277
6279
  elif Topology.IsInstance(top, "Shell"): #Shell
6278
6280
  tempFace = Topology.Faces(top)[0]
6279
- vst = Face.InternalVertex(tempFace, tolerance=tolerance)
6281
+ vst = Face.InternalVertex(tempFace, tolerance=tolerance, silent=silent)
6280
6282
  elif Topology.IsInstance(top, "Face"): #Face
6281
- vst = Face.InternalVertex(top, tolerance=tolerance)
6283
+ vst = Face.InternalVertex(top, tolerance=tolerance, silent=silent)
6282
6284
  elif Topology.IsInstance(top, "Wire"): #Wire
6283
6285
  if top.IsClosed():
6284
6286
  internalBoundaries = []
6285
6287
  try:
6286
6288
  tempFace = topologic.Face.ByExternalInternalBoundaries(top, internalBoundaries)
6287
- vst = Face.InternalVertex(tempFace, tolerance=tolerance)
6289
+ vst = Face.InternalVertex(tempFace, tolerance=tolerance, silent=silent)
6288
6290
  except:
6289
6291
  vst = Topology.Centroid(top)
6290
6292
  else:
@@ -6295,7 +6297,7 @@ class Topology():
6295
6297
  elif Topology.IsInstance(top, "Vertex"): #Vertex
6296
6298
  vst = top
6297
6299
  elif Topology.IsInstance(topology, "Aperture"): #Aperture
6298
- vst = Face.InternalVertex(Aperture.Topology(top), tolerance=tolerance)
6300
+ vst = Face.InternalVertex(Aperture.Topology(top), tolerance=tolerance, silent=silent)
6299
6301
  else:
6300
6302
  vst = Topology.Centroid(top)
6301
6303
  return vst
@@ -6303,7 +6305,7 @@ class Topology():
6303
6305
 
6304
6306
 
6305
6307
  @staticmethod
6306
- def InternalVertex(topology, timeout: int = 10, tolerance: float = 0.0001):
6308
+ def InternalVertex(topology, timeout: int = 30, tolerance: float = 0.0001, silent: bool = False):
6307
6309
  """
6308
6310
  Returns a vertex guaranteed to be inside the input topology.
6309
6311
 
@@ -6312,9 +6314,11 @@ class Topology():
6312
6314
  topology : topologic_core.Topology
6313
6315
  The input topology.
6314
6316
  timeout : int , optional
6315
- The amount of seconds to wait before timing out. The default is 10 seconds.
6317
+ The amount of seconds to wait before timing out. The default is 30 seconds.
6316
6318
  tolerance : float , ptional
6317
6319
  The desired tolerance. The default is 0.0001.
6320
+ silent : bool , optional
6321
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
6318
6322
 
6319
6323
  Returns
6320
6324
  -------
@@ -6325,22 +6329,21 @@ class Topology():
6325
6329
  import concurrent.futures
6326
6330
  import time
6327
6331
  # Wrapper function with timeout
6328
- def run_with_timeout(func, topology, tolerance=0.0001, timeout=10):
6332
+ def run_with_timeout(func, topology, tolerance=0.0001, silent=False, timeout=10):
6329
6333
  with concurrent.futures.ThreadPoolExecutor() as executor:
6330
- future = executor.submit(func, topology, tolerance=tolerance)
6334
+ future = executor.submit(func, topology, tolerance=tolerance, silent=silent)
6331
6335
  try:
6332
6336
  result = future.result(timeout=timeout) # Wait for the result with a timeout
6333
6337
  return result
6334
6338
  except concurrent.futures.TimeoutError:
6335
- print("Function took too long, retrying with a different solution.")
6336
6339
  return None # or try another approach here
6337
6340
 
6338
- result = run_with_timeout(Topology._InternalVertex, topology=topology, tolerance=tolerance, timeout=timeout) # Set a 10 second timeout
6341
+ result = run_with_timeout(Topology._InternalVertex, topology=topology, tolerance=tolerance, silent=silent, timeout=timeout) # Set a 10 second timeout
6339
6342
  if result is None:
6340
6343
  # Handle failure case (e.g., try a different solution)
6341
- print("Using a different approach.")
6342
- result = Topology.Centroid(topology)
6343
- print("Result is:", result)
6344
+ if not silent:
6345
+ print("Topology.InternalVertex - Warning: Operation took too long. Returning None")
6346
+ return None
6344
6347
  return result
6345
6348
 
6346
6349
  @staticmethod
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.87'
1
+ __version__ = '0.7.90'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.87
3
+ Version: 0.7.90
4
4
  Summary: An AI-Powered Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: AGPL v3 License
@@ -1,7 +1,7 @@
1
1
  topologicpy/ANN.py,sha256=m_WxD1lgQqDhUpaM20Lia6TmJACDYaAE96wigsi-99U,47932
2
2
  topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
3
  topologicpy/BVH.py,sha256=mKVCAu9K8qzcWXtPDVH5usXZV1DNNNJl4n3rU5Lh1ZM,12931
4
- topologicpy/Cell.py,sha256=nVJEFgj6nnHDNUYIlMf1NS2xiufDMj18szKGqf9HwDM,108090
4
+ topologicpy/Cell.py,sha256=Fdqf2GCWfKe50EecBVcB8PCHKWENRUTTH8yPrOSF3-0,108321
5
5
  topologicpy/CellComplex.py,sha256=ncjfvJ2QJzz4Fu8BMaQBLxAQ6WHx6HfUCddaLP8kXsc,51480
6
6
  topologicpy/Cluster.py,sha256=__PvNVjRnFfy12aawd7HSrb3UBX3Rtd1iWSSQnPGpfk,55768
7
7
  topologicpy/Color.py,sha256=q9xsGmxFMz7sQKmygwSVS12GaTRB-OT0-_i6t3-cthE,20307
@@ -10,8 +10,8 @@ topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
10
10
  topologicpy/Dictionary.py,sha256=t0O7Du-iPq46FyKqZfcjHfsUK1E8GS_e67R2V5cpkbw,33186
11
11
  topologicpy/Edge.py,sha256=KWOJCkLDwCWyZJ5MKwDhT5umWwCYBHtLOz6ulHrSOfY,67205
12
12
  topologicpy/EnergyModel.py,sha256=AqTtmXE35SxvRXhG3vYAQd7GQDW-6HtjYPHua6ME4Eg,53762
13
- topologicpy/Face.py,sha256=qiQmvCRFHO248VMqPxcE4Jrrw2JvNIJDdWHMopCPWGQ,142173
14
- topologicpy/Graph.py,sha256=YKVo3ePAesJL4pt8GBekzPhujGeTc2XbErnzqEOZITQ,431147
13
+ topologicpy/Face.py,sha256=f4DrZJ2AgwnTwIorJpwuOXtWq501wOMRixMgHZC78so,143843
14
+ topologicpy/Graph.py,sha256=Zxmoy2FAl5m_MGUd62jDeajmZAFlKXVHf1Fy68TrsSw,436694
15
15
  topologicpy/Grid.py,sha256=2s9cSlWldivn1i9EUz4OOokJyANveqmRe_vR93CAndI,18245
16
16
  topologicpy/Helper.py,sha256=F3h4_qcOD_PHAoVe0tEbEE7_jYyVcaHjtwVs4QHOZuI,23978
17
17
  topologicpy/Honeybee.py,sha256=HfTaEV1R8K1xOVQQy9sBOhBTF_ap8A2RxZOYhirp_Mw,21835
@@ -23,14 +23,14 @@ topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
23
23
  topologicpy/Shell.py,sha256=UdDz3zfIYmGRjoZIseviJ2cXNtR5Kx5tIsZLhWMyO_U,87906
24
24
  topologicpy/Speckle.py,sha256=AlsGlSDuKRtX5jhVsPNSSjjbZis079HbUchDH_5RJmE,18187
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
- topologicpy/Topology.py,sha256=E683mKTwx4a1p1l6vN5KWFqX9gVJwV78S12EdtkfQjM,441297
26
+ topologicpy/Topology.py,sha256=d99wryPPXvw7eRw12GVKV-DT6jhlmVq6GsMAjg-E-40,441693
27
27
  topologicpy/Vector.py,sha256=A1g83zDHep58iVPY8WQ8iHNrSOfGWFEzvVeDuMnjDNY,33078
28
28
  topologicpy/Vertex.py,sha256=sYWTbAHqKGRUAJRCIUqrCO_xFhvsXK09Sx7E4dafPLQ,73754
29
29
  topologicpy/Wire.py,sha256=HjagWKoJb8Z3zhgOij_4k6ZnKIl5gk8LletHbsT1ZKU,190632
30
30
  topologicpy/__init__.py,sha256=vlPCanUbxe5NifC4pHcnhSzkmmYcs_UrZrTlVMsxcFs,928
31
- topologicpy/version.py,sha256=9To1hhHw5YQrfDyVdFvuKgwM_UIfjviXKudPl9B2kdE,23
32
- topologicpy-0.7.87.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
- topologicpy-0.7.87.dist-info/METADATA,sha256=UWltJr_9E-eV2trZxj7ZsvXZlVD8GHtBWdIxgUvn6zM,10513
34
- topologicpy-0.7.87.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
- topologicpy-0.7.87.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.7.87.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=mYCzbNDO5wSdD-Yv5YhtOF5hGlgyQ-E65V4XiSUOLnk,23
32
+ topologicpy-0.7.90.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
+ topologicpy-0.7.90.dist-info/METADATA,sha256=h8bGLDHNJXflEvDHHSsD0bDwwj39F_AvSqvvwVvi5Ec,10513
34
+ topologicpy-0.7.90.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
+ topologicpy-0.7.90.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.7.90.dist-info/RECORD,,