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: 

MoveFeature does not work when i am out of the rootComponent

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Mehrab.Nasrabadi
329 Views, 6 Replies

MoveFeature does not work when i am out of the rootComponent

Hello,

I have modified a sample that goes through all bodies and moves them, first all bodies in the rootComponent and then all bodies in the other occurences and compnents. When I apply the MoveFeature in the rootComponent it works without problems but when I apply the MoveFeature in the components I get this error:

 

Failed:

Traceback (most recent call last):

File "C:/Users/Admin/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/NewScript6/NewScript6.py", line 109, in run

moveFeats.add(moveFeatureInput)

File "C:\Users/Admin/AppData/Local/Autodesk/webdeploy/production/540c9578410bc15ff261605667cfced82aa9ac6d/Api/Python/packages\adsk\fusion.py", line 27957, in add

return _fusion.MoveFeatures_add(self, input)

RuntimeError: 3 : object is not in the assembly context of this component

 

Can someone please explain to me why and what I should do differently?
I have the feeling that the movefeature only works with bodies in the rootComponent but I am not sure. Does anyone know how to address a body in a component to move it?

 

Also, how can I use the MoveFeaturePointToPosition to move a body?


I am grateful for any helpful hints and especially for a small sample code.

Greetings 🙂

 

 @BrianEkins  I have often come across your posts and have also seen and read your course on
Customizing Fusion 360 Using its Programming Interface at Autodesk University but apparently didn't understand something 😄 If you would have the time and kindness to help me with my problem I would be very honoured!

 

 

 

try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        ui.messageBox(str(bodiesDict))
        
        design = app.activeProduct
        if not design:
            ui.messageBox('No active Fusion design', 'No Design')
            return

        # Get the root component of the active design.
        rootComp = design.rootComponent
        
        # Iterate over any bodies in the root component.
        
        for j in range(0, rootComp.bRepBodies.count):
            body = rootComp.bRepBodies.item(j)

            bodies = adsk.core.ObjectCollection.create()
            bodies.add(body)

            features = rootComp.features
            vector = adsk.core.Vector3D.create(50,50, 0)
            transform = adsk.core.Matrix3D.create()
            transform.translation = vector

            # Create a move feature
            moveFeats = features.moveFeatures
            moveFeatureInput = moveFeats.createInput(bodies, transform)
            moveFeats.add(moveFeatureInput)

        # here starts the second part-----------------------------------
        # Iterate through all of the occurrences in the assembly.
        for i in range(0, rootComp.allOccurrences.count):
            occ = rootComp.allOccurrences.item(i)

            # Get the associated component.
            comp = occ.component
            
            # Iterate over all of the bodies within the component.
            for j in range(0, comp.bRepBodies.count):
                body = comp.bRepBodies.item(j)
                thisBody = body.name

                features = rootComp.features
                vector = adsk.core.Vector3D.create(50,50, 0)
                transform = adsk.core.Matrix3D.create()
                transform.translation = vector
                
                bodies = adsk.core.ObjectCollection.create()
                bodies.add(body)
            
                # Create a move feature
                moveFeats = features.moveFeatures
                moveFeatureInput = moveFeats.createInput(bodies, transform)
                moveFeats.add(moveFeatureInput) # <--- this line fails, i think  because bodies in the line above is a adsk.core.ObjectCollection.create() filled with body = comp.bRepBodies.item(j) and not like in the rootComponent body = rootComp.bRepBodies.item(j). 

 

 

 

 

6 REPLIES 6
Message 2 of 7

Hi @Mehrab.Nasrabadi .

 

It is a Proxy issue.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-88A4DB43-CFDD-4CFF-B124-7EE67915A07A 

 

If the root component is executable and the occurrence of an error occurs in the occurrence component, it is almost certain that the Proxy is involved.

・・・
            # Iterate over all of the bodies within the component.
            for j in range(0, comp.bRepBodies.count):
                body = comp.bRepBodies.item(j)
                # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-88A4DB43-CFDD-4CFF-B124-7EE67915A07A
                body = body.createForAssemblyContext(occ)
                thisBody = body.name
・・・
Message 3 of 7

thank you very much it worked and i think i understand it a little more!

Do you maybe have also a clue about how to use the MoveFeaturePointToPosition ? Maybe i should start a new question right?

But Thank you very much i wish you a long and healthy life!

Message 4 of 7

@Mehrab.Nasrabadi .

 

There was no sample of the defineAsPointToPosition method, so I created one.

I used the MoveFeatures.createInput2 method, but I think the createInput method would also work.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-GUID-GUID-12b98475-8e53-4427-aa87-05f8c8095a... 

# Fusion360API Python script

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

def run(context):
    ui = core.UserInterface.cast(None)
    try:
        app: core.Application = core.Application.get()
        ui = app.userInterface
        app.documents.add(core.DocumentTypes.FusionDesignDocumentType)
        des: fusion.Design = app.activeProduct
        des.designType = fusion.DesignTypes.ParametricDesignType
        root: fusion.Component = des.rootComponent


        # *** create body - root ***
        body: fusion.BRepBody = create_box(root)
        body.name = 'Root'

        objs: core.ObjectCollection = core.ObjectCollection.create()
        objs.add(body)

        # move body
        moveFeats: fusion.MoveFeatures = root.features.moveFeatures
        moveIpt: fusion.MoveFeatureInput = moveFeats.createInput2(objs)

        moveIpt.defineAsPointToPosition(
            body.vertices[0],
            core.ValueInput.createByReal(1),
            core.ValueInput.createByReal(2),
            core.ValueInput.createByReal(3),
            True
        )
        moveFeats.add(moveIpt)


        # *** create body - Occurrence ***
        occ: fusion.Occurrence = root.occurrences.addNewComponent(
            get_matrix()
        )
        body = create_box(occ.component)
        body.name = 'Occurrence_DesignSpace'
        proxyBody: fusion.BRepBody = body.createForAssemblyContext(occ)

        objs: core.ObjectCollection = core.ObjectCollection.create()
        objs.add(proxyBody)

        # move body - DesignSpace
        moveFeats = occ.component.features.moveFeatures
        moveIpt = moveFeats.createInput2(objs)

        moveIpt.defineAsPointToPosition(
            body.vertices[0],
            core.ValueInput.createByReal(1),
            core.ValueInput.createByReal(2),
            core.ValueInput.createByReal(3),
            True # <- DesignSpace
        )
        moveFeats.add(moveIpt)


        # *** create body - Occurrence ***
        occ: fusion.Occurrence = root.occurrences.addNewComponent(
            get_matrix()
        )
        body = create_box(occ.component)
        body.name = 'Occurrence_ComponentSpace'
        proxyBody: fusion.BRepBody = body.createForAssemblyContext(occ)

        objs: core.ObjectCollection = core.ObjectCollection.create()
        objs.add(proxyBody)

        # move body - ComponentSpace
        moveFeats = occ.component.features.moveFeatures
        moveIpt = moveFeats.createInput2(objs)

        moveIpt.defineAsPointToPosition(
            body.vertices[0],
            core.ValueInput.createByReal(1),
            core.ValueInput.createByReal(2),
            core.ValueInput.createByReal(3),
            False # <- ComponentSpace
        )
        moveFeats.add(moveIpt)
        ui.messageBox('Done')

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


def get_matrix(
    ) -> core.Matrix3D:

    mat: core.Matrix3D = core.Matrix3D.create()
    mat.setToRotation(
        math.radians(30),
        core.Vector3D.create(1,0,0),
        core.Point3D.create(0,0,0),
    )
    mat.translation = core.Vector3D.create(
        1,
        2,
        3,
    )

    return mat


def create_box(
    comp: fusion.Component
    ) -> fusion.BRepBody:

    tmpMgr: fusion.TemporaryBRepManager = fusion.TemporaryBRepManager.get()
    box: fusion.BRepBody = tmpMgr.createBox(
        core.OrientedBoundingBox3D.create(
            core.Point3D.create(1,2,3),
            core.Vector3D.create(0,1,0),
            core.Vector3D.create(1,0,0),
            4,
            5,
            6,
        )
    )

    baseFeat: fusion.BaseFeature = comp.features.baseFeatures.add()
    bodies: fusion.BRepBodies = comp.bRepBodies
    try:
        baseFeat.startEdit()
        bodies.add(box, baseFeat)
    except:
        pass
    finally:
        baseFeat.finishEdit()

    return baseFeat.bodies[0]

 

 

Message 5 of 7

Thank you very much also for that Sample, I am sure that Fusion should add it to the Samples!

But I have a question on that part:
moveIpt.defineAsPointToPosition(
body.vertices[0],
core.ValueInput.createByReal(1),
core.ValueInput.createByReal(2),
core.ValueInput.createByReal(3),
False # <- ComponentSpace
)
How can I use instead of body.vertices[0] a specific point I chose by myself? For example I want to take the origin of the component before and put it on the new created Component origin. I tried differnt kinds of points but i always get an error. Do you have any hints?

I am very grateful for your help! Thank you!
Message 6 of 7

@Mehrab.Nasrabadi .

 

The following sample creates a new component (occurrence) and stops waiting for the origin to be selected after the body is created.
After selecting the origin, the body is moved.

# Fusion360API Python script

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

def run(context):
    ui = core.UserInterface.cast(None)
    try:
        app: core.Application = core.Application.get()
        ui = app.userInterface
        app.documents.add(core.DocumentTypes.FusionDesignDocumentType)
        des: fusion.Design = app.activeProduct
        des.designType = fusion.DesignTypes.ParametricDesignType
        root: fusion.Component = des.rootComponent

        # *** create body - Occurrence ***
        occ: fusion.Occurrence = root.occurrences.addNewComponent(
            get_matrix()
        )
        occ.component.isOriginFolderLightBulbOn = True

        body = create_box(occ.component)
        body.name = 'Occurrence_ComponentSpace'
        proxyBody: fusion.BRepBody = body.createForAssemblyContext(occ)

        objs: core.ObjectCollection = core.ObjectCollection.create()
        objs.add(proxyBody)

        # select point
        msg: str = 'Select New Component Origin Point'
        selFilter: str = 'ConstructionPoints'
        sel: core.Selection = selectEnt(msg, selFilter)
        if not sel:
            return

        basePoint: fusion.ConstructionPoint = sel.entity

        # move body
        moveFeats = occ.component.features.moveFeatures
        moveIpt = moveFeats.createInput2(objs)

        moveIpt.defineAsPointToPosition(
            basePoint,
            core.ValueInput.createByReal(1),
            core.ValueInput.createByReal(2),
            core.ValueInput.createByReal(3),
            False
        )
        moveFeats.add(moveIpt)

        ui.messageBox('Done')

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


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 get_matrix(
    ) -> core.Matrix3D:

    mat: core.Matrix3D = core.Matrix3D.create()
    mat.setToRotation(
        math.radians(30),
        core.Vector3D.create(1,0,0),
        core.Point3D.create(0,0,0),
    )
    mat.translation = core.Vector3D.create(
        1,
        2,
        3,
    )

    return mat


def create_box(
    comp: fusion.Component
    ) -> fusion.BRepBody:

    tmpMgr: fusion.TemporaryBRepManager = fusion.TemporaryBRepManager.get()
    box: fusion.BRepBody = tmpMgr.createBox(
        core.OrientedBoundingBox3D.create(
            core.Point3D.create(1,2,3),
            core.Vector3D.create(0,1,0),
            core.Vector3D.create(1,0,0),
            4,
            5,
            6,
        )
    )

    baseFeat: fusion.BaseFeature = comp.features.baseFeatures.add()
    bodies: fusion.BRepBodies = comp.bRepBodies
    try:
        baseFeat.startEdit()
        bodies.add(box, baseFeat)
    except:
        pass
    finally:
        baseFeat.finishEdit()

    return baseFeat.bodies[0]
Message 7 of 7

Thank you very much for your effort. I appreciate that a lot.

But i meant something more like:
the originPoint shall be the origin of the original component and the body shall move from this origin to a new origin of the component to be created. and i assign all variables myself except the origin of the component whose body i have selected, which should later have the same orientation and actually also the same rotation but somehow i can't use a transformation matrix and only rotate around one axis

 

occ = rootComp.allOccurrences.item(i)
comp = occ.component
originPoint = comp.originConstructionPoint
objs: core.ObjectCollection = core.ObjectCollection.create()
objs.add(proxyBody)

newCompOriX = float # here i can define my own paramters
newCompOriY = float
newCompOriZ = float

# then i create a new component at that point
occ2: fusion.Occurrence = rootComp.occurrences.addNewComponent(
get_matrix(newCompOriX, newCompOriZ, newCompOriY)
)
occ2.component.isOriginFolderLightBulbOn = True


# to put originPoint into right assembly context with right occ was a tough lesson for me :D
# two occ because one before move and one where it should moved to so i get the body in the same orientation
# before. Right now i am struggleing how i can move that body into that new Component and how i can rotate
# the orientation of the created component and moved body over more than one axis

originPoint: fusion.ConstructionPoint = originPoint.createForAssemblyContext(occ)

moveFeats: fusion.MoveFeatures = rootComp.features.moveFeatures
moveIpt: fusion.MoveFeatureInput = moveFeats.createInput2(objs)

# # move body
moveFeats = occ.component.features.moveFeatures
moveIpt = moveFeats.createInput2(bodies)

moveIpt.defineAsPointToPosition(
originPoint,
core.ValueInput.createByReal(newCompOriX),
core.ValueInput.createByReal(newCompOriZ),
core.ValueInput.createByReal(newCompOriY),
True
)
moveFeats.add(moveIpt)

 

 i also like very much that clicking on the selected point in your sample and will save it 😉 . Thank you also for that and all of the samples.

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