topologicpy 0.8.36__py3-none-any.whl → 0.8.38__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 +96 -35
- topologicpy/Face.py +4 -0
- topologicpy/Graph.py +561 -27
- topologicpy/Plotly.py +2 -2
- topologicpy/Topology.py +28 -19
- topologicpy/Wire.py +4 -0
- topologicpy/version.py +1 -1
- {topologicpy-0.8.36.dist-info → topologicpy-0.8.38.dist-info}/METADATA +1 -1
- {topologicpy-0.8.36.dist-info → topologicpy-0.8.38.dist-info}/RECORD +12 -12
- {topologicpy-0.8.36.dist-info → topologicpy-0.8.38.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.36.dist-info → topologicpy-0.8.38.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.36.dist-info → topologicpy-0.8.38.dist-info}/top_level.txt +0 -0
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.
|
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
|
-
|
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
|
-
|
1252
|
-
|
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
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
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.
|
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
|
-
|
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=
|
2086
|
-
placement=
|
2110
|
+
direction=[0,0,1],
|
2111
|
+
placement="center",
|
2087
2112
|
tolerance=tolerance,
|
2088
2113
|
silent=silent)
|
2089
|
-
|
2090
|
-
|
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.
|
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
|
-
|
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
|
-
|
2278
|
-
|
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.
|
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
|
-
|
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=
|
3435
|
-
placement=
|
3488
|
+
direction=[0,0,1],
|
3489
|
+
placement="center",
|
3436
3490
|
tolerance=tolerance,
|
3437
3491
|
silent=silent)
|
3438
|
-
|
3439
|
-
|
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, sort_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
|
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
|
-
|
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
|
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
|
10324
|
+
The smaller graph (subgraph).
|
10003
10325
|
graphB : topologic_core.Graph
|
10004
|
-
The
|
10005
|
-
|
10006
|
-
|
10007
|
-
|
10008
|
-
|
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
|
-
|
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
|
-
|
10020
|
-
|
10021
|
-
|
10022
|
-
|
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.
|
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
|
10034
|
-
|
10035
|
-
|
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,
|
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
|
-
|
10042
|
-
|
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
|
-
|
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
|
-
|
10154
|
-
|
10155
|
-
|
10156
|
-
|
10157
|
-
|
10158
|
-
|
10159
|
-
|
10160
|
-
|
10161
|
-
|
10162
|
-
|
10163
|
-
|
10164
|
-
|
10165
|
-
|
10166
|
-
|
10167
|
-
|
10168
|
-
|
10169
|
-
|
10170
|
-
|
10171
|
-
|
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.
|
1
|
+
__version__ = '0.8.38'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.38
|
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=
|
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=
|
15
|
-
topologicpy/Graph.py,sha256=
|
14
|
+
topologicpy/Face.py,sha256=BT_5ymb7-s-Wb1tuaBtkopJpeNg-RbooTUk_-KInQ6c,201618
|
15
|
+
topologicpy/Graph.py,sha256=e9_KSCvRI8jilx7afqicPDJqsCPHA5ucz5To8mfbFKo,605658
|
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=
|
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=
|
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=
|
31
|
+
topologicpy/Wire.py,sha256=vE6IoObVucOZVTFMPiHuNN4DDezRHHyFbwhF5WRBm3s,231547
|
32
32
|
topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
|
33
|
-
topologicpy/version.py,sha256=
|
34
|
-
topologicpy-0.8.
|
35
|
-
topologicpy-0.8.
|
36
|
-
topologicpy-0.8.
|
37
|
-
topologicpy-0.8.
|
38
|
-
topologicpy-0.8.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|