SaveAs multiple documents

SaveAs multiple documents

espablo
Enthusiast Enthusiast
1,565 Views
13 Replies
Message 1 of 14

SaveAs multiple documents

espablo
Enthusiast
Enthusiast

First I wanted to say hello because this is my first post.
The script below should save the currently open document under new names 3 times. Unfortunately, during operation, the program saves only one document, but v3

 

 

import adsk.core, adsk.fusion, adsk.cam, traceback


def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        document = app.activeDocument

        path = design.parentDocument.dataFile.parentFolder
        baseName = document.dataFile.name

        for idx in range(3):
            if not document.isSaved:
                ui.messageBox(
                    "The active document must be saved before running this script."
                )
                return

            newFilename = f"{idx}_{baseName}"
            document.saveAs(newFilename, path, "Dec", "Tag")

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

 

Below are some pictures of the process from start through recording and the end result

 

Clipboard01.pngClipboard02.pngClipboard03.pngClipboard04.png

How can I force this script to get 3 new correctly saved documents at the end?

0 Likes
1,566 Views
13 Replies
Replies (13)
Message 2 of 14

BrianEkins
Mentor
Mentor

I can reproduce the issue you're seeing and thought it was a bug, but after looking closer, I'm not sure. It's certainly not expected behavior, but I'm unsure what is expected here. 

 

When you do a Save As operation, either in the UI or using the API, it saves the current document using the new name and replaces the current document with the new file. Because of that you were actually creating the following:

file1  ->  0_file

0_File -> 1_file

1_file -> 2_file 

 

I also found it strange that the variable "documents" remained OK because the document was being switched to the newly saved document. I think we're seeing some symptoms of the internals of how "save as works", and Fusion is changing the name of the current document, but the document remains the same.

 

I modified your code so that it gets the DataFile associated with the active document and after each "save as" it closes the current document and reopens the original and does the next "save as". This seems to work as expected.

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        document = app.activeDocument
        file = document.dataFile

        path = design.parentDocument.dataFile.parentFolder
        baseName = document.dataFile.name

        if not document.isSaved:
            ui.messageBox(
                "The active document must be saved before running this script."
            )
            return

        for idx in range(3):           
            newFilename = f"{idx}_{baseName}"
            document.saveAs(newFilename, path, "Dec", "Tag")
            document.close(False)
            document = app.documents.open(file)

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

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 14

espablo
Enthusiast
Enthusiast

Thank you for your response. My code snippet is part of an example I watched here https://www.youtube.com/watch?v=mxvQgpgOvzE. It works on video and you don't have to reopen the document

0 Likes
Message 4 of 14

BrianEkins
Mentor
Mentor

I don't know if something has changed in the internals of Fusion since that video was created, but it's risky anytime you attempt to do something differently than Fusion allows in the user interface. It usually means you are using Fusion in a way that is not intended or tested.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 5 of 14

espablo
Enthusiast
Enthusiast

I don't want to open a new document and save it every time. I would like to be able to save the currently open document under a new, different name, just like in the video. The savAs method should save the new document but it doesn't. If I do it manually in the fusion menu it works fine without opening a new document. Unfortunately, due to the API, you have to reopen the document each time for the saveAs method to work properly.

0 Likes
Message 6 of 14

BrianEkins
Mentor
Mentor

I wasn't clear in my description of the problem with the original code. Here's what it's doing:

  1. Gets the active document and assigns it to the variable named "document".
  2. Call the saveAs method on the Document referenced by the "document" variable.
  3. This results in the original Document being closed, and the current document is the newly created Document. What does the variable "document" reference at this point. I'm a bit surprised the call to saveAs doesn't fail.

What my code is doing is closing the newly created document and re-opening the original document to do the next saveAs, so it's back to the original state. However, I also found another solution where it gets the newly created document and assigns it to the variable "document" and then continues with the saveAs. Now the "document" variable is referencing a valid Document.

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        document = app.activeDocument
        file = document.dataFile

        path = design.parentDocument.dataFile.parentFolder
        baseName = document.dataFile.name

        if not document.isSaved:
            ui.messageBox(
                "The active document must be saved before running this script."
            )
            return

        for idx in range(3):           
            newFilename = f"{idx}_{baseName}"
            document.saveAs(newFilename, path, "Dec", "Tag")
            document = app.activeDocument

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

 The only change is in the for loop where the original calls to close and open are now replaced with following, which seems to work.

document = app.activeDocument

  

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 7 of 14

espablo
Enthusiast
Enthusiast

It still doesn't work. The effect is the same as in my first example.

0 Likes
Message 8 of 14

espablo
Enthusiast
Enthusiast

I also tried the code that is shown on Youtube with a CSV file. I can see the element changing size, but only the first element is saved using the document.saveAs(...) method, and each subsequent element looks as if the program used the document.save("") method

 

 

import traceback
import adsk.fusion
import adsk.core
import adsk.cam
import os
import csv


def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)
        document = app.activeDocument

        path = design.parentDocument.dataFile.parentFolder
        baseName = document.dataFile.name

        file = open(
            os.path.join(os.path.dirname(os.path.abspath(__file__)), "", "test.csv")
        )

        with file as f:
            reader = list(csv.reader(f))
            # Go through line in the list and do something
        for csvData in reader:
            Length = csvData[0]
            Width = csvData[1]
            # Set user params from CSV data
            csvParams = design.userParameters
            csvParams.itemByName("Length").expression = Length
            csvParams.itemByName("Width").expression = Width
            # Set up a new file name
            newFileName = baseName[0] + " - " + Length + " x " + Width
            document.saveAs(newFileName, path, "Desc", "Tag")
    except:
        ui.messageBox("Failed:\n{}".format(traceback.format_exc()))

 

 

Clipboard05.pngClipboard06.png

0 Likes
Message 9 of 14

espablo
Enthusiast
Enthusiast

I noticed one more regularity. If Fusion 360 works in offline mode, the recording is correct, but when I switch to online mode, everything starts to go wrong.
If there is no solution, where can I report it as a bug?

0 Likes
Message 10 of 14

kandennti
Mentor
Mentor

@espablo -San.

 

I haven't tried it, but if it can be processed correctly offline, why not process it temporarily offline and then bring it back online after processing is complete?

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-939A8FA7-9A5D-439F-9F60-E7B0943F782D 

0 Likes
Message 11 of 14

espablo
Enthusiast
Enthusiast

For the test, I manually took the F360 offline. The program generated 3 files and saved as expected. Each file has version V1. The program has ended. Up to this point everything works as it should. Then I manually switch to online mode and see spinning circles indicating an attempt to save to Cloud Fusion. It takes a very long time and at the end only one file is saved, but it has version V3. This is a simple script that works on any open document. I suggest running it and see how it works. I thought I had something with Fusion 360, I tried removing it and reinstalling it but it still happens.

0 Likes
Message 12 of 14

BrianEkins
Mentor
Mentor

What's the problem with closing the new file and reopening the original file? Maybe it's not as clean as you would like but it seems to consistently work.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 13 of 14

espablo
Enthusiast
Enthusiast

Closing and reopening the document works well, but imagine that you have a project that takes some time to load and you want to duplicate several such projects. I wanted to use it to duplicate furniture fronts. For now I am using document reloading, but some documents are large and loading takes time. There is no point in reopening a document that is already open. Saving the document with a new name should create a new document and activate it. It used to work but now it doesn't work anymore. It doesn't matter whether I use document = app.activeDocument before the "for" loop or whether I use it in the loop, 1 document is created and the saveAs() method overwrites the existing document, although each time I provide a different name for the new document.

0 Likes
Message 14 of 14

espablo
Enthusiast
Enthusiast

The problem still exists and I took the liberty of recording a video in which I show how it works. The program should generate 3 elements of different dimensions. The program generates these 3 elements correctly but when saving only one remains and two disappear.

0 Likes