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/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
- if topology == None:
5921
- return [None, None, None]
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
- return {"vertices":vertices, "edges":edges, "faces":faces}
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
- Calculates the percentage of coordinates in list1 that do not have a corresponding
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
- def distance(coord1, coord2):
6500
- """Calculate the Euclidean distance between two coordinates."""
6501
- return np.linalg.norm(np.array(coord1) - np.array(coord2))
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
- unmatched = list2.copy()
6505
-
6506
- for coord1 in list1:
6507
- match_found = False
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
- print("Topology.RemoveCoplanarFaces - Error: The input topology parameter is not a valid topologic topology. Returning None.")
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
- print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
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
- print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
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
- print("Topology.Triangulate - Error: The input parameter is not a valid topology. Returning None.")
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(Face.Centroid(triFace), Topology.Dictionary(aFace)))
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.x, source.y, z)
3865
+ source_vertex = Vertex.ByCoordinates(source.X(), source.Y(), z)
3866
3866
 
3867
3867
  for sink in subtree.sinks:
3868
- if (sink.x, sink.y) in polygon_z:
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.x == sink.x and st.source.y == sink.y:
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.x == sink.x and sk.y == sink.y:
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.x, sink.y, z)
3884
- if (source.x, source.y) == (sink.x, sink.y):
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.15'
1
+ __version__ = '0.8.18'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: topologicpy
3
- Version: 0.8.15
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