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: 

design.findEntityByToken return type is BaseVector and does not recognize the Root Component

2 REPLIES 2
Reply
Message 1 of 3
adamantlife
222 Views, 2 Replies

design.findEntityByToken return type is BaseVector and does not recognize the Root Component

TL:DR-
  • Documentation for design.findEntityByToken provides incorrect Type (return type is BaseVector, not list)
  • No Documentation for BaseVector
  • design.findEntityByToken does not work on the Design's Root Component (either undocumented behavior or unintended behavior)
  • (From Update)
  • All Root Components share the same Entity Token
    • This appears to be what prevents design.findEntityByToken from working, as it cannot distinguish between multiple Root Components that have been inserted into a Design.
It took me several hours to finally figure this out, but as it turns out design.findEntityByToken() does not recognize the Root Component. Initially I thought I wasn't getting a result because the result was a BaseVector instead of a List, as specified by the Documentation here.

 

I therefore spent a bunch of time trying to figure out if there was a special method for accessing the BaseVector because there is no documentation for BaseVector for me to look at. There are several methods for interfacing with lists that are not interoperable with BaseVector (most importantly, BaseVector does not appear to implement  the __len__ property), so I did a lot of guess-and-checking.

 

Eventually I determined that the problem was that design.findEntityByToken does not work on the Root Component, which is not mentioned anywhere.

 

This problem is boiled down into the following MVE which can be plugged into the in-app Console for verification.

 

design = adsk.core.Application.get().activeDocument.design
design.findEntityByToken(design.rootComponent.entityToken)

 

 

If we create an additional component, we can compare the behavior between the two:

 

[list(vector) for vector in
    [design.findEntityByToken(component.entityToken) for component in design.allComponents]
]

 

 

Since the documentation on Component and this blog post here both recommends using fetching Entities via Entity Tokens to make comparisons, I'm asking if there is an alternative to design.findEntityByToken to use with the Root Component.

 

Update

 

I did some more testing which seems to explain why design.findEntityByToken does not work on Root Components (sometimes). I'm providing the minimal recreation of those tests here with my observations. For the tests I'm getting references to the different designs with "designX = adsk.core.Application.get().activeDocument.design" while I have the Document active in the App and I am checking Component's Entity Tokens with "[component.entityToken for component in designX.allComponents]". For the most part this update is serving as documentation for anyone else who may come across this thread in the future as it demonstrates several important points about Entity Tokens that I did not see elucidated elsewhere.

 

Create and Save Design1: Root Component's Entity Token is '/v4BAAEAAwAAAAAAAAAAAAAA'

Create a new Component in Design1: Component's Entity Token is pseudo randomly generated

> Observation: all Entity Tokens I've noted in testing start with "/v4BAAEA", don't know if this is Machine Specific

 

Create and Save Design2: Root Component's Entity Token is '/v4BAAEAAwAAAAAAAAAAAAAA' 

Create a new Component in Design2: Component's Entity Token is unique

Observation: All Root Components have the same Entity Token (which is unexpected); all other Entity Tokens (appear) to be unique (which was the expectation)

 

Insert Design1 into Design2: None of Design1's Entity Tokens have changed (which was expected)

Create a copy of Design1 and Rename it to Design3: All of the Entity Tokens in Design3 are the same as Design1

Insert Design3 into Design2: There are now 3 identical Root Component ET's and 2 identical Non-Root ET's

Observation: This seems unexpected due to the fact that Design1 and Design3 do not share a history; if they did then it would be understandable for them to have identical ET's. At this point, however, they are effectively completely distinct documents and designs and may as well have been generated independently.

 

Undo the Insertion of Design3 in order to remove it

Derive Design3 into Design2: Design3's Root and Sub Component now have unique ET's.

Break the Link on Design1's insertion in Design2: Design1's Root and Sub Component now have unique ET's.

Observation: Deriving a Root Component automatically breaks its link to its parentDesign (changes the reference to the destination design) which removes its status as a Root Component. Part of the process of reparenting a Component (either by Deriving or Breaking a Link for an Inserted Design) generates a new Entity Token. This allows Components that were previously Root Components to now be found using design.findEntityByToken.

Labels (3)
2 REPLIES 2
Message 2 of 3
BrianEkins
in reply to: adamantlife

It seems like a bug that findEntityByToken doesn't work for the root component. However, the root component is special because it's the only one within a design. It's not like identifying one of many edges. Because it's a singleton, it's easy to find without using entity tokens.

 

The BaseVector is something that needs to be added to the documentation and is confusing. The documentation is written generically because the API is exposed using more than one language and potentially could be exposed through more languages in the future. When a property or method returns multiple entities, the help says an array is returned. In C++, a vector object from the std library represents arrays or lists. The API is implemented in C++ and then wrapped as Python using SWIG. SWIG creates the BaseVector class to represent the std::vector class in C++. Ideally, it would be a standard Python List.

 

In most cases, no one notices that it's not a list since it does support basic Python iteration, but it doesn't support everything. You can easily convert it to a list.

 

myList = list(des.findEntityByToken(token))

 

Also, thank you for the well-written description of the problem.

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 3
adamantlife
in reply to: BrianEkins

Thank you for the response.

 

I did more testing and have updated my original post.  I've accepted that I'll have to add work-arounds for Root Components for the time being (update demonstrates how there can be multiple Root Components in one document). The update is not looking for any further response and is just me making a public note of some specifics.

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