topologicpy 0.8.36__py3-none-any.whl → 0.8.37__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/Cell.py CHANGED
@@ -1122,6 +1122,7 @@ class Cell():
1122
1122
  width=1,
1123
1123
  length=1,
1124
1124
  height=1,
1125
+ wSides=1,
1125
1126
  a=0.25,
1126
1127
  b=0.25,
1127
1128
  c=0.25,
@@ -1129,6 +1130,7 @@ class Cell():
1129
1130
  flipVertical = False,
1130
1131
  direction=[0,0,1],
1131
1132
  placement="center",
1133
+ mantissa=6,
1132
1134
  tolerance=0.0001,
1133
1135
  silent=False):
1134
1136
  """
@@ -1144,16 +1146,24 @@ class Cell():
1144
1146
  The overall length of the C-shape. The default is 1.0.
1145
1147
  height : float , optional
1146
1148
  The overall height of the C-shape. The default is 1.0.
1149
+ wSides : int , optional
1150
+ The desired number of sides along the Z-axis. The default is 1.
1147
1151
  a : float , optional
1148
1152
  The hortizontal thickness of the vertical arm of the C-shape. The default is 0.25.
1149
1153
  b : float , optional
1150
1154
  The vertical thickness of the bottom horizontal arm of the C-shape. The default is 0.25.
1151
1155
  c : float , optional
1152
1156
  The vertical thickness of the top horizontal arm of the C-shape. The default is 0.25.
1157
+ flipHorizontal : bool , optional
1158
+ if set to True, the shape is flipped horizontally. The default is False.
1159
+ flipVertical : bool , optional
1160
+ if set to True, the shape is flipped vertically. The default is False.
1153
1161
  direction : list , optional
1154
1162
  The vector representing the up direction of the C-shape. The default is [0, 0, 1].
1155
1163
  placement : str , optional
1156
1164
  The description of the placement of the origin of the C-shape. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
1165
+ mantissa: int , optional
1166
+ The desired length of the mantissa. The default is 6.
1157
1167
  tolerance : float , optional
1158
1168
  The desired tolerance. The default is 0.0001.
1159
1169
  silent : bool , optional
@@ -1166,7 +1176,7 @@ class Cell():
1166
1176
 
1167
1177
  """
1168
1178
  from topologicpy.Vertex import Vertex
1169
- from topologicpy.Face import Face
1179
+ from topologicpy.Wire import Wire
1170
1180
  from topologicpy.Topology import Topology
1171
1181
 
1172
1182
  if not isinstance(width, int) and not isinstance(width, float):
@@ -1234,8 +1244,8 @@ class Cell():
1234
1244
  if not len(direction) == 3:
1235
1245
  if not silent:
1236
1246
  print("Cell.CShape - Error: The direction input parameter is not a valid vector. Returning None.")
1237
- return None
1238
- c_shape_face = Face.CShape(origin=origin,
1247
+ return None
1248
+ c_shape_wire = Wire.CShape(origin=origin,
1239
1249
  width=width,
1240
1250
  length=length,
1241
1251
  a=a,
@@ -1247,9 +1257,12 @@ class Cell():
1247
1257
  placement="center",
1248
1258
  tolerance=tolerance,
1249
1259
  silent=silent)
1250
-
1251
- return_cell = Cell.ByThickenedFace(c_shape_face, thickness=height, bothSides=True, reverse=False,
1252
- planarize = False, tolerance=tolerance, silent=silent)
1260
+ distance = height/wSides
1261
+ wires = [c_shape_wire]
1262
+ for i in range(wSides):
1263
+ c_shape_wire = Topology.Translate(c_shape_wire, 0, 0, distance)
1264
+ wires.append(c_shape_wire)
1265
+ return_cell = Cell.ByWires(wires, triangulate=False, mantissa=mantissa, tolerance=tolerance, silent=silent)
1253
1266
  xOffset = 0
1254
1267
  yOffset = 0
1255
1268
  zOffset = 0
@@ -1972,18 +1985,20 @@ class Cell():
1972
1985
 
1973
1986
  @staticmethod
1974
1987
  def IShape(origin=None,
1975
- width=1,
1976
- length=1,
1977
- height=1,
1978
- a=0.25,
1979
- b=0.25,
1980
- c=0.25,
1981
- flipHorizontal = False,
1982
- flipVertical = False,
1983
- direction=[0,0,1],
1984
- placement="center",
1985
- tolerance=0.0001,
1986
- silent=False):
1988
+ width: float = 1,
1989
+ length: float = 1,
1990
+ height: float = 1,
1991
+ wSides: int = 1,
1992
+ a: float = 0.25,
1993
+ b: float = 0.25,
1994
+ c: float = 0.25,
1995
+ flipHorizontal: bool = False,
1996
+ flipVertical: bool = False,
1997
+ direction: list = [0,0,1],
1998
+ placement: str = "center",
1999
+ mantissa: int = 6,
2000
+ tolerance: float = 0.0001,
2001
+ silent: bool = False):
1987
2002
  """
1988
2003
  Creates an I-shape cell.
1989
2004
 
@@ -1995,16 +2010,26 @@ class Cell():
1995
2010
  The overall width of the I-shape. The default is 1.0.
1996
2011
  length : float , optional
1997
2012
  The overall length of the I-shape. The default is 1.0.
2013
+ height : float , optional
2014
+ The overall height of the I-shape. The default is 1.0.
2015
+ wSides : int , optional
2016
+ The desired number of sides along the Z-Axis. The default is 1.
1998
2017
  a : float , optional
1999
2018
  The hortizontal thickness of the central vertical arm of the I-shape. The default is 0.25.
2000
2019
  b : float , optional
2001
2020
  The vertical thickness of the bottom horizontal arm of the I-shape. The default is 0.25.
2002
2021
  c : float , optional
2003
2022
  The vertical thickness of the top horizontal arm of the I-shape. The default is 0.25.
2023
+ flipHorizontal : bool , optional
2024
+ if set to True, the shape is flipped horizontally. The default is False.
2025
+ flipVertical : bool , optional
2026
+ if set to True, the shape is flipped vertically. The default is False.
2004
2027
  direction : list , optional
2005
2028
  The vector representing the up direction of the I-shape. The default is [0, 0, 1].
2006
2029
  placement : str , optional
2007
2030
  The description of the placement of the origin of the I-shape. This can be "center", "bottom", "top", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
2031
+ mantissa : int , optional
2032
+ The desired length of the mantissa. The default is 6.
2008
2033
  tolerance : float , optional
2009
2034
  The desired tolerance. The default is 0.0001.
2010
2035
  silent : bool , optional
@@ -2017,7 +2042,7 @@ class Cell():
2017
2042
 
2018
2043
  """
2019
2044
  from topologicpy.Vertex import Vertex
2020
- from topologicpy.Face import Face
2045
+ from topologicpy.Wire import Wire
2021
2046
  from topologicpy.Topology import Topology
2022
2047
 
2023
2048
  if not isinstance(width, int) and not isinstance(width, float):
@@ -2074,7 +2099,7 @@ class Cell():
2074
2099
  if not silent:
2075
2100
  print("Cell.IShape - Error: The direction input parameter is not a valid vector. Returning None.")
2076
2101
  return None
2077
- i_shape_face = Face.IShape(origin=origin,
2102
+ i_shape_wire = Wire.IShape(origin=origin,
2078
2103
  width=width,
2079
2104
  length=length,
2080
2105
  a=a,
@@ -2082,12 +2107,18 @@ class Cell():
2082
2107
  c=c,
2083
2108
  flipHorizontal=flipHorizontal,
2084
2109
  flipVertical=flipVertical,
2085
- direction=direction,
2086
- placement=placement,
2110
+ direction=[0,0,1],
2111
+ placement="center",
2087
2112
  tolerance=tolerance,
2088
2113
  silent=silent)
2089
- return_cell = Cell.ByThickenedFace(i_shape_face, thickness=height, bothSides=True, reverse=False,
2090
- planarize = False, tolerance=tolerance, silent=silent)
2114
+ distance = height/wSides
2115
+ wires = [i_shape_wire]
2116
+ for i in range(wSides):
2117
+ i_shape_wire = Topology.Translate(i_shape_wire, 0, 0, distance)
2118
+ wires.append(i_shape_wire)
2119
+ return_cell = Cell.ByWires(wires, triangulate=False, mantissa=mantissa, tolerance=tolerance, silent=silent)
2120
+ # move down to center
2121
+ return_cell = Topology.Translate(return_cell, 0, 0, -height*0.5)
2091
2122
  xOffset = 0
2092
2123
  yOffset = 0
2093
2124
  zOffset = 0
@@ -2156,12 +2187,14 @@ class Cell():
2156
2187
  width=1,
2157
2188
  length=1,
2158
2189
  height=1,
2190
+ wSides=1,
2159
2191
  a=0.25,
2160
2192
  b=0.25,
2161
2193
  flipHorizontal = False,
2162
2194
  flipVertical = False,
2163
2195
  direction=[0,0,1],
2164
2196
  placement="center",
2197
+ mantissa=6,
2165
2198
  tolerance=0.0001,
2166
2199
  silent=False):
2167
2200
  """
@@ -2177,14 +2210,22 @@ class Cell():
2177
2210
  The overall length of the L-shape. The default is 1.0.
2178
2211
  height : float , optional
2179
2212
  The overall height of the L-shape. The default is 1.0.
2213
+ wSides : int , optional
2214
+ The desired number of sides along the Z-axis. The default is 1.
2180
2215
  a : float , optional
2181
2216
  The hortizontal thickness of the vertical arm of the L-shape. The default is 0.25.
2182
2217
  b : float , optional
2183
2218
  The vertical thickness of the horizontal arm of the L-shape. The default is 0.25.
2219
+ flipHorizontal : bool , optional
2220
+ if set to True, the shape is flipped horizontally. The default is False.
2221
+ flipVertical : bool , optional
2222
+ if set to True, the shape is flipped vertically. The default is False.
2184
2223
  direction : list , optional
2185
2224
  The vector representing the up direction of the L-shape. The default is [0, 0, 1].
2186
2225
  placement : str , optional
2187
2226
  The description of the placement of the origin of the L-shape. This can be "center", "bottom", "top", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
2227
+ manitssa : int , optional
2228
+ The desired length of the mantissa. The default is 6.
2188
2229
  tolerance : float , optional
2189
2230
  The desired tolerance. The default is 0.0001.
2190
2231
  silent : bool , optional
@@ -2197,7 +2238,7 @@ class Cell():
2197
2238
 
2198
2239
  """
2199
2240
  from topologicpy.Vertex import Vertex
2200
- from topologicpy.Face import Face
2241
+ from topologicpy.Wire import Wire
2201
2242
  from topologicpy.Topology import Topology
2202
2243
 
2203
2244
  if not isinstance(width, int) and not isinstance(width, float):
@@ -2262,7 +2303,7 @@ class Cell():
2262
2303
  if not silent:
2263
2304
  print("Cell.LShape - Error: The direction input parameter is not a valid vector. Returning None.")
2264
2305
  return None
2265
- l_shape_face = Face.LShape(origin=origin,
2306
+ l_shape_wire = Wire.LShape(origin=origin,
2266
2307
  width=width,
2267
2308
  length=length,
2268
2309
  a=a,
@@ -2273,9 +2314,12 @@ class Cell():
2273
2314
  placement="center",
2274
2315
  tolerance=tolerance,
2275
2316
  silent=silent)
2276
-
2277
- return_cell = Cell.ByThickenedFace(l_shape_face, thickness=height, bothSides=True, reverse=False,
2278
- planarize = False, tolerance=tolerance, silent=silent)
2317
+ distance = height/wSides
2318
+ wires = [l_shape_wire]
2319
+ for i in range(wSides):
2320
+ l_shape_wire = Topology.Translate(l_shape_wire, 0, 0, distance)
2321
+ wires.append(l_shape_wire)
2322
+ return_cell = Cell.ByWires(wires, triangulate=False, mantissa=mantissa, tolerance=tolerance, silent=silent)
2279
2323
  xOffset = 0
2280
2324
  yOffset = 0
2281
2325
  zOffset = 0
@@ -3326,12 +3370,14 @@ class Cell():
3326
3370
  width=1,
3327
3371
  length=1,
3328
3372
  height=1,
3373
+ wSides=1,
3329
3374
  a=0.25,
3330
3375
  b=0.25,
3331
3376
  flipHorizontal = False,
3332
3377
  flipVertical = False,
3333
3378
  direction=[0,0,1],
3334
3379
  placement="center",
3380
+ mantissa=6,
3335
3381
  tolerance=0.0001,
3336
3382
  silent=False):
3337
3383
  """
@@ -3347,14 +3393,22 @@ class Cell():
3347
3393
  The overall length of the T-shape. The default is 1.0.
3348
3394
  height : float , optional
3349
3395
  the overall height of the T-shape. The default is 1.0.
3396
+ wSides : int , optional
3397
+ The desired number of sides along the Z-axis. The default is 1.
3350
3398
  a : float , optional
3351
3399
  The hortizontal thickness of the vertical arm of the T-shape. The default is 0.25.
3352
3400
  b : float , optional
3353
3401
  The vertical thickness of the horizontal arm of the T-shape. The default is 0.25.
3402
+ flipHorizontal : bool , optional
3403
+ if set to True, the shape is flipped horizontally. The default is False.
3404
+ flipVertical : bool , optional
3405
+ if set to True, the shape is flipped vertically. The default is False.
3354
3406
  direction : list , optional
3355
3407
  The vector representing the up direction of the T-shape. The default is [0, 0, 1].
3356
3408
  placement : str , optional
3357
3409
  The description of the placement of the origin of the T-shape. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
3410
+ mantissa: int , optional
3411
+ The desired length of the mantissa. The default is 6.
3358
3412
  tolerance : float , optional
3359
3413
  The desired tolerance. The default is 0.0001.
3360
3414
  silent : bool , optional
@@ -3367,7 +3421,7 @@ class Cell():
3367
3421
 
3368
3422
  """
3369
3423
  from topologicpy.Vertex import Vertex
3370
- from topologicpy.Face import Face
3424
+ from topologicpy.Wire import Wire
3371
3425
  from topologicpy.Topology import Topology
3372
3426
 
3373
3427
  if not isinstance(width, int) and not isinstance(width, float):
@@ -3424,19 +3478,26 @@ class Cell():
3424
3478
  if not silent:
3425
3479
  print("Cell.TShape - Error: The direction input parameter is not a valid vector. Returning None.")
3426
3480
  return None
3427
- t_shape_face = Face.TShape(origin=origin,
3481
+ t_shape_wire = Wire.TShape(origin=origin,
3428
3482
  width=width,
3429
3483
  length=length,
3430
3484
  a=a,
3431
3485
  b=b,
3432
3486
  flipHorizontal=flipHorizontal,
3433
3487
  flipVertical=flipVertical,
3434
- direction=direction,
3435
- placement=placement,
3488
+ direction=[0,0,1],
3489
+ placement="center",
3436
3490
  tolerance=tolerance,
3437
3491
  silent=silent)
3438
- return_cell = Cell.ByThickenedFace(t_shape_face, thickness=height, bothSides=True, reverse=False,
3439
- planarize = False, tolerance=tolerance, silent=silent)
3492
+
3493
+ distance = height/wSides
3494
+ wires = [t_shape_wire]
3495
+ for i in range(wSides):
3496
+ t_shape_wire = Topology.Translate(t_shape_wire, 0, 0, distance)
3497
+ wires.append(t_shape_wire)
3498
+ return_cell = Cell.ByWires(wires, triangulate=False, mantissa=mantissa, tolerance=tolerance, silent=silent)
3499
+ # move down to center
3500
+ return_cell = Topology.Translate(return_cell, 0, 0, -height*0.5)
3440
3501
  xOffset = 0
3441
3502
  yOffset = 0
3442
3503
  zOffset = 0
topologicpy/Face.py CHANGED
@@ -2080,6 +2080,10 @@ class Face():
2080
2080
  The vertical thickness of the bottom horizontal arm of the I-shape. The default is 0.25.
2081
2081
  c : float , optional
2082
2082
  The vertical thickness of the top horizontal arm of the I-shape. The default is 0.25.
2083
+ flipHorizontal : bool , optional
2084
+ if set to True, the shape is flipped horizontally. The default is False.
2085
+ flipVertical : bool , optional
2086
+ if set to True, the shape is flipped vertically. The default is False.
2083
2087
  direction : list , optional
2084
2088
  The vector representing the up direction of the I-shape. The default is [0, 0, 1].
2085
2089
  placement : str , optional
topologicpy/Graph.py CHANGED
@@ -723,6 +723,68 @@ class Graph:
723
723
  matrix[evi][svi] = valueBwd
724
724
  return matrix
725
725
 
726
+
727
+ @staticmethod
728
+ def AdjacencyMatrixCSVString(graph, vertexKey=None, reverse=False, edgeKeyFwd=None, edgeKeyBwd=None, bidirKey=None, bidirectional=True, useEdgeIndex=False, useEdgeLength=False, mantissa: int = 6, tolerance=0.0001):
729
+ """
730
+ Returns the adjacency matrix CSV string of the input Graph. See https://en.wikipedia.org/wiki/Adjacency_matrix.
731
+
732
+ Parameters
733
+ ----------
734
+ graph : topologic_core.Graph
735
+ The input graph.
736
+ vertexKey : str , optional
737
+ If set, the returned list of vertices is sorted according to the dictionary values stored under this key. The default is None.
738
+ reverse : bool , optional
739
+ If set to True, the vertices are sorted in reverse order (only if vertexKey is set). Otherwise, they are not. The default is False.
740
+ edgeKeyFwd : str , optional
741
+ If set, the value at this key in the connecting edge from start vertex to end vertex (forward) will be used instead of the value 1. The default is None. useEdgeIndex and useEdgeLength override this setting.
742
+ edgeKeyBwd : str , optional
743
+ If set, the value at this key in the connecting edge from end vertex to start vertex (backward) will be used instead of the value 1. The default is None. useEdgeIndex and useEdgeLength override this setting.
744
+ bidirKey : bool , optional
745
+ If set to True or False, this key in the connecting edge will be used to determine is the edge is supposed to be bidirectional or not. If set to None, the input variable bidrectional will be used instead. The default is None
746
+ bidirectional : bool , optional
747
+ If set to True, the edges in the graph that do not have a bidireKey in their dictionaries will be treated as being bidirectional. Otherwise, the start vertex and end vertex of the connecting edge will determine the direction. The default is True.
748
+ useEdgeIndex : bool , optional
749
+ If set to True, the adjacency matrix values will the index of the edge in Graph.Edges(graph). The default is False. Both useEdgeIndex, useEdgeLength should not be True at the same time. If they are, useEdgeLength will be used.
750
+ useEdgeLength : bool , optional
751
+ If set to True, the adjacency matrix values will the length of the edge in Graph.Edges(graph). The default is False. Both useEdgeIndex, useEdgeLength should not be True at the same time. If they are, useEdgeLength will be used.
752
+ mantissa : int , optional
753
+ The desired length of the mantissa. The default is 6.
754
+ tolerance : float , optional
755
+ The desired tolerance. The default is 0.0001.
756
+
757
+ Returns
758
+ -------
759
+ str
760
+ A string in CSV format representing the adjacency matrix.
761
+ Returns an empty string if conversion fails.
762
+ """
763
+ import io
764
+
765
+ adj_matrix = Graph.AdjacencyMatrix(graph,
766
+ vertexKey=vertexKey,
767
+ reverse=reverse,
768
+ edgeKeyFwd=edgeKeyFwd,
769
+ edgeKeyBwd=edgeKeyBwd,
770
+ bidirKey=bidirKey,
771
+ bidirectional=bidirectional,
772
+ useEdgeIndex=useEdgeIndex,
773
+ useEdgeLength=useEdgeLength,
774
+ mantissa=mantissa,
775
+ tolerance=tolerance)
776
+
777
+ try:
778
+ # Convert the adjacency matrix (nested list) to a DataFrame
779
+ adjacency_matrix_df = pd.DataFrame(adj_matrix)
780
+
781
+ # Use a buffer to get the CSV output as a string
782
+ csv_buffer = io.StringIO()
783
+ adjacency_matrix_df.to_csv(csv_buffer, index=False, header=False)
784
+ return csv_buffer.getvalue()
785
+ except Exception as e:
786
+ return ""
787
+
726
788
  @staticmethod
727
789
  def AdjacencyList(graph, vertexKey=None, reverse=True, tolerance=0.0001):
728
790
  """
@@ -9465,6 +9527,267 @@ class Graph:
9465
9527
 
9466
9528
  return True
9467
9529
 
9530
+ @staticmethod
9531
+ def JSONLDData(graph, context=None, verticesKey="nodes", edgesKey="edges", labelKey="label", sourceKey="source", targetKey="target", categoryKey="category", xKey="x", yKey="y", zKey="z", mantissa=6):
9532
+ """
9533
+ Exports the Graph to a JSON-LD representation.
9534
+
9535
+ Parameters
9536
+ ----------
9537
+ graph : topologic_core.Graph
9538
+ The TopologicPy Graph object to export.
9539
+ context : dict, optional
9540
+ A JSON-LD context mapping TopologicPy keys to IRIs (e.g., schema.org, geo, etc.).
9541
+ verticesKey : str , optional
9542
+ The desired key name to call vertices. The default is "vertices".
9543
+ edgesKey : str , optional
9544
+ The desired key name to call edges. The default is "edges".
9545
+ labelKey : str , optional
9546
+ The desired key name to use for label. The default is "label".
9547
+ sourceKey : str , optional
9548
+ The desired key name to use for source. The default is "source".
9549
+ targetKey : str , optional
9550
+ The desired key name to use for target. The default is "target".
9551
+ categoryKey : str , optional
9552
+ The desired key name to use for lcategoryabel. The default is "category".
9553
+ xKey : str , optional
9554
+ The desired key name to use for x-coordinates. The default is "x".
9555
+ yKey : str , optional
9556
+ The desired key name to use for y-coordinates. The default is "y".
9557
+ zKey : str , optional
9558
+ The desired key name to use for z-coordinates. The default is "z".
9559
+ mantissa : int , optional
9560
+ The desired length of the mantissa. The default is 6.
9561
+
9562
+ Returns
9563
+ -------
9564
+ dict
9565
+ A JSON-LD representation of the graph.
9566
+ """
9567
+ from topologicpy.Graph import Graph
9568
+ from topologicpy.Vertex import Vertex
9569
+ from topologicpy.Edge import Edge
9570
+ from topologicpy.Topology import Topology
9571
+ from topologicpy.Dictionary import Dictionary
9572
+
9573
+ if context is None:
9574
+ context = {
9575
+ labelKey: "rdfs:"+labelKey,
9576
+ categoryKey: "schema:"+categoryKey,
9577
+ xKey: "schema:"+xKey,
9578
+ yKey: "schema:"+yKey,
9579
+ zKey: "schema:"+zKey,
9580
+ "Graph": "https://topologic.app/vocab#Graph",
9581
+ "Vertex": "https://topologic.app/vocab#Vertex",
9582
+ "Edge": "https://topologic.app/vocab#Edge"
9583
+ }
9584
+
9585
+
9586
+ # Helper: Serialize a Vertex
9587
+ def serialize_vertex(vertex):
9588
+ props = Dictionary.PythonDictionary(Topology.Dictionary(vertex))
9589
+ coords = Vertex.Coordinates(vertex, mantissa=mantissa)
9590
+ props.update({
9591
+ "@type": "Vertex",
9592
+ xKey: coords[0],
9593
+ yKey: coords[1],
9594
+ zKey: coords[2],
9595
+ })
9596
+ props["@id"] = Topology.UUID(vertex)
9597
+ return props
9598
+
9599
+ # Helper: Serialize an Edge
9600
+ def serialize_edge(edge, tp_edge, edge_dict, s_vertices):
9601
+ sv = edge[0]
9602
+ ev = edge[1]
9603
+ edge_dict.update({
9604
+ "@type": "Edge",
9605
+ sourceKey: s_vertices[sv]["@id"],
9606
+ targetKey: s_vertices[ev]["@id"]
9607
+ })
9608
+ edge_dict["@id"] = Topology.UUID(tp_edge)
9609
+ return edge_dict
9610
+
9611
+ # Assemble graph
9612
+ jsonld = {
9613
+ "@context": context,
9614
+ "@id": Topology.UUID(graph),
9615
+ "@type": "Graph",
9616
+ verticesKey: [],
9617
+ edgesKey: []
9618
+ }
9619
+
9620
+ vertices = Graph.Vertices(graph)
9621
+ tp_edges = Graph.Edges(graph)
9622
+ mesh_data = Graph.MeshData(graph)
9623
+ m_edges = mesh_data['edges']
9624
+ edge_dicts = mesh_data['edgeDictionaries']
9625
+
9626
+ s_vertices = []
9627
+ for v in vertices:
9628
+ sv = serialize_vertex(v)
9629
+ s_vertices.append(sv)
9630
+ jsonld[verticesKey].append(sv)
9631
+
9632
+ for i, tp_edge in enumerate(tp_edges):
9633
+ se = serialize_edge(m_edges[i], tp_edge, edge_dicts[i], s_vertices)
9634
+ jsonld[edgesKey].append(se)
9635
+
9636
+ return jsonld
9637
+
9638
+ @staticmethod
9639
+ def JSONLDString(graph, context=None, verticesKey="nodes", edgesKey="edges", labelKey="label", sourceKey="source", targetKey="target", categoryKey="category", xKey="x", yKey="y", zKey="z", indent=2, sortKeys=False, mantissa=6):
9640
+ """
9641
+ Converts the input graph into a JSON-LD string.
9642
+
9643
+ Parameters
9644
+ ----------
9645
+ graph : topologic_core.Graph
9646
+ The TopologicPy Graph object to export.
9647
+ context : dict, optional
9648
+ A JSON-LD context mapping TopologicPy keys to IRIs (e.g., schema.org, geo, etc.)
9649
+ context : dict, optional
9650
+ A JSON-LD context mapping TopologicPy keys to IRIs (e.g., schema.org, geo, etc.).
9651
+ verticesKey : str , optional
9652
+ The desired key name to call vertices. The default is "vertices".
9653
+ edgesKey : str , optional
9654
+ The desired key name to call edges. The default is "edges".
9655
+ labelKey : str , optional
9656
+ The desired key name to use for label. The default is "label".
9657
+ sourceKey : str , optional
9658
+ The desired key name to use for source. The default is "source".
9659
+ targetKey : str , optional
9660
+ The desired key name to use for target. The default is "target".
9661
+ categoryKey : str , optional
9662
+ The desired key name to use for lcategoryabel. The default is "category".
9663
+ xKey : str , optional
9664
+ The desired key name to use for x-coordinates. The default is "x".
9665
+ yKey : str , optional
9666
+ The desired key name to use for y-coordinates. The default is "y".
9667
+ zKey : str , optional
9668
+ The desired key name to use for z-coordinates. The default is "z".
9669
+ indent : int , optional
9670
+ The desired indent. The default is 2.
9671
+ sortKeys : bool , optional
9672
+ If set to True, the keys will be sorted. Otherwise, they won't be. The default is False.
9673
+ mantissa : int , optional
9674
+ The desired length of the mantissa. The default is 6.
9675
+ Returns
9676
+ -------
9677
+ dict
9678
+ A JSON-LD representation of the graph.
9679
+ """
9680
+ import json
9681
+ jsonld_data = Graph.JSONLDData(graph,
9682
+ context=context,
9683
+ verticesKey=verticesKey,
9684
+ edgesKey=edgesKey,
9685
+ labelKey=labelKey,
9686
+ sourceKey=sourceKey,
9687
+ targetKey=targetKey,
9688
+ categoryKey=categoryKey,
9689
+ xKey=xKey,
9690
+ yKey=yKey,
9691
+ zKey=zKey,
9692
+ mantissa=mantissa)
9693
+ return json.dumps(jsonld_data, indent=indent, ort_keys=sortKeys)
9694
+
9695
+ @staticmethod
9696
+ def ExportToJSONLD(graph,
9697
+ path,
9698
+ context=None,
9699
+ verticesKey="nodes",
9700
+ edgesKey="edges",
9701
+ labelKey="label",
9702
+ sourceKey="source",
9703
+ targetKey="target",
9704
+ categoryKey="category",
9705
+ xKey="x",
9706
+ yKey="y",
9707
+ zKey="z",
9708
+ indent=2,
9709
+ sortKeys=False,
9710
+ mantissa=6,
9711
+ overwrite=False):
9712
+ """
9713
+ Exports the input graph to a JSON file.
9714
+
9715
+ Parameters
9716
+ ----------
9717
+ graph : topologic_core.Graph
9718
+ The input graph.
9719
+ path : str
9720
+ The path to the JSON file.
9721
+ verticesKey : str , optional
9722
+ The desired key name to call vertices. The default is "vertices".
9723
+ edgesKey : str , optional
9724
+ The desired key name to call edges. The default is "edges".
9725
+ vertexLabelKey : str , optional
9726
+ If set to a valid string, the vertex label will be set to the value at this key. Otherwise it will be set to Vertex_XXXX where XXXX is a sequential unique number.
9727
+ Note: If vertex labels are not unique, they will be forced to be unique.
9728
+ edgeLabelKey : str , optional
9729
+ If set to a valid string, the edge label will be set to the value at this key. Otherwise it will be set to Edge_XXXX where XXXX is a sequential unique number.
9730
+ Note: If edge labels are not unique, they will be forced to be unique.
9731
+ xKey : str , optional
9732
+ The desired key name to use for x-coordinates. The default is "x".
9733
+ yKey : str , optional
9734
+ The desired key name to use for y-coordinates. The default is "y".
9735
+ zKey : str , optional
9736
+ The desired key name to use for z-coordinates. The default is "z".
9737
+ indent : int , optional
9738
+ The desired amount of indent spaces to use. The default is 4.
9739
+ sortKeys : bool , optional
9740
+ If set to True, the keys will be sorted. Otherwise, they won't be. The default is False.
9741
+ mantissa : int , optional
9742
+ The desired length of the mantissa. The default is 6.
9743
+ overwrite : bool , optional
9744
+ If set to True the ouptut file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
9745
+
9746
+ Returns
9747
+ -------
9748
+ bool
9749
+ The status of exporting the JSON file. If True, the operation was successful. Otherwise, it was unsuccesful.
9750
+
9751
+ """
9752
+ import json
9753
+ from os.path import exists
9754
+ # Make sure the file extension is .json
9755
+ ext = path[len(path)-5:len(path)]
9756
+ if ext.lower() != ".json":
9757
+ path = path+".json"
9758
+ if not overwrite and exists(path):
9759
+ print("Graph.ExportToJSONLD - Error: a file already exists at the specified path and overwrite is set to False. Returning None.")
9760
+ return None
9761
+ f = None
9762
+ try:
9763
+ if overwrite == True:
9764
+ f = open(path, "w")
9765
+ else:
9766
+ f = open(path, "x") # Try to create a new File
9767
+ except:
9768
+ raise Exception("Graph.ExportToJSONLD - Error: Could not create a new file at the following location: "+path)
9769
+ if (f):
9770
+ jsonld_data = Graph.JSONLDData(graph,
9771
+ context=context,
9772
+ verticesKey=verticesKey,
9773
+ edgesKey=edgesKey,
9774
+ labelKey=labelKey,
9775
+ sourceKey=sourceKey,
9776
+ targetKey=targetKey,
9777
+ categoryKey=categoryKey,
9778
+ xKey=xKey,
9779
+ yKey=yKey,
9780
+ zKey=zKey,
9781
+ mantissa=mantissa)
9782
+ if jsonld_data != None:
9783
+ json.dump(jsonld_data, f, indent=indent, sort_keys=sortKeys)
9784
+ f.close()
9785
+ return True
9786
+ else:
9787
+ f.close()
9788
+ return False
9789
+ return False
9790
+
9468
9791
  @staticmethod
9469
9792
  def JSONData(graph,
9470
9793
  verticesKey: str = "vertices",
@@ -9597,7 +9920,7 @@ class Graph:
9597
9920
  sortKeys=False,
9598
9921
  mantissa=6):
9599
9922
  """
9600
- Converts the input graph into JSON data.
9923
+ Converts the input graph into a JSON string.
9601
9924
 
9602
9925
  Parameters
9603
9926
  ----------
@@ -9991,58 +10314,269 @@ class Graph:
9991
10314
  longest_path = Topology.SetDictionary(longest_path, d)
9992
10315
  return longest_path
9993
10316
 
9994
- @staticmethod
9995
- def Match(graphA, graphB, vertexKey: str = None, silent: bool = False):
10317
+ def Match(graphA, graphB, vertexKeys: list = None, edgeKeys: list = None, maxMatches: int = 10, timeLimit: int = 10, tolerance: float = 0.0, silent: bool = False):
9996
10318
  """
9997
- Matches two input graphs using isomorphism coupled with semantic matching.
10319
+ Matches graphA as a subgraph of graphB using structural and semantic similarity.
9998
10320
 
9999
10321
  Parameters
10000
10322
  ----------
10001
10323
  graphA : topologic_core.Graph
10002
- The first input graph. This should be the smaller sub-graph or a graph isomorphice with the second input graph.
10324
+ The smaller graph (subgraph).
10003
10325
  graphB : topologic_core.Graph
10004
- The second input graph.
10005
- vertexKey : str , optional
10006
- If set, the dictionaries of the vertices will be searched for this key and their values matched.
10007
- silent : bool , optional
10008
- If set to True, error and warning messages are suppressed. The default is False.
10326
+ The larger graph (supergraph).
10327
+ vertexKeys : str or list of str, optional
10328
+ Keys used to semantically compare vertices.
10329
+ edgeKeys : str or list of str, optional
10330
+ Keys used to semantically compare edges.
10331
+ maxMatches : int , optional
10332
+ The maximum number of matches to find. The default is 10.
10333
+ timeLimit : int , optional
10334
+ The time limit in seconds. The default is 10 seconds. Note that this time limit only applies to finding the matches.
10335
+ tolerance : float, optional
10336
+ Allowed numeric deviation or minimum string similarity (e.g. 0.2 = ≥80% match). Default is 0.
10337
+ silent : bool, optional
10338
+ If True, suppresses warnings and errors.
10009
10339
 
10010
10340
  Returns
10011
10341
  -------
10012
- list
10013
- A list of dictionaries that match the vertices of graphA to the vertices of graphB.
10342
+ list of dict
10343
+ List of mappings from node index in graphA to graphB, sorted by descending similarity.
10014
10344
  """
10015
-
10016
10345
  import networkx as nx
10017
10346
  from topologicpy.Topology import Topology
10347
+ from topologicpy.Graph import Graph
10348
+ from topologicpy.Helper import Helper
10349
+ from difflib import SequenceMatcher
10350
+ import time
10018
10351
 
10019
- if not Topology.IsInstance(graphA, "graph"):
10020
- if not silent:
10021
- print("Graph.Map - Error: The graphA input parameter is not a valid graph. Returning None.")
10022
- return None
10023
-
10024
- if not Topology.IsInstance(graphB, "graph"):
10352
+ def string_similarity(s1, s2):
10353
+ return SequenceMatcher(None, s1.lower(), s2.lower()).ratio()
10354
+
10355
+ if not Topology.IsInstance(graphA, "Graph") or not Topology.IsInstance(graphB, "Graph"):
10025
10356
  if not silent:
10026
- print("Graph.Map - Error: The graphB input parameter is not a valid graph. Returning None.")
10357
+ print("Graph.Match - Error: One or both inputs are not valid Graphs.")
10027
10358
  return None
10028
10359
 
10360
+ # Normalize keys
10361
+ if isinstance(vertexKeys, str):
10362
+ vertexKeys = [vertexKeys]
10363
+ if isinstance(edgeKeys, str):
10364
+ edgeKeys = [edgeKeys]
10365
+
10029
10366
  nx_ga = Graph.NetworkXGraph(graphA)
10030
10367
  nx_gb = Graph.NetworkXGraph(graphB)
10031
10368
 
10369
+ def similarity_score(val1, val2):
10370
+ try:
10371
+ v1 = float(val1)
10372
+ v2 = float(val2)
10373
+ if v1 == 0:
10374
+ return 1.0 if abs(v2) <= tolerance else 0.0
10375
+ diff = abs(v1 - v2) / abs(v1)
10376
+ return max(0.0, 1.0 - diff)
10377
+ except (ValueError, TypeError):
10378
+ return string_similarity(str(val1), str(val2))
10379
+
10380
+ def compute_mapping_score(mapping):
10381
+ total_score = 0
10382
+ count = 0
10383
+
10384
+ # Score vertices
10385
+ for i_b, i_a in mapping.items():
10386
+ a_attrs = nx_ga.nodes[i_a]
10387
+ b_attrs = nx_gb.nodes[i_b]
10388
+ if vertexKeys:
10389
+ for key in vertexKeys:
10390
+ if key in a_attrs and key in b_attrs:
10391
+ score = similarity_score(a_attrs[key], b_attrs[key])
10392
+ total_score += score
10393
+ count += 1
10394
+
10395
+ # Score edges
10396
+ for (i_a1, i_a2) in nx_ga.edges:
10397
+ if i_a1 in mapping and i_a2 in mapping:
10398
+ j_b1 = mapping[i_a1]
10399
+ j_b2 = mapping[i_a2]
10400
+ if nx_gb.has_edge(j_b1, j_b2):
10401
+ a_attrs = nx_ga.get_edge_data(i_a1, i_a2)
10402
+ b_attrs = nx_gb.get_edge_data(j_b1, j_b2)
10403
+ if edgeKeys:
10404
+ for key in edgeKeys:
10405
+ if key in a_attrs and key in b_attrs:
10406
+ score = similarity_score(a_attrs[key], b_attrs[key])
10407
+ total_score += score
10408
+ count += 1
10409
+
10410
+ return total_score / count if count > 0 else 1.0
10411
+
10032
10412
  def node_match(n1, n2):
10033
- if vertexKey:
10034
- return str(n1.get(vertexKey)) == str(n2.get(vertexKey))
10035
- return True # topology-only match
10413
+ if vertexKeys:
10414
+ for key in vertexKeys:
10415
+ if key not in n1 or key not in n2:
10416
+ return False
10417
+ sim = similarity_score(n1[key], n2[key])
10418
+ if sim < (1.0 - tolerance):
10419
+ return False
10420
+ return True
10421
+
10422
+ def edge_match(e1, e2):
10423
+ if edgeKeys:
10424
+ for key in edgeKeys:
10425
+ if key not in e1 or key not in e2:
10426
+ return False
10427
+ sim = similarity_score(e1[key], e2[key])
10428
+ if sim < (1.0 - tolerance):
10429
+ return False
10430
+ return True
10036
10431
 
10037
10432
  matcher = nx.algorithms.isomorphism.GraphMatcher(
10038
- nx_gb, nx_ga, node_match=node_match if vertexKey else None
10433
+ nx_gb, nx_ga,
10434
+ node_match=node_match if vertexKeys else None,
10435
+ edge_match=edge_match if edgeKeys else None
10039
10436
  )
10040
10437
 
10041
- matches = list(matcher.subgraph_isomorphisms_iter())
10042
- if not matches and not silent:
10438
+ start = time.time()
10439
+ raw_matches = []
10440
+ for i, m in enumerate(matcher.subgraph_isomorphisms_iter()):
10441
+ raw_matches.append(m)
10442
+ elapsed_time = time.time() - start
10443
+ if i + 1 >= maxMatches or elapsed_time >= timeLimit:
10444
+ break
10445
+
10446
+ if not raw_matches and not silent:
10043
10447
  print("Graph.Match - Warning: No subgraph isomorphisms found.")
10044
- return matches
10448
+ return []
10045
10449
 
10450
+ scores = [compute_mapping_score(m) for m in raw_matches]
10451
+ sorted_matches = Helper.Sort(raw_matches, scores, reverseFlags=[True])
10452
+ return sorted_matches
10453
+
10454
+ # @staticmethod
10455
+ # def Match(graphA, graphB, vertexKeys=None, edgeKeys=None, tolerance: float = 0.0, silent: bool = False):
10456
+ # """
10457
+ # Matches graphA as a subgraph of graphB using structural and semantic similarity.
10458
+
10459
+ # Parameters
10460
+ # ----------
10461
+ # graphA : topologic_core.Graph
10462
+ # The smaller graph (subgraph).
10463
+ # graphB : topologic_core.Graph
10464
+ # The larger graph (supergraph).
10465
+ # vertexKeys : str or list of str, optional
10466
+ # Keys used to semantically compare vertices.
10467
+ # edgeKeys : str or list of str, optional
10468
+ # Keys used to semantically compare edges.
10469
+ # tolerance : float, optional
10470
+ # Allowed numeric deviation or minimum string similarity (e.g. 0.2 = ≥80% match). Default is 0.
10471
+ # silent : bool, optional
10472
+ # If True, suppresses warnings and errors.
10473
+
10474
+ # Returns
10475
+ # -------
10476
+ # list of dict
10477
+ # List of mappings from node index in graphA to graphB, sorted by descending similarity.
10478
+ # """
10479
+ # import networkx as nx
10480
+ # from topologicpy.Topology import Topology
10481
+ # from topologicpy.Graph import Graph
10482
+ # from topologicpy.Helper import Helper
10483
+ # from difflib import SequenceMatcher
10484
+
10485
+ # def string_similarity(s1, s2):
10486
+ # return SequenceMatcher(None, s1.lower(), s2.lower()).ratio()
10487
+
10488
+ # if not Topology.IsInstance(graphA, "Graph") or not Topology.IsInstance(graphB, "Graph"):
10489
+ # if not silent:
10490
+ # print("Graph.Match - Error: One or both inputs are not valid Graphs.")
10491
+ # return None
10492
+
10493
+ # # Normalize keys
10494
+ # if isinstance(vertexKeys, str):
10495
+ # vertexKeys = [vertexKeys]
10496
+ # if isinstance(edgeKeys, str):
10497
+ # edgeKeys = [edgeKeys]
10498
+
10499
+ # nx_ga = Graph.NetworkXGraph(graphA)
10500
+ # nx_gb = Graph.NetworkXGraph(graphB)
10501
+
10502
+ # def similarity_score(val1, val2):
10503
+ # try:
10504
+ # v1 = float(val1)
10505
+ # v2 = float(val2)
10506
+ # if v1 == 0:
10507
+ # return 1.0 if abs(v2) <= tolerance else 0.0
10508
+ # diff = abs(v1 - v2) / abs(v1)
10509
+ # return max(0.0, 1.0 - diff)
10510
+ # except (ValueError, TypeError):
10511
+ # return string_similarity(str(val1), str(val2))
10512
+
10513
+ # def compute_mapping_score(mapping):
10514
+ # total_score = 0
10515
+ # count = 0
10516
+
10517
+ # # Score vertices
10518
+ # for i_a, i_b in mapping.items():
10519
+ # a_attrs = nx_ga.nodes[i_a]
10520
+ # b_attrs = nx_gb.nodes[i_b]
10521
+ # if vertexKeys:
10522
+ # for key in vertexKeys:
10523
+ # if key in a_attrs and key in b_attrs:
10524
+ # score = similarity_score(a_attrs[key], b_attrs[key])
10525
+ # total_score += score
10526
+ # count += 1
10527
+
10528
+ # # Score edges
10529
+ # for (i_a1, i_a2) in nx_ga.edges:
10530
+ # if i_a1 in mapping and i_a2 in mapping:
10531
+ # j_b1 = mapping[i_a1]
10532
+ # j_b2 = mapping[i_a2]
10533
+ # if nx_gb.has_edge(j_b1, j_b2):
10534
+ # a_attrs = nx_ga.get_edge_data(i_a1, i_a2)
10535
+ # b_attrs = nx_gb.get_edge_data(j_b1, j_b2)
10536
+ # if edgeKeys:
10537
+ # for key in edgeKeys:
10538
+ # if key in a_attrs and key in b_attrs:
10539
+ # score = similarity_score(a_attrs[key], b_attrs[key])
10540
+ # total_score += score
10541
+ # count += 1
10542
+
10543
+ # return total_score / count if count > 0 else 1.0
10544
+
10545
+ # def node_match(n1, n2):
10546
+ # if vertexKeys:
10547
+ # for key in vertexKeys:
10548
+ # if key not in n1 or key not in n2:
10549
+ # return False
10550
+ # sim = similarity_score(n1[key], n2[key])
10551
+ # if sim < (1.0 - tolerance):
10552
+ # return False
10553
+ # return True
10554
+
10555
+ # def edge_match(e1, e2):
10556
+ # if edgeKeys:
10557
+ # for key in edgeKeys:
10558
+ # if key not in e1 or key not in e2:
10559
+ # return False
10560
+ # sim = similarity_score(e1[key], e2[key])
10561
+ # if sim < (1.0 - tolerance):
10562
+ # return False
10563
+ # return True
10564
+
10565
+ # matcher = nx.algorithms.isomorphism.GraphMatcher(
10566
+ # nx_gb, nx_ga,
10567
+ # node_match=node_match if vertexKeys else None,
10568
+ # edge_match=edge_match if edgeKeys else None
10569
+ # )
10570
+
10571
+ # raw_matches = list(matcher.subgraph_isomorphisms_iter())
10572
+ # if not raw_matches and not silent:
10573
+ # print("Graph.Match - Warning: No subgraph isomorphisms found.")
10574
+ # return []
10575
+
10576
+ # scores = [compute_mapping_score(m) for m in raw_matches]
10577
+ # sorted_matches = Helper.Sort(raw_matches, scores, reverse=True)
10578
+
10579
+ # return sorted_matches
10046
10580
 
10047
10581
  @staticmethod
10048
10582
  def MaximumDelta(graph):
topologicpy/Plotly.py CHANGED
@@ -551,10 +551,10 @@ 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] = Dictionary.ValueAtKey(d, key=sizeKey)
554
+ sizes[m] = float(Dictionary.ValueAtKey(d, key=sizeKey))
555
555
  if sizes[m] == None:
556
556
  sizes[m] = size
557
- if sizes[m] <= 0:
557
+ if float(sizes[m]) <= 0:
558
558
  sizes[m] = 1.1
559
559
  if not borderColorKey == None:
560
560
  temp_color = Dictionary.ValueAtKey(d, key=borderColorKey)
topologicpy/Topology.py CHANGED
@@ -10147,28 +10147,37 @@ class Topology():
10147
10147
  """
10148
10148
  import uuid
10149
10149
  from topologicpy.Dictionary import Dictionary
10150
+ from topologicpy.Graph import Graph
10150
10151
 
10151
10152
  predefined_namespace_dns = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
10152
10153
  namespace_uuid = uuid.uuid5(predefined_namespace_dns, namespace)
10153
- cellComplexes = Topology.CellComplexes(topology)
10154
- cells = Topology.Cells(topology)
10155
- shells = Topology.Shells(topology)
10156
- faces = Topology.Faces(topology)
10157
- wires = Topology.Wires(topology)
10158
- edges = Topology.Edges(topology)
10159
- vertices = Topology.Vertices(topology)
10160
- apertures = Topology.Apertures(topology, subTopologyType="all")
10161
- subTopologies = cellComplexes+cells+shells+faces+wires+edges+vertices+apertures
10162
- dictionaries = [Dictionary.PythonDictionary(Topology.Dictionary(topology))]
10163
- dictionaries += [Dictionary.PythonDictionary(Topology.Dictionary(s)) for s in subTopologies]
10164
- dict_str = str(dictionaries)
10165
- top_geom = Topology.Geometry(topology, mantissa=6)
10166
- verts_str = str(top_geom['vertices'])
10167
- edges_str = str(top_geom['edges'])
10168
- faces_str = str(top_geom['faces'])
10169
- geo_str = verts_str+edges_str+faces_str
10170
- final_str = geo_str+dict_str
10171
- uuid_str = uuid.uuid5(namespace_uuid, final_str)
10154
+ if Topology.IsInstance(topology, "graph"):
10155
+ mesh_data = Graph.MeshData(topology)
10156
+ verts_str = str(mesh_data["vertices"])
10157
+ edges_str = str(mesh_data["edges"])
10158
+ dict_str = str(mesh_data['vertexDictionaries']+mesh_data["edgeDictionaries"])
10159
+ final_str = verts_str+edges_str+dict_str
10160
+ uuid_str = uuid.uuid5(namespace_uuid, final_str)
10161
+ else:
10162
+ cellComplexes = Topology.CellComplexes(topology)
10163
+ cells = Topology.Cells(topology)
10164
+ shells = Topology.Shells(topology)
10165
+ faces = Topology.Faces(topology)
10166
+ wires = Topology.Wires(topology)
10167
+ edges = Topology.Edges(topology)
10168
+ vertices = Topology.Vertices(topology)
10169
+ apertures = Topology.Apertures(topology, subTopologyType="all")
10170
+ subTopologies = cellComplexes+cells+shells+faces+wires+edges+vertices+apertures
10171
+ dictionaries = [Dictionary.PythonDictionary(Topology.Dictionary(topology))]
10172
+ dictionaries += [Dictionary.PythonDictionary(Topology.Dictionary(s)) for s in subTopologies]
10173
+ dict_str = str(dictionaries)
10174
+ top_geom = Topology.Geometry(topology, mantissa=6)
10175
+ verts_str = str(top_geom['vertices'])
10176
+ edges_str = str(top_geom['edges'])
10177
+ faces_str = str(top_geom['faces'])
10178
+ geo_str = verts_str+edges_str+faces_str
10179
+ final_str = geo_str+dict_str
10180
+ uuid_str = uuid.uuid5(namespace_uuid, final_str)
10172
10181
  return str(uuid_str)
10173
10182
 
10174
10183
  @staticmethod
topologicpy/Wire.py CHANGED
@@ -2793,6 +2793,10 @@ class Wire():
2793
2793
  The vertical thickness of the lower horizontal arm of the I-shape. The default is 0.25.
2794
2794
  c : float , optional
2795
2795
  The vertical thickness of the upper horizontal arm of the I-shape. The default is 0.25.
2796
+ flipHorizontal : bool , optional
2797
+ if set to True, the shape is flipped horizontally. The default is False.
2798
+ flipVertical : bool , optional
2799
+ if set to True, the shape is flipped vertically. The default is False.
2796
2800
  direction : list , optional
2797
2801
  The vector representing the up direction of the I-shape. The default is [0, 0, 1].
2798
2802
  placement : str , optional
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.36'
1
+ __version__ = '0.8.37'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topologicpy
3
- Version: 0.8.36
3
+ Version: 0.8.37
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
@@ -2,7 +2,7 @@ topologicpy/ANN.py,sha256=DrNAhNHp-jSvsPc1fb7KVPU46cYmejAvghhknOM430Y,47932
2
2
  topologicpy/Aperture.py,sha256=wNn5miB_IrGCBYuQ18HXQYRva20dUC3id4AJCulL7to,2723
3
3
  topologicpy/BVH.py,sha256=Iwp_8VDG8ETE4330k7ifWxdI4jmWmv9h8e8IIIZZFGY,13043
4
4
  topologicpy/CSG.py,sha256=uDkOSmc8m1V_k7T3UCerODhOSyYNO4FRDzoOqt0kEt8,15590
5
- topologicpy/Cell.py,sha256=7goddVyduyeZFbBBMAUG4_JGa-bjvjgpVm42fOvF9sk,173110
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
8
  topologicpy/Color.py,sha256=ZVVQRKGjebY9aOU1gpN_AbssdRRiVKlZV3f8TrsTNgg,20307
@@ -11,28 +11,28 @@ topologicpy/DGL.py,sha256=HQXy9iDnrvWGDxaBfe5pRbweQ2zLBvAf6UdjfhKkQYI,139041
11
11
  topologicpy/Dictionary.py,sha256=PageNwgFmLakb0cKizsCEGkL_u_JV0CVqYGRM60XdsI,40837
12
12
  topologicpy/Edge.py,sha256=CPdQKaE7ft6zgh0vxekkfGRRUY_yEqkEJ14NvjSgJOA,73190
13
13
  topologicpy/EnergyModel.py,sha256=Pyb28gDDwhzlQIH0xqAygqS0P3SJxWyyV7OWS_AAfRs,53856
14
- topologicpy/Face.py,sha256=L7D1rO3ntZ1vCWFMN0Pd-G6dEq_Fe6Eg3_Ms5X5yJN8,201370
15
- topologicpy/Graph.py,sha256=kk0c7Vl40jjQ72qn56cc6SbGHduIqBwLOdEIOPsdjK4,581757
14
+ topologicpy/Face.py,sha256=BT_5ymb7-s-Wb1tuaBtkopJpeNg-RbooTUk_-KInQ6c,201618
15
+ topologicpy/Graph.py,sha256=jUuaoEPQaF-4wEEcVhOHJnep9EmVlpzjCGdgmSXyRNc,605657
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=uqAfiSKpi1eCgoanA1ddgR9C31aeQgv0m0IQMDByfkY,120519
21
+ topologicpy/Plotly.py,sha256=B6CxNyAGfhv70N6sa4B4aHLYd7zIpH5S1hmpk3sQ3ys,120533
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
25
25
  topologicpy/Shell.py,sha256=fx0WTndC8blkvWe38nKsJsI_AmklOA0qsjU0gbZp4b4,90501
26
26
  topologicpy/Speckle.py,sha256=-eiTqJugd7pHiHpD3pDUcDO6CGhVyPV14HFRzaqEoaw,18187
27
27
  topologicpy/Sun.py,sha256=_VBBAUIDhvpkp72JBZlv7k9qx9jYubm3yM56UZ1Nc6c,36837
28
- topologicpy/Topology.py,sha256=27KbYx9-W8j5Ef44eMLnTMh0avkTI8WcT5TD0isDu9A,466111
28
+ topologicpy/Topology.py,sha256=G6KtKRKabV1gNUKCZ3rzZJkCogGkOJDnCl-_S7DuHKc,466648
29
29
  topologicpy/Vector.py,sha256=X12eqskn28bdB7sLY1EZhq3noPYzPbNEgHPb4a959ss,42302
30
30
  topologicpy/Vertex.py,sha256=epBfbD7fm87T-TZ0WuwrioXdYqg9NgRlHn_qUFtVbkc,84562
31
- topologicpy/Wire.py,sha256=nNsBhzHdg2TXj24OTtuOkQ6AGNcITE5h_I3j02Ckoyg,231299
31
+ topologicpy/Wire.py,sha256=vE6IoObVucOZVTFMPiHuNN4DDezRHHyFbwhF5WRBm3s,231547
32
32
  topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
33
- topologicpy/version.py,sha256=ImLBq3Km5E4vhZfPIT4-5gepfQy6e8kz6LS9ac50W7U,23
34
- topologicpy-0.8.36.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
- topologicpy-0.8.36.dist-info/METADATA,sha256=4BPPT871pkw8SfY3nUotK3Bukgd5-yrXz21uKPxHr0c,10535
36
- topologicpy-0.8.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- topologicpy-0.8.36.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
- topologicpy-0.8.36.dist-info/RECORD,,
33
+ topologicpy/version.py,sha256=VE1FGBgDJhbrCqc_YF_8MXIrldKfurVX4fi2rgDHG5I,23
34
+ topologicpy-0.8.37.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
+ topologicpy-0.8.37.dist-info/METADATA,sha256=3U3CqjhrPP3kyS3CiWqO5bAqGJkYJZ7GlYb2K33MC1w,10535
36
+ topologicpy-0.8.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ topologicpy-0.8.37.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
+ topologicpy-0.8.37.dist-info/RECORD,,