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 would you modify this script to use DirectDesign instead of Parametric ?

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Le_Bear
280 Views, 6 Replies

How would you modify this script to use DirectDesign instead of Parametric ?

I am absolutely NOT familiar with the API for DirectDesign, BUT the script below works, just awfully slow. So, I would love to learn how I should do the same, using DirectDesign instead.

#Author-Le Bear
#Description-Get all the VISIBLE bodies from a selected assembly, to combine them all into one single body. The goal is to make cinematic studies easier.

from typing import NewType
import adsk.core, adsk.fusion, traceback


#lst = [] #body list
sourceBodies = adsk.core.ObjectCollection.create()

def traverse(occurences, bodies):
    # recursive method to get all bodies from components and sub-components
    for occ in occurences:    
        for bod in occ.bRepBodies:
            if (bod.isVisible and bod.isSolid) :
                sourceBodies.add(bod)

        if occ.childOccurrences:
            traverse(occ.childOccurrences,bodies)
    
def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        

        # Get active design
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        if not design:
            ui.messageBox('It is not supported in current workspace, please change to SOLID workspace and try again.')
            return

        # Bon, on va essayer d'ajouter des barres de progression.        
        progressDialog = ui.createProgressDialog()
        progressDialog.cancelButtonText = 'Cancel'
        progressDialog.isBackgroundTranslucent = False
        progressDialog.isCancelButtonShown = True
        progressDialog.hide()

        # History must be captured for this to work
        if design.designType == adsk.fusion.DesignTypes.DirectDesignType:
            design.designType = adsk.fusion.DesignTypes.ParametricDesignType

 
        # Get root component in this design
        rootComp = design.rootComponent
        selectedComp = design.activeComponent
               
        # Get all Components below root       
        occs = selectedComp.occurrences
        r_occs = rootComp.occurrences

        bodies = selectedComp.bRepBodies

        # add all bodies from all components in the collection 
        traverse(occs, bodies)     

        # show created dialog
        progressDialog.show('Copy Bodies Progress', 'Percentage: %p, Current Value: %v, Total steps: %m', 0,sourceBodies.count, 1)
         # display progress bar only after we have all bodies   

        # create the new component , adding " - ONE BODY" to the name
        newComp = r_occs.addNewComponent(adsk.core.Matrix3D.create())                
                       
        newComp.component.name = selectedComp.name + " - ONE BODY"
            
        cpyBodies = newComp.component.features.copyPasteBodies        
        # Paste that first body to the new component
        cpyBodies.add(sourceBodies.item(0))
                      
       # ui.messageBox('Num bodies: ' + str(len(sourceBodies)))                       
       # I need an object collection as parameter for CreateInput, even if it contains only one body
        followingBody = adsk.core.ObjectCollection.create() 

        # as it seems to crash if I have a few hundredth of bodies; I'll do this in a loop, one per one. Slow, but should not crash (fingers crossed !)
        i = 1 # we start at 1, as 0 is already copied into the new component
        cancelledFlag = False
        while i < len(sourceBodies):
            # firstBody MUST be a BRepBody, NOT an item from a collection. Inside the loop, it should always be the last result of combine
            firstBody = newComp.component.bRepBodies.item(0) 
            followingBody.add(sourceBodies.item(i))                 
            combines = rootComp.features.combineFeatures            
            combine_input = combines.createInput(firstBody,followingBody)
            combine_input.operation = adsk.fusion.FeatureOperations.JoinFeatureOperation
            combine_input.isKeepToolBodies = False 
            combine_input.isNewComponent = False  
            #returnValue = combines.add(combine_input)
            combines.add(combine_input)
            followingBody.clear()
            i += 1
            progressDialog.progressValue = i
            if progressDialog.wasCancelled:
                cancelledFlag = True
                break
            adsk.doEvents() 

        #combines.add(combine_input)       
        returnValue = newComp.component.bRepBodies.item(0)               
        returnValue.timelineObject.rollTo(True)  #nécessaire, sinon erreur
        #firstBody = returnValue        
        returnValue.timelineObject.rollTo(False)  #nécessaire, sinon erreur
        progressDialog.hide()
        if  cancelledFlag == False :
            ui.messageBox("La combinaison des bodies en un seul est terminée avec succès.")
        else:
            ui.messageBox("La combinaison des bodies a été interrompue.")
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


Thanks for your help,

Bernard

Bernard Grosperrin

Autodesk Certified Instructor

FaceBook Group | Forum | YouTube

Group Network Leader
 
6 REPLIES 6
Message 2 of 7
kandennti
in reply to: Le_Bear

Hi @Le_Bear .

 

Can't I try to put it all together when I do the combine?

・・・
def run(context):
    ui = None
・・・
        # History must be captured for this to work
        # if design.designType == adsk.fusion.DesignTypes.DirectDesignType:
        #     design.designType = adsk.fusion.DesignTypes.ParametricDesignType
・・・
        newComp.component.name = selectedComp.name + " - ONE BODY"

        if design.designType == adsk.fusion.DesignTypes.DirectDesignType:
            # Direct
            tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get()
            clone: adsk.fusion.BRepBody = tmpMgr.copy(sourceBodies.item(0))
            newComp.component.bRepBodies.add(clone)
        else:
            # Parametric
            cpyBodies = newComp.component.features.copyPasteBodies
            # Paste that first body to the new component
            cpyBodies.add(sourceBodies.item(0))
・・・
        cancelledFlag = False
        # firstBody MUST be a BRepBody, NOT an item from a collection. Inside the loop, it should always be the last result of combine
        firstBody = newComp.component.bRepBodies.item(0)
        sourceBodies.removeByIndex(0)

        combines = rootComp.features.combineFeatures
        combine_input = combines.createInput(firstBody, sourceBodies)
        combine_input.operation = adsk.fusion.FeatureOperations.JoinFeatureOperation
        combine_input.isKeepToolBodies = False
        combine_input.isNewComponent = False
        combines.add(combine_input)
・・・
Message 3 of 7
Le_Bear
in reply to: Le_Bear

Thank you very much. I'll try this and let you know.

Bernard Grosperrin

Autodesk Certified Instructor

FaceBook Group | Forum | YouTube

Group Network Leader
 
Message 4 of 7
Le_Bear
in reply to: kandennti

After tests, it works perfectly well, and is so much faster in direct design mode. It's great, really. A test with a bit more than 600 bodies was done in a couple of seconds! in parametric mode, it needs a couple of ... 1/2 hour 🙂

So thank you very , very much!

Bernard Grosperrin

Autodesk Certified Instructor

FaceBook Group | Forum | YouTube

Group Network Leader
 
Message 5 of 7
Le_Bear
in reply to: kandennti

Well, after some more testing, I observe something strange that I am unable to understand.
First, let's say that it DOES work, that is I get a single body in a new document created by the script, and it's fast, now, which is good.
Problem is, the same bodies in the original assembly are invisible, while they are clearly visible looking at the icon in the browser. This was true even before I decided to copy into a new document. Obviously, I can go back to before I used the script, and they appear again. I just would like to understand what is causing this.

Here is my script as of now:

 

 

 

#Author-BG
#Description-Attempt to create one single body from multiples components in an assembly

from typing import NewType
import adsk.core, adsk.fusion, traceback


#lst = [] #body list
sourceBodies = adsk.core.ObjectCollection.create()

def traverse(occurences, bodies):
    # recursive method to get all bodies from components and sub-components
    for occ in occurences:    
        for bod in occ.bRepBodies:
            if (bod.isVisible and bod.isSolid) :
                sourceBodies.add(bod)

        if occ.childOccurrences:
            traverse(occ.childOccurrences,bodies)
    
def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        

        # Get active design
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        if not design:
            ui.messageBox('It is not supported in current workspace, please change to SOLID workspace and try again.')
            return
        
        # Get root component in this design
        rootComp = design.rootComponent
        selectedComp = design.activeComponent
               
        # Get all Components below root       
        occs = selectedComp.occurrences
        r_occs = rootComp.occurrences

        bodies = selectedComp.bRepBodies

        # add all bodies from all components in the collection 
        traverse(occs, bodies)   

        ui.messageBox('Num bodies: ' + str(len(sourceBodies))) 

        # create a new document in which we will put the "One Body"
        newDoc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        newDoc.activate
        new_product = app.activeProduct
        new_design = adsk.fusion.Design.cast(new_product)
        new_design.designType = adsk.fusion.DesignTypes.DirectDesignType
        newRoot = new_design.rootComponent
       # new_occs = newRoot.occurences

        # create the new component , adding " - ONE BODY" to the name
        #newComp = r_occs.addNewComponent(adsk.core.Matrix3D.create())                                       
        #newComp = newRoot.addNewComponent(adsk.core.Matrix3D.create())                                       
        newComp = newRoot
       # newComp.component.name = selectedComp.name + " - ONE BODY" 
       # newComp.name = selectedComp.name + " - ONE BODY"
        newDoc.name = selectedComp.name + " - ONE BODY"
        if new_design.designType == adsk.fusion.DesignTypes.DirectDesignType:
            #Direct
            tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get()
            clone: adsk.fusion.BRepBody = tmpMgr.copy(sourceBodies.item(0))
            #newComp.component.bRepBodies.add(clone)
            newComp.bRepBodies.add(clone)
        else:
            # Parametric
            #cpyBodies = newComp.component.features.copyPasteBodies
            cpyBodies = newComp.features.copyPasteBodies
            # Paste that first body to the new component
            cpyBodies.add(sourceBodies.item(0))
                    
        #firstBody = newComp.component.bRepBodies.item(0) 
        firstBody = newComp.bRepBodies.item(0) 
       # sourceBodies.removeByIndex(0)             
        #combines = rootComp.features.combineFeatures
        combines = newComp.features.combineFeatures
        combine_input = combines.createInput(firstBody, sourceBodies)
        combine_input.operation = adsk.fusion.FeatureOperations.JoinFeatureOperation
        combine_input.isKeepToolBodies = False
        combine_input.isNewComponent = False
        combines.add(combine_input)

        ui.messageBox("La combinaison des bodies en un seul est terminée avec succès.")
        
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

 

 Thanks for helping,

Bernard

PS- When I say it does work, it's not 100% true. In my last test, I got 14 bodies (out of 600+) and some bodies are missing, as you see on this image

Le_Bear_0-1625313693479.png

Thinking a little bit more about this, I believe the reason for which I have more than one body, and some bodies missing, is because of the order in which the bodies are stored in the collection. They don't necessarily touch each other, so they can't be joined. So the new "question du jour" is: how do I test to see if a body is touching/overlapping another one ?

 



Bernard Grosperrin

Autodesk Certified Instructor

FaceBook Group | Forum | YouTube

Group Network Leader
 
Message 6 of 7
kandennti
in reply to: Le_Bear

I'm not sure I understand the situation, but it is possible that you are creating an add-in similar to the one I created.

 

This is from a Japanese forum.
Since creating a motion study for a model with many parts is a very heavy process, it seems that they are cloning each component (API occurrence) and combining the bodies.

 

He has published sample data here.

https://gallery.autodesk.com/projects/how-to-move-large-assemblies-in-fusion-360?_ga=2.259512074.141... 

 

At first, I did this manually, but it seemed like it could be handled by the API, so I consulted with him and created this add-in.

https://github.com/kantoku-code/Fusion360_BUNKURO 

 

It's all in Japanese, but the process may be helpful. The direct processing is in this file.

https://github.com/kantoku-code/Fusion360_BUNKURO/blob/main/BUNKURO/commands/BUNKUROFactry.py 

Message 7 of 7
Le_Bear
in reply to: kandennti

Hi, great. I will look at this in detail. My motivation for this is very similar. It's for motion study as well as to create machines for CAM. (CNC world)

Thank you so much.

Bernard Grosperrin

Autodesk Certified Instructor

FaceBook Group | Forum | YouTube

Group Network Leader
 

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