Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for
Show  only  | Search instead for
Did you mean:

## How to tell if two faces meet in an 'inwards' or 'outwards' edge?

2 REPLIES 2
SOLVED
Message 1 of 3
189 Views, 2 Replies

## How to tell if two faces meet in an 'inwards' or 'outwards' edge?

Hi,

I'm trying tell the difference between Edge 1 and Edge 2 on the screenshot.

My first idea was to measure the angle between them and see which was larger. But the api returns 90 degrees / 1.57 radians between both A and B and B and C. Was hoping for 270 degrees in the case of Edge 1.

Any other way?

My code:

def get_angle_between_faces(app, ui):
import math
face1 = ui.selectEntity('Select face 1', 'PlanarFaces').entity
face2 = ui.selectEntity('Select face 2', 'PlanarFaces').entity
angle = math.degrees(app.measureManager.measureAngle(face1, face2).value)

# [Fusion 360 Help | Measure Sample | Autodesk](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-4b13c86c-7aa0-4555-b3e3-02f7d1b01d10)
print(f'Angle between the two faces: {angle}')

# [Fusion 360 Help | SurfaceEvaluator.getNormalAtPoint Method | Autodesk](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-602c29fe-5b96-4ce8-8c8b-4765ede9f7fb)
faceEval1 = face1.evaluator
(success, normal1) = faceEval1.getNormalAtPoint(face1.pointOnFace)

faceEval2 = face2.evaluator
(success, normal2) = faceEval2.getNormalAtPoint(face2.pointOnFace)

angle_between_normals = normal1.angleTo(normal2)
print(f'{angle_between_normals=}')

What are the correct terms for inwards and outwards corners btw?

Thanks!

2 REPLIES 2
Message 2 of 3

It's a bit tricky to figure out, but here's a function I wrote a while ago that does it. You pass in the edge that connects to planar faces, and it returns the angle between them. In your example, edge1 will return 270 degrees and edge2 will return 90 degrees.

# Measures the angle between two planar faces that share the input edge.
# The angle is measured with respect to the exterior of the face so that
# an internal corner will be 90 deg and and external corner will be 270 deg.
def angleBetweenFaces(edge):
try:
if edge.faces.count == 2:
# Get the faces that connect along the input edge.
face1 = edge.faces.item(0)
face2 = edge.faces.item(1)

# Get the middle of the edge.
(_, minParam, maxParam) = edgeEval.getParameterExtents()
midParam = (minParam + maxParam)/2
(_, midPoint) = edgeEval.getPointAtParameter(midParam)

# Get the normal of each face at the edge center.
ret = face1.evaluator.getNormalAtPoint(midPoint)
normal1 = ret[1]
ret = face2.evaluator.getNormalAtPoint(midPoint)
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 at the midpoint of the edge.
testParam = midParam + ((maxParam - minParam) * 0.001)
(_, testPoint) = edgeEval.getPointAtParameter(testParam)
edgeDir = midPoint.vectorTo(testPoint)
edgeDir.normalize()
if not coEdge.isOpposedToEdge:
edgeDir.scaleBy(-1)

# 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
else:
# This can occur for periodic surfaces and the edge where the face
# connects to itself.  We'll assume that it's a smooth connection
# and return 180 degrees.
return math.pi
except:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 3