A programmer, especially a CAD programmer, has many advantages over normal CAD users. Two of my favorites are:
- You can perform many mundane, boring, routine tasks within seconds that others will take hours by developing a small quick_n_dirty code for private use.
- The more enjoyable advantage for me is that these routines can be shared with others so that they can also benefit from it.
Recently, I received an assembly from one of my customers. When I opened the folder, it contained multiple part & assembly files. I didn't know which of these was the top (main) assembly file.
This was primarily due to me not being very familiar with the domain of, and the vocabulary used by, the Customer. Getting familiar with the vocabulary of your Customer is one of the first duties of a programmer, That saves a lot of time, unnecessary confusion and misunderstanding in later stages and it counts! But that's another story (As they say in Hindi, 'Voh kissa phir kabhee').
Let's get back to from where we strayed - finding the name of the main assembly. The easy way out was to ask the Customer. I was about to ring them, when I suddenly stopped in the track. I asked myself, why loose a learning opportunity? Why not write some code - a program? It would be also be useful for other projects in future. I, hence, jumped into to my new cAdventure, of finding the name of the main assembly file from the multiple assembly files available, using code.
The first thought that came to my mind was the file size. The size (on the disk) of the main assembly file should be largest than any of the (sub)assembly files it references. (I'm sure, you know that size of a part can be bigger than the size of the assembly file in which it is used). And this seems to be generally true!
But I wanted to be sure. I needed a more robust solution. Besides, I decided to include the ability to calculate the depth - maximum nesting level - of the assembly. Before going ahead, let's get clear about what I mean by depth of an assembly.
The image ('Assembly depth') symbolically shows an assembly structure with its sub-assemblies and parts. The red number in the bracket shows the level of each sub-assembly and part in the hierarchy. If we assume that, in the hierarchy, the main assembly is at level 1 then the Part2 at level 4 is the lowest in the hierarchy - the leaf. I call this 4 as the depth or maximum nesting level of the assembly. Just a reminder - in any assembly the 'leaf' is always a part.
![]() |
| Assembly Depth |
With this, we come to the beginning of the end. I decided the following procedure - sequence of actions - for the code. Let's go into details this procedure, and its implementation, with the assembly shown in 'Assembly Depth' as the sample.
- Make a list of all assembly files.
- 'Open' the first assembly file (parent assembly) from the list of assembly files. It could be any assembly file, depending on the sequence the list was generated.
- Find all second level sub-assemblies (child assemblies) 'referenced' by it.
- Make a paired list of the parent assembly and child assembly for each child assembly.For example, if the 'Assembly Depth' Sub-Assembly1 references Sub-Assembly2. Store this information as "Sub-Assembly1/Sub-Assembly2".
- Process all sub-assemblies in the list, one by one, in this manner.
- This will generate the following lists (not necessarily in that order):
6.1 "Assembly/Sub-Assembly1"
6.2 "Assembly/Sub-Assembly2"
6.3 "Sub-Assembly1/Sub-Assembly2" - In this step, substitute the pair in all lists, where a parent assembly appears as child assembly. Thus, the list "Assembly/Sub-Assembly1" becomes "Assembly/Sub-Assembly1/Sub-Assembly2"
After completion of this task, only those lists remain where main assembly is the parent assembly and all its children appear after it, separated by "/", as listed below:
7.1 "Assembly/Sub-Assembly1/Sub-Assembly2"
7.2 "Assembly/Sub-Assembly2"
Note that the name of the parent assembly ("Assembly") is same in each of these lists. - Find the name of the main assembly. This is obvious now - its the name of the parent assembly in each of the remaining lists.
- Find the depth of the assembly.
This is a simple task now.
9.1 Find the list with maximum number of occurrences of the separator"/".
9.2 Count the number of occurrences of the separator in that list.
9.3 Add 2 (1 for main assembly and 1 for the leaf part) and you get the depth. - This ends our adventure of the finding the name of the main assembly and its depth.
With the process developed and proved on paper, I wrote the code in VB.Net Express edition and compiled it into an .exe file. The surprise element in this is that the code performs all the actions without actually opening Inventor. The code runs under the 'Apprentice' API, that makes it possible. But you must have Inventor installed on your PC.
If you want to use / test this code, just write your email id in the comment file and I will send you the code. Your suggestion for improving / expanding the capability of the code to make it more useful are always welcome.
Since the assembly files I received were in Inventor, I developed this code for Inventor. But the good news, in case you are not an inventor user, is that this code can be modified for use with SolidEdge, SolidWorks, CATIA or NX.
So, ... till the next cAdventure in APIs .....
UPDATE 1:
The function of this macro is to traverse through the children of the already open top assembly, looking at the Level attribute. It will then create and assign a Level attribute to the main assembly. The value of this attribute will be one higher than the highest of the children components.'
UPDATE 1:
I came across this old post on a CAD forum. The code I described in the post can be an ideal solution for this problem.
'I'm trying to do a seemingly simple task that is to be a portion of a much larger macro. I have created several test components and assemblies. The children of the main assembly have been assigned a custom property called "Level". The value associated with "Level" is 0 or 1.
And the User would not need to manually add the Level attribute to individual parts resulting in considerable amount of time saved.
UPDATE 2:
One of the readers of the blog requested me to send the Solid Edge version of the code. I sent him the code. After he tested it, this is the feedback I received.
'I checked the utility you provided and works fine.
In essence, you need an installation to run this utility, but it does not consume a licence. It is possible to perform many more activities using this mode.
'I checked the utility you provided and works fine.
Solid edge Open File dialog has this while opening the document. But this requires to opening the Solid Edge. By using the utility we don't need that which might be useful when we have to just find out the the top node from an assembly.'
In essence, you need an installation to run this utility, but it does not consume a licence. It is possible to perform many more activities using this mode.
