topologicpy 0.8.30__py3-none-any.whl → 0.8.33__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/BVH.py +5 -3
- topologicpy/CSG.py +1 -1
- topologicpy/Cell.py +1105 -12
- topologicpy/CellComplex.py +213 -1
- topologicpy/Cluster.py +4 -2
- topologicpy/Edge.py +61 -28
- topologicpy/Face.py +384 -101
- topologicpy/Graph.py +149 -2
- topologicpy/Plotly.py +0 -1
- topologicpy/ShapeGrammar.py +65 -6
- topologicpy/Topology.py +56 -416
- topologicpy/Vertex.py +1 -1
- topologicpy/Wire.py +95 -45
- topologicpy/version.py +1 -1
- {topologicpy-0.8.30.dist-info → topologicpy-0.8.33.dist-info}/METADATA +1 -1
- {topologicpy-0.8.30.dist-info → topologicpy-0.8.33.dist-info}/RECORD +19 -19
- {topologicpy-0.8.30.dist-info → topologicpy-0.8.33.dist-info}/WHEEL +1 -1
- {topologicpy-0.8.30.dist-info → topologicpy-0.8.33.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.30.dist-info → topologicpy-0.8.33.dist-info}/top_level.txt +0 -0
topologicpy/Graph.py
CHANGED
@@ -171,7 +171,7 @@ class WorkerProcess(Process):
|
|
171
171
|
if self.used[i + self.start_index][j] == 1 or self.used[j][i + self.start_index]:
|
172
172
|
continue
|
173
173
|
if Vertex.Distance(source, destination) > self.tolerance:
|
174
|
-
edge = Edge.ByVertices([source, destination])
|
174
|
+
edge = Edge.ByVertices([source, destination], tolerance=self.tolerance, silent=True)
|
175
175
|
e = Topology.Intersect(edge, face)
|
176
176
|
if Topology.IsInstance(e, "Edge"):
|
177
177
|
edges.append(edge)
|
@@ -437,7 +437,7 @@ class Graph:
|
|
437
437
|
for vertex in vertices:
|
438
438
|
graph_vertices, nv = addIfUnique(graph_vertices, vertex, tolerance=tolerance)
|
439
439
|
new_vertices.append(nv)
|
440
|
-
new_edge = Edge.ByVertices([new_vertices[0], new_vertices[1]], tolerance=tolerance)
|
440
|
+
new_edge = Edge.ByVertices([new_vertices[0], new_vertices[1]], tolerance=tolerance, silent=silent)
|
441
441
|
if transferEdgeDictionaries == True:
|
442
442
|
d = Topology.Dictionary(edge)
|
443
443
|
keys = Dictionary.Keys(d)
|
@@ -10133,6 +10133,153 @@ class Graph:
|
|
10133
10133
|
edge = Topology.SetDictionary(edge, d)
|
10134
10134
|
return max_flow
|
10135
10135
|
|
10136
|
+
@staticmethod
|
10137
|
+
def MergeVertices(graph, *vertices, targetVertex=None, transferDictionaries: bool = True, tolerance: float = 0.0001, silent: bool = False):
|
10138
|
+
"""
|
10139
|
+
Merges the input vertices into one vertex and reconnects all edges to the new vertex.
|
10140
|
+
If two of the input vertices are the end points of the same edge, that edge is deleted.
|
10141
|
+
|
10142
|
+
Parameters
|
10143
|
+
----------
|
10144
|
+
graph : topologic_core.Graph
|
10145
|
+
The input graph.
|
10146
|
+
*vertices : topologic_core.Vertex
|
10147
|
+
Two or more instances of `topologic_core.Topology` to be processed.
|
10148
|
+
targetVertex : topologic_core.Vertex, optional
|
10149
|
+
The target vertex to merge into. If None, a centroid is computed. Default is None.
|
10150
|
+
transferDictionaries : bool, optional
|
10151
|
+
If True, the dictionaries of all input vertices (including the target vertex if given) are merged. Default is True.
|
10152
|
+
tolerance : float , optional
|
10153
|
+
The desired tolerance. The default is 0.0001.
|
10154
|
+
silent : bool , optional
|
10155
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
10156
|
+
|
10157
|
+
Returns
|
10158
|
+
-------
|
10159
|
+
topologic_core.Graph
|
10160
|
+
A new graph with the vertices merged and edges updated.
|
10161
|
+
"""
|
10162
|
+
from topologicpy.Cluster import Cluster
|
10163
|
+
from topologicpy.Topology import Topology
|
10164
|
+
from topologicpy.Edge import Edge
|
10165
|
+
from topologicpy.Dictionary import Dictionary
|
10166
|
+
from topologicpy.Helper import Helper
|
10167
|
+
import inspect
|
10168
|
+
|
10169
|
+
if not Topology.IsInstance(graph, "Graph"):
|
10170
|
+
print("Graph:", graph)
|
10171
|
+
if not silent:
|
10172
|
+
print("Graph.MergeVertices - Error: The input graph is not valid. Returning None.")
|
10173
|
+
return None
|
10174
|
+
|
10175
|
+
if len(vertices) == 0:
|
10176
|
+
if not silent:
|
10177
|
+
print("Graph.MergeVertices - Error: The input vertices parameter is an empty list. Returning None.")
|
10178
|
+
curframe = inspect.currentframe()
|
10179
|
+
calframe = inspect.getouterframes(curframe, 2)
|
10180
|
+
print('caller name:', calframe[1][3])
|
10181
|
+
return None
|
10182
|
+
if len(vertices) == 1:
|
10183
|
+
vertices = vertices[0]
|
10184
|
+
if isinstance(vertices, list):
|
10185
|
+
if len(vertices) == 0:
|
10186
|
+
if not silent:
|
10187
|
+
print("Graph.MergeVertices - Error: The input topologies parameter is an empty list. Returning None.")
|
10188
|
+
curframe = inspect.currentframe()
|
10189
|
+
calframe = inspect.getouterframes(curframe, 2)
|
10190
|
+
print('caller name:', calframe[1][3])
|
10191
|
+
return None
|
10192
|
+
else:
|
10193
|
+
vertexList = [x for x in vertices if Topology.IsInstance(x, "Topology")]
|
10194
|
+
if len(vertexList) == 0:
|
10195
|
+
if not silent:
|
10196
|
+
print("Graph.MergeVertices - Error: The input topologies parameter does not contain any valid vertices. Returning None.")
|
10197
|
+
curframe = inspect.currentframe()
|
10198
|
+
calframe = inspect.getouterframes(curframe, 2)
|
10199
|
+
print('caller name:', calframe[1][3])
|
10200
|
+
return None
|
10201
|
+
else:
|
10202
|
+
if not silent:
|
10203
|
+
print("Graph.MergeVertices - Error: The input vertices parameter contains only one vertex. Returning None.")
|
10204
|
+
curframe = inspect.currentframe()
|
10205
|
+
calframe = inspect.getouterframes(curframe, 2)
|
10206
|
+
print('caller name:', calframe[1][3])
|
10207
|
+
return None
|
10208
|
+
else:
|
10209
|
+
vertexList = Helper.Flatten(list(vertices))
|
10210
|
+
vertexList = [x for x in vertexList if Topology.IsInstance(x, "Vertex")]
|
10211
|
+
if len(vertexList) == 0:
|
10212
|
+
if not silent:
|
10213
|
+
print("Graph.MergeVertices - Error: The input parameters do not contain any valid vertices. Returning None.")
|
10214
|
+
curframe = inspect.currentframe()
|
10215
|
+
calframe = inspect.getouterframes(curframe, 2)
|
10216
|
+
print('caller name:', calframe[1][3])
|
10217
|
+
return None
|
10218
|
+
|
10219
|
+
# Step 1: gather all vertices and edges
|
10220
|
+
all_vertices = Graph.Vertices(graph)
|
10221
|
+
all_edges = Graph.Edges(graph)
|
10222
|
+
|
10223
|
+
# Step 2: determine merged vertex
|
10224
|
+
dictionaries = []
|
10225
|
+
if targetVertex and Topology.IsInstance(targetVertex, "Vertex"):
|
10226
|
+
merged_vertex = targetVertex
|
10227
|
+
if targetVertex not in all_vertices:
|
10228
|
+
all_vertices.append(targetVertex)
|
10229
|
+
dictionaries.append(Topology.Dictionary(targetVertex))
|
10230
|
+
else:
|
10231
|
+
# Compute centroid
|
10232
|
+
merged_vertex = Topology.Centroid(Cluster.ByTopologies(vertexList))
|
10233
|
+
|
10234
|
+
# Step 3: collect dictionaries
|
10235
|
+
if transferDictionaries:
|
10236
|
+
for v in vertexList:
|
10237
|
+
d = Topology.Dictionary(v)
|
10238
|
+
dictionaries.append(d)
|
10239
|
+
merged_dict = Dictionary.ByMergedDictionaries(*dictionaries)
|
10240
|
+
merged_vertex = Topology.SetDictionary(merged_vertex, merged_dict, silent=True)
|
10241
|
+
|
10242
|
+
# Step 4: remove merged vertices from all_vertices
|
10243
|
+
for v in vertexList:
|
10244
|
+
for gv in all_vertices:
|
10245
|
+
if Topology.IsSame(v, gv):
|
10246
|
+
all_vertices.remove(gv)
|
10247
|
+
break
|
10248
|
+
|
10249
|
+
# Step 5: rebuild edge list
|
10250
|
+
new_edges = []
|
10251
|
+
seen = set()
|
10252
|
+
for edge in all_edges:
|
10253
|
+
sv = Edge.StartVertex(edge)
|
10254
|
+
ev = Edge.EndVertex(edge)
|
10255
|
+
|
10256
|
+
sv_merged = any(Topology.IsSame(sv, v) for v in vertexList)
|
10257
|
+
ev_merged = any(Topology.IsSame(ev, v) for v in vertexList)
|
10258
|
+
|
10259
|
+
if sv_merged and ev_merged:
|
10260
|
+
continue # Remove edges between merged vertices
|
10261
|
+
|
10262
|
+
new_sv = merged_vertex if sv_merged else sv
|
10263
|
+
new_ev = merged_vertex if ev_merged else ev
|
10264
|
+
|
10265
|
+
if Topology.IsSame(new_sv, new_ev):
|
10266
|
+
continue # Avoid self-loop
|
10267
|
+
|
10268
|
+
key = tuple(sorted([Topology.UUID(new_sv), Topology.UUID(new_ev)]))
|
10269
|
+
if key in seen:
|
10270
|
+
continue
|
10271
|
+
seen.add(key)
|
10272
|
+
|
10273
|
+
new_edge = Edge.ByVertices([new_sv, new_ev])
|
10274
|
+
if Topology.IsInstance(new_edge, "edge"):
|
10275
|
+
d = Topology.Dictionary(edge)
|
10276
|
+
if d:
|
10277
|
+
new_edge = Topology.SetDictionary(new_edge, d, silent=True)
|
10278
|
+
new_edges.append(new_edge)
|
10279
|
+
|
10280
|
+
all_vertices.append(merged_vertex)
|
10281
|
+
return Graph.ByVerticesEdges(all_vertices, new_edges)
|
10282
|
+
|
10136
10283
|
@staticmethod
|
10137
10284
|
def MeshData(graph, mantissa: int = 6, tolerance: float = 0.0001):
|
10138
10285
|
"""
|
topologicpy/Plotly.py
CHANGED
topologicpy/ShapeGrammar.py
CHANGED
@@ -384,7 +384,7 @@ class ShapeGrammar:
|
|
384
384
|
|
385
385
|
return result_output
|
386
386
|
|
387
|
-
def
|
387
|
+
def ClusterByInputOutput(self, input, output, silent: bool = False):
|
388
388
|
"""
|
389
389
|
Returns the Plotly figure of the input and output topologies as a rule.
|
390
390
|
|
@@ -407,15 +407,14 @@ class ShapeGrammar:
|
|
407
407
|
from topologicpy.Topology import Topology
|
408
408
|
from topologicpy.Dictionary import Dictionary
|
409
409
|
from topologicpy.Cluster import Cluster
|
410
|
-
from topologicpy.Plotly import Plotly
|
411
410
|
|
412
411
|
if not Topology.IsInstance(input, "Topology"):
|
413
412
|
if not silent:
|
414
|
-
print("ShapeGrammar.
|
413
|
+
print("ShapeGrammar.ClusterByInputOutput - Error: The input topology parameter is not a valid topology. Returning None.")
|
415
414
|
return None
|
416
415
|
if not Topology.IsInstance(output, "Topology"):
|
417
416
|
if not silent:
|
418
|
-
print("ShapeGrammar.
|
417
|
+
print("ShapeGrammar.ClusterByInputOutput - Error: The output topology parameter is not a valid topology. Returning None.")
|
419
418
|
return None
|
420
419
|
|
421
420
|
input_bb = Topology.BoundingBox(input)
|
@@ -463,6 +462,65 @@ class ShapeGrammar:
|
|
463
462
|
cone = Topology.Translate(cone, 1.65, 0, 0)
|
464
463
|
cluster = Cluster.ByTopologies([temp_input, temp_output, cyl, cone])
|
465
464
|
cluster = Topology.Place(cluster, originA=Topology.Centroid(cluster), originB=Vertex.Origin())
|
465
|
+
return cluster
|
466
|
+
|
467
|
+
def ClusterByRule(self, rule, silent: bool = False):
|
468
|
+
"""
|
469
|
+
Returns the Plotly figure of the input rule.
|
470
|
+
|
471
|
+
Parameters
|
472
|
+
----------
|
473
|
+
rule : dict
|
474
|
+
The input rule
|
475
|
+
silent : bool, optional
|
476
|
+
If True, suppresses error/warning messages. Default is False.
|
477
|
+
|
478
|
+
Returns
|
479
|
+
-------
|
480
|
+
topologic_core.Cluster
|
481
|
+
The created rule cluster
|
482
|
+
"""
|
483
|
+
|
484
|
+
if not isinstance(rule, dict):
|
485
|
+
if not silent:
|
486
|
+
print("ShapeGrammar.ClusterByRule - Error: The input rule parameter is not a valid rule. Returning None.")
|
487
|
+
return None
|
488
|
+
input = rule["input"]
|
489
|
+
output = self.ApplyRule(input, rule)
|
490
|
+
return self.ClusterByInputOutput(input, output, silent=silent)
|
491
|
+
|
492
|
+
def FigureByInputOutput(self, input, output, silent: bool = False):
|
493
|
+
"""
|
494
|
+
Returns the Plotly figure of the input and output topologies as a rule.
|
495
|
+
|
496
|
+
Parameters
|
497
|
+
----------
|
498
|
+
input : topologic_core.Topology
|
499
|
+
The input topology
|
500
|
+
output : topologic_core.Topology
|
501
|
+
The output topology
|
502
|
+
silent : bool, optional
|
503
|
+
If True, suppresses error/warning messages. Default is False.
|
504
|
+
|
505
|
+
Returns
|
506
|
+
-------
|
507
|
+
Plotly.Figure
|
508
|
+
The created plotly figure.
|
509
|
+
"""
|
510
|
+
|
511
|
+
from topologicpy.Topology import Topology
|
512
|
+
from topologicpy.Plotly import Plotly
|
513
|
+
|
514
|
+
if not Topology.IsInstance(input, "Topology"):
|
515
|
+
if not silent:
|
516
|
+
print("ShapeGrammar.FigureByInputOutput - Error: The input topology parameter is not a valid topology. Returning None.")
|
517
|
+
return None
|
518
|
+
if not Topology.IsInstance(output, "Topology"):
|
519
|
+
if not silent:
|
520
|
+
print("ShapeGrammar.FigureByInputOutput - Error: The output topology parameter is not a valid topology. Returning None.")
|
521
|
+
return None
|
522
|
+
|
523
|
+
cluster = self.ClusterByInputOutput(input, output, silent=silent)
|
466
524
|
data = Plotly.DataByTopology(cluster)
|
467
525
|
fig = Plotly.FigureByData(data)
|
468
526
|
return fig
|
@@ -480,7 +538,8 @@ class ShapeGrammar:
|
|
480
538
|
|
481
539
|
Returns
|
482
540
|
-------
|
483
|
-
|
541
|
+
Plotly.Figure
|
542
|
+
The create plotly figure
|
484
543
|
"""
|
485
544
|
from topologicpy.Topology import Topology
|
486
545
|
if not isinstance(rule, dict):
|
@@ -489,4 +548,4 @@ class ShapeGrammar:
|
|
489
548
|
return None
|
490
549
|
input = rule["input"]
|
491
550
|
output = self.ApplyRule(input, rule)
|
492
|
-
return self.FigureByInputOutput(input, output)
|
551
|
+
return self.FigureByInputOutput(input, output, silent=silent)
|