CustomGraphics and Transaction steps

CustomGraphics and Transaction steps

mcd8604
Enthusiast Enthusiast
1,542 Views
12 Replies
Message 1 of 13

CustomGraphics and Transaction steps

mcd8604
Enthusiast
Enthusiast

I am implementing an addin that creates and deletes temporary custom graphics in response to a palette's html events. For some reason, the graphics transaction steps are showing up in the undo/redo menu. I'd rather these not show up (as I'm sure users of the addin would also).

mcd8604_0-1637613056266.png

 

Is there a way to prevent this from happening? I have no active command to be able to call begin and set makeExistingStepNonUndoable to True (not sure if this would even work anyway).

Accepted solutions (1)
1,543 Views
12 Replies
Replies (12)
Message 2 of 13

KrisKaplan
Autodesk
Autodesk

Unfortunately, no. CustomGraphics are transacted entities in the data model, so any changes to them (CRUD) need to be done in the context of a transaction. There currently isn't an API on the transaction manager for any other control.

BTW: beginStep on the Command would not achieve what you describe. It just controls the boundary of a child 'step' transaction that is part of a sequence of transacted steps that make up a command.

 

Kris



Kris Kaplan
Message 3 of 13

kandennti
Mentor
Mentor
Accepted solution

Hi @mcd8604 .

 

I gave it a try.
In order to reproduce the phenomenon, I made a sample like this.

# Fusion360API Python script

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

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        des: adsk.fusion.Design = app.activeProduct
        des.designType = adsk.fusion.DesignTypes.ParametricDesignType
        root: adsk.fusion.Component = des.rootComponent

        # Create Temporary Box
        tmpBox: adsk.fusion.BRepBody = initTempBox()   

        # Create CustomGraphics Box
        cgGroup: adsk.fusion.CustomGraphicsGroup = root.customGraphicsGroups.add()
        cgGroup.addBRepBody(tmpBox)
        app.activeViewport.refresh()
        ui.messageBox('Create CustomGraphics Box')

        # Delete CustomGraphics Box
        cgGroup.deleteMe()
        ui.messageBox('Delete CustomGraphics Box')

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

def initTempBox():
    bBox: adsk.core.OrientedBoundingBox3D = adsk.core.OrientedBoundingBox3D.create(
        adsk.core.Point3D.create(0.0, 10.0, 0.0),
        adsk.core.Vector3D.create(1.0, 0.0, 0.0),
        adsk.core.Vector3D.create(0.0, 1.0, 0.0),
        5.0,
        6.0,
        2.0
    )

    tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get()
    return tmpMgr.createBox(bBox)

 

It's not a very good method, but it's what I know how to do to create and abort a transaction.

https://github.com/kantoku-code/Fusion360_Small_Tools_for_Developers/blob/master/TextCommands/TextCo... 

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        des: adsk.fusion.Design = app.activeProduct
        des.designType = adsk.fusion.DesignTypes.ParametricDesignType
        root: adsk.fusion.Component = des.rootComponent

        # Create Temporary Box
        tmpBox: adsk.fusion.BRepBody = initTempBox()   

        # Transaction Start
        transactionName = 'hoge'
        app.executeTextCommand(u'Transaction.Start {}'.format(transactionName))

        # Create CustomGraphics Box
        cgGroup: adsk.fusion.CustomGraphicsGroup = root.customGraphicsGroups.add()
        cgGroup.addBRepBody(tmpBox)
        app.activeViewport.refresh()
        ui.messageBox('Create CustomGraphics Box')

        # Transaction Abort
        app.executeTextCommand(u'Transaction.Abort')
        ui.messageBox('Transaction Abort')

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

 

I think you need to make sure that no other process is involved, because it aborts everything between "Start" and "Abort".

Message 4 of 13

mcd8604
Enthusiast
Enthusiast

Thanks @kandennti. I tried creating and aborting a transaction using app.executeTextCommand and seems to be working so far!

0 Likes
Message 5 of 13

mcd8604
Enthusiast
Enthusiast

Does the name 'hoge' have any special meaning or is it arbitrary?

0 Likes
Message 6 of 13

mcd8604
Enthusiast
Enthusiast

@KrisKaplan 

Thanks for the insight.

While I have a workaround for this atm, it doesn't seem like a good long-term solution. Do you know if there are any plans to expose more of transactions to the API, generally?

0 Likes
Message 7 of 13

kandennti
Mentor
Mentor

The word "hoge" has no meaning; when you commit, it goes into the undo history.

0 Likes
Message 8 of 13

mcd8604
Enthusiast
Enthusiast

Does creating the transaction through the text command preventing F360 from creating a new transaction for the CustomGraphics and just using the one we create? In other words, are we putting a fresh transaction in the manager that otherwise would have created one automatically?

0 Likes
Message 9 of 13

kandennti
Mentor
Mentor

@mcd8604 .

 

I don't know exactly what it is either.

 

I think it does the same thing as described here in Transactions.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-3922697A-7BF1-4799-9A5B-C8539DF57051 

 

I think the "abort" at the end does the same thing as pressing the cancel button in the dialog.

 

 

As I recall, the script I created here temporarily created a sketch text, retrieved the available font names, and then used "Abort" to make it behave as if the sketch text had not been created.

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/script-to-edit-font-across-multiple-sketch... 

 

0 Likes
Message 10 of 13

mcd8604
Enthusiast
Enthusiast

I tried another approach as well. I thought maybe I could put the custom graphics creation inside a command and then execute the command from the html event handler (instead of just creating the custom graphics directly from the html event handler). My addin displays information based on the user's current selection, so it kind of relies on the selection to remain selected. Unfortunately, I think creating this new command causing the active selection to release and this defeats the whole purpose.

0 Likes
Message 11 of 13

KrisKaplan
Autodesk
Autodesk

Using this debug text command is fairly risky. It doesn't prevent the custom graphics transaction from being created. It just makes it a child of the transaction you create with this command. So when you abort that transaction, it aborts all child transactions as well.

The risk of using this (besides being unsupported) would be if you accidentally left this transaction open, or aborted it at a point in time that would overlap a user initiated transaction you would corrupt the transaction manager and thus the current users session (potentially leading to user data loss).

 

Adding a formal API on the transaction manager is definitely in the backlog, but I don't have any information on when it might get done.

 

Kris



Kris Kaplan
Message 12 of 13

kandennti
Mentor
Mentor

The only other way I can think of is to give up on Palette and use BrowserCommandInput and executePreview Event to handle it.

 

However, the fact that Palette can be used modaless is very attractive.

0 Likes
Message 13 of 13

mcd8604
Enthusiast
Enthusiast

I can definitely understand this is unstable and is why I consider the above as a temporary solution. Luckily the use case I have allows me to create and abort the transaction before the user can do anything else. I'll look forward to new API developments in the future 😄

0 Likes