Select a Face and get XYZ of 4 vertices relative to Root origin

Select a Face and get XYZ of 4 vertices relative to Root origin

info83PHN
Advocate Advocate
877 Views
3 Replies
Message 1 of 4

Select a Face and get XYZ of 4 vertices relative to Root origin

info83PHN
Advocate
Advocate

Looking for a way ( API ) to ask the user to Click on a Face ( which may be part of a body in a sub component ), and return the XYZ coordinates of the 4 corners, relative to the origin point / system of the root component.

 

I found some code to pause the script so the user can select a Face, but not sure what I am looking for after this

unsafe_faces = []
selected_face = ui.selectEntity("Please select Face 1", 'PlanarFaces')
0 Likes
Accepted solutions (2)
878 Views
3 Replies
Replies (3)
Message 2 of 4

kandennti
Mentor
Mentor
Accepted solution

Hi @info83PHN .

 

Since there are no images or sample data, your assumptions and my assumptions may differ, but I have created a sample script.

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core


def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        # Face Selection
        try:
            sel: adsk.core.Selection = ui.selectEntity("Please select Face 1", 'PlanarFaces')
        except:
            # Pressing the ESC key raises an exception.
            return
        face: adsk.fusion.BRepFace = sel.entity

        # Retrieving the state of the location as seen by the root component is easy with the TemporaryBRepManager.copy method.
        tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get()
        tempBody: adsk.fusion.BRepBody = tmpMgr.copy(face)
        tempFace: adsk.fusion.BRepFace = tempBody.faces[0]

        # Get the boundary box with the method measureManager.getOrientedBounding.
        measMgr: adsk.core.MeasureManager = app.measureManager
        bbox: adsk.core.OrientedBoundingBox3D = measMgr.getOrientedBoundingBox(
            tempFace,
            adsk.core.Vector3D.create(0,1,0),
            adsk.core.Vector3D.create(1,0,0)
        )

        # Calculate 4 points from the boundary box.
        points = [bbox.centerPoint.copy() for _ in range(4)]
        offsetX = bbox.width * 0.5
        offsetY = bbox.length * 0.5
        vectors = [
            adsk.core.Vector3D.create(offsetX, offsetY, 0),
            adsk.core.Vector3D.create(-offsetX, offsetY, 0),
            adsk.core.Vector3D.create(offsetX, -offsetY, 0),
            adsk.core.Vector3D.create(-offsetX, -offsetY, 0),
        ]
        [p.translateBy(v) for p, v in zip(points, vectors)]

        # Show results.
        coordinates = [str(p.asArray()) for p in points]
        ui.messageBox('\n'.join(coordinates))

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

BrianEkins
Mentor
Mentor
Accepted solution

There are some basic principles about the internals of Fusion you should understand. The first is how a solid is represented internally, which you can learn about in Fusion 360 Solids and Surfaces. The second is how data is structured, particularly components and occurrences in Document and Assembly Structure.

 

A face is bounded by edges, and edges are connected by vertices. A rectangular face will have four vertices, one at each corner, but generally, a face can be any shape and have zero to n vertices. A circular face at the end of a cylinder doesn't have any vertices.

 

A body exists within a component, and each component is represented as an occurrence in an assembly. You can have multiple instances of a component in the same assembly, each in a different position. When you select a face, the BRepFace returned is in the context of the root component, and querying its edges and faces will return the data relative to the world coordinate system. You don't need to do anything special. Here's some code that will print out the coordinates of each face vertex

import traceback
import adsk.fusion
import adsk.core

def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        # Face Selection
        try:
            sel: adsk.core.Selection = ui.selectEntity("Please select Face 1", 'PlanarFaces')
        except:
            # Pressing the ESC key raises an exception.
            return
        face: adsk.fusion.BRepFace = sel.entity

        app.log(' ')
        app.log('Vertex Report')
        vertCount = 0
        for vertex in face.vertices:
            vertCount += 1
            app.log(f'   Vertex {vertCount}: {vertex.geometry.asArray()}')
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

.

 

 

 

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

info83PHN
Advocate
Advocate

Thank You to both kandennti and Brian for these methods - both very helpful !

0 Likes