April 23, 2019

Have Your Own 'Style'

Do you use the 'Copy And Paste' functionality in the software you use? Obviously, everybody does that! But that is not the real question.

When you copy something from a document and paste it into another document of same type, you expect it to be exact copy of the original. Now the real question - Have you ever encountered a situation when the copy is not the same (that too by the look) as the original?

Well, I did recently, in one of my projects. When I copied an AutoCAD table from one drawing to another, the text in the table visually looked different from the original.

As you may be aware, every CAD software controls display of its contents by 'styles'. And there are many of them like Dimension Style, Table Style. Text Styles, that control the display of text (font / size / formatting),  are common across all CAD softwares - 2D or 3D.

AutoCAD provides default styles for each category of styles (And it is no different for Inventer / SolidEdge / SolidWorks / ProE - Creo / CATIA).  It is a good practice not to tamper with any of the default styles. If you need any change, even a minor one, create a new style of your own. But leave the default styles untouched. I learned this message loud and clear.  Here is how it happened all.

This particular project required me to create an AutoCAD table in the Customer's existing drawing, collect some information from that drawing and fill the table, using VisualLISP code, with that information.

For a  trial, I created a new drawing, created a table in it and played with the table until it looked perfect. Then I opened the Customer's drawing and copy-pasted the table in that drawing. The result (shown below) was unexpected. It seemed as if these were two different tables.

The Source Table
The copy of the table in Customer Drawing

Its obvious from the first look that there seems to be some mismatch with fonts. The fonts, in AutoCAD, are controlled by the Text Style.

In this particular case, I had made no changes to any of the settings that control the fonts nor had I changed any default settings while creating the table.

So, after some thoughtful moments, I decided to first compare the settings related to table in both the drawings. In both the the drawings, Table Style (that controls the formatting of tables) & Text Style (that controls the formatting of text) user were 'Standard' - the default styles. With these settings, the look and size of the text in table should theoretically be the exactly similar. But it wasn't. And that meant something was wrong somewhere.

On further detailed investigations, I found out that the Customer had modified the font in the 'Standard' text style - from default 'Arial' to 'txt'. 

The situation was ideal to throw the ball back into Customer's court and ask them to 'repair' and restore the 'Standard' text style in their drawing. But that might create another set of problems for the Customer (... not good, you see!). And who am I to advise the Customer to change their default settings?

So, taking matter into my own hands instead, I created a new text style in my drawing that was exact copy of the 'Standard' text style (in my drawing). I applied the new text style to text inside all the cells in the table. This did not make any difference to the text formatting in my drawing and the table displayed exactly as it appeared before.

When I copied the modified table in the Customer's drawing, the new text style was copied and applied to the text in the table automatically (This is the default AutoCAD behavior).
The table with new text style
Copy in Customer Drawing Displays correctly












I was then able to run my VisualLISP code successfully to populate 10 rows of data.

This done, my next step would be to educate and cajole the Customer to repair & restore the "Standard" text style.

Till then, the Customer maintains his own 'Standard' text style, me my own. And we live happily ever after.

So, ... till the next cAdventure in APIs .....  have a nice time and don't ever modify your default styles ....







April 6, 2019

Who's The Boss Here - The Main Assembly

A programmer, especially a CAD programmer, has many advantages over normal CAD users. Two of my favorites are:
  1. 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.
  2. 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.

  1. Make a list of all assembly files.
  2. '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.
  3. Find all second level sub-assemblies (child assemblies) 'referenced' by it.
  4. 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".
  5. Process all sub-assemblies in the list, one by one, in this manner.
  6. 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"
  7. 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.
  8. Find the name of the main assembly. This is obvious now - its the name of the parent assembly in each of the remaining lists.
  9. 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. 
  10. 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:


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.

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.'

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.
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.