topologicpy 0.7.15__py3-none-any.whl → 0.7.18__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 +19 -12
- topologicpy/CellComplex.py +3 -3
- topologicpy/DGL.py +1 -1
- topologicpy/Edge.py +46 -20
- topologicpy/Face.py +215 -110
- topologicpy/Graph.py +230 -106
- topologicpy/Neo4j.py +2 -2
- topologicpy/Shell.py +57 -11
- topologicpy/Topology.py +17 -37
- topologicpy/Vector.py +1 -3
- topologicpy/Vertex.py +2 -4
- topologicpy/Wire.py +288 -191
- topologicpy/version.py +1 -1
- {topologicpy-0.7.15.dist-info → topologicpy-0.7.18.dist-info}/METADATA +37 -1
- topologicpy-0.7.18.dist-info/RECORD +33 -0
- topologicpy-0.7.15.dist-info/RECORD +0 -33
- {topologicpy-0.7.15.dist-info → topologicpy-0.7.18.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.15.dist-info → topologicpy-0.7.18.dist-info}/WHEEL +0 -0
- {topologicpy-0.7.15.dist-info → topologicpy-0.7.18.dist-info}/top_level.txt +0 -0
topologicpy/Shell.py
CHANGED
@@ -331,6 +331,52 @@ class Shell():
|
|
331
331
|
_ = cluster.Faces(None, faces)
|
332
332
|
return Shell.ByFaces(faces, tolerance=tolerance)
|
333
333
|
|
334
|
+
|
335
|
+
@staticmethod
|
336
|
+
def ByThickenedWire(wire, offsetA: float = 1.0, offsetB: float = 1.0, tolerance: float = 0.0001):
|
337
|
+
"""
|
338
|
+
Creates a shell by thickening the input wire. This method assumes the wire is manifold and planar.
|
339
|
+
|
340
|
+
Parameters
|
341
|
+
----------
|
342
|
+
wire : topologic_core.Wire
|
343
|
+
The input wire to be thickened.
|
344
|
+
offsetA : float , optional
|
345
|
+
The desired offset to the exterior of the wire. The default is 1.0.
|
346
|
+
offsetB : float , optional
|
347
|
+
The desired offset to the interior of the wire. The default is 1.0.
|
348
|
+
tolerance : float , optional
|
349
|
+
The desired tolerance. The default is 0.0001.
|
350
|
+
|
351
|
+
Returns
|
352
|
+
-------
|
353
|
+
topologic_core.Cell
|
354
|
+
The created cell.
|
355
|
+
|
356
|
+
"""
|
357
|
+
from topologicpy.Edge import Edge
|
358
|
+
from topologicpy.Wire import Wire
|
359
|
+
from topologicpy.Face import Face
|
360
|
+
from topologicpy.Topology import Topology
|
361
|
+
|
362
|
+
if not Topology.IsInstance(wire, "Wire"):
|
363
|
+
print("Shell.ByThickenedWire - Error: The input wire parameter is not a valid wire. Returning None.")
|
364
|
+
return None
|
365
|
+
|
366
|
+
f = Face.ByThickenedWire(wire, offsetA=offsetA, offsetB=offsetB, tolerance=tolerance)
|
367
|
+
outside_wire = Wire.ByOffset(wire, offset=abs(offsetA)*-1, bisectors = False, tolerance=tolerance)
|
368
|
+
inside_wire = Wire.ByOffset(wire, offset=abs(offsetB), bisectors = False, tolerance=tolerance)
|
369
|
+
border = Topology.Merge(outside_wire, inside_wire)
|
370
|
+
outside_wire = Wire.ByOffset(wire, offset=abs(offsetA)*-1, bisectors = True, tolerance=tolerance)
|
371
|
+
inside_wire = Wire.ByOffset(wire, offset=abs(offsetB), bisectors = True, tolerance=tolerance)
|
372
|
+
grid = Topology.Merge(outside_wire, inside_wire)
|
373
|
+
bisectors = Topology.Difference(grid, border)
|
374
|
+
return_shell = Topology.Slice(f, bisectors)
|
375
|
+
if not Topology.IsInstance(return_shell, "Shell"):
|
376
|
+
print("Shell.ByThickenedWire - Error: The operation failed. Returning None.")
|
377
|
+
return None
|
378
|
+
return return_shell
|
379
|
+
|
334
380
|
@staticmethod
|
335
381
|
def ByWires(wires: list, triangulate: bool = True, tolerance: float = 0.0001, silent: bool = False):
|
336
382
|
"""
|
@@ -708,23 +754,23 @@ class Shell():
|
|
708
754
|
Parameters
|
709
755
|
----------
|
710
756
|
origin : topologic_core.Vertex , optional
|
711
|
-
The origin of the hyperbolic
|
757
|
+
The origin of the hyperbolic paraboloid. If set to None, it will be placed at the (0, 0, 0) origin. The default is None.
|
712
758
|
llVertex : topologic_core.Vertex , optional
|
713
|
-
The lower left corner of the hyperbolic
|
759
|
+
The lower left corner of the hyperbolic paraboloid. If set to None, it will be set to (-0.5, -0.5, -0.5).
|
714
760
|
lrVertex : topologic_core.Vertex , optional
|
715
|
-
The lower right corner of the hyperbolic
|
761
|
+
The lower right corner of the hyperbolic paraboloid. If set to None, it will be set to (0.5, -0.5, 0.5).
|
716
762
|
ulVertex : topologic_core.Vertex , optional
|
717
|
-
The upper left corner of the hyperbolic
|
763
|
+
The upper left corner of the hyperbolic paraboloid. If set to None, it will be set to (-0.5, 0.5, 0.5).
|
718
764
|
urVertex : topologic_core.Vertex , optional
|
719
|
-
The upper right corner of the hyperbolic
|
765
|
+
The upper right corner of the hyperbolic paraboloid. If set to None, it will be set to (0.5, 0.5, -0.5).
|
720
766
|
uSides : int , optional
|
721
767
|
The number of segments along the X axis. The default is 10.
|
722
768
|
vSides : int , optional
|
723
769
|
The number of segments along the Y axis. The default is 10.
|
724
770
|
direction : list , optional
|
725
|
-
The vector representing the up direction of the hyperbolic
|
771
|
+
The vector representing the up direction of the hyperbolic paraboloid. The default is [0, 0, 1].
|
726
772
|
placement : str , optional
|
727
|
-
The description of the placement of the origin of the hyperbolic
|
773
|
+
The description of the placement of the origin of the hyperbolic paraboloid. This can be "center", "lowerleft", "bottom". It is case insensitive. The default is "center".
|
728
774
|
mantissa : int , optional
|
729
775
|
The desired length of the mantissa. The default is 6.
|
730
776
|
tolerance : float , optional
|
@@ -827,7 +873,7 @@ class Shell():
|
|
827
873
|
Returns
|
828
874
|
-------
|
829
875
|
topologic_core.Shell
|
830
|
-
The created
|
876
|
+
The created hyperbolic paraboloid.
|
831
877
|
|
832
878
|
"""
|
833
879
|
from topologicpy.Vertex import Vertex
|
@@ -1287,7 +1333,7 @@ class Shell():
|
|
1287
1333
|
The desired angle in degrees of the roof. The default is 45.
|
1288
1334
|
epsilon : float , optional
|
1289
1335
|
The desired epsilon (another form of tolerance for distance from plane). The default is 0.01. (This is set to a larger number as it was found to work better)
|
1290
|
-
|
1336
|
+
mantissa : int , optional
|
1291
1337
|
The desired length of the mantissa. The default is 6.
|
1292
1338
|
tolerance : float , optional
|
1293
1339
|
The desired tolerance. The default is 0.001. (This is set to a larger number as it was found to work better)
|
@@ -1495,7 +1541,7 @@ class Shell():
|
|
1495
1541
|
@staticmethod
|
1496
1542
|
def Simplify(shell, simplifyBoundary: bool = True, mantissa: int = 6, tolerance: float = 0.0001):
|
1497
1543
|
"""
|
1498
|
-
Simplifies the input shell edges based on the Douglas Peucker
|
1544
|
+
Simplifies the input shell edges based on the Douglas Peucker algorithm. See https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
|
1499
1545
|
Part of this code was contributed by gaoxipeng. See https://github.com/wassimj/topologicpy/issues/35
|
1500
1546
|
|
1501
1547
|
Parameters
|
@@ -1765,7 +1811,7 @@ class Shell():
|
|
1765
1811
|
for v in tempWire:
|
1766
1812
|
if len(temp_verts) == 0:
|
1767
1813
|
temp_verts.append(v)
|
1768
|
-
elif Vertex.Index(v, temp_verts) == None:
|
1814
|
+
elif Vertex.Index(v, temp_verts, tolerance=tolerance) == None:
|
1769
1815
|
temp_verts.append(v)
|
1770
1816
|
tempWire = temp_verts
|
1771
1817
|
temp_w = Wire.ByVertices(tempWire, close=True)
|
topologicpy/Topology.py
CHANGED
@@ -200,7 +200,7 @@ class Topology():
|
|
200
200
|
@staticmethod
|
201
201
|
def AddApertures(topology, apertures, exclusive=False, subTopologyType=None, tolerance=0.001):
|
202
202
|
"""
|
203
|
-
Adds the input list of apertures to the input topology or to its
|
203
|
+
Adds the input list of apertures to the input topology or to its subtopologies based on the input subTopologyType.
|
204
204
|
|
205
205
|
Parameters
|
206
206
|
----------
|
@@ -350,7 +350,7 @@ class Topology():
|
|
350
350
|
@staticmethod
|
351
351
|
def AdjacentTopologies(topology, hostTopology, topologyType=None):
|
352
352
|
"""
|
353
|
-
Returns the topologies, as specified by the input topology type, adjacent to the input topology
|
353
|
+
Returns the topologies, as specified by the input topology type, adjacent to the input topology within the input host topology.
|
354
354
|
|
355
355
|
Parameters
|
356
356
|
----------
|
@@ -1402,7 +1402,7 @@ class Topology():
|
|
1402
1402
|
faces : list , optional
|
1403
1403
|
The input list of faces in the form of [i, j, k, l, ...] where the items in the list are vertex indices. The face is assumed to be closed to the last vertex is connected to the first vertex automatically.
|
1404
1404
|
color : list , optional
|
1405
|
-
The desired color of the object in the form of [r, g, b, a] where the components are between 0 and 1 and represent red, blue, green, and alpha (transparency)
|
1405
|
+
The desired color of the object in the form of [r, g, b, a] where the components are between 0 and 1 and represent red, blue, green, and alpha (transparency) respectively. The default is [1.0, 1.0, 1.0, 1.0].
|
1406
1406
|
id : str , optional
|
1407
1407
|
The desired ID of the object. If set to None, an automatic uuid4 will be assigned to the object. The default is None.
|
1408
1408
|
name : str , optional
|
@@ -1410,7 +1410,7 @@ class Topology():
|
|
1410
1410
|
lengthUnit : str , optional
|
1411
1411
|
The length unit used for the object. The default is "METERS"
|
1412
1412
|
outputMode : str , optional
|
1413
|
-
The desired
|
1413
|
+
The desired output mode of the object. This can be "wire", "shell", "cell", "cellcomplex", or "default". It is case insensitive. The default is "default".
|
1414
1414
|
tolerance : float , optional
|
1415
1415
|
The desired tolerance. The default is 0.0001.
|
1416
1416
|
|
@@ -1571,7 +1571,7 @@ class Topology():
|
|
1571
1571
|
path : str
|
1572
1572
|
The input file path.
|
1573
1573
|
overwrite : bool , optional
|
1574
|
-
If set to True the
|
1574
|
+
If set to True the output file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
|
1575
1575
|
version : str , optional
|
1576
1576
|
The desired version number for the BIM file. The default is "1.0.0".
|
1577
1577
|
guidKey : str , optional
|
@@ -1635,7 +1635,7 @@ class Topology():
|
|
1635
1635
|
path : str
|
1636
1636
|
The input file path.
|
1637
1637
|
overwrite : bool , optional
|
1638
|
-
If set to True the
|
1638
|
+
If set to True the output file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
|
1639
1639
|
version : str , optional
|
1640
1640
|
The desired version number for the BIM file. The default is "1.0.0".
|
1641
1641
|
guidKey : str , optional
|
@@ -1731,7 +1731,7 @@ class Topology():
|
|
1731
1731
|
path : str
|
1732
1732
|
The input file path.
|
1733
1733
|
overwrite : bool , optional
|
1734
|
-
If set to True the
|
1734
|
+
If set to True the output file will overwrite any pre-existing file. Otherwise, it won't. The default is False.
|
1735
1735
|
version : str , optional
|
1736
1736
|
The desired version number for the BIM file. The default is "1.0.0".
|
1737
1737
|
guidKey : str , optional
|
@@ -2041,7 +2041,7 @@ class Topology():
|
|
2041
2041
|
file : file object
|
2042
2042
|
The input IFC file.
|
2043
2043
|
transferDictionaries : bool , optional
|
2044
|
-
If set to True, the dictionaries from the IFC file will be
|
2044
|
+
If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
|
2045
2045
|
includeTypes : list , optional
|
2046
2046
|
The list of IFC object types to include. It is case insensitive. If set to an empty list, all types are included. The default is [].
|
2047
2047
|
excludeTypes : list , optional
|
@@ -2134,7 +2134,7 @@ class Topology():
|
|
2134
2134
|
path : str
|
2135
2135
|
The path to the IFC file.
|
2136
2136
|
transferDictionaries : bool , optional
|
2137
|
-
If set to True, the dictionaries from the IFC file will be
|
2137
|
+
If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
|
2138
2138
|
includeTypes : list , optional
|
2139
2139
|
The list of IFC object types to include. It is case insensitive. If set to an empty list, all types are included. The default is [].
|
2140
2140
|
excludeTypes : list , optional
|
@@ -2708,7 +2708,7 @@ class Topology():
|
|
2708
2708
|
@staticmethod
|
2709
2709
|
def ByOBJString(string, transposeAxes = True, progressBar=False, tolerance=0.0001):
|
2710
2710
|
"""
|
2711
|
-
Creates a topology from the input
|
2711
|
+
Creates a topology from the input Wavefront OBJ string. This is a very experimental method and only works with simple planar solids. Materials and Colors are ignored.
|
2712
2712
|
|
2713
2713
|
Parameters
|
2714
2714
|
----------
|
@@ -2783,7 +2783,7 @@ class Topology():
|
|
2783
2783
|
@staticmethod
|
2784
2784
|
def ByOBJFile(file, transposeAxes=True, progressBar=False, tolerance=0.0001):
|
2785
2785
|
"""
|
2786
|
-
Imports the topology from a
|
2786
|
+
Imports the topology from a Wevefront OBJ file. This is a very experimental method and only works with simple planar solids. Materials and Colors are ignored.
|
2787
2787
|
|
2788
2788
|
Parameters
|
2789
2789
|
----------
|
@@ -2813,7 +2813,7 @@ class Topology():
|
|
2813
2813
|
@staticmethod
|
2814
2814
|
def ByOBJPath(path, transposeAxes=True, progressBar=False, tolerance=0.0001):
|
2815
2815
|
"""
|
2816
|
-
Imports the topology from a
|
2816
|
+
Imports the topology from a Wevefront OBJ file path. This is a very experimental method and only works with simple planar solids. Materials and Colors are ignored.
|
2817
2817
|
|
2818
2818
|
Parameters
|
2819
2819
|
----------
|
@@ -3236,7 +3236,7 @@ class Topology():
|
|
3236
3236
|
_ = topology.Faces(None, faces)
|
3237
3237
|
normals = []
|
3238
3238
|
for aFace in faces:
|
3239
|
-
normals.append(Face.
|
3239
|
+
normals.append(Face.Normal(aFace, outputType="XYZ", mantissa=3))
|
3240
3240
|
# build a matrix of similarity
|
3241
3241
|
mat = buildSimilarityMatrix(normals, angTolerance)
|
3242
3242
|
categories = categorizeIntoClusters(mat)
|
@@ -4799,17 +4799,6 @@ class Topology():
|
|
4799
4799
|
_ = topology.CellComplexes(None, topologies)
|
4800
4800
|
return topologies
|
4801
4801
|
|
4802
|
-
def triangulateFace(face):
|
4803
|
-
faceTriangles = []
|
4804
|
-
for i in range(0, 5, 1):
|
4805
|
-
try:
|
4806
|
-
_ = topologic.FaceUtility.Triangulate(face, float(i)*0.1, faceTriangles)
|
4807
|
-
return faceTriangles
|
4808
|
-
except:
|
4809
|
-
continue
|
4810
|
-
faceTriangles.append(face)
|
4811
|
-
return faceTriangles
|
4812
|
-
|
4813
4802
|
vertices = []
|
4814
4803
|
edges = []
|
4815
4804
|
faces = []
|
@@ -4858,14 +4847,10 @@ class Topology():
|
|
4858
4847
|
ib = []
|
4859
4848
|
_ = aFace.InternalBoundaries(ib)
|
4860
4849
|
if(len(ib) > 0):
|
4861
|
-
triFaces =
|
4850
|
+
triFaces = Face.Triangulate(aFace)
|
4862
4851
|
for aTriFace in triFaces:
|
4863
|
-
wire =
|
4852
|
+
wire = Face.ExternalBoundary(aTriFace)
|
4864
4853
|
faceVertices = getSubTopologies(wire, topologic.Vertex)
|
4865
|
-
temp_face = Face.ByWire(wire)
|
4866
|
-
temp_dir = Face.Normal(temp_face)
|
4867
|
-
if Vector.IsAntiParallel(f_dir, temp_dir):
|
4868
|
-
faceVertices.reverse()
|
4869
4854
|
f = []
|
4870
4855
|
for aVertex in faceVertices:
|
4871
4856
|
try:
|
@@ -4876,13 +4861,8 @@ class Topology():
|
|
4876
4861
|
f.append(fVertexIndex)
|
4877
4862
|
faces.append(f)
|
4878
4863
|
else:
|
4879
|
-
wire =
|
4880
|
-
#wire = topologic.WireUtility.RemoveCollinearEdges(wire, 0.1) #This is an angle Tolerance
|
4864
|
+
wire = Face.ExternalBoundary(aFace)
|
4881
4865
|
faceVertices = getSubTopologies(wire, topologic.Vertex)
|
4882
|
-
temp_face = Face.ByWire(wire)
|
4883
|
-
temp_dir = Face.Normal(temp_face)
|
4884
|
-
if Vector.IsAntiParallel(f_dir, temp_dir):
|
4885
|
-
faceVertices.reverse()
|
4886
4866
|
f = []
|
4887
4867
|
for aVertex in faceVertices:
|
4888
4868
|
try:
|
@@ -5540,7 +5520,7 @@ class Topology():
|
|
5540
5520
|
#final_faces.append(Face.RemoveCollinearEdges(t))
|
5541
5521
|
final_faces.append(t)
|
5542
5522
|
elif Topology.IsInstance(t, "Shell"):
|
5543
|
-
f = Face.ByShell(t)
|
5523
|
+
f = Face.ByShell(t, silent=True)
|
5544
5524
|
if Topology.IsInstance(f, "Face"):
|
5545
5525
|
final_faces.append(f)
|
5546
5526
|
else:
|
topologicpy/Vector.py
CHANGED
@@ -133,7 +133,7 @@ class Vector(list):
|
|
133
133
|
def AzimuthAltitude(vector, mantissa: int = 6):
|
134
134
|
"""
|
135
135
|
Returns a dictionary of azimuth and altitude angles in degrees for the input vector. North is assumed to be the positive Y axis [0, 1, 0]. Up is assumed to be the positive Z axis [0, 0, 1].
|
136
|
-
Azimuth is calculated in a counter-clockwise fashion from North where 0 is North, 90 is East, 180 is South, and 270 is West. Altitude is calculated in a counter-clockwise
|
136
|
+
Azimuth is calculated in a counter-clockwise fashion from North where 0 is North, 90 is East, 180 is South, and 270 is West. Altitude is calculated in a counter-clockwise fashion where -90 is straight down (negative Z axis), 0 is in the XY plane, and 90 is straight up (positive Z axis).
|
137
137
|
If the altitude is -90 or 90, the azimuth is assumed to be 0.
|
138
138
|
|
139
139
|
Parameters
|
@@ -196,7 +196,6 @@ class Vector(list):
|
|
196
196
|
# Normalize input vectors
|
197
197
|
vector1_norm = vector1 / np.linalg.norm(vector1)
|
198
198
|
vector2_norm = vector2 / np.linalg.norm(vector2)
|
199
|
-
|
200
199
|
# Check if the angle between vectors is either 0 or 180 degrees
|
201
200
|
dot_product = np.dot(vector1_norm, vector2_norm)
|
202
201
|
if np.isclose(dot_product, 1.0) or np.isclose(dot_product, -1.0):
|
@@ -207,7 +206,6 @@ class Vector(list):
|
|
207
206
|
else:
|
208
207
|
# Compute bisecting vector
|
209
208
|
bisecting_vector = (vector1_norm + vector2_norm) / np.linalg.norm(vector1_norm + vector2_norm)
|
210
|
-
|
211
209
|
return list(bisecting_vector)
|
212
210
|
|
213
211
|
@staticmethod
|
topologicpy/Vertex.py
CHANGED
@@ -1057,10 +1057,8 @@ class Vertex():
|
|
1057
1057
|
import inspect
|
1058
1058
|
|
1059
1059
|
if not Topology.IsInstance(vertex, "Vertex"):
|
1060
|
+
print("Called from:", inspect.stack()[1][3])
|
1060
1061
|
if not silent:
|
1061
|
-
stack = inspect.stack()
|
1062
|
-
if len(stack) > 2:
|
1063
|
-
print(stack[2].function)
|
1064
1062
|
print("Vertex.IsInternal - Error: The input vertex parameter is not a valid vertex. Returning None.", vertex, topology)
|
1065
1063
|
return None
|
1066
1064
|
if not Topology.IsInstance(topology, "Topology"):
|
@@ -1074,7 +1072,7 @@ class Vertex():
|
|
1074
1072
|
try:
|
1075
1073
|
parameter = Edge.ParameterAtVertex(topology, vertex)
|
1076
1074
|
except:
|
1077
|
-
parameter = 400 #
|
1075
|
+
parameter = 400 #arbitrary large number greater than 1
|
1078
1076
|
if parameter == None:
|
1079
1077
|
return False
|
1080
1078
|
return 0 <= parameter <= 1
|