topologicpy 0.7.82__py3-none-any.whl → 0.7.84__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/Cell.py CHANGED
@@ -1967,9 +1967,13 @@ class Cell():
1967
1967
  """
1968
1968
  from topologicpy.Face import Face
1969
1969
  from topologicpy.Topology import Topology
1970
-
1970
+ import inspect
1971
+
1971
1972
  if not Topology.IsInstance(cell, "Cell"):
1972
1973
  print("Cell.RemoveCollinearEdges - Error: The input cell parameter is not a valid cell. Returning None.")
1974
+ curframe = inspect.currentframe()
1975
+ calframe = inspect.getouterframes(curframe, 2)
1976
+ print('caller name:', calframe[1][3])
1973
1977
  return None
1974
1978
  faces = Cell.Faces(cell)
1975
1979
  clean_faces = []
@@ -972,9 +972,14 @@ class CellComplex():
972
972
  """
973
973
  from topologicpy.Cell import Cell
974
974
  from topologicpy.Topology import Topology
975
-
975
+ import inspect
976
+
976
977
  if not Topology.IsInstance(cellComplex, "CellComplex"):
977
978
  print("CellComplex.RemoveCollinearEdges - Error: The input cellComplex parameter is not a valid cellComplex. Returning None.")
979
+ print("CellComplex.RemoveCollinearEdges - Inspection:")
980
+ curframe = inspect.currentframe()
981
+ calframe = inspect.getouterframes(curframe, 2)
982
+ print('caller name:', calframe[1][3])
978
983
  return None
979
984
  cells = CellComplex.Cells(cellComplex)
980
985
  clean_cells = []
topologicpy/Edge.py CHANGED
@@ -1477,7 +1477,7 @@ class Edge():
1477
1477
  svb = Edge.StartVertex(edgeB)
1478
1478
  evb = Edge.EndVertex(edgeB)
1479
1479
  intVertex = None
1480
- if Edge.IsCollinear(edgeA, edgeB):
1480
+ if Edge.IsCollinear(edgeA, edgeB, tolerance=tolerance):
1481
1481
  if Vertex.IsInternal(svb, edgeA):
1482
1482
  intVertex = svb
1483
1483
  elif Vertex.IsInternal(evb, edgeA):
topologicpy/Face.py CHANGED
@@ -594,6 +594,7 @@ class Face():
594
594
  # Try the simple method first
595
595
  face = None
596
596
  ext_boundary = Wire.RemoveCollinearEdges(Shell.ExternalBoundary(shell))
597
+ #ext_boundary = Shell.ExternalBoundary(shell)
597
598
  if Topology.IsInstance(ext_boundary, "Wire"):
598
599
  face = Face.ByWire(ext_boundary, silent=silent)
599
600
  elif Topology.IsInstance(ext_boundary, "Cluster"):
@@ -652,8 +653,11 @@ class Face():
652
653
  for int_boundary in int_boundaries:
653
654
  temp_wires = Topology.Wires(int_boundary)
654
655
  int_wires.append(Topology.RemoveCollinearEdges(temp_wires[0], angTolerance))
656
+ #int_wires.append(temp_wires[0])
657
+
655
658
  temp_wires = Topology.Wires(ext_boundary)
656
659
  ext_wire = Topology.RemoveCollinearEdges(temp_wires[0], angTolerance)
660
+ #ext_wire = temp_wires[0]
657
661
  face = Face.ByWires(ext_wire, int_wires)
658
662
  face = Topology.Unflatten(face, origin=origin, direction=normal)
659
663
  return face
@@ -1623,10 +1627,10 @@ class Face():
1623
1627
  return None
1624
1628
 
1625
1629
  if not Topology.IsInstance(faceA, "Face"):
1626
- print("Face.IsInside - Error: The input faceA parameter is not a valid topologic face. Returning None.")
1630
+ print("Face.IsCoplanar - Error: The input faceA parameter is not a valid topologic face. Returning None.")
1627
1631
  return None
1628
1632
  if not Topology.IsInstance(faceB, "Face"):
1629
- print("Face.IsInside - Error: The input faceB parameter is not a valid topologic face. Returning None.")
1633
+ print("Face.IsCoplanar - Error: The input faceB parameter is not a valid topologic face. Returning None.")
1630
1634
  return None
1631
1635
 
1632
1636
  def normalize_plane_coefficients(plane):
@@ -1649,7 +1653,7 @@ class Face():
1649
1653
  return are_planes_coplanar(plane_a, plane_b, tolerance=tolerance)
1650
1654
 
1651
1655
  @staticmethod
1652
- def Isovist(face, vertex, obstacles: list = [], direction: list = [0,1,0], fov: float = 360, transferDictionaries: bool = False, metrics: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
1656
+ def Isovist(face, vertex, obstacles: list = [], direction: list = [0,1,0], fov: float = 360, transferDictionaries: bool = False, metrics: bool = False, triangles: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
1653
1657
  """
1654
1658
  Returns the face representing the isovist projection from the input viewpoint.
1655
1659
  This method assumes all input is in 2D. Z coordinates are ignored.
@@ -1682,7 +1686,11 @@ class Face():
1682
1686
  - perimeter : float , the perimeter length of the isovist
1683
1687
  - compactness : float , how closely the shape of the isovist approximates a circle (the most compact geometric shape).
1684
1688
  - d_max : float, Maximum Visibility Distance. the length of the longest straight line that can be seen from the viewpoint.
1689
+ - d_min : float, Minimum Visibility Distance. the length of the shortest straight line that can be seen from the viewpoint.
1690
+ - d_avg : float, Average Visibility Distance. the length of the average straight line that can be seen from the viewpoint.
1685
1691
  - v_max : list, Furthest Point measures the x , y , z coordinates of the furthest visible point from the viewpoint.
1692
+ - v_min : list, Closest Point measures the x , y , z coordinates of the closest visible point from the viewpoint.
1693
+ - centroid: list, Centroid measures the x, y, z coordinates of the centroid of the isovist face.
1686
1694
  - v_d : list, Visibility Distribution quantifies the angular distribution (in degrees) of visible points across the isovist.
1687
1695
  This metric can tell you whether the visibility from a point is more spread out or concentrated in a certain direction. A uniform visibility distribution indicates a more balanced visual field, while a skewed distribution suggests that the observer's line of sight is constrained in certain directions.
1688
1696
  - v_density : float, Viewpoint Density which refers to the number of visible points per unit area within the isovist.
@@ -1690,6 +1698,8 @@ class Face():
1690
1698
  - d_f : float, Fractal Dimension measures the complexity of the isovist's boundary.
1691
1699
  - e_c : float , Edge Complexity measures how complex the edges of the isovist boundary are.
1692
1700
  - theta : float, Mean Visual Field Angle measures the average angular extent of the visible area from the observation point.
1701
+ triangles : bool , optional
1702
+ If set to True, the subtended triangles of the isovist are created and stored as contents of the returned isovist face. The default is False.
1693
1703
  mantissa : int , optional
1694
1704
  The desired length of the mantissa. The default is 6.
1695
1705
  tolerance : float , optional:
@@ -1855,6 +1865,42 @@ class Face():
1855
1865
  else:
1856
1866
  obstacles = []
1857
1867
 
1868
+ def closest_distance_vertex(vertex, edge, mantissa):
1869
+ point = Vertex.Coordinates(vertex, mantissa=mantissa)
1870
+ line_start = Vertex.Coordinates(Edge.StartVertex(edge), mantissa=mantissa)
1871
+ line_end = Vertex.Coordinates(Edge.EndVertex(edge), mantissa=mantissa)
1872
+
1873
+ # Convert input points to NumPy arrays for vector operations
1874
+ point = np.array(point)
1875
+ line_start = np.array(line_start)
1876
+ line_end = np.array(line_end)
1877
+
1878
+ # Calculate the direction vector of the edge
1879
+ line_direction = line_end - line_start
1880
+
1881
+ # Vector from the edge's starting point to the point
1882
+ point_to_start = point - line_start
1883
+
1884
+ # Calculate the parameter 't' where the projection of the point onto the edge occurs
1885
+ if np.dot(line_direction, line_direction) == 0:
1886
+ t = 0
1887
+ else:
1888
+ t = np.dot(point_to_start, line_direction) / np.dot(line_direction, line_direction)
1889
+
1890
+ # Check if 't' is outside the range [0, 1], and if so, calculate distance to closest endpoint
1891
+ if t < 0:
1892
+ t = 0
1893
+ elif t > 1:
1894
+ t = 1
1895
+
1896
+ # Calculate the closest point on the edge to the given point
1897
+ closest_point = line_start + t * line_direction
1898
+
1899
+ # Calculate the distance between the closest point and the given point
1900
+ distance = np.linalg.norm(point - closest_point)
1901
+
1902
+ return float(distance), Vertex.ByCoordinates(list(closest_point))
1903
+
1858
1904
  origin = Topology.Centroid(face)
1859
1905
  normal = Face.Normal(face)
1860
1906
  flat_face = Topology.Flatten(face, origin=origin, direction=normal)
@@ -1879,6 +1925,10 @@ class Face():
1879
1925
  for obs in flat_obstacles:
1880
1926
  flat_face = Topology.Difference(flat_face, Face.ByWire(obs))
1881
1927
 
1928
+ # Check that the viewpoint is inside the face
1929
+ if not Vertex.IsInternal(flat_vertex, flat_face):
1930
+ print("Face.Isovist - Error: The viewpoint is not inside the face. Returning None.")
1931
+ return None
1882
1932
  targets = Topology.Vertices(flat_face)
1883
1933
  distances = []
1884
1934
  for target in targets:
@@ -1958,6 +2008,8 @@ class Face():
1958
2008
  return_face = Topology.Unflatten(simpler_face, origin=origin, direction=normal)
1959
2009
  return_face = Topology.Unflatten(return_face, origin=origin, direction=normal)
1960
2010
  if metrics == True:
2011
+ vertices = Topology.Vertices(return_face)
2012
+ edges = Topology.Edges(return_face)
1961
2013
  # 1 Viewpoint
1962
2014
  viewpoint = Vertex.Coordinates(vertex, mantissa=mantissa)
1963
2015
  # 2 Direction
@@ -1971,30 +2023,59 @@ class Face():
1971
2023
  # 6 Compactness
1972
2024
  compactness = round(Face.Compactness(return_face), mantissa)
1973
2025
  # 7 Maximum Distance (d_max)
1974
- vertices = Topology.Vertices(return_face)
1975
- furthest_vertex = vertices[0]
2026
+ # 8 Minimum Distance (d_min)
2027
+ # 9 Average Distance (d_avg)
2028
+ # 10 Furthest Visible Vertex (v_max)
2029
+ # 11 Closest Visible Vertex (v_min)
1976
2030
  d_max = round(Vertex.Distance(vertex, vertices[0]), mantissa)
1977
- # 8 Furthest Visible Vertex
2031
+ d_min = round(Vertex.Distance(vertex, vertices[0]), mantissa)
2032
+ furthest_vertex = vertices[0]
2033
+ closest_vertex = vertices[0]
1978
2034
  coords = []
2035
+ distances = []
1979
2036
  for v in vertices:
1980
2037
  coords.append(Vertex.Coordinates(v, mantissa=mantissa))
1981
2038
  dis = Vertex.Distance(vertex, v, mantissa=mantissa)
2039
+ distances.append(dis)
1982
2040
  if dis > d_max:
1983
2041
  d_max = dis
1984
2042
  furthest_vertex = v
2043
+ distances = []
2044
+ edges = Topology.Edges(Cluster.ByTopologies([face]+obstacles))
2045
+ for edge in edges:
2046
+ dis, c_v = closest_distance_vertex(vertex, edge, mantissa=mantissa)
2047
+ if dis < d_min and Vertex.IsPeripheral(c_v, return_face):
2048
+ d_min = dis
2049
+ closest_vertex = c_v
2050
+
2051
+ # 12 Average Visible Distance
2052
+ if len(distances) > 0:
2053
+ d_avg = sum(distances)/float(len(distances))
2054
+ else:
2055
+ d_avg = 0
2056
+
2057
+ # 10 Furthest Visible Vertex (v_max)
1985
2058
  v_max = Vertex.Coordinates(furthest_vertex, mantissa=mantissa)
1986
- # 9 Visibility Distribution (v_d)
2059
+ # 11 Closest Visible Vertex (v_min)
2060
+ v_min = Vertex.Coordinates(closest_vertex, mantissa=mantissa)
2061
+ # 12 Centroid of Isovist (centroid)
2062
+ centroid = Vertex.Coordinates(Topology.Centroid(return_face), mantissa=mantissa)
2063
+
2064
+ # 13 Visibility Distribution (v_d)
1987
2065
  v_d = visibility_distribution(viewpoint, coords)
1988
2066
  v_d = [round(x) for x in v_d]
1989
- # 10 Viewpoint density
1990
- v_density = round(float(len(vertices)) / abs(Face.Area(return_face)), mantissa)
1991
- # 11 Isovist Symmetry
2067
+ # 14 Viewpoint density
2068
+ if abs(Face.Area(return_face)) > 0:
2069
+ v_density = round(float(len(vertices)) / abs(Face.Area(return_face)), mantissa)
2070
+ else:
2071
+ v_density = 0
2072
+ # 15 Isovist Symmetry
1992
2073
  symmetry = round(isovist_symmetry(viewpoint, coords), mantissa)
1993
- # 12 Fractal Dimension
2074
+ # 16 Fractal Dimension
1994
2075
  d_f = round(fractal_dimension(coords), mantissa)
1995
- # 13 Edge Complexity
2076
+ # 17 Edge Complexity
1996
2077
  e_c = round(edge_complexity(coords), mantissa)
1997
- # 14 Mean Visual Field Angle
2078
+ # 18 Mean Visual Field Angle
1998
2079
  theta = round(mean_visual_field_angle(viewpoint, coords), mantissa)
1999
2080
  keys = ["viewpoint",
2000
2081
  "direction",
@@ -2003,7 +2084,11 @@ class Face():
2003
2084
  "perimeter",
2004
2085
  "compactness",
2005
2086
  "d_max",
2087
+ "d_min",
2088
+ "d_avg",
2006
2089
  "v_max",
2090
+ "v_min",
2091
+ "centroid",
2007
2092
  "v_d",
2008
2093
  "v_density",
2009
2094
  "symmetry",
@@ -2011,21 +2096,47 @@ class Face():
2011
2096
  "e_c",
2012
2097
  "theta"]
2013
2098
  values = [viewpoint,
2014
- direction,
2015
- fov,
2016
- area,
2017
- perimeter,
2018
- compactness,
2019
- d_max,
2020
- v_max,
2021
- v_d,
2022
- v_density,
2023
- symmetry,
2024
- d_f,
2025
- e_c,
2026
- theta]
2099
+ direction,
2100
+ fov,
2101
+ area,
2102
+ perimeter,
2103
+ compactness,
2104
+ d_max,
2105
+ d_min,
2106
+ d_avg,
2107
+ v_max,
2108
+ v_min,
2109
+ centroid,
2110
+ v_d,
2111
+ v_density,
2112
+ symmetry,
2113
+ d_f,
2114
+ e_c,
2115
+ theta]
2027
2116
  d = Dictionary.ByKeysValues(keys, values)
2028
2117
  return_face = Topology.SetDictionary(return_face, d)
2118
+ if triangles:
2119
+ triangle_list = []
2120
+ edges = Topology.Edges(return_face)
2121
+ for edge in edges:
2122
+ d = Topology.Dictionary(edge)
2123
+ if Vertex.Distance(Edge.StartVertex(edge), v) > 0.0001:
2124
+ e1 = Edge.ByVertices(Edge.StartVertex(edge), v)
2125
+ if Vertex.Distance(Edge.EndVertex(edge), v) > 0.0001:
2126
+ e2 = Edge.ByVertices(Edge.EndVertex(edge), v)
2127
+ triangle = Topology.SelfMerge(Cluster.ByTopologies(edge, e1, e2))
2128
+ if Topology.IsInstance(triangle, "wire"):
2129
+ if Wire.IsClosed(triangle):
2130
+ triangle = Face.ByWire(triangle, silent=True)
2131
+ if Topology.IsInstance(triangle, "face"):
2132
+ if transferDictionaries == True:
2133
+ triangle = Topology.SetDictionary(triangle, d)
2134
+ tri_edges = Topology.Edges(triangle)
2135
+ for tri_edge in tri_edges:
2136
+ tri_edge = Topology.SetDictionary(tri_edge, d)
2137
+ triangle_list.append(triangle)
2138
+ if len(triangle_list) > 0:
2139
+ return_face = Topology.AddContent(return_face, triangle_list)
2029
2140
  return return_face
2030
2141
 
2031
2142
  @staticmethod
@@ -2466,9 +2577,13 @@ class Face():
2466
2577
  """
2467
2578
  from topologicpy.Wire import Wire
2468
2579
  from topologicpy.Topology import Topology
2469
-
2580
+ import inspect
2581
+
2470
2582
  if not Topology.IsInstance(face, "Face"):
2471
2583
  print("Face.RemoveCollinearEdges - Error: The input face parameter is not a valid face. Returning None.")
2584
+ curframe = inspect.currentframe()
2585
+ calframe = inspect.getouterframes(curframe, 2)
2586
+ print('caller name:', calframe[1][3])
2472
2587
  return None
2473
2588
  eb = Wire.RemoveCollinearEdges(Face.Wire(face), angTolerance=angTolerance, tolerance=tolerance)
2474
2589
  ib = [Wire.RemoveCollinearEdges(w, angTolerance=angTolerance, tolerance=tolerance) for w in Face.InternalBoundaries(face)]
topologicpy/Shell.py CHANGED
@@ -1456,9 +1456,13 @@ class Shell():
1456
1456
  """
1457
1457
  from topologicpy.Face import Face
1458
1458
  from topologicpy.Topology import Topology
1459
-
1459
+ import inspect
1460
+
1460
1461
  if not Topology.IsInstance(shell, "Shell"):
1461
1462
  print("Shell.RemoveCollinearEdges - Error: The input shell parameter is not a valid shell. Returning None.")
1463
+ curframe = inspect.currentframe()
1464
+ calframe = inspect.getouterframes(curframe, 2)
1465
+ print('caller name:', calframe[1][3])
1462
1466
  return None
1463
1467
  faces = Shell.Faces(shell)
1464
1468
  clean_faces = []
topologicpy/Topology.py CHANGED
@@ -4184,7 +4184,6 @@ class Topology():
4184
4184
  from topologicpy.Dictionary import Dictionary
4185
4185
  from topologicpy.Helper import Helper
4186
4186
  import inspect
4187
- print("input topologies:", topologies)
4188
4187
 
4189
4188
  topologies_list = []
4190
4189
  if Topology.IsInstance(topologies, "Topology"):
@@ -6749,8 +6748,13 @@ class Topology():
6749
6748
  from topologicpy.Cell import Cell
6750
6749
  from topologicpy.CellComplex import CellComplex
6751
6750
  from topologicpy.Cluster import Cluster
6752
-
6751
+ import inspect
6753
6752
  if not Topology.IsInstance(topology, "Topology"):
6753
+ if not silent:
6754
+ print("Topology.RemoveCollinearEdges - Error: The input topology parameter is not a valid topology. Returning None.")
6755
+ curframe = inspect.currentframe()
6756
+ calframe = inspect.getouterframes(curframe, 2)
6757
+ print('caller name:', calframe[1][3])
6754
6758
  return None
6755
6759
  return_topology = topology
6756
6760
  if Topology.IsInstance(topology, "Vertex") or Topology.IsInstance(topology, "Edge"): #Vertex or Edge or Cluster, return the original topology
@@ -6776,7 +6780,7 @@ class Topology():
6776
6780
  topologies += Cluster.FreeEdges(topology)
6777
6781
  faces = Topology.Faces(topology)
6778
6782
  for face in faces:
6779
- topologies.append(Face.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance))
6783
+ topologies.append(Face.RemoveCollinearEdges(face, angTolerance=angTolerance, tolerance=tolerance))
6780
6784
  return_topology = Topology.SelfMerge(Cluster.ByTopologies(topologies), tolerance=tolerance)
6781
6785
  return return_topology
6782
6786
 
@@ -9045,7 +9049,7 @@ class Topology():
9045
9049
  r_shells = Topology.Shells(return_topology)
9046
9050
  r_cells = Topology.Cells(return_topology)
9047
9051
  r_cellComplexes = Topology.CellComplexes(return_topology)
9048
-
9052
+
9049
9053
  for i, t in enumerate(r_vertices):
9050
9054
  t = Topology.SetDictionary(t, Topology.Dictionary(vertices[i]), silent=True)
9051
9055
  for i, t in enumerate(r_edges):
topologicpy/Vertex.py CHANGED
@@ -1110,13 +1110,18 @@ class Vertex():
1110
1110
  import inspect
1111
1111
 
1112
1112
  if not Topology.IsInstance(vertex, "Vertex"):
1113
- print("Called from:", inspect.stack()[1][3])
1114
1113
  if not silent:
1115
1114
  print("Vertex.IsInternal - Error: The input vertex parameter is not a valid vertex. Returning None.", vertex, topology)
1115
+ curframe = inspect.currentframe()
1116
+ calframe = inspect.getouterframes(curframe, 2)
1117
+ print('caller name:', calframe[1][3])
1116
1118
  return None
1117
1119
  if not Topology.IsInstance(topology, "Topology"):
1118
1120
  if not silent:
1119
1121
  print("Vertex.IsInternal - Error: The input topology parameter is not a valid topology. Returning None.")
1122
+ curframe = inspect.currentframe()
1123
+ calframe = inspect.getouterframes(curframe, 2)
1124
+ print('caller name:', calframe[1][3])
1120
1125
  return None
1121
1126
 
1122
1127
  if Topology.IsInstance(topology, "Vertex"):
@@ -1178,7 +1183,6 @@ class Vertex():
1178
1183
  return False
1179
1184
  return False
1180
1185
 
1181
-
1182
1186
  @staticmethod
1183
1187
  def IsPeripheral(vertex, topology, tolerance: float = 0.0001, silent: bool = False) -> bool:
1184
1188
  """
topologicpy/Wire.py CHANGED
@@ -2966,12 +2966,107 @@ class Wire():
2966
2966
  if direction != [0, 0, 1]:
2967
2967
  baseWire = Topology.Orient(baseWire, origin=origin, dirA=[0, 0, 1], dirB=direction)
2968
2968
  return baseWire
2969
-
2969
+
2970
+
2970
2971
  @staticmethod
2971
2972
  def RemoveCollinearEdges(wire, angTolerance: float = 0.1, tolerance: float = 0.0001, silent: bool = False):
2972
2973
  """
2973
2974
  Removes any collinear edges in the input wire.
2974
2975
 
2976
+ Parameters
2977
+ ----------
2978
+ wire : topologic_core.Wire
2979
+ The input wire.
2980
+ angTolerance : float, optional
2981
+ The desired angular tolerance. The default is 0.1.
2982
+ tolerance : float, optional
2983
+ The desired tolerance. The default is 0.0001.
2984
+ silent : bool, optional
2985
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
2986
+
2987
+ Returns
2988
+ -------
2989
+ topologic_core.Wire
2990
+ The wire without collinear edges, or the original wire if no modifications were necessary.
2991
+ """
2992
+ from topologicpy.Vertex import Vertex
2993
+ from topologicpy.Edge import Edge
2994
+ from topologicpy.Wire import Wire
2995
+ from topologicpy.Cluster import Cluster
2996
+ from topologicpy.Topology import Topology
2997
+
2998
+ def cleanup(wire):
2999
+ """Fuses vertices and removes edges below the tolerance distance."""
3000
+ vertices = Vertex.Fuse(Topology.Vertices(wire), tolerance=tolerance)
3001
+ edges = Topology.Edges(wire)
3002
+ new_edges = []
3003
+
3004
+ for edge in edges:
3005
+ sv = vertices[Vertex.Index(Edge.StartVertex(edge), vertices, tolerance=tolerance)]
3006
+ ev = vertices[Vertex.Index(Edge.EndVertex(edge), vertices, tolerance=tolerance)]
3007
+ if Vertex.Distance(sv, ev) > tolerance:
3008
+ new_edges.append(Edge.ByVertices([sv, ev]))
3009
+
3010
+ return Topology.SelfMerge(Cluster.ByTopologies(new_edges, silent=silent), tolerance=tolerance) if new_edges else wire
3011
+
3012
+ def remove_collinear_vertices(wire):
3013
+ """Removes collinear vertices from a wire."""
3014
+ if not Topology.IsInstance(wire, "Wire"):
3015
+ return wire
3016
+
3017
+ vertices = Topology.Vertices(wire)
3018
+ filtered_vertices = []
3019
+
3020
+ for i, vertex in enumerate(vertices):
3021
+ edges = Topology.SuperTopologies(topology=vertex, hostTopology=wire, topologyType="edge")
3022
+
3023
+ if len(edges) != 2:
3024
+ filtered_vertices.append(vertex)
3025
+ elif not Edge.IsCollinear(edges[0], edges[1], tolerance=tolerance):
3026
+ filtered_vertices.append(vertex)
3027
+
3028
+ if len(filtered_vertices) > 2:
3029
+ return Wire.ByVertices(filtered_vertices, close=wire.IsClosed())
3030
+ elif len(filtered_vertices) == 2:
3031
+ return Edge.ByStartVertexEndVertex(filtered_vertices[0], filtered_vertices[1], tolerance=tolerance, silent=True)
3032
+ else:
3033
+ return wire
3034
+
3035
+ # Main function logic
3036
+ if Topology.IsInstance(wire, "Cluster"):
3037
+ wires = Topology.Wires(wire)
3038
+ processed_wires = [Wire.RemoveCollinearEdges(w, angTolerance, tolerance, silent) for w in wires]
3039
+ if len(processed_wires) == 0:
3040
+ if not silent:
3041
+ print("Wire.RemoveCollinearEdges - Error: No wires were produced. Returning None.")
3042
+ return None
3043
+ elif len(processed_wires) == 1:
3044
+ return Topology.SelfMerge(processed_wires[0])
3045
+ else:
3046
+ return Topology.SelfMerge(Cluster.ByTopologies(processed_wires, silent=silent))
3047
+
3048
+ if not Topology.IsInstance(wire, "Wire"):
3049
+ if not silent:
3050
+ print(f"Wire.RemoveCollinearEdges - Error: Input is not a valid wire. Returning None.")
3051
+ return None
3052
+
3053
+ new_wire = cleanup(wire)
3054
+ wires = Wire.Split(new_wire) if not Wire.IsManifold(new_wire) else [new_wire]
3055
+
3056
+ processed_wires = [remove_collinear_vertices(w) for w in wires]
3057
+
3058
+ if len(processed_wires) == 0:
3059
+ return wire
3060
+ elif len(processed_wires) == 1:
3061
+ return Topology.SelfMerge(processed_wires[0])
3062
+ else:
3063
+ return Topology.SelfMerge(Cluster.ByTopologies(processed_wires, silent=silent))
3064
+
3065
+ @staticmethod
3066
+ def RemoveCollinearEdges_old(wire, angTolerance: float = 0.1, tolerance: float = 0.0001, silent: bool = False):
3067
+ """
3068
+ Removes any collinear edges in the input wire.
3069
+
2975
3070
  Parameters
2976
3071
  ----------
2977
3072
  wire : topologic_core.Wire
@@ -3051,8 +3146,6 @@ class Wire():
3051
3146
  return result
3052
3147
  if not Topology.IsInstance(wire, "Wire"):
3053
3148
  if not silent:
3054
- print("The wire is:", wire)
3055
- Topology.Show(wire)
3056
3149
  print("Wire.RemoveCollinearEdges - Error: The input wire parameter is not a valid wire. Returning None.")
3057
3150
  curframe = inspect.currentframe()
3058
3151
  calframe = inspect.getouterframes(curframe, 2)
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.82'
1
+ __version__ = '0.7.84'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.82
3
+ Version: 0.7.84
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
@@ -1,16 +1,16 @@
1
1
  topologicpy/ANN.py,sha256=m_WxD1lgQqDhUpaM20Lia6TmJACDYaAE96wigsi-99U,47932
2
2
  topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
3
  topologicpy/BVH.py,sha256=mKVCAu9K8qzcWXtPDVH5usXZV1DNNNJl4n3rU5Lh1ZM,12931
4
- topologicpy/Cell.py,sha256=2izd-YGqy897_JHHgrGlIo5WwUeEIWVD3KspV1z_sj8,107860
5
- topologicpy/CellComplex.py,sha256=5PtnRrDx_3zmtt4aTosxK9XBzZtayzaOC50pkJiIlFY,51170
4
+ topologicpy/Cell.py,sha256=j6e0Hk5GVlCPXhwc39Qo3pSpWZF4nv4uCZojdg3uXO8,108046
5
+ topologicpy/CellComplex.py,sha256=DbSiVZ-_J8vXud1cm69p9Te9sTJUB-_zE3rgbhqKw5E,51424
6
6
  topologicpy/Cluster.py,sha256=51q5G1L5xAzRMfVU8YBXhq0g3g2X9aVNcahU-vYZRrI,55672
7
7
  topologicpy/Color.py,sha256=wPhA7rLr9BTZsWYUUVnQpbmL5ZMkGlDSsa8f3S5B-d4,20250
8
8
  topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
9
9
  topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
10
10
  topologicpy/Dictionary.py,sha256=0AsGoz48pGTye_F4KcJopNjD9STeQ50LHc6PPvERFaA,31932
11
- topologicpy/Edge.py,sha256=9u9SdUxuenLUIK26xwFvPoYV34p0dCfXmHHBxdgvAdM,67164
11
+ topologicpy/Edge.py,sha256=k71TGaJRERI2vgygDu-pYprUgu49N9UApcCxCorQyzc,67185
12
12
  topologicpy/EnergyModel.py,sha256=AqTtmXE35SxvRXhG3vYAQd7GQDW-6HtjYPHua6ME4Eg,53762
13
- topologicpy/Face.py,sha256=Y13hw84bjJO8bzEG7sB7PRDxcSqqmGZnNAbIhIUQ1Ys,136243
13
+ topologicpy/Face.py,sha256=IAAueOqHOw3Kn_ZPxxBKgVgC5fFdcuiLMC1HeOPI92Y,142159
14
14
  topologicpy/Graph.py,sha256=ZhMVB6ntuhIgTrKLUPryeAJFFBF0cnRsNgESbaohOiw,416914
15
15
  topologicpy/Grid.py,sha256=9N6PE84qCm40TRi2WtlVZSBwXXr47zHpscEpZHg_JW4,18205
16
16
  topologicpy/Helper.py,sha256=vUWbnZJxn0e9YsFUNyJ5Dee8Nh6TmDp9uCzCk4e0qAA,21897
@@ -20,17 +20,17 @@ topologicpy/Neo4j.py,sha256=t52hgE9cVsqkGc7m7fjRsLnyfRHakVHwdvF4ms7ow78,22342
20
20
  topologicpy/Plotly.py,sha256=z7xs9Ra2OwJNv5NMapH27R6didS8UMpjZIN35ZnAQcE,113501
21
21
  topologicpy/Polyskel.py,sha256=EFsuh2EwQJGPLiFUjvtXmAwdX-A4r_DxP5hF7Qd3PaU,19829
22
22
  topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
23
- topologicpy/Shell.py,sha256=8OJjlWk9eCZ3uGOTht6ZVrcMczCafw-YWoDGueaz7eg,87673
23
+ topologicpy/Shell.py,sha256=xYpGxQ1x7hKVYD03_zhEY77lbDAsffttKYZWKiZAsNs,87859
24
24
  topologicpy/Speckle.py,sha256=AlsGlSDuKRtX5jhVsPNSSjjbZis079HbUchDH_5RJmE,18187
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
- topologicpy/Topology.py,sha256=nTthwB8vmfdpfoP8tTQCUhHr29WhjuV7l0btAI1rHkQ,433216
26
+ topologicpy/Topology.py,sha256=9X9Y2Y1tXe_oefNp6oQRG6v7ZgmIec5pZ7KiBxSXKNY,433499
27
27
  topologicpy/Vector.py,sha256=A1g83zDHep58iVPY8WQ8iHNrSOfGWFEzvVeDuMnjDNY,33078
28
- topologicpy/Vertex.py,sha256=mcLJaWFCct03dkVmT25wAl6k0k2EaYvB1PWNO9WQHWg,73465
29
- topologicpy/Wire.py,sha256=o6MlOjubkJ_f5s1tUamizCsoPKvcQ2OudtJv0yCF-2o,186477
28
+ topologicpy/Vertex.py,sha256=7oEu6xXl1vi8M_HFnPT66W8OO8Eb3eab2oKvgzzLK-A,73737
29
+ topologicpy/Wire.py,sha256=e9vN5nRIUIqwA0bElVB6Vrto862OXJ97iDHhc-JEt3s,190501
30
30
  topologicpy/__init__.py,sha256=vlPCanUbxe5NifC4pHcnhSzkmmYcs_UrZrTlVMsxcFs,928
31
- topologicpy/version.py,sha256=rXEi2ZZcGFgf2u3AMH7tyJUFE9nvS8L279fdB54xeCk,23
32
- topologicpy-0.7.82.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
- topologicpy-0.7.82.dist-info/METADATA,sha256=CZZqWePZAWM-hGdFkhmjQf9qbm3Ub_fKCPzHnu7RYvk,10513
34
- topologicpy-0.7.82.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
- topologicpy-0.7.82.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.7.82.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=U66vZMAESD9QWsvrRbFl3J6Cqc8Xv9QpUU903eulUJI,23
32
+ topologicpy-0.7.84.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
+ topologicpy-0.7.84.dist-info/METADATA,sha256=WKYqAGNwpDTkn9KOQDEUQkV7w5v-v4jCEuzpnemh7Cs,10513
34
+ topologicpy-0.7.84.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
+ topologicpy-0.7.84.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.7.84.dist-info/RECORD,,