Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Confused by normals retuned for simple box solid

tiktuk
Advocate

Confused by normals retuned for simple box solid

tiktuk
Advocate
Advocate

I am trying to do something to each face of a body where I need to look at each normal.

 

When listing the normals for a simple box I am getting this from the below script:

 

 

 

Body1
 6 faces found for Body1.
 Normal: (x: 1.00, y: 0.00, z: 0.00)
 Normal: (x: 0.00, y: 0.00, z: 1.00)
 Normal: (x: 0.00, y: -1.00, z: 0.00)
 Normal: (x: -1.00, y: 0.00, z: 0.00)
 Normal: (x: 0.00, y: 0.00, z: 1.00)
 Normal: (x: 0.00, y: 1.00, z: 0.00)

 

 

 

 Why is (x: 0.00, y: 0.00, z: 1.00) repeated? I expected one of them to have a negative Z.

 

The script:

 

 

 

#Author-
#Description-

import adsk.core, adsk.fusion, adsk.cam, traceback

app = adsk.core.Application.get()

# Function to convert a vector to a string
def vector_to_str(v: adsk.core.Vector3D):
    '''
    Converts a vector to a string.
    '''
    return '(x: {0:.2f}, y: {1:.2f}, z: {2:.2f})'.format(v.x, v.y, v.z)

# Function to list the normals of the faces of a body
def list_normals(body: adsk.fusion.BRepBody):
    # Log the amount of faces.
    app.log(f'{body.faces.count} faces found for {body.name}.')

    for face in body.faces:
        _, normal = face.geometry.evaluator.getNormalAtPoint(face.pointOnFace)
        app.log(f'Normal: {vector_to_str(normal)}')


def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        body = ui.selectEntity('Pick a body', 'SolidBodies').entity
        app.log(body.name)
        list_normals(body)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

 

0 Likes
Reply
Accepted solutions (1)
278 Views
2 Replies
Replies (2)

BrianEkins
Mentor
Mentor
Accepted solution

The bad normal is because you're using the geometry associated with the BRepFace instead of the face itself. The face's normal will always point "outside" of the solid, and the normal from the geometry should be considered arbitrary. Instead of getting the SurfaceEvaluator from the geometry, get it from the BRepFace. To do this, change your line 21 from this:

 

_, normal = face.geometry.evaluator.getNormalAtPoint(face.pointOnFace)

 

to this:

 

_, normal = face.evaluator.getNormalAtPoint(face.pointOnFace)

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
2 Likes

tiktuk
Advocate
Advocate

Thanks @BrianEkins , that makes all the difference 😄 !

0 Likes