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/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
- walls = Topology.Difference(internalBoundary, facesCluster)
81
- skeleton = Wire.Skeleton(walls)
82
- skEdges = Topology.Edges(skeleton)
83
- skeleton = Topology.Difference(skeleton, facesCluster)
84
- skeleton = Topology.Difference(skeleton, Face.Wire(walls))
85
-
86
- skEdges = Topology.SelfMerge(Cluster.ByTopologies(removeShards(Topology.Edges(skeleton), skeleton, maximumGap=maximumGap)))
87
- skEdges = extendEdges(Topology.Edges(skEdges), skEdges, maximumGap=maximumGap)
88
- cluster = Cluster.ByTopologies(skEdges)
89
- shell = Topology.Slice(internalBoundary, cluster)
90
- if mergeJunctions == True:
91
- vertices = Shell.Vertices(shell)
92
- centers = []
93
- used = []
94
- for v in vertices:
95
- for w in vertices:
96
- if not Topology.IsSame(v,w) and not w in used:
97
- if Vertex.Distance(v,w) < threshold:
98
- centers.append(v)
99
- used.append(w)
100
- edges = Shell.Edges(shell)
101
- new_edges = []
102
- for e in edges:
103
- sv = Edge.StartVertex(e)
104
- ev = Edge.EndVertex(e)
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
- for y in yList:
149
- if abs(evy-y) < threshold:
150
- evy = y
151
- break;
152
- sv = Vertex.ByCoordinates(svx, svy, 0)
153
- ev = Vertex.ByCoordinates(evx, evy, 0)
154
- new_edges.append(Edge.ByVertices([sv, ev]))
155
-
156
- cluster = Cluster.ByTopologies(new_edges)
157
- ob = Face.ByWire(Shell.ExternalBoundary(shell))
158
- shell = Topology.Slice(ob, cluster)
159
- temp_wires = [Wire.RemoveCollinearEdges(w, angTolerance=1.0) for w in Topology.Wires(shell)]
160
- temp_faces = [Face.ByWire(w) for w in temp_wires]
161
- shell = Shell.ByFaces(temp_faces, tolerance=tolerance)
162
-
163
- if transferDictionaries == True:
164
- selectors = []
165
- for f in faces:
166
- d = Topology.Dictionary(f)
167
- s = Face.InternalVertex(f)
168
- s = Topology.SetDictionary(s, d)
169
- selectors.append(s)
170
- _ = Topology.TransferDictionariesBySelectors(topology=shell, selectors=selectors, tranFaces=True, tolerance=tolerance)
171
- return shell
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
  """