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: 

Select specific face in API automatically

11 REPLIES 11
Reply
Message 1 of 12
oyvindTMNSU
1897 Views, 11 Replies

Select specific face in API automatically

how can I know the index of a face of a cube? This it what I want to do: 

Select a plane- draw a rectangle- extrude it- make new sketch on a specific face of that cube. Automatically, not by user selection. How to find/choose the wanted face?

11 REPLIES 11
Message 2 of 12
BrianEkins
in reply to: oyvindTMNSU

Here's a link to a paper I presented a couple of years ago at Autodesk University. There's a section called "Accessing Topology Objects" that specifically addresses your question but the rest of it will be useful to help you get a broader view of how it all works.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 12
kandennti
in reply to: oyvindTMNSU

Hi @oyvindTMNSU .

 

If it is a simple cube and direction, you can determine it by the center of gravity of the face.


This is not an index, but a sample of finding a BRepFace and creating a sketch text.

Fusion360API Python script
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        des :adsk.fusion.Design = app.activeProduct
        root :adsk.fusion.Component = des.rootComponent

        # get body
        body :adsk.fusion.BRepBody = root.bRepBodies[0]

        # get face
        # Judgment by the position of the center of gravity
        faces :adsk.fusion.BRepFaces = body.faces
        lst =[
            ['top', max(faces, key=(lambda f: f.centroid.z))],
            ['bottom', min(faces, key=(lambda f: f.centroid.z))],
            ['right', max(faces, key=(lambda f: f.centroid.x))],
            ['left', min(faces, key=(lambda f: f.centroid.x))],
            ['front', min(faces, key=(lambda f: f.centroid.y))],
            ['back', max(faces, key=(lambda f: f.centroid.y))]
        ]

        # create Sketch Text
        for name, face in lst:
            createText(name, face)

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

def createText(
    name :str,
    face :adsk.fusion.BRepFace
    ):

    comp :adsk.fusion.Component = face.body.parentComponent
    skt :adsk.fusion.Sketch = comp.sketches.addWithoutEdges(face)

    txts :adsk.fusion.SketchTexts = skt.sketchTexts
    txts.add(txts.createInput(name, 1, skt.modelToSketchSpace(face.centroid)))
Message 4 of 12
MichaelT_123
in reply to: oyvindTMNSU

Hi M?. OyvindTMNSU

 

The face(s) can be determined from the chain of processes leading to their creation.

Let's assume that a cube has been created by extrude feature.

Extruded profile's path segments give you indexes of side faces which can be accessed by extrudeFeat.sideFaces.

Cups of an extrude can be referenced by  extrudeFeat.startFaces and extrudeFeat.endFaces.

There are similar schemes available for other methods of face creation.

 

Regards

MichaelT

MichaelT
Tags (2)
Message 5 of 12
oyvindTMNSU
in reply to: MichaelT_123

Thank you.

It it obvious which of the 4 sides of the box extrude to choose. Like, is it always start counting from left to right or is it some kind of system at all? Meaning, how to differ between the 4 side faces of an extrude of a rectangle?

Message 6 of 12
MichaelT_123
in reply to: oyvindTMNSU

Hi M?. OyvindTMNSU

 

The answer is summarized in my previous post-sentence:

''Extruded profile's path segments give you indexes of side faces which can be accessed by extrudeFeat.sideFaces.item(idx).''

In other words, faces will likely correspond to separate line/curve segments constituting the extruded profileI use word likely here,  as based on my diligence it is not clearly stated in API, although the method works in practice. In order to be  absolutely sure one can check match between face's edges and profile's segments. It is however, quite expensive.

 

Regards

MichaelT

MichaelT
Message 7 of 12
oyvindTMNSU
in reply to: MichaelT_123

Ok. I will try to do some coding and see. Thanks!

Message 8 of 12
BrianEkins
in reply to: oyvindTMNSU

Relying on indices is usually risky. Even if it seems to work now it's possible it may not work in the future.  I prefer finding faces geometrically.  Here are a couple of approaches:

  1. From a face, you can get a SurfaceEvaluator object. It supports methods to a normal from the face. You can compare this normal with a vector you create that is the normal of the face you're looking for. If they match, you've found your face.
  2. Calculate a point in 3D space that should lie on the desired face.  On the root component, you can call the findBRepUsingPoint method and pass in the point and it will return the face.
---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 9 of 12
oyvindTMNSU
in reply to: BrianEkins

Thanks! I saw someting about that in the link you posted and i will try it!

Message 10 of 12
oyvindTMNSU
in reply to: BrianEkins

Thanks!

Would you mind to give me a quick example code doing this?:

 

Sketching a rectangle on an origin plane -> extrude it --> make a sketch on the end face.

 

Just to Kickstart me a bit...

Thanks in advance!

Message 11 of 12
BrianEkins
in reply to: oyvindTMNSU

Here's a small example that uses the findBRepUsingPoint method to find the face of the box. 

 

import adsk.core, adsk.fusion, traceback

def run(context):
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        des: adsk.fusion.Design = app.activeProduct
        root = des.rootComponent

        # Crate a sketch on the XY plane and draw a rectangle 10 x 7.
        sk = root.sketches.add(root.xYConstructionPlane)
        sk.sketchCurves.sketchLines.addTwoPointRectangle(adsk.core.Point3D.create(0,0,0),
                                                         adsk.core.Point3D.create(10,7,0))

        # Create an extrusion.
        prof = sk.profiles.item(0)
        boxHeight = adsk.core.ValueInput.createByReal(5)
        extrude = root.features.extrudeFeatures.addSimple(prof, boxHeight, 
                                    adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

        # Get the created body.
        body = extrude.bodies.item(0)

        # Find one of the side faces.
        foundFaces = root.findBRepUsingPoint(adsk.core.Point3D.create(10, 3.5, 2.5), 
                                             adsk.fusion.BRepEntityTypes.BRepFaceEntityType)

        # If the face was found, create a sketch and draw a rectangle on it.
        if foundFaces.count == 1:
            sideFace = foundFaces.item(0)

            # Create a sketch so the edges of the face aren't copied into the sketch.
            sk = root.sketches.addWithoutEdges(sideFace)

            # Define the corner points of the sketch in model space.
            modelPnt1 = adsk.core.Point3D.create(10, 1, 1)
            modelPnt2 = adsk.core.Point3D.create(10, 6, 4)

            # Get the equivalent points in sketch space.
            skPnt1 = sk.modelToSketchSpace(modelPnt1)
            skPnt2 = sk.modelToSketchSpace(modelPnt2)

            # Draw the rectangle and extrude it.
            sk.sketchCurves.sketchLines.addTwoPointRectangle(skPnt1, skPnt2)
            prof = sk.profiles.item(0)
            root.features.extrudeFeatures.addSimple(prof, adsk.core.ValueInput.createByReal(2), 
                                            adsk.fusion.FeatureOperations.JoinFeatureOperation)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

Finding the face is the easy part. There are some other things you need to understand once you've found that face to successfully draw the sketch for the next extrusion. Every sketch has its own coordinate system and the geometry you draw in that sketch is with respect to that coordinate system. Creating a sketch on the base XY construction plane is a special case where the sketch coordinate system and the model coordinate system line up with one another.  If you create a sketch on the other base construction planes, their origins will align with the model origin but the orientations will be different.

 

When creating a sketch on a face, Fusion has its own algorithm for determining the origin and orientation of the sketch that isn't always predictable. In the sample above, I calculate the corner points of the rectangle in model space and then use the modelToSketchSpace method of the sketch to get the equivalent point in sketch space and then use that to create the rectangle. Hopefully, that makes sense.

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 12 of 12
oyvindTMNSU
in reply to: BrianEkins

I see! 

Thank you very much! I will try to see if I manage to use it in other settings as well

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report