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/Graph.py
CHANGED
@@ -448,6 +448,67 @@ class Graph:
|
|
448
448
|
new_graph = Graph.ByVerticesEdges(graph_vertices, graph_edges)
|
449
449
|
return new_graph
|
450
450
|
|
451
|
+
@staticmethod
|
452
|
+
def AddEdgeByIndex(graph, index: list = None, dictionary = None, silent: bool = False):
|
453
|
+
"""
|
454
|
+
Creates an edge in the input Graph by connecting the two vertices specified by their indices (e.g., [5, 6] connects the 4th and 6th vertices).
|
455
|
+
|
456
|
+
Parameters
|
457
|
+
----------
|
458
|
+
graph : topologic_core.Graph
|
459
|
+
The input graph.
|
460
|
+
index : list or tuple
|
461
|
+
The input list of vertex indices (e.g. [4, 6]).
|
462
|
+
dictionary : topologic_core.Dictionary , optional
|
463
|
+
The input edge dictionary.
|
464
|
+
silent : bool , optional
|
465
|
+
If set to True, error and warning messages are suppressed. Default is False.
|
466
|
+
|
467
|
+
Returns
|
468
|
+
-------
|
469
|
+
topologic_core.Graph
|
470
|
+
The input graph with the input edge added to it.
|
471
|
+
|
472
|
+
"""
|
473
|
+
from topologicpy.Edge import Edge
|
474
|
+
from topologicpy.Topology import Topology
|
475
|
+
|
476
|
+
if not Topology.IsInstance(graph, "Graph"):
|
477
|
+
if not silent:
|
478
|
+
print("Graph.AddEdgeIndex - Error: The input graph parameter is not a valid graph. Returning None.")
|
479
|
+
return None
|
480
|
+
if dictionary:
|
481
|
+
if not Topology.IsInstance(dictionary, "Dictionary"):
|
482
|
+
if not silent:
|
483
|
+
print("Graph.AddEdgeIndex - Error: The input dictionary parameter is not a valid dictionary. Returning None.")
|
484
|
+
return None
|
485
|
+
if not isinstance(index, list):
|
486
|
+
if not silent:
|
487
|
+
print("Graph.AddEdgeIndex - Error: The input index parameter is not a valid list. Returning None.")
|
488
|
+
return None
|
489
|
+
index = [x for x in index if isinstance(x, int)]
|
490
|
+
if not len(index) == 2:
|
491
|
+
if not silent:
|
492
|
+
print("Graph.AddEdgeIndex - Error: The input index parameter should only contain two integer numbers. Returning None.")
|
493
|
+
return None
|
494
|
+
vertices = Graph.Vertices(graph)
|
495
|
+
n = len(vertices)
|
496
|
+
if index[0] < 0 or index[0] > n-1:
|
497
|
+
if not silent:
|
498
|
+
print("Graph.AddEdgeIndex - Error: The first integer in the input index parameter does not exist in the input graph. Returning None.")
|
499
|
+
return None
|
500
|
+
if index[1] < 0 or index[1] > n-1:
|
501
|
+
if not silent:
|
502
|
+
print("Graph.AddEdgeIndex - Error: The second integer in the input index parameter does not exist in the input graph. Returning None.")
|
503
|
+
return None
|
504
|
+
sv = vertices[index[0]]
|
505
|
+
ev = vertices[index[1]]
|
506
|
+
edge = Edge.ByVertices(sv, ev)
|
507
|
+
if dictionary:
|
508
|
+
edge = Topology.SetDictionary(edge, dictionary)
|
509
|
+
graph = Graph.AddEdge(graph,edge)
|
510
|
+
return graph
|
511
|
+
|
451
512
|
@staticmethod
|
452
513
|
def AddVertex(graph, vertex, tolerance: float = 0.0001, silent: bool = False):
|
453
514
|
"""
|
@@ -2835,6 +2896,158 @@ class Graph:
|
|
2835
2896
|
graphs.append(Graph.ByVerticesEdges(vertices, edges))
|
2836
2897
|
return {'graphs':graphs, 'labels':labels}
|
2837
2898
|
|
2899
|
+
@staticmethod
|
2900
|
+
def ByDictionaries(graphDictionary, vertexDictionaries, edgeDictionaries, vertexKey: str = None, edgeKey: str = None, silent: bool = False, tolerance: float = 0.0001):
|
2901
|
+
"""
|
2902
|
+
Creates a graph from input python dictionaries.
|
2903
|
+
|
2904
|
+
Rules:
|
2905
|
+
All vertex dictionaries must contain at least the vertexKey.
|
2906
|
+
All edge dictionaries must contain at least the edgeKey.
|
2907
|
+
The edgeKey must be a tuple or list of two str values.
|
2908
|
+
x,y,z coordinates are optional. However, if a vertex dictionary contains x,y,z coordinates then all vertex dictionaries must contain x,y,z coordinates.
|
2909
|
+
If vertex dictionaries contain x,y,z coordinates they must not overlap and be separated by a distance greater than tolerance.
|
2910
|
+
Keys and values are case sensitive.
|
2911
|
+
x,y,z keys, if present must be lowercase.
|
2912
|
+
|
2913
|
+
Example:
|
2914
|
+
graphDictionary = {"name": "Small Apartment", "location": "123 Main Street"}
|
2915
|
+
vertexDictionaries = [
|
2916
|
+
{"name":"Entry", "type":"Circulation", "x":1, "y":4, "z":0, "area":5},
|
2917
|
+
{"name":"Living Room", "type":"Living Room", "x":3, "y":4 , "z":0, "area":24},
|
2918
|
+
{"name":"Dining Room", "type":"Dining Room", "x":5, "y":2, "z":0, "area":18},
|
2919
|
+
{"name":"Kitchen", "type":"Kitchen", "x":1, "y":2, "z":0, "area":15},
|
2920
|
+
{"name":"Bathroom", "type":"Bathroom", "x":3, "y":6, "z":0, "area":9},
|
2921
|
+
{"name":"Bedroom", "type":"Bedroom", "x":5, "y":4, "z":0, "area":16}
|
2922
|
+
]
|
2923
|
+
edgeDictionaries = [
|
2924
|
+
{"connects": ("Entry","Living Room"), "relationship": "adjacent_to"},
|
2925
|
+
{"connects": ("Living Room","Kitchen"), "relationship": "adjacent_to"},
|
2926
|
+
{"connects": ("Dining Room","Kitchen"), "relationship": "adjacent_to"},
|
2927
|
+
{"connects": ("Living Room","Dining Room"), "relationship": "adjacent_to"},
|
2928
|
+
{"connects": ("Living Room","Bedroom"), "relationship": "adjacent_to"},
|
2929
|
+
{"connects": ("Living Room","Bathroom"), "relationship": "adjacent_to"}
|
2930
|
+
]
|
2931
|
+
vertexKey = "name"
|
2932
|
+
edgeKey = "connects"
|
2933
|
+
|
2934
|
+
Parameters
|
2935
|
+
----------
|
2936
|
+
graphDictionary : dict
|
2937
|
+
The python dictionary to associate with the resulting graph
|
2938
|
+
vertexDictionaries : list
|
2939
|
+
The input list of vertex dictionaries. These must contain the vertexKey. X,Y,Z coordinates are optional.
|
2940
|
+
edgeDictionaries : list
|
2941
|
+
The input list of edge dictionaries. These must have the edgeKey to specify the two vertices they connect (by using the vertexKey)
|
2942
|
+
vertexKey: str
|
2943
|
+
The vertex key used to identify which vertices and edge connects.
|
2944
|
+
edgeKey: str
|
2945
|
+
The edge key under which the pair of vertex keys are listed as a tuple or list.
|
2946
|
+
tolerance: float , optional
|
2947
|
+
The desired tolerance. The default is 0.0001
|
2948
|
+
silent : bool , optional
|
2949
|
+
If set to True, error and warning messages are suppressed. Default is False.
|
2950
|
+
|
2951
|
+
Returns
|
2952
|
+
-------
|
2953
|
+
topologic_core.Graph
|
2954
|
+
The resulting graph
|
2955
|
+
|
2956
|
+
"""
|
2957
|
+
from topologicpy.Vertex import Vertex
|
2958
|
+
from topologicpy.Edge import Edge
|
2959
|
+
from topologicpy.Cluster import Cluster
|
2960
|
+
from topologicpy.Topology import Topology
|
2961
|
+
from topologicpy.Dictionary import Dictionary
|
2962
|
+
|
2963
|
+
def _set_dict(obj, kv: dict):
|
2964
|
+
keys = list(kv.keys())
|
2965
|
+
vals = list(kv.values())
|
2966
|
+
d = Dictionary.ByKeysValues(keys, vals)
|
2967
|
+
Topology.SetDictionary(obj, d)
|
2968
|
+
return obj
|
2969
|
+
|
2970
|
+
def _vertex(vertexDictionary, vertices, vertexKey, tolerance=0.0001, silent=False):
|
2971
|
+
x = vertexDictionary.get("x", 0)
|
2972
|
+
y = vertexDictionary.get("y", 0)
|
2973
|
+
z = vertexDictionary.get("z", 0)
|
2974
|
+
v = Vertex.ByCoordinates(x, y, z)
|
2975
|
+
v = _set_dict(v, vertexDictionary)
|
2976
|
+
if "x" in vertexDictionary.keys(): # Check for overlap only if coords are given.
|
2977
|
+
if len(vertices) > 0:
|
2978
|
+
nv = Vertex.NearestVertex(v, Cluster.ByTopologies(vertices))
|
2979
|
+
d = Topology.Dictionary(nv)
|
2980
|
+
nv_name = Dictionary.ValueAtKey(d, vertexKey, "Unknown")
|
2981
|
+
if Vertex.Distance(v, nv) < tolerance:
|
2982
|
+
if not silent:
|
2983
|
+
v_name = vertexDictionary[vertexKey]
|
2984
|
+
print(f"Graph.ByDictionaries - Warning: Vertices {v_name} and {nv_name} overlap.")
|
2985
|
+
return v
|
2986
|
+
|
2987
|
+
|
2988
|
+
if graphDictionary:
|
2989
|
+
if not isinstance(graphDictionary, dict):
|
2990
|
+
if not silent:
|
2991
|
+
print("Graph.ByDictionaries - Error: The input graphDictionary parameter is not a valid python dictionary. Returning None.")
|
2992
|
+
return None
|
2993
|
+
|
2994
|
+
if not isinstance(vertexDictionaries, list):
|
2995
|
+
if not silent:
|
2996
|
+
print("Graph.ByDictionaries - Error: The input vertexDictionaries parameter is not a valid list. Returning None.")
|
2997
|
+
return None
|
2998
|
+
|
2999
|
+
if not isinstance(edgeDictionaries, list):
|
3000
|
+
if not silent:
|
3001
|
+
print("Graph.ByDictionaries - Error: The input edgeDictionaries parameter is not a valid list. Returning None.")
|
3002
|
+
return None
|
3003
|
+
|
3004
|
+
name_to_vertex = {}
|
3005
|
+
vertices = []
|
3006
|
+
for vd in vertexDictionaries:
|
3007
|
+
v = _vertex(vd, vertices, vertexKey=vertexKey, tolerance=tolerance, silent=silent)
|
3008
|
+
if v:
|
3009
|
+
vertices.append(v)
|
3010
|
+
|
3011
|
+
# If coordinates are not present, make sure you separate the vertices to allow edges to be created.
|
3012
|
+
if "x" not in vertexDictionaries[0].keys():
|
3013
|
+
vertices = Vertex.Separate(vertices, minDistance=max(1, tolerance))
|
3014
|
+
|
3015
|
+
for i, v in enumerate(vertices):
|
3016
|
+
vd = vertexDictionaries[i]
|
3017
|
+
name_to_vertex[vd[vertexKey]] = v
|
3018
|
+
|
3019
|
+
# Create adjacency edges (undirected: one edge per pair)
|
3020
|
+
edges = []
|
3021
|
+
for d in edgeDictionaries:
|
3022
|
+
a, b = d[edgeKey]
|
3023
|
+
va = name_to_vertex.get(a, None)
|
3024
|
+
vb = name_to_vertex.get(b, None)
|
3025
|
+
if not va and not vb:
|
3026
|
+
if not silent:
|
3027
|
+
print(f"Graph.ByDictionaries - Warning: vertices '{a}' and '{b}' are missing. Could not create an edge between them.")
|
3028
|
+
continue
|
3029
|
+
if not va:
|
3030
|
+
if not silent:
|
3031
|
+
print(f"Graph.ByDictionaries - Warning: vertex '{a}' is missing. Could not create an edge between '{a}' and '{b}'.")
|
3032
|
+
continue
|
3033
|
+
if not vb:
|
3034
|
+
if not silent:
|
3035
|
+
print(f"Graph.ByDictionaries - Warning: vertex '{b}' is missing. Could not create an edge between '{a}' and '{b}'.")
|
3036
|
+
continue
|
3037
|
+
e = Edge.ByStartVertexEndVertex(va, vb, silent=True)
|
3038
|
+
if not e:
|
3039
|
+
if not silent:
|
3040
|
+
print(f"Graph.ByDictionaries - Warning: Could not create an edge between '{a}' and '{b}'. Check if the distance betwen '{a}' and '{b}' is kess than the input tolerance.")
|
3041
|
+
continue
|
3042
|
+
edges.append(e)
|
3043
|
+
# Build graph
|
3044
|
+
g = Graph.ByVerticesEdges(vertices, edges)
|
3045
|
+
|
3046
|
+
# Attach graph-level metadata
|
3047
|
+
if graphDictionary:
|
3048
|
+
_set_dict(g, graphDictionary)
|
3049
|
+
return g
|
3050
|
+
|
2838
3051
|
@staticmethod
|
2839
3052
|
def ByIFCFile(file,
|
2840
3053
|
includeTypes: list = [],
|
@@ -9117,8 +9330,6 @@ class Graph:
|
|
9117
9330
|
|
9118
9331
|
return pos
|
9119
9332
|
|
9120
|
-
|
9121
|
-
|
9122
9333
|
def radial_layout_2d(edge_list, root_index=0):
|
9123
9334
|
import numpy as np
|
9124
9335
|
from collections import deque
|
@@ -9270,9 +9481,15 @@ class Graph:
|
|
9270
9481
|
|
9271
9482
|
if not Topology.IsInstance(graph, "Graph"):
|
9272
9483
|
if not silent:
|
9273
|
-
print("Graph.
|
9484
|
+
print("Graph.Reshape - Error: The input graph is not a valid topologic graph. Returning None.")
|
9274
9485
|
return None
|
9275
9486
|
|
9487
|
+
vertices = Graph.Vertices(graph)
|
9488
|
+
if len(vertices) < 2:
|
9489
|
+
if not silent:
|
9490
|
+
print("Graph.Reshape - Warning: The graph has less than two vertices. It cannot be rehsaped. Returning the original input graph.")
|
9491
|
+
return graph
|
9492
|
+
|
9276
9493
|
if 'circ' in shape.lower():
|
9277
9494
|
return circle_layout_2d(graph, radius=size/2, sides=sides)
|
9278
9495
|
elif 'lin' in shape.lower():
|