topologicpy 0.8.31__py3-none-any.whl → 0.8.35__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 +1098 -10
- topologicpy/CellComplex.py +28 -1
- topologicpy/Dictionary.py +119 -0
- topologicpy/Edge.py +16 -0
- topologicpy/Face.py +319 -54
- topologicpy/Graph.py +2 -7
- topologicpy/Helper.py +52 -0
- topologicpy/Shell.py +119 -92
- topologicpy/Topology.py +189 -11
- topologicpy/Vertex.py +1 -1
- topologicpy/Wire.py +66 -31
- topologicpy/version.py +1 -1
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/METADATA +1 -1
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/RECORD +17 -17
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/licenses/LICENSE +0 -0
- {topologicpy-0.8.31.dist-info → topologicpy-0.8.35.dist-info}/top_level.txt +0 -0
topologicpy/Face.py
CHANGED
@@ -1004,58 +1004,75 @@ class Face():
|
|
1004
1004
|
else:
|
1005
1005
|
internalBoundaries = Cluster.Wires(internalBoundariesCluster)
|
1006
1006
|
return Face.ByWires(externalBoundary, internalBoundaries, tolerance=tolerance, silent=silent)
|
1007
|
-
|
1007
|
+
|
1008
1008
|
@staticmethod
|
1009
|
-
def
|
1010
|
-
placement: str = "center", tolerance: float = 0.0001):
|
1009
|
+
def CHS(origin= None, radius: float = 0.5, thickness: float = 0.25, sides: int = 16, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001, silent: bool = False):
|
1011
1010
|
"""
|
1012
|
-
Creates a
|
1011
|
+
Creates a circular hollow section (CHS).
|
1013
1012
|
|
1014
1013
|
Parameters
|
1015
1014
|
----------
|
1016
1015
|
origin : topologic_core.Vertex, optional
|
1017
|
-
The location of the origin of the
|
1016
|
+
The location of the origin of the CHS. The default is None which results in the CHS being placed at (0, 0, 0).
|
1018
1017
|
radius : float , optional
|
1019
|
-
The radius of the
|
1020
|
-
|
1021
|
-
The
|
1018
|
+
The outer radius of the CHS. The default is 0.5.
|
1019
|
+
thickness : float , optional
|
1020
|
+
The thickness of the CHS. The default is 0.25.
|
1022
1021
|
direction : list , optional
|
1023
|
-
The vector representing the up direction of the
|
1024
|
-
northAngle : float , optional
|
1025
|
-
The angular offset in degrees from the positive Y axis direction. The angle is measured in a counter-clockwise fashion where 0 is positive Y, 90 is negative X, 180 is negative Y, and 270 is positive X.
|
1022
|
+
The vector representing the up direction of the CHS. The default is [0, 0, 1].
|
1026
1023
|
placement : str , optional
|
1027
|
-
The description of the placement of the origin of the
|
1024
|
+
The description of the placement of the origin of the CHS. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
|
1028
1025
|
tolerance : float , optional
|
1029
1026
|
The desired tolerance. The default is 0.0001.
|
1027
|
+
silent : bool , optional
|
1028
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1030
1029
|
|
1031
1030
|
Returns
|
1032
1031
|
-------
|
1033
1032
|
topologic_core.Face
|
1034
|
-
The created
|
1033
|
+
The created face.
|
1035
1034
|
|
1036
1035
|
"""
|
1037
|
-
from topologicpy.Topology import Topology
|
1038
1036
|
from topologicpy.Vertex import Vertex
|
1039
|
-
|
1037
|
+
from topologicpy.Wire import Wire
|
1038
|
+
from topologicpy.Topology import Topology
|
1039
|
+
|
1040
|
+
if thickness >= radius:
|
1041
|
+
if not silent:
|
1042
|
+
print("Face.SHS - Error: The thickness value is larger than or equal to the outer radius value. Returning None.")
|
1043
|
+
return None
|
1044
|
+
if origin == None:
|
1040
1045
|
origin = Vertex.Origin()
|
1041
1046
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
+
outer_wire = Wire.Circle(origin=Vertex.Origin(), radius=radius, sides=sides, direction=[0,0,1], placement="center", tolerance=tolerance)
|
1048
|
+
inner_wire = Wire.Circle(origin=Vertex.Origin(), radius=radius-thickness, sides=sides, direction=[0,0,1], placement="center", tolerance=tolerance)
|
1049
|
+
return_face = Face.ByWires(outer_wire, [inner_wire])
|
1050
|
+
if not Topology.IsInstance(return_face, "face"):
|
1051
|
+
if not silent:
|
1052
|
+
print("Face.CHS - Error: Could not create the face for the CHS. Returning None.")
|
1053
|
+
return None
|
1054
|
+
|
1055
|
+
xOffset = 0
|
1056
|
+
yOffset = 0
|
1057
|
+
zOffset = 0
|
1047
1058
|
if placement.lower() == "lowerleft":
|
1048
|
-
|
1059
|
+
xOffset = radius
|
1060
|
+
yOffset = radius
|
1049
1061
|
elif placement.lower() == "upperleft":
|
1050
|
-
|
1062
|
+
xOffset = radius
|
1063
|
+
yOffset = -radius
|
1051
1064
|
elif placement.lower() == "lowerright":
|
1052
|
-
|
1065
|
+
xOffset = -radius
|
1066
|
+
yOffset = radius
|
1053
1067
|
elif placement.lower() == "upperright":
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1068
|
+
xOffset = -radius
|
1069
|
+
yOffset = -radius
|
1070
|
+
return_face = Topology.Translate(return_face, x=xOffset, y=yOffset, z=zOffset)
|
1071
|
+
return_face = Topology.Place(return_face, originA=Vertex.Origin(), originB=origin)
|
1072
|
+
if direction != [0, 0, 1]:
|
1073
|
+
return_face = Topology.Orient(return_face, origin=origin, dirA=[0, 0, 1], dirB=direction)
|
1074
|
+
return return_face
|
1075
|
+
|
1059
1076
|
@staticmethod
|
1060
1077
|
def Circle(origin= None, radius: float = 0.5, sides: int = 16, fromAngle: float = 0.0, toAngle: float = 360.0, direction: list = [0, 0, 1],
|
1061
1078
|
placement: str = "center", tolerance: float = 0.0001):
|
@@ -1218,19 +1235,19 @@ class Face():
|
|
1218
1235
|
|
1219
1236
|
if not isinstance(width, int) and not isinstance(width, float):
|
1220
1237
|
if not silent:
|
1221
|
-
print("
|
1238
|
+
print("Face.CrossShape - Error: The width input parameter is not a valid number. Returning None.")
|
1222
1239
|
return None
|
1223
1240
|
if not isinstance(length, int) and not isinstance(length, float):
|
1224
1241
|
if not silent:
|
1225
|
-
print("
|
1242
|
+
print("Face.CrossShape - Error: The length input parameter is not a valid number. Returning None.")
|
1226
1243
|
return None
|
1227
1244
|
if not isinstance(a, int) and not isinstance(a, float):
|
1228
1245
|
if not silent:
|
1229
|
-
print("
|
1246
|
+
print("Face.CrossShape - Error: The a input parameter is not a valid number. Returning None.")
|
1230
1247
|
return None
|
1231
1248
|
if not isinstance(b, int) and not isinstance(b, float):
|
1232
1249
|
if not silent:
|
1233
|
-
print("
|
1250
|
+
print("Face.CrossShape - Error: The b input parameter is not a valid number. Returning None.")
|
1234
1251
|
return None
|
1235
1252
|
if c == None:
|
1236
1253
|
c = width/2
|
@@ -1238,72 +1255,72 @@ class Face():
|
|
1238
1255
|
d = length/2
|
1239
1256
|
if not isinstance(c, int) and not isinstance(c, float):
|
1240
1257
|
if not silent:
|
1241
|
-
print("
|
1258
|
+
print("Face.CrossShape - Error: The c input parameter is not a valid number. Returning None.")
|
1242
1259
|
return None
|
1243
1260
|
if not isinstance(d, int) and not isinstance(d, float):
|
1244
1261
|
if not silent:
|
1245
|
-
print("
|
1262
|
+
print("Face.CrossShape - Error: The d input parameter is not a valid number. Returning None.")
|
1246
1263
|
if width <= tolerance:
|
1247
1264
|
if not silent:
|
1248
|
-
print("
|
1265
|
+
print("Face.CrossShape - Error: The width input parameter must be a positive number greater than the tolerance input parameter. Returning None.")
|
1249
1266
|
return None
|
1250
1267
|
if length <= tolerance:
|
1251
1268
|
if not silent:
|
1252
|
-
print("
|
1269
|
+
print("Face.CrossShape - Error: The length input parameter must be a positive number greater than the tolerance input parameter. Returning None.")
|
1253
1270
|
return None
|
1254
1271
|
if a <= tolerance:
|
1255
1272
|
if not silent:
|
1256
|
-
print("
|
1273
|
+
print("Face.CrossShape - Error: The a input parameter must be a positive number greater than the tolerance input parameter. Returning None.")
|
1257
1274
|
return None
|
1258
1275
|
if b <= tolerance:
|
1259
1276
|
if not silent:
|
1260
|
-
print("
|
1277
|
+
print("Face.CrossShape - Error: The b input parameter must be a positive number greater than the tolerance input parameter. Returning None.")
|
1261
1278
|
return None
|
1262
1279
|
if c <= tolerance:
|
1263
1280
|
if not silent:
|
1264
|
-
print("
|
1281
|
+
print("Face.CrossShape - Error: The c input parameter must be a positive number greater than the tolerance input parameter. Returning None.")
|
1265
1282
|
return None
|
1266
1283
|
if d <= tolerance:
|
1267
1284
|
if not silent:
|
1268
|
-
print("
|
1285
|
+
print("Face.CrossShape - Error: The d input parameter must be a positive number greater than the tolerance input parameter. Returning None.")
|
1269
1286
|
return None
|
1270
1287
|
if a >= (width - tolerance*2):
|
1271
1288
|
if not silent:
|
1272
|
-
print("
|
1289
|
+
print("Face.CrossShape - Error: The a input parameter must be less than the width input parameter. Returning None.")
|
1273
1290
|
return None
|
1274
1291
|
if b >= (length - tolerance*2):
|
1275
1292
|
if not silent:
|
1276
|
-
print("
|
1293
|
+
print("Face.CrossShape - Error: The b input parameter must be less than the length input parameter. Returning None.")
|
1277
1294
|
return None
|
1278
1295
|
if c <= (tolerance + a/2):
|
1279
1296
|
if not silent:
|
1280
|
-
print("
|
1297
|
+
print("Face.CrossShape - Error: The c input parameter must be more than half the a input parameter. Returning None.")
|
1281
1298
|
return None
|
1282
1299
|
if d <= (tolerance + b/2):
|
1283
1300
|
if not silent:
|
1284
|
-
print("
|
1301
|
+
print("Face.CrossShape - Error: The c input parameter must be more than half the b input parameter. Returning None.")
|
1285
1302
|
return None
|
1286
1303
|
if c >= (width - tolerance - a/2):
|
1287
1304
|
if not silent:
|
1288
|
-
print("
|
1305
|
+
print("Face.CrossShape - Error: The c input parameter must be less than the width minus half the a input parameter. Returning None.")
|
1289
1306
|
return None
|
1290
1307
|
if d >= (length - tolerance - b/2):
|
1291
1308
|
if not silent:
|
1292
|
-
print("
|
1309
|
+
print("Face.CrossShape - Error: The c input parameter must be less than the width minus half the b input parameter. Returning None.")
|
1293
1310
|
return None
|
1294
1311
|
if origin == None:
|
1295
1312
|
origin = Vertex.Origin()
|
1296
1313
|
if not Topology.IsInstance(origin, "vertex"):
|
1297
1314
|
if not silent:
|
1298
|
-
print("
|
1315
|
+
print("Face.CrossShape - Error: The origin input parameter is not a valid topologic vertex. Returning None.")
|
1299
1316
|
return None
|
1300
1317
|
if not isinstance(direction, list):
|
1301
1318
|
if not silent:
|
1302
|
-
print("
|
1319
|
+
print("Face.CrossShape - Error: The direction input parameter is not a valid list. Returning None.")
|
1303
1320
|
return None
|
1304
1321
|
if not len(direction) == 3:
|
1305
1322
|
if not silent:
|
1306
|
-
print("
|
1323
|
+
print("Face.CrossShape - Error: The direction input parameter is not a valid vector. Returning None.")
|
1307
1324
|
return None
|
1308
1325
|
cross_shape_wire = Wire.CrossShape(origin=origin,
|
1309
1326
|
width=width,
|
@@ -1667,7 +1684,7 @@ class Face():
|
|
1667
1684
|
return True
|
1668
1685
|
|
1669
1686
|
@staticmethod
|
1670
|
-
def Fillet(face, radius: float = 0, radiusKey: str = None, tolerance: float = 0.0001, silent: bool = False):
|
1687
|
+
def Fillet(face, radius: float = 0, sides: int = 16, radiusKey: str = None, tolerance: float = 0.0001, silent: bool = False):
|
1671
1688
|
"""
|
1672
1689
|
Fillets (rounds) the interior and exterior corners of the input face given the input radius. See https://en.wikipedia.org/wiki/Fillet_(mechanics)
|
1673
1690
|
|
@@ -1675,8 +1692,10 @@ class Face():
|
|
1675
1692
|
----------
|
1676
1693
|
face : topologic_core.Face
|
1677
1694
|
The input face.
|
1678
|
-
radius : float
|
1679
|
-
The desired radius of the fillet.
|
1695
|
+
radius : float , optional
|
1696
|
+
The desired radius of the fillet. The default is 0.
|
1697
|
+
sides : int , optional
|
1698
|
+
The number of sides (segments) of the fillet. The default is 16.
|
1680
1699
|
radiusKey : str , optional
|
1681
1700
|
If specified, the dictionary of the vertices will be queried for this key to specify the desired fillet radius. The default is None.
|
1682
1701
|
tolerance : float , optional
|
@@ -1704,7 +1723,7 @@ class Face():
|
|
1704
1723
|
f_vertices = Topology.Vertices(face)
|
1705
1724
|
if isinstance(radiusKey, str):
|
1706
1725
|
eb = Topology.TransferDictionariesBySelectors(eb, selectors=f_vertices, tranVertices=True)
|
1707
|
-
eb = Wire.Fillet(eb, radius=radius, radiusKey=radiusKey, tolerance=tolerance)
|
1726
|
+
eb = Wire.Fillet(eb, radius=radius, sides=sides, radiusKey=radiusKey, tolerance=tolerance, silent=True)
|
1708
1727
|
if not Topology.IsInstance(eb, "Wire"):
|
1709
1728
|
if not silent:
|
1710
1729
|
print("Face.Fillet - Error: The operation failed. Returning None.")
|
@@ -1716,7 +1735,7 @@ class Face():
|
|
1716
1735
|
if isinstance(radiusKey, str):
|
1717
1736
|
ib = Topology.TransferDictionariesBySelectors(ib, selectors=f_vertices, tranVertices=True)
|
1718
1737
|
|
1719
|
-
ib_wire = Wire.Fillet(ib, radius=radius, radiusKey=radiusKey, tolerance=tolerance, silent=
|
1738
|
+
ib_wire = Wire.Fillet(ib, radius=radius, sides=sides, radiusKey=radiusKey, tolerance=tolerance, silent=True)
|
1720
1739
|
if Topology.IsInstance(ib, "Wire"):
|
1721
1740
|
ib_wires.append(ib_wire)
|
1722
1741
|
else:
|
@@ -3129,6 +3148,57 @@ class Face():
|
|
3129
3148
|
ev = Topology.TranslateByDirectionDistance(iv, vec, length)
|
3130
3149
|
return Edge.ByVertices([iv, ev], tolerance=tolerance, silent=silent)
|
3131
3150
|
|
3151
|
+
@staticmethod
|
3152
|
+
def NorthArrow(origin= None, radius: float = 0.5, sides: int = 16, direction: list = [0, 0, 1], northAngle: float = 0.0,
|
3153
|
+
placement: str = "center", tolerance: float = 0.0001):
|
3154
|
+
"""
|
3155
|
+
Creates a north arrow.
|
3156
|
+
|
3157
|
+
Parameters
|
3158
|
+
----------
|
3159
|
+
origin : topologic_core.Vertex, optional
|
3160
|
+
The location of the origin of the circle. The default is None which results in the circle being placed at (0, 0, 0).
|
3161
|
+
radius : float , optional
|
3162
|
+
The radius of the circle. The default is 1.
|
3163
|
+
sides : int , optional
|
3164
|
+
The number of sides of the circle. The default is 16.
|
3165
|
+
direction : list , optional
|
3166
|
+
The vector representing the up direction of the circle. The default is [0, 0, 1].
|
3167
|
+
northAngle : float , optional
|
3168
|
+
The angular offset in degrees from the positive Y axis direction. The angle is measured in a counter-clockwise fashion where 0 is positive Y, 90 is negative X, 180 is negative Y, and 270 is positive X.
|
3169
|
+
placement : str , optional
|
3170
|
+
The description of the placement of the origin of the circle. This can be "center", "lowerleft", "upperleft", "lowerright", or "upperright". It is case insensitive. The default is "center".
|
3171
|
+
tolerance : float , optional
|
3172
|
+
The desired tolerance. The default is 0.0001.
|
3173
|
+
|
3174
|
+
Returns
|
3175
|
+
-------
|
3176
|
+
topologic_core.Face
|
3177
|
+
The created circle.
|
3178
|
+
|
3179
|
+
"""
|
3180
|
+
from topologicpy.Topology import Topology
|
3181
|
+
from topologicpy.Vertex import Vertex
|
3182
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
3183
|
+
origin = Vertex.Origin()
|
3184
|
+
|
3185
|
+
c = Face.Circle(origin=origin, radius=radius, sides=sides, direction=[0, 0, 1], placement="center", tolerance=tolerance)
|
3186
|
+
r = Face.Rectangle(origin=origin, width=radius*0.01,length=radius*1.2, placement="lowerleft")
|
3187
|
+
r = Topology.Translate(r, -0.005*radius,0,0)
|
3188
|
+
arrow = Topology.Difference(c, r, tolerance=tolerance)
|
3189
|
+
arrow = Topology.Rotate(arrow, origin=Vertex.Origin(), axis=[0, 0, 1], angle=northAngle)
|
3190
|
+
if placement.lower() == "lowerleft":
|
3191
|
+
arrow = Topology.Translate(arrow, radius, radius, 0)
|
3192
|
+
elif placement.lower() == "upperleft":
|
3193
|
+
arrow = Topology.Translate(arrow, radius, -radius, 0)
|
3194
|
+
elif placement.lower() == "lowerright":
|
3195
|
+
arrow = Topology.Translate(arrow, -radius, radius, 0)
|
3196
|
+
elif placement.lower() == "upperright":
|
3197
|
+
arrow = Topology.Translate(arrow, -radius, -radius, 0)
|
3198
|
+
arrow = Topology.Place(arrow, originA=Vertex.Origin(), originB=origin)
|
3199
|
+
arrow = Topology.Orient(arrow, origin=origin, dirA=[0,0,1], dirB=direction)
|
3200
|
+
return arrow
|
3201
|
+
|
3132
3202
|
@staticmethod
|
3133
3203
|
def PlaneEquation(face, mantissa: int = 6) -> dict:
|
3134
3204
|
"""
|
@@ -3332,6 +3402,201 @@ class Face():
|
|
3332
3402
|
ib = [Wire.RemoveCollinearEdges(w, angTolerance=angTolerance, tolerance=tolerance, silent=silent) for w in Face.InternalBoundaries(face)]
|
3333
3403
|
return Face.ByWires(eb, ib)
|
3334
3404
|
|
3405
|
+
@staticmethod
|
3406
|
+
def RHS(origin= None, width: float = 1.0, length: float = 1.0, thickness: float = 0.25, outerFillet: float = 0.0, innerFillet: float = 0.0, sides: int = 16, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001, silent: bool = False):
|
3407
|
+
"""
|
3408
|
+
Creates a rectangluar hollow section (RHS).
|
3409
|
+
|
3410
|
+
Parameters
|
3411
|
+
----------
|
3412
|
+
origin : topologic_core.Vertex, optional
|
3413
|
+
The location of the origin of the RHS. The default is None which results in the RHS being placed at (0, 0, 0).
|
3414
|
+
width : float , optional
|
3415
|
+
The width of the RHS. The default is 1.0.
|
3416
|
+
length : float , optional
|
3417
|
+
The length of the RHS. The default is 1.0.
|
3418
|
+
thickness : float , optional
|
3419
|
+
The thickness of the RHS. The default is 0.25.
|
3420
|
+
outerFillet : float , optional
|
3421
|
+
The outer fillet multiplication factor based on the thickness (e.g. 1t). The default is 0.
|
3422
|
+
innerFillet : float , optional
|
3423
|
+
The inner fillet multiplication factor based on the thickness (e.g. 1.5t). The default is 0.
|
3424
|
+
sides : int , optional
|
3425
|
+
The desired number of sides of the fillets. The default is 16.
|
3426
|
+
direction : list , optional
|
3427
|
+
The vector representing the up direction of the RHS. The default is [0, 0, 1].
|
3428
|
+
placement : str , optional
|
3429
|
+
The description of the placement of the origin of the RHS. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
|
3430
|
+
tolerance : float , optional
|
3431
|
+
The desired tolerance. The default is 0.0001.
|
3432
|
+
silent : bool , optional
|
3433
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
3434
|
+
|
3435
|
+
Returns
|
3436
|
+
-------
|
3437
|
+
topologic_core.Face
|
3438
|
+
The created face.
|
3439
|
+
|
3440
|
+
"""
|
3441
|
+
from topologicpy.Vertex import Vertex
|
3442
|
+
from topologicpy.Wire import Wire
|
3443
|
+
from topologicpy.Topology import Topology
|
3444
|
+
|
3445
|
+
if 2*thickness >= width:
|
3446
|
+
if not silent:
|
3447
|
+
print("Face.RHS - Error: Twice the thickness value is larger than or equal to the width value. Returning None.")
|
3448
|
+
return None
|
3449
|
+
if 2*thickness >= width:
|
3450
|
+
if not silent:
|
3451
|
+
print("Face.RHS - Error: Twice the thickness value is larger than or equal to the length value. Returning None.")
|
3452
|
+
return None
|
3453
|
+
outer_dimension = min(width, length)
|
3454
|
+
fillet_dimension = 2*outerFillet*thickness
|
3455
|
+
if fillet_dimension > outer_dimension:
|
3456
|
+
if not silent:
|
3457
|
+
print("Face.RHS = Error: The outer fillet radius input value is too large given the desired dimensions of the RHS. Returning None.")
|
3458
|
+
return None
|
3459
|
+
inner_dimension = min(width, length) - 2*thickness
|
3460
|
+
fillet_dimension = 2*innerFillet*thickness
|
3461
|
+
if fillet_dimension > inner_dimension:
|
3462
|
+
if not silent:
|
3463
|
+
print("Face.RHS = Error: The inner fillet radius input value is too large given the desired dimensions of the RHS. Returning None.")
|
3464
|
+
return None
|
3465
|
+
if origin == None:
|
3466
|
+
origin = Vertex.Origin()
|
3467
|
+
|
3468
|
+
outer_wire = Wire.Rectangle(origin=Vertex.Origin(), width=width, length=length, direction=[0,0,1], placement="center", tolerance=tolerance, silent=silent)
|
3469
|
+
inner_wire = Wire.Rectangle(origin=Vertex.Origin(), width=width-thickness*2, length=length-thickness*2, direction=[0,0,1], placement="center", tolerance=tolerance, silent=silent)
|
3470
|
+
if outerFillet > 0:
|
3471
|
+
outer_wire = Wire.Fillet(outer_wire, radius=outerFillet*thickness, sides=sides, silent=silent)
|
3472
|
+
if innerFillet > 0:
|
3473
|
+
inner_wire = Wire.Fillet(inner_wire, radius=innerFillet*thickness, sides=sides, silent=silent)
|
3474
|
+
return_face = Face.ByWires(outer_wire, [inner_wire], silent=silent)
|
3475
|
+
if not Topology.IsInstance(return_face, "face"):
|
3476
|
+
if not silent:
|
3477
|
+
print("Face.RHS - Error: Could not create the face for the RHS. Returning None.")
|
3478
|
+
return None
|
3479
|
+
|
3480
|
+
xOffset = 0
|
3481
|
+
yOffset = 0
|
3482
|
+
zOffset = 0
|
3483
|
+
if placement.lower() == "lowerleft":
|
3484
|
+
xOffset = width*0.5
|
3485
|
+
yOffset = length*0.5
|
3486
|
+
elif placement.lower() == "upperleft":
|
3487
|
+
xOffset = width*0.5
|
3488
|
+
yOffset = -length*0.5
|
3489
|
+
elif placement.lower() == "lowerright":
|
3490
|
+
xOffset = -width*0.5
|
3491
|
+
yOffset = length*0.5
|
3492
|
+
elif placement.lower() == "upperright":
|
3493
|
+
xOffset = -width*0.5
|
3494
|
+
yOffset = -length*0.5
|
3495
|
+
return_face = Topology.Translate(return_face, x=xOffset, y=yOffset, z=zOffset)
|
3496
|
+
return_face = Topology.Place(return_face, originA=Vertex.Origin(), originB=origin)
|
3497
|
+
if direction != [0, 0, 1]:
|
3498
|
+
return_face = Topology.Orient(return_face, origin=origin, dirA=[0, 0, 1], dirB=direction)
|
3499
|
+
return return_face
|
3500
|
+
|
3501
|
+
@staticmethod
|
3502
|
+
def Ring(origin= None, radius: float = 0.5, thickness: float = 0.25, sides: int = 16, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001, silent: bool = False):
|
3503
|
+
"""
|
3504
|
+
Creates a circular ring. This is an alias method for creating a circular hollow section (CHS).
|
3505
|
+
|
3506
|
+
Parameters
|
3507
|
+
----------
|
3508
|
+
origin : topologic_core.Vertex, optional
|
3509
|
+
The location of the origin of the ring. The default is None which results in the ring being placed at (0, 0, 0).
|
3510
|
+
radius : float , optional
|
3511
|
+
The outer radius of the ring. The default is 0.5.
|
3512
|
+
thickness : float , optional
|
3513
|
+
The thickness of the ring. The default is 0.25.
|
3514
|
+
direction : list , optional
|
3515
|
+
The vector representing the up direction of the ring. The default is [0, 0, 1].
|
3516
|
+
placement : str , optional
|
3517
|
+
The description of the placement of the origin of the ring. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
|
3518
|
+
tolerance : float , optional
|
3519
|
+
The desired tolerance. The default is 0.0001.
|
3520
|
+
silent : bool , optional
|
3521
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
3522
|
+
|
3523
|
+
Returns
|
3524
|
+
-------
|
3525
|
+
topologic_core.Face
|
3526
|
+
The created face.
|
3527
|
+
|
3528
|
+
"""
|
3529
|
+
|
3530
|
+
if thickness >= radius:
|
3531
|
+
if not silent:
|
3532
|
+
print("Face.Ring - Error: The thickness value is larger than or equal to the outer radius value. Returning None.")
|
3533
|
+
return None
|
3534
|
+
return Face.CHS(origin=origin,
|
3535
|
+
radius=radius,
|
3536
|
+
thickness=thickness,
|
3537
|
+
sides=sides,
|
3538
|
+
direction=direction,
|
3539
|
+
placement=placement,
|
3540
|
+
tolerance=tolerance,
|
3541
|
+
silent=silent)
|
3542
|
+
@staticmethod
|
3543
|
+
def SHS(origin= None, size: float = 1.0, thickness: float = 0.25, outerFillet: float = 0.0, innerFillet: float = 0.0, sides: int = 16, direction: list = [0, 0, 1], placement: str = "center", tolerance: float = 0.0001, silent: bool = False):
|
3544
|
+
"""
|
3545
|
+
Creates a square hollow section (SHS).
|
3546
|
+
|
3547
|
+
Parameters
|
3548
|
+
----------
|
3549
|
+
origin : topologic_core.Vertex, optional
|
3550
|
+
The location of the origin of the SHS. The default is None which results in the SHS being placed at (0, 0, 0).
|
3551
|
+
size : float , optional
|
3552
|
+
The outer size of the SHS. The default is 1.0.
|
3553
|
+
thickness : float , optional
|
3554
|
+
The thickness of the SHS. The default is 0.25.
|
3555
|
+
outerFillet : float , optional
|
3556
|
+
The outer fillet multiplication factor based on the thickness (e.g. 1t). The default is 0.
|
3557
|
+
innerFillet : float , optional
|
3558
|
+
The inner fillet multiplication factor based on the thickness (e.g. 1.5t). The default is 0.
|
3559
|
+
sides : int , optional
|
3560
|
+
The desired number of sides of the fillets. The default is 16.
|
3561
|
+
direction : list , optional
|
3562
|
+
The vector representing the up direction of the SHS. The default is [0, 0, 1].
|
3563
|
+
placement : str , optional
|
3564
|
+
The description of the placement of the origin of the SHS. This can be "center", "lowerleft", "upperleft", "lowerright", "upperright". It is case insensitive. The default is "center".
|
3565
|
+
tolerance : float , optional
|
3566
|
+
The desired tolerance. The default is 0.0001.
|
3567
|
+
silent : bool , optional
|
3568
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
3569
|
+
|
3570
|
+
Returns
|
3571
|
+
-------
|
3572
|
+
topologic_core.Face
|
3573
|
+
The created face.
|
3574
|
+
|
3575
|
+
"""
|
3576
|
+
from topologicpy.Vertex import Vertex
|
3577
|
+
from topologicpy.Wire import Wire
|
3578
|
+
from topologicpy.Topology import Topology
|
3579
|
+
|
3580
|
+
if 2*thickness >= size:
|
3581
|
+
if not silent:
|
3582
|
+
print("Face.SHS - Error: Twice the thickness value is larger than or equal to the outer size value. Returning None.")
|
3583
|
+
return None
|
3584
|
+
fillet_dimension = 2*outerFillet*thickness
|
3585
|
+
if fillet_dimension > size:
|
3586
|
+
if not silent:
|
3587
|
+
print("Face.RHS = Error: The outer fillet radius input value is too large given the desired dimensions of the RHS. Returning None.")
|
3588
|
+
return None
|
3589
|
+
inner_dimension = size - 2*thickness
|
3590
|
+
fillet_dimension = 2*innerFillet*thickness
|
3591
|
+
if fillet_dimension > inner_dimension:
|
3592
|
+
if not silent:
|
3593
|
+
print("Face.RHS = Error: The inner fillet radius input value is too large given the desired dimensions of the RHS. Returning None.")
|
3594
|
+
return None
|
3595
|
+
if origin == None:
|
3596
|
+
origin = Vertex.Origin()
|
3597
|
+
|
3598
|
+
return Face.RHS(origin = origin, width = size, length = size, thickness = thickness, outerFillet = outerFillet, innerFillet = innerFillet, sides = sides, direction = direction, placement = placement, tolerance = tolerance, silent = silent)
|
3599
|
+
|
3335
3600
|
@staticmethod
|
3336
3601
|
def Simplify(face, tolerance=0.0001):
|
3337
3602
|
"""
|
topologicpy/Graph.py
CHANGED
@@ -523,7 +523,7 @@ class Graph:
|
|
523
523
|
_ = graph.AddVertices(vertices, tolerance) # Hook to Core
|
524
524
|
return graph
|
525
525
|
|
526
|
-
def AdjacencyDictionary(graph, vertexLabelKey: str = None, edgeKey: str = "Length", includeWeights: bool = False,
|
526
|
+
def AdjacencyDictionary(graph, vertexLabelKey: str = None, edgeKey: str = "Length", includeWeights: bool = False, mantissa: int = 6):
|
527
527
|
"""
|
528
528
|
Returns the adjacency dictionary of the input Graph.
|
529
529
|
|
@@ -537,9 +537,7 @@ class Graph:
|
|
537
537
|
edgeKey : str , optional
|
538
538
|
If set, the edges' dictionaries will be searched for this key to set their weight. If the key is set to "length" (case insensitive), the length of the edge will be used as its weight. If set to None, a weight of 1 will be used. The default is "Length".
|
539
539
|
includeWeights : bool , optional
|
540
|
-
If set to True, edge weights are included. Otherwise, they are not. The default is False.
|
541
|
-
reverse : bool , optional
|
542
|
-
If set to True, the vertices are sorted in reverse order (only if vertexKey is set). Otherwise, they are not. The default is False.
|
540
|
+
If set to True, edge weights are included. Otherwise, they are not. The default is False.
|
543
541
|
mantissa : int , optional
|
544
542
|
The desired length of the mantissa. The default is 6.
|
545
543
|
|
@@ -578,9 +576,6 @@ class Graph:
|
|
578
576
|
labels.append(value)
|
579
577
|
vertices = Helper.Sort(vertices, labels)
|
580
578
|
labels.sort()
|
581
|
-
if reverse == True:
|
582
|
-
vertices.reverse()
|
583
|
-
labels.reverse()
|
584
579
|
order = len(vertices)
|
585
580
|
adjDict = {}
|
586
581
|
for i in range(order):
|
topologicpy/Helper.py
CHANGED
@@ -286,6 +286,58 @@ class Helper:
|
|
286
286
|
flat_list = flat_list + Helper.Flatten(item)
|
287
287
|
return flat_list
|
288
288
|
|
289
|
+
@staticmethod
|
290
|
+
def Grow(seed_idx, group_size, adjacency, visited_global):
|
291
|
+
"""
|
292
|
+
Attempts to grow a spatially connected group of a specified size starting from a given seed index.
|
293
|
+
|
294
|
+
This method uses a breadth-first search strategy to explore neighboring indices from the seed index,
|
295
|
+
guided by the provided adjacency dictionary. It avoids reusing indices that are globally visited.
|
296
|
+
The growth continues until the desired group size is reached or no further expansion is possible.
|
297
|
+
|
298
|
+
Parameters
|
299
|
+
----------
|
300
|
+
seed_idx : int
|
301
|
+
The index from which to start growing the group.
|
302
|
+
group_size : int
|
303
|
+
The target size of the group to be grown.
|
304
|
+
adjacency : dict
|
305
|
+
A dictionary mapping each index to a list of adjacent indices. This defines the connectivity.
|
306
|
+
visited_global : set
|
307
|
+
A set of indices that have already been used in previously grown groups and should be avoided.
|
308
|
+
|
309
|
+
Returns
|
310
|
+
-------
|
311
|
+
list[int] or None
|
312
|
+
A list of indices representing a connected group of the specified size if successful, otherwise None.
|
313
|
+
|
314
|
+
Notes
|
315
|
+
-----
|
316
|
+
This method is intended for internal use in functions that generate connected subgroups
|
317
|
+
of spatial elements (e.g., cells) based on adjacency. The result may vary between runs due to random shuffling
|
318
|
+
of neighbor order to diversify outputs.
|
319
|
+
"""
|
320
|
+
from collections import deque
|
321
|
+
import random
|
322
|
+
|
323
|
+
group = [seed_idx]
|
324
|
+
visited = set(group)
|
325
|
+
queue = deque([seed_idx])
|
326
|
+
|
327
|
+
while queue and len(group) < group_size:
|
328
|
+
current = queue.popleft()
|
329
|
+
neighbors = adjacency.get(current, [])
|
330
|
+
random.shuffle(neighbors)
|
331
|
+
for neighbor in neighbors:
|
332
|
+
if neighbor not in visited and neighbor not in visited_global:
|
333
|
+
group.append(neighbor)
|
334
|
+
visited.add(neighbor)
|
335
|
+
queue.append(neighbor)
|
336
|
+
if len(group) >= group_size:
|
337
|
+
break
|
338
|
+
|
339
|
+
return group if len(group) == group_size else None
|
340
|
+
|
289
341
|
@staticmethod
|
290
342
|
def Iterate(listA):
|
291
343
|
"""
|