topologicpy 0.8.87__py3-none-any.whl → 0.8.89__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 +295 -16
- topologicpy/Plotly.py +1 -1
- topologicpy/Shell.py +1 -2
- topologicpy/Topology.py +30 -2
- topologicpy/version.py +1 -1
- {topologicpy-0.8.87.dist-info → topologicpy-0.8.89.dist-info}/METADATA +1 -1
- {topologicpy-0.8.87.dist-info → topologicpy-0.8.89.dist-info}/RECORD +10 -10
- {topologicpy-0.8.87.dist-info → topologicpy-0.8.89.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.87.dist-info → topologicpy-0.8.89.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.87.dist-info → topologicpy-0.8.89.dist-info}/top_level.txt +0 -0
topologicpy/Graph.py
CHANGED
|
@@ -4753,13 +4753,16 @@ class Graph:
|
|
|
4753
4753
|
@staticmethod
|
|
4754
4754
|
def BySpatialRelationships(
|
|
4755
4755
|
*topologies,
|
|
4756
|
-
include: list = ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within"],
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4756
|
+
include: list = ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within", "proximity"],
|
|
4757
|
+
proximityValues = [1, 5, 10],
|
|
4758
|
+
proximityLabels = ["near", "intermediate", "far"],
|
|
4759
|
+
useShortestDistance: bool = False,
|
|
4760
|
+
useInternalVertex: bool = False,
|
|
4761
|
+
vertexIDKey: str = "id",
|
|
4762
|
+
edgeKeyFwd: str = "relFwd",
|
|
4763
|
+
edgeKeyBwd: str = "relBwd",
|
|
4764
|
+
connectsKey:str = "connects",
|
|
4765
|
+
storeBREP: bool = False,
|
|
4763
4766
|
mantissa: int = 6,
|
|
4764
4767
|
tolerance: float = 0.0001,
|
|
4765
4768
|
silent: bool = False
|
|
@@ -4773,6 +4776,18 @@ class Graph:
|
|
|
4773
4776
|
The list of input topologies
|
|
4774
4777
|
include : list , optional
|
|
4775
4778
|
The type(s) of spatial relationships to build. Default is ["contains", "disjoint", "equals", "overlaps", "touches", "within", "covers", "coveredBy"]
|
|
4779
|
+
proximityValues: list , optional
|
|
4780
|
+
The list of maximum distance values that specify the desired proximityLabel.
|
|
4781
|
+
This list must be sorted in ascending order and have the same number of elements as the proximityLabels list.
|
|
4782
|
+
Objects that are further than the largest specified distance are not classified and not included.
|
|
4783
|
+
An object is considered to fall within the range if it is less than or equal to the value in this list.
|
|
4784
|
+
If you wish ALL objects to be classified specifiy the last number in this list to be larger than the
|
|
4785
|
+
largest distance that can exist between any two objects in the list. Default is [1, 5, 10]
|
|
4786
|
+
proximityLabels: list , optional
|
|
4787
|
+
The list of range labels (e.g. "near", "intermediate", "far") that correspond to the proximityValues list.
|
|
4788
|
+
The list must have the same number of elements as the proximityValues list. Default is ["near", "intermediate", "far"]
|
|
4789
|
+
useShortestDistance: bool , optional
|
|
4790
|
+
If set to True, the shortest distance between objects is used. Otherwise, the distance between their centroids is used. Default is False.
|
|
4776
4791
|
useInternalVertex: bool , optional
|
|
4777
4792
|
If set to True, an internal vertex of the represented topology will be used as a graph node.
|
|
4778
4793
|
Otherwise, its centroid will be used. Default is False.
|
|
@@ -4801,6 +4816,7 @@ class Graph:
|
|
|
4801
4816
|
"""
|
|
4802
4817
|
from topologicpy.Graph import Graph
|
|
4803
4818
|
from topologicpy.BVH import BVH
|
|
4819
|
+
from topologicpy.Cell import Cell
|
|
4804
4820
|
from topologicpy.Vertex import Vertex
|
|
4805
4821
|
from topologicpy.Topology import Topology
|
|
4806
4822
|
from topologicpy.Dictionary import Dictionary
|
|
@@ -4819,12 +4835,252 @@ class Graph:
|
|
|
4819
4835
|
if not silent:
|
|
4820
4836
|
print("Graph.BySpatialRelationships - Error: No valid topologies. Returning None")
|
|
4821
4837
|
return None
|
|
4838
|
+
|
|
4839
|
+
if len(proximityValues) != len(proximityLabels):
|
|
4840
|
+
if not silent:
|
|
4841
|
+
print("Graph.BySpatialRelationships - Error: the proximityValues and proximityLabels input parameters are not of the same length. Returning None")
|
|
4842
|
+
return None
|
|
4843
|
+
|
|
4844
|
+
include = [t.lower() for t in include if t.lower() in ["contains", "coveredBy", "covers", "crosses", "disjoint", "equals", "overlaps", "touches","within", "proximity"]]
|
|
4845
|
+
|
|
4846
|
+
if len(include) == 0:
|
|
4847
|
+
if not silent:
|
|
4848
|
+
print("Graph.BySpatialRelationships - Error: The include input parameter does not contain any valid spatial relationship types. Returning None")
|
|
4849
|
+
return None
|
|
4822
4850
|
|
|
4823
4851
|
if n == 1:
|
|
4824
4852
|
v = Topology.InternalVertex(topologyList[0]) if useInternalVertex else Topology.Centroid(topologyList[0])
|
|
4825
4853
|
v = Topology.SetDictionary(v, Topology.Dictionary(topologyList[0]))
|
|
4826
4854
|
return Graph.ByVerticesEdges([v], [])
|
|
4827
4855
|
|
|
4856
|
+
# ---------- Calculate Proximity ------------
|
|
4857
|
+
|
|
4858
|
+
def _calc_proximity(topologies: list,
|
|
4859
|
+
ranges: list,
|
|
4860
|
+
labels: list,
|
|
4861
|
+
useShortestDistance: bool = True,
|
|
4862
|
+
tolerance: float = 0.0001,
|
|
4863
|
+
silent: bool = False):
|
|
4864
|
+
"""
|
|
4865
|
+
Creates a proximity graph from a list of topologies using a BVH
|
|
4866
|
+
to prune distance checks for large input sets.
|
|
4867
|
+
|
|
4868
|
+
Each topology is represented by a vertex in the graph.
|
|
4869
|
+
An edge is created between two vertices if the distance between
|
|
4870
|
+
their corresponding topologies is <= max(ranges).
|
|
4871
|
+
|
|
4872
|
+
A BVH is used as a broad-phase accelerator: for each topology,
|
|
4873
|
+
a query box centred at its centroid and sized to cover the
|
|
4874
|
+
maximum proximity range is used to retrieve only nearby
|
|
4875
|
+
candidates. Exact distances are then computed only for those
|
|
4876
|
+
candidates.
|
|
4877
|
+
|
|
4878
|
+
Parameters
|
|
4879
|
+
----------
|
|
4880
|
+
topologies : list of topologic_core.Topology
|
|
4881
|
+
The input topologies to be represented as vertices.
|
|
4882
|
+
ranges : list of float
|
|
4883
|
+
A list of positive numeric thresholds (e.g. [1.0, 3.0, 5.0]).
|
|
4884
|
+
Interpreted as upper bounds of proximity bands.
|
|
4885
|
+
Distances larger than max(ranges) are ignored (no edge).
|
|
4886
|
+
labels : list of str
|
|
4887
|
+
A list of proximity labels, same length as `ranges`.
|
|
4888
|
+
For a pair distance d:
|
|
4889
|
+
- d <= ranges[0] -> labels[0]
|
|
4890
|
+
- ranges[0] < d <= ranges[1] -> labels[1]
|
|
4891
|
+
- ...
|
|
4892
|
+
useShortestDistance : bool , optional
|
|
4893
|
+
If True, use Topology.ShortestDistance(topologyA, topologyB)
|
|
4894
|
+
if available. If False (or if that fails), fall back to the
|
|
4895
|
+
distance between the centroids of the two topologies.
|
|
4896
|
+
Default is True.
|
|
4897
|
+
tolerance : float , optional
|
|
4898
|
+
A small numeric tolerance used when comparing distances to
|
|
4899
|
+
range bounds. Default is 0.0001.
|
|
4900
|
+
silent : bool , optional
|
|
4901
|
+
If False, basic sanity-check warnings are printed.
|
|
4902
|
+
Default is False.
|
|
4903
|
+
|
|
4904
|
+
Returns
|
|
4905
|
+
-------
|
|
4906
|
+
graph : topologic_core.Graph
|
|
4907
|
+
A graph whose vertices correspond to the input topologies
|
|
4908
|
+
and whose edges connect topologies that fall within the
|
|
4909
|
+
supplied distance ranges. Each edge dictionary contains:
|
|
4910
|
+
- "distance" : float (actual distance)
|
|
4911
|
+
- "proximity" : str (label from `labels`)
|
|
4912
|
+
- "range_max" : float (upper bound used for the bin)
|
|
4913
|
+
- "source_index" : int
|
|
4914
|
+
- "target_index" : int
|
|
4915
|
+
|
|
4916
|
+
Notes
|
|
4917
|
+
-----
|
|
4918
|
+
- Complexity is approximately O(n log n + k) where k is the
|
|
4919
|
+
number of candidate pairs returned by the BVH.
|
|
4920
|
+
- BVH is used only as a broad-phase filter; exact distance
|
|
4921
|
+
tests still guarantee correctness with respect to `ranges`.
|
|
4922
|
+
"""
|
|
4923
|
+
|
|
4924
|
+
# Basic validation
|
|
4925
|
+
if not isinstance(topologies, list) or len(topologies) < 2:
|
|
4926
|
+
if not silent:
|
|
4927
|
+
print("Graph.BySpatialRelationships - Error: Need a list of at least two topologies.")
|
|
4928
|
+
return None
|
|
4929
|
+
|
|
4930
|
+
if not isinstance(ranges, list) or not isinstance(labels, list):
|
|
4931
|
+
if not silent:
|
|
4932
|
+
print("Graph.BySpatialRelationships - Error: 'proximityValues' and 'proximityLabels' must be lists.")
|
|
4933
|
+
return None
|
|
4934
|
+
|
|
4935
|
+
if len(ranges) == 0 or len(ranges) != len(labels):
|
|
4936
|
+
if not silent:
|
|
4937
|
+
print("Graph.BySpatialRelationships - Error: 'proximityValues' must be non-empty and "
|
|
4938
|
+
"have the same length as 'labels'.")
|
|
4939
|
+
return None
|
|
4940
|
+
|
|
4941
|
+
# Sort ranges and labels together (ascending by range)
|
|
4942
|
+
try:
|
|
4943
|
+
rl = sorted(zip(ranges, labels), key=lambda x: x[0])
|
|
4944
|
+
except Exception:
|
|
4945
|
+
if not silent:
|
|
4946
|
+
print("Graph.BySpatialRelationships - Error: Could not sort ranges; check they are numeric.")
|
|
4947
|
+
return None
|
|
4948
|
+
|
|
4949
|
+
sorted_ranges = [r for (r, _) in rl]
|
|
4950
|
+
sorted_labels = [lab for (_, lab) in rl]
|
|
4951
|
+
|
|
4952
|
+
max_range = sorted_ranges[-1]
|
|
4953
|
+
|
|
4954
|
+
# Precompute representative vertices (centroids) for each topology
|
|
4955
|
+
vertices = []
|
|
4956
|
+
n = len(topologies)
|
|
4957
|
+
for i, topo in enumerate(topologies):
|
|
4958
|
+
if not topo:
|
|
4959
|
+
if not silent:
|
|
4960
|
+
print(f"Graph.BySpatialRelationships - Warning: Ignoring None topology at index {i}.")
|
|
4961
|
+
vertices.append(None)
|
|
4962
|
+
continue
|
|
4963
|
+
try:
|
|
4964
|
+
c_vtx = Topology.Centroid(topo)
|
|
4965
|
+
except Exception:
|
|
4966
|
+
# Fallback if centroid fails
|
|
4967
|
+
if not silent:
|
|
4968
|
+
print(f"Graph.BySpatialRelationships - Error: Failed to compute centroid for topology {i}, "
|
|
4969
|
+
f"using origin as placeholder.")
|
|
4970
|
+
c_vtx = Vertex.ByCoordinates(0, 0, 0)
|
|
4971
|
+
|
|
4972
|
+
# Attach index dictionary to the vertex (not to the original topology)
|
|
4973
|
+
d_keys = ["index"]
|
|
4974
|
+
d_vals = [i]
|
|
4975
|
+
v_dict = Dictionary.ByKeysValues(d_keys, d_vals)
|
|
4976
|
+
c_vtx = Topology.SetDictionary(c_vtx, v_dict)
|
|
4977
|
+
vertices.append(c_vtx)
|
|
4978
|
+
|
|
4979
|
+
# Build BVH on the original topologies
|
|
4980
|
+
try:
|
|
4981
|
+
bvh = BVH.ByTopologies(topologies)
|
|
4982
|
+
except Exception as e:
|
|
4983
|
+
if not silent:
|
|
4984
|
+
print(f"Graph.BySpatialRelationships - Error: Failed to build BVH, falling back to O(n^2): {e}")
|
|
4985
|
+
# Fallback: use the non-BVH variant if you like,
|
|
4986
|
+
# or just early-return None. Here we just bail out.
|
|
4987
|
+
return None
|
|
4988
|
+
|
|
4989
|
+
# Map from topology identity to index for fast lookup
|
|
4990
|
+
id_to_index = {id(topo): i for i, topo in enumerate(topologies)}
|
|
4991
|
+
|
|
4992
|
+
# Helper to compute distance between two topologies
|
|
4993
|
+
def _distance(topoA, topoB, vA, vB):
|
|
4994
|
+
d_val = None
|
|
4995
|
+
if useShortestDistance:
|
|
4996
|
+
try:
|
|
4997
|
+
d_val = Topology.ShortestDistance(topoA, topoB)
|
|
4998
|
+
except Exception:
|
|
4999
|
+
d_val = None
|
|
5000
|
+
if d_val is None:
|
|
5001
|
+
try:
|
|
5002
|
+
d_val = Vertex.Distance(vA, vB)
|
|
5003
|
+
except Exception:
|
|
5004
|
+
d_val = None
|
|
5005
|
+
return d_val
|
|
5006
|
+
|
|
5007
|
+
edges = []
|
|
5008
|
+
|
|
5009
|
+
# Main loop: for each topology, query BVH for candidates within
|
|
5010
|
+
# a bounding box of size 2*max_range around its centroid.
|
|
5011
|
+
for i in range(n):
|
|
5012
|
+
topo_i = topologies[i]
|
|
5013
|
+
v_i = vertices[i]
|
|
5014
|
+
if topo_i is None or v_i is None:
|
|
5015
|
+
continue
|
|
5016
|
+
|
|
5017
|
+
# Build a query box centered at the centroid with size 2 * max_range
|
|
5018
|
+
try:
|
|
5019
|
+
query_box = Cell.Prism(
|
|
5020
|
+
origin=v_i,
|
|
5021
|
+
width=2 * max_range,
|
|
5022
|
+
length=2 * max_range,
|
|
5023
|
+
height=2 * max_range
|
|
5024
|
+
)
|
|
5025
|
+
except Exception as q_err:
|
|
5026
|
+
if not silent:
|
|
5027
|
+
print(f"Graph.BySpatialRelationships - Error: Failed to build query box for {i}: {q_err}")
|
|
5028
|
+
continue
|
|
5029
|
+
|
|
5030
|
+
try:
|
|
5031
|
+
candidates = BVH.Clashes(bvh, query_box)
|
|
5032
|
+
except Exception as c_err:
|
|
5033
|
+
if not silent:
|
|
5034
|
+
print(f"Graph.BySpatialRelationships - Error: BVH.Clashes failed for {i}: {c_err}")
|
|
5035
|
+
continue
|
|
5036
|
+
|
|
5037
|
+
if not candidates:
|
|
5038
|
+
continue
|
|
5039
|
+
|
|
5040
|
+
for cand in candidates:
|
|
5041
|
+
j = id_to_index.get(id(cand), None)
|
|
5042
|
+
if j is None:
|
|
5043
|
+
continue
|
|
5044
|
+
# Enforce i < j to avoid duplicate edges
|
|
5045
|
+
if j <= i:
|
|
5046
|
+
continue
|
|
5047
|
+
|
|
5048
|
+
topo_j = topologies[j]
|
|
5049
|
+
v_j = vertices[j]
|
|
5050
|
+
if topo_j is None or v_j is None:
|
|
5051
|
+
continue
|
|
5052
|
+
|
|
5053
|
+
# Compute exact distance
|
|
5054
|
+
d = _distance(topo_i, topo_j, v_i, v_j)
|
|
5055
|
+
if d is None:
|
|
5056
|
+
if not silent:
|
|
5057
|
+
print(f"Graph.BySpatialRelationships - Error: Could not compute distance between "
|
|
5058
|
+
f"{i} and {j}.")
|
|
5059
|
+
continue
|
|
5060
|
+
|
|
5061
|
+
# Skip if beyond max range (plus tolerance)
|
|
5062
|
+
if d > max_range + tolerance:
|
|
5063
|
+
continue
|
|
5064
|
+
|
|
5065
|
+
# Bin the distance into the appropriate range/label
|
|
5066
|
+
label = None
|
|
5067
|
+
range_max = None
|
|
5068
|
+
for r, lab in zip(sorted_ranges, sorted_labels):
|
|
5069
|
+
if d <= r + tolerance:
|
|
5070
|
+
label = lab
|
|
5071
|
+
range_max = r
|
|
5072
|
+
break
|
|
5073
|
+
|
|
5074
|
+
if label is None:
|
|
5075
|
+
continue
|
|
5076
|
+
|
|
5077
|
+
e_keys = ["distance", "proximity", "range_max", "source_index", "target_index"]
|
|
5078
|
+
e_values = [float(d), str(label), float(range_max), i, j]
|
|
5079
|
+
d = Dictionary.ByKeysValues(e_keys, e_values)
|
|
5080
|
+
edges.append(d)
|
|
5081
|
+
|
|
5082
|
+
return edges
|
|
5083
|
+
|
|
4828
5084
|
# ---------- BVH once ----------
|
|
4829
5085
|
bvh = BVH.ByTopologies(topologyList, silent=True)
|
|
4830
5086
|
|
|
@@ -4838,7 +5094,8 @@ class Graph:
|
|
|
4838
5094
|
for i, t in enumerate(topologyList):
|
|
4839
5095
|
d = Topology.Dictionary(t)
|
|
4840
5096
|
d = Dictionary.SetValueAtKey(d, vertexIDKey, i)
|
|
4841
|
-
|
|
5097
|
+
if storeBREP == True:
|
|
5098
|
+
d = Dictionary.SetValuesAtKeys(d, ["brep", "brepType", "brepTypeString"], [Topology.BREPString(t), Topology.Type(t), Topology.TypeAsString(t)])
|
|
4842
5099
|
vertex_dicts[i] = d
|
|
4843
5100
|
v = Topology.InternalVertex(t) if useInternalVertex else Topology.Centroid(t)
|
|
4844
5101
|
vertices_objs[i] = v
|
|
@@ -4882,16 +5139,38 @@ class Graph:
|
|
|
4882
5139
|
# keep same tag both ways for symmetric predicates
|
|
4883
5140
|
fwd = rel
|
|
4884
5141
|
bwd = rel
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
Dictionary.ByKeysValues(
|
|
5142
|
+
if [ai, bj] in edges:
|
|
5143
|
+
i = edges.index([ai, bj])
|
|
5144
|
+
edge_dict = Dictionary.ByKeysValues(
|
|
4888
5145
|
[edgeKeyFwd, edgeKeyBwd, connectsKey],
|
|
4889
|
-
[fwd, bwd, [ai, bj]]
|
|
4890
|
-
|
|
4891
|
-
|
|
5146
|
+
[fwd, bwd, [ai, bj]])
|
|
5147
|
+
edge_dicts[i] = edge_dict
|
|
5148
|
+
else:
|
|
5149
|
+
|
|
5150
|
+
edges.append([ai, bj])
|
|
5151
|
+
edge_dicts.append(
|
|
5152
|
+
Dictionary.ByKeysValues(
|
|
5153
|
+
[edgeKeyFwd, edgeKeyBwd, connectsKey],
|
|
5154
|
+
[fwd, bwd, [ai, bj]],
|
|
5155
|
+
))
|
|
4892
5156
|
|
|
4893
5157
|
# ---------- main loops (each unordered pair once) ----------
|
|
5158
|
+
if "proximity" in include:
|
|
5159
|
+
prox_dicts = _calc_proximity(topologies = topologyList,
|
|
5160
|
+
ranges = proximityValues,
|
|
5161
|
+
labels = proximityLabels,
|
|
5162
|
+
useShortestDistance = useShortestDistance,
|
|
5163
|
+
tolerance = tolerance,
|
|
5164
|
+
silent = silent)
|
|
5165
|
+
for prox_dict in prox_dicts:
|
|
5166
|
+
ai = Dictionary.ValueAtKey(prox_dict, "source_index")
|
|
5167
|
+
bj = Dictionary.ValueAtKey(prox_dict, "target_index")
|
|
5168
|
+
rel = Dictionary.ValueAtKey(prox_dict, "proximity")
|
|
5169
|
+
if (rel in proximityLabels):
|
|
5170
|
+
_add_edge(ai, bj, rel)
|
|
5171
|
+
|
|
4894
5172
|
for i, a in enumerate(topologyList):
|
|
5173
|
+
candidates = []
|
|
4895
5174
|
ai = i
|
|
4896
5175
|
candidates = BVH.Clashes(bvh, a) or []
|
|
4897
5176
|
if not candidates:
|
|
@@ -4901,7 +5180,7 @@ class Graph:
|
|
|
4901
5180
|
|
|
4902
5181
|
for b in candidates:
|
|
4903
5182
|
bj = index_of.get(id(b))
|
|
4904
|
-
if bj is None or bj <= ai:
|
|
5183
|
+
if bj is None or bj <= ai:
|
|
4905
5184
|
continue # skip self and already-processed pairs
|
|
4906
5185
|
|
|
4907
5186
|
# Ultra-fast "disjoint" emit via AABB if requested and boxes do not overlap
|
|
@@ -4909,7 +5188,7 @@ class Graph:
|
|
|
4909
5188
|
if want_disjoint:
|
|
4910
5189
|
_add_edge(ai, bj, "disjoint")
|
|
4911
5190
|
continue # done with this pair
|
|
4912
|
-
|
|
5191
|
+
|
|
4913
5192
|
# Otherwise evaluate exact relation (short-circuit inside)
|
|
4914
5193
|
rel = Topology.SpatialRelationship(
|
|
4915
5194
|
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=
|
|
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
|
|
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.
|
|
1
|
+
__version__ = '0.8.89'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: topologicpy
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.89
|
|
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=
|
|
15
|
+
topologicpy/Graph.py,sha256=AfX4M_55zGBOm5RwpVEkr3JHv-hITFh9ckW1_jsLxFs,808052
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
35
|
-
topologicpy-0.8.
|
|
36
|
-
topologicpy-0.8.
|
|
37
|
-
topologicpy-0.8.
|
|
38
|
-
topologicpy-0.8.
|
|
39
|
-
topologicpy-0.8.
|
|
34
|
+
topologicpy/version.py,sha256=YhsAc7e0YNllH7mN5LamhWpA_q-FmHWAFByeNTu5xTk,23
|
|
35
|
+
topologicpy-0.8.89.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
|
|
36
|
+
topologicpy-0.8.89.dist-info/METADATA,sha256=55cNepIhl59TBcxtlcTmihxcT8dcait0fIEuKHXUq3A,10535
|
|
37
|
+
topologicpy-0.8.89.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
38
|
+
topologicpy-0.8.89.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
|
|
39
|
+
topologicpy-0.8.89.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|