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: 

Rotate object to be perpendicular to a selected CircularEdge plane

1 REPLY 1
Reply
Message 1 of 2
ll100avgas
247 Views, 1 Reply

Rotate object to be perpendicular to a selected CircularEdge plane

Hi,

 

I'm trying to create a script that places screw instances to the list of selected screw holes on a body. Currently it can find the hole pivot (origin) and can put the screw into that. Currently it works if the screw is parallel to the hole. If the whole has an angle with the screw the script puts the screw in a wrong direction.

 

Here is the code I have currently:

 

                    command = args.firingEvent.sender
                    eventArgs = adsk.core.CommandEventArgs.cast(args)

                    # Get the values from the command inputs. 
                    inputs = eventArgs.command.commandInputs

                    numberOfSelectedEdge = inputs.itemById(edgeSelectionInputId).selectionCount
                    # screw:
                    selectedBodyToInstantiate = inputs.itemById(bodySelectionInputId).selection(0).entity
                    # holes to put screw:
                    selectedEdges = []
                    for i in range (0, numberOfSelectedEdge ):
                        selectedEdges.append(inputs.itemById(edgeSelectionInputId).selection(i).entity)
                    
                    #ui.messageBox(('selected: {} ').format(selectedEdges))

                    for edge in selectedEdges:
                        ent = edge

                        circGeom = ent.geometry
                
                        center = getCircleGeometryInfo(circGeom)

                        # The second point is defined using a known coordinate.
                        p = selectedBodyToInstantiate.transform.translation
                        pnt1 = adsk.core.Point3D.create(p.x, p.y, p.z)
                        pnt2 = adsk.core.Point3D.create(center.x, center.y, center.z)

                        # Create a matrix that defines the translation from point 1 to point 2.
                        trans: adsk.core.Matrix3D = adsk.core.Matrix3D.create()
                        trans.translation = pnt1.vectorTo(pnt2)

                        addResult = design.activeComponent.occurrences.addExistingComponent(selectedBodyToInstantiate.component, trans)

 

This places the screw to the pivot (center) of circle, but as you can see in the attachment, the angle is wrong. My plan is to calculate a vector that is perpendicular to the CircularEdge plane (so a vector that goes through the hole). Then pick the same for the screw (ie. picking the CircularEdge under the screw head) calculate that vector as well, and transform the second one to the first one somehow to take the rotation. This sounds easy, but I do not know where to start, I'm not familiar with the API...

 

(the whole stuff is needed because the Align described here: https://forums.autodesk.com/t5/fusion-360-api-and-scripts/api-access-to-align-components-function/td... works only for two selection, and I cannot find the programmatical way of joining/aligning two objects in Fusion 360)

 

Thanks for your help!

1 REPLY 1
Message 2 of 2
BrianEkins
in reply to: ll100avgas

The code below replaces your for loop where it builds a matrix for each bolt. It does this by getting the planar face the edge connects to and using the normal of that face as the Z-axis. It then creates arbitrary Y and Z axes but makes sure they are perpendicular to each other, that they define a right-handed coordinate system, and are unit vectors. It then creates a matrix using this data and uses that matrix to place the bolt. You might need to adjust this depending on how your bolt is defined. For mine, the Z-axis comes out of the head of the bolt, and the origin is at the base where the shaft meets the head.

 

edge: adsk.fusion.BRepEdge = None
for edge in selectedEdges:
    # Get the planar face for the edge.
    planeFace: adsk.fusion.BRepFace = None
    if edge.faces.item(0).geometry.objectType == adsk.core.Plane.classType():
        planeFace = edge.faces.item(0)
    elif edge.faces.item(1).geometry.objectType == adsk.core.Plane.classType():
        planeFace = edge.faces.item(1)

    # Get the normal from the face.
    zVec: adsk.core.Vector3D = None
    (_, zVec) = planeFace.evaluator.getNormalAtPoint(planeFace.pointOnFace)

    # Create an arbitrary vector that is different than the normal. This will
    # be used to define the X axis.
    tempY = adsk.core.Vector3D.create(zVec.x + 1, zVec.y + 2, zVec.z + 3)
    xVec = zVec.crossProduct(tempY)
    xVec.normalize()
    yVec = zVec.crossProduct(xVec)

    circGeom: adsk.core.Circle3D = edge.geometry
    origin = circGeom.center

    trans = adsk.core.Matrix3D.create()
    trans.setWithCoordinateSystem(origin, xVec, yVec, zVec)

    bolt = root.occurrences.addExistingComponent(boltComp, trans)

 

Here's an image illustrating the origin of the bolt and an example part where I picked several edges in different orientations and it correctly positioned the bolt.

 

Bolt.png

 

 

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

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report