MoveFeature does not work when i am out of the rootComponent

MoveFeature does not work when i am out of the rootComponent

Mehrab.Nasrabadi
Participant Participant
861 Views
6 Replies
Message 1 of 7

MoveFeature does not work when i am out of the rootComponent

Mehrab.Nasrabadi
Participant
Participant

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). 

 

 

 

 

0 Likes
Accepted solutions (3)
862 Views
6 Replies
Replies (6)
Message 2 of 7

kandennti
Mentor
Mentor
Accepted solution

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

Mehrab.Nasrabadi
Participant
Participant
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!

0 Likes
Message 4 of 7

kandennti
Mentor
Mentor
Accepted solution

@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

Mehrab.Nasrabadi
Participant
Participant
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!
0 Likes
Message 6 of 7

kandennti
Mentor
Mentor
Accepted solution

@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

Mehrab.Nasrabadi
Participant
Participant

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.