topologicpy 0.8.54__py3-none-any.whl → 0.8.57__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/Graph.py +220 -3
- topologicpy/Honeybee.py +527 -2
- topologicpy/Kuzu.py +589 -0
- topologicpy/Vertex.py +78 -48
- topologicpy/version.py +1 -1
- {topologicpy-0.8.54.dist-info → topologicpy-0.8.57.dist-info}/METADATA +1 -1
- {topologicpy-0.8.54.dist-info → topologicpy-0.8.57.dist-info}/RECORD +10 -9
- {topologicpy-0.8.54.dist-info → topologicpy-0.8.57.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.54.dist-info → topologicpy-0.8.57.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.54.dist-info → topologicpy-0.8.57.dist-info}/top_level.txt +0 -0
topologicpy/Vertex.py
CHANGED
@@ -1818,6 +1818,7 @@ class Vertex():
|
|
1818
1818
|
pt = project_point_onto_plane(Vertex.Coordinates(vertex), [eq["a"], eq["b"], eq["c"], eq["d"]], direction)
|
1819
1819
|
return Vertex.ByCoordinates(pt[0], pt[1], pt[2])
|
1820
1820
|
|
1821
|
+
|
1821
1822
|
@staticmethod
|
1822
1823
|
def Separate(*vertices, minDistance: float = 0.0001, iterations: int = 100, strength: float = 0.1, tolerance: float = 0.0001, silent: bool = False):
|
1823
1824
|
"""
|
@@ -1846,68 +1847,97 @@ class Vertex():
|
|
1846
1847
|
"""
|
1847
1848
|
from topologicpy.Topology import Topology
|
1848
1849
|
from topologicpy.Helper import Helper
|
1850
|
+
from topologicpy.Vertex import Vertex
|
1849
1851
|
import math
|
1852
|
+
from collections import defaultdict
|
1850
1853
|
|
1854
|
+
# --- Gather & validate inputs ---
|
1851
1855
|
if len(vertices) == 0:
|
1852
1856
|
if not silent:
|
1853
1857
|
print("Vertex.Separate - Error: The input vertices parameter is an empty list. Returning None.")
|
1854
1858
|
return None
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
if not silent:
|
1860
|
-
print("Vertex.Separate - Error: The input vertices parameter is an empty list. Returning None.")
|
1861
|
-
return None
|
1862
|
-
else:
|
1863
|
-
vertexList = [x for x in vertices if Topology.IsInstance(x, "Vertex")]
|
1864
|
-
if len(vertexList) == 0:
|
1865
|
-
if not silent:
|
1866
|
-
print("Vertex.Separate - Error: The input vertices parameter does not contain any valid vertices. Returning None.")
|
1867
|
-
return None
|
1868
|
-
else:
|
1869
|
-
if not silent:
|
1870
|
-
print("Vertex.Separate - Warning: The input vertices parameter contains only one vertex. Returning the same vertex.")
|
1871
|
-
return vertices
|
1859
|
+
|
1860
|
+
# Allow either a single list or varargs
|
1861
|
+
if len(vertices) == 1 and isinstance(vertices[0], list):
|
1862
|
+
raw_list = vertices[0]
|
1872
1863
|
else:
|
1873
|
-
|
1874
|
-
|
1864
|
+
raw_list = Helper.Flatten(list(vertices))
|
1865
|
+
|
1866
|
+
vertexList = [v for v in raw_list if Topology.IsInstance(v, "Vertex")]
|
1875
1867
|
if len(vertexList) == 0:
|
1876
1868
|
if not silent:
|
1877
1869
|
print("Vertex.Separate - Error: The input parameters do not contain any valid vertices. Returning None.")
|
1878
1870
|
return None
|
1871
|
+
if len(vertexList) == 1:
|
1872
|
+
if not silent:
|
1873
|
+
print("Vertex.Separate - Warning: Only one vertex supplied. Returning it unchanged.")
|
1874
|
+
return vertexList
|
1875
|
+
|
1876
|
+
minDistance = float(minDistance) + float(tolerance) # safety margin
|
1877
|
+
n = len(vertexList)
|
1878
|
+
|
1879
|
+
# Mutable coordinates
|
1880
|
+
coords = [[vertexList[i].X(), vertexList[i].Y(), vertexList[i].Z()] for i in range(n)]
|
1881
|
+
dicts = [Topology.Dictionary(v) for v in vertexList]
|
1882
|
+
|
1883
|
+
# --- Pre-seed coincident vertices so they can start moving ---
|
1884
|
+
# Cluster indices by quantized coordinate to catch exact (or near-exact) duplicates
|
1885
|
+
key_scale = max(tolerance, 1e-12)
|
1886
|
+
clusters = defaultdict(list)
|
1887
|
+
for idx, (x, y, z) in enumerate(coords):
|
1888
|
+
key = (round(x / key_scale), round(y / key_scale), round(z / key_scale))
|
1889
|
+
clusters[key].append(idx)
|
1890
|
+
|
1891
|
+
# For any cluster with >1 vertex, spread them on a small circle in XY
|
1892
|
+
for idxs in clusters.values():
|
1893
|
+
k = len(idxs)
|
1894
|
+
if k > 1:
|
1895
|
+
r = minDistance * 0.5 # small initial spread; repulsion will take it from here
|
1896
|
+
for m, idx in enumerate(idxs):
|
1897
|
+
ang = (2.0 * math.pi * m) / k
|
1898
|
+
coords[idx][0] += r * math.cos(ang)
|
1899
|
+
coords[idx][1] += r * math.sin(ang)
|
1900
|
+
# leave Z unchanged to avoid unintended vertical drift
|
1901
|
+
|
1902
|
+
# --- Repulsion simulation ---
|
1903
|
+
eps = 1e-12
|
1904
|
+
for _ in range(int(iterations)):
|
1905
|
+
all_ok = True
|
1906
|
+
for i in range(n):
|
1907
|
+
xi, yi, zi = coords[i]
|
1908
|
+
for j in range(i + 1, n):
|
1909
|
+
xj, yj, zj = coords[j]
|
1910
|
+
dx = xj - xi
|
1911
|
+
dy = yj - yi
|
1912
|
+
dz = zj - zi
|
1913
|
+
dist_sq = dx*dx + dy*dy + dz*dz
|
1914
|
+
if dist_sq <= 0.0:
|
1915
|
+
# still coincident: nudge with a tiny deterministic push along x
|
1916
|
+
dx, dy, dz = (eps, 0.0, 0.0)
|
1917
|
+
dist_sq = eps*eps
|
1918
|
+
dist = math.sqrt(dist_sq)
|
1919
|
+
|
1920
|
+
if dist < minDistance:
|
1921
|
+
all_ok = False
|
1922
|
+
# Repulsion magnitude; clamp denominator to avoid blow-ups
|
1923
|
+
repel = (minDistance - dist) / max(dist, eps) * float(strength)
|
1924
|
+
# Split the move equally
|
1925
|
+
sx = 0.5 * dx * repel
|
1926
|
+
sy = 0.5 * dy * repel
|
1927
|
+
sz = 0.5 * dz * repel
|
1928
|
+
coords[i][0] -= sx; coords[i][1] -= sy; coords[i][2] -= sz
|
1929
|
+
coords[j][0] += sx; coords[j][1] += sy; coords[j][2] += sz
|
1930
|
+
if all_ok:
|
1931
|
+
break # everything already at least minDistance apart
|
1932
|
+
|
1933
|
+
# --- Rebuild vertices & restore dictionaries ---
|
1934
|
+
new_vertices = [Vertex.ByCoordinates(x, y, z) for (x, y, z) in coords]
|
1935
|
+
for i in range(n):
|
1936
|
+
new_vertices[i] = Topology.SetDictionary(new_vertices[i], dicts[i])
|
1879
1937
|
|
1880
|
-
minDistance = minDistance + tolerance # Add a bit of a safety factor
|
1881
|
-
|
1882
|
-
# Convert to mutable coordinates
|
1883
|
-
coords = [[v.X(), v.Y(), v.Z()] for v in vertices]
|
1884
|
-
|
1885
|
-
for _ in range(iterations):
|
1886
|
-
for i in range(len(coords)):
|
1887
|
-
for j in range(i + 1, len(coords)):
|
1888
|
-
dx = coords[j][0] - coords[i][0]
|
1889
|
-
dy = coords[j][1] - coords[i][1]
|
1890
|
-
dz = coords[j][2] - coords[i][2]
|
1891
|
-
dist = math.sqrt(dx*dx + dy*dy + dz*dz)
|
1892
|
-
|
1893
|
-
if dist < minDistance and dist > 1e-9:
|
1894
|
-
# Calculate repulsion vector
|
1895
|
-
repel = (minDistance - dist) / dist * strength
|
1896
|
-
shift = [dx * repel * 0.5, dy * repel * 0.5, dz * repel * 0.5]
|
1897
|
-
coords[i][0] -= shift[0]
|
1898
|
-
coords[i][1] -= shift[1]
|
1899
|
-
coords[i][2] -= shift[2]
|
1900
|
-
coords[j][0] += shift[0]
|
1901
|
-
coords[j][1] += shift[1]
|
1902
|
-
coords[j][2] += shift[2]
|
1903
|
-
|
1904
|
-
# Reconstruct TopologicPy Vertex objects
|
1905
|
-
new_vertices = [Vertex.ByCoordinates(x, y, z) for x, y, z in coords]
|
1906
|
-
# Transfer the dictionaries
|
1907
|
-
for i, v in enumerate(new_vertices):
|
1908
|
-
v = Topology.SetDictionary(v, Topology.Dictionary(vertices[i]))
|
1909
1938
|
return new_vertices
|
1910
1939
|
|
1940
|
+
|
1911
1941
|
@staticmethod
|
1912
1942
|
def Transform(vertex, matrix, mantissa: int = 6, silent: bool = False):
|
1913
1943
|
"""
|
topologicpy/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.8.
|
1
|
+
__version__ = '0.8.57'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.57
|
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
|
@@ -12,10 +12,11 @@ topologicpy/Dictionary.py,sha256=Z4YQ88tONWd-0X0dENQ8IZqIOa9mbBqhJkTBsHmft2g,446
|
|
12
12
|
topologicpy/Edge.py,sha256=DifItuyabFDUFC7CVMlt2DeMFMNaGOqCg43iU9CPP0A,74029
|
13
13
|
topologicpy/EnergyModel.py,sha256=hB1aiJe45gdDMFm1AhkBr-1djjtXSzn24iRpQMk43-4,57749
|
14
14
|
topologicpy/Face.py,sha256=aX9EcR3JGbLITElhd25J0Z8m9U8KkmbYivGg3oZN-Uw,202296
|
15
|
-
topologicpy/Graph.py,sha256=
|
15
|
+
topologicpy/Graph.py,sha256=EdB8N58bm74Uy6Y9xTrNgtewU-wx8Tq7y8EhyZ50wvs,716133
|
16
16
|
topologicpy/Grid.py,sha256=3OsBMyHh4w8gpFOTMKHMNTpo62V0CwRNu5cwm87yDUA,18421
|
17
17
|
topologicpy/Helper.py,sha256=Nr6pyzl0sZm4Cu11wOqoYKu6yYal5N6A9jErXnaZBJc,31765
|
18
|
-
topologicpy/Honeybee.py,sha256=
|
18
|
+
topologicpy/Honeybee.py,sha256=DzaG9wpkJdcDWcjOGXhuN5X0gCqypmZGBa1y5E2MkjU,48964
|
19
|
+
topologicpy/Kuzu.py,sha256=4j6yPMOlCtugXKO-nrjjige98MeYOE1PfzKdFEenpjk,20959
|
19
20
|
topologicpy/Matrix.py,sha256=bOofT34G3YHu9aMIWx60YHAJga4R0GbDjsZBUD4Hu_k,22706
|
20
21
|
topologicpy/Neo4j.py,sha256=J8jU_mr5-mWC0Lg_D2dMjMlx1rY_eh8ks_aubUuTdWw,22319
|
21
22
|
topologicpy/Plotly.py,sha256=kF7JwBMWJQAuGezaJYI6Cq7ErNwEtcKzaExOfdGPIMc,123003
|
@@ -27,12 +28,12 @@ topologicpy/Speckle.py,sha256=-eiTqJugd7pHiHpD3pDUcDO6CGhVyPV14HFRzaqEoaw,18187
|
|
27
28
|
topologicpy/Sun.py,sha256=8S6dhCKfOhUGVny-jEk87Q08anLYMB1JEBKRGCklvbQ,36670
|
28
29
|
topologicpy/Topology.py,sha256=R5Ac3V_ADDRDZjhpcNvhM3AvDOLU6ORvB3yILyEkxnI,472559
|
29
30
|
topologicpy/Vector.py,sha256=pEC8YY3TeHGfGdeNgvdHjgMDwxGabp5aWjwYC1HSvMk,42236
|
30
|
-
topologicpy/Vertex.py,sha256=
|
31
|
+
topologicpy/Vertex.py,sha256=r_3cicgpino96ymm1ANptfOuqE59b99YWwksxyPOYK4,85914
|
31
32
|
topologicpy/Wire.py,sha256=gjgQUGHdBdXUIijgZc_VIW0E39w-smaVhhdl0jF63fQ,230466
|
32
33
|
topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
|
33
|
-
topologicpy/version.py,sha256=
|
34
|
-
topologicpy-0.8.
|
35
|
-
topologicpy-0.8.
|
36
|
-
topologicpy-0.8.
|
37
|
-
topologicpy-0.8.
|
38
|
-
topologicpy-0.8.
|
34
|
+
topologicpy/version.py,sha256=9nWlfIrJh0NFxdTerGFsViWVZBvjxJ997KXXkuz9AiM,23
|
35
|
+
topologicpy-0.8.57.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
|
36
|
+
topologicpy-0.8.57.dist-info/METADATA,sha256=fHGtx2lc9MaC1L2EVY49mFCTJBz9V6zKGFpX08QyrZQ,10535
|
37
|
+
topologicpy-0.8.57.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
38
|
+
topologicpy-0.8.57.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
|
39
|
+
topologicpy-0.8.57.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|