Get Python Code to act on current model

Hey all i’m a newbie on this forum and tried to search for an answer before posting but could not locate anything to help, so here it goes.

Backstory:
I have a Dynamo Graph combined with a python node and am accessing it through a button on a Dyno Browser tab. It is working great if I only have one model open. If I have more than one model open and I activate the command it works on the first model I open even if my current active view is in the second model.

Question:
Is there a way to have the python code direct the code to be run in the model with the active view?

‘working’ code snip is pasted below:
Thanks for the help

doc = DocumentManager.Instance.CurrentDBDocument
if doc.IsWorkshared:
    TransactionManager.Instance.EnsureInTransaction(doc)
    create_arch_worksets(A_Worksets)
    TransactionManager.Instance.TransactionTaskDone()
    OUT = new_worksets


elif doc.IsWorkshared == False:
    if doc.CanEnableWorksharing() == True:
        doc.EnableWorksharing(A_Worksets[0], A_Worksets[1])        
        TransactionManager.Instance.EnsureInTransaction(doc)
        create_arch_worksets(A_Worksets)
        TransactionManager.Instance.TransactionTaskDone()
        A_Worksets.sort()

        OUT = A_Worksets

Are you using the Dynamo Player? It will automatically shift focus to the active model if you switch.

You are correct it does shift focus to the active document, however it I have it set up so the user can choose their discipline with a button selection on the dyno browser, if I run it through the player it only runs the variable that is set in the dyno graph. Need to have some sort of selection process.
ex.
Landscape Worksets
Structural Worksets
Architectural Worksets
…and so on for a total of 8 separate choices.

Can this be done with dynamo?

Check out the DataShapes package. This would allow you to run the graph from the player but also allow the user to make a selection. You could use a UI.DropDown node if the user only needs to pick a single option or the UI.Listview node if multiple selections need to be made.

1 Like

Great! I’ll check it out.

Thanks for replying.

1 Like

I’m not entirely sure if this would work (I haven’t tested) … But if you require an open document you might be able to use Application.Documents which gives you a DocumentSet and if the DocumentSet.Size > 1 you could have documents in that DocumentSet be displayed in a Data-shapes dropdown node where the user could select the document or if there is only one then skip the UI and pass directly to your node (of course you wouldnt use the doc = DocumentManager.Instance.CurrentDBDocument, instead pass in the user selected doc).

I was thinking this as well, but I realized that there would then be no way to get the active view of the document. I was thinking you could get the ActiveUIDocument from the UIApplication and, in turn, get the ActiveView, however if you open Dynamo the normal way, rather than in the player, there is no way to get it to point to a different document without closing and re-opening. Your method would work for most conditions, however I think the specific requirement of getting the document’s active view prevents this from working.

Do you need the active view? The code given only creates worksets, so this doesn’t require a view of any kind. I’m thinking maybe you can ignore that with using a UI (although, it doesn’t answer the original question I suppose).

I always assumed dynamo switched the current documents context when the document is switched and I don’t think there is a UI method to switch documents other than this hack…

https://forums.autodesk.com/t5/revit-api-forum/change-active-document/td-p/7787792

Have you tried the ActiveUIDocument? Because you can get the document from that and pass it into the python rather than get the current doc.

@cgartland

I just did a quick test and you can just use UIApplication.ActiveUIDocument.Document…

I have two models open and I am able to get both documents and edit both just fine creating a grid in both documents…

image

here is the code…

import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

clr.AddReference("RevitAPIUI")
from Autodesk.Revit.UI import *

outList = []

# get docs...
doc =  DocumentManager.Instance.CurrentDBDocument
uiApp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiApp.ActiveUIDocument.Document

# Grid curve...
gl = Line.CreateBound(XYZ(),XYZ(10,10,0))

# Create Grid in current doc...
TransactionManager.Instance.EnsureInTransaction(doc)
docGrid = Grid.Create(doc, gl)
# Need to force close here because otherwise it can't open another transaction in the ActiveDoc
TransactionManager.Instance.ForceCloseTransaction()

# Create Grid in ActiveDoc...
TransactionManager.Instance.EnsureInTransaction(uidoc)
uidocGrid = Grid.Create(uidoc, gl)
TransactionManager.Instance.TransactionTaskDone()

OUT = [docGrid, doc.Title],[uidocGrid, uidoc.Title]

Does this solve the issue?

Cheers,
Dan

3 Likes

Yes, the active view is probably not required in this case. Is this intended to be run using the dynamo player? I would think that if you are using dynamo traditionally, doc and uidoc would contain the same document as dynamo will not run if you are working in a document different from that in which it was initiated.

Yup, you can use this either in Player or the Dynamo Application. When using the Dynamo app you do indeed get a warning, but it can still run. Here are some video demo’s of this in both player and app respectively…

Using Player

Using Dynamo

Yes, if you are using Dynamo traditionally (without the API) then I think most nodes would be pointing at the CurrentDBDocument as their document context so this would not work, but as demonstrated, with the API you can get and operate on the ActiveUIDocument even if it is not Dynamo’s context document.

Good Morning all -

Thank you for your responses. I was able to get the Dynamo Player solution to work using a numbered switch that can be controlled by the user.

Also using Daniel’s Suggestion, I amended my code to use the uidoc as suggested and it is now working as desired through the Dyno Player buttons I had created, as well.

Thank you all very much for your assistance and helping me get this working as desired!!

Hope I can keep learning and pass some knowledge on to others in the future.

Cheers

3 Likes