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 +133 -26
- topologicpy/Vertex.py +0 -1
- topologicpy/version.py +1 -1
- {topologicpy-0.7.82.dist-info → topologicpy-0.7.83.dist-info}/METADATA +1 -1
- {topologicpy-0.7.82.dist-info → topologicpy-0.7.83.dist-info}/RECORD +8 -8
- {topologicpy-0.7.82.dist-info → topologicpy-0.7.83.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.82.dist-info → topologicpy-0.7.83.dist-info}/WHEEL +0 -0
- {topologicpy-0.7.82.dist-info → topologicpy-0.7.83.dist-info}/top_level.txt +0 -0
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.
|
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.
|
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
|
-
|
1975
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
#
|
1990
|
-
|
1991
|
-
|
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
|
-
#
|
2070
|
+
# 16 Fractal Dimension
|
1994
2071
|
d_f = round(fractal_dimension(coords), mantissa)
|
1995
|
-
#
|
2072
|
+
# 17 Edge Complexity
|
1996
2073
|
e_c = round(edge_complexity(coords), mantissa)
|
1997
|
-
#
|
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
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
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
topologicpy/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.7.
|
1
|
+
__version__ = '0.7.83'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.7.
|
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=
|
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=
|
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=
|
32
|
-
topologicpy-0.7.
|
33
|
-
topologicpy-0.7.
|
34
|
-
topologicpy-0.7.
|
35
|
-
topologicpy-0.7.
|
36
|
-
topologicpy-0.7.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|