topologicpy 0.4.36__py3-none-any.whl → 0.4.38__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/Color.py +47 -0
- topologicpy/Graph.py +181 -0
- topologicpy/Plotly.py +33 -24
- topologicpy/Shell.py +159 -95
- topologicpy/Topology.py +609 -614
- topologicpy/Vertex.py +53 -1
- topologicpy/Wire.py +26 -21
- topologicpy/__init__.py +1 -1
- {topologicpy-0.4.36.dist-info → topologicpy-0.4.38.dist-info}/METADATA +1 -1
- {topologicpy-0.4.36.dist-info → topologicpy-0.4.38.dist-info}/RECORD +13 -13
- {topologicpy-0.4.36.dist-info → topologicpy-0.4.38.dist-info}/WHEEL +1 -1
- {topologicpy-0.4.36.dist-info → topologicpy-0.4.38.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.36.dist-info → topologicpy-0.4.38.dist-info}/top_level.txt +0 -0
topologicpy/Shell.py
CHANGED
|
@@ -3,10 +3,19 @@ import topologicpy
|
|
|
3
3
|
import topologic
|
|
4
4
|
from topologicpy.Topology import Topology
|
|
5
5
|
import math
|
|
6
|
+
try:
|
|
7
|
+
from tqdm.auto import tqdm
|
|
8
|
+
except:
|
|
9
|
+
call = [sys.executable, '-m', 'pip', 'install', 'tqdm', '-t', sys.path[0]]
|
|
10
|
+
subprocess.run(call)
|
|
11
|
+
try:
|
|
12
|
+
from tqdm.auto import tqdm
|
|
13
|
+
except:
|
|
14
|
+
print("Shell - Error: Could not import tqdm")
|
|
6
15
|
|
|
7
16
|
class Shell(Topology):
|
|
8
17
|
@staticmethod
|
|
9
|
-
def ByDisjointFaces(externalBoundary, faces, maximumGap=0.5, mergeJunctions=False, threshold=0.5, transferDictionaries=False, tolerance=0.0001):
|
|
18
|
+
def ByDisjointFaces(externalBoundary, faces, maximumGap=0.5, mergeJunctions=False, threshold=0.5, uSides=1, vSides=1, transferDictionaries=False, tolerance=0.0001):
|
|
10
19
|
"""
|
|
11
20
|
Creates a shell from an input list of disjointed faces.
|
|
12
21
|
|
|
@@ -22,6 +31,10 @@ class Shell(Topology):
|
|
|
22
31
|
If set to True, the interior junctions are merged into a single vertex. Otherwise, diagonal edges are added to resolve transitions between different gap distances.
|
|
23
32
|
threshold : float , optional
|
|
24
33
|
The desired threshold under which vertices are merged into a single vertex. The default is 0.5.
|
|
34
|
+
uSides : int , optional
|
|
35
|
+
The desired number of sides along the X axis for the grid that subdivides the input faces to aid in processing. The default is 1.
|
|
36
|
+
vSides : int , optional
|
|
37
|
+
The desired number of sides along the Y axis for the grid that subdivides the input faces to aid in processing. The default is 1.
|
|
25
38
|
transferDictionaries : bool, optional.
|
|
26
39
|
If set to True, the dictionaries in the input list of faces are transfered to the faces of the resulting shell. The default is False.
|
|
27
40
|
tolerance : float , optional
|
|
@@ -39,10 +52,13 @@ class Shell(Topology):
|
|
|
39
52
|
from topologicpy.Face import Face
|
|
40
53
|
from topologicpy.Cluster import Cluster
|
|
41
54
|
from topologicpy.Helper import Helper
|
|
55
|
+
from topologicpy.Topology import Topology
|
|
56
|
+
from topologicpy.Grid import Grid
|
|
57
|
+
from topologicpy.Dictionary import Dictionary
|
|
42
58
|
|
|
43
59
|
def removeShards(edges, hostTopology, maximumGap=0.5):
|
|
44
60
|
returnEdges = []
|
|
45
|
-
for e in edges:
|
|
61
|
+
for e in tqdm(edges, desc="Removing Shards", leave=False):
|
|
46
62
|
if Edge.Length(e) < maximumGap:
|
|
47
63
|
sv = Edge.StartVertex(e)
|
|
48
64
|
ev = Edge.EndVertex(e)
|
|
@@ -58,7 +74,7 @@ class Shell(Topology):
|
|
|
58
74
|
|
|
59
75
|
def extendEdges(edges, hostTopology, maximumGap=0.5):
|
|
60
76
|
returnEdges = []
|
|
61
|
-
for e in edges:
|
|
77
|
+
for e in tqdm(edges, desc="Extending Edges", leave=False):
|
|
62
78
|
sv = Edge.StartVertex(e)
|
|
63
79
|
ev = Edge.EndVertex(e)
|
|
64
80
|
sEdges = Topology.SuperTopologies(sv, hostTopology, "edge")
|
|
@@ -77,99 +93,147 @@ class Shell(Topology):
|
|
|
77
93
|
|
|
78
94
|
facesCluster = Cluster.ByTopologies(faces)
|
|
79
95
|
internalBoundary = Face.ByWire(Face.InternalBoundaries(externalBoundary)[0])
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
for v in centers:
|
|
106
|
-
if Vertex.Distance(sv, v) < threshold:
|
|
107
|
-
sv = v
|
|
108
|
-
if Vertex.Distance(ev, v) < threshold:
|
|
109
|
-
ev = v
|
|
110
|
-
new_edges.append(Edge.ByVertices([sv,ev]))
|
|
111
|
-
cluster = Cluster.ByTopologies(new_edges)
|
|
112
|
-
|
|
113
|
-
vertices = Topology.Vertices(cluster)
|
|
114
|
-
edges = Topology.Edges(shell)
|
|
115
|
-
|
|
116
|
-
xList = list(set([Vertex.X(v) for v in vertices]))
|
|
117
|
-
xList.sort()
|
|
118
|
-
xList = Helper.MergeByThreshold(xList, 0.5)
|
|
119
|
-
yList = list(set([Vertex.Y(v) for v in vertices]))
|
|
120
|
-
yList.sort()
|
|
121
|
-
yList = Helper.MergeByThreshold(yList, 0.5)
|
|
122
|
-
yList.sort()
|
|
123
|
-
|
|
124
|
-
centers = []
|
|
125
|
-
|
|
126
|
-
new_edges = []
|
|
127
|
-
|
|
128
|
-
for e in edges:
|
|
129
|
-
sv = Edge.StartVertex(e)
|
|
130
|
-
ev = Edge.EndVertex(e)
|
|
131
|
-
svx = Vertex.X(sv)
|
|
132
|
-
svy = Vertex.Y(sv)
|
|
133
|
-
evx = Vertex.X(ev)
|
|
134
|
-
evy = Vertex.Y(ev)
|
|
135
|
-
for x in xList:
|
|
136
|
-
if abs(svx-x) < threshold:
|
|
137
|
-
svx = x
|
|
138
|
-
break;
|
|
139
|
-
for y in yList:
|
|
140
|
-
if abs(svy-y) < threshold:
|
|
141
|
-
svy = y
|
|
142
|
-
break;
|
|
143
|
-
sv = Vertex.ByCoordinates(svx, svy, 0)
|
|
144
|
-
for x in xList:
|
|
145
|
-
if abs(evx-x) < threshold:
|
|
146
|
-
evx = x
|
|
96
|
+
bb = Topology.BoundingBox(internalBoundary)
|
|
97
|
+
bb_d = Topology.Dictionary(bb)
|
|
98
|
+
unitU = Dictionary.ValueAtKey(bb_d, 'width') / uSides
|
|
99
|
+
unitV = Dictionary.ValueAtKey(bb_d, 'length') / vSides
|
|
100
|
+
uRange = [u*unitU for u in range(uSides)]
|
|
101
|
+
vRange = [v*unitV for v in range(vSides)]
|
|
102
|
+
grid = Grid.EdgesByDistances(internalBoundary, uRange=uRange, vRange=vRange, clip=True)
|
|
103
|
+
#grid = Topology.Rotate(grid, origin=Topology.Centroid(grid), degree=25)
|
|
104
|
+
#grid = Topology.Scale(grid, origin=Topology.Centroid(grid), x=3, y=3, z=1)
|
|
105
|
+
grid = Topology.Slice(internalBoundary, grid)
|
|
106
|
+
Topology.Show(grid)
|
|
107
|
+
#temp_clus = Cluster.ByTopologies([grid, internalBoundary, facesCluster])
|
|
108
|
+
#Topology.Show(temp_clus)
|
|
109
|
+
grid_faces = Topology.Faces(grid)
|
|
110
|
+
skeletons = []
|
|
111
|
+
for ib in tqdm(grid_faces, desc="Processing "+str(len(grid_faces))+" tiles", leave=False):
|
|
112
|
+
building_shell = Topology.Slice(ib, facesCluster)
|
|
113
|
+
wall_faces = Topology.Faces(building_shell)
|
|
114
|
+
walls = []
|
|
115
|
+
for w1 in wall_faces:
|
|
116
|
+
iv = Face.InternalVertex(w1)
|
|
117
|
+
flag = False
|
|
118
|
+
for w2 in faces:
|
|
119
|
+
if Face.IsInside(w2, iv):
|
|
120
|
+
flag = True
|
|
147
121
|
break;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
122
|
+
if flag == False:
|
|
123
|
+
walls.append(w1)
|
|
124
|
+
for wall in walls:
|
|
125
|
+
skeleton = Wire.Skeleton(wall)
|
|
126
|
+
skeleton = Topology.Difference(skeleton, facesCluster)
|
|
127
|
+
skeleton = Topology.Difference(skeleton, Face.Wire(wall))
|
|
128
|
+
skeletons.append(skeleton)
|
|
129
|
+
print("Finished all tiles")
|
|
130
|
+
if len(skeletons) > 0:
|
|
131
|
+
skeleton_cluster = Cluster.ByTopologies(skeletons+[internalBoundary])
|
|
132
|
+
Topology.Show(skeleton_cluster)
|
|
133
|
+
skEdges = Topology.SelfMerge(Cluster.ByTopologies(removeShards(Topology.Edges(skeleton_cluster), skeleton_cluster, maximumGap=maximumGap)))
|
|
134
|
+
if isinstance(skEdges, topologic.Edge):
|
|
135
|
+
skEdges = extendEdges([skEdges], skEdges, maximumGap=maximumGap)
|
|
136
|
+
else:
|
|
137
|
+
skEdges = extendEdges(Topology.Edges(skEdges), skEdges, maximumGap=maximumGap)
|
|
138
|
+
if len(skEdges) < 1:
|
|
139
|
+
print("WARNING - No Edges!")
|
|
140
|
+
#Topology.Show(walls)
|
|
141
|
+
#Topology.Show(skeleton_cluster)
|
|
142
|
+
#return Cluster.ByTopologies(skEdges)
|
|
143
|
+
#print("ShellByDisjointFaces - Error: Could not derive central skeleton of interior walls. Returning None.")
|
|
144
|
+
#return None
|
|
145
|
+
|
|
146
|
+
Topology.Show(skeleton_cluster)
|
|
147
|
+
shell = Topology.Slice(internalBoundary, skeleton_cluster)
|
|
148
|
+
#Topology.Show(shell)
|
|
149
|
+
if mergeJunctions == True:
|
|
150
|
+
vertices = Shell.Vertices(shell)
|
|
151
|
+
centers = []
|
|
152
|
+
used = []
|
|
153
|
+
for v in vertices:
|
|
154
|
+
for w in vertices:
|
|
155
|
+
if not Topology.IsSame(v,w) and not w in used:
|
|
156
|
+
if Vertex.Distance(v,w) < threshold:
|
|
157
|
+
centers.append(v)
|
|
158
|
+
used.append(w)
|
|
159
|
+
edges = Shell.Edges(shell)
|
|
160
|
+
new_edges = []
|
|
161
|
+
for e in edges:
|
|
162
|
+
sv = Edge.StartVertex(e)
|
|
163
|
+
ev = Edge.EndVertex(e)
|
|
164
|
+
for v in centers:
|
|
165
|
+
if Vertex.Distance(sv, v) < threshold:
|
|
166
|
+
sv = v
|
|
167
|
+
if Vertex.Distance(ev, v) < threshold:
|
|
168
|
+
ev = v
|
|
169
|
+
new_edges.append(Edge.ByVertices([sv,ev]))
|
|
170
|
+
cluster = Cluster.ByTopologies(new_edges)
|
|
171
|
+
|
|
172
|
+
vertices = Topology.Vertices(cluster)
|
|
173
|
+
edges = Topology.Edges(shell)
|
|
174
|
+
|
|
175
|
+
xList = list(set([Vertex.X(v) for v in vertices]))
|
|
176
|
+
xList.sort()
|
|
177
|
+
xList = Helper.MergeByThreshold(xList, 0.5)
|
|
178
|
+
yList = list(set([Vertex.Y(v) for v in vertices]))
|
|
179
|
+
yList.sort()
|
|
180
|
+
yList = Helper.MergeByThreshold(yList, 0.5)
|
|
181
|
+
yList.sort()
|
|
182
|
+
|
|
183
|
+
centers = []
|
|
184
|
+
|
|
185
|
+
new_edges = []
|
|
186
|
+
|
|
187
|
+
for e in edges:
|
|
188
|
+
sv = Edge.StartVertex(e)
|
|
189
|
+
ev = Edge.EndVertex(e)
|
|
190
|
+
svx = Vertex.X(sv)
|
|
191
|
+
svy = Vertex.Y(sv)
|
|
192
|
+
evx = Vertex.X(ev)
|
|
193
|
+
evy = Vertex.Y(ev)
|
|
194
|
+
for x in xList:
|
|
195
|
+
if abs(svx-x) < threshold:
|
|
196
|
+
svx = x
|
|
197
|
+
break;
|
|
198
|
+
for y in yList:
|
|
199
|
+
if abs(svy-y) < threshold:
|
|
200
|
+
svy = y
|
|
201
|
+
break;
|
|
202
|
+
sv = Vertex.ByCoordinates(svx, svy, 0)
|
|
203
|
+
for x in xList:
|
|
204
|
+
if abs(evx-x) < threshold:
|
|
205
|
+
evx = x
|
|
206
|
+
break;
|
|
207
|
+
for y in yList:
|
|
208
|
+
if abs(evy-y) < threshold:
|
|
209
|
+
evy = y
|
|
210
|
+
break;
|
|
211
|
+
sv = Vertex.ByCoordinates(svx, svy, 0)
|
|
212
|
+
ev = Vertex.ByCoordinates(evx, evy, 0)
|
|
213
|
+
new_edges.append(Edge.ByVertices([sv, ev]))
|
|
214
|
+
|
|
215
|
+
cluster = Cluster.ByTopologies(new_edges)
|
|
216
|
+
eb = Face.ByWire(Shell.ExternalBoundary(shell))
|
|
217
|
+
shell = Topology.Slice(eb, cluster)
|
|
218
|
+
print("184, Shell", shell)
|
|
219
|
+
if not isinstance(shell, topologic.Shell):
|
|
220
|
+
try:
|
|
221
|
+
temp_wires = [Wire.RemoveCollinearEdges(w, angTolerance=1.0) for w in Topology.Wires(shell)]
|
|
222
|
+
temp_faces = [Face.ByWire(w) for w in temp_wires]
|
|
223
|
+
except:
|
|
224
|
+
temp_faces = Topology.Faces(shell)
|
|
225
|
+
shell = Shell.ByFaces(temp_faces, tolerance=tolerance)
|
|
226
|
+
if transferDictionaries == True:
|
|
227
|
+
selectors = []
|
|
228
|
+
for f in faces:
|
|
229
|
+
d = Topology.Dictionary(f)
|
|
230
|
+
s = Face.InternalVertex(f)
|
|
231
|
+
s = Topology.SetDictionary(s, d)
|
|
232
|
+
selectors.append(s)
|
|
233
|
+
_ = Topology.TransferDictionariesBySelectors(topology=shell, selectors=selectors, tranFaces=True, tolerance=tolerance)
|
|
234
|
+
return shell
|
|
235
|
+
return None
|
|
236
|
+
|
|
173
237
|
@staticmethod
|
|
174
238
|
def ByFaces(faces: list, tolerance: float = 0.0001) -> topologic.Shell:
|
|
175
239
|
"""
|