Hi,
I developed a function for that, and it worked in my tests:
import adsk, adsk.core, adsk.fusion, adsk.cam, traceback
import math
app = adsk.core.Application.get()
doc = app.activeDocument
des: adsk.fusion.Design = adsk.fusion.Design.cast(app.activeProduct)
root = des.rootComponent
def is_edge_clockwise(
edge: adsk.fusion.BRepEdge,
body_center: adsk.core.Point3D,
face_centroid: adsk.core.Point3D,
) -> bool:
normal_vector = body_center.vectorTo(face_centroid)
normal_vector.normalize()
vector1: adsk.core.Vector3D = body_center.vectorTo(edge.startVertex.geometry)
vector2: adsk.core.Vector3D = body_center.vectorTo(edge.endVertex.geometry)
cp = vector1.crossProduct(vector2)
cp.normalize()
return(abs(cp.angleTo(normal_vector)) > 0.5 * math.pi)
def check_direction_of_face_edges(face: adsk.fusion.BRepFace, body_center: adsk.core.Point3D) -> None:
for n, edge in enumerate(face.edges):
app.log(f'{n=} is_clockwise={is_edge_clockwise(edge, body_center, face.centroid)}')
# Uncomment next line to add marks next to the start of every edge to check direction visually
#add_mark_at_beginning_of_edge(edge, f'{n}')
def run(context) -> None:
try:
face = root.bRepBodies[0].faces[7]
check_direction_of_face_edges(face, root.bRepBodies[0].getPhysicalProperties().centerOfMass)
except:
app.log('Failed:\n{}'.format(traceback.format_exc()))
adsk.terminate()
def add_mark_at_beginning_of_edge(edge: adsk.fusion.BRepEdge, text: str) -> None:
try:
evaltr = edge.evaluator
_, stParam, enParam = evaltr.getParameterExtents()
_, mark_point = evaltr.getPointAtParameter(stParam + (enParam-stParam)*.15)
if root.customGraphicsGroups.count:
cus_graphics = root.customGraphicsGroups[0]
else:
cus_graphics = root.customGraphicsGroups.add()
font_name = 'Arial'
text_size = 2.0
billboard_effect = adsk.fusion.CustomGraphicsBillBoard.create(None)
show_through_color = adsk.fusion.CustomGraphicsShowThroughColorEffect.create(
adsk.core.Color.create(0, 0, 250, 255), 1.0)
transform = adsk.core.Matrix3D.create()
transform.translation = adsk.core.Vector3D.create(mark_point.x, mark_point.y, mark_point.z)
text_graphics: adsk.fusion.CustomGraphicsText = cus_graphics.addText(text, font_name, text_size, transform)
text_graphics.billBoarding = billboard_effect
text_graphics.color = show_through_color
except:
app.log(f'Failed:\n{traceback.format_exc()}')
The function is is_edge_clockwise() and have three parameters:
edge : the edge to analyze
body_center: body center point
face_centroid: face centroid where the edge belongs to
You can uncomment the line #29 in order to get some marks (edge index #) next to the start of each edge, just to visually check the results.
This is one of the tests I made:

I highlighted in red the edge that is clockwise and with red the counter-clockwise.
TO TEST: you just need some a design with some body on it, and in line #33 choose the body and face you want to analyze the edges to.
I hope this can help you. Let me know if it works for you.
Regards,
Jorge Jaramillo