topologicpy 0.8.38__py3-none-any.whl → 0.8.40__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/Color.py CHANGED
@@ -55,7 +55,80 @@ class Color:
55
55
 
56
56
  return return_hex.upper()
57
57
 
58
-
58
+ @staticmethod
59
+ def AverageHex(*colors, silent: bool = False):
60
+ """
61
+ Averages the input list of hex colors.
62
+
63
+ Parameters
64
+ ----------
65
+ colors : *list or str
66
+ The input color parameter which can be any of RGB, CMYK, CSS Named Color, or Hex
67
+
68
+ Returns
69
+ -------
70
+ str
71
+ A hexadecimal color string in the format '#RRGGBB'.
72
+ """
73
+ from topologicpy.Helper import Helper
74
+ import inspect
75
+
76
+ def avg(hex1, hex2):
77
+ # Remove leading "#" if present
78
+ hex1 = hex1.lstrip('#')
79
+ hex2 = hex2.lstrip('#')
80
+
81
+ # Convert to RGB components
82
+ r1, g1, b1 = int(hex1[0:2], 16), int(hex1[2:4], 16), int(hex1[4:6], 16)
83
+ r2, g2, b2 = int(hex2[0:2], 16), int(hex2[2:4], 16), int(hex2[4:6], 16)
84
+
85
+ # Compute average for each channel
86
+ r_avg = (r1 + r2) // 2
87
+ g_avg = (g1 + g2) // 2
88
+ b_avg = (b1 + b2) // 2
89
+
90
+ # Return as hex string
91
+ return f"#{r_avg:02X}{g_avg:02X}{b_avg:02X}"
92
+
93
+ if len(colors) == 0:
94
+ if not silent:
95
+ print("Color.AverageColors - Error: The input colors parameter is an empty list. Returning None.")
96
+ curframe = inspect.currentframe()
97
+ calframe = inspect.getouterframes(curframe, 2)
98
+ print('caller name:', calframe[1][3])
99
+ return None
100
+ if len(colors) == 1:
101
+ colorList = colors[0]
102
+ if isinstance(colorList, list):
103
+ if len(colorList) == 0:
104
+ if not silent:
105
+ print("Color.AverageHex - Error: The input colors parameter is an empty list. Returning None.")
106
+ curframe = inspect.currentframe()
107
+ calframe = inspect.getouterframes(curframe, 2)
108
+ print('caller name:', calframe[1][3])
109
+ return None
110
+ else:
111
+ if not silent:
112
+ print("Color.AverageHex - Warning: The input colors parameter contains only one color. Returning the same topology.")
113
+ curframe = inspect.currentframe()
114
+ calframe = inspect.getouterframes(curframe, 2)
115
+ print('caller name:', calframe[1][3])
116
+ return colorList
117
+ else:
118
+ colorList = Helper.Flatten(list(colors))
119
+ colorList = [x for x in colorList if isinstance(x, str)]
120
+ if len(colorList) == 0:
121
+ if not silent:
122
+ print("Color.AverageHex - Error: The input parameters do not contain any valid colors. Returning None.")
123
+ curframe = inspect.currentframe()
124
+ calframe = inspect.getouterframes(curframe, 2)
125
+ print('caller name:', calframe[1][3])
126
+ return None
127
+ final_color = Color.AnyToHex(colorList[0])
128
+ for clr in colorList[1:]:
129
+ final_color = avg(final_color, Color.AnyToHex(clr))
130
+ return final_color
131
+
59
132
  @staticmethod
60
133
  def ByCSSNamedColor(color, alpha: float = None):
61
134
  """
topologicpy/Dictionary.py CHANGED
@@ -324,6 +324,7 @@ class Dictionary():
324
324
  return new_dictionaries[0]
325
325
  else:
326
326
  dictionaries = return_dictionaries
327
+
327
328
  sinkKeys = []
328
329
  sinkValues = []
329
330
  d = dictionaries[0]
topologicpy/Graph.py CHANGED
@@ -6295,7 +6295,9 @@ class Graph:
6295
6295
  if not vertices:
6296
6296
  edges = []
6297
6297
  _ = graph.Edges(edges, tolerance) # Hook to Core
6298
- return edges
6298
+ if not edges:
6299
+ return []
6300
+ return list(dict.fromkeys(edges)) # remove duplicates
6299
6301
  else:
6300
6302
  vertices = [v for v in vertices if Topology.IsInstance(v, "Vertex")]
6301
6303
  if len(vertices) < 1:
@@ -12909,4 +12911,719 @@ class Graph:
12909
12911
  numerator = sum(min(weights1.get(k, 0), weights2.get(k, 0)) for k in keys)
12910
12912
  denominator = sum(max(weights1.get(k, 0), weights2.get(k, 0)) for k in keys)
12911
12913
 
12912
- return round(numerator / denominator, mantissa) if denominator != 0 else 0.0
12914
+ return round(numerator / denominator, mantissa) if denominator != 0 else 0.0
12915
+
12916
+ @staticmethod
12917
+ def _vertex_is_same(v1, v2, keys=None, tolerance=0.0001):
12918
+ from topologicpy.Vertex import Vertex
12919
+ from topologicpy.Topology import Topology
12920
+ from topologicpy.Dictionary import Dictionary
12921
+
12922
+ if keys == None or keys == [] or keys == "":
12923
+ return Vertex.Distance(v1, v2) <= tolerance
12924
+
12925
+ if isinstance(keys, str):
12926
+ if "loc" in keys.lower() or "coord" in keys.lower() or "xyz" in keys.lower():
12927
+ return Vertex.Distance(v1, v2) <= tolerance
12928
+ if not isinstance(keys, list):
12929
+ keys = [keys]
12930
+
12931
+ d1 = Topology.Dictionary(v1)
12932
+ d2 = Topology.Dictionary(v2)
12933
+ a = [Dictionary.ValueAtKey(d1, k, "0") for k in keys]
12934
+ b = [Dictionary.ValueAtKey(d2, k, "1") for k in keys]
12935
+ return a == b
12936
+
12937
+ @staticmethod
12938
+ def _vertex_in_list(vertex, vertex_list, keys=None, tolerance=0.0001):
12939
+ for i, v1 in enumerate(vertex_list):
12940
+ if Graph._vertex_is_same(vertex, v1, keys=keys, tolerance=tolerance):
12941
+ return i+1
12942
+ return False
12943
+
12944
+ @staticmethod
12945
+ def _edge_in_list(edge, edge_list, vertices_a, vertices_b, keys=None, tolerance=0.0001):
12946
+ sv1 = vertices_a[edge[0]]
12947
+ ev1 = vertices_a[edge[1]]
12948
+ for i, e in enumerate(edge_list):
12949
+ sv2 = vertices_b[e[0]]
12950
+ ev2 = vertices_b[e[1]]
12951
+ if (Graph._vertex_is_same(sv1, sv2, keys=keys, tolerance=tolerance) and Graph._vertex_is_same(ev1, ev2, keys=keys, tolerance=tolerance)) or \
12952
+ (Graph._vertex_is_same(sv1, ev2, keys=keys, tolerance=tolerance) and Graph._vertex_is_same(ev1, sv2, keys=keys, tolerance=tolerance)):
12953
+ return i+1
12954
+ return False
12955
+
12956
+ @staticmethod
12957
+ def Union(graphA, graphB, vertexKeys=None, useCentroid: bool = False, tolerance: float = 0.0001, silent: bool = False):
12958
+ """
12959
+ Union the two input graphs based on the input vertex keys. See https://en.wikipedia.org/wiki/Boolean_operation.
12960
+
12961
+ Parameters
12962
+ ----------
12963
+ graphA : topologic_core.Graph
12964
+ The first input graph.
12965
+ graphB : topologic_core.Graph
12966
+ The second input graph.
12967
+ vertexKeys : list or str , optional
12968
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
12969
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
12970
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
12971
+ useCentroid : bool , optional
12972
+ If set to True, the coordinates of identical vertices from each graph are averaged to located the new merged vertex of the resulting graph.
12973
+ Otherwise, the coordinates of the vertex of the first input graph are used. The default is False.
12974
+ tolerance : float , optional
12975
+ The desired tolerance. The default is 0.0001.
12976
+ silent : bool , optional
12977
+ If set to True, error and warning messages are suppressed. The default is False.
12978
+
12979
+ Returns
12980
+ -------
12981
+ topologic_core.Graph
12982
+ the resultant graph. Vertex and edge dictionaries are merged.
12983
+
12984
+ """
12985
+ from topologicpy.Vertex import Vertex
12986
+ from topologicpy.Edge import Edge
12987
+ from topologicpy.Topology import Topology
12988
+ from topologicpy.Dictionary import Dictionary
12989
+ from topologicpy.Cluster import Cluster
12990
+
12991
+ if not Topology.IsInstance(graphA, "graph"):
12992
+ if not silent:
12993
+ print("Graph.Union - Error: The graphA input parameter is not a valid graph. Returning None.")
12994
+ return None
12995
+ if not Topology.IsInstance(graphB, "graph"):
12996
+ if not silent:
12997
+ print("Graph.Union - Error: The graphB input parameter is not a valid graph. Returning None.")
12998
+ return None
12999
+ vertices_a = Graph.Vertices(graphA)
13000
+ vertices_a_new = []
13001
+ for v in vertices_a:
13002
+ d = Topology.Dictionary(v)
13003
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13004
+ v_new = Topology.SetDictionary(v_new, d)
13005
+ vertices_a_new.append(v_new)
13006
+ vertices_a = vertices_a_new
13007
+ vertices_b = Graph.Vertices(graphB)
13008
+ vertices_b_new = []
13009
+ for v in vertices_b:
13010
+ d = Topology.Dictionary(v)
13011
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13012
+ v_new = Topology.SetDictionary(v_new, d)
13013
+ vertices_b_new.append(v_new)
13014
+ vertices_b = vertices_b_new
13015
+ mesh_data_a = Graph.MeshData(graphA)
13016
+ mesh_data_b = Graph.MeshData(graphB)
13017
+ edges_a = mesh_data_a['edges']
13018
+ edges_b = mesh_data_b['edges']
13019
+ edges_a_dicts = mesh_data_a['edgeDictionaries']
13020
+ edges_b_dicts = mesh_data_b['edgeDictionaries']
13021
+
13022
+ union_vertices = []
13023
+
13024
+ def _add_vertex(v):
13025
+ for i, uv in enumerate(union_vertices):
13026
+ if Graph._vertex_is_same(v, uv, keys=vertexKeys):
13027
+ d_a = Topology.Dictionary(v)
13028
+ d_b = Topology.Dictionary(uv)
13029
+ d_c = Dictionary.ByMergedDictionaries(d_a, d_b)
13030
+ if useCentroid:
13031
+ c = Topology.Centroid(Cluster.ByTopologies([v, uv]))
13032
+ else:
13033
+ c = uv
13034
+ c = Topology.SetDictionary(c, d_c)
13035
+ union_vertices[i] = c
13036
+ return i
13037
+ union_vertices.append(v)
13038
+ return len(union_vertices) - 1
13039
+
13040
+ # Map original vertices to indices in union list
13041
+ index_map_a = [_add_vertex(v) for v in vertices_a]
13042
+ index_map_b = [_add_vertex(v) for v in vertices_b]
13043
+
13044
+ union_edges = []
13045
+
13046
+ def _add_edge(i, j, dictionary):
13047
+ vi = union_vertices[i]
13048
+ vj = union_vertices[j]
13049
+ for k, e in enumerate(union_edges):
13050
+ svi = Edge.StartVertex(e)
13051
+ evi = Edge.EndVertex(e)
13052
+ if (Graph._vertex_is_same(svi, vi, keys=vertexKeys, tolerance=tolerance) and Graph._vertex_is_same(evi, vj, keys=vertexKeys, tolerance=tolerance)) or \
13053
+ (Graph._vertex_is_same(svi, vj, keys=vertexKeys, tolerance=tolerance) and Graph._vertex_is_same(evi, vi, keys=vertexKeys, tolerance=tolerance)):
13054
+ # Merge dictionaries
13055
+ d_a = Topology.Dictionary(e)
13056
+ d_c = Dictionary.ByMergedDictionaries([d_a, dictionary], silent=True)
13057
+ new_edge = Edge.ByVertices(vi, vj)
13058
+ new_edge = Topology.SetDictionary(new_edge, d_c, silent=True)
13059
+ union_edges[k] = new_edge
13060
+ return
13061
+ # If not found, add new edge
13062
+ edge = Edge.ByVertices(vi, vj)
13063
+ edge = Topology.SetDictionary(edge, dictionary)
13064
+ union_edges.append(edge)
13065
+
13066
+ # Add edges from A
13067
+ for idx, e in enumerate(edges_a):
13068
+ i = index_map_a[e[0]]
13069
+ j = index_map_a[e[1]]
13070
+ if not i == j:
13071
+ _add_edge(i, j, Dictionary.ByPythonDictionary(edges_a_dicts[idx]))
13072
+
13073
+ # Add edges from B, merging duplicates
13074
+ for idx, e in enumerate(edges_b):
13075
+ i = index_map_b[e[0]]
13076
+ j = index_map_b[e[1]]
13077
+ if not i == j:
13078
+ _add_edge(i, j, Dictionary.ByPythonDictionary(edges_b_dicts[idx]))
13079
+
13080
+ return Graph.ByVerticesEdges(union_vertices, union_edges)
13081
+
13082
+ @staticmethod
13083
+ def Impose(graphA, graphB, vertexKeys=None, useCentroid: bool = False, tolerance: float = 0.0001, silent: bool = False):
13084
+ """
13085
+ Imposes the second input graph on the first input graph based on the input vertex keys. See https://en.wikipedia.org/wiki/Boolean_operation.
13086
+
13087
+ Parameters
13088
+ ----------
13089
+ graphA : topologic_core.Graph
13090
+ The first input graph.
13091
+ graphB : topologic_core.Graph
13092
+ The second input graph.
13093
+ vertexKeys : list or str , optional
13094
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13095
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13096
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13097
+ useCentroid : bool , optional
13098
+ If set to True, the coordinates of identical vertices from each graph are averaged to located the new merged vertex of the resulting graph.
13099
+ Otherwise, the coordinates of the vertex of the second input graph are used. The default is False.
13100
+ tolerance : float , optional
13101
+ The desired tolerance. The default is 0.0001.
13102
+ silent : bool , optional
13103
+ If set to True, error and warning messages are suppressed. The default is False.
13104
+
13105
+
13106
+ Returns
13107
+ -------
13108
+ topologic_core.Graph
13109
+ the resultant graph. Vertex and edge dictionaries are merged.
13110
+
13111
+ """
13112
+ from topologicpy.Vertex import Vertex
13113
+ from topologicpy.Edge import Edge
13114
+ from topologicpy.Topology import Topology
13115
+ from topologicpy.Dictionary import Dictionary
13116
+ from topologicpy.Cluster import Cluster
13117
+
13118
+ if not Topology.IsInstance(graphA, "graph"):
13119
+ if not silent:
13120
+ print("Graph.Impose - Error: The graphA input parameter is not a valid graph. Returning None.")
13121
+ return None
13122
+ if not Topology.IsInstance(graphB, "graph"):
13123
+ if not silent:
13124
+ print("Graph.Impose - Error: The graphB input parameter is not a valid graph. Returning None.")
13125
+ return None
13126
+ vertices_a = Graph.Vertices(graphA)
13127
+ vertices_a_new = []
13128
+ for v in vertices_a:
13129
+ d = Topology.Dictionary(v)
13130
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13131
+ v_new = Topology.SetDictionary(v_new, d)
13132
+ vertices_a_new.append(v_new)
13133
+ vertices_a = vertices_a_new
13134
+ vertices_b = Graph.Vertices(graphB)
13135
+ vertices_b_new = []
13136
+ for v in vertices_b:
13137
+ d = Topology.Dictionary(v)
13138
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13139
+ v_new = Topology.SetDictionary(v_new, d)
13140
+ vertices_b_new.append(v_new)
13141
+ vertices_b = vertices_b_new
13142
+ mesh_data_a = Graph.MeshData(graphA)
13143
+ mesh_data_b = Graph.MeshData(graphB)
13144
+ edges_a = mesh_data_a['edges']
13145
+ edges_b = mesh_data_b['edges']
13146
+ edges_a_dicts = mesh_data_a['edgeDictionaries']
13147
+ edges_b_dicts = mesh_data_b['edgeDictionaries']
13148
+
13149
+ union_vertices = []
13150
+
13151
+ def _add_vertex(v):
13152
+ for i, uv in enumerate(union_vertices):
13153
+ if Graph._vertex_is_same(v, uv, keys=vertexKeys):
13154
+ d_c = Topology.Dictionary(v) # Dictionaries of graphB are imposed.
13155
+ if useCentroid:
13156
+ c = Topology.Centroid(Cluster.ByTopologies([v, uv]))
13157
+ else:
13158
+ c = v
13159
+ c = Topology.SetDictionary(c, d_c)
13160
+ union_vertices[i] = c
13161
+ return i
13162
+ union_vertices.append(v)
13163
+ return len(union_vertices) - 1
13164
+
13165
+ # Map original vertices to indices in union list
13166
+ index_map_a = [_add_vertex(v) for v in vertices_a]
13167
+ index_map_b = [_add_vertex(v) for v in vertices_b]
13168
+
13169
+ union_edges = []
13170
+
13171
+ def _add_edge(i, j, dictionary):
13172
+ vi = union_vertices[i]
13173
+ vj = union_vertices[j]
13174
+ for k, e in enumerate(union_edges):
13175
+ svi = Edge.StartVertex(e)
13176
+ evi = Edge.EndVertex(e)
13177
+ if (Graph._vertex_is_same(svi, vi, keys=vertexKeys, tolerance=tolerance) and Graph._vertex_is_same(evi, vj, keys=vertexKeys, tolerance=tolerance)) or \
13178
+ (Graph._vertex_is_same(svi, vj, keys=vertexKeys, tolerance=tolerance) and Graph._vertex_is_same(evi, vi, keys=vertexKeys, tolerance=tolerance)):
13179
+ # Impose edge dictionary from graphB
13180
+ new_edge = Edge.ByVertices(vi, vj)
13181
+ new_edge = Topology.SetDictionary(new_edge, dictionary, silent=True)
13182
+ union_edges[k] = new_edge
13183
+ return
13184
+ # If not found, add new edge
13185
+ edge = Edge.ByVertices(vi, vj)
13186
+ edge = Topology.SetDictionary(edge, dictionary)
13187
+ union_edges.append(edge)
13188
+
13189
+ # Add edges from A
13190
+ for idx, e in enumerate(edges_a):
13191
+ i = index_map_a[e[0]]
13192
+ j = index_map_a[e[1]]
13193
+ if not i == j:
13194
+ _add_edge(i, j, Dictionary.ByPythonDictionary(edges_a_dicts[idx]))
13195
+
13196
+ # Add edges from B, merging duplicates
13197
+ for idx, e in enumerate(edges_b):
13198
+ i = index_map_b[e[0]]
13199
+ j = index_map_b[e[1]]
13200
+ if not i == j:
13201
+ _add_edge(i, j, Dictionary.ByPythonDictionary(edges_b_dicts[idx]))
13202
+
13203
+ return Graph.ByVerticesEdges(union_vertices, union_edges)
13204
+
13205
+ @staticmethod
13206
+ def Imprint(graphA, graphB, vertexKeys, useCentroid: bool = False, tolerance: float = 0.0001, silent: bool = False):
13207
+ """
13208
+ Imprints the second input graph on the first input graph based on the input vertex keys. See https://en.wikipedia.org/wiki/Boolean_operation.
13209
+
13210
+ Parameters
13211
+ ----------
13212
+ graphA : topologic_core.Graph
13213
+ The first input graph.
13214
+ graphB : topologic_core.Graph
13215
+ The second input graph.
13216
+ vertexKeys : list or str , optional
13217
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13218
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13219
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13220
+ useCentroid : bool , optional
13221
+ If set to True, the coordinates of identical vertices from each graph are averaged to located the new merged vertex of the resulting graph.
13222
+ Otherwise, the coordinates of the vertex of the first input graph are used. The default is False.
13223
+ tolerance : float , optional
13224
+ The desired tolerance. The default is 0.0001.
13225
+ silent : bool , optional
13226
+ If set to True, error and warning messages are suppressed. The default is False.
13227
+
13228
+ Returns
13229
+ -------
13230
+ topologic_core.Graph
13231
+ the resultant graph. Vertex and edge dictionaries are merged.
13232
+
13233
+ """
13234
+ from topologicpy.Vertex import Vertex
13235
+ from topologicpy.Edge import Edge
13236
+ from topologicpy.Cluster import Cluster
13237
+ from topologicpy.Topology import Topology
13238
+ from topologicpy.Dictionary import Dictionary
13239
+
13240
+ if not Topology.IsInstance(graphA, "graph"):
13241
+ if not silent:
13242
+ print("Graph.Imprint - Error: The graphA input parameter is not a valid graph. Returning None.")
13243
+ return None
13244
+ if not Topology.IsInstance(graphB, "graph"):
13245
+ if not silent:
13246
+ print("Graph.Imprint - Error: The graphB input parameter is not a valid graph. Returning None.")
13247
+ return None
13248
+
13249
+ vertices_a = Graph.Vertices(graphA)
13250
+ vertices_a_new = []
13251
+ for v in vertices_a:
13252
+ d = Topology.Dictionary(v)
13253
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13254
+ v_new = Topology.SetDictionary(v_new, d)
13255
+ vertices_a_new.append(v_new)
13256
+ vertices_a = vertices_a_new
13257
+ vertices_b = Graph.Vertices(graphB)
13258
+ vertices_b_new = []
13259
+ for v in vertices_b:
13260
+ d = Topology.Dictionary(v)
13261
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13262
+ v_new = Topology.SetDictionary(v_new, d)
13263
+ vertices_b_new.append(v_new)
13264
+ vertices_b = vertices_b_new
13265
+ mesh_data_a = Graph.MeshData(graphA)
13266
+ mesh_data_b = Graph.MeshData(graphB)
13267
+ topo_edges_a = Graph.Edges(graphA)
13268
+ edges_a = mesh_data_a['edges']
13269
+ edges_b = mesh_data_b['edges']
13270
+ edges_b_dicts = mesh_data_b['edgeDictionaries']
13271
+
13272
+ final_vertices = []
13273
+ vertex_map = {}
13274
+ for i, a in enumerate(vertices_a):
13275
+ j = Graph._vertex_in_list(a, vertices_b, keys=vertexKeys, tolerance=tolerance)
13276
+ if j:
13277
+ b = vertices_b[j-1]
13278
+ if useCentroid:
13279
+ c = Topology.Centroid(Cluster.ByTopologies([a, b]))
13280
+ else:
13281
+ c = a
13282
+ d_c = Topology.Dictionary(b)
13283
+ c = Topology.SetDictionary(c, d_c, silent=True)
13284
+ vertex_map[i] = c
13285
+ final_vertices.append(c)
13286
+ else:
13287
+ final_vertices.append(a)
13288
+ if len(final_vertices) < 1:
13289
+ if not silent:
13290
+ print("Graph.Imprint - Warning: graphA and graphB do not intersect. Returning None.")
13291
+ return None
13292
+
13293
+ final_edges = []
13294
+
13295
+ for i, e in enumerate(edges_a):
13296
+ j = Graph._edge_in_list(e, edges_b, vertices_a, vertices_b, keys=vertexKeys, tolerance=tolerance)
13297
+ if j:
13298
+ # Merge the dictionaries
13299
+ d_c = Dictionary.ByPythonDictionary(edges_b_dicts[j-1]) # We added 1 to j to avoid 0 which can be interpreted as False.
13300
+ # Create the edge
13301
+ #final_edge = Edge.ByVertices(vertices_a[e[0]], vertices_a[e[1]])
13302
+ sv = vertex_map[e[0]]
13303
+ ev = vertex_map[e[1]]
13304
+ final_edge = Edge.ByVertices(sv, ev)
13305
+ # Set the edge's dictionary
13306
+ final_edge = Topology.SetDictionary(final_edge, d_c, silent=True)
13307
+ # Add the final edge to the list
13308
+ final_edges.append(final_edge)
13309
+ else:
13310
+ final_edges.append(topo_edges_a[i])
13311
+
13312
+ return Graph.ByVerticesEdges(final_vertices, final_edges)
13313
+
13314
+ @staticmethod
13315
+ def Intersect(graphA, graphB, vertexKeys, vertexColorKey="color", useCentroid: bool = False, tolerance: float = 0.0001, silent: bool = False):
13316
+ """
13317
+ Intersect the two input graphs based on the input vertex keys. See https://en.wikipedia.org/wiki/Boolean_operation.
13318
+
13319
+ Parameters
13320
+ ----------
13321
+ graphA : topologic_core.Graph
13322
+ The first input graph.
13323
+ graphB : topologic_core.Graph
13324
+ The second input graph.
13325
+ vertexKeys : list or str , optional
13326
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13327
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13328
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13329
+ useCentroid : bool , optional
13330
+ If set to True, the coordinates of identical vertices from each graph are averaged to located the new merged vertex of the resulting graph.
13331
+ Otherwise, the coordinates of the vertex of the first input graph are used. The default is False.
13332
+ tolerance : float , optional
13333
+ The desired tolerance. The default is 0.0001.
13334
+ silent : bool , optional
13335
+ If set to True, error and warning messages are suppressed. The default is False.
13336
+
13337
+ Returns
13338
+ -------
13339
+ topologic_core.Graph
13340
+ the resultant graph. Vertex and edge dictionaries are merged.
13341
+
13342
+ """
13343
+ from topologicpy.Vertex import Vertex
13344
+ from topologicpy.Edge import Edge
13345
+ from topologicpy.Cluster import Cluster
13346
+ from topologicpy.Topology import Topology
13347
+ from topologicpy.Dictionary import Dictionary
13348
+
13349
+ if not Topology.IsInstance(graphA, "graph"):
13350
+ if not silent:
13351
+ print("Graph.Intersect - Error: The graphA input parameter is not a valid graph. Returning None.")
13352
+ return None
13353
+ if not Topology.IsInstance(graphB, "graph"):
13354
+ if not silent:
13355
+ print("Graph.Intersect - Error: The graphB input parameter is not a valid graph. Returning None.")
13356
+ return None
13357
+
13358
+ vertices_a = Graph.Vertices(graphA)
13359
+ vertices_a_new = []
13360
+ for v in vertices_a:
13361
+ d = Topology.Dictionary(v)
13362
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13363
+ v_new = Topology.SetDictionary(v_new, d)
13364
+ vertices_a_new.append(v_new)
13365
+ vertices_a = vertices_a_new
13366
+ vertices_b = Graph.Vertices(graphB)
13367
+ vertices_b_new = []
13368
+ for v in vertices_b:
13369
+ d = Topology.Dictionary(v)
13370
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13371
+ v_new = Topology.SetDictionary(v_new, d)
13372
+ vertices_b_new.append(v_new)
13373
+ vertices_b = vertices_b_new
13374
+ mesh_data_a = Graph.MeshData(graphA)
13375
+ mesh_data_b = Graph.MeshData(graphB)
13376
+ edges_a = mesh_data_a['edges']
13377
+ edges_b = mesh_data_b['edges']
13378
+ edges_a_dicts = mesh_data_a['edgeDictionaries']
13379
+ edges_b_dicts = mesh_data_b['edgeDictionaries']
13380
+
13381
+ common_vertices = []
13382
+ vertex_map = {}
13383
+ for i, a in enumerate(vertices_a):
13384
+ j = Graph._vertex_in_list(a, vertices_b, keys=vertexKeys, tolerance=tolerance)
13385
+ if j:
13386
+ b = vertices_b[j-1]
13387
+ if useCentroid:
13388
+ c = Topology.Centroid(Cluster.ByTopologies([a, b]))
13389
+ else:
13390
+ c = a
13391
+ d_a = Topology.Dictionary(a)
13392
+ d_b = Topology.Dictionary(b)
13393
+ d_c = Dictionary.ByMergedDictionaries([d_a, d_b], silent=True)
13394
+ c = Topology.SetDictionary(c, d_c, silent=True)
13395
+ vertex_map[i] = c
13396
+ common_vertices.append(c)
13397
+ if len(common_vertices) < 1:
13398
+ if not silent:
13399
+ print("Graph.Intersect - Warning: graphA and graphB do not intersect. Returning None.")
13400
+ return None
13401
+
13402
+ common_edges = []
13403
+
13404
+ for i, e in enumerate(edges_a):
13405
+ j = Graph._edge_in_list(e, edges_b, vertices_a, vertices_b, keys=vertexKeys, tolerance=tolerance)
13406
+ if j:
13407
+ # Merge the dictionaries
13408
+ d_a = Dictionary.ByPythonDictionary(edges_a_dicts[i])
13409
+ d_b = Dictionary.ByPythonDictionary(edges_b_dicts[j-1]) # We added 1 to j to avoid 0 which can be interpreted as False.
13410
+ d_c = Dictionary.ByMergedDictionaries([d_a, d_b], silent=True)
13411
+ # Create the edge
13412
+ #final_edge = Edge.ByVertices(vertices_a[e[0]], vertices_a[e[1]])
13413
+ sv = vertex_map[e[0]]
13414
+ ev = vertex_map[e[1]]
13415
+ final_edge = Edge.ByVertices(sv, ev)
13416
+ # Set the edge's dictionary
13417
+ final_edge = Topology.SetDictionary(final_edge, d_c, silent=True)
13418
+ # Add the final edge to the list
13419
+ common_edges.append(final_edge)
13420
+
13421
+ return Graph.ByVerticesEdges(common_vertices, common_edges)
13422
+
13423
+ @staticmethod
13424
+ def Difference(graphA, graphB, vertexKeys, useCentroid: bool = False, tolerance: float = 0.0001, silent: bool = False):
13425
+ """
13426
+ Intersect the two input graphs based on the input vertex keys. See https://en.wikipedia.org/wiki/Boolean_operation.
13427
+
13428
+ Parameters
13429
+ ----------
13430
+ graphA : topologic_core.Graph
13431
+ The first input graph.
13432
+ graphB : topologic_core.Graph
13433
+ The second input graph.
13434
+ vertexKeys : list or str , optional
13435
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13436
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13437
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13438
+ useCentroid : bool , optional
13439
+ This is not used here, but included for API consistency for boolean operations.
13440
+ tolerance : float , optional
13441
+ The desired tolerance. The default is 0.0001.
13442
+ silent : bool , optional
13443
+ If set to True, error and warning messages are suppressed. The default is False.
13444
+
13445
+ Returns
13446
+ -------
13447
+ topologic_core.Graph
13448
+ the resultant graph. Vertex and edge dictionaries are not merged.
13449
+
13450
+ """
13451
+ from topologicpy.Vertex import Vertex
13452
+ from topologicpy.Edge import Edge
13453
+ from topologicpy.Topology import Topology
13454
+ from topologicpy.Dictionary import Dictionary
13455
+
13456
+ if not Topology.IsInstance(graphA, "graph"):
13457
+ if not silent:
13458
+ print("Graph.Difference - Error: The graphA input parameter is not a valid graph. Returning None.")
13459
+ return None
13460
+ if not Topology.IsInstance(graphB, "graph"):
13461
+ if not silent:
13462
+ print("Graph.Difference - Error: The graphB input parameter is not a valid graph. Returning None.")
13463
+ return None
13464
+
13465
+ vertices_a = Graph.Vertices(graphA)
13466
+ vertices_a_new = []
13467
+ for v in vertices_a:
13468
+ d = Topology.Dictionary(v)
13469
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13470
+ v_new = Topology.SetDictionary(v_new, d)
13471
+ vertices_a_new.append(v_new)
13472
+ vertices_a = vertices_a_new
13473
+ vertices_b = Graph.Vertices(graphB)
13474
+ vertices_b_new = []
13475
+ for v in vertices_b:
13476
+ d = Topology.Dictionary(v)
13477
+ v_new = Vertex.ByCoordinates(Vertex.Coordinates(v))
13478
+ v_new = Topology.SetDictionary(v_new, d)
13479
+ vertices_b_new.append(v_new)
13480
+ vertices_b = vertices_b_new
13481
+ mesh_data_a = Graph.MeshData(graphA)
13482
+ mesh_data_b = Graph.MeshData(graphB)
13483
+ edges_a = mesh_data_a['edges']
13484
+ edges_b = mesh_data_b['edges']
13485
+ edges_a_dicts = mesh_data_a['edgeDictionaries']
13486
+
13487
+ diff_vertices = [v for v in vertices_a if not Graph._vertex_in_list(v, vertices_b, keys=vertexKeys, tolerance=tolerance)]
13488
+ diff_edges = []
13489
+
13490
+ for i, e in enumerate(edges_a):
13491
+ if not Graph._edge_in_list(e, edges_b, vertices_a, vertices_b, keys=vertexKeys, tolerance=tolerance):
13492
+ # Create the edge
13493
+ if Graph._vertex_in_list(vertices_a[e[0]], diff_vertices, keys=vertexKeys, tolerance=tolerance) and Graph._vertex_in_list(vertices_a[e[1]], diff_vertices, keys=vertexKeys, tolerance=tolerance):
13494
+ final_edge = Edge.ByVertices(vertices_a[e[0]], vertices_a[e[1]])
13495
+ # Set the edge's dictionary
13496
+ final_edge = Topology.SetDictionary(final_edge, Dictionary.ByPythonDictionary(edges_a_dicts[i]), silent=True)
13497
+ # Add the final edge to the list
13498
+ diff_edges.append(final_edge)
13499
+
13500
+ return Graph.ByVerticesEdges(diff_vertices, diff_edges)
13501
+
13502
+ @staticmethod
13503
+ def Merge(graphA, graphB, vertexKeys=None, vertexColorKey="color", useCentroid: bool = False, tolerance: float = 0.0001, silent: bool = False):
13504
+ """
13505
+ Merges the two input graphs based on the input vertex keys. This is an alias for Graph.Union. See https://en.wikipedia.org/wiki/Boolean_operation.
13506
+
13507
+ Parameters
13508
+ ----------
13509
+ graphA : topologic_core.Graph
13510
+ The first input graph.
13511
+ graphB : topologic_core.Graph
13512
+ The second input graph.
13513
+ vertexKeys : list or str , optional
13514
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13515
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13516
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13517
+ vertexColorKey : str , optional
13518
+ The dictionary key that is storing the vertex's color. The final colors will be averaged. The default is "color".
13519
+ useCentroid : bool , optional
13520
+ If set to True, the coordinates of identical vertices from each graph are averaged to located the new merged vertex of the resulting graph.
13521
+ Otherwise, the coordinates of the vertex of the first input graph are used. The default is False.
13522
+ tolerance : float , optional
13523
+ The desired tolerance. The default is 0.0001.
13524
+ silent : bool , optional
13525
+ If set to True, error and warning messages are suppressed. The default is False.
13526
+
13527
+ Returns
13528
+ -------
13529
+ topologic_core.Graph
13530
+ the resultant graph. Vertex and edge dictionaries are merged.
13531
+
13532
+ """
13533
+ from topologicpy.Topology import Topology
13534
+
13535
+ if not Topology.IsInstance(graphA, "graph"):
13536
+ if not silent:
13537
+ print("Graph.Union - Error: The graphA input parameter is not a valid graph. Returning None.")
13538
+ return None
13539
+ if not Topology.IsInstance(graphB, "graph"):
13540
+ if not silent:
13541
+ print("Graph.Union - Error: The graphB input parameter is not a valid graph. Returning None.")
13542
+ return None
13543
+ return Graph.Union(graphA, graphB, vertexKeys=vertexKeys, vertexColorKey=vertexColorKey, useCentroid=useCentroid, tolerance=tolerance, silent=silent)
13544
+
13545
+ @staticmethod
13546
+ def SymmetricDifference(graphA, graphB, vertexKeys, useCentroid: bool = False, tolerance: float = 0.001, silent: bool = False):
13547
+ """
13548
+ Find the symmetric difference (exclusive OR / XOR) of the two input graphs based on the input vertex keys. See https://en.wikipedia.org/wiki/Boolean_operation.
13549
+
13550
+ Parameters
13551
+ ----------
13552
+ graphA : topologic_core.Graph
13553
+ The first input graph.
13554
+ graphB : topologic_core.Graph
13555
+ The second input graph.
13556
+ vertexKeys : list or str , optional
13557
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13558
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13559
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13560
+ useCentroid : bool , optional
13561
+ This is not used here, but included for API consistency for boolean operations.
13562
+ tolerance : float , optional
13563
+ The desired tolerance. The default is 0.0001.
13564
+ silent : bool , optional
13565
+ If set to True, error and warning messages are suppressed. The default is False.
13566
+
13567
+ Returns
13568
+ -------
13569
+ topologic_core.Graph
13570
+ the resultant graph. Vertex and edge dictionaries are not merged.
13571
+
13572
+ """
13573
+
13574
+ from topologicpy.Topology import Topology
13575
+
13576
+ if not Topology.IsInstance(graphA, "graph"):
13577
+ if not silent:
13578
+ print("Graph.SymmetricDifference - Error: The graphA input parameter is not a valid graph. Returning None.")
13579
+ return None
13580
+ if not Topology.IsInstance(graphB, "graph"):
13581
+ if not silent:
13582
+ print("Graph.SymmetricDifference - Error: The graphB input parameter is not a valid graph. Returning None.")
13583
+ return None
13584
+ diffAB = Graph.Difference(graphA, graphB, vertexKeys=vertexKeys, useCentroid=useCentroid, tolerance=tolerance, silent=True)
13585
+ diffBA = Graph.Difference(graphB, graphA, vertexKeys=vertexKeys, useCentroid=useCentroid, tolerance=tolerance, silent=True)
13586
+ return Graph.Union(diffAB, diffBA, vertexKeys=vertexKeys, useCentroid=useCentroid, tolerance=tolerance, silent=True)
13587
+
13588
+ @staticmethod
13589
+ def XOR(graphA, graphB, vertexKeys, useCentroid: bool = False, tolerance: float = 0.001, silent: bool = False):
13590
+ """
13591
+ Find the symmetric difference (exclusive OR / XOR) of the two input graphs based on an input vertex key. See https://en.wikipedia.org/wiki/Boolean_operation.
13592
+
13593
+ Parameters
13594
+ ----------
13595
+ graphA : topologic_core.Graph
13596
+ The first input graph.
13597
+ graphB : topologic_core.Graph
13598
+ The second input graph.
13599
+ vertexKeys : list or str , optional
13600
+ The vertex dictionary key (str) or keys (list of str) to use to determine if two vertices are the same.
13601
+ If the vertexKeys are set to None or "loc" or "coord" or "xyz" (case insensitive), the distance between the
13602
+ vertices (within the tolerance) will be used to determine sameness. The default is None.
13603
+ useCentroid : bool , optional
13604
+ This is not used here, but included for API consistency for boolean operations.
13605
+ tolerance : float , optional
13606
+ The desired tolerance. The default is 0.0001.
13607
+ silent : bool , optional
13608
+ If set to True, error and warning messages are suppressed. The default is False.
13609
+
13610
+ Returns
13611
+ -------
13612
+ topologic_core.Graph
13613
+ the resultant graph. Vertex and edge dictionaries are not merged.
13614
+
13615
+ """
13616
+
13617
+ from topologicpy.Topology import Topology
13618
+
13619
+ if not Topology.IsInstance(graphA, "graph"):
13620
+ if not silent:
13621
+ print("Graph.XOR - Error: The graphA input parameter is not a valid graph. Returning None.")
13622
+ return None
13623
+ if not Topology.IsInstance(graphB, "graph"):
13624
+ if not silent:
13625
+ print("Graph.XOR - Error: The graphB input parameter is not a valid graph. Returning None.")
13626
+ return None
13627
+ diffAB = Graph.Difference(graphA, graphB, vertexKeys=vertexKeys, useCentroid=useCentroid, tolerance=tolerance, silent=True)
13628
+ diffBA = Graph.Difference(graphB, graphA, vertexKeys=vertexKeys, useCentroid=useCentroid, tolerance=tolerance, silent=True)
13629
+ return Graph.Union(diffAB, diffBA, vertexKeys=vertexKeys, useCentroid=useCentroid, tolerance=tolerance, silent=True)
topologicpy/Plotly.py CHANGED
@@ -551,7 +551,7 @@ class Plotly:
551
551
  if not labelKey == None:
552
552
  labels[m] = Dictionary.ValueAtKey(d, key=labelKey, defaultValue=" ")
553
553
  if not sizeKey == None:
554
- sizes[m] = float(Dictionary.ValueAtKey(d, key=sizeKey))
554
+ sizes[m] = float(Dictionary.ValueAtKey(d, key=sizeKey, defaultValue=sizes[m]))
555
555
  if sizes[m] == None:
556
556
  sizes[m] = size
557
557
  if float(sizes[m]) <= 0:
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.38'
1
+ __version__ = '0.8.40'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topologicpy
3
- Version: 0.8.38
3
+ Version: 0.8.40
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
@@ -5,20 +5,20 @@ topologicpy/CSG.py,sha256=uDkOSmc8m1V_k7T3UCerODhOSyYNO4FRDzoOqt0kEt8,15590
5
5
  topologicpy/Cell.py,sha256=3et98bv27m1-7OqFCeD4cLMBgC_BAsSGyxHi_4PgJ4Y,176072
6
6
  topologicpy/CellComplex.py,sha256=NP6yptbkGXYmlfBv9fRimOnNle0mkjV8Yo_ug5NKpKE,60877
7
7
  topologicpy/Cluster.py,sha256=wvfMAx6aPrSAt5nQ4--KnqD4EK9MGjch6Dg985WF7JQ,58748
8
- topologicpy/Color.py,sha256=ZVVQRKGjebY9aOU1gpN_AbssdRRiVKlZV3f8TrsTNgg,20307
8
+ topologicpy/Color.py,sha256=FcR0-__giyGQqvgiOrG8GkA65arHbiS33Si-QbUADPI,23362
9
9
  topologicpy/Context.py,sha256=G3CwMvN8Jw2rnQRwB-n4MaQq_wLS0vPimbXKwsdMJ80,3055
10
10
  topologicpy/DGL.py,sha256=HQXy9iDnrvWGDxaBfe5pRbweQ2zLBvAf6UdjfhKkQYI,139041
11
- topologicpy/Dictionary.py,sha256=PageNwgFmLakb0cKizsCEGkL_u_JV0CVqYGRM60XdsI,40837
11
+ topologicpy/Dictionary.py,sha256=2Sxm8twR1W4ksZho0YXQB_EltK2qbZWK4UHskP3jvFQ,40846
12
12
  topologicpy/Edge.py,sha256=CPdQKaE7ft6zgh0vxekkfGRRUY_yEqkEJ14NvjSgJOA,73190
13
13
  topologicpy/EnergyModel.py,sha256=Pyb28gDDwhzlQIH0xqAygqS0P3SJxWyyV7OWS_AAfRs,53856
14
14
  topologicpy/Face.py,sha256=BT_5ymb7-s-Wb1tuaBtkopJpeNg-RbooTUk_-KInQ6c,201618
15
- topologicpy/Graph.py,sha256=e9_KSCvRI8jilx7afqicPDJqsCPHA5ucz5To8mfbFKo,605658
15
+ topologicpy/Graph.py,sha256=z_9TeMkmwFXlCfVDW9Z56PX0sHxGj8iVKlCdJLreMo0,639785
16
16
  topologicpy/Grid.py,sha256=EbI2NcYhQDpD5mItd7A1Lpr8Puuf87vZPWuoh7_gChQ,18483
17
17
  topologicpy/Helper.py,sha256=qEsE4yaboEGW94q9lFCff0I_JwwTTQnDAFXw006yHaQ,31203
18
18
  topologicpy/Honeybee.py,sha256=yctkwfdupKnp7bAOjP1Z4YaYpRrWoMEb4gz9Z5zaWwE,21751
19
19
  topologicpy/Matrix.py,sha256=LqVckk2qTwKwEo79eyNsOrHVSHdO82JCREcfy6WIk4I,22716
20
20
  topologicpy/Neo4j.py,sha256=ELKmON7R16j1kQD8xRHDGGCvzjIM2HGHNekdaXDUw6w,22371
21
- topologicpy/Plotly.py,sha256=B6CxNyAGfhv70N6sa4B4aHLYd7zIpH5S1hmpk3sQ3ys,120533
21
+ topologicpy/Plotly.py,sha256=Dmy9i9puSfvB42mrBUip3v0TCXIzHpAETWDUCDxfqNA,120556
22
22
  topologicpy/Polyskel.py,sha256=oVfM4lqSMPTjnkHfsRU9VI8Blt6Vf0LVPkD9ebz7Wmw,27082
23
23
  topologicpy/PyG.py,sha256=zvV6jtnol_aFiN6JRoMpYwBVfOU2aFs9gdWSdEo6mtU,109757
24
24
  topologicpy/ShapeGrammar.py,sha256=UVb8VPwVKd6V3zDTNzpBecQPgYo1EjSsS10XJ8k5YcI,23364
@@ -30,9 +30,9 @@ topologicpy/Vector.py,sha256=X12eqskn28bdB7sLY1EZhq3noPYzPbNEgHPb4a959ss,42302
30
30
  topologicpy/Vertex.py,sha256=epBfbD7fm87T-TZ0WuwrioXdYqg9NgRlHn_qUFtVbkc,84562
31
31
  topologicpy/Wire.py,sha256=vE6IoObVucOZVTFMPiHuNN4DDezRHHyFbwhF5WRBm3s,231547
32
32
  topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
33
- topologicpy/version.py,sha256=K8Qib--QiI1qx6hx2xqHbVpHiSCs5RJ_6E-TRDxr1Y8,23
34
- topologicpy-0.8.38.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
- topologicpy-0.8.38.dist-info/METADATA,sha256=ebAGBKEzxeo5cll1YKrRoo-G0mOx6Dwzmwsl246AwYo,10535
36
- topologicpy-0.8.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- topologicpy-0.8.38.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
- topologicpy-0.8.38.dist-info/RECORD,,
33
+ topologicpy/version.py,sha256=9UtSkYQrOL8TXxQBwLoy5jvQKNWp84nSX32fmM7V0Ac,23
34
+ topologicpy-0.8.40.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
+ topologicpy-0.8.40.dist-info/METADATA,sha256=8YuR3I1XDjArnIbbajaveZEDc7Q8eVk4aBOvtaLhULA,10535
36
+ topologicpy-0.8.40.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ topologicpy-0.8.40.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
+ topologicpy-0.8.40.dist-info/RECORD,,