DynamoDS / Dynamo

Open Source Graphical Programming for Design
https://dynamobim.org
Other
1.72k stars 632 forks source link

Migration issue: Accessing the Revit API via Python nodes #1718

Closed andydandy74 closed 10 years ago

andydandy74 commented 10 years ago

It seems like Dynamo 0.7 has introduced a wrapper around the Revit API that previously wasn't there, at least when accessing Revit objects using the Python node. For example, accessing the properties/methods of an object selected in Dynamo (e.g. a wall) in 0.6.3. would look like this: obj.Property or obj.Method(arg) In 0.7 it needs to be called like this: obj.InternalElement.Property or obj.InternalElement.Method(arg) For documents, it used to be like this: doc.Property or doc.Method(arg) Now it is: doc.InternalDocument.Property or doc.InternalDocument.Method(arg) Maybe there are other cases that I am not aware of yet, but this is what I have figured out so far. My question is: Is this a permanent change, i.e. can I start converting Python-based packages using this new way of calling the object members? If so, I would highly recommend adding this information to the migration guide that @kronz has started compiling. Plus, it would be good to know if there are other similar changes besides InternalElement and InternalDocument. If not, I would be interested to know what changes we should expect.

ikeough commented 10 years ago

That's exactly right Andreas. Those "wrappers" are the mechanism that allow us to do things like transaction control and element binding. For each of these wrapper types there is an InternalElement field which gives you access to the raw API type.

@Steell is in the process of documenting these changes.

archinate commented 10 years ago

Just started running into this when migrating nodes and is probably the cause of the issues I'm having here in this issue I just posted #1728

I sure hope it's not a permanent change... it adds another level of complexity to migrating scripts and and other API snippets for use with Python/Revit

andydandy74 commented 10 years ago

In most cases it's just going to be changing obj=IN[0] into obj=IN[0].InternalElement right at the beginning of the script - I can live with that because it leaves the script itself "intact". For list inputs, however, I am doing the conversion when the list is actually processed in the script, like so:

for item in items:
     item = item.InternalElement

I am not very happy with that since I'll actually have to insert it right into the middle of the script. If anyone can think of a good one-liner to get this done with at the beginning of the script, please let me know. What I really like, though, is that apparently any Revit object I output through Python automatically gets "wrapped" again. That means I can safely mix Revit objects from built-in nodes and Python nodes and can call all of them in subsequent Python nodes through obj.InternalElement. One thing less to worry about.

archinate commented 10 years ago

"I am not very happy with that since I'll actually have to insert it right into the middle of the script."

Exactly right... many of the scripts that I have made have Revit objects being accessed/created/etc. throughout the python script. Migrating them to the new Dynamo environment is not an insignificant undertaking. The "wrapper" layer seems to add another layer of complexity and also means that I have to now maintain a set of unique Revit API Python scripts for Dynamo separate from other Python tools like the RevitPythonShell or Macro editor. Before it was just copy/paste in most cases.

pboyer commented 10 years ago

Hi guys,

Andreas has noticed the auto-marshaling that the Python nodes does on the outputs.

We decided that it made more sense not to automatically unwrap the inputs before script execution takes place. As a result, the user has a continuous API both outside of and inside of nodes. Clearly, this complicates migration.

In order to simplify migration, it's possible that we could supply a simplified unwrap method in the python script execution environment. This might look like this:

result = UnwrapRevitType( elementOrListOfElements )

As the argument name implies, this would work on a single wrapped Element, lists of wrapped Elements, or a nested list of wrapped Elements and return the expected Revit Elements.

Would that make sense?

~Peter

On Thu, Jun 5, 2014 at 7:57 AM, Nathan Miller notifications@github.com wrote:

"I am not very happy with that since I'll actually have to insert it right into the middle of the script."

Exactly right... many of the scripts that I have made have Revit objects being accessed/created/etc. throughout the python script. Migrating them to the new Dynamo environment is not an insignificant undertaking. The "wrapper" layer seems to add another layer of complexity and also means that I have to now maintain a set of unique Revit API Python scripts for Dynamo separate from other Python tools like the RevitPythonShell or Macro editor. Before it was just copy/paste in most cases.

— Reply to this email directly or view it on GitHub https://github.com/DynamoDS/Dynamo/issues/1718#issuecomment-45210514.

andydandy74 commented 10 years ago

Sounds like a smart move. That should make the upgrade process a lot simpler. Ideally, this method would be forgiving in terms of any non-unwrappable types (and would just return the input unchanged).

pboyer commented 10 years ago

Yes, I assumed this would be an extremely forgiving method, accepting unwrappable types.

pboyer commented 10 years ago

By the way, I've filed this internally and will try and take care of it on Monday.

archinate commented 10 years ago

Peter, This sounds like an interesting approach. Also happy to test it when it is ready.

Thanks, -Nate

pboyer commented 10 years ago

Hi all,

This is simplified in the latest daily build with the incorporation of the UnwrapElement method. This is only available in Revit.

unwrapelement

andydandy74 commented 10 years ago

Great, Peter, thanks. Time to download a new daily and start converting those Python nodes... BTW: This should be included in the wiki article that @Steell wrote last week.

pboyer commented 10 years ago

Thanks Andreas - I added it to the wiki.