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: 

How do I move / rotate the mesh?

4 REPLIES 4
Reply
Message 1 of 5
shutov441-vuz
867 Views, 4 Replies

How do I move / rotate the mesh?

Hi,

I have a task. I need to rotate and move imported stl model, i do it like this:

 

...
dlg = ui.createFileDialog()
dlg.title = 'Open STL File'
dlg.filter = 'Model (*.stl);;All Files (*.*)'
if dlg.showOpen() != adsk.core.DialogResults.DialogOK :
   return
filename = dlg.filename
ModelStl = root.meshBodies
ModelStl.add(filename, adsk.fusion.MeshUnits.CentimeterMeshUnit)
...

 

and then i should to rotate and move this model. I found this topic

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/bug-move-feature-is-broken/m-p/9223668

it works fine, but i need to do it inside one script. I tried to move the mesh like a default object, but it throws errors.

something like this...

rotateModel = adsk.core.Matrix3D.create()
rotateModel.setToRotation(math.pi / 2.0, adsk.core.Vector3D.create(1,0,0), adsk.core.Point3D.create(0,0,0))

moveFeats = root.features.moveFeatures
moveFeatureInput = moveFeats.createInput(ModelStl, rotateModel)
moveFeats.add(moveFeatureInput)

 

Labels (1)
  • API
4 REPLIES 4
Message 2 of 5
BrianEkins
in reply to: shutov441-vuz

Unfortunately, the API doesn't currently support moving a mesh body.  There have been significant changes/enhancements made to the move command and the API has not yet been updated to support these.  Hopefully, not too far in the future.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 5
Anonymous
in reply to: shutov441-vuz

Hi @shutov441-vuz,

like @BrianEkins said, there is no method in the fusion API to move/rotate a MeshBody.

But you can use the trimesh-library to create a non-fusion-mesh, move/transform this and add this transformed mesh back to fusion.

You'll need the trimesh-lib, as well as the numpy-lib.

 

You can use a class I created recently:

import numpy as np
import trimesh as tri
import adsk.core, adsk.fusion

class MyTrimesh():
    """Class handles the trimesh functionality """
    
    def __init__(self):
        self.trimesh = tri.base.Trimesh()


    def create_from_fMesh(self, fmesh:adsk.fusion.MeshBody):
        """creates a Trimesh from a Fusion-MeshBody"""
        self.trimesh = tri.base.Trimesh(
            vertices=np.reshape(fmesh.mesh.nodeCoordinatesAsDouble,(-1,3)),
            faces=np.reshape(fmesh.mesh.triangleNodeIndices,(-1,3)),
            vertex_normals=np.reshape(fmesh.mesh.normalVectorsAsDouble, (-1,3)))
        self.trimesh.merge_vertices(merge_tex=True, merge_norm=True)


    def create_from_bRep(self, brep:adsk.fusion.BRepBody):
        """creates a Trimesh from a bRepBody"""
        mgr = brep.meshManager.createMeshCalculator()
        mgr.setQuality(adsk.fusion.TriangleMeshQualityOptions.LowQualityTriangleMesh)
        meshbody = mgr.calculate()

        self.trimesh = tri.base.Trimesh(
            vertices=np.reshape(meshbody.nodeCoordinatesAsDouble, (-1, 3)),
            faces=np.reshape(meshbody.nodeIndices, (-1, 3)),
            vertex_normals=np.reshape(meshbody.normalVectorsAsDouble, (-1, 3)))

        self.trimesh.merge_vertices(merge_tex=True,merge_norm=True)
        

    def transform(self, matrix:adsk.core.Matrix3D):
        """executes a transformation on the trimeshBody"""
        self.trimesh.apply_transform(np.reshape(matrix,(-1,3)))


    def add_to_component(self, comp:adsk.fusion.Component) -> adsk.fusion.MeshBody:
        """adds the Trimesh to the components meshBodies and returns the created fMeshBody"""
        
        nodeCoordinates = self.trimesh.vertices.flatten().tolist()
        nodeIndices = self.trimesh.faces.flatten().tolist()
        normalVectors = self.trimesh.vertex_normals.flatten().tolist()

        meshBody = comp.meshBodies.addByTriangleMeshData(nodeCoordinates, nodeIndices, normalVectors, nodeIndices)
        return meshBody


    def deleteMe(self):
        """sets the trimesh-value to None"""
        self.trimesh = None
        

 

So you can add this to your code:

# if you added the class as separate file to your folder
from . import MyTrimesh as tri

#root = adsk.core.Application.get().activeProduct.rootComponent

mesh0 = ModelStl[0]   # or any other body

trimesh = tri.MyTrimesh()   # creates Instance
trimesh.create_from_fMesh(mesh0)   # add meshbody to trimesh
trimesh.transform(rotateModel)   # move/rotate trimesh
trimesh.add_to_component(root)   # add rotated meshbody to root.meshBodies

del trimesh

 

I hope this works for you, I´m using this class and it works fine for me. The only issue is, the Meshbody will added to the root.meshBodies, no matter what component you put in to the add_to_component-function.

 

Message 4 of 5
Anonymous
in reply to: Anonymous

I made a misstake in the transform-function

instead of

def transform(self, matrix:adsk.core.Matrix3D):
        """executes a transformation on the trimeshBody"""
        self.trimesh.apply_transform(np.reshape(matrix,(-1,3)))

 

it should be

def transform(self, matrix:adsk.core.Matrix3D):
        """executes a transformation on the trimeshBody"""
        self.trimesh.apply_transform(np.reshape(matrix.asArray(),(-1,4)))
Message 5 of 5
shutov441-vuz
in reply to: Anonymous

Hi @Anonymous, thank you for your solution. I solved this problem. All I needed to do was move and rotate the model. I did it like this. 

def move_mesh_model(vector3D, mesh_item):
    design.designType = adsk.fusion.DesignTypes.DirectDesignType

    temp_mesh_models.add(mesh_models.item(mesh_item))

    transform = adsk.core.Matrix3D.create()
    transform.translation = vector3D

    moveFeats = root.features.moveFeatures
    moveFeatureInput = moveFeats.createInput(temp_mesh_models, transform)
    moveFeats.add(moveFeatureInput)

    temp_mesh_models.clear()

All you had to do was switch the design mode.

design.designType = adsk.fusion.DesignTypes.DirectDesignTyp

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

Post to forums