Autodesk Inventor API Adventures – Monday

(Sometimes as a developer you get to be a super hero and overcome incredible odds. Of course, it helps if you have the skills to pull off magic – in this week-long story we paint a tongue-in-cheek picture of one of those situations.)

Fresh off the weekend, you are ready to get to work…. well, almost.  Two cups of coffee and a few web sites later, you open your email, discarding the all so tempting Nigerian 50% of 4 billion offer and spot an email from your boss with the subject “Gonna need you to come in on Saturday & Sunday”.   Now we know you usually just glance over the emails and file them under the knucklehead folder and move on, but realizing your boss can be somewhat of a comedian and by this subject alone, this might come up at the water fountain, you click on the email and you start to grin…

InventorEmail

You sit there with this grin because you have an ace in your pocket the boss doesn’t know about.  You know how to program.  Yes this was disclosed on your resume, but never utilized in the work environment because management is old school.  Leaning back and stretching your arms over your head, you murmur …“Time to bring them into the 21st century”.

Before you start, you decide to do a quick estimate to determine how much time you would have to put in to get it done in 30 days.  During the normal work flow, it would take about 120 days (or 640 work hours) to complete this task.  In order to do it in 30 days, you would have to work 21 hours a day (640 / 30 days).  This only concretes what you have to do…AUTOMATION.

You refill your coffee, sit back down, dig your heals in, and start programming.

First things first, get a handle on Inventor

After creating the solution and adding the Autodesk Inventor references, we can start with the code. I created a windows form and just made a button called [Start Inventor].

app1

Clicking the button runs the btnHook_Click method outlined below. However, during development, I would like to bind to a new instance of Inventor every time; while ensuring that there is not another running in the background (or in the system dumps generated by windows). I would also like the option to hide / show the inventor window… why? you may ask.. good question. It’s all about speed. If I can do things while hidden, the screen doesn’t have to redraw, except that I would like to watch it during development to make sure it’s doing what I need it to do. And since its default is to start up invisible, we need to change that.

private const string CLSID = "Inventor.Application";

private void btnHook_Click(object sender, EventArgs e)
{
	m_application = InitializeInventor(false, true);
	CloseAllDocuments();
}

private void CleanupRunningInstances(bool killInventors)
{
	System.Diagnostics.Process[] processes = null;
	if( killInventors )
	{
		processes = System.Diagnostics.Process.GetProcessesByName("Inventor");
		if (null != processes)
		{
			foreach (System.Diagnostics.Process p in processes)
			{
				p.Kill();
			}
		}
	}
	processes = System.Diagnostics.Process.GetProcessesByName("senddmp");
	if (null != processes)
	{
		foreach (System.Diagnostics.Process p in processes)
		{
			p.Kill();
		}
	}
}

private Inventor.Application InitializeInventor(bool bindToRunningInstance, bool makeVisible)
{
	CleanupRunningInstances(!bindToRunningInstance);
	Inventor.Application application = null;
	if (bindToRunningInstance)
	{
		// Try to get running instance
		try
		{
			application = (Inventor.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application");
		}
		catch (Exception ex)
		{
			System.Diagnostics.Debug.WriteLine(ex.Message);
		}
	}

	// no running instance was found or if you want a new instance, create one
	if (null == application)
	{
		try
		{
			System.Type inventorType = System.Type.GetTypeFromProgID(CLSID);
			if (null == inventorType)
			{
				// Cannot find registered typeID in the registery for Inventor
				return null;
			}
			application = (Inventor.Application)Activator.CreateInstance(inventorType);
		}
		catch (Exception ex)
		{
			System.Diagnostics.Debug.WriteLine(ex.Message);
		}
	}

	if (null != application)
	{
		application.Visible = makeVisible;
	}
	return application;
}

private void CloseAllDocuments()
{
	try
	{
		m_application.Documents.CloseAll(false);
	}
	catch
	{
	}
}

Awesome, you start up your code and presto, a new version of Autodesk Inventor(r) appears on your screen. You take a big gulp of your coffee and think…“I still got the mojo!”

Next we outline all the things we need to do

  • Project Setup
    1. Monday (today)
      1. Application Loading and Hooking….check!
      2. Remove unused / not needed Addins (everybody needs to save memory)
  • Main Assembly
    1. Tuesday
      1. Load Project File
      2. Load in the main assembly template
      3. Load in parts and position them
  • IDW
    1. Wednesday
      1. Load IDW Template
      2. Load Base View
      3. Load Projected View
      4. Scale
      5. Position
    2. Thursday
      1. Insert Breaks
      2. Dimension
      3. Insert Symbols
    3. Friday
      1. Export PDF
      2. Export DXF
      3. Save IDW
      4. Save JPG

Looking at this list, you think, heck, I bet I can have this done by Friday and go on that Xtreeme Parkour Wingsuit Bungie Slacklining Adventure with the family this weekend. You push back on your chair and join your colleagues at the local eating establishment.

<Insert Lunch here/>

Sitting there enjoying the post lunch soda, you decide to finish the day by making your application remove the unwanted addins that Inventor thoughtfully includes in every startup and include only the ones you will be needing.

Let’s use that handle to Inventor and get rid of some of these things.

First let’s create a list of ones we will need and while cycling thru the list, enable or disable each one, making sure to remove their automatic startup ability if we are not going to be using them.

Here is our list of things we need to finish by the end of the day…

  1. Let’s modify the button click to call the addIn cleanup method.
  2. I know I’m going to need to export the documents to PDF and to DXF… so we might as well include those now.

To start off, I’m going to create a list of ones to always have loaded and a list of ones to keep loaded, otherwise disable the addIns…

  • NOTE:  translators do not like to be unloaded for some reason, so just leave them alone…take my word on this
private Inventor.Application m_application;
private readonly string[] AddInsToLoad = { "Translator: DXF", "Translator: PDF"};

private void btnHook_Click(object sender, EventArgs e)
{
	m_application = InitializeInventor(false, true);
	CloseAllDocuments();
	AddInCleanup();
}

private void AddInCleanup()
{
	foreach (Inventor.ApplicationAddIn addIn in m_application.ApplicationAddIns)
	{
		try
		{
			if (AddInsToLoad.Contains(addIn.DisplayName))
			{
				if (!addIn.Activated)
				{
					addIn.Activate();
				}
				if (!addIn.LoadAutomatically)
				{
					addIn.LoadAutomatically = true;
				}
			}
			else
			{
				if (addIn.Activated)
				{
					addIn.Deactivate();
				}
				if (addIn.LoadAutomatically && !addIn.DisplayName.ToLower().Contains("translator:"))
				{
					addIn.LoadAutomatically = false;
				}
			}
		}
		catch (Exception)
		{
		}
	}
}

Here is a before and after of the AddIn Cleanup routines.

AddIn

As the day winds down, you lean back in your steel folding chair and admire your work. At that moment, your boss, Sam, walks by your cubical and you give him a smirk and a short chuckle. He pauses for a brief moment, but wisely decides against striking up a conversation with you. Your plan is now in motion and they cannot stop you. You pack up your belongings and head home. As you do, your boss seems very surprised that you are leaving at the normal time, but you do not break stride.

Start typing and press Enter to search