topologicpy 0.8.87__py3-none-any.whl → 0.8.88__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 CHANGED
@@ -4753,7 +4753,9 @@ class Graph:
4753
4753
  @staticmethod
4754
4754
  def BySpatialRelationships(
4755
4755
  *topologies,
4756
- include: list = ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within"],
4756
+ include: list = ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within", "proximity"],
4757
+ proximityValues = [1, 5, 10],
4758
+ proximityLabels = ["near", "intermediate", "far"],
4757
4759
  useInternalVertex = False,
4758
4760
  vertexIDKey = "id",
4759
4761
  edgeKeyFwd = "relFwd",
@@ -4773,6 +4775,17 @@ class Graph:
4773
4775
  The list of input topologies
4774
4776
  include : list , optional
4775
4777
  The type(s) of spatial relationships to build. Default is ["contains", "disjoint", "equals", "overlaps", "touches", "within", "covers", "coveredBy"]
4778
+ proximityValues: list , optional
4779
+ The list of maximum distance values that specify the desired proximityLabel.
4780
+ This list must be sorted in ascending order and have the same number of elements as the proximityLabels list.
4781
+ Objects that are further than the largest specified distance are not classified and not included.
4782
+ An object is considered to fall within the range if it is less than or equal to the value in this list.
4783
+ If you wish ALL objects to be classified specifiy the last number in this list to be larger than the
4784
+ largest distance that can exist between any two objects in the list. Default is [1, 5, 10]
4785
+ proximityLabels: list , optional
4786
+ The list of range labels (e.g. "near", "intermediate", "far") that correspond to the proximityValues list.
4787
+ The list must have the same number of elements as the proximityValues list. Default is ["near", "intermediate", "far"]
4788
+
4776
4789
  useInternalVertex: bool , optional
4777
4790
  If set to True, an internal vertex of the represented topology will be used as a graph node.
4778
4791
  Otherwise, its centroid will be used. Default is False.
@@ -4819,6 +4832,18 @@ class Graph:
4819
4832
  if not silent:
4820
4833
  print("Graph.BySpatialRelationships - Error: No valid topologies. Returning None")
4821
4834
  return None
4835
+
4836
+ if len(proximityValues) != len(proximityLabels):
4837
+ if not silent:
4838
+ print("Graph.BySpatialRelationships - Error: the proximityValues and proximityLabels input parameters are not of the same length. Returning None")
4839
+ return None
4840
+
4841
+ include = [t.lower() for t in include if t.lower() in ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within", "proximity"]]
4842
+
4843
+ if len(include) == 0:
4844
+ if not silent:
4845
+ print("Graph.BySpatialRelationships - Error: The include input parameter does not contain any valid spatial relationship types. Returning None")
4846
+ return None
4822
4847
 
4823
4848
  if n == 1:
4824
4849
  v = Topology.InternalVertex(topologyList[0]) if useInternalVertex else Topology.Centroid(topologyList[0])
@@ -4838,7 +4863,8 @@ class Graph:
4838
4863
  for i, t in enumerate(topologyList):
4839
4864
  d = Topology.Dictionary(t)
4840
4865
  d = Dictionary.SetValueAtKey(d, vertexIDKey, i)
4841
- d = Dictionary.SetValuesAtKeys(d, ["brep", "brepType", "brepTypeString"], [Topology.BREPString(t), Topology.Type(t), Topology.TypeAsString(t)])
4866
+ if storeBREP == True:
4867
+ d = Dictionary.SetValuesAtKeys(d, ["brep", "brepType", "brepTypeString"], [Topology.BREPString(t), Topology.Type(t), Topology.TypeAsString(t)])
4842
4868
  vertex_dicts[i] = d
4843
4869
  v = Topology.InternalVertex(t) if useInternalVertex else Topology.Centroid(t)
4844
4870
  vertices_objs[i] = v
@@ -4882,17 +4908,47 @@ class Graph:
4882
4908
  # keep same tag both ways for symmetric predicates
4883
4909
  fwd = rel
4884
4910
  bwd = rel
4885
- edges.append([ai, bj])
4886
- edge_dicts.append(
4887
- Dictionary.ByKeysValues(
4911
+ if [ai, bj] in edges:
4912
+ i = edges.index([ai, bj])
4913
+ edge_dict = Dictionary.ByKeysValues(
4888
4914
  [edgeKeyFwd, edgeKeyBwd, connectsKey],
4889
- [fwd, bwd, [ai, bj]],
4890
- )
4891
- )
4915
+ [fwd, bwd, [ai, bj]])
4916
+ edge_dicts[i] = edge_dict
4917
+ else:
4918
+
4919
+ edges.append([ai, bj])
4920
+ edge_dicts.append(
4921
+ Dictionary.ByKeysValues(
4922
+ [edgeKeyFwd, edgeKeyBwd, connectsKey],
4923
+ [fwd, bwd, [ai, bj]],
4924
+ ))
4892
4925
 
4893
4926
  # ---------- main loops (each unordered pair once) ----------
4927
+ used = []
4928
+ proximity_edges = []
4894
4929
  for i, a in enumerate(topologyList):
4930
+ candidates = []
4895
4931
  ai = i
4932
+ if "proximity" in include:
4933
+ for j, b in enumerate(topologyList):
4934
+ bj = index_of.get(id(b))
4935
+ if i == bj or (i,bj) in used or (bj,i) in used:
4936
+ continue
4937
+ else:
4938
+ used.append((i,bj))
4939
+ used.append((bj,i))
4940
+ rel = Topology.SpatialRelationship( a,
4941
+ b,
4942
+ include=["proximity"],
4943
+ proximityValues = proximityValues,
4944
+ proximityLabels = proximityLabels,
4945
+ mantissa=mantissa,
4946
+ tolerance=tolerance,
4947
+ silent=True
4948
+ )
4949
+ rel_ok = (rel in proximityLabels)
4950
+ if rel_ok:
4951
+ _add_edge(ai, bj, rel)
4896
4952
  candidates = BVH.Clashes(bvh, a) or []
4897
4953
  if not candidates:
4898
4954
  # If you want to connect "disjoint" to *all* non-candidates, that would be O(n) per i.
@@ -4901,7 +4957,7 @@ class Graph:
4901
4957
 
4902
4958
  for b in candidates:
4903
4959
  bj = index_of.get(id(b))
4904
- if bj is None or bj <= ai:
4960
+ if bj is None or bj <= ai:
4905
4961
  continue # skip self and already-processed pairs
4906
4962
 
4907
4963
  # Ultra-fast "disjoint" emit via AABB if requested and boxes do not overlap
@@ -4909,7 +4965,7 @@ class Graph:
4909
4965
  if want_disjoint:
4910
4966
  _add_edge(ai, bj, "disjoint")
4911
4967
  continue # done with this pair
4912
-
4968
+
4913
4969
  # Otherwise evaluate exact relation (short-circuit inside)
4914
4970
  rel = Topology.SpatialRelationship(
4915
4971
  a,
topologicpy/Plotly.py CHANGED
@@ -799,7 +799,7 @@ class Plotly:
799
799
  z=z,
800
800
  name=legendLabel,
801
801
  showlegend=showLegend,
802
- marker=dict(symbol="circle", size=marker_width, color=color),
802
+ marker=dict(symbol="circle", size=marker_width, color=d_color),
803
803
  mode=mode,
804
804
  line=dict(color=d_color, width=width, dash=dot),
805
805
  legendgroup=legendGroup,
topologicpy/Shell.py CHANGED
@@ -179,8 +179,7 @@ class Shell():
179
179
  #return Cluster.ByTopologies(skEdges)
180
180
  #print("ShellByDisjointFaces - Error: Could not derive central skeleton of interior walls. Returning None.")
181
181
  #return None
182
-
183
- shell = Topology.Slice(internalBoundary, skeleton_cluster, tolerance=tolerance)
182
+ shell = Topology.Slice(Topology.Copy(internalBoundary), skeleton_cluster, tolerance=tolerance)
184
183
  if mergeJunctions == True:
185
184
  vertices = Topology.Vertices(shell, silent=True)
186
185
  centers = []
topologicpy/Topology.py CHANGED
@@ -10098,7 +10098,9 @@ class Topology():
10098
10098
  @staticmethod
10099
10099
  def SpatialRelationship(topologyA,
10100
10100
  topologyB,
10101
- include: list = ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within"],
10101
+ include: list = ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within", "proximity"],
10102
+ proximityValues = [1, 5, 10],
10103
+ proximityLabels = ["near", "intermediate", "far"],
10102
10104
  mantissa: int = 6,
10103
10105
  tolerance: float = 0.0001,
10104
10106
  silent: bool = False):
@@ -10123,6 +10125,17 @@ class Topology():
10123
10125
  - Overlaps: The intersection of the two geometries results in a new, distinct geometry of the same dimension. For example, two overlapping polygons produce a new polygon.
10124
10126
  - Touches: The geometries share at least one point on their boundaries but their interiors do not intersect.
10125
10127
  - Within: The interior and boundary of geometry A are completely contained within the interior of geometry B.
10128
+ - Proximity: Classifies the shortest distance between the objects according to proximityValues and proximityLabels.
10129
+ proximityValues: list , optional
10130
+ The list of maximum distance values that specify the desired proximityLabel.
10131
+ This list must be sorted in ascending order and have the same number of elements as the proximityLabels list.
10132
+ Objects that are further than the largest specified distance are not classified and not included.
10133
+ An object is considered to fall within the range if it is less than or equal to the value in this list.
10134
+ If you wish ALL objects to be classified specifiy the last number in this list to be larger than the
10135
+ largest distance that can exist between any two objects in the list. Default is [1, 5, 10]
10136
+ proximityLabels: list , optional
10137
+ The list of range labels (e.g. "near", "intermediate", "far") that correspond to the proximityValues list.
10138
+ The list must have the same number of elements as the proximityValues list. Default is ["near", "intermediate", "far"]
10126
10139
  mantissa : int , optional
10127
10140
  The desired length of the mantissa. Default is 6.
10128
10141
  tolerance : float , optional
@@ -10147,6 +10160,11 @@ class Topology():
10147
10160
  if not silent:
10148
10161
  print("Topology.SpatialRelationship - Error: The topologyB input parameter is not a valid Topology. Returning None.")
10149
10162
  return None
10163
+
10164
+ if len(proximityValues) != len(proximityLabels):
10165
+ if not silent:
10166
+ print("Topology.SpatialRelationship - Error: the proximityValues and proximityLabels input parameters are not of the same length. Returning None")
10167
+ return None
10150
10168
 
10151
10169
  from topologicpy.Vertex import Vertex
10152
10170
  from topologicpy.Cluster import Cluster
@@ -10263,6 +10281,13 @@ class Topology():
10263
10281
 
10264
10282
  # ---------- predicates ----------
10265
10283
 
10284
+ def proximity(a, b, proximityValues, proximityLabels):
10285
+ sd = Topology.ShortestDistance(a,b, tolerance=tolerance, silent=silent)
10286
+ for i, pv in enumerate(proximityValues):
10287
+ if sd <= pv:
10288
+ return proximityLabels[i]
10289
+ return None
10290
+
10266
10291
  def contains(a, b):
10267
10292
  # The inverse of "within," where geometry A contains geometry B.
10268
10293
  # The interior and boundary of B are completely contained within the interior of A.
@@ -10439,8 +10464,11 @@ class Topology():
10439
10464
  # 7) touches (incl. vertex-at-endpoint)
10440
10465
  if "touches" in inc and touches(topologyA, topologyB):
10441
10466
  return "touches"
10467
+ # 8) proximity
10468
+ if "proximity" in inc:
10469
+ return proximity(topologyA, topologyB, proximityValues, proximityLabels)
10442
10470
 
10443
- return "unknown"
10471
+ return None
10444
10472
 
10445
10473
  @staticmethod
10446
10474
  def Spin(topology, origin=None, triangulate: bool = True, direction: list = [0, 0, 1], angle: float = 360, sides: int = 16,
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.87'
1
+ __version__ = '0.8.88'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topologicpy
3
- Version: 0.8.87
3
+ Version: 0.8.88
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,28 +12,28 @@ topologicpy/Dictionary.py,sha256=goODXIM6AoC5Qn_d8LGc5pRoxZKgIWbkn3IOEbsQ4c4,449
12
12
  topologicpy/Edge.py,sha256=aiRd1xZgG2GGYHxva0bM-kDy3AVmwGA_S2pMur8EeMg,74911
13
13
  topologicpy/EnergyModel.py,sha256=MEai1GF1hINeH5bhclJj_lpMU3asFTvW2RlPm40GNj4,57794
14
14
  topologicpy/Face.py,sha256=qAl36LcwiyRclMM2pI9NyWHzmgNlaykXiJx1wu10RmA,201317
15
- topologicpy/Graph.py,sha256=GtDUoAOLG1jAIBPcuUBLwjkvNZP7-gDL-x6fcSbCtmI,794853
15
+ topologicpy/Graph.py,sha256=oDzAX_lmM10ayRA8mNenlccJu-oe-FYwW2GHbAp9x5s,798255
16
16
  topologicpy/Grid.py,sha256=3OsBMyHh4w8gpFOTMKHMNTpo62V0CwRNu5cwm87yDUA,18421
17
17
  topologicpy/Helper.py,sha256=NsmMlbbKFPRX6jfoko-ZQVQ7MBsfVp9FD0ZvC2U7q-8,32002
18
18
  topologicpy/Honeybee.py,sha256=dBk01jIvxjQMGHqSarM1Cukv16ot4Op7Dwlitn2OMoc,48990
19
19
  topologicpy/Kuzu.py,sha256=fxaDPWM5Xam7Tot0olPZsazS_7xgE_Vo-jf0Sbv3VZE,36298
20
20
  topologicpy/Matrix.py,sha256=bOofT34G3YHu9aMIWx60YHAJga4R0GbDjsZBUD4Hu_k,22706
21
21
  topologicpy/Neo4j.py,sha256=J8jU_mr5-mWC0Lg_D2dMjMlx1rY_eh8ks_aubUuTdWw,22319
22
- topologicpy/Plotly.py,sha256=sYCP7D112sbWWGnA2q7ThjHv7KHL5wHUwsIs5xEnvLA,123246
22
+ topologicpy/Plotly.py,sha256=jQTIPaOZErZhj1vDjsF3SYsDhPx4fQ0W75q6XEQFMBk,123248
23
23
  topologicpy/Polyskel.py,sha256=oVfM4lqSMPTjnkHfsRU9VI8Blt6Vf0LVPkD9ebz7Wmw,27082
24
24
  topologicpy/PyG.py,sha256=wOsoBFxMgwZYWjj86OMkz_PJuQ02locV_djhSDD6dVc,109644
25
25
  topologicpy/ShapeGrammar.py,sha256=q_BvMKOBDW3GVSRjPLIGAZkHW2egw3mTOPzIyEpYOLg,23349
26
- topologicpy/Shell.py,sha256=qvIkE76cie7cOl-AK23ORi6mDQb-UsXVOF7or7hBvWw,101070
26
+ topologicpy/Shell.py,sha256=2EPzDT_t0IAjBRYPDuKNAz_Ax_HaEkvNpXBxDkPdcTg,101084
27
27
  topologicpy/Speckle.py,sha256=-eiTqJugd7pHiHpD3pDUcDO6CGhVyPV14HFRzaqEoaw,18187
28
28
  topologicpy/Sun.py,sha256=ezisiHfc2nd7A_8w0Ykq2VgbS0A9WNSg-tBwvfTQAVM,36735
29
- topologicpy/Topology.py,sha256=p8jOONJz19PrFAuMV3eGti6iTer8bAUk0zpvKmkAK48,546600
29
+ topologicpy/Topology.py,sha256=E_AyPPCIx_Eq-UT74QS3LKFXIwdwekRjJJGTo1CRMRY,548577
30
30
  topologicpy/Vector.py,sha256=pEC8YY3TeHGfGdeNgvdHjgMDwxGabp5aWjwYC1HSvMk,42236
31
31
  topologicpy/Vertex.py,sha256=26TrlX9OCZUN-lMlZG3g4RHTWBqw69NW4AOEgRz_YMo,91269
32
32
  topologicpy/Wire.py,sha256=au0ZkuuZgVzHYE5E1fRwflRT3win0yTivHKOhonAzUk,234116
33
33
  topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
34
- topologicpy/version.py,sha256=koft0X1ZY8adezuRt_HJmfuap76X3-p_mFskEkgvYXg,23
35
- topologicpy-0.8.87.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
36
- topologicpy-0.8.87.dist-info/METADATA,sha256=_9u_cKxdwaFzHH_RADU3YEESPkfjqPpIszuPaaUGNFc,10535
37
- topologicpy-0.8.87.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
- topologicpy-0.8.87.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
39
- topologicpy-0.8.87.dist-info/RECORD,,
34
+ topologicpy/version.py,sha256=qAXCd2Ric5BF00XcziW6Y7EfWidI5Yii7_q1vhA8if4,23
35
+ topologicpy-0.8.88.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
36
+ topologicpy-0.8.88.dist-info/METADATA,sha256=TmanTsL4EPrwo0Fd1oWarCyWzj91C3AWRbJE0LMxbag,10535
37
+ topologicpy-0.8.88.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
+ topologicpy-0.8.88.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
39
+ topologicpy-0.8.88.dist-info/RECORD,,