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: 

Fusion crashes with a certain model.

4 REPLIES 4
Reply
Message 1 of 5
SilvioMan
397 Views, 4 Replies

Fusion crashes with a certain model.

Fusion crashes with the model "One building near Ekaterinburg" ( https://fusion360.autodesk.com/projects/one-building-near-ekaterinburg ) after running this code in the third or the fourth time.

If it is clear, please, help with it. Otherwise, I just report this.

 

 

import adsk.core, adsk.fusion, traceback
from xml.etree.ElementTree import Element, SubElement, tostring

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        quality = adsk.fusion.TriangleMeshQualityOptions.LowQualityTriangleMesh
        root = Element('geometry')
        listComp = adsk.core.ObjectCollection.create()
        for occ in adsk.fusion.Design.cast(app.activeProduct).rootComponent.allOccurrences:
            listComp.add(occ)
        listComp.add(adsk.fusion.Design.cast(app.activeProduct).rootComponent)
        for l in listComp:
            if l.classType() == adsk.fusion.Occurrence.classType():
                bodies = l.component.bRepBodies
                matrix = GetMatrix(l)
            if l.classType() == adsk.fusion.Component.classType():
                bodies = l.bRepBodies
                matrix = adsk.core.Matrix3D.create()
            for body in bodies:
                if body.isVisible:
                        for face in body.faces:
                            meshCalc = face.meshManager.createMeshCalculator()
                            meshCalc.setQuality(quality)
                            triangleMesh = meshCalc.calculate()
                            if triangleMesh:
                                coordinates = triangleMesh.nodeCoordinates
                                indices = triangleMesh.nodeIndices
                                normalVectors = triangleMesh.normalVectorsAsDouble
                                mesh = SubElement(root, 'mesh')
                                materialXML = SubElement(mesh, 'material')
                                color = SubElement(materialXML, 'color')
                                materialID = SubElement(materialXML, 'id')
                                r = SubElement(color, 'R')
                                g = SubElement(color, 'G')
                                b = SubElement(color, 'B')
                                opacity = SubElement(color, 'opacity')
                                shininess = SubElement(materialXML, 'shininess')
                                reflective = SubElement(materialXML, 'reflective')
                                transparency = SubElement(materialXML, 'transparency')
                                properties = body.appearance.appearanceProperties
                                if properties:
                                    colorprop = properties.itemById('metal_f0')
                                    if not colorprop:
                                        colorprop = properties.itemById('opaque_albedo')
                                    if not colorprop:
                                        colorprop = properties.itemById('transparent_color')
                                    if not colorprop:
                                        colorprop = properties.itemById('concrete_color')
                                    if colorprop and colorprop.value:
                                        materialID.text = str(body.appearance.id)+"-"+str(colorprop.value.red)+str(colorprop.value.green)+str(colorprop.value.blue)
                                        r.text = str(colorprop.value.red)
                                        g.text = str(colorprop.value.green)
                                        b.text = str(colorprop.value.blue)
                                        opacity.text = str(colorprop.value.opacity)
                                    shinprop = properties.itemById('surface_roughness')
                                    if shinprop and shinprop.value:
                                        shininess.text = str(shinprop.value)
                                    reflprop = properties.itemById('opaque_f0')
                                    if reflprop and reflprop.value:
                                        reflective.text = str(reflprop.value)
                                    transpprop = properties.itemById('transparent_ior')
                                    if transpprop and transpprop.value:
                                        transparency.text = str(transpprop.value)
                                vertices = SubElement(mesh, 'vertices')
                                for c in coordinates:
                                    vertice = SubElement(vertices, 'vertice')
                                    c.transformBy(matrix)
                                    x = SubElement(vertice, 'x')
                                    x.text = str(c.x/-100)
                                    y = SubElement(vertice, 'y')
                                    y.text = str(c.z/100)
                                    z = SubElement(vertice, 'z')
                                    z.text = str(c.y/100)
                                normals = SubElement(mesh, 'normals')
                                nNormals = 0
                                for c in coordinates:
                                    normal = SubElement(normals, 'normal')
                                    x = SubElement(normal, 'x')
                                    x.text = str(normalVectors[nNormals*3])
                                    y = SubElement(normal, 'y')
                                    y.text = str(normalVectors[nNormals*3+1])
                                    z = SubElement(normal, 'z')
                                    z.text = str(normalVectors[nNormals*3+2])
                                    nNormals+=1
                                triangles = SubElement(mesh, 'triangles')
                                for t in range(triangleMesh.triangleCount):
                                    triangle = SubElement(triangles, 'triangle')
                                    a = SubElement(triangle, 'A')
                                    a.text = str(indices[t*3])
                                    b = SubElement(triangle, 'B')
                                    b.text = str(indices[t*3+1])
                                    c = SubElement(triangle, 'C')
                                    c.text = str(indices[t*3+2])
        
        xml_str = tostring(root)
        with open('D:\\ctetemptriangle.xml', 'wb') as f:
            f.write(xml_str)
        ui.messageBox('Done')
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def GetMatrix(occurrence):    
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        matrix = occurrence.transform
        while occurrence.assemblyContext:
            matrix.transformBy(occurrence.assemblyContext.transform)
            occurrence = occurrence.assemblyContext
        return matrix                              
    except:
        if ui:
            ui.messageBox('Get Matrix failed:\n{}'.format(traceback.format_exc()))   

 

4 REPLIES 4
Message 2 of 5
zhijie.li
in reply to: SilvioMan

Hi SilvioMan,

 

We have reproduced the issue and logged a defect in our internal system. Thank you for posting the issue. It is on investigation now and planned to be fixed in the comming release.

 

Regards,

Zhije

Message 3 of 5
SilvioMan
in reply to: zhijie.li

Thank you for reply.

Message 4 of 5
KrisKaplan
in reply to: SilvioMan

A fix for this was made and will be in the next major update.  The problem was a reference counting problem in the 'None' object returned from any API that returns None without setting an error.  In your script, this was happening in the calls to Properties.itemById when the specified id was not in the set of properties.

 

But you can work around this pretty easily with a fairly minor change to your script.  Instead of using Properties.itemById, just loop over the items in the properties collection looking for the properties by id (e.g. 'for property in properties: if property.id == ...').  This would be more expensive, but you can (should) move this appearance logic out of this inner face loop.  Instead of rebuilding this color information for every single face, it would be better (faster) to get these values once for each material you encounter, and store them in a global dictionary with the Appearance.id as the key.

 

Also note that your code translates the node points, but does not rotate the normal vectors.  So this won't property account for rotation transformations of occurrences, only translations (moves).

 

Kris



Kris Kaplan
Message 5 of 5
SilvioMan
in reply to: KrisKaplan

Thank you for your reply and tips. They are very helpful.

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