topologicpy 0.7.24__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/Edge.py +4 -2
- topologicpy/Face.py +61 -52
- topologicpy/Graph.py +1 -1
- topologicpy/Topology.py +256 -39
- topologicpy/Vector.py +6 -0
- topologicpy/version.py +1 -1
- {topologicpy-0.7.24.dist-info → topologicpy-0.7.26.dist-info}/METADATA +1 -1
- {topologicpy-0.7.24.dist-info → topologicpy-0.7.26.dist-info}/RECORD +12 -12
- {topologicpy-0.7.24.dist-info → topologicpy-0.7.26.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.24.dist-info → topologicpy-0.7.26.dist-info}/WHEEL +0 -0
- {topologicpy-0.7.24.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/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)))
|
@@ -4686,7 +4715,7 @@ class Topology():
|
|
4686
4715
|
return json_string
|
4687
4716
|
|
4688
4717
|
@staticmethod
|
4689
|
-
def
|
4718
|
+
def _OBJString(topology, color, vertexIndex, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, mantissa: int = 6, tolerance: float = 0.0001):
|
4690
4719
|
"""
|
4691
4720
|
Returns the Wavefront string of the input topology. This is very experimental and outputs a simple solid topology.
|
4692
4721
|
|
@@ -4757,6 +4786,7 @@ class Topology():
|
|
4757
4786
|
finalLines = finalLines + "\n" + lines[i]
|
4758
4787
|
return finalLines, len(vertices)
|
4759
4788
|
|
4789
|
+
|
4760
4790
|
@staticmethod
|
4761
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):
|
4762
4792
|
"""
|
@@ -4809,7 +4839,6 @@ class Topology():
|
|
4809
4839
|
|
4810
4840
|
"""
|
4811
4841
|
from topologicpy.Helper import Helper
|
4812
|
-
from topologicpy.Dictionary import Dictionary
|
4813
4842
|
from os.path import exists
|
4814
4843
|
|
4815
4844
|
if isinstance(topologies, tuple):
|
@@ -4820,7 +4849,7 @@ class Topology():
|
|
4820
4849
|
print("Topology.ExportToOBJ - Error: the input topologies parameter does not contain any valid topologies. Returning None.")
|
4821
4850
|
return None
|
4822
4851
|
if not isinstance(new_topologies, list):
|
4823
|
-
print("
|
4852
|
+
print("Topology.ExportToOBJ - Error: The input topologies parameter is not a valid list. Returning None.")
|
4824
4853
|
return None
|
4825
4854
|
|
4826
4855
|
if not overwrite and exists(path):
|
@@ -4834,39 +4863,126 @@ class Topology():
|
|
4834
4863
|
status = False
|
4835
4864
|
|
4836
4865
|
mtl_path = path[:-4] + ".mtl"
|
4837
|
-
|
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)
|
4838
4878
|
# Write out the material file
|
4839
|
-
n = max(len(str(len(topologies))), 3)
|
4840
4879
|
with open(mtl_path, "w") as mtl_file:
|
4841
|
-
|
4842
|
-
d = Topology.Dictionary(new_topologies[i])
|
4843
|
-
name = Dictionary.ValueAtKey(d, nameKey) or "Untitled_"+str(i).zfill(n)
|
4844
|
-
color = Dictionary.ValueAtKey(d, colorKey) or defaultColor
|
4845
|
-
color = [c/255 for c in color]
|
4846
|
-
opacity = Dictionary.ValueAtKey(d, opacityKey) or defaultOpacity
|
4847
|
-
mtl_file.write("newmtl color_" + str(i).zfill(n) + "\n")
|
4848
|
-
mtl_file.write("Kd " + ' '.join(map(str, color)) + "\n")
|
4849
|
-
mtl_file.write("d " + str(opacity) + "\n")
|
4850
|
-
|
4880
|
+
mtl_file.write(mtl_string)
|
4851
4881
|
# Write out the obj file
|
4852
4882
|
with open(path, "w") as obj_file:
|
4853
|
-
|
4854
|
-
|
4855
|
-
|
4856
|
-
|
4857
|
-
|
4858
|
-
|
4859
|
-
|
4860
|
-
|
4861
|
-
|
4862
|
-
|
4863
|
-
|
4864
|
-
|
4865
|
-
|
4866
|
-
|
4867
|
-
|
4868
|
-
|
4869
|
-
|
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
|
4870
4986
|
|
4871
4987
|
@staticmethod
|
4872
4988
|
def Filter(topologies, topologyType="any", searchType="any", key=None, value=None):
|
@@ -8003,4 +8119,105 @@ class Topology():
|
|
8003
8119
|
predefined_namespace_dns = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
|
8004
8120
|
namespace_uuid = uuid.uuid5(predefined_namespace_dns, namespace)
|
8005
8121
|
brep_string = Topology.BREPString(topology)
|
8006
|
-
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,4 +1,4 @@
|
|
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
4
|
topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
|
@@ -7,10 +7,10 @@ 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
9
|
topologicpy/Dictionary.py,sha256=4VtIT1p4UHWButzRUnajj16V0DY-d5RaENbXLNTbCYU,27097
|
10
|
-
topologicpy/Edge.py,sha256=
|
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
|
File without changes
|