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 +8 -2
- topologicpy/CellComplex.py +14 -1
- topologicpy/Cluster.py +4 -3
- topologicpy/Dictionary.py +13 -6
- topologicpy/Edge.py +4 -2
- topologicpy/Face.py +61 -52
- topologicpy/Graph.py +1 -1
- topologicpy/Topology.py +295 -59
- topologicpy/Vector.py +6 -0
- topologicpy/version.py +1 -1
- {topologicpy-0.7.23.dist-info → topologicpy-0.7.26.dist-info}/METADATA +1 -1
- {topologicpy-0.7.23.dist-info → topologicpy-0.7.26.dist-info}/RECORD +15 -15
- {topologicpy-0.7.23.dist-info → topologicpy-0.7.26.dist-info}/WHEEL +1 -1
- {topologicpy-0.7.23.dist-info → topologicpy-0.7.26.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.23.dist-info → topologicpy-0.7.26.dist-info}/top_level.txt +0 -0
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 =
|
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
|
-
'
|
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,
|
topologicpy/CellComplex.py
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
768
|
-
The
|
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
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
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
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
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
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
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.
|
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
|
-
|
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
|
-
|
978
|
-
|
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
|
982
|
-
if len(results) ==
|
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
|
-
|
2678
|
-
|
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
|
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 =
|
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
|
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("
|
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
|
-
|
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
|
-
|
4840
|
-
|
4841
|
-
|
4842
|
-
|
4843
|
-
|
4844
|
-
|
4845
|
-
|
4846
|
-
|
4847
|
-
|
4848
|
-
|
4849
|
-
|
4850
|
-
|
4851
|
-
|
4852
|
-
|
4853
|
-
|
4854
|
-
|
4855
|
-
|
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.
|
7643
|
-
sinkCells
|
7776
|
+
if Topology.IsInstance(topology, "Cell"):
|
7777
|
+
sinkCells = [topology]
|
7644
7778
|
elif hidimSink >= Topology.TypeID("Cell"):
|
7645
|
-
|
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.
|
1
|
+
__version__ = '0.7.26'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.7.
|
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=
|
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
|
5
|
-
topologicpy/Cluster.py,sha256=
|
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=
|
10
|
-
topologicpy/Edge.py,sha256=
|
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=
|
13
|
-
topologicpy/Graph.py,sha256=
|
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=
|
25
|
-
topologicpy/Vector.py,sha256=
|
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=
|
30
|
-
topologicpy-0.7.
|
31
|
-
topologicpy-0.7.
|
32
|
-
topologicpy-0.7.
|
33
|
-
topologicpy-0.7.
|
34
|
-
topologicpy-0.7.
|
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,,
|
File without changes
|
File without changes
|