topologicpy 0.7.50__py3-none-any.whl → 0.7.51__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/Color.py +1 -1
- topologicpy/Dictionary.py +0 -2
- topologicpy/Face.py +5 -3
- topologicpy/Plotly.py +35 -38
- topologicpy/Topology.py +689 -52
- topologicpy/Wire.py +22 -14
- topologicpy/version.py +1 -1
- {topologicpy-0.7.50.dist-info → topologicpy-0.7.51.dist-info}/METADATA +1 -1
- {topologicpy-0.7.50.dist-info → topologicpy-0.7.51.dist-info}/RECORD +12 -12
- {topologicpy-0.7.50.dist-info → topologicpy-0.7.51.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.50.dist-info → topologicpy-0.7.51.dist-info}/WHEEL +0 -0
- {topologicpy-0.7.50.dist-info → topologicpy-0.7.51.dist-info}/top_level.txt +0 -0
topologicpy/Color.py
CHANGED
@@ -371,7 +371,7 @@ class Color:
|
|
371
371
|
Parameters
|
372
372
|
----------
|
373
373
|
color : list
|
374
|
-
The input color list. This is assumed to be in the format [r, g, b] or [r, g, b, a]
|
374
|
+
The input color list. This is assumed to be in the format [r, g, b] or [r, g, b, a] where the range is from 0 to 255.
|
375
375
|
alpha : float , optional
|
376
376
|
The transparency value. 0.0 means the color is fully transparent, 1.0 means the color is fully opaque. The default is 1.0.
|
377
377
|
useAlpha : bool , optional
|
topologicpy/Dictionary.py
CHANGED
@@ -642,10 +642,8 @@ class Dictionary():
|
|
642
642
|
The value found at the input key in the input dictionary.
|
643
643
|
|
644
644
|
"""
|
645
|
-
import json
|
646
645
|
from topologicpy.Topology import Topology
|
647
646
|
|
648
|
-
|
649
647
|
if not Topology.IsInstance(dictionary, "Dictionary") and not isinstance(dictionary, dict):
|
650
648
|
print("Dictionary.ValueAtKey - Error: The input dictionary parameter is not a valid topologic or python dictionary. Returning None.")
|
651
649
|
return None
|
topologicpy/Face.py
CHANGED
@@ -2373,7 +2373,7 @@ class Face():
|
|
2373
2373
|
from topologicpy.Face import Face
|
2374
2374
|
|
2375
2375
|
if not Topology.IsInstance(face, "Face"):
|
2376
|
-
print("
|
2376
|
+
print("Face.Triangulate - Error: The input face parameter is not a valid face. Returning None.")
|
2377
2377
|
return None
|
2378
2378
|
if not meshSize:
|
2379
2379
|
bounding_face = Face.BoundingRectangle(face)
|
@@ -2477,9 +2477,11 @@ class Face():
|
|
2477
2477
|
wire = Face.ExternalBoundary(f)
|
2478
2478
|
wire = Wire.Invert(wire)
|
2479
2479
|
f = Face.ByWire(wire)
|
2480
|
-
|
2480
|
+
if Topology.IsInstance(f, "Face"):
|
2481
|
+
finalFaces.append(f)
|
2481
2482
|
else:
|
2482
|
-
|
2483
|
+
if Topology.IsInstance(f, "face"):
|
2484
|
+
finalFaces.append(f)
|
2483
2485
|
face_normal = Face.Normal(face)
|
2484
2486
|
return_faces = []
|
2485
2487
|
for ff in finalFaces:
|
topologicpy/Plotly.py
CHANGED
@@ -372,12 +372,11 @@ class Plotly:
|
|
372
372
|
v_label = ""
|
373
373
|
v_group = ""
|
374
374
|
d = Topology.Dictionary(v)
|
375
|
-
v_group = Dictionary.ValueAtKey(d, key=vertexGroupKey)
|
376
375
|
if d:
|
377
376
|
if vertexLabelKey:
|
378
377
|
v_label = str(Dictionary.ValueAtKey(d, key=vertexLabelKey)) or ""
|
379
378
|
if vertexGroupKey:
|
380
|
-
v_group = Dictionary.ValueAtKey(d, key=vertexGroupKey) or
|
379
|
+
v_group = Dictionary.ValueAtKey(d, key=vertexGroupKey) or ""
|
381
380
|
try:
|
382
381
|
v_groupList.append(vertexGroups.index(v_group))
|
383
382
|
except:
|
@@ -439,14 +438,10 @@ class Plotly:
|
|
439
438
|
e_group = ""
|
440
439
|
d = Topology.Dictionary(e)
|
441
440
|
if d:
|
442
|
-
|
441
|
+
if not edgeLabelKey == None:
|
443
442
|
e_label = str(Dictionary.ValueAtKey(d, key=edgeLabelKey)) or ""
|
444
|
-
|
445
|
-
e_label = ""
|
446
|
-
try:
|
443
|
+
if not edgeGroupKey == None:
|
447
444
|
e_group = str(Dictionary.ValueAtKey(d, key=edgeGroupKey)) or ""
|
448
|
-
except:
|
449
|
-
e_group = ""
|
450
445
|
try:
|
451
446
|
e_groupList.append(edgeGroups.index(e_group))
|
452
447
|
except:
|
@@ -490,12 +485,12 @@ class Plotly:
|
|
490
485
|
@staticmethod
|
491
486
|
def DataByTopology(topology,
|
492
487
|
showVertices=True, vertexSize=1.1, vertexColor="black",
|
493
|
-
vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
|
488
|
+
vertexLabelKey=None, showVertexLabel=False, vertexGroupKey=None, vertexGroups=[],
|
494
489
|
vertexMinGroup=None, vertexMaxGroup=None,
|
495
490
|
showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
|
496
491
|
vertexLegendGroup=1,
|
497
492
|
showEdges=True, edgeWidth=1, edgeColor="black",
|
498
|
-
edgeLabelKey=None, edgeGroupKey=None, edgeGroups=[],
|
493
|
+
edgeLabelKey=None, showEdgeLabel=False, edgeGroupKey=None, edgeGroups=[],
|
499
494
|
edgeMinGroup=None, edgeMaxGroup=None,
|
500
495
|
showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
|
501
496
|
edgeLegendGroup=2,
|
@@ -633,7 +628,7 @@ class Plotly:
|
|
633
628
|
def closest_index(input_value, values):
|
634
629
|
return int(min(range(len(values)), key=lambda i: abs(values[i] - input_value)))
|
635
630
|
|
636
|
-
def vertexData(vertices, dictionaries=[], color="black", size=1.1, labelKey=None, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Vertices", legendGroup=1, legendRank=1, showLegend=True, colorScale="Viridis"):
|
631
|
+
def vertexData(vertices, dictionaries=[], color="black", size=1.1, labelKey=None, showVertexLabel = False, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Vertices", legendGroup=1, legendRank=1, showLegend=True, colorScale="Viridis"):
|
637
632
|
x = []
|
638
633
|
y = []
|
639
634
|
z = []
|
@@ -664,16 +659,14 @@ class Plotly:
|
|
664
659
|
if len(dictionaries) > 0:
|
665
660
|
d = dictionaries[m]
|
666
661
|
if d:
|
667
|
-
|
662
|
+
if not labelKey == None:
|
668
663
|
label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
|
669
|
-
|
670
|
-
|
671
|
-
try:
|
672
|
-
group = Dictionary.ValueAtKey(d, key=groupKey) or None
|
673
|
-
except:
|
674
|
-
group = ""
|
664
|
+
if not groupKey == None:
|
665
|
+
group = Dictionary.ValueAtKey(d, key=groupKey) or ""
|
675
666
|
try:
|
676
|
-
if
|
667
|
+
if group == "":
|
668
|
+
color = 'white'
|
669
|
+
elif type(group) == int or type(group) == float:
|
677
670
|
if group < minGroup:
|
678
671
|
group = minGroup
|
679
672
|
if group > maxGroup:
|
@@ -696,13 +689,17 @@ class Plotly:
|
|
696
689
|
groupList = color
|
697
690
|
if len(labels) < 1:
|
698
691
|
labels = ""
|
692
|
+
if showVertexLabel == True:
|
693
|
+
mode = "markers+text"
|
694
|
+
else:
|
695
|
+
mode = "markers"
|
699
696
|
vData= go.Scatter3d(x=x,
|
700
697
|
y=y,
|
701
698
|
z=z,
|
702
699
|
name=legendLabel,
|
703
700
|
showlegend=showLegend,
|
704
701
|
marker=dict(color=groupList, size=vertexSize),
|
705
|
-
mode=
|
702
|
+
mode=mode,
|
706
703
|
legendgroup=legendGroup,
|
707
704
|
legendrank=legendRank,
|
708
705
|
text=labels,
|
@@ -711,7 +708,7 @@ class Plotly:
|
|
711
708
|
)
|
712
709
|
return vData
|
713
710
|
|
714
|
-
def edgeData(vertices, edges, dictionaries=None, color="black", width=1, labelKey=None, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Edges", legendGroup=2, legendRank=2, showLegend=True, colorScale="Viridis"):
|
711
|
+
def edgeData(vertices, edges, dictionaries=None, color="black", width=1, labelKey=None, showEdgeLabel = False, groupKey=None, minGroup=None, maxGroup=None, groups=[], legendLabel="Topology Edges", legendGroup=2, legendRank=2, showLegend=True, colorScale="Viridis"):
|
715
712
|
x = []
|
716
713
|
y = []
|
717
714
|
z = []
|
@@ -744,15 +741,13 @@ class Plotly:
|
|
744
741
|
if len(dictionaries) > 0:
|
745
742
|
d = dictionaries[m]
|
746
743
|
if d:
|
747
|
-
|
744
|
+
if not labelKey == None:
|
748
745
|
label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
|
749
|
-
|
750
|
-
|
751
|
-
try:
|
752
|
-
group = Dictionary.ValueAtKey(d, key=groupKey) or None
|
753
|
-
except:
|
754
|
-
group = ""
|
746
|
+
if not groupKey == None:
|
747
|
+
group = Dictionary.ValueAtKey(d, key=groupKey) or ""
|
755
748
|
try:
|
749
|
+
if group == "":
|
750
|
+
color = 'white'
|
756
751
|
if type(group) == int or type(group) == float:
|
757
752
|
if group < minGroup:
|
758
753
|
group = minGroup
|
@@ -778,13 +773,17 @@ class Plotly:
|
|
778
773
|
groupList = color
|
779
774
|
if len(labels) < 1:
|
780
775
|
labels = ""
|
776
|
+
if showEdgeLabel == True:
|
777
|
+
mode = "lines+text"
|
778
|
+
else:
|
779
|
+
mode = "lines"
|
781
780
|
eData = go.Scatter3d(x=x,
|
782
781
|
y=y,
|
783
782
|
z=z,
|
784
783
|
name=legendLabel,
|
785
784
|
showlegend=showLegend,
|
786
785
|
marker_size=0,
|
787
|
-
mode=
|
786
|
+
mode=mode,
|
788
787
|
line=dict(color=groupList, width=edgeWidth),
|
789
788
|
legendgroup=legendGroup,
|
790
789
|
legendrank=legendRank,
|
@@ -834,16 +833,14 @@ class Plotly:
|
|
834
833
|
if len(dictionaries) > 0:
|
835
834
|
d = dictionaries[m]
|
836
835
|
if d:
|
837
|
-
|
836
|
+
if not labelKey == None:
|
838
837
|
label = str(Dictionary.ValueAtKey(d, key=labelKey)) or ""
|
839
|
-
|
840
|
-
label = ""
|
841
|
-
try:
|
838
|
+
if not groupKey == None:
|
842
839
|
group = Dictionary.ValueAtKey(d, key=groupKey) or None
|
843
|
-
except:
|
844
|
-
group = ""
|
845
840
|
try:
|
846
|
-
if
|
841
|
+
if group == "":
|
842
|
+
color = 'white'
|
843
|
+
elif type(group) == int or type(group) == float:
|
847
844
|
if group < minGroup:
|
848
845
|
group = minGroup
|
849
846
|
if group > maxGroup:
|
@@ -955,7 +952,7 @@ class Plotly:
|
|
955
952
|
d = Topology.Dictionary(tp_v)
|
956
953
|
v_dictionaries.append(d)
|
957
954
|
vertices.append([Vertex.X(tp_v, mantissa=mantissa), Vertex.Y(tp_v, mantissa=mantissa), Vertex.Z(tp_v, mantissa=mantissa)])
|
958
|
-
data.append(vertexData(vertices, dictionaries=v_dictionaries, color=vertexColor, size=vertexSize, labelKey=vertexLabelKey, groupKey=vertexGroupKey, minGroup=vertexMinGroup, maxGroup=vertexMaxGroup, groups=vertexGroups, legendLabel=vertexLegendLabel, legendGroup=vertexLegendGroup, legendRank=vertexLegendRank, showLegend=showVertexLegend, colorScale=colorScale))
|
955
|
+
data.append(vertexData(vertices, dictionaries=v_dictionaries, color=vertexColor, size=vertexSize, labelKey=vertexLabelKey, showVertexLabel=showVertexLabel, groupKey=vertexGroupKey, minGroup=vertexMinGroup, maxGroup=vertexMaxGroup, groups=vertexGroups, legendLabel=vertexLegendLabel, legendGroup=vertexLegendGroup, legendRank=vertexLegendRank, showLegend=showVertexLegend, colorScale=colorScale))
|
959
956
|
|
960
957
|
if showEdges and Topology.Type(topology) > Topology.TypeID("Vertex"):
|
961
958
|
if Topology.Type(topology) == Topology.TypeID("Edge"):
|
@@ -971,7 +968,7 @@ class Plotly:
|
|
971
968
|
geo = Topology.Geometry(e_cluster, mantissa=mantissa)
|
972
969
|
vertices = geo['vertices']
|
973
970
|
edges = geo['edges']
|
974
|
-
data.append(edgeData(vertices, edges, dictionaries=e_dictionaries, color=edgeColor, width=edgeWidth, labelKey=edgeLabelKey, groupKey=edgeGroupKey, minGroup=edgeMinGroup, maxGroup=edgeMaxGroup, groups=edgeGroups, legendLabel=edgeLegendLabel, legendGroup=edgeLegendGroup, legendRank=edgeLegendRank, showLegend=showEdgeLegend, colorScale=colorScale))
|
971
|
+
data.append(edgeData(vertices, edges, dictionaries=e_dictionaries, color=edgeColor, width=edgeWidth, labelKey=edgeLabelKey, showEdgeLabel=showEdgeLabel, groupKey=edgeGroupKey, minGroup=edgeMinGroup, maxGroup=edgeMaxGroup, groups=edgeGroups, legendLabel=edgeLegendLabel, legendGroup=edgeLegendGroup, legendRank=edgeLegendRank, showLegend=showEdgeLegend, colorScale=colorScale))
|
975
972
|
|
976
973
|
if showFaces and Topology.Type(topology) >= Topology.TypeID("Face"):
|
977
974
|
if Topology.IsInstance(topology, "Face"):
|
topologicpy/Topology.py
CHANGED
@@ -1477,8 +1477,144 @@ class Topology():
|
|
1477
1477
|
st = None
|
1478
1478
|
return st
|
1479
1479
|
|
1480
|
+
|
1480
1481
|
@staticmethod
|
1481
|
-
def ByGeometry(vertices=[], edges=[], faces=[],
|
1482
|
+
def ByGeometry(vertices=[], edges=[], faces=[], topologyType = None, tolerance=0.0001):
|
1483
|
+
"""
|
1484
|
+
Create a topology by the input lists of vertices, edges, and faces.
|
1485
|
+
|
1486
|
+
Parameters
|
1487
|
+
----------
|
1488
|
+
vertices : list
|
1489
|
+
The input list of vertices in the form of [x, y, z]
|
1490
|
+
edges : list , optional
|
1491
|
+
The input list of edges in the form of [i, j] where i and j are vertex indices.
|
1492
|
+
faces : list , optional
|
1493
|
+
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.
|
1494
|
+
topologyType : str , optional
|
1495
|
+
The desired topology type. The options are: "Vertex", "Edge", "Wire", "Face", "Shell", "Cell", "CellComplex". If set to None, a "Cluster" will be returned. The default is None.
|
1496
|
+
tolerance : float , optional
|
1497
|
+
The desired tolerance. The default is 0.0001.
|
1498
|
+
|
1499
|
+
Returns
|
1500
|
+
-------
|
1501
|
+
topology : topologic_core.Topology
|
1502
|
+
The created topology. The topology will have a dictionary embedded in it that records the input attributes (color, id, lengthUnit, name, type)
|
1503
|
+
|
1504
|
+
"""
|
1505
|
+
from topologicpy.Vertex import Vertex
|
1506
|
+
from topologicpy.Edge import Edge
|
1507
|
+
from topologicpy.Wire import Wire
|
1508
|
+
from topologicpy.Face import Face
|
1509
|
+
from topologicpy.Shell import Shell
|
1510
|
+
from topologicpy.Cell import Cell
|
1511
|
+
from topologicpy.CellComplex import CellComplex
|
1512
|
+
from topologicpy.Cluster import Cluster
|
1513
|
+
|
1514
|
+
def topologyByFaces(faces, topologyType, tolerance):
|
1515
|
+
if len(faces) == 1:
|
1516
|
+
return faces[0]
|
1517
|
+
|
1518
|
+
output = None
|
1519
|
+
if topologyType == "cell":
|
1520
|
+
c = Cell.ByFaces(faces, tolerance=tolerance)
|
1521
|
+
if Topology.IsInstance(c, "Cell"):
|
1522
|
+
output = c
|
1523
|
+
else:
|
1524
|
+
cc = CellComplex.ByFaces(faces, tolerance=tolerance)
|
1525
|
+
if Topology.IsInstance(cc, "CellComplex"):
|
1526
|
+
output = CellComplex.ExternalBoundary(cc)
|
1527
|
+
elif topologyType == "cellcomplex":
|
1528
|
+
output = CellComplex.ByFaces(faces, tolerance=tolerance)
|
1529
|
+
if Topology.IsInstance(output, "CellComplex"):
|
1530
|
+
cells = Topology.Cells(output)
|
1531
|
+
if len(cells) == 1:
|
1532
|
+
output = cells[0]
|
1533
|
+
else:
|
1534
|
+
output = Cluster.ByTopologies(faces)
|
1535
|
+
elif topologyType == "shell":
|
1536
|
+
output = Shell.ByFaces(faces, tolerance=tolerance) # This can return a list
|
1537
|
+
if Topology.IsInstance(output, "Shell"):
|
1538
|
+
return output
|
1539
|
+
elif topologyType == None:
|
1540
|
+
output = Cluster.ByTopologies(faces)
|
1541
|
+
|
1542
|
+
return output
|
1543
|
+
|
1544
|
+
def topologyByEdges(edges, topologyType):
|
1545
|
+
if len(edges) == 1:
|
1546
|
+
return edges[0]
|
1547
|
+
|
1548
|
+
output = Cluster.ByTopologies(edges)
|
1549
|
+
if topologyType.lower() == "wire":
|
1550
|
+
output = Topology.SelfMerge(output, tolerance=tolerance)
|
1551
|
+
if Topology.IsInstance(output, "Wire"):
|
1552
|
+
return output
|
1553
|
+
return None
|
1554
|
+
return output
|
1555
|
+
|
1556
|
+
vertices = [v for v in vertices if v]
|
1557
|
+
edges = [e for e in edges if e]
|
1558
|
+
faces = [f for f in faces if f]
|
1559
|
+
|
1560
|
+
if not vertices:
|
1561
|
+
return None
|
1562
|
+
|
1563
|
+
topVerts = [Vertex.ByCoordinates(v[0], v[1], v[2]) for v in vertices]
|
1564
|
+
topEdges = []
|
1565
|
+
topFaces = []
|
1566
|
+
|
1567
|
+
if not topologyType == None:
|
1568
|
+
topologyType = topologyType.lower()
|
1569
|
+
|
1570
|
+
if topologyType == "vertex":
|
1571
|
+
if len(topVerts) >= 1:
|
1572
|
+
return topVerts[0]
|
1573
|
+
else:
|
1574
|
+
return None
|
1575
|
+
elif topologyType == "edge":
|
1576
|
+
if len(edges) >= 1 and len(vertices) >= 2:
|
1577
|
+
return Edge.ByVertices(topVerts[edges[0][0]], topVerts[edges[0][1]], tolerance=tolerance)
|
1578
|
+
else:
|
1579
|
+
return None
|
1580
|
+
|
1581
|
+
if topologyType == "wire" and edges:
|
1582
|
+
topEdges = [Edge.ByVertices([topVerts[e[0]], topVerts[e[1]]], tolerance=tolerance) for e in edges]
|
1583
|
+
if topEdges:
|
1584
|
+
returnTopology = topologyByEdges(topEdges, topologyType)
|
1585
|
+
elif faces:
|
1586
|
+
for aFace in faces:
|
1587
|
+
faceEdges = [Edge.ByVertices([topVerts[aFace[i]], topVerts[aFace[i + 1]]], tolerance=tolerance) for i in range(len(aFace) - 1)]
|
1588
|
+
# Connect the last vertex to the first one
|
1589
|
+
faceEdges.append(Edge.ByVertices([topVerts[aFace[-1]], topVerts[aFace[0]]], tolerance=tolerance))
|
1590
|
+
|
1591
|
+
if len(faceEdges) > 2:
|
1592
|
+
faceWire = Wire.ByEdges(faceEdges, tolerance=tolerance)
|
1593
|
+
try:
|
1594
|
+
topFace = Face.ByWire(faceWire, tolerance=tolerance, silent=True)
|
1595
|
+
if Topology.IsInstance(topFace, "Face"):
|
1596
|
+
topFaces.append(topFace)
|
1597
|
+
elif isinstance(topFace, list):
|
1598
|
+
topFaces.extend(topFace)
|
1599
|
+
except:
|
1600
|
+
pass
|
1601
|
+
if topFaces:
|
1602
|
+
returnTopology = topologyByFaces(topFaces, topologyType=topologyType, tolerance=tolerance)
|
1603
|
+
elif edges:
|
1604
|
+
topEdges = [Edge.ByVertices([topVerts[e[0]], topVerts[e[1]]], tolerance=tolerance) for e in edges]
|
1605
|
+
if topEdges:
|
1606
|
+
returnTopology = topologyByEdges(topEdges, topologyType)
|
1607
|
+
else:
|
1608
|
+
returnTopology = Cluster.ByTopologies(topVerts)
|
1609
|
+
return returnTopology
|
1610
|
+
|
1611
|
+
|
1612
|
+
|
1613
|
+
|
1614
|
+
|
1615
|
+
|
1616
|
+
@staticmethod
|
1617
|
+
def ByGeometry_old(vertices=[], edges=[], faces=[], color=[1.0, 1.0, 1.0, 1.0], id=None, name=None, lengthUnit="METERS", outputMode="default", tolerance=0.0001):
|
1482
1618
|
"""
|
1483
1619
|
Create a topology by the input lists of vertices, edges, and faces.
|
1484
1620
|
|
@@ -2201,7 +2337,215 @@ class Topology():
|
|
2201
2337
|
return Topology.ByDXFFile(file, sides=sides)
|
2202
2338
|
|
2203
2339
|
@staticmethod
|
2204
|
-
def ByIFCFile(file, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False):
|
2340
|
+
def ByIFCFile(file, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False, epsilon=0.0001, tolerance=0.0001):
|
2341
|
+
"""
|
2342
|
+
Create a list of topologies by importing them from an IFC file.
|
2343
|
+
|
2344
|
+
Parameters
|
2345
|
+
----------
|
2346
|
+
file : file object
|
2347
|
+
The input IFC file.
|
2348
|
+
includeTypes : list , optional
|
2349
|
+
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 [].
|
2350
|
+
excludeTypes : list , optional
|
2351
|
+
The list of IFC object types to exclude. It is case insensitive. If set to an empty list, no types are excluded. The default is [].
|
2352
|
+
transferDictionaries : bool , optional
|
2353
|
+
If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
|
2354
|
+
removeCoplanarFaces : bool , optional
|
2355
|
+
If set to True, coplanar faces are removed. Otherwise they are not. The default is False.
|
2356
|
+
epsilon : float , optional
|
2357
|
+
The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.0001.
|
2358
|
+
tolerance : float , optional
|
2359
|
+
The desired tolerance. The default is 0.0001.
|
2360
|
+
Returns
|
2361
|
+
-------
|
2362
|
+
list
|
2363
|
+
The created list of topologies.
|
2364
|
+
|
2365
|
+
"""
|
2366
|
+
|
2367
|
+
import ifcopenshell
|
2368
|
+
from topologicpy.Dictionary import Dictionary
|
2369
|
+
|
2370
|
+
def get_psets(entity):
|
2371
|
+
# Initialize the PSET dictionary for this entity
|
2372
|
+
psets = {}
|
2373
|
+
|
2374
|
+
# Check if the entity has a GlobalId
|
2375
|
+
if not hasattr(entity, 'GlobalId'):
|
2376
|
+
raise ValueError("The provided entity does not have a GlobalId.")
|
2377
|
+
|
2378
|
+
# Get the property sets related to this entity
|
2379
|
+
for definition in entity.IsDefinedBy:
|
2380
|
+
if definition.is_a('IfcRelDefinesByProperties'):
|
2381
|
+
property_set = definition.RelatingPropertyDefinition
|
2382
|
+
|
2383
|
+
# Check if it is a property set
|
2384
|
+
if property_set.is_a('IfcPropertySet'):
|
2385
|
+
pset_name = "IFC_"+property_set.Name
|
2386
|
+
|
2387
|
+
# Dictionary to hold individual properties
|
2388
|
+
properties = {}
|
2389
|
+
|
2390
|
+
# Iterate over the properties in the PSET
|
2391
|
+
for prop in property_set.HasProperties:
|
2392
|
+
if prop.is_a('IfcPropertySingleValue'):
|
2393
|
+
# Get the property name and value
|
2394
|
+
prop_name = "IFC_"+prop.Name
|
2395
|
+
prop_value = prop.NominalValue.wrappedValue if prop.NominalValue else None
|
2396
|
+
properties[prop_name] = prop_value
|
2397
|
+
|
2398
|
+
# Add this PSET to the dictionary for this entity
|
2399
|
+
psets[pset_name] = properties
|
2400
|
+
return psets
|
2401
|
+
|
2402
|
+
def get_color_transparency_material(entity):
|
2403
|
+
import random
|
2404
|
+
|
2405
|
+
# Set default Material Name and ID
|
2406
|
+
material_list = []
|
2407
|
+
# Set default transparency based on entity type or material
|
2408
|
+
default_transparency = 0.0
|
2409
|
+
|
2410
|
+
# Check if the entity is an opening or made of glass
|
2411
|
+
is_a = entity.is_a().lower()
|
2412
|
+
if "opening" in is_a or "window" in is_a or "door" in is_a or "space" in is_a:
|
2413
|
+
default_transparency = 0.7
|
2414
|
+
elif "space" in is_a:
|
2415
|
+
default_transparency = 0.8
|
2416
|
+
|
2417
|
+
# Check if the entity has constituent materials (e.g., glass)
|
2418
|
+
else:
|
2419
|
+
# Check for associated materials (ConstituentMaterial or direct material assignment)
|
2420
|
+
materials_checked = False
|
2421
|
+
if hasattr(entity, 'HasAssociations'):
|
2422
|
+
for rel in entity.HasAssociations:
|
2423
|
+
if rel.is_a('IfcRelAssociatesMaterial'):
|
2424
|
+
material = rel.RelatingMaterial
|
2425
|
+
if material.is_a('IfcMaterial') and 'glass' in material.Name.lower():
|
2426
|
+
default_transparency = 0.5
|
2427
|
+
materials_checked = True
|
2428
|
+
elif material.is_a('IfcMaterialLayerSetUsage'):
|
2429
|
+
material_layers = material.ForLayerSet.MaterialLayers
|
2430
|
+
for layer in material_layers:
|
2431
|
+
material_list.append(layer.Material.Name)
|
2432
|
+
if 'glass' in layer.Material.Name.lower():
|
2433
|
+
default_transparency = 0.5
|
2434
|
+
materials_checked = True
|
2435
|
+
|
2436
|
+
# Check for ConstituentMaterial if available
|
2437
|
+
if hasattr(entity, 'HasAssociations') and not materials_checked:
|
2438
|
+
for rel in entity.HasAssociations:
|
2439
|
+
if rel.is_a('IfcRelAssociatesMaterial'):
|
2440
|
+
material = rel.RelatingMaterial
|
2441
|
+
if material.is_a('IfcMaterialConstituentSet'):
|
2442
|
+
for constituent in material.MaterialConstituents:
|
2443
|
+
material_list.append(constituent.Material.Name)
|
2444
|
+
if 'glass' in constituent.Material.Name.lower():
|
2445
|
+
default_transparency = 0.5
|
2446
|
+
materials_checked = True
|
2447
|
+
|
2448
|
+
# Check if the entity has ShapeAspects with associated materials or styles
|
2449
|
+
if hasattr(entity, 'HasShapeAspects') and not materials_checked:
|
2450
|
+
for shape_aspect in entity.HasShapeAspects:
|
2451
|
+
if hasattr(shape_aspect, 'StyledByItem') and shape_aspect.StyledByItem:
|
2452
|
+
for styled_item in shape_aspect.StyledByItem:
|
2453
|
+
for style in styled_item.Styles:
|
2454
|
+
if style.is_a('IfcSurfaceStyle'):
|
2455
|
+
for surface_style in style.Styles:
|
2456
|
+
if surface_style.is_a('IfcSurfaceStyleRendering'):
|
2457
|
+
transparency = getattr(surface_style, 'Transparency', default_transparency)
|
2458
|
+
if transparency > 0:
|
2459
|
+
default_transparency = transparency
|
2460
|
+
|
2461
|
+
# Try to get the actual color and transparency if defined
|
2462
|
+
if hasattr(entity, 'Representation') and entity.Representation:
|
2463
|
+
for rep in entity.Representation.Representations:
|
2464
|
+
for item in rep.Items:
|
2465
|
+
if hasattr(item, 'StyledByItem') and item.StyledByItem:
|
2466
|
+
for styled_item in item.StyledByItem:
|
2467
|
+
if hasattr(styled_item, 'Styles'):
|
2468
|
+
for style in styled_item.Styles:
|
2469
|
+
if style.is_a('IfcSurfaceStyle'):
|
2470
|
+
for surface_style in style.Styles:
|
2471
|
+
if surface_style.is_a('IfcSurfaceStyleRendering'):
|
2472
|
+
color = surface_style.SurfaceColour
|
2473
|
+
transparency = getattr(surface_style, 'Transparency', default_transparency)
|
2474
|
+
return (color.Red*255, color.Green*255, color.Blue*255), transparency, material_list
|
2475
|
+
|
2476
|
+
# If no color is defined, return a consistent random color based on the entity type
|
2477
|
+
if "wall" in is_a:
|
2478
|
+
color = (0.4, 0.4, 0.4)
|
2479
|
+
elif "slab" in is_a:
|
2480
|
+
color = (0.6, 0.6, 0.6)
|
2481
|
+
elif "space" in is_a:
|
2482
|
+
color = (250, 250, 250)
|
2483
|
+
else:
|
2484
|
+
random.seed(hash(is_a))
|
2485
|
+
color = (random.random(), random.random(), random.random())
|
2486
|
+
|
2487
|
+
return color, default_transparency, material_list
|
2488
|
+
|
2489
|
+
def convert_to_topology(entity, settings):
|
2490
|
+
if hasattr(entity, "Representation") and entity.Representation:
|
2491
|
+
for rep in entity.Representation.Representations:
|
2492
|
+
if rep.is_a("IfcShapeRepresentation"):
|
2493
|
+
# Generate the geometry for this entity
|
2494
|
+
shape = ifcopenshell.geom.create_shape(settings, entity)
|
2495
|
+
shape_geometry = shape.geometry
|
2496
|
+
verts = shape_geometry.verts
|
2497
|
+
verts = [ [verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
|
2498
|
+
edges = shape_geometry.edges
|
2499
|
+
edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
|
2500
|
+
faces = shape_geometry.faces
|
2501
|
+
faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
|
2502
|
+
# Convert geometry to Topologic format
|
2503
|
+
#shape_topology = ifc_to_topologic_geometry(verts, edges, faces)
|
2504
|
+
#shape_topology = Topology.SelfMerge(Topology.ByGeometry(verts, edges, faces))
|
2505
|
+
shape_topology = Topology.ByGeometry(verts, edges, faces, topologyType="CellComplex")
|
2506
|
+
if removeCoplanarFaces == True:
|
2507
|
+
shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
|
2508
|
+
|
2509
|
+
# Store relevant information
|
2510
|
+
color, transparency, material_list = get_color_transparency_material(entity)
|
2511
|
+
entity_dict = {
|
2512
|
+
"TOPOLOGIC_id": str(Topology.UUID(shape_topology)),
|
2513
|
+
"TOPOLOGIC_name": getattr(entity, 'Name', "Untitled"),
|
2514
|
+
"TOPOLOGIC_type": Topology.TypeAsString(shape_topology),
|
2515
|
+
"TOPOLOGIC_color": color,
|
2516
|
+
"TOPOLOGIC_opacity": 1.0 - transparency,
|
2517
|
+
"IFC_global_id": getattr(entity, 'GlobalId', 0),
|
2518
|
+
"IFC_name": getattr(entity, 'Name', "Untitled"),
|
2519
|
+
"IFC_type": entity.is_a(),
|
2520
|
+
"IFC_material_list": material_list,
|
2521
|
+
}
|
2522
|
+
topology_dict = Dictionary.ByPythonDictionary(entity_dict)
|
2523
|
+
# Get PSETs dictionary
|
2524
|
+
pset_python_dict = get_psets(entity)
|
2525
|
+
pset_dict = Dictionary.ByPythonDictionary(pset_python_dict)
|
2526
|
+
topology_dict = Dictionary.ByMergedDictionaries([topology_dict, pset_dict])
|
2527
|
+
shape_topology = Topology.SetDictionary(shape_topology, topology_dict)
|
2528
|
+
return shape_topology
|
2529
|
+
return None
|
2530
|
+
|
2531
|
+
# Main Code
|
2532
|
+
topologies = []
|
2533
|
+
settings = ifcopenshell.geom.settings()
|
2534
|
+
settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.SOLID)
|
2535
|
+
settings.set(settings.USE_WORLD_COORDS, True)
|
2536
|
+
products = file.by_type("IfcProduct")
|
2537
|
+
entities = []
|
2538
|
+
for product in products:
|
2539
|
+
is_a = product.is_a()
|
2540
|
+
if (is_a in includeTypes or len(includeTypes) == 0) and (not is_a in excludeTypes):
|
2541
|
+
entities.append(product)
|
2542
|
+
topologies = []
|
2543
|
+
for entity in entities:
|
2544
|
+
topologies.append(convert_to_topology(entity, settings))
|
2545
|
+
return topologies
|
2546
|
+
|
2547
|
+
@staticmethod
|
2548
|
+
def _ByIFCFile_old(file, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False):
|
2205
2549
|
"""
|
2206
2550
|
Create a topology by importing it from an IFC file.
|
2207
2551
|
|
@@ -2229,7 +2573,9 @@ class Topology():
|
|
2229
2573
|
import uuid
|
2230
2574
|
import random
|
2231
2575
|
import hashlib
|
2232
|
-
|
2576
|
+
import re
|
2577
|
+
import numpy as np
|
2578
|
+
|
2233
2579
|
try:
|
2234
2580
|
import ifcopenshell
|
2235
2581
|
import ifcopenshell.geom
|
@@ -2250,6 +2596,148 @@ class Topology():
|
|
2250
2596
|
print("Topology.ByIFCFile - Error: the input file parameter is not a valid file. Returning None.")
|
2251
2597
|
return None
|
2252
2598
|
|
2599
|
+
def clean_key(string):
|
2600
|
+
# Replace any character that is not a letter, digit, or underscore with an underscore
|
2601
|
+
cleaned_string = re.sub(r'[^a-zA-Z0-9_]', '_', string)
|
2602
|
+
return cleaned_string
|
2603
|
+
|
2604
|
+
def transform_wall_vertices(wall):
|
2605
|
+
|
2606
|
+
# Relatives Placement abrufen und ausgeben
|
2607
|
+
if wall.ObjectPlacement and wall.ObjectPlacement.RelativePlacement:
|
2608
|
+
relative_placement = wall.ObjectPlacement.RelativePlacement
|
2609
|
+
if relative_placement.is_a('IFCAXIS2PLACEMENT3D'):
|
2610
|
+
location = relative_placement.Location
|
2611
|
+
ref_direction = relative_placement.RefDirection
|
2612
|
+
print("Relative Placement Location:", location.Coordinates)
|
2613
|
+
if ref_direction:
|
2614
|
+
print("Relative Placement RefDirection:", ref_direction.DirectionRatios)
|
2615
|
+
else:
|
2616
|
+
print("Relative Placement RefDirection: None")
|
2617
|
+
|
2618
|
+
# IFCPRODUCTDEFINITIONSHAPE der Wand abrufen
|
2619
|
+
product_definition_shape = wall.Representation
|
2620
|
+
if not product_definition_shape:
|
2621
|
+
print("Keine Repräsentation gefunden.")
|
2622
|
+
return
|
2623
|
+
|
2624
|
+
# Initialisieren von Variablen für Representation Type und Layer-Infos
|
2625
|
+
representation_type = None
|
2626
|
+
diverse_representation = False
|
2627
|
+
layer_details = []
|
2628
|
+
|
2629
|
+
if hasattr(product_definition_shape, 'HasShapeAspects'):
|
2630
|
+
for aspect in product_definition_shape.HasShapeAspects:
|
2631
|
+
for representation in aspect.ShapeRepresentations:
|
2632
|
+
if representation.is_a('IFCSHAPEREPRESENTATION'):
|
2633
|
+
for item in representation.Items:
|
2634
|
+
if item.is_a('IFCEXTRUDEDAREASOLID'):
|
2635
|
+
# Profilbeschreibung abrufen
|
2636
|
+
profile = item.SweptArea
|
2637
|
+
if profile.is_a('IFCARBITRARYCLOSEDPROFILEDEF'):
|
2638
|
+
if not representation_type:
|
2639
|
+
representation_type = "ArbitraryClosedProfil"
|
2640
|
+
elif representation_type != "ArbitraryClosedProfil":
|
2641
|
+
diverse_representation = True
|
2642
|
+
|
2643
|
+
# Profilpunkte abrufen
|
2644
|
+
if hasattr(profile, 'OuterCurve') and profile.OuterCurve.is_a('IFCINDEXEDPOLYCURVE'):
|
2645
|
+
indexed_polycurve = profile.OuterCurve
|
2646
|
+
if hasattr(indexed_polycurve, 'Points') and indexed_polycurve.Points.is_a('IFCCARTESIANPOINTLIST2D'):
|
2647
|
+
point_list_2d = indexed_polycurve.Points
|
2648
|
+
points = point_list_2d.CoordList
|
2649
|
+
layer_info["Profilpunkte"] = points
|
2650
|
+
else:
|
2651
|
+
diverse_representation = True
|
2652
|
+
|
2653
|
+
# Location und RefDirection abrufen
|
2654
|
+
if item.Position.is_a('IFCAXIS2PLACEMENT3D'):
|
2655
|
+
axis_placement = item.Position
|
2656
|
+
location = axis_placement.Location
|
2657
|
+
ref_direction = axis_placement.RefDirection
|
2658
|
+
layer_info["Location"] = location.Coordinates
|
2659
|
+
if ref_direction:
|
2660
|
+
layer_info["RefDirection"] = ref_direction.DirectionRatios
|
2661
|
+
else:
|
2662
|
+
layer_info["RefDirection"] = None
|
2663
|
+
|
2664
|
+
layer_details.append(layer_info)
|
2665
|
+
|
2666
|
+
# Representation Type ausgeben
|
2667
|
+
if diverse_representation:
|
2668
|
+
representation_type = "divers"
|
2669
|
+
print("Representation Type der Wand:", representation_type)
|
2670
|
+
|
2671
|
+
# Layer-Details ausgeben
|
2672
|
+
for index, layer in enumerate(layer_details):
|
2673
|
+
print(f"\nLayer {index + 1} Details:")
|
2674
|
+
print("Material:", layer.get("Material", "Nicht verfügbar"))
|
2675
|
+
print("Extrusionsstärke:", layer.get("Extrusionsstärke", "Nicht verfügbar"))
|
2676
|
+
print("Profilpunkte:", layer.get("Profilpunkte", "Nicht verfügbar"))
|
2677
|
+
print("Location:", layer.get("Location", "Nicht verfügbar"))
|
2678
|
+
print("RefDirection:", layer.get("RefDirection", "Nicht verfügbar"))
|
2679
|
+
|
2680
|
+
|
2681
|
+
|
2682
|
+
|
2683
|
+
|
2684
|
+
|
2685
|
+
def extract_matrix_from_placement(placement):
|
2686
|
+
"""Constructs a transformation matrix from an IFC Local Placement."""
|
2687
|
+
# Initialize identity matrix
|
2688
|
+
matrix = np.identity(4)
|
2689
|
+
|
2690
|
+
# Check if the placement is IfcLocalPlacement
|
2691
|
+
if placement.is_a("IfcLocalPlacement"):
|
2692
|
+
relative_placement = placement.RelativePlacement
|
2693
|
+
|
2694
|
+
if relative_placement.is_a("IfcAxis2Placement3D"):
|
2695
|
+
location = relative_placement.Location.Coordinates
|
2696
|
+
z_dir = relative_placement.Axis.DirectionRatios if relative_placement.Axis else [0, 0, 1]
|
2697
|
+
x_dir = relative_placement.RefDirection.DirectionRatios if relative_placement.RefDirection else [1, 0, 0]
|
2698
|
+
|
2699
|
+
# Compute y direction (cross product of z and x)
|
2700
|
+
y_dir = np.cross(z_dir, x_dir)
|
2701
|
+
|
2702
|
+
# Construct the rotation matrix
|
2703
|
+
rotation_matrix = np.array([
|
2704
|
+
[x_dir[0], y_dir[0], z_dir[0], 0],
|
2705
|
+
[x_dir[1], y_dir[1], z_dir[1], 0],
|
2706
|
+
[x_dir[2], y_dir[2], z_dir[2], 0],
|
2707
|
+
[0, 0, 0, 1]
|
2708
|
+
])
|
2709
|
+
|
2710
|
+
# Translation vector
|
2711
|
+
translation_vector = np.array([
|
2712
|
+
[1, 0, 0, location[0]],
|
2713
|
+
[0, 1, 0, location[1]],
|
2714
|
+
[0, 0, 1, location[2]],
|
2715
|
+
[0, 0, 0, 1]
|
2716
|
+
])
|
2717
|
+
|
2718
|
+
# Combine the rotation matrix and the translation vector
|
2719
|
+
matrix = np.dot(translation_vector, rotation_matrix)
|
2720
|
+
|
2721
|
+
return matrix
|
2722
|
+
|
2723
|
+
def apply_transformation(verts, matrix):
|
2724
|
+
"""Applies a 4x4 transformation matrix to a list of vertices."""
|
2725
|
+
transformed_verts = []
|
2726
|
+
for vert in verts:
|
2727
|
+
print("vert:", vert)
|
2728
|
+
v = np.array([vert[0], vert[1], vert[2], 1.0])
|
2729
|
+
transformed_v = np.dot(matrix, v)
|
2730
|
+
transformed_verts.append([transformed_v[0], transformed_v[1], transformed_v[2]])
|
2731
|
+
return transformed_verts
|
2732
|
+
|
2733
|
+
def get_entity_transformation_matrix(entity):
|
2734
|
+
"""Extracts the transformation matrix from an IFC entity."""
|
2735
|
+
matrix = np.identity(4) # Default to an identity matrix
|
2736
|
+
if hasattr(entity, "ObjectPlacement") and entity.ObjectPlacement:
|
2737
|
+
placement = entity.ObjectPlacement
|
2738
|
+
matrix = extract_matrix_from_placement(placement)
|
2739
|
+
return matrix
|
2740
|
+
|
2253
2741
|
# Function to generate a unique random color based on material ID
|
2254
2742
|
def generate_color_for_material(material_id):
|
2255
2743
|
# Use a hash function to get a consistent "random" seed
|
@@ -2264,88 +2752,185 @@ class Topology():
|
|
2264
2752
|
|
2265
2753
|
# Function to get the material IDs associated with an entity
|
2266
2754
|
def get_material_ids_of_entity(entity):
|
2267
|
-
|
2755
|
+
return_dict = {}
|
2756
|
+
material_names = []
|
2268
2757
|
material_ids = []
|
2269
2758
|
if hasattr(entity, "HasAssociations"):
|
2270
2759
|
for association in entity.HasAssociations:
|
2271
2760
|
if association.is_a("IfcRelAssociatesMaterial"):
|
2272
2761
|
material = association.RelatingMaterial
|
2273
|
-
|
2762
|
+
try:
|
2763
|
+
material_name = material.Name
|
2764
|
+
except:
|
2765
|
+
material_name = material.to_string()
|
2274
2766
|
if material.is_a("IfcMaterial"):
|
2275
2767
|
material_ids.append(material.id())
|
2768
|
+
material_names.append(material_name)
|
2769
|
+
return_dict[clean_key(material_name)] = material.id
|
2276
2770
|
elif material.is_a("IfcMaterialList"):
|
2277
2771
|
for mat in material.Materials:
|
2278
2772
|
material_ids.append(mat.id())
|
2773
|
+
try:
|
2774
|
+
material_name = mat.Name
|
2775
|
+
except:
|
2776
|
+
material_name = mat.to_string()
|
2777
|
+
material_names.append(material_name)
|
2778
|
+
return_dict[clean_key(material_name)] = mat.id
|
2279
2779
|
elif material.is_a("IfcMaterialLayerSetUsage") or material.is_a("IfcMaterialLayerSet"):
|
2280
2780
|
for layer in material.ForLayerSet.MaterialLayers:
|
2281
2781
|
material_ids.append(layer.Material.id())
|
2782
|
+
try:
|
2783
|
+
material_name = layer.Name
|
2784
|
+
except:
|
2785
|
+
material_name = layer.to_string()
|
2786
|
+
material_names.append(material_name)
|
2787
|
+
return_dict[clean_key(material_name)] = layer.Material.id()
|
2282
2788
|
elif material.is_a("IfcMaterialConstituentSet"):
|
2283
2789
|
for constituent in material.MaterialConstituents:
|
2284
2790
|
material_ids.append(constituent.Material.id())
|
2791
|
+
try:
|
2792
|
+
material_name = constituent.Material.Name
|
2793
|
+
except:
|
2794
|
+
material_name = constituent.Material.to_string()
|
2795
|
+
material_names.append(material_name)
|
2796
|
+
return_dict[clean_key(material_name)] = constituent.Material.id()
|
2285
2797
|
|
2286
|
-
return
|
2287
|
-
|
2798
|
+
return return_dict
|
2288
2799
|
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2800
|
+
def get_wall_layers(wall, matrix=None, transferDictionaries=False):
|
2801
|
+
settings = ifcopenshell.geom.settings()
|
2802
|
+
settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.CURVES_SURFACES_AND_SOLIDS)
|
2803
|
+
settings.set(settings.USE_WORLD_COORDS, False)
|
2804
|
+
|
2805
|
+
# IFCPRODUCTDEFINITIONSHAPE der Wand abrufen
|
2806
|
+
product_definition_shape = wall.Representation
|
2807
|
+
if not product_definition_shape:
|
2808
|
+
print("Topology.ByIFCFile - Error: The object has no representation. Returning None")
|
2809
|
+
return None
|
2810
|
+
|
2811
|
+
if hasattr(product_definition_shape, 'HasShapeAspects'):
|
2812
|
+
for aspect in product_definition_shape.HasShapeAspects:
|
2813
|
+
material_name = aspect.Name
|
2814
|
+
for representation in aspect.ShapeRepresentations:
|
2815
|
+
print(dir(representation))
|
2816
|
+
axis_placement = representation.Position
|
2817
|
+
location = axis_placement.Location
|
2818
|
+
ref_direction = axis_placement.RefDirection
|
2819
|
+
print("Location:", location)
|
2820
|
+
print("Direction", ref_direction)
|
2821
|
+
aspect_matrix = get_entity_transformation_matrix(representation)
|
2822
|
+
print("Aspect Matrix:", aspect_matrix)
|
2823
|
+
shape = ifcopenshell.geom.create_shape(settings, representation)
|
2824
|
+
verts = shape.verts
|
2825
|
+
edges = shape.edges
|
2826
|
+
faces = shape.faces
|
2308
2827
|
grouped_verts = [ [verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
|
2828
|
+
grouped_verts = apply_transformation(grouped_verts, aspect_matrix)
|
2309
2829
|
grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
|
2310
2830
|
grouped_faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
|
2311
2831
|
topology = Topology.SelfMerge(Topology.ByGeometry(grouped_verts, grouped_edges, grouped_faces))
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2832
|
+
#matrix = shape.transformation.matrix
|
2833
|
+
#topology = Topology.Transform(topology, matrix)
|
2834
|
+
d = get_material_ids_of_entity(wall)
|
2835
|
+
material_id = d.get(clean_key(material_name), 0)
|
2315
2836
|
if transferDictionaries:
|
2316
2837
|
keys = []
|
2317
2838
|
values = []
|
2839
|
+
try:
|
2840
|
+
entity_name = entity.Name
|
2841
|
+
except:
|
2842
|
+
entity_name = entity.to_str()
|
2318
2843
|
keys.append("TOPOLOGIC_id")
|
2319
2844
|
values.append(str(uuid.uuid4()))
|
2320
2845
|
keys.append("TOPOLOGIC_name")
|
2321
|
-
values.append(
|
2846
|
+
values.append(entity_name)
|
2322
2847
|
keys.append("TOPOLOGIC_type")
|
2323
2848
|
values.append(Topology.TypeAsString(topology))
|
2324
2849
|
keys.append("IFC_id")
|
2325
|
-
values.append(str(
|
2326
|
-
keys.append("IFC_guid")
|
2327
|
-
values.append(str(
|
2328
|
-
keys.append("IFC_unique_id")
|
2329
|
-
values.append(str(
|
2850
|
+
values.append(str(aspect.id))
|
2851
|
+
#keys.append("IFC_guid")
|
2852
|
+
#values.append(str(aspect.guid))
|
2853
|
+
#keys.append("IFC_unique_id")
|
2854
|
+
#values.append(str(aspect.unique_id))
|
2330
2855
|
keys.append("IFC_name")
|
2331
|
-
values.append(
|
2332
|
-
keys.append("IFC_type")
|
2333
|
-
values.append(
|
2334
|
-
|
2335
|
-
|
2336
|
-
values.append(material_ids)
|
2856
|
+
values.append(entity_name)
|
2857
|
+
#keys.append("IFC_type")
|
2858
|
+
#values.append(aspect.type)
|
2859
|
+
keys.append("IFC_material_id")
|
2860
|
+
values.append(material_id)
|
2337
2861
|
keys.append("IFC_material_name")
|
2338
2862
|
values.append(material_name)
|
2339
2863
|
keys.append("TOPOLOGIC_color")
|
2340
|
-
color = generate_color_for_material(str(
|
2864
|
+
color = generate_color_for_material(str(material_id))
|
2341
2865
|
values.append(color)
|
2342
2866
|
d = Dictionary.ByKeysValues(keys, values)
|
2343
2867
|
topology = Topology.SetDictionary(topology, d)
|
2344
|
-
|
2868
|
+
|
2869
|
+
return topology
|
2870
|
+
|
2871
|
+
|
2872
|
+
includeTypes = [s.lower() for s in includeTypes]
|
2873
|
+
excludeTypes = [s.lower() for s in excludeTypes]
|
2874
|
+
topologies = []
|
2875
|
+
settings = ifcopenshell.geom.settings()
|
2876
|
+
settings.set("dimensionality", ifcopenshell.ifcopenshell_wrapper.SOLID)
|
2877
|
+
settings.set(settings.USE_WORLD_COORDS, True)
|
2878
|
+
for entity in file.by_type('IfcProduct'): # You might want to refine the types you check
|
2879
|
+
if hasattr(entity, "Representation") and entity.Representation:
|
2880
|
+
print("Number of Representations:", len(entity.Representation.Representations))
|
2881
|
+
for rep in entity.Representation.Representations:
|
2882
|
+
print("Rep:", rep)
|
2883
|
+
print(dir(rep))
|
2884
|
+
matrix = get_entity_transformation_matrix(entity)
|
2885
|
+
print(matrix)
|
2886
|
+
if rep.is_a("IfcShapeRepresentation"):
|
2887
|
+
# Generate the geometry for this entity
|
2888
|
+
shape = ifcopenshell.geom.create_shape(settings, rep)
|
2889
|
+
verts = shape.verts
|
2890
|
+
edges = shape.edges
|
2891
|
+
faces = shape.faces
|
2892
|
+
grouped_verts = [ [verts[i], verts[i + 1], verts[i + 2]] for i in range(0, len(verts), 3)]
|
2893
|
+
#grouped_verts = apply_transformation(grouped_verts, matrix)
|
2894
|
+
grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
|
2895
|
+
grouped_faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3)]
|
2896
|
+
topology = Topology.SelfMerge(Topology.ByGeometry(grouped_verts, grouped_edges, grouped_faces))
|
2897
|
+
if removeCoplanarFaces:
|
2898
|
+
topology = Topology.RemoveCoplanarFaces(topology)
|
2899
|
+
if transferDictionaries:
|
2900
|
+
keys = []
|
2901
|
+
values = []
|
2902
|
+
keys.append("TOPOLOGIC_id")
|
2903
|
+
values.append(str(uuid.uuid4()))
|
2904
|
+
keys.append("TOPOLOGIC_name")
|
2905
|
+
values.append(shape.name)
|
2906
|
+
keys.append("TOPOLOGIC_type")
|
2907
|
+
values.append(Topology.TypeAsString(topology))
|
2908
|
+
keys.append("IFC_id")
|
2909
|
+
values.append(str(shape.id))
|
2910
|
+
keys.append("IFC_guid")
|
2911
|
+
values.append(str(shape.guid))
|
2912
|
+
keys.append("IFC_unique_id")
|
2913
|
+
values.append(str(shape.unique_id))
|
2914
|
+
keys.append("IFC_name")
|
2915
|
+
values.append(shape.name)
|
2916
|
+
keys.append("IFC_type")
|
2917
|
+
values.append(shape.type)
|
2918
|
+
material_dict = get_material_ids_of_entity(entity)
|
2919
|
+
keys.append("IFC_materials")
|
2920
|
+
values.append(material_dict)
|
2921
|
+
#keys.append("IFC_material_name")
|
2922
|
+
#values.append(material_name)
|
2923
|
+
#keys.append("TOPOLOGIC_color")
|
2924
|
+
#color = generate_color_for_material(str(material_ids))
|
2925
|
+
#values.append(color)
|
2926
|
+
d = Dictionary.ByKeysValues(keys, values)
|
2927
|
+
topology = Topology.SetDictionary(topology, d)
|
2928
|
+
topology = Topology.Transform(topology, matrix)
|
2929
|
+
topologies.append(topology)
|
2345
2930
|
return topologies
|
2346
2931
|
|
2347
2932
|
@staticmethod
|
2348
|
-
def ByIFCPath(path, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False):
|
2933
|
+
def ByIFCPath(path, includeTypes=[], excludeTypes=[], transferDictionaries=False, removeCoplanarFaces=False, epsilon=0.0001, tolerance=0.0001):
|
2349
2934
|
"""
|
2350
2935
|
Create a topology by importing it from an IFC file path.
|
2351
2936
|
|
@@ -2361,7 +2946,10 @@ class Topology():
|
|
2361
2946
|
If set to True, the dictionaries from the IFC file will be transferred to the topology. Otherwise, they won't. The default is False.
|
2362
2947
|
removeCoplanarFaces : bool , optional
|
2363
2948
|
If set to True, coplanar faces are removed. Otherwise they are not. The default is False.
|
2364
|
-
|
2949
|
+
epsilon : float , optional
|
2950
|
+
The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.0001.
|
2951
|
+
tolerance : float , optional
|
2952
|
+
The desired tolerance. The default is 0.0001.
|
2365
2953
|
Returns
|
2366
2954
|
-------
|
2367
2955
|
list
|
@@ -2380,7 +2968,7 @@ class Topology():
|
|
2380
2968
|
if not file:
|
2381
2969
|
print("Topology.ByIFCPath - Error: the input file parameter is not a valid file. Returning None.")
|
2382
2970
|
return None
|
2383
|
-
return Topology.ByIFCFile(file, includeTypes=includeTypes, excludeTypes=excludeTypes, transferDictionaries=transferDictionaries, removeCoplanarFaces=removeCoplanarFaces)
|
2971
|
+
return Topology.ByIFCFile(file, includeTypes=includeTypes, excludeTypes=excludeTypes, transferDictionaries=transferDictionaries, removeCoplanarFaces=removeCoplanarFaces, epsilon=epsilon, tolerance=tolerance)
|
2384
2972
|
|
2385
2973
|
'''
|
2386
2974
|
@staticmethod
|
@@ -5504,6 +6092,20 @@ class Topology():
|
|
5504
6092
|
flat_topology = Topology.Translate(topology, -Vertex.X(origin, mantissa=mantissa), -Vertex.Y(origin, mantissa=mantissa), -Vertex.Z(origin, mantissa=mantissa))
|
5505
6093
|
tran_mat = Vector.TransformationMatrix(direction, up)
|
5506
6094
|
flat_topology = Topology.Transform(flat_topology, tran_mat)
|
6095
|
+
flat_topology = Topology.SetDictionary(flat_topology, Topology.Dictionary(topology), silent=True)
|
6096
|
+
flat_vertices = Topology.Vertices(flat_topology)
|
6097
|
+
vertices = Topology.Vertices(topology)
|
6098
|
+
flat_edges = Topology.Edges(flat_topology)
|
6099
|
+
edges = Topology.Edges(topology)
|
6100
|
+
faces = []
|
6101
|
+
flat_faces = []
|
6102
|
+
if Topology.IsInstance(topology, "Face"):
|
6103
|
+
flat_faces = Topology.Faces(flat_topology)
|
6104
|
+
faces = Topology.Faces(topology)
|
6105
|
+
elements = vertices+edges+faces
|
6106
|
+
flat_elements = flat_vertices+flat_edges+flat_faces
|
6107
|
+
for i, f, in enumerate(flat_elements):
|
6108
|
+
f = Topology.SetDictionary(f, Topology.Dictionary(elements[i]), silent=True)
|
5507
6109
|
return flat_topology
|
5508
6110
|
|
5509
6111
|
@staticmethod
|
@@ -6950,20 +7552,30 @@ class Topology():
|
|
6950
7552
|
|
6951
7553
|
"""
|
6952
7554
|
from topologicpy.Dictionary import Dictionary
|
7555
|
+
import inspect
|
6953
7556
|
|
6954
7557
|
if not Topology.IsInstance(topology, "Topology") and not Topology.IsInstance(topology, "Graph"):
|
6955
7558
|
if not silent:
|
6956
7559
|
print("Topology.SetDictionary - Error: the input topology parameter is not a valid topology or graph. Returning None.")
|
7560
|
+
curframe = inspect.currentframe()
|
7561
|
+
calframe = inspect.getouterframes(curframe, 2)
|
7562
|
+
print('caller name:', calframe[1][3])
|
6957
7563
|
return None
|
6958
7564
|
if isinstance(dictionary, dict):
|
6959
7565
|
dictionary = Dictionary.ByPythonDictionary(dictionary)
|
6960
7566
|
if not Topology.IsInstance(dictionary, "Dictionary"):
|
6961
7567
|
if not silent:
|
6962
7568
|
print("Topology.SetDictionary - Warning: the input dictionary parameter is not a valid dictionary. Returning original input.")
|
7569
|
+
curframe = inspect.currentframe()
|
7570
|
+
calframe = inspect.getouterframes(curframe, 2)
|
7571
|
+
print('caller name:', calframe[1][3])
|
6963
7572
|
return topology
|
6964
7573
|
if len(dictionary.Keys()) < 1:
|
6965
7574
|
if not silent:
|
6966
7575
|
print("Topology.SetDictionary - Warning: the input dictionary parameter is empty. Returning original input.")
|
7576
|
+
curframe = inspect.currentframe()
|
7577
|
+
calframe = inspect.getouterframes(curframe, 2)
|
7578
|
+
print('caller name:', calframe[1][3])
|
6967
7579
|
return topology
|
6968
7580
|
_ = topology.SetDictionary(dictionary)
|
6969
7581
|
return topology
|
@@ -7166,13 +7778,15 @@ class Topology():
|
|
7166
7778
|
colorKey = "color",
|
7167
7779
|
opacityKey = "opacity",
|
7168
7780
|
showVertices=True, vertexSize=1.1, vertexColor="black",
|
7169
|
-
vertexLabelKey=None,
|
7781
|
+
vertexLabelKey=None, showVertexLabel= False,
|
7782
|
+
vertexGroupKey=None, vertexGroups=[],
|
7170
7783
|
vertexMinGroup=None, vertexMaxGroup=None,
|
7171
7784
|
showVertexLegend=False, vertexLegendLabel="Topology Vertices", vertexLegendRank=1,
|
7172
7785
|
vertexLegendGroup=1,
|
7173
7786
|
|
7174
7787
|
showEdges=True, edgeWidth=1, edgeColor="black",
|
7175
|
-
edgeLabelKey=None,
|
7788
|
+
edgeLabelKey=None, showEdgeLabel = False,
|
7789
|
+
edgeGroupKey=None, edgeGroups=[],
|
7176
7790
|
edgeMinGroup=None, edgeMaxGroup=None,
|
7177
7791
|
showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
|
7178
7792
|
edgeLegendGroup=2,
|
@@ -7217,6 +7831,8 @@ class Topology():
|
|
7217
7831
|
The default is "black".
|
7218
7832
|
vertexLabelKey : str , optional
|
7219
7833
|
The dictionary key to use to display the vertex label. The default is None.
|
7834
|
+
showVertexLabels : bool , optional
|
7835
|
+
If set to True, the vertex labels are shown permenantely on screen. Otherwise, they are not. The default is False.
|
7220
7836
|
vertexGroupKey : str , optional
|
7221
7837
|
The dictionary key to use to display the vertex group. The default is None.
|
7222
7838
|
vertexGroups : list , optional
|
@@ -7248,6 +7864,8 @@ class Topology():
|
|
7248
7864
|
The default is "black".
|
7249
7865
|
edgeLabelKey : str , optional
|
7250
7866
|
The dictionary key to use to display the edge label. The default is None.
|
7867
|
+
showEdgeLabels : bool , optional
|
7868
|
+
If set to True, the edge labels are shown permenantely on screen. Otherwise, they are not. The default is False.
|
7251
7869
|
edgeGroupKey : str , optional
|
7252
7870
|
The dictionary key to use to display the edge group. The default is None.
|
7253
7871
|
edgeGroups : list , optional
|
@@ -7400,12 +8018,12 @@ class Topology():
|
|
7400
8018
|
faceOpacity = Dictionary.ValueAtKey(d, opacityKey) or faceOpacity
|
7401
8019
|
data += Plotly.DataByTopology(topology=topology,
|
7402
8020
|
showVertices=showVertices, vertexSize=vertexSize, vertexColor=vertexColor,
|
7403
|
-
vertexLabelKey=vertexLabelKey, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups,
|
8021
|
+
vertexLabelKey=vertexLabelKey, showVertexLabel=showVertexLabel, vertexGroupKey=vertexGroupKey, vertexGroups=vertexGroups,
|
7404
8022
|
vertexMinGroup=vertexMinGroup, vertexMaxGroup=vertexMaxGroup,
|
7405
8023
|
showVertexLegend=showVertexLegend, vertexLegendLabel=vertexLegendLabel, vertexLegendRank=vertexLegendRank,
|
7406
8024
|
vertexLegendGroup=vertexLegendGroup,
|
7407
8025
|
showEdges=showEdges, edgeWidth=edgeWidth, edgeColor=edgeColor,
|
7408
|
-
edgeLabelKey=edgeLabelKey, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups,
|
8026
|
+
edgeLabelKey=edgeLabelKey, showEdgeLabel=showEdgeLabel, edgeGroupKey=edgeGroupKey, edgeGroups=edgeGroups,
|
7409
8027
|
edgeMinGroup=edgeMinGroup, edgeMaxGroup=edgeMaxGroup,
|
7410
8028
|
showEdgeLegend=showEdgeLegend, edgeLegendLabel=edgeLegendLabel, edgeLegendRank=edgeLegendRank,
|
7411
8029
|
edgeLegendGroup=edgeLegendGroup,
|
@@ -8538,11 +9156,30 @@ class Topology():
|
|
8538
9156
|
|
8539
9157
|
"""
|
8540
9158
|
import uuid
|
9159
|
+
from topologicpy.Dictionary import Dictionary
|
8541
9160
|
|
8542
9161
|
predefined_namespace_dns = uuid.UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
|
8543
9162
|
namespace_uuid = uuid.uuid5(predefined_namespace_dns, namespace)
|
8544
|
-
|
8545
|
-
|
9163
|
+
cellComplexes = Topology.CellComplexes(topology)
|
9164
|
+
cells = Topology.Cells(topology)
|
9165
|
+
Shells = Topology.Shells(topology)
|
9166
|
+
Faces = Topology.Faces(topology)
|
9167
|
+
Wires = Topology.Wires(topology)
|
9168
|
+
Edges = Topology.Edges(topology)
|
9169
|
+
Vertices = Topology.Vertices(topology)
|
9170
|
+
Apertures = Topology.Apertures(topology, subTopologyType="all")
|
9171
|
+
subTopologies = cellComplexes+cells+Shells+Faces+Wires+Edges+Vertices+Apertures
|
9172
|
+
dictionaries = [Dictionary.PythonDictionary(Topology.Dictionary(topology))]
|
9173
|
+
dictionaries += [Dictionary.PythonDictionary(Topology.Dictionary(s)) for s in subTopologies]
|
9174
|
+
dict_str = str(dictionaries)
|
9175
|
+
top_geom = Topology.Geometry(topology, mantissa=6)
|
9176
|
+
verts_str = str(top_geom['vertices'])
|
9177
|
+
edges_str = str(top_geom['edges'])
|
9178
|
+
faces_str = str(top_geom['faces'])
|
9179
|
+
geo_str = verts_str+edges_str+faces_str
|
9180
|
+
final_str = geo_str+dict_str
|
9181
|
+
uuid_str = uuid.uuid5(namespace_uuid, final_str)
|
9182
|
+
return str(uuid_str)
|
8546
9183
|
|
8547
9184
|
@staticmethod
|
8548
9185
|
def View3D(*topologies, uuid = None, nameKey="name", colorKey="color", opacityKey="opacity", defaultColor=[256,256,256], defaultOpacity=0.5, transposeAxes: bool = True, mode: int = 0, meshSize: float = None, overwrite: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
|
topologicpy/Wire.py
CHANGED
@@ -373,13 +373,14 @@ class Wire():
|
|
373
373
|
normal = Face.Normal(temp_face)
|
374
374
|
flat_wire = Topology.Flatten(wire, direction=normal, origin=origin)
|
375
375
|
edges = Topology.Edges(flat_wire)
|
376
|
+
original_edges = Topology.Edges(wire)
|
376
377
|
offsets = []
|
377
378
|
offset_edges = []
|
378
379
|
final_vertices = []
|
379
380
|
bisectors_list = []
|
380
381
|
edge_dictionaries = []
|
381
|
-
for edge in edges:
|
382
|
-
d = Topology.Dictionary(
|
382
|
+
for i, edge in enumerate(edges):
|
383
|
+
d = Topology.Dictionary(original_edges[i])
|
383
384
|
d_offset = Dictionary.ValueAtKey(d, offsetKey)
|
384
385
|
if d_offset == None:
|
385
386
|
d_offset = offset
|
@@ -406,7 +407,7 @@ class Wire():
|
|
406
407
|
if bisectors == True:
|
407
408
|
bisectors_list.append(Edge.ByVertices(v_a, v1))
|
408
409
|
if transferDictionaries == True:
|
409
|
-
v1 = Topology.SetDictionary(v1, Topology.Dictionary(v_a))
|
410
|
+
v1 = Topology.SetDictionary(v1, Topology.Dictionary(v_a), silent=True)
|
410
411
|
edge_dictionaries.append(Topology.Dictionary(edges[i]))
|
411
412
|
final_vertices.append(v1)
|
412
413
|
else:
|
@@ -463,15 +464,15 @@ class Wire():
|
|
463
464
|
v1_2 = Topology.TranslateByDirectionDistance(Edge.StartVertex(o_edge_a),
|
464
465
|
direction = Edge.Direction(o_edge_a),
|
465
466
|
distance = d_stepOffsetB)
|
467
|
+
if transferDictionaries == True:
|
468
|
+
v1_1 = Topology.SetDictionary(v1_1, Topology.Dictionary(v_a), silent=True)
|
469
|
+
v1_2 = Topology.SetDictionary(v1_2, Topology.Dictionary(v_a), silent=True)
|
470
|
+
edge_dictionaries.append(Topology.Dictionary(v_a))
|
471
|
+
edge_dictionaries.append(Topology.Dictionary(edges[i]))
|
466
472
|
bisectors_list.append(Edge.ByVertices(v_a, v1_1))
|
467
473
|
bisectors_list.append(Edge.ByVertices(v_a, v1_2))
|
468
474
|
final_vertices.append(v1_1)
|
469
475
|
final_vertices.append(v1_2)
|
470
|
-
if transferDictionaries == True:
|
471
|
-
v1_1 = Topology.SetDictionary(v1_1, Topology.Dictionary(v_a))
|
472
|
-
v1_2 = Topology.SetDictionary(v1_2, Topology.Dictionary(v_a))
|
473
|
-
edge_dictionaries.append(Topology.Dictionary(v_a))
|
474
|
-
edge_dictionaries.append(Topology.Dictionary(edges[i]))
|
475
476
|
v_a = Edge.EndVertex(edges[-1])
|
476
477
|
if Wire.IsClosed(wire) == False:
|
477
478
|
v1 = Edge.EndVertex(offset_edges[-1])
|
@@ -481,12 +482,7 @@ class Wire():
|
|
481
482
|
if bisectors == True:
|
482
483
|
bisectors_list.append(Edge.ByVertices(v_a, v1))
|
483
484
|
|
484
|
-
|
485
485
|
return_wire = Wire.ByVertices(final_vertices, close=Wire.IsClosed(wire))
|
486
|
-
wire_edges = Topology.Edges(return_wire)
|
487
|
-
if transferDictionaries == True:
|
488
|
-
for i, wire_edge in enumerate(wire_edges):
|
489
|
-
wire_edge = Topology.SetDictionary(wire_edge, edge_dictionaries[i], silent=True)
|
490
486
|
if not Topology.IsInstance(return_wire, "Wire"):
|
491
487
|
if not silent:
|
492
488
|
print("Wire.ByOffset - Warning: The resulting wire is not well-formed, please check your offsets.")
|
@@ -494,6 +490,18 @@ class Wire():
|
|
494
490
|
if not Wire.IsManifold(return_wire) and bisectors == False:
|
495
491
|
if not silent:
|
496
492
|
print("Wire.ByOffset - Warning: The resulting wire is non-manifold, please check your offsets.")
|
493
|
+
wire_edges = Topology.Edges(return_wire)
|
494
|
+
|
495
|
+
if transferDictionaries == True:
|
496
|
+
if not len(wire_edges) == len(edge_dictionaries):
|
497
|
+
if not silent:
|
498
|
+
print("Length of Wire Edges:", len(wire_edges))
|
499
|
+
print("Length of Edge Dictionaries:", len(edge_dictionaries))
|
500
|
+
print("Wire.ByOffset - Warning: The resulting wire is not well-formed, offsets may not be applied correctly. Please check your offsets.")
|
501
|
+
for i, wire_edge in enumerate(wire_edges):
|
502
|
+
if len(edge_dictionaries) > 0:
|
503
|
+
temp_dictionary = edge_dictionaries[min(i,len(edge_dictionaries)-1)]
|
504
|
+
wire_edge = Topology.SetDictionary(wire_edge, temp_dictionary, silent=True)
|
497
505
|
if bisectors == True:
|
498
506
|
temp_return_wire = Topology.SelfMerge(Cluster.ByTopologies(Topology.Edges(return_wire)+bisectors_list))
|
499
507
|
if transferDictionaries == True:
|
@@ -738,7 +746,7 @@ class Wire():
|
|
738
746
|
if not(([i1, i2] in g_edges) or ([i2, i1] in g_edges)):
|
739
747
|
g_edges.append([i1, i2])
|
740
748
|
used.append(end)
|
741
|
-
new_wire = Topology.ByGeometry(vertices=g_vertices, edges=g_edges, faces=[]
|
749
|
+
new_wire = Topology.SelfMerge(Topology.ByGeometry(vertices=g_vertices, edges=g_edges, faces=[]))
|
742
750
|
return new_wire
|
743
751
|
|
744
752
|
@staticmethod
|
topologicpy/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.7.
|
1
|
+
__version__ = '0.7.51'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.7.
|
3
|
+
Version: 0.7.51
|
4
4
|
Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
|
5
5
|
Author-email: Wassim Jabi <wassim.jabi@gmail.com>
|
6
6
|
License: MIT License
|
@@ -3,33 +3,33 @@ topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
|
|
3
3
|
topologicpy/Cell.py,sha256=uZ1gNVlfVtpi6sNgyfazP_nqe7mPjarE7MYzf8KoEI4,107930
|
4
4
|
topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
|
5
5
|
topologicpy/Cluster.py,sha256=TZXuxzdaUr6OHSWnjWpjCOMlVj6YHBH8aUVbDVsncVA,54999
|
6
|
-
topologicpy/Color.py,sha256=
|
6
|
+
topologicpy/Color.py,sha256=FrxX2yILqWvYrqD8kBaknfMfOR_phJOmhvTvFc07bY4,18065
|
7
7
|
topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
|
8
8
|
topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
|
9
|
-
topologicpy/Dictionary.py,sha256=
|
9
|
+
topologicpy/Dictionary.py,sha256=X_WARSYtWtYIsEUKdLH-plZmGZ3pHz_FBFxxeHGHdrU,27065
|
10
10
|
topologicpy/Edge.py,sha256=vhYHkobSLGSWV-oe2oJFFDobqFToDyb7s71yQ840AAA,65166
|
11
11
|
topologicpy/EnergyModel.py,sha256=XcCP55VW5WHDIIKcURijmBOZEgNUDEn_V9h5EejkntA,53876
|
12
|
-
topologicpy/Face.py,sha256=
|
12
|
+
topologicpy/Face.py,sha256=7GCYo4ATkMW1skiv4gXOVARM29A7Buim9lTQu57B22Y,115489
|
13
13
|
topologicpy/Graph.py,sha256=1dtcE342b6d7cTiMbtUWWOud6Vu0vHaf4HP2eG_-iqg,402544
|
14
14
|
topologicpy/Grid.py,sha256=3-sn7CHWGcXk18XCnHjsUttNJTWwmN63g_Insj__p04,18218
|
15
15
|
topologicpy/Helper.py,sha256=i-AfI29NMsZXBaymjilfvxQbuS3wpYbpPw4RWu1YCHs,16358
|
16
16
|
topologicpy/Honeybee.py,sha256=vcBECJlgWVjNNdD9ZmjNik_pA1Y_ZNoOorsQb2CiyGA,21965
|
17
17
|
topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
|
18
18
|
topologicpy/Neo4j.py,sha256=YvtF7RYUMATEZ8iHwFwK_MOxEDyARby2DTI2CCK6-cI,19694
|
19
|
-
topologicpy/Plotly.py,sha256=
|
19
|
+
topologicpy/Plotly.py,sha256=gfGadsDBgXOeefzzceXkVshqONuPtkGiW-XNVuT2rrA,106193
|
20
20
|
topologicpy/Polyskel.py,sha256=EFsuh2EwQJGPLiFUjvtXmAwdX-A4r_DxP5hF7Qd3PaU,19829
|
21
21
|
topologicpy/PyG.py,sha256=3U59QObO56EBwrvaplGeLZhbTao0gJCYhWm3oTpjFAE,109505
|
22
22
|
topologicpy/Shell.py,sha256=joahFtpRQTWJpQOmi3qU4Xe0Sx2XXeayHlXTNx8CzMk,87610
|
23
23
|
topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
|
24
24
|
topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
|
25
|
-
topologicpy/Topology.py,sha256=
|
25
|
+
topologicpy/Topology.py,sha256=100DUg9EUcFg3K9wlNdaKrXcFEZLvqHsexs3R-8pbYw,416196
|
26
26
|
topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
|
27
27
|
topologicpy/Vertex.py,sha256=bLY60YWoMsgCgHk7F7k9F93Sq2FJ6AzUcTfJ83NZfHA,71107
|
28
|
-
topologicpy/Wire.py,sha256=
|
28
|
+
topologicpy/Wire.py,sha256=h-vcKAuyHVvfX34nJx4bVF-AxeaUCx4NbVzGBq98M9o,154201
|
29
29
|
topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
|
30
|
-
topologicpy/version.py,sha256=
|
31
|
-
topologicpy-0.7.
|
32
|
-
topologicpy-0.7.
|
33
|
-
topologicpy-0.7.
|
34
|
-
topologicpy-0.7.
|
35
|
-
topologicpy-0.7.
|
30
|
+
topologicpy/version.py,sha256=Nl_BpJIhLQbbkeSiv2q5IgytCINu26pAUqkPjuq0FPg,23
|
31
|
+
topologicpy-0.7.51.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
|
32
|
+
topologicpy-0.7.51.dist-info/METADATA,sha256=E68AdA4I73vasiialUPW6sDhhX4xFhYSwysUl_7ZR1g,10918
|
33
|
+
topologicpy-0.7.51.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
34
|
+
topologicpy-0.7.51.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
|
35
|
+
topologicpy-0.7.51.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|