topologicpy 0.8.47__py3-none-any.whl → 0.8.48__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.
@@ -193,6 +193,153 @@ class CellComplex():
193
193
  cells = Topology.Cells(cluster)
194
194
  return CellComplex.ByCells(cells, tolerance=tolerance)
195
195
 
196
+ @staticmethod
197
+ def ByDisjointedFaces(faces: list,
198
+ minOffset: float = 0,
199
+ maxOffset: float = 1.0,
200
+ minCells: float = 2,
201
+ maxCells: float = 10,
202
+ maxAttempts: int = 100,
203
+ patience: int = 5,
204
+ transferDictionaries: bool = False,
205
+ exclusive: bool = True,
206
+ tolerance: float = 0.0001,
207
+ silent: bool = False):
208
+ """
209
+ Creates a CellComplex from a list of disjointed faces. The algorithm expands the faces by an offset to find intersections before building cells.
210
+
211
+ Parameters
212
+ ----------
213
+ faces : list of topologic_core.Face
214
+ The linput ist of faces.
215
+ minOffset : float , optional
216
+ The minimum initial face offset to try. Default is 0.
217
+ maxOffset : float , optional
218
+ The final maximum face offset to try. Default is 1.0.
219
+ minCells : int , optional
220
+ The minimum number of cells to create. A CellComplex cannot have less than 2 cells. Default is 2.
221
+ maxCells : int , optional
222
+ The maximum number of cells to create. Default is 10.
223
+ maxAttempts : int , optional
224
+ The desired maximum number of attempts. Default is 100.
225
+ patience : int , optional
226
+ The desired number of attempts to wait with no change in the created number of cells. Default is 5.
227
+ transferDictionaries : bool , optional
228
+ If set to True, face dictionaries are inhertied. Default is False.
229
+ exclusive : bool , optional
230
+ Applies only if transferDictionaries is set to True. If set to True, only one source face contributes its dictionary to a target face. Default is True.
231
+ tolerance : float , optional
232
+ The desired tolerance. Default is 0.0001.
233
+ silent : bool , optional
234
+ If set to True, error and warning messages are suppressed. Default is False.
235
+
236
+ Returns
237
+ -------
238
+ topologic_core.CellComplex
239
+ The created CellComplex
240
+
241
+ """
242
+
243
+ from topologicpy.Face import Face
244
+ from topologicpy.Cell import Cell
245
+ from topologicpy.Topology import Topology
246
+ from topologicpy.Helper import Helper
247
+
248
+ def trim(cells, n):
249
+ volumes = [Cell.Volume(c) for c in cells]
250
+ return_cc = Helper.Sort(cells, volumes)
251
+ return_cc.reverse()
252
+ return return_cc[:n]
253
+
254
+ faces = [f for f in faces if Topology.IsInstance(f, "Face")]
255
+ if len(faces) == 0:
256
+ if not silent:
257
+ print("CellComplex.ByDisjointedFaces - Error: The input list of faces does not contain any valid topologic faces. Returning None.")
258
+ return None
259
+ if len(faces) < 3:
260
+ if not silent:
261
+ print("CellComplex.ByDisjointedFaces - Error: The input list of faces contains less than three topologic faces. Returning None.")
262
+ return None
263
+ if minOffset < 0:
264
+ if not silent:
265
+ print("CellComplex.ByDisjointedFaces - Error: The input minOffset parameter is less than 0. Returning None.")
266
+ return None
267
+ if minOffset > maxOffset:
268
+ if not silent:
269
+ print("CellComplex.ByDisjointedFaces - Error: The input minOffset parameter is greater than the input maxOffset parameter. Returning None.")
270
+ return None
271
+ if minCells < 2:
272
+ if not silent:
273
+ print("CellComplex.ByDisjointedFaces - Error: The input minCells parameter is less than 2. Returning None.")
274
+ return None
275
+ if minCells > maxCells:
276
+ if not silent:
277
+ print("CellComplex.ByDisjointedFaces - Error: The input minCells parameter is greater than the input maxCells parameter. Returning None.")
278
+ return None
279
+ if maxAttempts <= 0:
280
+ if not silent:
281
+ print("CellComplex.ByDisjointedFaces - Error: The input maxAttempts parameter is not greater than 0. Returning None.")
282
+ return None
283
+ if patience < 0:
284
+ if not silent:
285
+ print("CellComplex.ByDisjointedFaces - Error: The input patience parameter is not greater than or equal to 0. Returning None.")
286
+ return None
287
+ if patience > maxAttempts:
288
+ if not silent:
289
+ print("CellComplex.ByDisjointedFaces - Error: The input patience parameter is greater than the input maxAttempts parameter. Returning None.")
290
+ return None
291
+ cc = None
292
+ attempts = 0
293
+ increment = float(maxOffset) / float(maxAttempts)
294
+ cellComplexes = [] # List of all possible cellComplexes
295
+ patience_list = []
296
+ offset = minOffset
297
+
298
+ while attempts < maxAttempts:
299
+ expanded_faces = [Face.ByOffset(f, offset=-offset) for f in faces]
300
+ try:
301
+ cc = CellComplex.ByFaces(expanded_faces, silent=True)
302
+ if Topology.IsInstance(cc, "cellComplex"):
303
+ cells = Topology.Cells(cc)
304
+ n_cells = len(cells)
305
+ if minCells <= n_cells <= maxCells:
306
+ cellComplexes.append(cc)
307
+ elif n_cells > maxCells:
308
+ cells = trim(cells, maxCells)
309
+ try:
310
+ new_cc = CellComplex.ByCells(cells)
311
+ if Topology.IsInstance(new_cc, "CellComplex"):
312
+ cellComplexes.append(new_cc)
313
+ except:
314
+ pass
315
+ patience_list.append(n_cells)
316
+ except:
317
+ patience_list.append(0)
318
+
319
+ if len(patience_list) >= patience:
320
+ if len(set(patience_list)) == 1 and not patience_list[0] == 0:
321
+ if not silent:
322
+ print("CellComplex.ByDisjointedFaces - Warning: Ran out of patience.")
323
+ break
324
+ else:
325
+ patience_list = []
326
+ attempts += 1
327
+ offset += increment
328
+
329
+ if len(cellComplexes) == 0:
330
+ if not silent:
331
+ print("CellComplex.ByDisjointedFaces - Error: Could not create a CellComplex. Consider revising the input parameters. Returning None.")
332
+ return None
333
+ n_cells = [len(Topology.Cells(c)) for c in cellComplexes] # Get the number of cells in each cellComplex
334
+ cellComplexes = Helper.Sort(cellComplexes, n_cells) # Sort the cellComplexes by their number of cells
335
+ for cc in cellComplexes:
336
+ cells = Topology.Cells(cc)
337
+ cc = cellComplexes[-1] # Choose the last cellComplex (the one with the most number of cells)
338
+ if transferDictionaries == True:
339
+ cc_faces = Topology.Faces(cc)
340
+ cc_faces = Topology.Inherit(targets=cc_faces, sources=faces, exclusive=exclusive, tolerance=tolerance, silent=silent)
341
+ return cc
342
+
196
343
  @staticmethod
197
344
  def ByFaces(faces: list, tolerance: float = 0.0001, silent: bool = False):
198
345
  """
topologicpy/Wire.py CHANGED
@@ -870,6 +870,7 @@ class Wire():
870
870
  edges.append(e)
871
871
  else:
872
872
  if not silent:
873
+ print("Wire.ByVertices - Warning: Degenerate edge. Skipping.")
873
874
  curframe = inspect.currentframe()
874
875
  calframe = inspect.getouterframes(curframe, 2)
875
876
  print('caller name:', calframe[1][3])
@@ -885,6 +886,7 @@ class Wire():
885
886
  curframe = inspect.currentframe()
886
887
  calframe = inspect.getouterframes(curframe, 2)
887
888
  print('caller name:', calframe[1][3])
889
+
888
890
  if len(edges) < 1:
889
891
  if not silent:
890
892
  print("Wire.ByVertices - Error: The number of edges is less than 1. Returning None.")
@@ -893,9 +895,21 @@ class Wire():
893
895
  print('caller name:', calframe[1][3])
894
896
  return None
895
897
  elif len(edges) == 1:
898
+ if not silent:
899
+ print("Wire.ByVertices - Warning: The wire is made of only one edge.")
896
900
  wire = Wire.ByEdges(edges, orient=False, silent=silent)
897
901
  else:
898
902
  wire = Topology.SelfMerge(Cluster.ByTopologies(edges), tolerance=tolerance)
903
+ if Topology.IsInstance(wire, "Edge"):
904
+ wire = Wire.ByEdges([wire], orient=False, silent=silent)
905
+ # Final Check
906
+ if not Topology.IsInstance(wire, "Wire"):
907
+ if not silent:
908
+ print("Wire.ByVertices - Error: Could not create a wire. Returning None.")
909
+ curframe = inspect.currentframe()
910
+ calframe = inspect.getouterframes(curframe, 2)
911
+ print('caller name:', calframe[1][3])
912
+ return None
899
913
  return wire
900
914
 
901
915
  @staticmethod
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.47'
1
+ __version__ = '0.8.48'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topologicpy
3
- Version: 0.8.47
3
+ Version: 0.8.48
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
@@ -3,7 +3,7 @@ topologicpy/Aperture.py,sha256=wNn5miB_IrGCBYuQ18HXQYRva20dUC3id4AJCulL7to,2723
3
3
  topologicpy/BVH.py,sha256=JA4bb-9hgMfVZ_syzmSmTL3ueCq-0vMUGMPZxNcawAY,13023
4
4
  topologicpy/CSG.py,sha256=09la1-xzS9vr-WnV7tpJ0I-mkZ-XY0MRSd5iB50Nfgw,15556
5
5
  topologicpy/Cell.py,sha256=gldsBl3LnrvTRS4SnK9aAM8k_kS1aNovTjUNHxQRNKk,175319
6
- topologicpy/CellComplex.py,sha256=TOnMnhBX4eXypKjDdkyhNesEDc9yRetPSDUNIi2eqU0,60948
6
+ topologicpy/CellComplex.py,sha256=1GS2X6feo3EoapNaOoV8fcbIHVjAHvWJKu39KQy0IlM,68066
7
7
  topologicpy/Cluster.py,sha256=G49AuhJHQ1s819cB5MtVdmAGgkag19IC3dRP1ub1Wh4,58608
8
8
  topologicpy/Color.py,sha256=hzSmgBWhiuYc55RSipkQNIgGtgyhC5BqY8AakNYEK-U,24486
9
9
  topologicpy/Context.py,sha256=G3CwMvN8Jw2rnQRwB-n4MaQq_wLS0vPimbXKwsdMJ80,3055
@@ -28,11 +28,11 @@ topologicpy/Sun.py,sha256=8S6dhCKfOhUGVny-jEk87Q08anLYMB1JEBKRGCklvbQ,36670
28
28
  topologicpy/Topology.py,sha256=x6NTJ8AFIeFq3emZRT7FA_6NgNd-aavd4i9ws704AAU,470541
29
29
  topologicpy/Vector.py,sha256=pEC8YY3TeHGfGdeNgvdHjgMDwxGabp5aWjwYC1HSvMk,42236
30
30
  topologicpy/Vertex.py,sha256=0f6HouARKaCuxhdxsUEYi8T9giJycnWhQ8Cn70YILBA,84885
31
- topologicpy/Wire.py,sha256=u1q8SA5m5jtcoCTRd9cCizPo7nUOqpdtN9k_ju7QyWc,229757
31
+ topologicpy/Wire.py,sha256=zqeTR9wou18OPJOB1lCAO2ZTd3q4ugL6IBxocImIDjs,230467
32
32
  topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
33
- topologicpy/version.py,sha256=tn529OlBICnQHhkm_PSnCq9jyPIoFccHmsIrezWqemo,23
34
- topologicpy-0.8.47.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
- topologicpy-0.8.47.dist-info/METADATA,sha256=FJ5bz-y-rgUKcMp5vKMPN6_lyG9158OcT-nPhOfrXxs,10535
36
- topologicpy-0.8.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- topologicpy-0.8.47.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
- topologicpy-0.8.47.dist-info/RECORD,,
33
+ topologicpy/version.py,sha256=rQU26Jir73SrvldR5URzF8LbyF1xpXWvqr62PHMFfvg,23
34
+ topologicpy-0.8.48.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
+ topologicpy-0.8.48.dist-info/METADATA,sha256=V8Xh5XT8zuIn4oYFXkSngAurwDemSN4MiXzZ10jQvhk,10535
36
+ topologicpy-0.8.48.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ topologicpy-0.8.48.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
+ topologicpy-0.8.48.dist-info/RECORD,,