Inventor API: Custom add-in #3 – Working with the API, implementing the functionality

Hello there!
It’s time for the last part of our small tutorial on writing Inventor add-ins. Today we’ll write the actual implementation of the functionality described in previous post and explain some other small details. So, let’s get to work!

INVENTOR HANDLER

Our main functionality will be performed by a single class – InventorHandler (which will also be abstracted by IInventorHandler interface). It’s going to have only one public method AutoBreak() which will be responsible for applying the break to correct view. Let’s start with constructing it.

Private fields

It consist of three private fields: invInstance which stores reference to current instance of Inventor apllication, settings which stores reference to settings model and comparer which stores reference to IComparer implementation for sorting drawing views descending, area-wise.

This implementation is actually an internal class within our InventorHandler class. We won’t need that anywhere else.
Next, we have static list which contains orientation types which can work with our auto-break. This means that all views which are different orientation will not be take into consideration when executing auto break.

That list contain only perpendicular projections (back, left, right etc.) and the one called kArbitraryViewOrientation. This is the type of all views generated from a base view. This mean that although isometric views are not present this our collection the add-in will break that kind of view if it is created from an existing view.
The last thing is a predicate that is used for removing all views which are orientated differently than types allowed in the collection that we have just explained.

Constructor

The constructor for our InventorHandler class is very simple. It sets invInstance and settings to those given as arguments and instantiates new DrawingViewSizeComparerHelper class.

AutoBreak();

Now, let’s go through our only public method in the class:

It takes current active document in running Inventor application and sets a reference to in in a local variable drawing as a type DrawingDocument. Although property ActiveDocument of invInstance is of Document type (which is more general than DrawingDocument) it is safe to set is as DrawingDocument as our button to execute will be visible only in Drawing ribbon, therefore we’re sure that the active document IS DrawingDocument.
Next, we set another local variable which is of type DrawingView and assign result of getBiggest method executed with argument of drawing.ActiveSheet. This gets currently activated sheet in active document. If it’s null (meaning no drawing views are in the sheet) or it is too small to be broken the add-in will display a message and terminate execution of AutoBreak method. Otherwise, it continues.
Now, it checks if there already is a break applied to the view. If it is, again, it displays appropriate message and terminates.
Next step is to determine start and end points for the break. They are of type Point2d and they are set as local variables inside the method’s body. To give them appropriate values one of two methods is invoked: horizontalPoints or verticalPoints. These methods return boolean whether it is possible to break, and outs break points.
The last step is to apply the break:

It is done by executing Add method of BreakOperations collection in a view. It takes several arguments, as follows:

  • BreakOrientationTypeEnum – break orientation;
  • Point2D – start point;
  • Point2D – end point;
  • BreakStyleEnum – style of break, rectangular or structural;
  • integer – display level, in our case we pass default value of 5;
  • double – gap between left and right part of the view;
  • int – number of symbols, works only for rectangular view;
  • bool – propagate to parent view, defines if the break will be visible in parent view, in our case we pass default value true.

And that’s it. That’s the workflow. Now, as you probably noticed the method described above uses few private methods. To fully comprehend how the add-in works it is necessary to describe them as well.

DrawingView getBiggest(Sheet _sheet)

This method finds the biggest view in the given sheet. All views which are not orientated correctly (remember the list of ViewOrientationTypeEnum?) will be excluded from the selection.

bool isHorizontal(DrawingView _view)

Simply checks if a view is wider than higher and returns true if does.

bool canBeBroken(DrawingView _view, bool _isHorizontal)

This one checks if a view is sufficiently wide for horizontal break, or sufficiently high for vertical break. Minimum height/width is 5 cm plus gap. Remember that the API operates on centimetres expresses in variables of type double.

bool horizontalPoints/verticalPoints(DrawingView _view, int _percentage, out Point2d _start, out Point2d _end)

These two counterparting methods calculate start and end points based on given view and percentage of the view that needs to be removed. Methods return boolean whether a break can be applied and outs the points.

Converters

As some values from settings model are of simple types while methods exposed by the API require some arguments of different enum types there are two converters in the InventorHandler class: one is to convert boolean to BreakOrientationEnum

and the second one is to convert integer to BreakStyleEnum:

And that’s it if it comes to our InventorHandler class. However, to make the add-in actually work there are some changes needed in StandardAddInServer class.

CHANGES IN MAIN ADD-IN CLASS

First of all, we need an instance of InventorHandler. We’ll create a private field for that and initialise it in the constructor:

The last step is to modify action that is fired when the ‘Apply’ button is clicked:

And that’s it. The add-in is now functional. See the demo below:



FINAL REMARKS

There are two things I want to mention at this point. First, is about embedding the stdole assembly. When it’s added to the project and the project is built you will get a warning message:

Although, it does not affect the build you can get rid of these messages by setting Embed Interop Types property of stdole reference to false:

The other things is a word of explanation about NameValueMap interface. It used (amongst other uses) in the API to pass parameters in the events (as in our case events fired by clicking buttons). It works similarly to dictionaries, it stores pairs of name (which are strings) and values (which are of type object). I will not describe it in details (if you need that, simply go to its metadata in Visual Studio), but now you know the main thing – it is name/value pair to pass event parameters.

 

CONCLUSION

A vast portion of things can be manually done in Inventor can be automatised. However, the freedom in modelling that software gives you makes it really difficult to develop universal add-ins that will work always, no matter what you’re modelling. But all of translation, conversion, export things can be easily worked with. I know that there are some add-in that allow to generate models of sprockets, pulleys etc. and that works perfectly.
The hard thing when developing add-in is debugging. Possibilities here are limited because every time you want to debug you need to build your project and run the application, and you won’t get any error messages – either the application will crash, the add-in will be disabled or it won’t be executed.

To make things clear – I have worked with that software as a professional for more that 5 years and I am a big, big fan. I have experience with others systems, but this one seems to be most user-friendly, most of the features works as you would expect and has that professional-feel. But, it’s not a review, so I’ll stop here.
Thanks for your time, I hope that it is in any way useful for you. Good luck!
Michal

GitHub repo: https://github.com/mickaj/AutoBreaker-Inventor

Inventor API – Custom add-in Part #1
Inventor API – Custom add-in Part #2