Inventor API: EventTimingEnum

Hi there,
Some time ago I started writing an add-in for Autodesk Inventor. That software exposes an API that allow to develop add-ins in C#/.NET. In this post I am not going to write anything specific about the project; it will neither be an insight into API specifics. I just want to give quick explanation about controlling events with use of EventTimigEnum.

Some actions in Inventor can take a bit of a while – for instance placing big component into an assembly. Therefore, it is possible to decide when custom action is performed – either before or after an event is completed.

Let’s start this demo with writing a method that will be executed when a new component is placed into an assembly:

Just a brief explanation to the code above: of course only a method with matching signature can be assigned to an event, and it is necessary to set value of HandlingCodeEnum output parameter.
Now, to attach that method to an event that fires whenever a new component is inserted to assembly you need to access Inventor instance. In this example it will be done in add-in Activate method.

Once that is done we can start Inventor and see what’s the result:



As you have probably noticed our CustomAction was executed twice. Sometimes this behaviour is desired, sometimes it’s not. Now, let’s modify our method to perform action only after the event is completed. To do that we need to check value of EventTimingEnum parameter and perform action whenever its value is what we desire.

Now, the message box will be displayed only after the event is completed. EventTimingEnum can have one of three possible values: kAfterkBefore (which are self explanatory) and kAbort. The last value can be used in case we want to perform an action when an event is cancelled – for instance, when opening an assembly with lost reference user can decide to cancel opening.

It is also important to mention that not all events in Inventor are fired both kBefore and kAfter. Most of them are but you need to be aware that there are exceptions from that rule.

So that’s it if it comes to EventTimingEnum.
Unfortunately, there is not much about writing Inventor add-ins in .NET. What I recommend to check is first and foremost this GitHub repository:
https://github.com/ADN-DevTech/Inventor-Training-Material
It is complete course on Inventor API. There are presentations and code examples (in VB.NET and C#) for each chapter.
The other thing is class diagram delivered by Autodesk which comes with Inventor SDK installation. It can be found in Autodesk/Inventor/SDK/DeveloperTools/Docs in PublicDocuments on your C drive.
Regards, Michal

WPF: TreeView control

Hello there! It’s been a while since I finished GetNoticed contest and my last post here. I am done with SheetMetalArranger – at least for the minute. But that the contest is done doesn’t mean that I am done with programming. Not at all!

I started new project (maybe one time I will get back to SheetMetalArranger to improve it, but after ten weeks I need something fresh now). It doesn’t matter what the project is about at the minute (I will probably write a post or two about that), the important thing is that I’m continuing with WPF and the time has come to take a closer look at TreeView control.

Basics

TreeView control is used to display hierarchically organised structure. The best example is folder tree, for instance the one you have in Windows Explorer.

Here’s simplest example:

To build hard-coded tree you simply nest one <TreeViewItem> into another and build your structure. Notice that Header property is what is going to be displayed in your application. There are two other properties of TreeViewItem that should be mentioned here: IsExpanded and IsSelected which are pretty much self-explanatory but it is worth to mention them as they are fundamental for controlling behaviour of the control.

Binding

Binding a collection to TreeView can be easily achieved, it is no different as other controls. You simply bind a collection to ItemsSource property. But the tricky thing is that you need to reflect the hierarchy somehow. One way to do that could be binding a collection that contains objects of class TreeViewItem which is equipped in collection Items which contains child objects. Here’s the same example but with the difference that all data is stored in data model:

1) Lets start with the data model: our library node will consist of name, collection of books (stored as strings) and collection of sub-nodes.

2) Our actual data for the purpose of this example will be stored in static class with one static method GetData() that return instance of LibContainer

3) Our view model will consist of observalbe collection of TreeViewItems and in its constructor it will get data from the above static class. Inside the view model there is also one small private method that converts LibContainers to TreeViewItems

4) We set instance of view model and set it as data context. For example as below. Now, after that our tree view can be simplified just to only one line.

Load on-demand

The above example is nice and easy. It gets a bit more complicated when you want to load content of your tree view on-demand when content of your tree is huge and loading all data at once would be lengthy operation – I guess that’s common situation.

To achieve that we need to build custom class that will replace TreeViewItems in collection in our view model. That class must have: 1) collection of child items of the same class, 2) Parent, IsExpanded and IsSelected properties, 3) method to load children, 4) property that defines if the element can be expanded.

Here’s our example build this way:

What’s important in the code above is that Children collection must contain dummy element before actual elements are loaded. This is necessary because it would not be possible to expand the element, therefore it would not be possible to execute method that load further elements.

ViewModel class will now have only collection of TreeElement and will gather data from DataModel in its constructor.

Now, we need to define our TreeView control to display our custom items correctly. This is done by creating local style where we bind IsExpanded and IsSelected properties of TreeViewItem with counterparting properties of our custom TreeElement

And that’s it. This is how I use TreeView control. Possible extension to the above would be to create custom WPF control to handle custom types of tree elements and equip it with dependency property that exposes currently selected item. But that’s easy to do and isn’t in any way specific to TreeView.

So, thanks for today and good luck!

Sources:
WPF 4.5 Księga eksperta. Podręcznikprogramisty WPF 4.5! Adam Nathan (translated by Paweł Gonera, Ireneusz Jakóbik), published by HELION S.A 2005
https://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode

 

GetNoticed DEV#10: Updates in demo

Good evening!
Although the demo was presented in my previous post I have updated it slightly: I added a progress dialog. This is to report how many items have been processed and how many of them is yet to be processed. The progress dialog also ensures the user that the program isn’t hanging without checking that in Windows task manager. Links to source code and installer below. And here’s quick video to demonstrate that:


 

Future of SheetMetalArranger
This project was developed for purposes of GetNoticed contest. At this moment I can’t say if I’m going to do anything more with it. Maybe I will, maybe I won’t. But if I do here’s what could be added/improved:

  •  efficiency: this is the most important factor to asses this program. In on of my previous DEV posts I wrote that 82% is good enough. And for the purpose of the contest it is enough, but if Arranger is to really serve its purpose it needs to be more efficient. It could be achiever by improving merging. Now only boxes which are the same width or the same height and are adjacent on equal edge are merger.
  • project files: it would be useful if arrangements could be saved and reopened later, JSON or XML would do the job
  • export: the demo just demonstrates calculated arrangement in its UI, it also saves generated PNGs in ProgramData folder on C:/ drive. But it would be much useful if a user could click a button and save them in required location. Also export to DXF would be handy and brief look at DXF standard allows me to think that it is achievable.

GetNoticed – my conclusion
As this is my last post for the contest I allow myself to write few words of conclusion. First and foremost the contest was a great boost of motivation. For me personally this is the biggest advantage. I am aware that my project isn’t the best, maybe it’s not even good. But keep in mind that I am still a newbie but I’m excited about the path that’s in front of me.
Thanks for everyone who read even one of my post.

Regards, Michal

SheetMetalArranger on GitHub
ClickOnce installer

GetNoticed IT#10: Factory method

Good evening!
Post number TEN in my GetNoticed IT series! In my DEV#8 post I mentioned that most likely my next IT post will be about tabs in WPF/MVVM but as you’ve probably figured it out it won’t be about tabs. It’s going to be about factory method design pattern.
So, factory method allows to encapsulate object creation. For instance, you can bring all logic that decides which object to create into one class. Or another example. In my project I used some singletons (which is considered to be an anti-pattern). This could have been avoided by using factory method (and it will be). In this case wherever I wanted to use an instance of singleton I would call factory method that returns object of my singleton instead of static property Instance.

How it works
Basic construction of that pattern is that you create abstractions of your factory class and of your – call it – product. Then you can create multiple different factories that return concrete product. Depending on what logic you will include in your concrete factory. Once you have that concrete factory you inject that into your class and let your class use that factory to instantiate concrete objects. It is very well explained by Christopher Okhravi in his just recently posted video. I highly recommend his videos.

Example
I prepared quick example for the purpose of this post. There are books and bookstore:

Pretty simple: book described by two properties and a method to display details; and a bookstore with a collection of books and a method to list all books in that collection.
Now, our books can be paper, ebooks or audiobooks:

All of the above can be stored in our bookstore. And we want to decide which one to create at run time. So, let’s introduce a factory. We’ll start with abstraction and then concrete factories for each type of book. Our factory will have only one method that returns an object which is abstracted by IBook interface:

Now, we need to update our BookStore class and equip it with factory property and allow a factory to be injected in the constructor.

What more you can notice in the code above Factory property is public therefore you can swap factories anytime you want.
And here’s how you can do that:

When an instance of BookStore is created in gets default factory injected through the constructor and then every time a book is about to be created the factory is replaced by another factory. The output of the above would be:

Notice that each book is of different type depending on which factory has been used to create the object.
So, that’s the basic use of factory method. To dig deeper I recommend the links below:

https://www.youtube.com/watch?v=EcFVTgRHJLM
https://stackoverflow.com/questions/69849/factory-pattern-when-to-use-factory-methods

I hope that this post (as the rest of my IT posts) is in any way useful for you. That is my last post IT series post for Get Noticed contest. But I will continue blogging and reporting my learning progress so if you’ve been hoping for that post about tabs please come back later. You’ll get it, promise!
Thanks, Michal

GetNoticed DEV#9: Demo is alive!

Good evening!
Demo application is alive! Here’s quick video of how it operates:



You can set your own items or click button to randomly create 10 items. Panels can be defined by user or you may allow the application to create unlimited number of panels with size set by user. So feel free to test it.
Next step would be to refactor the code. It is nasty, nasty I say. I will probably continue to develop the project after the contest is finished so the code will get cleaner. I don’t know if the app will get any bigger but for me it will be finished when I am not ashamed to show off with the code 🙂
Thanks for today, check the links below and good luck!

SheetMetalArranger on GitHub
Zip file with ClickOnce installer

 

GetNoticed DEV#8: Demo app mockup

Good evening!
Just to let you know that the project isn’t dead. As planned I’m trying to prepare a working demo of my app. I’ve been working on it since last weekend and I’m at the stage where I can present how the application will look:

Of course the mock-up is not all that I have achieved so far. All panels are fully working and backed up by view model. The most time consuming for me was to figure out how to work DataGrids and make tabs to be stored in a collection inside view model (maybe my next IT post will be about it). Now I need to make the view model communicate with ArrangerLibrary which will be my model. I will also need to add a class to ArrangerLibrary which will be responsible for generating PNGs. After that is done, code of the demo app will need to be cleaned and reorganised a bit for clarity.
It’s short and quick today but consider it as a far far away beacon that gives me hope that the goal is achievable.
Thanks, Michal

Nice tutorial how to work with tab control: https://www.youtube.com/watch?v=rFhmTccRUpQ
SheetMetalArranger on GitHub



GetNoticed IT#9: User control with data grid and observable collection

Good morning!
It’s been 10 days since my last post so the time is high! Today I’m going to write how to bind an observable collection of custom objects to a data grid in a WPF user control. Some time ago I wrote a post about basic use of user controls (see here) so this post you are reading right now can be considered as extension of the first one.

Objects in collection
Let’s start with preparing a class which objects will be stored in our collection. I won’t look for anything bright, I will just use something for my project: the class will store information about rectangles: height, width, margin and if a rectangle can be rotated. Additionally the class will have a property that returns area of a rectangle.

That’s the basic implementation of our ListedItem class. Now, to use it with observable collection in a way that it is bound to datagrid in UI and all values are automatically refreshed it is necessary to implement INotifyPropertyChanged. At the same time it would be wise to tweak our class a little bit: properties Height and Width cannot be smaller than 1. Also, when implementing INotifyPropertyChanged it is necessary to notify about Area property changed when any of Height or Width changes.

The last step would be to add a parameterless constructor that assigns all properties with default values.

View model
Our observable collection will be stored in our view model.

In the constructor of MainViewModel class we initialize the collection and add first item. And that’s for the purpose of this post is sufficient.

User control
Out user control will consist only of data grid inside a group box therefore the XAML is very simple.

What’s important in the code above are two things marked above: 1) assigning name to the user control (“this”), 2) defining data grid and its binding to dependency property Source.
Now, let’s move on to the code-behind the user control where we define dependency property.

We need to set the property of type ObservableCollection<ListedItem>, owner type ItemsList (as the name of our user control class) and name Source.

View
Now the last thing: combining all together in view. First of all we need to add namespace that contains our user control to namespaces used by the UI, create an instance of view model that is going to be used be the UI and set it as data context of top level grid.

To add our user control to the UI and bind observable collection for view model:

In this case binding mode is set as TwoWay because I want changes made by user in data grid to be reflected in collection in view model. But you have complete freedom here, that depends only on your needs.

So, basically that’s it. Before I finish few notes about customising the data grid.

Columns
The implementation above will generate columns in data grid according to properties exposed by elements in collection. But that is not the only way. you can set up your own names, for instance when you’re building multi-language app. To do that you need first set AutoGenerateColumns property of your data grid to false, and second define the columns manually. In our case that would be:

Note, that you need to be careful to use correct column type and to set binding correctly. In our case Area property is generated automatically therefore user must not be able to put anything in that column. To achieve that I had to set binding mode for this column to OneWay.

User edits
Depending on particular needs you may want to disable editing your data grid. There are certain properties that allows you to customise access to your data grid. To disable any edits you must set IsReadOnly to true, to make more precise customisation you can use set of CanUser properties which are pretty self-explanatory so there’s no point in describing them here.

Thanks for today, I hope that it’s gonna be somehow useful for you.
Regards, Michal

Sources:
https://msdn.microsoft.com/en-us/library/ee340710(v=vs.110).aspx
http://helion.pl/ksiazki/mvvm-i-xaml-w-visual-studio-2015-jacek-matulewski,xamlmv.htm

 

GetNoticed DEV#7: 82% Not bad…

Hi there!
As promised in my previous dev post: I have performed series of test how efficient the algorithm is and the results are satisfactory – average of 82% utilisation.

Methodology
To measure the efficiency I ran 10 iterations of randomly generated set of rectangles. The size of the panel was fixed to 1500×3000 as this is standard size of sheet and most commonly used – at least that is my experience. Exact size of items was generated randomly, however there were some constraints to make the test more life-like. The list below illustrates that:

  • 15 items of size 50 to 60% panel size
  • 20 items of size 30 to 40% panel size
  • 30 items of size 20 to 30% panel size
  • 50 items of size 5 to 20% panel size

The number of panels was limited to 10 – this is to avoid having last panel filled only in quarter or half; the test is to check how densely the algorithm can pack items. In real application it is common to that the last panel is used only in fraction.

Tool
To perform the test I used xUnit. I wrote a unit test which doesn’t assert anything, just print the output string.

Results
As written at the very beginning the average utilisation is around 82%. I find that value satisfactory. Here’s quick extract from the report with most important figures:
Overall average utilisation: 0.8226
Overall max utilisation: 0.838
Overall min utilisation: 0.807
Single panel max utilisation: 0.911
Single panel min utilisation: 0.694

Conclusion
The algorithm performs sufficiently well. At this point I won’t look for further improvements.

Thanks, Michal

Report in xlsx
SheetMetalArranger on GitHub

 

GetNoticed IT#8: Singleton

Hello there!
The infamous singleton – a pattern and an anti-pattern. Despite it’s bad reputation I decided to use it in my project for GetNoticed contest. I explained it why in one of my posts: my singletons consist of methods only and they’re sealed.

Thread safety
The most dubious concern in singletons is their thread safety. This can be fixed by using locks (examples here) or by including private and static constructors. Private constructor makes it impossible to create an instance of a singleton class anywhere in the code. Static constructor will be executed only once: when first instance of the class is created or when a static member of a class is referenced.

Template
Whenever I need (and so far I have used them only once) a singleton I follow fourth template proposed by C# in depth. The template consist of private and static constructors, private static readonly instance field and public static property that gets instance.

Anti-pattern
Most sources I have encountered so far point out 4 main reasons to consider it as an anti-pattern.

  • accessible as a global instance and thus hiding dependencies
  • violation of SRP: singleton class is responsible for its business purpose and for its life cycle
  • tight coupling and weaker testability due to use of concrete singleton implementation
  • singleton carries its state as long as the program runs

These disadvantages are properly described (and discussed) by Scott Densmore and Johannes Rudolph. I recommend to read their posts.

To conclude I would say that I will be extremely careful next time I think about using singletons and will probably think of other solution for more complicated things than simple implementations of IComparer<T>.

Thanks, Michal

 

GetNoticed DEV#6: ArrangerLibrary seems to be completed

Hi!
Let me start with one general conclusion after this weekend: in my case it’s better to have coding sessions rarely but for longer time rather that having short sessions more often. I have accomplished more in today’s afternoon and yesterday’s evening that in last two or three weeks. But that’s just my case, not saying that’s a general rule.
Having the above said, let’s get back to real business: the ArrangerLibrary seems to be more or less completed. Of course some additions are still required (for instance a class that would generate a PNG image for calculated arrangement) but it’s core functionality (which is to calculate best arrangement of items) is finished. I haven’t thoroughly tested it yet but I am hoping to do that next week. After that, the next step would be to build a quickie demo with UI. Unfortunately, the risk is high that I will not have finished full application before GetNoticed contest is ended.
In my previous post I wrote that merging of adjacent boxes in panel had been implemented. The most important thing in this update is that now the algorithm, while placing an item into a box, looks for all possible assignments and create a separate branch in results tree for each possible assignment. Having that done at the end the algorithm can return all possible arrangements or just one which is most effective. Maybe I will change that so a new branch is created only if there are two equally good placements (utilisation-wise). I need to do a bit of testing before I make final decision.
Another important update is that now it is possible to set a margin for every item and decide if an item can be rotated.

Here are screenshots of results of two test cases:
1) Panel size is 8 units high and 14 units wide2) Panel size is 1500 units high and 3000 units wide
As you can see results look acceptable but these test cannot be considered as reliable, next week I’ll try to conduct more test with inputs from real life (or at least more plausible) but I don’t expect the results to worsen or get significantly better. We’ll see…
Thanks, Michal

SheetMetalArranger on GitHub
Design sheet (*.xlsx)