topologicpy 0.4.38__py3-none-any.whl → 0.4.40__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 +2 -1
- topologicpy/CellComplex.py +12 -17
- topologicpy/Edge.py +2 -1
- topologicpy/EnergyModel.py +1 -2
- topologicpy/Face.py +46 -65
- topologicpy/Graph.py +62 -60
- topologicpy/Plotly.py +12 -12
- topologicpy/Shell.py +11 -6
- topologicpy/Topology.py +33 -158
- topologicpy/Vertex.py +131 -11
- topologicpy/Wire.py +35 -25
- topologicpy/__init__.py +1 -1
- {topologicpy-0.4.38.dist-info → topologicpy-0.4.40.dist-info}/METADATA +1 -1
- {topologicpy-0.4.38.dist-info → topologicpy-0.4.40.dist-info}/RECORD +17 -17
- {topologicpy-0.4.38.dist-info → topologicpy-0.4.40.dist-info}/WHEEL +1 -1
- {topologicpy-0.4.38.dist-info → topologicpy-0.4.40.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.38.dist-info → topologicpy-0.4.40.dist-info}/top_level.txt +0 -0
topologicpy/Cell.py
CHANGED
|
@@ -453,11 +453,12 @@ class Cell(Topology):
|
|
|
453
453
|
The compactness of the input cell.
|
|
454
454
|
|
|
455
455
|
"""
|
|
456
|
+
from topologicpy.Face import Face
|
|
456
457
|
faces = []
|
|
457
458
|
_ = cell.Faces(None, faces)
|
|
458
459
|
area = 0.0
|
|
459
460
|
for aFace in faces:
|
|
460
|
-
area = area + abs(
|
|
461
|
+
area = area + abs(Face.Area(aFace))
|
|
461
462
|
volume = abs(topologic.CellUtility.Volume(cell))
|
|
462
463
|
compactness = 0
|
|
463
464
|
#From https://en.wikipedia.org/wiki/Sphericity
|
topologicpy/CellComplex.py
CHANGED
|
@@ -57,6 +57,9 @@ class CellComplex(topologic.CellComplex):
|
|
|
57
57
|
The created cellcomplex.
|
|
58
58
|
|
|
59
59
|
"""
|
|
60
|
+
from topologicpy.Cluster import Cluster
|
|
61
|
+
from topologicpy.Topology import Topology
|
|
62
|
+
|
|
60
63
|
if not cells:
|
|
61
64
|
return None
|
|
62
65
|
if not isinstance(cells, list):
|
|
@@ -64,23 +67,15 @@ class CellComplex(topologic.CellComplex):
|
|
|
64
67
|
cells = [x for x in cells if isinstance(x, topologic.Cell)]
|
|
65
68
|
if len(cells) < 1:
|
|
66
69
|
return None
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if result.Type() > 64:
|
|
77
|
-
returnCellComplexes = []
|
|
78
|
-
_ = result.CellComplexes(None, returnCellComplexes)
|
|
79
|
-
return returnCellComplexes[0]
|
|
80
|
-
else:
|
|
81
|
-
return None
|
|
82
|
-
else:
|
|
83
|
-
return cellComplex
|
|
70
|
+
elif len(cells) == 1:
|
|
71
|
+
print("CellComplex.ByCells - Warning: Found only one cell. Returning Cell instead of CellComplex.")
|
|
72
|
+
return cells[0]
|
|
73
|
+
cluster = Cluster.ByTopologies(cells)
|
|
74
|
+
cellComplex = Cluster.SelfMerge(cluster)
|
|
75
|
+
if not isinstance(cellComplex, topologic.CellComplex):
|
|
76
|
+
print("CellComplex.ByCells - Warning: Could not create a CellComplex. Returning Cluster instead of CellComplex.")
|
|
77
|
+
return cluster
|
|
78
|
+
return cellComplex
|
|
84
79
|
|
|
85
80
|
@staticmethod
|
|
86
81
|
def ByCellsCluster(cluster: topologic.Cluster, tolerance: float = 0.0001) -> topologic.CellComplex:
|
topologicpy/Edge.py
CHANGED
|
@@ -173,6 +173,7 @@ class Edge():
|
|
|
173
173
|
The created edge.
|
|
174
174
|
|
|
175
175
|
"""
|
|
176
|
+
from topologicpy.Vertex import Vertex
|
|
176
177
|
edge = None
|
|
177
178
|
if not isinstance(vertexA, topologic.Vertex):
|
|
178
179
|
return None
|
|
@@ -180,7 +181,7 @@ class Edge():
|
|
|
180
181
|
return None
|
|
181
182
|
if topologic.Topology.IsSame(vertexA, vertexB):
|
|
182
183
|
return None
|
|
183
|
-
if
|
|
184
|
+
if Vertex.Distance(vertexA, vertexB) < tolerance:
|
|
184
185
|
return None
|
|
185
186
|
try:
|
|
186
187
|
edge = topologic.Edge.ByStartVertexEndVertex(vertexA, vertexB)
|
topologicpy/EnergyModel.py
CHANGED
|
@@ -334,8 +334,7 @@ class EnergyModel:
|
|
|
334
334
|
if osFaceNormal.dot(osSurface.outwardNormal()) < 1e-6:
|
|
335
335
|
osSurface.setVertices(list(reversed(osFacePoints)))
|
|
336
336
|
osSurface.setSpace(osSpace)
|
|
337
|
-
faceCells =
|
|
338
|
-
_ = topologic.FaceUtility.AdjacentCells(buildingFace, building, faceCells)
|
|
337
|
+
faceCells = Topology.AdjacentTopologies(buildingFace, building, topologyType="cell")
|
|
339
338
|
if len(faceCells) == 1: #Exterior Surfaces
|
|
340
339
|
osSurface.setOutsideBoundaryCondition("Outdoors")
|
|
341
340
|
if (math.degrees(math.acos(osSurface.outwardNormal().dot(openstudio.Vector3d(0, 0, 1)))) > 135) or (math.degrees(math.acos(osSurface.outwardNormal().dot(openstudio.Vector3d(0, 0, 1)))) < 45):
|
topologicpy/Face.py
CHANGED
|
@@ -364,7 +364,7 @@ class Face(topologic.Face):
|
|
|
364
364
|
aFace = topologic.Face.ByExternalBoundary(Topology.RemoveCollinearEdges(aWire, angTolerance))
|
|
365
365
|
except:
|
|
366
366
|
aFace = topologic.Face.ByExternalBoundary(Wire.Planarize(Topology.RemoveCollinearEdges(aWire, angTolerance)))
|
|
367
|
-
anArea =
|
|
367
|
+
anArea = Face.Area(aFace)
|
|
368
368
|
faces.append(aFace)
|
|
369
369
|
areas.append(anArea)
|
|
370
370
|
max_index = areas.index(max(areas))
|
|
@@ -691,7 +691,7 @@ class Face(topologic.Face):
|
|
|
691
691
|
perimeter = 0.0
|
|
692
692
|
for anEdge in edges:
|
|
693
693
|
perimeter = perimeter + abs(topologic.EdgeUtility.Length(anEdge))
|
|
694
|
-
area = abs(
|
|
694
|
+
area = abs(Face.Area(face))
|
|
695
695
|
compactness = 0
|
|
696
696
|
#From https://en.wikipedia.org/wiki/Compactness_measure_of_a_shape
|
|
697
697
|
|
|
@@ -860,6 +860,8 @@ class Face(topologic.Face):
|
|
|
860
860
|
|
|
861
861
|
"""
|
|
862
862
|
|
|
863
|
+
from topologicpy.Vertex import Vertex
|
|
864
|
+
|
|
863
865
|
def leftMost(vertices, tolerance = 0.0001):
|
|
864
866
|
xCoords = []
|
|
865
867
|
for v in vertices:
|
|
@@ -884,7 +886,7 @@ class Face(topologic.Face):
|
|
|
884
886
|
|
|
885
887
|
def vIndex(v, vList, tolerance):
|
|
886
888
|
for i in range(len(vList)):
|
|
887
|
-
if
|
|
889
|
+
if Vertex.Distance(v, vList[i]) < tolerance:
|
|
888
890
|
return i+1
|
|
889
891
|
return None
|
|
890
892
|
|
|
@@ -1128,80 +1130,59 @@ class Face(topologic.Face):
|
|
|
1128
1130
|
True if the input vertex is inside the input face. False otherwise.
|
|
1129
1131
|
|
|
1130
1132
|
"""
|
|
1133
|
+
from topologicpy.Vertex import Vertex
|
|
1134
|
+
from topologicpy.Topology import Topology
|
|
1135
|
+
from topologicpy.Dictionary import Dictionary
|
|
1136
|
+
import numpy as np
|
|
1131
1137
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1138
|
+
def point_inside_face(point, outer_boundary, inner_boundaries):
|
|
1139
|
+
def is_point_inside_polygon(p, polygon):
|
|
1140
|
+
n = len(polygon)
|
|
1141
|
+
inside = False
|
|
1136
1142
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
p2x,p2y = poly[i % n]
|
|
1140
|
-
if y > min(p1y,p2y):
|
|
1141
|
-
if y <= max(p1y,p2y):
|
|
1142
|
-
if x <= max(p1x,p2x):
|
|
1143
|
-
if p1y != p2y:
|
|
1144
|
-
xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
|
|
1145
|
-
if p1x == p2x or x <= xints:
|
|
1146
|
-
inside = not inside
|
|
1147
|
-
p1x,p1y = p2x,p2y
|
|
1143
|
+
x, y, z = p
|
|
1144
|
+
p1x, p1y, p1z = polygon[0]
|
|
1148
1145
|
|
|
1149
|
-
|
|
1146
|
+
for i in range(n + 1):
|
|
1147
|
+
p2x, p2y, p2z = polygon[i % n]
|
|
1148
|
+
if y > min(p1y, p2y):
|
|
1149
|
+
if y <= max(p1y, p2y):
|
|
1150
|
+
if x <= max(p1x, p2x):
|
|
1151
|
+
if p1y != p2y:
|
|
1152
|
+
xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
|
|
1153
|
+
if x <= xinters:
|
|
1154
|
+
inside = not inside
|
|
1155
|
+
p1x, p1y, p1z = p2x, p2y, p2z
|
|
1150
1156
|
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1157
|
+
return inside
|
|
1158
|
+
|
|
1159
|
+
if is_point_inside_polygon(point, outer_boundary):
|
|
1160
|
+
for inner_boundary in inner_boundaries:
|
|
1161
|
+
if is_point_inside_polygon(point, inner_boundary):
|
|
1162
|
+
return False
|
|
1154
1163
|
|
|
1164
|
+
return True
|
|
1165
|
+
|
|
1166
|
+
return False
|
|
1167
|
+
|
|
1155
1168
|
if not isinstance(face, topologic.Face):
|
|
1156
1169
|
return None
|
|
1157
1170
|
if not isinstance(vertex, topologic.Vertex):
|
|
1158
1171
|
return None
|
|
1159
1172
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
flatFace = Face.Flatten(face)
|
|
1163
|
-
# Retrieve the needed transformations
|
|
1164
|
-
dictionary = Topology.Dictionary(flatFace)
|
|
1165
|
-
xTran = Dictionary.ValueAtKey(dictionary,"xTran")
|
|
1166
|
-
yTran = Dictionary.ValueAtKey(dictionary,"yTran")
|
|
1167
|
-
zTran = Dictionary.ValueAtKey(dictionary,"zTran")
|
|
1168
|
-
phi = Dictionary.ValueAtKey(dictionary,"phi")
|
|
1169
|
-
theta = Dictionary.ValueAtKey(dictionary,"theta")
|
|
1170
|
-
|
|
1171
|
-
vertex = Topology.Translate(vertex, -xTran, -yTran, -zTran)
|
|
1172
|
-
vertex = Topology.Rotate(vertex, origin=world_origin, x=0, y=0, z=1, degree=-phi)
|
|
1173
|
-
vertex = Topology.Rotate(vertex, origin=world_origin, x=0, y=1, z=0, degree=-theta)
|
|
1174
|
-
|
|
1175
|
-
# Test if Vertex is hovering above or below face
|
|
1176
|
-
if abs(Vertex.Z(vertex)) > tolerance:
|
|
1173
|
+
# Test the distance first
|
|
1174
|
+
if Vertex.Distance(vertex, face, includeCentroid=False) > tolerance:
|
|
1177
1175
|
return False
|
|
1178
|
-
|
|
1179
|
-
# Build 2D poly from flat face
|
|
1180
|
-
wire = Face.ExternalBoundary(flatFace)
|
|
1181
|
-
vertices = Wire.Vertices(wire)
|
|
1182
|
-
poly = []
|
|
1183
|
-
for v in vertices:
|
|
1184
|
-
poly.append([Vertex.X(v), Vertex.Y(v)])
|
|
1185
|
-
|
|
1186
|
-
# Use ray tracing method to test if vertex is inside the face
|
|
1187
|
-
status = ray_tracing_method(Vertex.X(vertex), Vertex.Y(vertex), poly)
|
|
1188
|
-
# Vertex is not inside
|
|
1189
|
-
if not status:
|
|
1190
|
-
return status
|
|
1191
|
-
|
|
1192
|
-
# If it is inside, we must check if it is inside a hole in the face
|
|
1193
|
-
internal_boundaries = Face.InternalBoundaries(flatFace)
|
|
1194
|
-
if len(internal_boundaries) == 0:
|
|
1195
|
-
return status
|
|
1196
1176
|
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1177
|
+
point = (Vertex.X(vertex), Vertex.Y(vertex), Vertex.Z(vertex))
|
|
1178
|
+
ob = Face.ExternalBoundary(face)
|
|
1179
|
+
ibs = Face.InternalBoundaries(face)
|
|
1180
|
+
outer_boundary = [(Vertex.X(v), Vertex.Y(v), Vertex.Z(v)) for v in Topology.Vertices(ob)]
|
|
1181
|
+
inner_boundaries = []
|
|
1182
|
+
for ib in ibs:
|
|
1183
|
+
inner_boundary = [(Vertex.X(v), Vertex.Y(v), Vertex.Z(v)) for v in Topology.Vertices(ib)]
|
|
1184
|
+
inner_boundaries.append(inner_boundary)
|
|
1185
|
+
status = point_inside_face(point, outer_boundary, inner_boundaries)
|
|
1205
1186
|
return status
|
|
1206
1187
|
|
|
1207
1188
|
@staticmethod
|