-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdbutils.py
More file actions
185 lines (150 loc) · 6.79 KB
/
Copy pathdbutils.py
File metadata and controls
185 lines (150 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import math, logging
import traceback
import adsk.core
import adsk.fusion
def getAngleBetweenFaces(edge):
# Verify that the two faces are planar.
face1 = edge.faces.item(0)
face2 = edge.faces.item(1)
if face1 and face2:
if face1.geometry.objectType != adsk.core.Plane.classType() or face2.geometry.objectType != adsk.core.Plane.classType():
return 0
else:
return 0
# Get the normal of each face.
ret = face1.evaluator.getNormalAtPoint(face1.pointOnFace)
normal1 = ret[1]
ret = face2.evaluator.getNormalAtPoint(face2.pointOnFace)
normal2 = ret[1]
# Get the angle between the normals.
normalAngle = normal1.angleTo(normal2)
# Get the co-edge of the selected edge for face1.
if edge.coEdges.item(0).loop.face == face1:
coEdge = edge.coEdges.item(0)
elif edge.coEdges.item(1).loop.face == face1:
coEdge = edge.coEdges.item(1)
# Create a vector that represents the direction of the co-edge.
if coEdge.isOpposedToEdge:
edgeDir = edge.startVertex.geometry.vectorTo(edge.endVertex.geometry)
else:
edgeDir = edge.endVertex.geometry.vectorTo(edge.startVertex.geometry)
# Get the cross product of the face normals.
cross = normal1.crossProduct(normal2)
# Check to see if the cross product is in the same or opposite direction
# of the co-edge direction. If it's opposed then it's a convex angle.
if edgeDir.angleTo(cross) > math.pi/2:
angle = (math.pi * 2) - (math.pi - normalAngle)
else:
angle = math.pi - normalAngle
return angle
def findExtent(face, edge):
# faceNormal = adsk.core.Vector3D.cast(face.evaluator.getNormalAtPoint(face.pointOnFace)[1])
if edge.startVertex in face.vertices:
endVertex = edge.endVertex
else:
endVertex = edge.startVertex
return endVertex
def correctedEdgeVector(edge, refVertex):
if edge.startVertex.geometry.isEqualTo(refVertex.geometry):
return edge.startVertex.geometry.vectorTo(edge.endVertex.geometry)
else:
return edge.endVertex.geometry.vectorTo(edge.startVertex.geometry)
return False
def correctedSketchEdgeVector(edge, refPoint):
if edge.startSketchPoint.geometry.isEqualTo(refPoint.geometry):
return edge.startSketchPoint.geometry.vectorTo(edge.endSketchPoint.geometry)
else:
return edge.endSketchPoint.geometry.vectorTo(edge.startSketchPoint.geometry)
return False
def isEdgeAssociatedWithFace(face, edge):
# have to check both ends - not sure which way around the start and end vertices are
if edge.startVertex in face.vertices:
return True
if edge.endVertex in face.vertices:
return True
return False
def getCornerEdgesAtFace(face, edge):
#not sure which end is which - so test edge ends for inclusion in face
if edge.startVertex in face.vertices:
startVertex = edge.startVertex
else:
startVertex = edge.endVertex
#edge has 2 adjacent faces - therefore the face that isn't from the 3 faces of startVertex, has to be the top face edges
# returnVal = [edge1 for edge1 in edge.startVertex.edges if edge1 in face.edges]
logger = logging.getLogger(__name__)
returnVal = []
for edge1 in startVertex.edges:
if edge1 not in face.edges:
continue
logger.debug('edge {} added to adjacent edge list'.format(edge1.tempId))
returnVal.append(edge1)
if len(returnVal)!= 2:
raise NameError('returnVal len != 2')
return (returnVal[0], returnVal[1])
def getVertexAtFace(face, edge):
if edge.startVertex in face.vertices:
return edge.startVertex
else:
return edge.endVertex
return False
def getFaceNormal(face):
return face.evaluator.getNormalAtPoint(face.pointOnFace)[1]
def messageBox(*args):
adsk.core.Application.get().userInterface.messageBox(*args)
def getTopFace(selectedFace):
normal = getFaceNormal(selectedFace)
refPlane = adsk.core.Plane.create(selectedFace.vertices.item(0).geometry, normal)
refLine = adsk.core.InfiniteLine3D.create(selectedFace.vertices.item(0).geometry, normal)
refPoint = refPlane.intersectWithLine(refLine)
faceList = []
body = adsk.fusion.BRepBody.cast(selectedFace.body)
for face in body.faces:
if not normal.isParallelTo(getFaceNormal(face)):
continue
facePlane = adsk.core.Plane.create(face.vertices.item(0).geometry, normal)
intersectionPoint = facePlane.intersectWithLine(refLine)
# distanceToRefPoint = refPoint.distanceTo(intersectionPoint)
directionVector = refPoint.vectorTo(intersectionPoint)
distance = directionVector.dotProduct(normal)
# distanceToRefPoint = distanceToRefPoint* (-1 if direction <0 else 1)
faceList.append([face, distance])
sortedFaceList = sorted(faceList, key = lambda x: x[1])
top = sortedFaceList[-1]
refPoint = top[0].nativeObject.pointOnFace if top[0].assemblyContext else top[0].pointOnFace
return (top[0], refPoint)
def getTranslateVectorBetweenFaces(fromFace, toFace):
# returns absolute distance
logger = logging.getLogger(__name__)
normal = getFaceNormal(fromFace)
if not normal.isParallelTo(getFaceNormal(fromFace)):
return False
fromFacePlane = adsk.core.Plane.create(fromFace.vertices.item(0).geometry, normal)
fromFaceLine = adsk.core.InfiniteLine3D.create(fromFace.vertices.item(0).geometry, normal)
fromFacePoint = fromFacePlane.intersectWithLine(fromFaceLine)
toFacePlane = adsk.core.Plane.create(toFace.vertices.item(0).geometry, normal)
toFacePoint = toFacePlane.intersectWithLine(fromFaceLine)
translateVector = fromFacePoint.vectorTo(toFacePoint)
return translateVector
class HandlerHelper(object):
def __init__(self):
# Note: we need to maintain a reference to each handler, otherwise the handlers will be GC'd and SWIG will be
# unable to call our callbacks. Learned this the hard way!
self.handlers = [] # needed to prevent GC of SWIG objects
def make_handler(self, handler_cls, notify_method, catch_exceptions=True):
class _Handler(handler_cls):
def notify(self, args):
self.logger = logging.getLogger(__name__)
if catch_exceptions:
try:
notify_method(args)
except:
messageBox('Failed:\n{}'.format(traceback.format_exc()))
self.logger.exception('error termination')
for handler in self.logger.handlers:
handler.flush()
handler.close()
else:
notify_method(args)
h = _Handler()
self.handlers.append(h)
return h