topologicpy 0.8.31__py3-none-any.whl → 0.8.35__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 +1098 -10
- topologicpy/CellComplex.py +28 -1
- topologicpy/Dictionary.py +119 -0
- topologicpy/Edge.py +16 -0
- topologicpy/Face.py +319 -54
- topologicpy/Graph.py +2 -7
- topologicpy/Helper.py +52 -0
- topologicpy/Shell.py +119 -92
- topologicpy/Topology.py +189 -11
- topologicpy/Vertex.py +1 -1
- topologicpy/Wire.py +66 -31
- topologicpy/version.py +1 -1
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/METADATA +1 -1
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/RECORD +17 -17
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/top_level.txt +0 -0
topologicpy/CellComplex.py
CHANGED
@@ -159,7 +159,7 @@ class CellComplex():
|
|
159
159
|
if transferDictionaries == True:
|
160
160
|
for temp_cell in temp_cells:
|
161
161
|
v = Topology.InternalVertex(temp_cell, tolerance=tolerance)
|
162
|
-
enclosing_cells = Vertex.
|
162
|
+
enclosing_cells = Vertex.EnclosingCells(v, cluster)
|
163
163
|
dictionaries = [Topology.Dictionary(ec) for ec in enclosing_cells]
|
164
164
|
d = Dictionary.ByMergedDictionaries(dictionaries, silent=silent)
|
165
165
|
temp_cell = Topology.SetDictionary(temp_cell, d)
|
@@ -1050,6 +1050,33 @@ class CellComplex():
|
|
1050
1050
|
shells = Topology.Shells(cellComplex)
|
1051
1051
|
return shells
|
1052
1052
|
|
1053
|
+
@staticmethod
|
1054
|
+
def _grow_connected_group(seed_idx, group_size, adjacency, visited_global):
|
1055
|
+
"""
|
1056
|
+
Attempts to grow a group of the given size starting from seed_idx using adjacency.
|
1057
|
+
Returns a list of indices if successful, else None.
|
1058
|
+
"""
|
1059
|
+
from collections import deque
|
1060
|
+
import random
|
1061
|
+
|
1062
|
+
group = [seed_idx]
|
1063
|
+
visited = set(group)
|
1064
|
+
queue = deque([seed_idx])
|
1065
|
+
|
1066
|
+
while queue and len(group) < group_size:
|
1067
|
+
current = queue.popleft()
|
1068
|
+
neighbors = adjacency.get(current, [])
|
1069
|
+
random.shuffle(neighbors)
|
1070
|
+
for neighbor in neighbors:
|
1071
|
+
if neighbor not in visited and neighbor not in visited_global:
|
1072
|
+
group.append(neighbor)
|
1073
|
+
visited.add(neighbor)
|
1074
|
+
queue.append(neighbor)
|
1075
|
+
if len(group) >= group_size:
|
1076
|
+
break
|
1077
|
+
|
1078
|
+
return group if len(group) == group_size else None
|
1079
|
+
|
1053
1080
|
@staticmethod
|
1054
1081
|
def Tetrahedron(origin = None, length: float = 1, depth: int = 1, direction=[0,0,1], placement="center", mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
1055
1082
|
"""
|
topologicpy/Dictionary.py
CHANGED
@@ -46,6 +46,125 @@ class Dictionary():
|
|
46
46
|
dictionaries.append(Dictionary.ByKeysValues(keys, values))
|
47
47
|
return dictionaries
|
48
48
|
'''
|
49
|
+
@staticmethod
|
50
|
+
def AdjacencyDictionary(topology, subTopologyType: str = None, labelKey: str = None, weightKey: str = None, includeWeights: bool = False, mantissa: int = 6, silent: bool = False):
|
51
|
+
"""
|
52
|
+
Returns the adjacency dictionary of the input Shell.
|
53
|
+
|
54
|
+
Parameters
|
55
|
+
----------
|
56
|
+
topology : topologic_core.Topology
|
57
|
+
The input topology.
|
58
|
+
subTopologyType : str , optional
|
59
|
+
The type of subTopology on which to base the adjacency dictionary.
|
60
|
+
labelKey : str , optional
|
61
|
+
The returned subTopologies are labelled according to the dictionary values stored under this key.
|
62
|
+
If the labelKey does not exist, it will be created and the subTopologies are labelled numerically and stored in the subTopologies' dictionary under this key. The default is None.
|
63
|
+
weightKey : str , optional
|
64
|
+
If set, the sharedTopologies' dictionaries will be searched for this key to set their weight. If the key is set to "Area" or "Length" (case insensitive), the area of shared faces or the length of the shared edges will be used as its weight. If set to None, a weight of 1 will be used. The default is None.
|
65
|
+
includeWeights : bool , optional
|
66
|
+
If set to True, edge weights are included. Otherwise, they are not. The default is False.
|
67
|
+
mantissa : int , optional
|
68
|
+
The desired length of the mantissa. The default is 6.
|
69
|
+
silent : bool , optional
|
70
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
71
|
+
|
72
|
+
Returns
|
73
|
+
-------
|
74
|
+
dict
|
75
|
+
The adjacency dictionary.
|
76
|
+
"""
|
77
|
+
from topologicpy.Edge import Edge
|
78
|
+
from topologicpy.Dictionary import Dictionary
|
79
|
+
from topologicpy.Topology import Topology
|
80
|
+
from topologicpy.Graph import Graph
|
81
|
+
from topologicpy.Helper import Helper
|
82
|
+
|
83
|
+
if not Topology.IsInstance(topology, "Topology") and not Topology.IsInstance(topology, "Graph"):
|
84
|
+
if not silent:
|
85
|
+
print("Dictionary.AdjacencyDictionary - Error: The input topology input parameter is not a valid topology. Returning None.")
|
86
|
+
return None
|
87
|
+
# Special Case for Graphs
|
88
|
+
|
89
|
+
if Topology.IsInstance(topology, "Graph"):
|
90
|
+
return Graph.AdjacencyDictionary(topology, vertexLabelKey=labelKey, edgeKey=weightKey, includeWeights=includeWeights, mantissa=mantissa)
|
91
|
+
if labelKey == None:
|
92
|
+
labelKey = "__label__"
|
93
|
+
if not isinstance(labelKey, str):
|
94
|
+
if not silent:
|
95
|
+
print("Dictionary.AdjacencyDictionary - Error: The input labelKey is not a valid string. Returning None.")
|
96
|
+
return None
|
97
|
+
if Topology.IsInstance(topology, "cellcomplex"):
|
98
|
+
if subTopologyType == None:
|
99
|
+
subTopologyType = "cell"
|
100
|
+
all_subtopologies = Topology.SubTopologies(topology, subTopologyType=subTopologyType, silent=silent)
|
101
|
+
elif Topology.IsInstance(topology, "cell") or Topology.IsInstance(topology, "shell"):
|
102
|
+
if subTopologyType == None:
|
103
|
+
subTopologyType = "face"
|
104
|
+
all_subtopologies = Topology.SubTopologies(topology, subTopologyType=subTopologyType, silent=silent)
|
105
|
+
elif Topology.IsInstance(topology, "face") or Topology.IsInstance(topology, "wire"):
|
106
|
+
if subTopologyType == None:
|
107
|
+
subTopologyType = "edge"
|
108
|
+
all_subtopologies = Topology.SubTopologies(topology, subTopologyType=subTopologyType, silent=silent)
|
109
|
+
labels = []
|
110
|
+
n = max(len(str(len(all_subtopologies))), 3)
|
111
|
+
for i, subtopology in enumerate(all_subtopologies):
|
112
|
+
d = Topology.Dictionary(subtopology)
|
113
|
+
value = Dictionary.ValueAtKey(d, labelKey)
|
114
|
+
if value == None:
|
115
|
+
value = str(i+1).zfill(n)
|
116
|
+
if d == None:
|
117
|
+
d = Dictionary.ByKeyValue(labelKey, value)
|
118
|
+
else:
|
119
|
+
d = Dictionary.SetValueAtKey(d, labelKey, value)
|
120
|
+
subtopology = Topology.SetDictionary(subtopology, d)
|
121
|
+
labels.append(value)
|
122
|
+
all_subtopologies = Helper.Sort(all_subtopologies, labels)
|
123
|
+
labels.sort()
|
124
|
+
order = len(all_subtopologies)
|
125
|
+
adjDict = {}
|
126
|
+
for i in range(order):
|
127
|
+
subtopology = all_subtopologies[i]
|
128
|
+
subt_label = labels[i]
|
129
|
+
adjacent_topologies = Topology.AdjacentTopologies(subtopology, hostTopology=topology, topologyType=subTopologyType)
|
130
|
+
temp_list = []
|
131
|
+
for adj_topology in adjacent_topologies:
|
132
|
+
adj_label = Dictionary.ValueAtKey(Topology.Dictionary(adj_topology), labelKey)
|
133
|
+
adj_index = labels.index(adj_label)
|
134
|
+
if includeWeights == True:
|
135
|
+
if weightKey == None:
|
136
|
+
weight = 1
|
137
|
+
elif "length" in weightKey.lower():
|
138
|
+
shared_topologies = Topology.SharedTopologies(subtopology, adj_topology)
|
139
|
+
edges = shared_topologies.get("edges", [])
|
140
|
+
weight = sum([Edge.Length(edge, mantissa=mantissa) for edge in edges])
|
141
|
+
elif "area" in weightKey.lower():
|
142
|
+
shared_topologies = Topology.SharedTopologies(subtopology, adj_topology)
|
143
|
+
faces = shared_topologies.get("faces", [])
|
144
|
+
weight = sum([Edge.Length(edge, mantissa=mantissa) for face in faces])
|
145
|
+
else:
|
146
|
+
shared_topologies = Topology.SharedTopologies(subtopology, adj_topology)
|
147
|
+
vertices = shared_topologies.get("vertices", [])
|
148
|
+
edges = shared_topologies.get("edges", [])
|
149
|
+
wires = shared_topologies.get("wires", [])
|
150
|
+
faces = shared_topologies.get("faces", [])
|
151
|
+
everything = vertices+edges+wires+faces
|
152
|
+
weight = sum([Dictionary.ValueAtKey(Topology.Dictionary(x),weightKey, 0) for x in everything])
|
153
|
+
weight = round(weight, mantissa)
|
154
|
+
if not adj_index == None:
|
155
|
+
temp_list.append((adj_label, weight))
|
156
|
+
else:
|
157
|
+
if not adj_index == None:
|
158
|
+
temp_list.append(adj_label)
|
159
|
+
temp_list.sort()
|
160
|
+
adjDict[subt_label] = temp_list
|
161
|
+
if labelKey == "__label__": # This is label we added, so remove it
|
162
|
+
for subtopology in all_subtopologies:
|
163
|
+
d = Topology.Dictionary(subtopology)
|
164
|
+
d = Dictionary.RemoveKey(d, labelKey)
|
165
|
+
subtopology = Topology.SetDictionary(subtopology, d)
|
166
|
+
return adjDict
|
167
|
+
|
49
168
|
@staticmethod
|
50
169
|
def ByKeyValue(key, value):
|
51
170
|
"""
|
topologicpy/Edge.py
CHANGED
@@ -306,29 +306,45 @@ class Edge():
|
|
306
306
|
"""
|
307
307
|
from topologicpy.Vertex import Vertex
|
308
308
|
from topologicpy.Topology import Topology
|
309
|
+
import inspect
|
309
310
|
|
310
311
|
edge = None
|
311
312
|
if not Topology.IsInstance(vertexA, "Vertex"):
|
312
313
|
if not silent:
|
313
314
|
print("Edge.ByStartVertexEndVertex - Error: The input vertexA parameter is not a valid topologic vertex. Returning None.")
|
315
|
+
curframe = inspect.currentframe()
|
316
|
+
calframe = inspect.getouterframes(curframe, 2)
|
317
|
+
print('caller name:', calframe[1][3])
|
314
318
|
return None
|
315
319
|
if not Topology.IsInstance(vertexB, "Vertex"):
|
316
320
|
if not silent:
|
317
321
|
print("Edge.ByStartVertexEndVertex - Error: The input vertexB parameter is not a valid topologic vertex. Returning None.")
|
322
|
+
curframe = inspect.currentframe()
|
323
|
+
calframe = inspect.getouterframes(curframe, 2)
|
324
|
+
print('caller name:', calframe[1][3])
|
318
325
|
return None
|
319
326
|
if Topology.IsSame(vertexA, vertexB):
|
320
327
|
if not silent:
|
321
328
|
print("Edge.ByStartVertexEndVertex - Error: The input vertexA and vertexB parameters are the same vertex. Returning None.")
|
329
|
+
curframe = inspect.currentframe()
|
330
|
+
calframe = inspect.getouterframes(curframe, 2)
|
331
|
+
print('caller name:', calframe[1][3])
|
322
332
|
return None
|
323
333
|
if Vertex.Distance(vertexA, vertexB) <= tolerance:
|
324
334
|
if not silent:
|
325
335
|
print("Edge.ByStartVertexEndVertex - Error: The distance between the input vertexA and vertexB parameters is less than the input tolerance. Returning None.")
|
336
|
+
curframe = inspect.currentframe()
|
337
|
+
calframe = inspect.getouterframes(curframe, 2)
|
338
|
+
print('caller name:', calframe[1][3])
|
326
339
|
return None
|
327
340
|
try:
|
328
341
|
edge = topologic.Edge.ByStartVertexEndVertex(vertexA, vertexB) # Hook to Core
|
329
342
|
except:
|
330
343
|
if not silent:
|
331
344
|
print("Edge.ByStartVertexEndVertex - Error: Could not create an edge. Returning None.")
|
345
|
+
curframe = inspect.currentframe()
|
346
|
+
calframe = inspect.getouterframes(curframe, 2)
|
347
|
+
print('caller name:', calframe[1][3])
|
332
348
|
edge = None
|
333
349
|
return edge
|
334
350
|
|