topologicpy 0.8.15__py3-none-any.whl → 0.8.18__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/Dictionary.py +24 -0
- topologicpy/Face.py +48 -12
- topologicpy/Polyskel.py +832 -620
- topologicpy/Topology.py +342 -55
- topologicpy/Vertex.py +4 -4
- topologicpy/Wire.py +6 -6
- topologicpy/version.py +1 -1
- {topologicpy-0.8.15.dist-info → topologicpy-0.8.18.dist-info}/METADATA +1 -1
- {topologicpy-0.8.15.dist-info → topologicpy-0.8.18.dist-info}/RECORD +12 -12
- {topologicpy-0.8.15.dist-info → topologicpy-0.8.18.dist-info}/WHEEL +1 -1
- {topologicpy-0.8.15.dist-info → topologicpy-0.8.18.dist-info}/LICENSE +0 -0
- {topologicpy-0.8.15.dist-info → topologicpy-0.8.18.dist-info}/top_level.txt +0 -0
topologicpy/Topology.py
CHANGED
@@ -3075,6 +3075,118 @@ class Topology():
|
|
3075
3075
|
json_dict = json.loads(string)
|
3076
3076
|
return Topology.ByJSONDictionary(json_dict, tolerance=tolerance)
|
3077
3077
|
|
3078
|
+
@staticmethod
|
3079
|
+
def ByMeshData(dictionary, transferDictionaries: bool = False, mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
3080
|
+
"""
|
3081
|
+
Create a cluster by the input python dictionary of vertices, edges, faces, and cells.
|
3082
|
+
|
3083
|
+
Parameters
|
3084
|
+
----------
|
3085
|
+
dictionary : dict
|
3086
|
+
The input python dictionary of vertices, edges, faces, and cells in the form of:
|
3087
|
+
{ 'mode': int, The expected mode of input face data:
|
3088
|
+
0: The faces list is indexed into the vertices list.
|
3089
|
+
1: The faces list is indexesd into the edges list.
|
3090
|
+
'vertices': list, (list of coordinates)
|
3091
|
+
'edges': list, (list of indices into the list of vertices)
|
3092
|
+
'faces': list, (list of indices into the list of edges)
|
3093
|
+
'cells': list, (list of indices into the list of faces)
|
3094
|
+
'vertex_dict': list of dicts,
|
3095
|
+
'edge_dicts': list of dicts,
|
3096
|
+
'face_dicts', list of dicts,
|
3097
|
+
'cell_dicts', list of dicts
|
3098
|
+
}
|
3099
|
+
transferDictionaries : bool , optional
|
3100
|
+
If set to True, the python dictionaries will be transferred to the coorespoding topologies. The default is False.
|
3101
|
+
mantissa : int , optional
|
3102
|
+
The desired length of the mantissa. The default is 6.
|
3103
|
+
tolerance : float , optional
|
3104
|
+
The desired tolerance. The default is 0.0001.
|
3105
|
+
silent : bool , optional
|
3106
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
3107
|
+
|
3108
|
+
Returns
|
3109
|
+
-------
|
3110
|
+
topologic_core.Cluster
|
3111
|
+
The created cluster of vertices, edges, faces, and cells.
|
3112
|
+
|
3113
|
+
"""
|
3114
|
+
from topologicpy.Vertex import Vertex
|
3115
|
+
from topologicpy.Edge import Edge
|
3116
|
+
from topologicpy.Face import Face
|
3117
|
+
from topologicpy.Cell import Cell
|
3118
|
+
from topologicpy.Cluster import Cluster
|
3119
|
+
from topologicpy.Dictionary import Dictionary
|
3120
|
+
from topologicpy.Helper import Helper
|
3121
|
+
|
3122
|
+
if not type(dictionary) == type({}):
|
3123
|
+
if not silent:
|
3124
|
+
print("Topology.ByMeshData - Error: The input dictionary parameter is not a valid dictionary. Returning None.")
|
3125
|
+
return None
|
3126
|
+
|
3127
|
+
vertices = dictionary['vertices']
|
3128
|
+
edges = dictionary['edges']
|
3129
|
+
faces = dictionary['faces']
|
3130
|
+
cells = dictionary['cells']
|
3131
|
+
if not 'mode' in dictionary.keys():
|
3132
|
+
mode = 0
|
3133
|
+
else:
|
3134
|
+
mode = dictionary['mode']
|
3135
|
+
if transferDictionaries == True:
|
3136
|
+
vertex_dicts = dictionary['vertex_dicts']
|
3137
|
+
edge_dicts = dictionary['edge_dicts']
|
3138
|
+
face_dicts = dictionary['face_dicts']
|
3139
|
+
cell_dicts = dictionary['cell_dicts']
|
3140
|
+
else:
|
3141
|
+
vertex_dicts = [{}]*len(vertices)
|
3142
|
+
edge_dicts = [{}]*len(edges)
|
3143
|
+
face_dicts = [{}]*len(faces)
|
3144
|
+
cell_dicts = [{}]*len(cells)
|
3145
|
+
|
3146
|
+
top_verts = []
|
3147
|
+
for i, vertex in enumerate(vertices):
|
3148
|
+
top_vertex = Vertex.ByCoordinates(vertex)
|
3149
|
+
if Topology.IsInstance(top_vertex, "Vertex"):
|
3150
|
+
if transferDictionaries:
|
3151
|
+
d = Dictionary.ByPythonDictionary(vertex_dicts[i])
|
3152
|
+
top_vertex = Topology.SetDictionary(top_vertex, d, silent=True)
|
3153
|
+
top_verts.append(top_vertex)
|
3154
|
+
|
3155
|
+
top_edges = []
|
3156
|
+
for i, edge in enumerate(edges):
|
3157
|
+
top_edge = Edge.ByVertices(top_verts[edge[0]], top_verts[edge[1]], tolerance=tolerance, silent=silent)
|
3158
|
+
if Topology.IsInstance(top_edge, "Edge"):
|
3159
|
+
if transferDictionaries:
|
3160
|
+
d = Dictionary.ByPythonDictionary(edge_dicts[i])
|
3161
|
+
top_edge = Topology.SetDictionary(top_edge, d, silent=True)
|
3162
|
+
top_edges.append(top_edge)
|
3163
|
+
|
3164
|
+
top_faces = []
|
3165
|
+
for i, face in enumerate(faces):
|
3166
|
+
if mode == 0:
|
3167
|
+
face_vertices = [top_verts[v] for v in face]
|
3168
|
+
top_face = Face.ByVertices(face_vertices, tolerance=tolerance, silent=silent)
|
3169
|
+
else:
|
3170
|
+
face_edges = [top_edges[e] for e in face]
|
3171
|
+
top_face = Face.ByEdges(face_edges, tolerance=tolerance, silent=silent)
|
3172
|
+
if Topology.IsInstance(top_face, "Face"):
|
3173
|
+
if transferDictionaries:
|
3174
|
+
d = Dictionary.ByPythonDictionary(face_dicts[i])
|
3175
|
+
top_face = Topology.SetDictionary(top_face, d, silent=True)
|
3176
|
+
top_faces.append(top_face)
|
3177
|
+
|
3178
|
+
top_cells = []
|
3179
|
+
for i, cell in enumerate(cells):
|
3180
|
+
cell_faces = [top_faces[f] for f in cell]
|
3181
|
+
top_cell = Cell.ByFaces(cell_faces, tolerance=tolerance, silent=silent)
|
3182
|
+
if Topology.IsInstance(top_cell, "Cell"):
|
3183
|
+
if transferDictionaries:
|
3184
|
+
d = Dictionary.ByPythonDictionary(cell_dicts[i])
|
3185
|
+
top_cell = Topology.SetDictionary(top_cell, d, silent=True)
|
3186
|
+
top_cells.append(top_cell)
|
3187
|
+
|
3188
|
+
return Cluster.ByTopologies(top_verts+top_edges+top_faces+top_cells)
|
3189
|
+
|
3078
3190
|
@staticmethod
|
3079
3191
|
def ByOBJFile(objFile, mtlFile = None,
|
3080
3192
|
defaultColor: list = [255,255,255],
|
@@ -3303,7 +3415,7 @@ class Topology():
|
|
3303
3415
|
vertex = list(map(float, parts[1:4]))
|
3304
3416
|
vertex = [round(coord, mantissa) for coord in vertex]
|
3305
3417
|
if transposeAxes == True:
|
3306
|
-
vertex = [vertex[0], vertex[2], vertex[1]]
|
3418
|
+
vertex = [vertex[0], -vertex[2], vertex[1]]
|
3307
3419
|
vertices.append(vertex)
|
3308
3420
|
elif parts[0] == 'vt':
|
3309
3421
|
texture = list(map(float, parts[1:3]))
|
@@ -3326,7 +3438,7 @@ class Topology():
|
|
3326
3438
|
elif parts[0] == 'usemtl':
|
3327
3439
|
current_material = parts[1]
|
3328
3440
|
elif parts[0] == 'g' or parts[0] == 'o':
|
3329
|
-
current_group = parts[1] if len(parts) > 1 else None
|
3441
|
+
current_group = ' '.join(parts[1:]) if len(parts) > 1 else None
|
3330
3442
|
|
3331
3443
|
obj_data = {
|
3332
3444
|
'vertices': vertices,
|
@@ -5893,7 +6005,7 @@ class Topology():
|
|
5893
6005
|
return flat_topology
|
5894
6006
|
|
5895
6007
|
@staticmethod
|
5896
|
-
def Geometry(topology, mantissa: int = 6):
|
6008
|
+
def Geometry(topology, transferDictionaries: bool = False, mantissa: int = 6, silent: bool = False):
|
5897
6009
|
"""
|
5898
6010
|
Returns the geometry (mesh data format) of the input topology as a dictionary of vertices, edges, and faces.
|
5899
6011
|
|
@@ -5901,8 +6013,12 @@ class Topology():
|
|
5901
6013
|
----------
|
5902
6014
|
topology : topologic_core.Topology
|
5903
6015
|
The input topology.
|
6016
|
+
transferDictionaries : bool , optional
|
6017
|
+
If set to True, vertex, edge, and face dictionaries will be included in the output. Otherwise, they are not. The default is False.
|
5904
6018
|
mantissa : int , optional
|
5905
6019
|
The desired length of the mantissa. The default is 6.
|
6020
|
+
silent : bool , optional
|
6021
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
5906
6022
|
|
5907
6023
|
Returns
|
5908
6024
|
-------
|
@@ -5913,22 +6029,34 @@ class Topology():
|
|
5913
6029
|
from topologicpy.Vertex import Vertex
|
5914
6030
|
from topologicpy.Edge import Edge
|
5915
6031
|
from topologicpy.Face import Face
|
6032
|
+
from topologicpy.Dictionary import Dictionary
|
5916
6033
|
|
5917
6034
|
vertices = []
|
5918
6035
|
edges = []
|
5919
6036
|
faces = []
|
5920
|
-
|
5921
|
-
|
6037
|
+
vertex_dicts = []
|
6038
|
+
edge_dicts = []
|
6039
|
+
face_dicts = []
|
6040
|
+
if not Topology.IsInstance(topology, "topology"):
|
6041
|
+
if not silent:
|
6042
|
+
print("Topology.Geometry - Error: The input topology parameter is not a valid topology. Retruning None.")
|
6043
|
+
return None
|
5922
6044
|
topVerts = []
|
5923
6045
|
if Topology.Type(topology) == Topology.TypeID("Vertex"): #input is a vertex, just add it and process it
|
5924
6046
|
topVerts.append(topology)
|
5925
6047
|
else:
|
5926
6048
|
topVerts = Topology.Vertices(topology)
|
5927
6049
|
for aVertex in topVerts:
|
6050
|
+
py_dict = {}
|
6051
|
+
if transferDictionaries == True:
|
6052
|
+
d = Topology.Dictionary(aVertex)
|
6053
|
+
if len(Dictionary.Keys(d)) > 0:
|
6054
|
+
py_dict = Dictionary.PythonDictionary(d)
|
5928
6055
|
try:
|
5929
6056
|
vertices.index(Vertex.Coordinates(aVertex, mantissa=mantissa)) # Vertex already in list
|
5930
6057
|
except:
|
5931
6058
|
vertices.append(Vertex.Coordinates(aVertex, mantissa=mantissa)) # Vertex not in list, add it.
|
6059
|
+
vertex_dicts.append(py_dict)
|
5932
6060
|
topEdges = []
|
5933
6061
|
if (Topology.Type(topology) == Topology.TypeID("Edge")): #Input is an Edge, just add it and process it
|
5934
6062
|
topEdges.append(topology)
|
@@ -5951,13 +6079,18 @@ class Topology():
|
|
5951
6079
|
e.append(svIndex)
|
5952
6080
|
e.append(evIndex)
|
5953
6081
|
edges.append(e)
|
6082
|
+
py_dict = {}
|
6083
|
+
if transferDictionaries == True:
|
6084
|
+
d = Topology.Dictionary(anEdge)
|
6085
|
+
if len(Dictionary.Keys(d)) > 0:
|
6086
|
+
py_dict = Dictionary.PythonDictionary(d)
|
6087
|
+
edge_dicts.append(py_dict)
|
5954
6088
|
topFaces = []
|
5955
6089
|
if (Topology.Type(topology) == Topology.TypeID("Face")): # Input is a Face, just add it and process it
|
5956
6090
|
topFaces.append(topology)
|
5957
6091
|
elif (Topology.Type(topology) > Topology.TypeID("Face")):
|
5958
6092
|
_ = topology.Faces(None, topFaces)
|
5959
6093
|
for aFace in topFaces:
|
5960
|
-
f_dir = Face.Normal(aFace)
|
5961
6094
|
ib = []
|
5962
6095
|
_ = aFace.InternalBoundaries(ib)
|
5963
6096
|
if(len(ib) > 0):
|
@@ -5986,7 +6119,13 @@ class Topology():
|
|
5986
6119
|
fVertexIndex = len(vertices)-1
|
5987
6120
|
f.append(fVertexIndex)
|
5988
6121
|
faces.append(f)
|
5989
|
-
|
6122
|
+
py_dict = {}
|
6123
|
+
if transferDictionaries == True:
|
6124
|
+
d = Topology.Dictionary(aFace)
|
6125
|
+
if len(Dictionary.Keys(d)) > 0:
|
6126
|
+
py_dict = Dictionary.PythonDictionary(d)
|
6127
|
+
face_dicts.append(py_dict)
|
6128
|
+
return {"vertices":vertices, "edges":edges, "faces":faces, "vertex_dicts": vertex_dicts, "edge_dicts": edge_dicts, "face_dicts": face_dicts}
|
5990
6129
|
|
5991
6130
|
@staticmethod
|
5992
6131
|
def HighestType(topology):
|
@@ -6477,45 +6616,26 @@ class Topology():
|
|
6477
6616
|
"""
|
6478
6617
|
from topologicpy.Vertex import Vertex
|
6479
6618
|
|
6619
|
+
|
6480
6620
|
def coordinates_unmatched_ratio(list1, list2, mantissa, tolerance):
|
6481
6621
|
"""
|
6482
|
-
|
6483
|
-
coordinate in list2 within a specified tolerance, with each match being unique.
|
6484
|
-
|
6485
|
-
Parameters
|
6486
|
-
----------
|
6487
|
-
list1 : list of list of float
|
6488
|
-
The first list of coordinates, where each coordinate is [x, y, z].
|
6489
|
-
list2 : list of list of float
|
6490
|
-
The second list of coordinates, where each coordinate is [x, y, z].
|
6491
|
-
tolerance : float
|
6492
|
-
The maximum distance within which two coordinates are considered matching.
|
6493
|
-
|
6494
|
-
Returns
|
6495
|
-
-------
|
6496
|
-
float
|
6497
|
-
The percentage of coordinates in list1 that did not find a match in list2.
|
6622
|
+
Optimized version using KDTree for faster nearest-neighbor search.
|
6498
6623
|
"""
|
6499
|
-
|
6500
|
-
|
6501
|
-
|
6502
|
-
|
6624
|
+
from scipy.spatial import KDTree
|
6625
|
+
import numpy as np
|
6626
|
+
rounded_list1 = [np.round(coord, mantissa) for coord in list1]
|
6627
|
+
rounded_list2 = [np.round(coord, mantissa) for coord in list2]
|
6628
|
+
|
6629
|
+
tree = KDTree(rounded_list2)
|
6503
6630
|
unmatched_count = 0
|
6504
|
-
|
6505
|
-
|
6506
|
-
|
6507
|
-
|
6508
|
-
for i, coord2 in enumerate(unmatched):
|
6509
|
-
if distance(coord1, coord2) <= tolerance:
|
6510
|
-
unmatched.pop(i) # Remove matched coordinate
|
6511
|
-
match_found = True
|
6512
|
-
break
|
6513
|
-
if not match_found:
|
6631
|
+
|
6632
|
+
for coord in rounded_list1:
|
6633
|
+
distances, indices = tree.query(coord, k=1)
|
6634
|
+
if distances > tolerance:
|
6514
6635
|
unmatched_count += 1
|
6515
|
-
|
6516
|
-
total_coordinates = len(list1)
|
6517
|
-
unmatched_ratio = (unmatched_count / total_coordinates)
|
6518
6636
|
|
6637
|
+
total_coordinates = len(list1)
|
6638
|
+
unmatched_ratio = unmatched_count / total_coordinates
|
6519
6639
|
return round(unmatched_ratio, mantissa)
|
6520
6640
|
|
6521
6641
|
if not Topology.IsInstance(topologyA, "topology"):
|
@@ -6680,6 +6800,161 @@ class Topology():
|
|
6680
6800
|
return None
|
6681
6801
|
return Topology.SelfMerge(Cluster.ByTopologies(topologyList), tolerance=tolerance)
|
6682
6802
|
|
6803
|
+
@staticmethod
|
6804
|
+
def MeshData(topology, mode: int = 1, transferDictionaries: bool = False, mantissa: int = 6, silent: bool = False):
|
6805
|
+
"""
|
6806
|
+
Creates a mesh data python dictionary from the input topology.
|
6807
|
+
|
6808
|
+
Parameters
|
6809
|
+
----------
|
6810
|
+
topology : topologic_core.Topology
|
6811
|
+
The input topology.
|
6812
|
+
mode : int , optional
|
6813
|
+
The desired mode of conversion:
|
6814
|
+
0: The faces list indexes into the vertices list.
|
6815
|
+
1: The faces list indexes into the edges list.
|
6816
|
+
The default is 1.
|
6817
|
+
transferDictionaries : bool , optional
|
6818
|
+
If set to True, the python dictionaries will be transferred to the coorespoding topologies. The default is False.
|
6819
|
+
mantissa : int , optional
|
6820
|
+
The desired length of the mantissa. The default is 6.
|
6821
|
+
tolerance : float , optional
|
6822
|
+
The desired tolerance. The default is 0.0001.
|
6823
|
+
silent : bool , optional
|
6824
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
6825
|
+
|
6826
|
+
Returns
|
6827
|
+
-------
|
6828
|
+
dict
|
6829
|
+
The created mesh data python dictionary of vertices, edges, faces, and cells in the form of:
|
6830
|
+
{ 'mode' : int (the mode of the face data)
|
6831
|
+
'vertices': list, (list of coordinates)
|
6832
|
+
'edges': list, (list of indices into the list of vertices)
|
6833
|
+
'faces': list, (list of indices into the list of edges or list of vertices based on mode)
|
6834
|
+
'cells': list, (list of indices into the list of faces)
|
6835
|
+
'vertex_dict': list of dicts,
|
6836
|
+
'edge_dicts': list of dicts,
|
6837
|
+
'face_dicts', list of dicts,
|
6838
|
+
'cell_dicts', list of dicts
|
6839
|
+
}
|
6840
|
+
|
6841
|
+
"""
|
6842
|
+
from topologicpy.Vertex import Vertex
|
6843
|
+
from topologicpy.Dictionary import Dictionary
|
6844
|
+
|
6845
|
+
vertex_dicts = []
|
6846
|
+
edge_dicts = []
|
6847
|
+
face_dicts = []
|
6848
|
+
cell_dicts = []
|
6849
|
+
top = Topology.Copy(topology)
|
6850
|
+
top = Topology.Triangulate(top, transferDictionaries=transferDictionaries)
|
6851
|
+
vertices = Topology.Vertices(top)
|
6852
|
+
edges = Topology.Edges(top)
|
6853
|
+
faces = Topology.Faces(top)
|
6854
|
+
if Topology.IsInstance(top, "Vertex"):
|
6855
|
+
vertices = [top]
|
6856
|
+
edges = []
|
6857
|
+
faces = []
|
6858
|
+
cells = []
|
6859
|
+
elif Topology.IsInstance(top, "Edge"):
|
6860
|
+
vertices = Topology.Vertices(top)
|
6861
|
+
edges = [top]
|
6862
|
+
faces = []
|
6863
|
+
cells = []
|
6864
|
+
elif Topology.IsInstance(top, "Wire"):
|
6865
|
+
vertices = Topology.Vertices(top)
|
6866
|
+
edges = Topology.Edges(top)
|
6867
|
+
faces = []
|
6868
|
+
cells = []
|
6869
|
+
elif Topology.IsInstance(top, "Face"):
|
6870
|
+
vertices = Topology.Vertices(top)
|
6871
|
+
edges = Topology.Edges(top)
|
6872
|
+
faces = [top]
|
6873
|
+
cells = []
|
6874
|
+
elif Topology.IsInstance(top, "Shell"):
|
6875
|
+
vertices = Topology.Vertices(top)
|
6876
|
+
edges = Topology.Edges(top)
|
6877
|
+
faces = Topology.Faces(top)
|
6878
|
+
cells = []
|
6879
|
+
elif Topology.IsInstance(top, "Cell"):
|
6880
|
+
vertices = Topology.Vertices(top)
|
6881
|
+
edges = Topology.Edges(top)
|
6882
|
+
faces = Topology.Faces(top)
|
6883
|
+
cells = [top]
|
6884
|
+
elif Topology.IsInstance(top, "CellComplex"):
|
6885
|
+
vertices = Topology.Vertices(top)
|
6886
|
+
edges = Topology.Edges(top)
|
6887
|
+
faces = Topology.Faces(top)
|
6888
|
+
cells = Topology.Cells(top)
|
6889
|
+
elif Topology.IsInstance(top, "Cluster"):
|
6890
|
+
vertices = Topology.Vertices(top)
|
6891
|
+
edges = Topology.Edges(top)
|
6892
|
+
faces = Topology.Faces(top)
|
6893
|
+
cells = Topology.Cells(top)
|
6894
|
+
else:
|
6895
|
+
if not silent:
|
6896
|
+
print("Topology.MeshData - Error: The input topology parameter is not a valid topology. Returning None.")
|
6897
|
+
return None
|
6898
|
+
|
6899
|
+
m_verts = []
|
6900
|
+
m_edges = []
|
6901
|
+
m_faces = []
|
6902
|
+
m_cells = []
|
6903
|
+
key = "_n_"
|
6904
|
+
|
6905
|
+
for i, v in enumerate(vertices):
|
6906
|
+
d = Topology.Dictionary(v)
|
6907
|
+
v = Topology.SetDictionary(v, Dictionary.ByKeyValue(key, i))
|
6908
|
+
m_verts.append(Vertex.Coordinates(v, mantissa=mantissa))
|
6909
|
+
vertex_dicts.append(Dictionary.PythonDictionary(d))
|
6910
|
+
|
6911
|
+
for i, e in enumerate(edges):
|
6912
|
+
d = Topology.Dictionary(e)
|
6913
|
+
e = Topology.SetDictionary(e, Dictionary.ByKeyValue(key, i), silent=True)
|
6914
|
+
sv, ev = Topology.Vertices(e)
|
6915
|
+
sv_n = Dictionary.ValueAtKey(Topology.Dictionary(sv), key)
|
6916
|
+
ev_n = Dictionary.ValueAtKey(Topology.Dictionary(ev), key)
|
6917
|
+
m_edges.append([sv_n, ev_n])
|
6918
|
+
edge_dicts.append(Dictionary.PythonDictionary(d))
|
6919
|
+
|
6920
|
+
for i, f in enumerate(faces):
|
6921
|
+
d = Topology.Dictionary(f)
|
6922
|
+
f = Topology.SetDictionary(f, Dictionary.ByKeyValue(key, i), silent=True)
|
6923
|
+
if mode == 1:
|
6924
|
+
f_edges = Topology.Edges(f)
|
6925
|
+
edge_indices = []
|
6926
|
+
for f_edge in f_edges:
|
6927
|
+
edge_indices.append(Dictionary.ValueAtKey(Topology.Dictionary(f_edge), key))
|
6928
|
+
m_faces.append(edge_indices)
|
6929
|
+
else:
|
6930
|
+
f_vertices = Topology.Vertices(f)
|
6931
|
+
vertex_indices = []
|
6932
|
+
for f_vertex in f_vertices:
|
6933
|
+
vertex_indices.append(Dictionary.ValueAtKey(Topology.Dictionary(f_vertex), key))
|
6934
|
+
m_faces.append(vertex_indices)
|
6935
|
+
face_dicts.append(Dictionary.PythonDictionary(d))
|
6936
|
+
|
6937
|
+
for i, c in enumerate(cells):
|
6938
|
+
d = Topology.Dictionary(c)
|
6939
|
+
c = Topology.SetDictionary(c, Dictionary.ByKeyValue(key, i), silent=True)
|
6940
|
+
c_faces = Topology.Faces(c)
|
6941
|
+
face_indices = []
|
6942
|
+
for c_face in c_faces:
|
6943
|
+
face_indices.append(Dictionary.ValueAtKey(Topology.Dictionary(c_face), key))
|
6944
|
+
m_cells.append(face_indices)
|
6945
|
+
cell_dicts.append(Dictionary.PythonDictionary(d))
|
6946
|
+
|
6947
|
+
return {"mode": mode,
|
6948
|
+
"vertices": m_verts,
|
6949
|
+
"edges": m_edges,
|
6950
|
+
"faces": m_faces,
|
6951
|
+
"cells": m_cells,
|
6952
|
+
"vertex_dicts": vertex_dicts,
|
6953
|
+
"edge_dicts": edge_dicts,
|
6954
|
+
"face_dicts": face_dicts,
|
6955
|
+
"cell_dicts": cell_dicts
|
6956
|
+
}
|
6957
|
+
|
6683
6958
|
@staticmethod
|
6684
6959
|
def Move(topology, x=0, y=0, z=0):
|
6685
6960
|
"""
|
@@ -7108,7 +7383,7 @@ class Topology():
|
|
7108
7383
|
return topology.RemoveContents(contents)
|
7109
7384
|
|
7110
7385
|
@staticmethod
|
7111
|
-
def RemoveCoplanarFaces(topology, epsilon=0.01, tolerance=0.0001):
|
7386
|
+
def RemoveCoplanarFaces(topology, epsilon=0.01, tolerance=0.0001, silent: bool = False):
|
7112
7387
|
"""
|
7113
7388
|
Removes coplanar faces in the input topology
|
7114
7389
|
|
@@ -7120,6 +7395,8 @@ class Topology():
|
|
7120
7395
|
The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.01.
|
7121
7396
|
tolerance : float , optional
|
7122
7397
|
The desired tolerance. The default is 0.0001.
|
7398
|
+
silent : bool , optional
|
7399
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
7123
7400
|
|
7124
7401
|
Returns
|
7125
7402
|
-------
|
@@ -7135,7 +7412,8 @@ class Topology():
|
|
7135
7412
|
from topologicpy.Cluster import Cluster
|
7136
7413
|
|
7137
7414
|
if not Topology.IsInstance(topology, "Topology"):
|
7138
|
-
|
7415
|
+
if not silent:
|
7416
|
+
print("Topology.RemoveCoplanarFaces - Error: The input topology parameter is not a valid topologic topology. Returning None.")
|
7139
7417
|
return None
|
7140
7418
|
t = Topology.Type(topology)
|
7141
7419
|
if (t == Topology.TypeID("Vertex")) or (t == Topology.TypeID("Edge")) or (t == Topology.TypeID("Wire")) or (t == Topology.TypeID("Face")):
|
@@ -7184,7 +7462,8 @@ class Topology():
|
|
7184
7462
|
if Topology.IsInstance(f, "Face"):
|
7185
7463
|
final_faces.append(f)
|
7186
7464
|
else:
|
7187
|
-
|
7465
|
+
if not silent:
|
7466
|
+
print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
|
7188
7467
|
final_faces += Shell.Faces(t)
|
7189
7468
|
else: # It is a cluster
|
7190
7469
|
shells = Topology.Shells(t)
|
@@ -7193,7 +7472,8 @@ class Topology():
|
|
7193
7472
|
if Topology.IsInstance(f, "Face"):
|
7194
7473
|
final_faces.append(f)
|
7195
7474
|
else:
|
7196
|
-
|
7475
|
+
if not silent:
|
7476
|
+
print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
|
7197
7477
|
final_faces += Shell.Faces(shell)
|
7198
7478
|
if len(shells) == 0:
|
7199
7479
|
faces = Topology.Faces(t)
|
@@ -7202,16 +7482,16 @@ class Topology():
|
|
7202
7482
|
final_faces += faces
|
7203
7483
|
return_topology = None
|
7204
7484
|
if Topology.IsInstance(topology, "CellComplex"):
|
7205
|
-
return_topology = CellComplex.ByFaces(final_faces, tolerance=tolerance)
|
7485
|
+
return_topology = CellComplex.ByFaces(final_faces, tolerance=tolerance, silent=silent)
|
7206
7486
|
elif Topology.IsInstance(topology, "Cell"):
|
7207
|
-
return_topology = Cell.ByFaces(final_faces, tolerance=tolerance)
|
7487
|
+
return_topology = Cell.ByFaces(final_faces, tolerance=tolerance, silent=silent)
|
7208
7488
|
elif Topology.IsInstance(topology, "Shell"):
|
7209
7489
|
if len(final_faces) == 1:
|
7210
7490
|
return_topology = final_faces[0]
|
7211
7491
|
else:
|
7212
|
-
return_topology = Shell.ByFaces(final_faces, tolerance=tolerance)
|
7492
|
+
return_topology = Shell.ByFaces(final_faces, tolerance=tolerance, silent=silent)
|
7213
7493
|
if not Topology.IsInstance(return_topology, "Topology"):
|
7214
|
-
return_topology = Cluster.ByTopologies(final_faces)
|
7494
|
+
return_topology = Cluster.ByTopologies(final_faces, silent=silent)
|
7215
7495
|
return return_topology
|
7216
7496
|
|
7217
7497
|
@staticmethod
|
@@ -9765,7 +10045,7 @@ class Topology():
|
|
9765
10045
|
|
9766
10046
|
|
9767
10047
|
@staticmethod
|
9768
|
-
def Triangulate(topology, transferDictionaries: bool = False, mode: int = 0, meshSize: float = None, tolerance: float = 0.0001):
|
10048
|
+
def Triangulate(topology, transferDictionaries: bool = False, mode: int = 0, meshSize: float = None, tolerance: float = 0.0001, silent: bool = False):
|
9769
10049
|
"""
|
9770
10050
|
Triangulates the input topology.
|
9771
10051
|
|
@@ -9792,6 +10072,8 @@ class Topology():
|
|
9792
10072
|
calculated automatically and set to 10% of the overall size of the face.
|
9793
10073
|
tolerance : float , optional
|
9794
10074
|
The desired tolerance. The default is 0.0001.
|
10075
|
+
silent : bool , optional
|
10076
|
+
If set to True, no warnings or errors will be printed. The default is False.
|
9795
10077
|
|
9796
10078
|
Returns
|
9797
10079
|
-------
|
@@ -9806,28 +10088,33 @@ class Topology():
|
|
9806
10088
|
from topologicpy.Cluster import Cluster
|
9807
10089
|
|
9808
10090
|
if not Topology.IsInstance(topology, "Topology"):
|
9809
|
-
|
10091
|
+
if not silent:
|
10092
|
+
print("Topology.Triangulate - Error: The input parameter is not a valid topology. Returning None.")
|
9810
10093
|
return None
|
9811
10094
|
t = Topology.Type(topology)
|
9812
10095
|
if (t == Topology.TypeID("Vertex")) or (t == Topology.TypeID("Edge")) or (t == Topology.TypeID("Wire")):
|
10096
|
+
if not silent:
|
10097
|
+
print("Topology.Triangulate - Warning: The input topology parameter contains no faces. Returning the original topology.")
|
9813
10098
|
return topology
|
9814
10099
|
elif t == Topology.TypeID("Cluster"):
|
9815
10100
|
temp_topologies = []
|
9816
10101
|
cellComplexes = Topology.SubTopologies(topology, subTopologyType="cellcomplex") or []
|
9817
10102
|
for cc in cellComplexes:
|
9818
|
-
temp_topologies.append(Topology.Triangulate(cc, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance))
|
10103
|
+
temp_topologies.append(Topology.Triangulate(cc, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance, silent=silent))
|
9819
10104
|
cells = Cluster.FreeCells(topology, tolerance=tolerance) or []
|
9820
10105
|
for c in cells:
|
9821
|
-
temp_topologies.append(Topology.Triangulate(c, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance))
|
10106
|
+
temp_topologies.append(Topology.Triangulate(c, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance, silent=silent))
|
9822
10107
|
shells = Cluster.FreeShells(topology, tolerance=tolerance) or []
|
9823
10108
|
for s in shells:
|
9824
|
-
temp_topologies.append(Topology.Triangulate(s, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance))
|
10109
|
+
temp_topologies.append(Topology.Triangulate(s, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance, silent=silent))
|
9825
10110
|
faces = Cluster.FreeFaces(topology, tolerance=tolerance) or []
|
9826
10111
|
for f in faces:
|
9827
|
-
temp_topologies.append(Topology.Triangulate(f, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance))
|
10112
|
+
temp_topologies.append(Topology.Triangulate(f, transferDictionaries=transferDictionaries, mode=mode, meshSize=meshSize, tolerance=tolerance, silent=silent))
|
9828
10113
|
if len(temp_topologies) > 0:
|
9829
10114
|
return Cluster.ByTopologies(temp_topologies)
|
9830
10115
|
else:
|
10116
|
+
if not silent:
|
10117
|
+
print("Topology.Triangulate - Warning: The input topology parameter contains no faces. Returning the original topology.")
|
9831
10118
|
return topology
|
9832
10119
|
topologyFaces = []
|
9833
10120
|
_ = topology.Faces(None, topologyFaces)
|
@@ -9840,7 +10127,7 @@ class Topology():
|
|
9840
10127
|
triFaces = [aFace]
|
9841
10128
|
for triFace in triFaces:
|
9842
10129
|
if transferDictionaries:
|
9843
|
-
selectors.append(Topology.SetDictionary(
|
10130
|
+
selectors.append(Topology.SetDictionary(Topology.Centroid(triFace), Topology.Dictionary(aFace), silent=True))
|
9844
10131
|
faceTriangles.append(triFace)
|
9845
10132
|
return_topology = None
|
9846
10133
|
if t == Topology.TypeID("Face") or t == Topology.TypeID("Shell"): # Face or Shell
|
topologicpy/Vertex.py
CHANGED
@@ -313,17 +313,17 @@ class Vertex():
|
|
313
313
|
return None
|
314
314
|
if len(args) > 0:
|
315
315
|
value = args[0]
|
316
|
-
if isinstance(value, list) and len(value) > 3:
|
316
|
+
if (isinstance(value, list) or isinstance(value, tuple)) and len(value) > 3:
|
317
317
|
print("Vertex.ByCoordinates - Error: Input parameters are greater than 3. Returning None.")
|
318
318
|
return None
|
319
|
-
elif isinstance(value, list) and len(value) == 3:
|
319
|
+
elif (isinstance(value, list) or isinstance(value, tuple)) and len(value) == 3:
|
320
320
|
x = value[0]
|
321
321
|
y = value[1]
|
322
322
|
z = value[2]
|
323
|
-
elif isinstance(value, list) and len(value) == 2:
|
323
|
+
elif (isinstance(value, list) or isinstance(value, tuple)) and len(value) == 2:
|
324
324
|
x = value[0]
|
325
325
|
y = value[1]
|
326
|
-
elif isinstance(value, list) and len(value) == 1:
|
326
|
+
elif (isinstance(value, list) or isinstance(value, tuple)) and len(value) == 1:
|
327
327
|
x = value[0]
|
328
328
|
elif len(args) == 3:
|
329
329
|
x = args[0]
|
topologicpy/Wire.py
CHANGED
@@ -3862,26 +3862,26 @@ class Wire():
|
|
3862
3862
|
source = subtree.source
|
3863
3863
|
height = subtree.height
|
3864
3864
|
z = slope * height
|
3865
|
-
source_vertex = Vertex.ByCoordinates(source.
|
3865
|
+
source_vertex = Vertex.ByCoordinates(source.X(), source.Y(), z)
|
3866
3866
|
|
3867
3867
|
for sink in subtree.sinks:
|
3868
|
-
if (sink.
|
3868
|
+
if (sink.X(), sink.Y()) in polygon_z:
|
3869
3869
|
z = 0
|
3870
3870
|
else:
|
3871
3871
|
z = None
|
3872
3872
|
for st in subtrees:
|
3873
|
-
if st.source.
|
3873
|
+
if st.source.X() == sink.X() and st.source.Y() == sink.Y():
|
3874
3874
|
z = slope * st.height
|
3875
3875
|
break
|
3876
3876
|
for sk in st.sinks:
|
3877
|
-
if sk.
|
3877
|
+
if sk.X() == sink.X() and sk.Y() == sink.Y():
|
3878
3878
|
z = slope * st.height
|
3879
3879
|
break
|
3880
3880
|
if z is None:
|
3881
3881
|
height = subtree.height
|
3882
3882
|
z = slope * height
|
3883
|
-
sink_vertex = Vertex.ByCoordinates(sink.
|
3884
|
-
if (source.
|
3883
|
+
sink_vertex = Vertex.ByCoordinates(sink.X(), sink.Y(), z)
|
3884
|
+
if (source.X(), source.Y()) == (sink.X(), sink.Y()):
|
3885
3885
|
continue
|
3886
3886
|
e = Edge.ByStartVertexEndVertex(source_vertex, sink_vertex, tolerance=tolerance, silent=True)
|
3887
3887
|
if e not in edges and e != None:
|
topologicpy/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.8.
|
1
|
+
__version__ = '0.8.18'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.18
|
4
4
|
Summary: An AI-Powered Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
|
5
5
|
Author-email: Wassim Jabi <wassim.jabi@gmail.com>
|
6
6
|
License: AGPL v3 License
|