Moving a Component Help

Moving a Component Help

rusty.bird
Advocate Advocate
551 Views
4 Replies
Message 1 of 5

Moving a Component Help

rusty.bird
Advocate
Advocate

Hello I am making a script to move a component from a selected point to another selected point but I am getting an error at the end.  It works if I move a body but not a component.  Here is the code below:

 

# Get a body by having the user select one.
        body: adsk.fusion.Components = ui.selectEntity('Select a component.', 'Occurrences').entity
        
        # Have an entity selected that represents a point.
        # This can be a Vertex, Sketch Point, or Construction Point.
        pointEnt = ui.selectEntity('Select a point entity', 'ConstructionPoints, SketchPoints, Vertices').entity
        
        # Get the XYZ position of the point in model space.
        pnt1: adsk.core.Point3D = None
        if pointEnt.objectType == adsk.fusion.SketchPoint.classType():
            skPoint: adsk.fusion.SketchPoint = pointEnt
            pnt1 = skPoint.worldGeometry
        else:
            pnt1 = pointEnt.geometry
            
        # Select a Second Point
        pointEnt2 = ui.selectEntity('Select a point entity', 'ConstructionPoints, SketchPoints, Vertices').entity
        
        # Get the XYZ position of the point in model space.
        pnt2: adsk.core.Point3D = None
        if pointEnt2.objectType == adsk.fusion.SketchPoint.classType():
            skPoint2: adsk.fusion.SketchPoint = pointEnt2
            pnt2 = skPoint2.worldGeometry
        else:
            pnt2 = pointEnt2.geometry
        
        # Create a matrix that defines the translation from point 1 to point 
        trans: adsk.core.Matrix3D = adsk.core.Matrix3D.create()
        trans.translation = pnt1.vectorTo(pnt2)
        
        # Create a move feature using the matrix.
        moveFeatures = design.rootComponent.features.moveFeatures
        inputEnts = adsk.core.ObjectCollection.create()
        inputEnts.add(body)
        moveInput = moveFeatures.createInput(inputEnts, trans)
        moveFeatures.add(moveInput)

 

0 Likes
Accepted solutions (1)
552 Views
4 Replies
Replies (4)
Message 2 of 5

kandennti
Mentor
Mentor
Accepted solution

Hi @rusty.bird .

 

It seems that the movement of occurrence is not done by MoveFeature, but by Occurrence.transform property or transform2 property.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7fb9ea55-5c24-4c27-b1c4-2e92f42774f7 

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7231EE6E-FB14-4370-AEE5-F9AE7419B97B 


※The document states that the transform property is obsolete, but I was able to use it. I don't think the transform property should be discontinued because what you get is different.

 

After changing the transform/transform2 property, the position is not fixed, so you need to do the following.

des.snapshots.add()

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/transformation-on-occurrence-getting-reset... 

0 Likes
Message 3 of 5

rusty.bird
Advocate
Advocate

Thanks, I removed the create move feature section in the code and it mostly worked.

 

body.transform2 = trans
design.snapshots.add()

 

 But I noticed it is not moving to the correct position.  I am assuming something to do with the vectors is wrong.  

Message 4 of 5

rusty.bird
Advocate
Advocate

I Found the Issue it was with my transform.  Here is the updated code that works.

trans: adsk.core.Matrix3D = adsk.core.Matrix3D.create() 
trans.translation = pnt1.vectorTo(pnt2)
        
transNew = body.transform2
transNew.transformBy(trans)
body.transform2 = transNew
Message 5 of 5

kandennti
Mentor
Mentor

@rusty.bird .

 

I am getting confused too, so I did a test to confirm.
This was tested based on ver 2.0.15509.

 

Create a component (level2) within the root component (level1) and then a component (level3).
Each component is created with XYZ+10.0.
Activate the level3 component, create a sketch on the XY plane, and draw a square.
Constrain only the lower left point by 10 mm in the XY direction.
Create the body by extrusion.
Create construction points at the vertices near the origin.
"Sketch point", "body vertex", and "construction point" all remain in the same position in the level3 component.
(The f3d file of this data is attached.)

1.png

 

Using this data, the following script is executed.
The text command is designed to output the coordinate values of the selected points.
We expect the output to be the coordinate values (3.0,3.0,2.0) from the origin of level1.

 

 

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.fusion as fusion

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

        msg: str = 'Select Point'
        selFilter: str = 'ConstructionPoints, SketchPoints, Vertices'
        sel: core.Selection = selectEnt(msg, selFilter)
        if not sel:
            return

        pointEntity = sel.entity
        point: core.Point3D = get_point3d(pointEntity)
        dump_point(point, f'{pointEntity.objectType} -> ')

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


def get_point3d(
    pointEntity
) -> core.Point3D:

    point: core.Point3D = None
    if pointEntity.objectType == fusion.SketchPoint.classType():
        point = pointEntity.worldGeometry
    else:
        point = pointEntity.geometry

    return point


def selectEnt(
    msg: str,
    filterStr: str
) -> core.Selection:

    try:
        app: core.Application = core.Application.get()
        ui: core.UserInterface = app.userInterface
        sel = ui.selectEntity(msg, filterStr)
        return sel
    except:
        return None


def dump_point(pnt: core.Point3D, msg: str = ''):
    app: core.Application = core.Application.get()
    app.log(f'{msg}{pnt.asArray()}')

 

The reason why selectEntity is used to select an element is because the selected element will be a proxy.

 

Here is the actual output.

 

 adsk::fusion::SketchPoint -> (3.0, 3.0, 2.0)
 adsk::fusion::BRepVertex -> (3.0, 3.0, 2.0)
 adsk::fusion::ConstructionPoint -> (2.0, 2.0, 1.0)

 

SketchPoint(worldGeometry) and BRepVertex are as expected, but only the ConstructionPoint is different.

 

The construction point coordinates are from the origin of the component one level above (level2).

1.png
I cannot determine if this is a bug or a specification. Unfortunately, the origin of each component is also greatly affected by the construction point.
I am sure this is a very confusing situation.

0 Likes