topologicpy 0.7.23__py3-none-any.whl → 0.7.26__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/ANN.py CHANGED
@@ -110,7 +110,7 @@ import numpy as np
110
110
  class _ANN(nn.Module):
111
111
  def __init__(self, input_size, hyperparameters, dataset=None):
112
112
  super(_ANN, self).__init__()
113
- self.title = hyperparameters['title']
113
+ self.title = hyperparameters.get('title', 'Untitled')
114
114
  self.task_type = hyperparameters['task_type']
115
115
  self.cross_val_type = hyperparameters['cross_val_type']
116
116
  self.k_folds = hyperparameters.get('k_folds', 5)
@@ -576,6 +576,10 @@ class ANN():
576
576
  interval = 1,
577
577
  mantissa = 6):
578
578
  """
579
+ Returns a Hyperparameters dictionary based on the input parameters.
580
+
581
+ Parameters
582
+ ----------
579
583
  title : str , optional
580
584
  The desired title for the dataset. The default is "Untitled".
581
585
  taskType : str , optional
@@ -623,6 +627,7 @@ class ANN():
623
627
  -------
624
628
  dict
625
629
  Returns a dictionary with the following keys:
630
+ 'title'
626
631
  'task_type'
627
632
  'test_ratio'
628
633
  'validation_ratio'
@@ -632,13 +637,14 @@ class ANN():
632
637
  'batch_size'
633
638
  'early_stopping'
634
639
  'patience'
635
- 'random_tate'
640
+ 'random_state'
636
641
  'cross_val_type'
637
642
  'kFolds'
638
643
  'interval'
639
644
  'mantissa'
640
645
  """
641
646
  return {
647
+ 'title': title,
642
648
  'task_type': taskType,
643
649
  'test_ratio': testRatio,
644
650
  'validation_ratio': validationRatio,
@@ -91,7 +91,7 @@ class CellComplex():
91
91
  direction=direction, placement=placement, tolerance=tolerance)
92
92
 
93
93
  @staticmethod
94
- def ByCells(cells: list, tolerance: float = 0.0001, silent: bool = False):
94
+ def ByCells(cells: list, transferDictionaries = False, tolerance: float = 0.0001, silent: bool = False):
95
95
  """
96
96
  Creates a cellcomplex by merging the input cells.
97
97
 
@@ -99,6 +99,8 @@ class CellComplex():
99
99
  ----------
100
100
  cells : list
101
101
  The list of input cells.
102
+ transferDictionaries : bool , optional
103
+ If set to True, any dictionaries in the cells are transferred to the CellComplex. Otherwise, they are not. The default is False.
102
104
  tolerance : float , optional
103
105
  The desired tolerance. The default is 0.0001.
104
106
 
@@ -108,8 +110,10 @@ class CellComplex():
108
110
  The created cellcomplex.
109
111
 
110
112
  """
113
+ from topologicpy.Vertex import Vertex
111
114
  from topologicpy.Cluster import Cluster
112
115
  from topologicpy.Topology import Topology
116
+ from topologicpy.Dictionary import Dictionary
113
117
 
114
118
  if not isinstance(cells, list):
115
119
  if not silent:
@@ -120,6 +124,7 @@ class CellComplex():
120
124
  if not silent:
121
125
  print("CellComplex.ByCells - Error: The input cells parameter does not contain any valid cells. Returning None.")
122
126
  return None
127
+ cluster = Cluster.ByTopologies(cells)
123
128
  cellComplex = None
124
129
  if len(cells) == 1:
125
130
  return topologic.CellComplex.ByCells(cells) # Hook to Core
@@ -149,6 +154,14 @@ class CellComplex():
149
154
  if not silent:
150
155
  print("CellComplex.ByCells - Warning: Resulting object contains only one cell. Returning object of type topologic_core.Cell instead of topologic_core.CellComplex.")
151
156
  return(temp_cells[0])
157
+ if transferDictionaries == True:
158
+ for temp_cell in temp_cells:
159
+ v = Topology.InternalVertex(temp_cell)
160
+ enclosing_cells = Vertex.EnclosingCell(v, cluster)
161
+ dictionaries = [Topology.Dictionary(ec) for ec in enclosing_cells]
162
+ d = Dictionary.ByMergedDictionaries(dictionaries, silent=silent)
163
+ temp_cell = Topology.SetDictionary(temp_cell, d)
164
+
152
165
  return cellComplex
153
166
 
154
167
  @staticmethod
topologicpy/Cluster.py CHANGED
@@ -143,7 +143,7 @@ class Cluster():
143
143
  return Cluster.ByTopologies(vertices)
144
144
 
145
145
  @staticmethod
146
- def ByTopologies(*args, transferDictionaries: bool = False):
146
+ def ByTopologies(*args, transferDictionaries: bool = False, silent=False):
147
147
  """
148
148
  Creates a topologic Cluster from the input list of topologies. The input can be individual topologies each as an input argument or a list of topologies stored in one input argument.
149
149
 
@@ -153,7 +153,8 @@ class Cluster():
153
153
  The list of topologies.
154
154
  transferDictionaries : bool , optional
155
155
  If set to True, the dictionaries from the input topologies are merged and transferred to the cluster. Otherwise they are not. The default is False.
156
-
156
+ silent : bool , optional
157
+ If set to True, error and warning messages are not displayed. Otherwise, they are. The default is False.
157
158
  Returns
158
159
  -------
159
160
  topologic_core.Cluster
@@ -197,7 +198,7 @@ class Cluster():
197
198
  dictionaries.append(d)
198
199
  if len(dictionaries) > 0:
199
200
  if len(dictionaries) > 1:
200
- d = Dictionary.ByMergedDictionaries(dictionaries)
201
+ d = Dictionary.ByMergedDictionaries(dictionaries, silent=silent)
201
202
  else:
202
203
  d = dictionaries[0]
203
204
  cluster = Topology.SetDictionary(cluster, d)
topologicpy/Dictionary.py CHANGED
@@ -153,7 +153,7 @@ class Dictionary():
153
153
  return topologic.Dictionary.ByKeysValues(stl_keys, stl_values) # Hook to Core
154
154
 
155
155
  @staticmethod
156
- def ByMergedDictionaries(*dictionaries):
156
+ def ByMergedDictionaries(*dictionaries, silent: bool = False):
157
157
  """
158
158
  Creates a dictionary by merging the list of input dictionaries.
159
159
 
@@ -161,6 +161,8 @@ class Dictionary():
161
161
  ----------
162
162
  dictionaries : list or comma separated dictionaries
163
163
  The input list of dictionaries to be merged.
164
+ silent : bool , optional
165
+ If set to True, error and warning messages are not displayed. Otherwise, they are. The default is False.
164
166
 
165
167
  Returns
166
168
  -------
@@ -176,13 +178,16 @@ class Dictionary():
176
178
  if isinstance(dictionaries, list):
177
179
  new_dictionaries = [d for d in dictionaries if Topology.IsInstance(d, "Dictionary")]
178
180
  if len(new_dictionaries) == 0:
179
- print("Dictionary.ByMergedDictionaries - Error: the input dictionaries parameter does not contain any valid dictionaries. Returning None.")
181
+ if not silent:
182
+ print("Dictionary.ByMergedDictionaries - Error: the input dictionaries parameter does not contain any valid dictionaries. Returning None.")
180
183
  return None
181
184
  if len(new_dictionaries) == 1:
182
- print("Dictionary.ByMergedDictionaries - Error: the input dictionaries parameter contains only one dictionary. Returning input dictionary.")
185
+ if not silent:
186
+ print("Dictionary.ByMergedDictionaries - Error: the input dictionaries parameter contains only one dictionary. Returning input dictionary.")
183
187
  return new_dictionaries[0]
184
188
  if not isinstance(new_dictionaries, list):
185
- print("Dictionary.ByMergedDictionaries - Error: The input dictionaries parameter is not a valid list. Returning None.")
189
+ if not silent:
190
+ print("Dictionary.ByMergedDictionaries - Error: The input dictionaries parameter is not a valid list. Returning None.")
186
191
  return None
187
192
  return_dictionaries = []
188
193
  for d in new_dictionaries:
@@ -191,10 +196,12 @@ class Dictionary():
191
196
  elif isinstance(d, dict):
192
197
  return_dictionaries.append(Dictionary.ByPythonDictionary(d))
193
198
  if len(return_dictionaries) == 0:
194
- print("Dictionary.ByMergedDictionaries - Error: The input dictionaries parameter does not contain valid dictionaries. Returning None.")
199
+ if not silent:
200
+ print("Dictionary.ByMergedDictionaries - Error: The input dictionaries parameter does not contain valid dictionaries. Returning None.")
195
201
  return None
196
202
  elif len(return_dictionaries) == 1:
197
- print("Dictionary.ByMergedDictionaries - Warning: The input dictionaries parameter contains only one valid dictionary. Returning that dictionary.")
203
+ if not silent:
204
+ print("Dictionary.ByMergedDictionaries - Warning: The input dictionaries parameter contains only one valid dictionary. Returning that dictionary.")
198
205
  return new_dictionaries[0]
199
206
  else:
200
207
  dictionaries = return_dictionaries
topologicpy/Edge.py CHANGED
@@ -475,6 +475,8 @@ class Edge():
475
475
  The first input edge. This edge will be extended to meet edgeB.
476
476
  edgeB : topologic_core.Edge
477
477
  The second input edge. This edge will be used to extend edgeA.
478
+ mantissa : int , optional
479
+ The desired length of the mantissa. The default is 6.
478
480
  tolerance : float , optional
479
481
  The desired tolerance. The default is 0.0001.
480
482
  silent : bool , optional
@@ -764,8 +766,8 @@ class Edge():
764
766
  The second input edge.
765
767
  mantissa : int , optional
766
768
  The desired length of the mantissa. The default is 6.
767
- angTolerance : float , optional
768
- The angular tolerance used for the test. The default is 0.1.
769
+ tolerance : float , optional
770
+ The desired tolerance. The default is 0.0001.
769
771
 
770
772
  Returns
771
773
  -------
topologicpy/Face.py CHANGED
@@ -133,6 +133,10 @@ class Face():
133
133
  return None
134
134
  dirA = Face.Normal(faceA, outputType="xyz", mantissa=3)
135
135
  dirB = Face.Normal(faceB, outputType="xyz", mantissa=3)
136
+ if dirA == None or dirB == None:
137
+ Topology.Show(faceA, faceB)
138
+ print("Face.Angle - Error: Could not compute the angle between the two input faces. Returning None.")
139
+ return None
136
140
  return round((Vector.Angle(dirA, dirB)), mantissa)
137
141
 
138
142
  @staticmethod
@@ -1684,6 +1688,7 @@ class Face():
1684
1688
  from topologicpy.Vertex import Vertex
1685
1689
  import os
1686
1690
  import warnings
1691
+
1687
1692
  try:
1688
1693
  import numpy as np
1689
1694
  except:
@@ -1703,60 +1708,64 @@ class Face():
1703
1708
  print("Face.Normal - Error: The input face parameter is not a valid face. Returning None.")
1704
1709
  return None
1705
1710
 
1706
- #vertices = Topology.Vertices(face)
1707
- v1 = Face.VertexByParameters(face, u=0, v=0)
1708
- v2 = Face.VertexByParameters(face, u=1, v=0)
1709
- v3 = Face.VertexByParameters(face, u=1, v=1)
1710
- vertices = [v1, v2, v3]
1711
- vertices = [Vertex.Coordinates(v, mantissa=mantissa) for v in vertices]
1712
-
1713
- if len(vertices) < 3:
1714
- print("Face.Normal - Error: At least three vertices are required to define a plane. Returning None.")
1715
- return None
1716
-
1717
- # Convert vertices to numpy array for easier manipulation
1718
- vertices = np.array(vertices)
1719
-
1720
- # Try to find two non-collinear edge vectors
1721
- vec1 = None
1722
- vec2 = None
1723
- for i in range(1, len(vertices)):
1724
- for j in range(i + 1, len(vertices)):
1725
- temp_vec1 = vertices[i] - vertices[0]
1726
- temp_vec2 = vertices[j] - vertices[0]
1727
- cross_product = np.cross(temp_vec1, temp_vec2)
1728
- if np.linalg.norm(cross_product) > 1e-6: # Check if the cross product is not near zero
1729
- vec1 = temp_vec1
1730
- vec2 = temp_vec2
1711
+ return_normal = None
1712
+ try:
1713
+ return_normal = list(topologic.FaceUtility.NormalAtParameters(face, 0.5, 0.5))
1714
+ except:
1715
+ vertices = Topology.Vertices(face)+Topology.Centroid(face)
1716
+ #v1 = Face.VertexByParameters(face, u=0, v=0)
1717
+ #v2 = Face.VertexByParameters(face, u=1, v=0)
1718
+ #v3 = Face.VertexByParameters(face, u=1, v=1)
1719
+ #vertices = [v1, v2, v3]
1720
+ vertices = [Vertex.Coordinates(v, mantissa=mantissa) for v in vertices]
1721
+
1722
+ if len(vertices) < 3:
1723
+ print("Face.Normal - Error: At least three vertices are required to define a plane. Returning None.")
1724
+ return None
1725
+
1726
+ # Convert vertices to numpy array for easier manipulation
1727
+ vertices = np.array(vertices)
1728
+
1729
+ # Try to find two non-collinear edge vectors
1730
+ vec1 = None
1731
+ vec2 = None
1732
+ for i in range(1, len(vertices)):
1733
+ for j in range(i + 1, len(vertices)):
1734
+ temp_vec1 = vertices[i] - vertices[0]
1735
+ temp_vec2 = vertices[j] - vertices[0]
1736
+ cross_product = np.cross(temp_vec1, temp_vec2)
1737
+ if np.linalg.norm(cross_product) > 1e-6: # Check if the cross product is not near zero
1738
+ vec1 = temp_vec1
1739
+ vec2 = temp_vec2
1740
+ break
1741
+ if vec1 is not None and vec2 is not None:
1731
1742
  break
1732
- if vec1 is not None and vec2 is not None:
1733
- break
1734
-
1735
- if vec1 is None or vec2 is None:
1736
- print("Face.Normal - Error: The given vertices do not form a valid plane (all vertices might be collinear). Returning None.")
1737
- return None
1738
-
1739
- # Calculate the cross product of the two edge vectors
1740
- normal = np.cross(vec1, vec2)
1743
+
1744
+ if vec1 is None or vec2 is None:
1745
+ print("Face.Normal - Error: The given vertices do not form a valid plane (all vertices might be collinear). Returning None.")
1746
+ return None
1747
+
1748
+ # Calculate the cross product of the two edge vectors
1749
+ normal = np.cross(vec1, vec2)
1741
1750
 
1742
- # Normalize the normal vector
1743
- normal_length = np.linalg.norm(normal)
1744
- if normal_length == 0:
1745
- print("Face.Normal - Error: The given vertices do not form a valid plane (cross product resulted in a zero vector). Returning None.")
1746
- return None
1747
-
1748
- normal = normal / normal_length
1749
- normal = normal.tolist()
1750
- normal = [round(x, mantissa) for x in normal]
1751
- return_normal = []
1752
- outputType = list(outputType.lower())
1753
- for axis in outputType:
1754
- if axis == "x":
1755
- return_normal.append(normal[0])
1756
- elif axis == "y":
1757
- return_normal.append(normal[1])
1758
- elif axis == "z":
1759
- return_normal.append(normal[2])
1751
+ # Normalize the normal vector
1752
+ normal_length = np.linalg.norm(normal)
1753
+ if normal_length == 0:
1754
+ print("Face.Normal - Error: The given vertices do not form a valid plane (cross product resulted in a zero vector). Returning None.")
1755
+ return None
1756
+
1757
+ normal = normal / normal_length
1758
+ normal = normal.tolist()
1759
+ normal = [round(x, mantissa) for x in normal]
1760
+ return_normal = []
1761
+ outputType = list(outputType.lower())
1762
+ for axis in outputType:
1763
+ if axis == "x":
1764
+ return_normal.append(normal[0])
1765
+ elif axis == "y":
1766
+ return_normal.append(normal[1])
1767
+ elif axis == "z":
1768
+ return_normal.append(normal[2])
1760
1769
  return return_normal
1761
1770
 
1762
1771
  @staticmethod
topologicpy/Graph.py CHANGED
@@ -158,7 +158,7 @@ class WorkerProcess(Process):
158
158
  continue
159
159
  if Vertex.Distance(source, destination) > self.tolerance:
160
160
  edge = Edge.ByVertices([source, destination])
161
- e = Topology.Boolean(edge, face, operation="intersect")
161
+ e = Topology.Intersect(edge, face)
162
162
  if Topology.IsInstance(e, "Edge"):
163
163
  edges.append(edge)
164
164
  self.used[i + self.start_index][j] = 1
topologicpy/Topology.py CHANGED
@@ -24,6 +24,9 @@ import math
24
24
  from collections import namedtuple
25
25
  from multiprocessing import Process, Queue
26
26
 
27
+ # This is for View3D as not to open new browser windows
28
+ opened_urls = set()
29
+
27
30
  try:
28
31
  import numpy as np
29
32
  from numpy import arctan, pi, signbit
@@ -968,18 +971,44 @@ class Topology():
968
971
  results = []
969
972
  if Topology.IsInstance(topologyA, "CellComplex"):
970
973
  cellsA = Topology.Cells(topologyA)
974
+ elif Topology.IsInstance(topologyA, "Cluster"):
975
+ cellsA = Cluster.FreeTopologies(topologyA)
971
976
  else:
972
977
  cellsA = [topologyA]
973
- for cellA in cellsA:
974
- if Topology.IsInstance(topologyB, "CellComplex"):
978
+ if Topology.IsInstance(topologyB, "CellComplex"):
975
979
  cellsB = Topology.Cells(topologyB)
980
+ elif Topology.IsInstance(topologyB, "Cluster"):
981
+ cellsB = Cluster.FreeTopologies(topologyB)
982
+ else:
983
+ cellsB = [topologyB]
984
+ cellsA_2 = []
985
+ cellsB_2 = []
986
+ for cellA in cellsA:
987
+ if Topology.IsInstance(cellA, "CellComplex"):
988
+ cellsA_2 += Topology.Cells(cellA)
989
+ elif Topology.IsInstance(cellA, "Shell"):
990
+ cellsA_2 += Topology.Faces(cellA)
991
+ else:
992
+ cellsA_2.append(cellA)
993
+
994
+ for cellB in cellsB:
995
+ if Topology.IsInstance(cellB, "CellComplex"):
996
+ cellsB_2 += Topology.Cells(cellB)
997
+ elif Topology.IsInstance(cellB, "Shell"):
998
+ cellsB_2 += Topology.Faces(cellB)
976
999
  else:
977
- cellsB = [topologyB]
978
- for cellB in cellsB:
1000
+ cellsB_2.append(cellB)
1001
+
1002
+ print("cellsA_2", cellsA_2)
1003
+ print("cellsB_2", cellsB_2)
1004
+ for cellA in cellsA_2:
1005
+ for cellB in cellsB_2:
979
1006
  cellC = cellA.Intersect(cellB)
980
1007
  results.append(cellC)
981
- results = [x for x in results if results is not None]
982
- if len(results) == 1:
1008
+ results = [x for x in results if x is not None]
1009
+ if len(results) == 0:
1010
+ return None
1011
+ elif len(results) == 1:
983
1012
  return results[0]
984
1013
  else:
985
1014
  return Topology.SelfMerge(Topology.SelfMerge(Cluster.ByTopologies(results)))
@@ -2443,7 +2472,6 @@ class Topology():
2443
2472
 
2444
2473
  def buildCell(json_item, j_shells, j_faces, j_wires, j_edges, j_vertices, uuidKey="uuid", tolerance=0.0001):
2445
2474
  cell_shells = json_item['shells']
2446
- shells = []
2447
2475
  external_boundary = buildShell(find_json_item(j_shells, uuidKey, cell_shells[0]), j_faces, j_wires, j_edges, j_vertices, uuidKey=uuidKey, tolerance=tolerance)
2448
2476
  internal_boundaries = []
2449
2477
  for j_s in cell_shells[1:]:
@@ -2468,7 +2496,7 @@ class Topology():
2468
2496
  cells = []
2469
2497
  for j_c in cc_cells:
2470
2498
  cells.append(buildCell(find_json_item(j_cells, uuidKey, j_c), j_shells, j_faces, j_wires, j_edges, j_vertices, uuidKey=uuidKey, tolerance=tolerance))
2471
- cc = CellComplex.ByCells(cells, tolerance=tolerance)
2499
+ cc = CellComplex.ByCells(cells, transferDictionaries=False, silent=True, tolerance=tolerance)
2472
2500
  if cc == None:
2473
2501
  print("Topology.ByJSONString - Error: Could not build a cellcomplex. Returning None.")
2474
2502
  return None
@@ -2645,18 +2673,10 @@ class Topology():
2645
2673
  d = Topology.Dictionary(ev)
2646
2674
  if Dictionary.ValueAtKey(d,'toplevel') == True:
2647
2675
  toplevelTopologies.append(ev)
2648
-
2676
+ return_topologies = []
2649
2677
  for tp in toplevelTopologies:
2650
2678
  # This is a hack because sometimes the imported topologies get weird. I think it is an opencascade bug.
2651
2679
  tp = Topology.ByBREPString(Topology.BREPString(tp))
2652
- if len(vertex_selectors) > 0:
2653
- _ = Topology.TransferDictionariesBySelectors(tp, vertex_selectors, tranVertices=True, tolerance=tolerance)
2654
- if len(edge_selectors) > 0:
2655
- _ = Topology.TransferDictionariesBySelectors(tp, edge_selectors, tranEdges=True, tolerance=tolerance)
2656
- if len(face_selectors) > 0:
2657
- _ = Topology.TransferDictionariesBySelectors(tp, face_selectors, tranFaces=True, tolerance=tolerance)
2658
- if len(cell_selectors) > 0:
2659
- _ = Topology.TransferDictionariesBySelectors(tp, cell_selectors, tranCells=True, tolerance=tolerance)
2660
2680
  if len(all_vertex_apertures) > 0:
2661
2681
  tp_vertices = Topology.Vertices(tp)
2662
2682
  for tp_vertex in tp_vertices:
@@ -2673,11 +2693,22 @@ class Topology():
2673
2693
  tp_cells = Topology.Cells(tp)
2674
2694
  for tp_cell in tp_cells:
2675
2695
  tp_cell = setApertures(tp_cell, all_cell_apertures, uuidKey="uuid")
2676
-
2677
- if len(toplevelTopologies) == 1:
2678
- return toplevelTopologies[0]
2696
+
2697
+ if len(vertex_selectors) > 0:
2698
+ _ = Topology.TransferDictionariesBySelectors(tp, vertex_selectors, tranVertices=True, tolerance=tolerance)
2699
+ if len(edge_selectors) > 0:
2700
+ _ = Topology.TransferDictionariesBySelectors(tp, edge_selectors, tranEdges=True, tolerance=tolerance)
2701
+ if len(face_selectors) > 0:
2702
+ _ = Topology.TransferDictionariesBySelectors(tp, face_selectors, tranFaces=True, tolerance=tolerance)
2703
+ if len(cell_selectors) > 0:
2704
+ _ = Topology.TransferDictionariesBySelectors(tp, cell_selectors, tranCells=True, tolerance=tolerance)
2705
+
2706
+ return_topologies.append(tp)
2707
+
2708
+ if len(return_topologies) == 1:
2709
+ return return_topologies[0]
2679
2710
  else:
2680
- return toplevelTopologies
2711
+ return return_topologies
2681
2712
 
2682
2713
  @staticmethod
2683
2714
  def ByJSONPath(path, tolerance=0.0001):
@@ -2711,7 +2742,7 @@ class Topology():
2711
2742
  defaultOpacity: float = 1.0,
2712
2743
  transposeAxes: bool = True,
2713
2744
  removeCoplanarFaces: bool = True,
2714
-
2745
+ selfMerge: bool = True,
2715
2746
  mantissa : int = 6,
2716
2747
  tolerance: float = 0.0001):
2717
2748
  """
@@ -2732,6 +2763,8 @@ class Topology():
2732
2763
  If set to True the Z and Y axes are transposed. Otherwise, they are not. The default is True.
2733
2764
  removeCoplanarFaces : bool , optional
2734
2765
  If set to True, coplanar faces are merged. The default is True.
2766
+ selfMerge : bool , optional
2767
+ If set to True, the faces of the imported topologies will each be self-merged to create higher-dimensional objects. Otherwise, they remain a cluster of faces. The default is False.
2735
2768
  mantissa : int , optional
2736
2769
  The desired length of the mantissa. The default is 6.
2737
2770
  tolerance : float , optional
@@ -2761,12 +2794,14 @@ class Topology():
2761
2794
  return Topology.ByOBJString(obj_string, mtl_string,
2762
2795
  defaultColor=defaultColor, defaultOpacity=defaultOpacity,
2763
2796
  transposeAxes=transposeAxes, removeCoplanarFaces=removeCoplanarFaces,
2797
+ selfMerge=selfMerge,
2764
2798
  mantissa=mantissa, tolerance=tolerance)
2765
2799
 
2766
2800
  @staticmethod
2767
2801
  def ByOBJPath(objPath,
2768
2802
  defaultColor: list = [255,255,255], defaultOpacity: float = 1.0,
2769
2803
  transposeAxes: bool = True, removeCoplanarFaces: bool = True,
2804
+ selfMerge: bool = False,
2770
2805
  mantissa : int = 6, tolerance: float = 0.0001):
2771
2806
  """
2772
2807
  Imports a topology from an OBJ file path and an associated materials file.
@@ -2784,6 +2819,8 @@ class Topology():
2784
2819
  If set to True the Z and Y axes are transposed. Otherwise, they are not. The default is True.
2785
2820
  removeCoplanarFaces : bool , optional
2786
2821
  If set to True, coplanar faces are merged. The default is True.
2822
+ selfMerge : bool , optional
2823
+ If set to True, the faces of the imported topologies will each be self-merged to create higher-dimensional objects. Otherwise, they remain a cluster of faces. The default is False.
2787
2824
  mantissa : int , optional
2788
2825
  The desired length of the mantissa. The default is 6.
2789
2826
  tolerance : float , optional
@@ -2824,12 +2861,14 @@ class Topology():
2824
2861
  return Topology.ByOBJString(obj_string, mtl_string,
2825
2862
  defaultColor=defaultColor, defaultOpacity=defaultOpacity,
2826
2863
  transposeAxes=transposeAxes, removeCoplanarFaces=removeCoplanarFaces,
2864
+ selfMerge = selfMerge,
2827
2865
  mantissa=mantissa, tolerance=tolerance)
2828
2866
 
2829
2867
  @staticmethod
2830
2868
  def ByOBJString(objString: str, mtlString: str = None,
2831
2869
  defaultColor: list = [255,255,255], defaultOpacity: float = 1.0,
2832
2870
  transposeAxes: bool = True, removeCoplanarFaces: bool = False,
2871
+ selfMerge: bool = False,
2833
2872
  mantissa = 6, tolerance = 0.0001):
2834
2873
  """
2835
2874
  Imports a topology from OBJ and MTL strings.
@@ -2848,6 +2887,8 @@ class Topology():
2848
2887
  If set to True the Z and Y axes are transposed. Otherwise, they are not. The default is True.
2849
2888
  removeCoplanarFaces : bool , optional
2850
2889
  If set to True, coplanar faces are merged. The default is True.
2890
+ selfMerge : bool , optional
2891
+ If set to True, the faces of the imported topologies will each be self-merged to create higher-dimensional objects. Otherwise, they remain a cluster of faces. The default is False.
2851
2892
  mantissa : int , optional
2852
2893
  The desired length of the mantissa. The default is 6.
2853
2894
  tolerance : float , optional
@@ -2994,7 +3035,9 @@ class Topology():
2994
3035
  selector = Topology.SetDictionary(selector, d)
2995
3036
  face_selectors.append(selector)
2996
3037
 
2997
- topology = Topology.SelfMerge(Cluster.ByTopologies(object_faces), tolerance=tolerance)
3038
+ topology = Cluster.ByTopologies(object_faces, tolerance=tolerance)
3039
+ if selfMerge:
3040
+ topology = Topology.SelfMerge(topology)
2998
3041
  if removeCoplanarFaces:
2999
3042
  topology = Topology.RemoveCoplanarFaces(topology, tolerance=tolerance)
3000
3043
  d = Dictionary.ByKeysValues(['name', 'color', 'opacity'], [object_name, object_color, object_opacity])
@@ -4672,7 +4715,7 @@ class Topology():
4672
4715
  return json_string
4673
4716
 
4674
4717
  @staticmethod
4675
- def OBJString(topology, color, vertexIndex, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
4718
+ def _OBJString(topology, color, vertexIndex, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
4676
4719
  """
4677
4720
  Returns the Wavefront string of the input topology. This is very experimental and outputs a simple solid topology.
4678
4721
 
@@ -4743,6 +4786,7 @@ class Topology():
4743
4786
  finalLines = finalLines + "\n" + lines[i]
4744
4787
  return finalLines, len(vertices)
4745
4788
 
4789
+
4746
4790
  @staticmethod
4747
4791
  def ExportToOBJ(*topologies, path, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, overwrite: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
4748
4792
  """
@@ -4795,7 +4839,6 @@ class Topology():
4795
4839
 
4796
4840
  """
4797
4841
  from topologicpy.Helper import Helper
4798
- from topologicpy.Dictionary import Dictionary
4799
4842
  from os.path import exists
4800
4843
 
4801
4844
  if isinstance(topologies, tuple):
@@ -4806,7 +4849,7 @@ class Topology():
4806
4849
  print("Topology.ExportToOBJ - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
4807
4850
  return None
4808
4851
  if not isinstance(new_topologies, list):
4809
- print("Dictionary.ByMergedDictionaries - Error: The input dictionaries parameter is not a valid list. Returning None.")
4852
+ print("Topology.ExportToOBJ - Error: The input topologies parameter is not a valid list. Returning None.")
4810
4853
  return None
4811
4854
 
4812
4855
  if not overwrite and exists(path):
@@ -4820,39 +4863,126 @@ class Topology():
4820
4863
  status = False
4821
4864
 
4822
4865
  mtl_path = path[:-4] + ".mtl"
4823
-
4866
+
4867
+ obj_string, mtl_string = Topology.OBJString(new_topologies,
4868
+ nameKey=nameKey,
4869
+ colorKey=colorKey,
4870
+ opacityKey=opacityKey,
4871
+ defaultColor=defaultColor,
4872
+ defaultOpacity=defaultOpacity,
4873
+ transposeAxes=transposeAxes,
4874
+ mode=mode,
4875
+ meshSize=meshSize,
4876
+ mantissa=mantissa,
4877
+ tolerance=tolerance)
4824
4878
  # Write out the material file
4825
- n = max(len(str(len(topologies))), 3)
4826
4879
  with open(mtl_path, "w") as mtl_file:
4827
- for i in range(len(new_topologies)):
4828
- d = Topology.Dictionary(new_topologies[i])
4829
- name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4830
- color = Dictionary.ValueAtKey(d, colorKey) or defaultColor
4831
- color = [c/255 for c in color]
4832
- opacity = Dictionary.ValueAtKey(d, opacityKey) or defaultOpacity
4833
- mtl_file.write("newmtl color_" + str(i).zfill(n) + "\n")
4834
- mtl_file.write("Kd " + ' '.join(map(str, color)) + "\n")
4835
- mtl_file.write("d " + str(opacity) + "\n")
4836
-
4880
+ mtl_file.write(mtl_string)
4837
4881
  # Write out the obj file
4838
4882
  with open(path, "w") as obj_file:
4839
- vertex_index = 1 # global vertex index counter
4840
- obj_file.writelines("# topologicpy "+Helper.Version()+"\n")
4841
- obj_file.writelines("mtllib " + mtl_path.split('/')[-1]) # reference the MTL file
4842
- for i in range(len(topologies)):
4843
- d = Topology.Dictionary(topologies[i])
4844
- name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4845
- name = name.replace(" ", "_")
4846
- obj_file.writelines("\ng "+name+"\n")
4847
- result = Topology.OBJString(topologies[i], "color_" + str(i).zfill(n), vertex_index, transposeAxes=transposeAxes, mode=mode,
4848
- meshSize=meshSize,
4849
- mantissa=mantissa, tolerance=tolerance)
4850
-
4851
- obj_file.writelines(result[0])
4852
- vertex_index += result[1]
4853
- obj_file.close()
4854
- status = True
4855
- return status
4883
+ obj_file.write(obj_string)
4884
+ return True
4885
+
4886
+ @staticmethod
4887
+ def OBJString(*topologies, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
4888
+ """
4889
+ Exports the input topology to a Wavefront OBJ file. This is very experimental and outputs a simple solid topology.
4890
+
4891
+ Parameters
4892
+ ----------
4893
+ topologies : list or comma separated topologies
4894
+ The input list of topologies.
4895
+ path : str
4896
+ The input file path.
4897
+ nameKey : str , optional
4898
+ The topology dictionary key under which to find the name of the topology. The default is "name".
4899
+ colorKey : str, optional
4900
+ The topology dictionary key under which to find the color of the topology. The default is "color".
4901
+ opacityKey : str , optional
4902
+ The topology dictionary key under which to find the opacity of the topology. The default is "opacity".
4903
+ defaultColor : list , optional
4904
+ The default color to use if no color is stored in the topology dictionary. The default is [255,255, 255] (white).
4905
+ defaultOpacity : float , optional
4906
+ The default opacity to use of no opacity is stored in the topology dictionary. This must be between 0 and 1. The default is 1 (fully opaque).
4907
+ transposeAxes : bool , optional
4908
+ If set to True the Z and Y coordinates are transposed so that Y points "up"
4909
+ mode : int , optional
4910
+ The desired mode of meshing algorithm (for triangulation). Several options are available:
4911
+ 0: Classic
4912
+ 1: MeshAdapt
4913
+ 3: Initial Mesh Only
4914
+ 5: Delaunay
4915
+ 6: Frontal-Delaunay
4916
+ 7: BAMG
4917
+ 8: Fontal-Delaunay for Quads
4918
+ 9: Packing of Parallelograms
4919
+ All options other than 0 (Classic) use the gmsh library. See https://gmsh.info/doc/texinfo/gmsh.html#Mesh-options
4920
+ WARNING: The options that use gmsh can be very time consuming and can create very heavy geometry.
4921
+ meshSize : float , optional
4922
+ The desired size of the mesh when using the "mesh" option. If set to None, it will be
4923
+ calculated automatically and set to 10% of the overall size of the face.
4924
+ mantissa : int , optional
4925
+ The desired length of the mantissa. The default is 6.
4926
+ tolerance : float , optional
4927
+ The desired tolerance. The default is 0.0001.
4928
+ overwrite : bool , optional
4929
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
4930
+
4931
+ Returns
4932
+ -------
4933
+ list
4934
+ Return the OBJ and MTL strings as a list.
4935
+
4936
+ """
4937
+ from topologicpy.Helper import Helper
4938
+ from topologicpy.Dictionary import Dictionary
4939
+ import io
4940
+
4941
+ obj_file = io.StringIO()
4942
+ mtl_file = io.StringIO()
4943
+
4944
+ if isinstance(topologies, tuple):
4945
+ topologies = Helper.Flatten(list(topologies))
4946
+ if isinstance(topologies, list):
4947
+ new_topologies = [d for d in topologies if Topology.IsInstance(d, "Topology")]
4948
+ if len(new_topologies) == 0:
4949
+ print("Topology.OBJString - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
4950
+ return None
4951
+ if not isinstance(new_topologies, list):
4952
+ print("Topology.OBJString - Error: The input dictionaries parameter is not a valid list. Returning None.")
4953
+ return None
4954
+
4955
+ # Write out the material file
4956
+ n = max(len(str(len(topologies))), 3)
4957
+ for i in range(len(new_topologies)):
4958
+ d = Topology.Dictionary(new_topologies[i])
4959
+ name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4960
+ color = Dictionary.ValueAtKey(d, colorKey) or defaultColor
4961
+ color = [c/255 for c in color]
4962
+ opacity = Dictionary.ValueAtKey(d, opacityKey) or defaultOpacity
4963
+ mtl_file.write("newmtl color_" + str(i).zfill(n) + "\n")
4964
+ mtl_file.write("Kd " + ' '.join(map(str, color)) + "\n")
4965
+ mtl_file.write("d " + str(opacity) + "\n")
4966
+
4967
+ vertex_index = 1 # global vertex index counter
4968
+ obj_file.writelines("# topologicpy "+Helper.Version()+"\n")
4969
+ obj_file.writelines("mtllib example.mtl")
4970
+ for i in range(len(topologies)):
4971
+ d = Topology.Dictionary(topologies[i])
4972
+ name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
4973
+ name = name.replace(" ", "_")
4974
+ obj_file.writelines("\ng "+name+"\n")
4975
+ result = Topology._OBJString(topologies[i], "color_" + str(i).zfill(n), vertex_index, transposeAxes=transposeAxes, mode=mode,
4976
+ meshSize=meshSize,
4977
+ mantissa=mantissa, tolerance=tolerance)
4978
+
4979
+ obj_file.writelines(result[0])
4980
+ vertex_index += result[1]
4981
+ obj_string = obj_file.getvalue()
4982
+ mtl_string = mtl_file.getvalue()
4983
+ obj_file.close()
4984
+ mtl_file.close()
4985
+ return obj_string, mtl_string
4856
4986
 
4857
4987
  @staticmethod
4858
4988
  def Filter(topologies, topologyType="any", searchType="any", key=None, value=None):
@@ -7599,6 +7729,10 @@ class Topology():
7599
7729
  The input topology with the dictionaries transferred to its subtopologies.
7600
7730
 
7601
7731
  """
7732
+ from topologicpy.Vertex import Vertex
7733
+ from topologicpy.Dictionary import Dictionary
7734
+ from topologicpy.Cluster import Cluster
7735
+ from topologicpy.Plotly import Plotly
7602
7736
  if not Topology.IsInstance(topology, "Topology"):
7603
7737
  print("Topology.TransferDictionariesBySelectors - Error: The input topology parameter is not a valid topology. Returning None.")
7604
7738
  return None
@@ -7639,10 +7773,11 @@ class Topology():
7639
7773
  _ = Topology.TransferDictionaries(selectors, sinkFaces, tolerance=tolerance, numWorkers=numWorkers)
7640
7774
  if tranCells == True:
7641
7775
  sinkCells = []
7642
- if Topology.Type(topology) == Topology.TypeID("Cell"):
7643
- sinkCells.append(topology)
7776
+ if Topology.IsInstance(topology, "Cell"):
7777
+ sinkCells = [topology]
7644
7778
  elif hidimSink >= Topology.TypeID("Cell"):
7645
- topology.Cells(None, sinkCells)
7779
+ print("Transfering Dictionaries to Cells")
7780
+ sinkCells = Topology.Cells(topology)
7646
7781
  _ = Topology.TransferDictionaries(selectors, sinkCells, tolerance=tolerance, numWorkers=numWorkers)
7647
7782
  return topology
7648
7783
 
@@ -7984,4 +8119,105 @@ class Topology():
7984
8119
  predefined_namespace_dns = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
7985
8120
  namespace_uuid = uuid.uuid5(predefined_namespace_dns, namespace)
7986
8121
  brep_string = Topology.BREPString(topology)
7987
- return uuid.uuid5(namespace_uuid, brep_string)
8122
+ return uuid.uuid5(namespace_uuid, brep_string)
8123
+
8124
+ @staticmethod
8125
+ def View3D(*topologies, uuid = None, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, overwrite: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
8126
+ """
8127
+ Sends the input topologies to 3dviewer.net. The topologies must be 3D meshes.
8128
+
8129
+ Parameters
8130
+ ----------
8131
+ topologies : list or comma separated topologies
8132
+ The input list of topologies.
8133
+ uuid : UUID , optional
8134
+ The UUID v5 to use to identify these topologies. The default is a UUID based on the topologies themselves.
8135
+ nameKey : str , optional
8136
+ The topology dictionary key under which to find the name of the topology. The default is "name".
8137
+ colorKey : str, optional
8138
+ The topology dictionary key under which to find the color of the topology. The default is "color".
8139
+ opacityKey : str , optional
8140
+ The topology dictionary key under which to find the opacity of the topology. The default is "opacity".
8141
+ defaultColor : list , optional
8142
+ The default color to use if no color is stored in the topology dictionary. The default is [255,255, 255] (white).
8143
+ defaultOpacity : float , optional
8144
+ The default opacity to use of no opacity is stored in the topology dictionary. This must be between 0 and 1. The default is 1 (fully opaque).
8145
+ transposeAxes : bool , optional
8146
+ If set to True the Z and Y coordinates are transposed so that Y points "up"
8147
+ mode : int , optional
8148
+ The desired mode of meshing algorithm (for triangulation). Several options are available:
8149
+ 0: Classic
8150
+ 1: MeshAdapt
8151
+ 3: Initial Mesh Only
8152
+ 5: Delaunay
8153
+ 6: Frontal-Delaunay
8154
+ 7: BAMG
8155
+ 8: Fontal-Delaunay for Quads
8156
+ 9: Packing of Parallelograms
8157
+ All options other than 0 (Classic) use the gmsh library. See https://gmsh.info/doc/texinfo/gmsh.html#Mesh-options
8158
+ WARNING: The options that use gmsh can be very time consuming and can create very heavy geometry.
8159
+ meshSize : float , optional
8160
+ The desired size of the mesh when using the "mesh" option. If set to None, it will be
8161
+ calculated automatically and set to 10% of the overall size of the face.
8162
+ mantissa : int , optional
8163
+ The desired length of the mantissa. The default is 6.
8164
+ tolerance : float , optional
8165
+ The desired tolerance. The default is 0.0001.
8166
+ overwrite : bool , optional
8167
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
8168
+
8169
+ Returns
8170
+ -------
8171
+ bool
8172
+ True if the export operation is successful. False otherwise.
8173
+
8174
+ """
8175
+ from topologicpy.Helper import Helper
8176
+ from topologicpy.Cluster import Cluster
8177
+ import requests
8178
+ import webbrowser
8179
+
8180
+ if isinstance(topologies, tuple):
8181
+ topologies = Helper.Flatten(list(topologies))
8182
+ if isinstance(topologies, list):
8183
+ new_topologies = [d for d in topologies if Topology.IsInstance(d, "Topology")]
8184
+ if len(new_topologies) == 0:
8185
+ print("Topology.View3D - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
8186
+ return None
8187
+ if not isinstance(new_topologies, list):
8188
+ print("Topology.View3D - Error: The input topologies parameter is not a valid list. Returning None.")
8189
+ return None
8190
+
8191
+ if uuid == None:
8192
+ cluster = Cluster.ByTopologies(new_topologies)
8193
+ uuid = Topology.UUID(cluster)
8194
+ obj_string, mtl_string = Topology.OBJString(new_topologies,
8195
+ nameKey=nameKey,
8196
+ colorKey=colorKey,
8197
+ opacityKey=opacityKey,
8198
+ defaultColor=defaultColor,
8199
+ defaultOpacity=defaultOpacity,
8200
+ transposeAxes=transposeAxes,
8201
+ mode=mode,
8202
+ meshSize=meshSize,
8203
+ mantissa=mantissa,
8204
+ tolerance=tolerance)
8205
+
8206
+
8207
+ file_contents = {}
8208
+ file_contents['example.obj'] = obj_string
8209
+ file_contents['example.mtl'] = mtl_string
8210
+
8211
+ try:
8212
+ response = requests.post('https://3dviewer.deno.dev/upload/'+str(uuid), files=file_contents)
8213
+ if response.status_code != 200:
8214
+ print(f'Failed to upload file(s): {response.status_code} {response.reason}')
8215
+ # Open the web page in the default web browser
8216
+ # URL of the web page you want to open
8217
+ url = "https://3dviewer.deno.dev/#channel="+str(uuid)
8218
+ if not url in opened_urls:
8219
+ opened_urls.add(url)
8220
+ webbrowser.open(url)
8221
+ except requests.exceptions.RequestException as e:
8222
+ print(f'Error uploading file(s): {e}')
8223
+ return True
topologicpy/Vector.py CHANGED
@@ -77,6 +77,12 @@ class Vector(list):
77
77
  The angle in degrees between the two input vectors.
78
78
 
79
79
  """
80
+ if vectorA == None:
81
+ print("Vector.Angle - Error: The input vectorA is None. Returning None.")
82
+ return None
83
+ if vectorB == None:
84
+ print("Vector.Angle - Error: The input vectorB is None. Returning None.")
85
+ return None
80
86
  n_v1=la.norm(vectorA)
81
87
  n_v2=la.norm(vectorB)
82
88
  if n_v1 == 0 or n_v2 == 0:
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.23'
1
+ __version__ = '0.7.26'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.23
3
+ Version: 0.7.26
4
4
  Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: MIT License
@@ -1,16 +1,16 @@
1
- topologicpy/ANN.py,sha256=CLK6kPV28ag-hc60pyqoXt4GPiYQDUL8N48tjAbZ9Do,48981
1
+ topologicpy/ANN.py,sha256=A7k3RZ6rVccLLzJhQMz_5xaDUnLJDgJMQTtnG_Bsc-s,49166
2
2
  topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
3
  topologicpy/Cell.py,sha256=NjcKAqZywkr7DouYP4MGLhG6grWrXYfEpzDgUN-qAC0,99802
4
- topologicpy/CellComplex.py,sha256=-f-O5lcz0nSNcjw89XYi3IYhZRrbzojG11dItpISI_U,47401
5
- topologicpy/Cluster.py,sha256=6ZKtS82E2gCkX3oQKbx_aYL1GDiLYkleQbWWK5wYP7U,54815
4
+ topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
5
+ topologicpy/Cluster.py,sha256=mwQVNXnh20VHms0ZqPzTROP8bUdVt8CTKtaNobAqHsE,54993
6
6
  topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
7
7
  topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
8
8
  topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
9
- topologicpy/Dictionary.py,sha256=R6dqA2hqJX5t8faZmXCen8Cn3ukJ8VCHkyk-bune7-E,26770
10
- topologicpy/Edge.py,sha256=QHXb0R9bdPHfHhi64rXrCeeFoLv8iaMeBxqvocBm1XI,58327
9
+ topologicpy/Dictionary.py,sha256=4VtIT1p4UHWButzRUnajj16V0DY-d5RaENbXLNTbCYU,27097
10
+ topologicpy/Edge.py,sha256=H5UVhdQ9hjBdipx0AL6U8XQXula_1pBajFB_JI_LIak,58409
11
11
  topologicpy/EnergyModel.py,sha256=ni0H1JgvLl1-q90yK9Sm1qj5P1fTuidlimEIcwuj6qE,53287
12
- topologicpy/Face.py,sha256=XS2ODccQRQvIdeuKAydjyAJmNqkwm8-RJJ5M1l4gt68,109523
13
- topologicpy/Graph.py,sha256=eKGKgfXFeTHOuKUTVfCjuRcHZLElE-nNNWhaJ2eZ4LM,391684
12
+ topologicpy/Face.py,sha256=gJNOzaTBxMcd71A-FAzQ3sQFKbsL35cpkGzgtNu6tmo,110131
13
+ topologicpy/Graph.py,sha256=rYUhw7XP6LVogbIZfAsrYEZoilN1BabloZHdcWskrMo,391663
14
14
  topologicpy/Grid.py,sha256=Q-2WNBkvIsJks7pbGkzzkRWVB4fTMYgWipG3lcDXbpE,18496
15
15
  topologicpy/Helper.py,sha256=mLwJmhyc-d-JqW82MBf7JwM91zWHVx8RzOmndPWHm-k,17717
16
16
  topologicpy/Honeybee.py,sha256=vcBECJlgWVjNNdD9ZmjNik_pA1Y_ZNoOorsQb2CiyGA,21965
@@ -21,14 +21,14 @@ topologicpy/Polyskel.py,sha256=4R5_DEdfrmi-4gR6axHNoHTCSAE2TCekOyN8jvb7bHQ,19722
21
21
  topologicpy/Shell.py,sha256=szuwRbQeHH9jd2X-DA9UhYAL_mzgfr_ctGrrQL2reWg,79917
22
22
  topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
23
23
  topologicpy/Sun.py,sha256=_gZfVyH0SDLQmmt775UeeAJ_BtwXO1STQnUMV1qkU0s,37161
24
- topologicpy/Topology.py,sha256=EAu5bQl69c1n5KkJE1V2bapeEQsaCDL-ms0r-KzM35w,349215
25
- topologicpy/Vector.py,sha256=JAIeOZplh7sQD46K4eP3gMgvK6iB1wwpZ0sC9-FFGq8,32803
24
+ topologicpy/Topology.py,sha256=PkuCetAUADmEuu17-R19ACoub7iZijA8S_v3t0YLL3s,361467
25
+ topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
26
26
  topologicpy/Vertex.py,sha256=deOrCOvvGJYAludUE4Tm_L4Bx0ykQzO_ddnYSrUzsBs,71157
27
27
  topologicpy/Wire.py,sha256=_-0s6lFCStTGEjK5M-_w79UCQoPVFH1Ou8PdH_urvT0,145180
28
28
  topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
29
- topologicpy/version.py,sha256=N6Bti6avPpwylwTGFsJIizCk0diNen56ql7y-MCAT6U,23
30
- topologicpy-0.7.23.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
31
- topologicpy-0.7.23.dist-info/METADATA,sha256=Km1K1jcxZhheChH715Z3gtb76475mzJZtqu-aJm2Y78,10916
32
- topologicpy-0.7.23.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
33
- topologicpy-0.7.23.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
34
- topologicpy-0.7.23.dist-info/RECORD,,
29
+ topologicpy/version.py,sha256=mExVIZTppRZKivnNYLkY3fXqANuLsLtYbD1gMqdgaXM,23
30
+ topologicpy-0.7.26.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
31
+ topologicpy-0.7.26.dist-info/METADATA,sha256=s84QUjxqFTjnzTZGzBs-L1GzOLxH63nzrUVVx7DrC2I,10916
32
+ topologicpy-0.7.26.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
33
+ topologicpy-0.7.26.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
34
+ topologicpy-0.7.26.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.1)
2
+ Generator: setuptools (70.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5