topologicpy 0.7.82__py3-none-any.whl → 0.7.83__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/Face.py CHANGED
@@ -1623,10 +1623,10 @@ class Face():
1623
1623
  return None
1624
1624
 
1625
1625
  if not Topology.IsInstance(faceA, "Face"):
1626
- print("Face.IsInside - Error: The input faceA parameter is not a valid topologic face. Returning None.")
1626
+ print("Face.IsCoplanar - Error: The input faceA parameter is not a valid topologic face. Returning None.")
1627
1627
  return None
1628
1628
  if not Topology.IsInstance(faceB, "Face"):
1629
- print("Face.IsInside - Error: The input faceB parameter is not a valid topologic face. Returning None.")
1629
+ print("Face.IsCoplanar - Error: The input faceB parameter is not a valid topologic face. Returning None.")
1630
1630
  return None
1631
1631
 
1632
1632
  def normalize_plane_coefficients(plane):
@@ -1649,7 +1649,7 @@ class Face():
1649
1649
  return are_planes_coplanar(plane_a, plane_b, tolerance=tolerance)
1650
1650
 
1651
1651
  @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):
1652
+ 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
1653
  """
1654
1654
  Returns the face representing the isovist projection from the input viewpoint.
1655
1655
  This method assumes all input is in 2D. Z coordinates are ignored.
@@ -1682,7 +1682,11 @@ class Face():
1682
1682
  - perimeter : float , the perimeter length of the isovist
1683
1683
  - compactness : float , how closely the shape of the isovist approximates a circle (the most compact geometric shape).
1684
1684
  - d_max : float, Maximum Visibility Distance. the length of the longest straight line that can be seen from the viewpoint.
1685
+ - d_min : float, Minimum Visibility Distance. the length of the shortest straight line that can be seen from the viewpoint.
1686
+ - d_avg : float, Average Visibility Distance. the length of the average straight line that can be seen from the viewpoint.
1685
1687
  - v_max : list, Furthest Point measures the x , y , z coordinates of the furthest visible point from the viewpoint.
1688
+ - v_min : list, Closest Point measures the x , y , z coordinates of the closest visible point from the viewpoint.
1689
+ - centroid: list, Centroid measures the x, y, z coordinates of the centroid of the isovist face.
1686
1690
  - v_d : list, Visibility Distribution quantifies the angular distribution (in degrees) of visible points across the isovist.
1687
1691
  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
1692
  - v_density : float, Viewpoint Density which refers to the number of visible points per unit area within the isovist.
@@ -1690,6 +1694,8 @@ class Face():
1690
1694
  - d_f : float, Fractal Dimension measures the complexity of the isovist's boundary.
1691
1695
  - e_c : float , Edge Complexity measures how complex the edges of the isovist boundary are.
1692
1696
  - theta : float, Mean Visual Field Angle measures the average angular extent of the visible area from the observation point.
1697
+ triangles : bool , optional
1698
+ 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
1699
  mantissa : int , optional
1694
1700
  The desired length of the mantissa. The default is 6.
1695
1701
  tolerance : float , optional:
@@ -1855,6 +1861,42 @@ class Face():
1855
1861
  else:
1856
1862
  obstacles = []
1857
1863
 
1864
+ def closest_distance_vertex(vertex, edge, mantissa):
1865
+ point = Vertex.Coordinates(vertex, mantissa=mantissa)
1866
+ line_start = Vertex.Coordinates(Edge.StartVertex(edge), mantissa=mantissa)
1867
+ line_end = Vertex.Coordinates(Edge.EndVertex(edge), mantissa=mantissa)
1868
+
1869
+ # Convert input points to NumPy arrays for vector operations
1870
+ point = np.array(point)
1871
+ line_start = np.array(line_start)
1872
+ line_end = np.array(line_end)
1873
+
1874
+ # Calculate the direction vector of the edge
1875
+ line_direction = line_end - line_start
1876
+
1877
+ # Vector from the edge's starting point to the point
1878
+ point_to_start = point - line_start
1879
+
1880
+ # Calculate the parameter 't' where the projection of the point onto the edge occurs
1881
+ if np.dot(line_direction, line_direction) == 0:
1882
+ t = 0
1883
+ else:
1884
+ t = np.dot(point_to_start, line_direction) / np.dot(line_direction, line_direction)
1885
+
1886
+ # Check if 't' is outside the range [0, 1], and if so, calculate distance to closest endpoint
1887
+ if t < 0:
1888
+ t = 0
1889
+ elif t > 1:
1890
+ t = 1
1891
+
1892
+ # Calculate the closest point on the edge to the given point
1893
+ closest_point = line_start + t * line_direction
1894
+
1895
+ # Calculate the distance between the closest point and the given point
1896
+ distance = np.linalg.norm(point - closest_point)
1897
+
1898
+ return float(distance), Vertex.ByCoordinates(list(closest_point))
1899
+
1858
1900
  origin = Topology.Centroid(face)
1859
1901
  normal = Face.Normal(face)
1860
1902
  flat_face = Topology.Flatten(face, origin=origin, direction=normal)
@@ -1879,6 +1921,10 @@ class Face():
1879
1921
  for obs in flat_obstacles:
1880
1922
  flat_face = Topology.Difference(flat_face, Face.ByWire(obs))
1881
1923
 
1924
+ # Check that the viewpoint is inside the face
1925
+ if not Vertex.IsInternal(flat_vertex, flat_face):
1926
+ print("Face.Isovist - Error: The viewpoint is not inside the face. Returning None.")
1927
+ return None
1882
1928
  targets = Topology.Vertices(flat_face)
1883
1929
  distances = []
1884
1930
  for target in targets:
@@ -1958,6 +2004,8 @@ class Face():
1958
2004
  return_face = Topology.Unflatten(simpler_face, origin=origin, direction=normal)
1959
2005
  return_face = Topology.Unflatten(return_face, origin=origin, direction=normal)
1960
2006
  if metrics == True:
2007
+ vertices = Topology.Vertices(return_face)
2008
+ edges = Topology.Edges(return_face)
1961
2009
  # 1 Viewpoint
1962
2010
  viewpoint = Vertex.Coordinates(vertex, mantissa=mantissa)
1963
2011
  # 2 Direction
@@ -1971,30 +2019,59 @@ class Face():
1971
2019
  # 6 Compactness
1972
2020
  compactness = round(Face.Compactness(return_face), mantissa)
1973
2021
  # 7 Maximum Distance (d_max)
1974
- vertices = Topology.Vertices(return_face)
1975
- furthest_vertex = vertices[0]
2022
+ # 8 Minimum Distance (d_min)
2023
+ # 9 Average Distance (d_avg)
2024
+ # 10 Furthest Visible Vertex (v_max)
2025
+ # 11 Closest Visible Vertex (v_min)
1976
2026
  d_max = round(Vertex.Distance(vertex, vertices[0]), mantissa)
1977
- # 8 Furthest Visible Vertex
2027
+ d_min = round(Vertex.Distance(vertex, vertices[0]), mantissa)
2028
+ furthest_vertex = vertices[0]
2029
+ closest_vertex = vertices[0]
1978
2030
  coords = []
2031
+ distances = []
1979
2032
  for v in vertices:
1980
2033
  coords.append(Vertex.Coordinates(v, mantissa=mantissa))
1981
2034
  dis = Vertex.Distance(vertex, v, mantissa=mantissa)
2035
+ distances.append(dis)
1982
2036
  if dis > d_max:
1983
2037
  d_max = dis
1984
2038
  furthest_vertex = v
2039
+ distances = []
2040
+ edges = Topology.Edges(Cluster.ByTopologies([face]+obstacles))
2041
+ for edge in edges:
2042
+ dis, c_v = closest_distance_vertex(vertex, edge, mantissa=mantissa)
2043
+ if dis < d_min and Vertex.IsPeripheral(c_v, return_face):
2044
+ d_min = dis
2045
+ closest_vertex = c_v
2046
+
2047
+ # 12 Average Visible Distance
2048
+ if len(distances) > 0:
2049
+ d_avg = sum(distances)/float(len(distances))
2050
+ else:
2051
+ d_avg = 0
2052
+
2053
+ # 10 Furthest Visible Vertex (v_max)
1985
2054
  v_max = Vertex.Coordinates(furthest_vertex, mantissa=mantissa)
1986
- # 9 Visibility Distribution (v_d)
2055
+ # 11 Closest Visible Vertex (v_min)
2056
+ v_min = Vertex.Coordinates(closest_vertex, mantissa=mantissa)
2057
+ # 12 Centroid of Isovist (centroid)
2058
+ centroid = Vertex.Coordinates(Topology.Centroid(return_face), mantissa=mantissa)
2059
+
2060
+ # 13 Visibility Distribution (v_d)
1987
2061
  v_d = visibility_distribution(viewpoint, coords)
1988
2062
  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
2063
+ # 14 Viewpoint density
2064
+ if abs(Face.Area(return_face)) > 0:
2065
+ v_density = round(float(len(vertices)) / abs(Face.Area(return_face)), mantissa)
2066
+ else:
2067
+ v_density = 0
2068
+ # 15 Isovist Symmetry
1992
2069
  symmetry = round(isovist_symmetry(viewpoint, coords), mantissa)
1993
- # 12 Fractal Dimension
2070
+ # 16 Fractal Dimension
1994
2071
  d_f = round(fractal_dimension(coords), mantissa)
1995
- # 13 Edge Complexity
2072
+ # 17 Edge Complexity
1996
2073
  e_c = round(edge_complexity(coords), mantissa)
1997
- # 14 Mean Visual Field Angle
2074
+ # 18 Mean Visual Field Angle
1998
2075
  theta = round(mean_visual_field_angle(viewpoint, coords), mantissa)
1999
2076
  keys = ["viewpoint",
2000
2077
  "direction",
@@ -2003,7 +2080,11 @@ class Face():
2003
2080
  "perimeter",
2004
2081
  "compactness",
2005
2082
  "d_max",
2083
+ "d_min",
2084
+ "d_avg",
2006
2085
  "v_max",
2086
+ "v_min",
2087
+ "centroid",
2007
2088
  "v_d",
2008
2089
  "v_density",
2009
2090
  "symmetry",
@@ -2011,21 +2092,47 @@ class Face():
2011
2092
  "e_c",
2012
2093
  "theta"]
2013
2094
  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]
2095
+ direction,
2096
+ fov,
2097
+ area,
2098
+ perimeter,
2099
+ compactness,
2100
+ d_max,
2101
+ d_min,
2102
+ d_avg,
2103
+ v_max,
2104
+ v_min,
2105
+ centroid,
2106
+ v_d,
2107
+ v_density,
2108
+ symmetry,
2109
+ d_f,
2110
+ e_c,
2111
+ theta]
2027
2112
  d = Dictionary.ByKeysValues(keys, values)
2028
2113
  return_face = Topology.SetDictionary(return_face, d)
2114
+ if triangles:
2115
+ triangle_list = []
2116
+ edges = Topology.Edges(return_face)
2117
+ for edge in edges:
2118
+ d = Topology.Dictionary(edge)
2119
+ if Vertex.Distance(Edge.StartVertex(edge), v) > 0.0001:
2120
+ e1 = Edge.ByVertices(Edge.StartVertex(edge), v)
2121
+ if Vertex.Distance(Edge.EndVertex(edge), v) > 0.0001:
2122
+ e2 = Edge.ByVertices(Edge.EndVertex(edge), v)
2123
+ triangle = Topology.SelfMerge(Cluster.ByTopologies(edge, e1, e2))
2124
+ if Topology.IsInstance(triangle, "wire"):
2125
+ if Wire.IsClosed(triangle):
2126
+ triangle = Face.ByWire(triangle, silent=True)
2127
+ if Topology.IsInstance(triangle, "face"):
2128
+ if transferDictionaries == True:
2129
+ triangle = Topology.SetDictionary(triangle, d)
2130
+ tri_edges = Topology.Edges(triangle)
2131
+ for tri_edge in tri_edges:
2132
+ tri_edge = Topology.SetDictionary(tri_edge, d)
2133
+ triangle_list.append(triangle)
2134
+ if len(triangle_list) > 0:
2135
+ return_face = Topology.AddContent(return_face, triangle_list)
2029
2136
  return return_face
2030
2137
 
2031
2138
  @staticmethod
topologicpy/Vertex.py CHANGED
@@ -1178,7 +1178,6 @@ class Vertex():
1178
1178
  return False
1179
1179
  return False
1180
1180
 
1181
-
1182
1181
  @staticmethod
1183
1182
  def IsPeripheral(vertex, topology, tolerance: float = 0.0001, silent: bool = False) -> bool:
1184
1183
  """
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.82'
1
+ __version__ = '0.7.83'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.82
3
+ Version: 0.7.83
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
@@ -10,7 +10,7 @@ topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
10
10
  topologicpy/Dictionary.py,sha256=0AsGoz48pGTye_F4KcJopNjD9STeQ50LHc6PPvERFaA,31932
11
11
  topologicpy/Edge.py,sha256=9u9SdUxuenLUIK26xwFvPoYV34p0dCfXmHHBxdgvAdM,67164
12
12
  topologicpy/EnergyModel.py,sha256=AqTtmXE35SxvRXhG3vYAQd7GQDW-6HtjYPHua6ME4Eg,53762
13
- topologicpy/Face.py,sha256=Y13hw84bjJO8bzEG7sB7PRDxcSqqmGZnNAbIhIUQ1Ys,136243
13
+ topologicpy/Face.py,sha256=tfsm7RSYZ7UbKAhUlUqfPQX4_96UuTJXXo6okTU9lm8,141831
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
@@ -25,12 +25,12 @@ topologicpy/Speckle.py,sha256=AlsGlSDuKRtX5jhVsPNSSjjbZis079HbUchDH_5RJmE,18187
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
26
  topologicpy/Topology.py,sha256=nTthwB8vmfdpfoP8tTQCUhHr29WhjuV7l0btAI1rHkQ,433216
27
27
  topologicpy/Vector.py,sha256=A1g83zDHep58iVPY8WQ8iHNrSOfGWFEzvVeDuMnjDNY,33078
28
- topologicpy/Vertex.py,sha256=mcLJaWFCct03dkVmT25wAl6k0k2EaYvB1PWNO9WQHWg,73465
28
+ topologicpy/Vertex.py,sha256=uHBSDrU5Wc3Eg8_-Se0czcTKNmhhBORUw7c3Mo0ZRz4,73460
29
29
  topologicpy/Wire.py,sha256=o6MlOjubkJ_f5s1tUamizCsoPKvcQ2OudtJv0yCF-2o,186477
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=Uj6-kAXgUUYCxdsrUyFr-xt-NFJYmXeo-tJWkJPzKSE,23
32
+ topologicpy-0.7.83.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
+ topologicpy-0.7.83.dist-info/METADATA,sha256=k4zYNOlhOqX64ck0YBOhF1u0LdmVQkO1uyiJl6n71HU,10513
34
+ topologicpy-0.7.83.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
+ topologicpy-0.7.83.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.7.83.dist-info/RECORD,,