<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10436678</id><updated>2011-12-14T21:56:25.373-05:00</updated><title type='text'>area 31</title><subtitle type='html'>Custom programming, design ideas and other interesting oddities for CAD programmers.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://area31.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10436678.post-115893234455066579</id><published>2006-09-22T08:37:00.000-05:00</published><updated>2006-09-22T08:41:15.030-05:00</updated><title type='text'>Autodesk Labs</title><content type='html'>Ever wondered what Autodesk is doing between releases?  Check out the &lt;a href="http://labs.autodesk.com/" target="_blank"&gt;Autodesk Labs&lt;/a&gt; site to have a sneak peek at what might be coming in the next release.  The feature recognition function looks very promising.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-115893234455066579?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/115893234455066579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=115893234455066579&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/115893234455066579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/115893234455066579'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/09/autodesk-labs.html' title='Autodesk Labs'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-114441646029833393</id><published>2006-04-07T08:16:00.000-05:00</published><updated>2006-04-07T08:27:42.426-05:00</updated><title type='text'>Error 1406 During Install - A Better Solution</title><content type='html'>Autodesk has come up with a simple solution to the 1406 error that's been annoying many Autodesk customers lately.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Early in the installation of Autodesk Inventor products, some customers may experience Error 1406:&lt;br /&gt;&lt;br /&gt;This error occurs if you have &lt;span style="font-weight:bold;"&gt;Macromedia Flash Player 8a&lt;/span&gt; installed on your system. Flash Player 8a was just recently released, so it is newer than version 8 that gets installed by Autodesk Inventor. You may already have version 8a without knowing.&lt;br /&gt;&lt;br /&gt;You should uninstall &lt;span style="font-weight:bold;"&gt;Flash Player 8a&lt;/span&gt; before installing Autodesk Inventor. Since Autodesk Inventor automatically installs &lt;span style="font-weight:bold;"&gt;Flash Player 8&lt;/span&gt; during installation; you will always have a working version of Flash Player. Future upgrades to Flash Player should not adversely affect your Autodesk Inventor environment.&lt;br /&gt;&lt;br /&gt;Please complete the following if you encounter this error:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt;Cancel the installation of Autodesk Inventor&lt;br /&gt; &lt;li&gt;Close all Internet Explorer and other internet browsers&lt;br /&gt; &lt;li&gt;Run C:\WINDOWS\system32\Macromed\Flash\UninstFl.exe to clean all Flash 8a registries&lt;br /&gt; &lt;li&gt;Remove Macromedia Flash Player 8 from Add/remove programs&lt;br /&gt; &lt;li&gt;Note: Although Flash Player 8 is listed, this is really version 8a&lt;br /&gt; &lt;li&gt;Retry installation of Autodesk Inventor&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;If you are not successful in completing the above steps, please contact Product Support for further assistance.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;...thanks Adobe.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-114441646029833393?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/114441646029833393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=114441646029833393&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114441646029833393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114441646029833393'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/04/error-1406-during-install-better.html' title='Error 1406 During Install - A Better Solution'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-114416713674622912</id><published>2006-04-04T11:11:00.000-05:00</published><updated>2006-04-04T11:15:35.026-05:00</updated><title type='text'>Error 1406 During Install</title><content type='html'>I've had a number of customers contact me lately about errors during new product installs and updates.  The error they are receiving is 1406.  Initially, Autodesk had no clue what was going on and kept directing me to the Microsoft MSDN article(&lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;300451" target="_blank"&gt;link&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Seems there's a bit of a bug in the Macromedia Flash player used in the install screen of Autodesk applications.  Macromedia is apparently working on it but there is no known fix yet.  Two methods I have found that have fairly good results are as follows:&lt;br /&gt;&lt;br /&gt;1. If you get a 1406 error message when installing Inventor, keep hitting 'Ignore' when installing and the install will complete.  Start Inventor and if the Content Center is broken or not there at all, do a Repair install from the Add/Remove Programs screen.  One customer has had success with this method.&lt;br /&gt;&lt;br /&gt;2. The preferred method is listed below and was sent to me from Autodesk Support:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;We have seen a rash of 1406 errors recently.&lt;br /&gt;&lt;br /&gt;We have noticed that there could be a mistake in the permissions for this registry key; on the affected computers the group 'Everyone' has special permissions: they are DENIED for Read en Change. &lt;br /&gt;-Administrators have full control but the 'denied' rights are higher in level, so the administrator is denied.&lt;br /&gt;-Also on other similar registry keys we don't see the 'everyone, special permissions'.&lt;br /&gt;If you change the permissions of the folder (for this registry key) for this user group (everyone) to 'Full Control' the problem is solved; you can click retry and the installation continues until the next error (you receive 3 errors in total).&lt;br /&gt;&lt;br /&gt;Example of affected registry keys:&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{D27CDB70-AE6D-11cf-96B8-444553540000}] :@="Macromedia Flash Factory Object" and [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{1171A62F-05D2-11D1-83FC-00A0C9089C5A}] :@="FlashProp Class"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If I get a more definitive answer I will update this article.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-114416713674622912?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/114416713674622912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=114416713674622912&amp;isPopup=true' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114416713674622912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114416713674622912'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/04/error-1406-during-install.html' title='Error 1406 During Install'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-114389299867563007</id><published>2006-04-01T06:56:00.000-05:00</published><updated>2006-04-01T07:03:55.110-05:00</updated><title type='text'>CAD Insider</title><content type='html'>&lt;span class="sg"&gt;Roopinder Tara, the Editor of &lt;a href="www.TenLinks.com" target="_blank"&gt;TenLinks&lt;/a&gt; has started a CAD blog entitled &lt;a href="http://cadinsider.typepad.com/" target="_blank"&gt;CAD Insider&lt;/a&gt;.  The name fits pretty well too, I don't know anyone that has access to more CAD related news than Roopinder.  Be sure to check it out.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-114389299867563007?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://cadinsider.typepad.com/' title='CAD Insider'/><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/114389299867563007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=114389299867563007&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114389299867563007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114389299867563007'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/04/cad-insider.html' title='CAD Insider'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-114238519261732425</id><published>2006-03-14T20:06:00.000-05:00</published><updated>2006-03-24T10:53:01.366-05:00</updated><title type='text'>Inventor 10 Super-clean Un-install</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Platform:&lt;/span&gt; Inventor 10&lt;br /&gt;&lt;br /&gt;With Inventor 11 right around the corner, I thought I'd post a step-by-step list of things required to properly remove Inventor 10.  Now, I'm not suggesting you move to Inventor 11 as soon as it comes out.  Most people wait for the first service pack but having a clean computer is a great starting point.&lt;br /&gt;&lt;br /&gt;To do a super-clean un-install try the following.  You will lose any customization you've made as deleting the registry keys removes all traces of the Inventor program except for the licensing:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Un-install "Autodesk Inventor10" using Add/Remove programs&lt;/li&gt;&lt;li&gt;Un-install "Microsoft SQL Server Desktop Engine (INVENTORCONTENT)" using Add/Remove programs&lt;/li&gt;&lt;li&gt;Delete the "Inventor 10" folder&lt;/li&gt;&lt;li&gt;Delete the C:\Program Files\Microsoft SQL Server\MSSQL$INVENTORCONTENT folder&lt;/li&gt;&lt;li&gt;Empty your "Temp" folder&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to Start--&gt;Programs--&gt;Run--&gt;type Regedit&lt;/li&gt;&lt;li&gt;Delete the folder HKEY_CURRENT_USER\Software\Autodesk\Inventor\RegistryVersion10.0&lt;/li&gt;&lt;li&gt;Delete the folder HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\Inventor\RegistryVersion10.0&lt;/li&gt;&lt;li&gt;Delete the folder HKEY_CURRENT_USER\Software\Autodesk\Inventor\Current Version&lt;/li&gt;&lt;li&gt;Delete the folder HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\Inventor\Current Version&lt;/li&gt;&lt;li&gt;Reboot&lt;/li&gt;&lt;li&gt;Install the version of Inventor you want, then all required &lt;a target="_blank" href="http://usa.autodesk.com/adsk/servlet/ps/dl/index?siteID=123112&amp;id=2334435&amp;amp;linkID=4183232#section1"&gt;hot fixes and service packs&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-114238519261732425?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/114238519261732425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=114238519261732425&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114238519261732425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/114238519261732425'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/03/inventor-10-super-clean-un-install.html' title='Inventor 10 Super-clean Un-install'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-113718257571713292</id><published>2006-01-13T14:04:00.000-05:00</published><updated>2006-01-13T15:04:37.670-05:00</updated><title type='text'>Linking AutoCAD VBA to a VB DLL</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2006&lt;br&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; Required VB 6&lt;br&gt;&lt;br /&gt;&lt;br /&gt;Visual Basic for Applications (VBA) is a great tool for quick routines or even large projects that have no budget.  However, if the project requires any controls that VBA does not include, like a listview, a full Visual Basic application might be required.  Linking a VB application to AutoCAD is not that easy and is usually left to C++ or .Net programmers with ObjectARX.&lt;br /&gt;&lt;br /&gt;Fortunately, we can reference a Visual Basic Dynamic Link Library (DLL) within AutoCAD VBA.&lt;br /&gt;&lt;br /&gt;Start a Visual Basic project with the ActiveX Dll template and copy the code below into the class module.&lt;br /&gt;&lt;br /&gt;&lt;div class="codeblock"&gt;&lt;br&gt;&lt;br /&gt;Public Function HelloWorld() As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  MsgBox "Hello World!", vbOKOnly + vbExclamation, "Hello"&lt;br /&gt;&lt;br /&gt;  HelloWorld = True&lt;br /&gt;ErrorHandler:&lt;br /&gt;&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Rename the class module to "Sample" and rename the project to "vb2vba".  Save the project as "vb2vba" as well.  Compile the application as "vb2vba.dll".&lt;br /&gt;&lt;br /&gt;In AutoCAD 2006, open the VBA Interface and add the code block below to the "ThisDrawing" module.&lt;br /&gt;&lt;br /&gt;&lt;div class="codeblock"&gt;&lt;br&gt;&lt;br /&gt;Public Sub ShowDialog()&lt;br /&gt;' Show the Hello World message box&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim objSample As vb2vba.Sample&lt;br /&gt;&lt;br /&gt;  Set objSample = New vb2vba.Sample&lt;br /&gt;  If Not objSample.HelloWorld = True Then Err.Raise vbObjectError + 1, , "Error calling HelloWorld from ShowDialog"&lt;br /&gt;&lt;br /&gt;  Set objSample = Nothing&lt;br /&gt;&lt;br /&gt;  Exit Sub&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set objSample = Nothing&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Click on the "Tools" menu in the VBA IDE and select "References...".  Find "vb2vba" and click the check mark on.&lt;br /&gt;&lt;br /&gt;You should now be able to run the "ShowDialog" subroutine in AutoCAD VBA.  It will call the VB Dll and display a message box with the famous "Hello World!" message.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-113718257571713292?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/113718257571713292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=113718257571713292&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/113718257571713292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/113718257571713292'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/01/linking-autocad-vba-to-vb-dll.html' title='Linking AutoCAD VBA to a VB DLL'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-113639651264223364</id><published>2006-01-04T12:35:00.000-05:00</published><updated>2006-01-04T12:41:52.643-05:00</updated><title type='text'>New Blog on the Block</title><content type='html'>I thought I should post a quick note about a new blog some of you might be interested in. &lt;a href="http://cadgneto.blogs.com/" target="_blank"&gt;CADgneto&lt;/a&gt; focuses on the Autodesk mechanical products with extra emphasis on &lt;a href="http://usa.autodesk.com/adsk/servlet/index?siteID=123112&amp;id=4255921"&gt;AutoCAD Electrical&lt;/a&gt;.  CADgneto is maintained by Steve McCarthy, an Applicaitons Specialist (and coworker) with &lt;a href="http://solidcad.ca/" target="_blank"&gt;SolidCAD&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Steve usualy knows more about AutoCAD Electrical than the Autodesk support desk so he's a good reference for those annoying little quirks &lt;a href="http://usa.autodesk.com/adsk/servlet/index?siteID=123112&amp;id=4255921"&gt;AutoCAD Electrical&lt;/a&gt; sometimes has.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-113639651264223364?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/113639651264223364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=113639651264223364&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/113639651264223364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/113639651264223364'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2006/01/new-blog-on-block.html' title='New Blog on the Block'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-112863142013104556</id><published>2005-10-06T15:23:00.000-05:00</published><updated>2005-10-06T15:44:06.886-05:00</updated><title type='text'>How to Improve Large Assembly Performance in Autodesk Inventor®</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; Inventor&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.summerfabulous.com/area31/Inventor_Performance.pdf"&gt;Inventor_Performance.pdf&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;I've been supporting Autodesk Inventor&amp;reg; for a while now and about seventy percent of the support calls I receive are from users having problems with 80% resource warnings or complete system crashes while working on large or very complex models.&lt;br /&gt;&lt;br /&gt;While there is no sure-fire way to completely protect your CAD system from crashing, there are a few tips and tricks you can do to hold your system together a bit longer.  If you're having problems with Inventor, download the PDF file listed above and see if some of the suggestions can help you out.  This document is a work in progress and is in no way complete.  If I’ve missed anything please let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-112863142013104556?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/112863142013104556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=112863142013104556&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/112863142013104556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/112863142013104556'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/10/how-to-improve-large-assembly.html' title='How to Improve Large Assembly Performance in Autodesk Inventor&amp;reg;'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-112128867523554184</id><published>2005-07-13T16:05:00.000-05:00</published><updated>2005-07-13T16:06:07.616-05:00</updated><title type='text'>Add-In Versioning In Autodesk Inventor</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; Inventor 10&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; n/a&lt;br /&gt;&lt;br /&gt;I've recently been developing an Add-In for Inventor to bring together all the utilities I've developed over the last few years.  One of the utilities requires a new toolbar in Inventor whenever a part or assembly document is open.  The API help files are pretty good but they have an issue with version skew.  Page 6 of the UI Customization overview explains AddIn Versioning in depth but Page 3 of the Add-In overview doesn't have the Version entry added to the registry file example.&lt;br /&gt;&lt;br /&gt;If you are developing an Add-In that deals with CommandBar creation or attaching buttons to a command bar listen up!  The FirstTime variable will never be set to False in the ApplicationAddInServer_Activate event if you compile and run your Add-In.  This means that you have &lt;span style="font-weight:bold;"&gt;ONE CHANCE&lt;/span&gt; to get it right.&lt;br /&gt;&lt;br /&gt;I posted this dilemma on the Inventor customization newsgroup (&lt;a href="http://discussion.autodesk.com/forum.jspa?forumID=120" target="_blank"&gt;http://discussion.autodesk.com/forum.jspa?forumID=120&lt;/a&gt;) and was quickly supplied with an answer from Sanjay Ramaswamy at Autodesk:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;The FirstTime argument will be true only when your Add-In is being loaded for &lt;br /&gt;the very first time after registration. User interface items such as command &lt;br /&gt;bars &amp; controls need to be created only during the first time and they will &lt;br /&gt;be persisted by Inventor. Please see page 6 of the UI Customization overview &lt;br /&gt;in Programming Help for a detailed explanation regarding this.&lt;br /&gt;&lt;br /&gt;In order to work around your present situation, you can force the FirstTime &lt;br /&gt;flag to True by changing the value of the "Version" entry in your Add-In's &lt;br /&gt;registry (the same place where you set things such as LoadOnStartUp, &lt;br /&gt;SupportedSoftwareVersionEqualTo, etc. Just increment the value of the &lt;br /&gt;Version entry to 1 (and 2,3,4,.... for each time you want to change the way &lt;br /&gt;your user interface looks).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here's a link to the full discussion thread:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;a href="http://discussion.autodesk.com/thread.jspa?threadID=415210"&gt;http://discussion.autodesk.com/thread.jspa?threadID=415210&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here's the Registry file I'm currently using and it seems to be working just fine:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;REGEDIT4&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\CLSID\{57E6E593-2CAE-4016-AE01-74BB752C670E}]&lt;br /&gt;@="SolidCAD ToolBox"&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\CLSID\{57E6E593-2CAE-4016-AE01-74BB752C670E}\Description]&lt;br /&gt;@="A collection of useful routines supplied by SolidCAD Inc."&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\CLSID\{57E6E593-2CAE-4016-AE01-74BB752C670E}\Implemented Categories\{39AD2B5C-7A29-11D6-8E0A-0010B541CAA8}]&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\CLSID\{57E6E593-2CAE-4016-AE01-74BB752C670E}\Required Categories]&lt;br /&gt;[HKEY_CLASSES_ROOT\CLSID\{57E6E593-2CAE-4016-AE01-74BB752C670E}\Required Categories\{E357129B-DB40-11D2-B783-0060B0F159EF}]&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\CLSID\{57E6E593-2CAE-4016-AE01-74BB752C670E}\Settings]&lt;br /&gt;"LoadOnStartUp"="1"&lt;br /&gt;"Type"="Standard"&lt;br /&gt;"Version"="10"&lt;br /&gt;"SupportedSoftwareVersionEqualTo"="10.."&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You're really missing out on a great resource if you haven't checked out the Autodesk Discussion Groups.&lt;br /&gt;&lt;br /&gt;Thanks again Sanjay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-112128867523554184?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/112128867523554184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=112128867523554184&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/112128867523554184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/112128867523554184'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/07/add-in-versioning-in-autodesk-inventor.html' title='Add-In Versioning In Autodesk Inventor'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-111998132101620204</id><published>2005-06-28T10:44:00.000-05:00</published><updated>2005-07-01T15:58:43.513-05:00</updated><title type='text'>Extracting All Blocks In a Drawing</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004-2006&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.summerfabulous.com/area31/Extract All.zip"&gt;Extract All.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Well here I am after a VERY long break!  I promise to be adding a few new articles in the near future, including some for Inventor.&lt;br /&gt;&lt;br /&gt;A while ago I had the need to individually wblock out every block in a very large file, around 1500 blocks...The prospect of having to find and export every one by hand was not very appealing so I decided to whip up the bit of code below.  Be sure to add all of this into a new module:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Public Function ExtractBlocks(strDestDir As String, _&lt;br /&gt;                              Optional OverwriteExisting As Boolean = False) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim objSS As AcadSelectionSet&lt;br /&gt;  Dim objBlock As AcadBlockReference&lt;br /&gt;  Dim retVal As Variant&lt;br /&gt;  Dim i As Long&lt;br /&gt;&lt;br /&gt;  ' Append backslash if required&lt;br /&gt;  If Not Right(strDestDir, 1) = "\" Then strDestDir = strDestDir &amp; "\"&lt;br /&gt;&lt;br /&gt;  ' Create destination directory if it doesn't exist&lt;br /&gt;  MakeSureDirectoryPathExists strDestDir&lt;br /&gt;&lt;br /&gt;  ' Delete existing selection set&lt;br /&gt;  For Each objSS In ThisDrawing.SelectionSets&lt;br /&gt;    If StrComp(objSS.Name, "EXTRACT_BLOCKS", vbTextCompare) = 0 Then&lt;br /&gt;      objSS.Delete&lt;br /&gt;      Exit For&lt;br /&gt;    End If&lt;br /&gt;  Next&lt;br /&gt;&lt;br /&gt;  ' Create a new selection set&lt;br /&gt;  Set objSS = ThisDrawing.SelectionSets.Add("EXTRACT_BLOCKS")&lt;br /&gt;&lt;br /&gt;  For i = 0 To ThisDrawing.ModelSpace.Count - 1&lt;br /&gt;    ' Clear current selection set&lt;br /&gt;    objSS.Clear&lt;br /&gt;&lt;br /&gt;    If TypeOf ThisDrawing.ModelSpace.Item(i) Is AcadBlockReference Then&lt;br /&gt;      ' PLace blockreference in the selection array&lt;br /&gt;      Set objBlock = ThisDrawing.ModelSpace.Item(i)&lt;br /&gt;&lt;br /&gt;      ' Explode the block into a variant array of entities&lt;br /&gt;      retVal = objBlock.Explode&lt;br /&gt;&lt;br /&gt;      ' Add the object into the selection set&lt;br /&gt;      objSS.AddItems retVal&lt;br /&gt;&lt;br /&gt;      ' Check to see if the file exists&lt;br /&gt;      If Not Dir(strDestDir &amp; objBlock.Name &amp; ".dwg") = "" Then&lt;br /&gt;        ' Check if we can overwrite an existing file and write if allowed&lt;br /&gt;        If OverwriteExisting = True Then&lt;br /&gt;          ThisDrawing.Wblock strDestDir &amp; objBlock.Name &amp; ".dwg", objSS&lt;br /&gt;        End If&lt;br /&gt;      Else&lt;br /&gt;        ' Output the selection set to a new file&lt;br /&gt;        ThisDrawing.Wblock strDestDir &amp; objBlock.Name &amp; ".dwg", objSS&lt;br /&gt;      End If&lt;br /&gt;&lt;br /&gt;      DoEvents&lt;br /&gt;    End If&lt;br /&gt;  Next&lt;br /&gt;&lt;br /&gt;  ' Remove our selection set&lt;br /&gt;  objSS.Delete&lt;br /&gt;&lt;br /&gt;  Set objSS = Nothing&lt;br /&gt;  Set objBlock = Nothing&lt;br /&gt;  Erase retVal&lt;br /&gt;&lt;br /&gt;  ExtractBlocks = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set objSS = Nothing&lt;br /&gt;  Set objBlock = Nothing&lt;br /&gt;  Erase retVal&lt;br /&gt;End Function&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Add the following to the top of the module.  It is a really neat API call that will create entire directory structures if they don't exist.  For example: C:\Foo\Bar.  If the following path does not exist, it will create each subdirectory as required.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Public Declare Function MakeSureDirectoryPathExists Lib "IMAGEHLP.DLL" (ByVal DirPath As String) As Long&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Be sure to add in the IsDimArray function which checks to see if an array has been dimensioned before we try to clear it.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Public Function IsDimArray(arr As Variant) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim i As Long&lt;br /&gt;&lt;br /&gt;  i = UBound(arr)&lt;br /&gt;  If Not i = -1 Then IsDimArray = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  IsDimArray = False&lt;br /&gt;End Function&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Finally, add the following subroutine which calls the main routine.  Be sure you have a drawing open that has a few blocks in it before running the ExtractAllBlocks sub.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Public Sub ExtractAllBlocks()&lt;br /&gt;  If Not ExtractBlocks("C:\temp\allblocks") Then Stop&lt;br /&gt;End Sub&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The only real trick is exploding eahk block you find and exporting the entities in it.  If we did not explode the block before writing it ou, we end up with a DWG file that has a block inside of it with the same name as the file...and this can not be inserted into another file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-111998132101620204?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/111998132101620204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=111998132101620204&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/111998132101620204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/111998132101620204'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/06/extracting-all-blocks-in-drawing.html' title='Extracting All Blocks In a Drawing'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110988570559131008</id><published>2005-03-03T18:34:00.000-05:00</published><updated>2005-03-03T21:06:00.536-05:00</updated><title type='text'>Extracting a BOM from blocks</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.mymcad.com/area31/ExtractBOM.zip"&gt;ExtractBOM.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Creating and maintaining Bill of Material lists or BOMs have always been a tedious task in AutoCAD.  Many of the Autodesk vertical products (Mechanical, MDT, Inventor) have inherent tools to help but if you're stuck with vanilla AutoCAD like me, you know the pain and suffering involved in creating an accurate BOM list.&lt;br /&gt;&lt;br /&gt;The company I currently work for has instituted the standard of blocking every item in their assembly drawings with intelligent names; this really speeds up the detailer's jobs and allows for easy reuse in later projects.  Most of the drawings I work with are plan-view layouts, so I only have one view to worry about.  I've taken a bit of my own time and expanded on their idea, what if one could extract a first level BOM (no sub-assemblies or sub objects listed) and export it to a CSV file?  CSV files are great because they open natively in Microsoft Excel without all the hassle of programming a hook into Excel.  Before anyone asks, yes, I know using a collection would be quicker when searching for duplicate items but VBA has a few quirks with collections so I opted to use a for-next loop, just to be safe.&lt;br /&gt;&lt;br /&gt;There are a couple of neat tricks in this article, for one the 'GetAttrValue' function is a nicely encapsulated function to extract a single known attribute value.  Also, most people seem to miss the fact that you can search for multiple strings while creating a selection set.  Simply separate each string by a comma and end each term with an asterisk wild card.  For example, to search for all blocks that start with the words 'TEST' or 'HARDWARE', use the following:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;CreateSelectionSet(objSS, DXF_NAME, "TEST*,HARDWARE*")&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This article is far from a complete BOM solution; it simply asks you to select items on screen, extracts an item number from each block name and a description from an attribute named 'DESC'.  The code for this article is quite extensive (about 260 lines) so please download it from the link above.  The zip file also includes a sample drawing I whipped together to show you how it works.&lt;br /&gt;&lt;br /&gt;Once you have the DVB extracted and loaded, open the Macros window (press Alt+F8) and run the 'CreateBOM' macro to get things started.  If for some reason the macro is not showing up, go to the VBAIDE and run the CreateBOM subroutine.&lt;br /&gt;&lt;br /&gt;Here are some thoughts for future development:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt;Filter out alternate views (top, side, front) of the same object&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Create the BOM in the drawing instead of exporting to a CSV&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Sort the BOM before exporting it to screen or file&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Create the BOM as an AutoCAD table entity (AutoCAD 2005 or greater required)&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;If you enjoyed this article and would like to see an example of exporting the BOM to the screen, drop me a line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110988570559131008?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110988570559131008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110988570559131008&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110988570559131008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110988570559131008'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/03/extracting-bom-from-blocks.html' title='Extracting a BOM from blocks'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110803655266129408</id><published>2005-02-10T06:53:00.000-05:00</published><updated>2005-02-11T06:27:22.193-05:00</updated><title type='text'>Inserting Point Data into AutoCAD</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.mymcad.com/area31/InsertPointData.zip"&gt;InsertPointData.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Many times throughout my career I've been required to insert point data into AutoCAD.  I've dealt with raw DXF data; reverse engineered the extremely old DR2 file format from 2D Catia; teach point data from industrial robots and most recently 2D point data from an Excel chart.  All of these require the same thing, take 2D or 3D points consisting of X, Y and possibly Z coordinates and place them in a CAD file.  With vanilla AutoCAD, this is an extremely time consuming and error prone manual task; with a bit of programming it takes seconds.&lt;br /&gt;&lt;br /&gt;I'll show two methods of bringing in 2D data, as points and as a lightweight polyline.  The sample data I'll be using is tab separated, but you can easily change the code to work with any delimiter character.  With both routines, I have hard coded the path to "C:\", either place the "pointdata.txt" file here or modify the path as you require.&lt;br /&gt;&lt;br /&gt;Let's look at inserting the data as AutoCAD point objects.  First, we load the file into a string variable.  Using the Split command, the data is broken down into rows; then it's a matter of looping through the rows in the "ptArray" array and splitting each value into the "pt" array as Variant/Strings.  AutoCAD will only accept point data as Variant/Doubles so we have to type cast the string data into the "point" array and then add the point to model space.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Sub Insert2DPointDataAsPoints()&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim oPoint As AcadPoint&lt;br /&gt;  Dim pt As Variant&lt;br /&gt;  Dim point(0 To 2) As Double&lt;br /&gt;  Dim ptArray As Variant&lt;br /&gt;  Dim fileNumber As Long&lt;br /&gt;  Dim strFile As String&lt;br /&gt;  Dim i As Long&lt;br /&gt;  &lt;br /&gt;  ' Open the text file and store it in strFile&lt;br /&gt;  fileNumber = FreeFile&lt;br /&gt;  Open "C:\pointdata.txt" For Binary Access Read As #fileNumber&lt;br /&gt;    strFile = String(LOF(fileNumber), " ")&lt;br /&gt;    If Not Len(strFile) = 0 Then Get #fileNumber, , strFile&lt;br /&gt;  Close #fileNumber&lt;br /&gt;&lt;br /&gt;  ' Make sure we have some data to work with&lt;br /&gt;  ' Also checks to see if user cancelled the dialog&lt;br /&gt;  If Len(Trim(strFile)) = 0 Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;  ' Split the file into rows&lt;br /&gt;  ptArray = Split(strFile, vbCrLf)&lt;br /&gt;&lt;br /&gt;  For i = 0 To UBound(ptArray)&lt;br /&gt;    ' Set the point&lt;br /&gt;    pt = Split(ptArray(i), vbTab)&lt;br /&gt;&lt;br /&gt;    ' Convert the string data to doubles&lt;br /&gt;    point(0) = CDbl(pt(0))&lt;br /&gt;    point(1) = CDbl(pt(1))&lt;br /&gt;&lt;br /&gt;    ' Add the point to Modelspace&lt;br /&gt;    Set oPoint = ThisDrawing.ModelSpace.AddPoint(point)&lt;br /&gt;  Next i&lt;br /&gt;&lt;br /&gt;  ' Clean up&lt;br /&gt;  Set oPoint = Nothing&lt;br /&gt;&lt;br /&gt;  If IsDimArray(pt) Then Erase pt&lt;br /&gt;  If IsDimArray(point) Then Erase point&lt;br /&gt;  If IsDimArray(ptArray) Then Erase ptArray&lt;br /&gt;  &lt;br /&gt;  Exit Sub&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set oPoint = Nothing&lt;br /&gt;&lt;br /&gt;  If IsDimArray(pt) Then Erase pt&lt;br /&gt;  If IsDimArray(point) Then Erase point&lt;br /&gt;  If IsDimArray(ptArray) Then Erase ptArray&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Adding a lightweight polyline isn't that different.  Instead of breaking down the string data into doubles, we dimension one large array for all the 2D data "points" and use a counter "cnt" to fill in the values with our loop.  Once all the data is loaded into the point array, the lightweight polyline is added to Modelspace.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Sub Insert2DPointDataAsLWPolyline()&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim oLWPline As AcadLWPolyline&lt;br /&gt;  Dim pt As Variant&lt;br /&gt;  Dim points() As Double&lt;br /&gt;  Dim ptArray As Variant&lt;br /&gt;  Dim fileNumber As Long&lt;br /&gt;  Dim strFile As String&lt;br /&gt;  Dim i As Long&lt;br /&gt;  Dim cnt As Long&lt;br /&gt;  &lt;br /&gt;  ' Open the text file and store it in strFile&lt;br /&gt;  fileNumber = FreeFile&lt;br /&gt;  Open "C:\pointdata.txt" For Binary Access Read As #fileNumber&lt;br /&gt;    strFile = String(LOF(fileNumber), " ")&lt;br /&gt;    If Not Len(strFile) = 0 Then Get #fileNumber, , strFile&lt;br /&gt;  Close #fileNumber&lt;br /&gt;&lt;br /&gt;  ' Make sure we have some data to work with&lt;br /&gt;  ' Also checks to see if user cancelled the dialog&lt;br /&gt;  If Len(Trim(strFile)) = 0 Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;  ' Split the file into rows&lt;br /&gt;  ptArray = Split(strFile, vbCrLf)&lt;br /&gt;&lt;br /&gt;  ' Resize the points array for the lightweight polyline&lt;br /&gt;  ReDim points((UBound(ptArray) * 2) + 1)&lt;br /&gt;&lt;br /&gt;  ' Set the counter&lt;br /&gt;  cnt = 0&lt;br /&gt;&lt;br /&gt;  For i = 0 To UBound(ptArray)&lt;br /&gt;    ' Set the point&lt;br /&gt;    pt = Split(ptArray(i), vbTab)&lt;br /&gt;&lt;br /&gt;    ' Convert the string data to doubles&lt;br /&gt;    points(cnt) = CDbl(pt(0))&lt;br /&gt;    points(cnt + 1) = CDbl(pt(1))&lt;br /&gt;&lt;br /&gt;    cnt = cnt + 2&lt;br /&gt;  Next i&lt;br /&gt;&lt;br /&gt;  ' Add the Light Weight Polyline to Modelspace&lt;br /&gt;  Set oLWPline = ThisDrawing.ModelSpace.AddLightWeightPolyline(points)&lt;br /&gt;&lt;br /&gt;  ' Clean up&lt;br /&gt;  Set oLWPline = Nothing&lt;br /&gt;&lt;br /&gt;  If IsDimArray(pt) Then Erase pt&lt;br /&gt;  If IsDimArray(points) Then Erase points&lt;br /&gt;  If IsDimArray(ptArray) Then Erase ptArray&lt;br /&gt;  &lt;br /&gt;  Exit Sub&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set oLWPline = Nothing&lt;br /&gt;&lt;br /&gt;  If IsDimArray(pt) Then Erase pt&lt;br /&gt;  If IsDimArray(points) Then Erase points&lt;br /&gt;  If IsDimArray(ptArray) Then Erase ptArray&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Before I forget again, add the helper routine "IsDimArray" used to clean up the arrays that were used.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function IsDimArray(arr As Variant) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim i As Long&lt;br /&gt;&lt;br /&gt;  i = UBound(arr)&lt;br /&gt;  If Not i = -1 Then IsDimArray = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  IsDimArray = False&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Changing these routines to insert 3D data is as simple as splitting the point data into 3 doubles (for the Z coordinate) or using a polyline instead of a lightweight polyline.  If you have any trouble with your own data, &lt;a href="mailto:jim.dowthwaite@gmail.com"&gt;let me know&lt;/a&gt;; I'd be happy to lend a hand.  A few other things that should be included for a fully useful routine:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Watch for blank lines in the point data&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Check all the data to be sure it is numeric before adding the point&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Add code to make sure the point data file exists before trying to open it&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110803655266129408?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110803655266129408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110803655266129408&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110803655266129408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110803655266129408'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/02/inserting-point-data-into-autocad.html' title='Inserting Point Data into AutoCAD'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110770915376580431</id><published>2005-02-06T11:58:00.000-05:00</published><updated>2005-02-11T06:39:38.413-05:00</updated><title type='text'>Drawing the Golden Ratio</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.mymcad.com/area31/GoldenRatio.zip"&gt;GoldenRatio.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://www.freespaces.com/area31/images/goldenratio.png" align="right" border="0" /&gt;The Golden Ratio has always fascinated me.  I'm no math wizard but the Golden Ration (also known as Phi) has a tendency to turn up in a great number of places: the spiral of a sea shell, the swirl of milk in coffee, clouds, crop circles, and the list goes on.  I highly recommend a movie directed by Darren Aronofsky, a very odd but interesting movie from 1998 entitled Pi (&lt;a target="_blank" href="http://imdb.com/title/tt0138704/"&gt;IMDB link&lt;/a&gt;) that touches on Phi and Fibonacci sequences.&lt;br /&gt;&lt;br /&gt;Fibonacci sequences occur when any term after the first two can be found by summing the two previous terms.  Here's an example: 1, 1, 2, 3, 5, 8, 13, ... &lt;br /&gt;&lt;br /&gt;I'll point you to the two links below for full details on Phi and Fibonacci sequences:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;a target="_blank" href="http://jwilson.coe.uga.edu/emt669/Student.Folders/Frietag.Mark/Homepage/Goldenratio/goldenratio.html"&gt;http://jwilson.coe.uga.edu/.../goldenratio.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" href="http://mathworld.wolfram.com/GoldenRatio.html"&gt;http://mathworld.wolfram.com/GoldenRatio.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We can calculate a Fibonacci sequence with this function:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function Fibonacci(ByVal lngNumber As Long) As Long&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  If lngNumber &lt;= 1 Then ' ignore negatives&lt;br /&gt;    Fibonacci = 0&lt;br /&gt;  ElseIf lngNumber = 2 Then&lt;br /&gt;    Fibonacci = 1&lt;br /&gt;  Else ' return the fibonacci number&lt;br /&gt;    Fibonacci = Fibonacci(lngNumber - 1) + Fibonacci(lngNumber - 2)&lt;br /&gt;  End If&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The trickiest part of the routine was resetting the start point for the arc as it moves every iteration of the loop.  First, Add a constant for PI, then add the routine below.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Const PI = 3.14159265358979          ' 3.1415926535897932384626433832795 or atn(1.0)*4&lt;br /&gt;&lt;br /&gt;Public Sub AddGoldenRatio(lngQuads As Long)&lt;br /&gt;' Draw the golden ratio (PHI) starting at 0,0 and spiral out&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim objArc As AcadArc&lt;br /&gt;  Dim pt1(0 To 2) As Double&lt;br /&gt;  Dim lngCorner As Long       ' Start corner: 0=SW, 1=SE, 2=NE, 3=NW&lt;br /&gt;  Dim dblLength As Double     ' Length of a side.&lt;br /&gt;  Dim dblLast As Double       ' Last Length&lt;br /&gt;  Dim dblAngleStart As Double ' Start angle of arc&lt;br /&gt;  Dim dblAngleEnd As Double   ' End angle of arc&lt;br /&gt;  Dim i As Long&lt;br /&gt;&lt;br /&gt;  lngCorner = 0                   ' Draw first square from 0,0&lt;br /&gt;  dblLength = 1                   ' Start with a 1x1 square&lt;br /&gt;  pt1(0) = 0#: pt1(1) = 0#        ' Center point of arc&lt;br /&gt;  dblAngleStart = 0#              ' Start at 0 deg&lt;br /&gt;  dblAngleEnd = 90# * (PI / 180#) ' Start at 90 deg (converted to radians)&lt;br /&gt;&lt;br /&gt;  ' Start at 4 to skip duplicates in Fibonacci sequence&lt;br /&gt;  ' Add 3 to compensate&lt;br /&gt;  For i = 4 To lngQuads + 3&lt;br /&gt;    ' Add arc to modelspace&lt;br /&gt;&lt;br /&gt;    Set objArc = ThisDrawing.ModelSpace.AddArc(pt1, dblLength, dblAngleStart, dblAngleEnd)&lt;br /&gt;&lt;br /&gt;    ' Update angles&lt;br /&gt;    dblAngleStart = dblAngleEnd&lt;br /&gt;    dblAngleEnd = dblAngleEnd + 90# * (PI / 180#)&lt;br /&gt;&lt;br /&gt;    ' Set lengths&lt;br /&gt;    dblLast = dblLength&lt;br /&gt;    dblLength = Fibonacci(i)&lt;br /&gt;&lt;br /&gt;    ' Move our startpoint&lt;br /&gt;    Select Case lngCorner&lt;br /&gt;      Case 0&lt;br /&gt;        pt1(0) = pt1(0)&lt;br /&gt;        pt1(1) = pt1(1) - (dblLength - dblLast)&lt;br /&gt;      Case 1&lt;br /&gt;        pt1(0) = pt1(0) + (dblLength - dblLast)&lt;br /&gt;        pt1(1) = pt1(1)&lt;br /&gt;      Case 2&lt;br /&gt;        pt1(0) = pt1(0)&lt;br /&gt;        pt1(1) = pt1(1) + (dblLength - dblLast)&lt;br /&gt;      Case 3&lt;br /&gt;        pt1(0) = pt1(0) - (dblLength - dblLast)&lt;br /&gt;        pt1(1) = pt1(1)&lt;br /&gt;    End Select&lt;br /&gt;&lt;br /&gt;    ' Incerement our corner&lt;br /&gt;    lngCorner = lngCorner + 1&lt;br /&gt;    If lngCorner = 4 Then lngCorner = 0&lt;br /&gt;  Next i&lt;br /&gt;&lt;br /&gt;  ' Clean up&lt;br /&gt;  Set objArc = Nothing&lt;br /&gt;  If IsDimArray(pt1) Then Erase pt1&lt;br /&gt;&lt;br /&gt;  Exit Sub&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set objArc = Nothing&lt;br /&gt;  If IsDimArray(pt1) Then Erase pt1&lt;br /&gt;End Sub&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; I forgot to add the IsDimArray function.  You can thank &lt;a target="_blank" href="http://jtbworld.blogspot.com/"&gt; Jimmy Bergmark&lt;/a&gt; for catching my mistake.  The IsDimArray function checks to see if an array has been dimensioned yet and reurns a boolean.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function IsDimArray(arr As Variant) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim i As Long&lt;br /&gt;&lt;br /&gt;  i = UBound(arr)&lt;br /&gt;  If Not i = -1 Then IsDimArray = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  IsDimArray = False&lt;br /&gt;&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Not sure if you can find any technical use for this, but I hope I have peaked you interest into this interesting corner of mathematics.  To call the routine add a sub like below:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Private Sub DrawGoldenRatio()&lt;br /&gt;  Call AddGoldenRatio(8)&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110770915376580431?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110770915376580431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110770915376580431&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110770915376580431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110770915376580431'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/02/drawing-golden-ratio.html' title='Drawing the Golden Ratio'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110752822316056029</id><published>2005-02-03T21:40:00.000-05:00</published><updated>2005-02-04T09:46:52.836-05:00</updated><title type='text'>The six laws of new software</title><content type='html'>This is an article &lt;span style="font-weight:bold;"&gt;every&lt;/span&gt; programmer should read, especially those just starting to enter the world of software development:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;&lt;a target="_blank" href="http://www.changethis.com/12.SixLawsSoftware/"&gt;http://www.changethis.com/12.SixLawsSoftware&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It's common sense for those of us who have been around long enough to learn the hard way; hindsight is 20/20.  Always a good idea to remember the real reason we're writing code, to help the end users.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110752822316056029?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110752822316056029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110752822316056029&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110752822316056029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110752822316056029'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/02/six-laws-of-new-software.html' title='The six laws of new software'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110745217008250719</id><published>2005-02-03T18:07:00.000-05:00</published><updated>2005-02-11T06:49:54.450-05:00</updated><title type='text'>I hate CAD standards. Part 2</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.mymcad.com/area31/IHateCADStandards.zip"&gt;IHateCADStandards.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Continuing from Part 1, we'll start by setting our units.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function setUnits() As Boolean&lt;br /&gt;' Set base drawing units&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  ' Set system variables&lt;br /&gt;  With ThisDrawing&lt;br /&gt;    .SetVariable "LUNITS", 2 ' Sets linear units to Decimal&lt;br /&gt;    .SetVariable "LUPREC", 3 ' Sets the # of decimal places displayed for all read-only linear units&lt;br /&gt;&lt;br /&gt;    .SetVariable "AUNITS", 0 ' Sets units for angles to Decimal degrees&lt;br /&gt;    .SetVariable "AUPREC", 3 ' Sets the number of decimal places for all read-only angular units&lt;br /&gt;&lt;br /&gt;    .SetVariable "MEASUREMENT", 0 'Sets units as imperial or metric for the current drawing only&lt;br /&gt;&lt;br /&gt;    .SetVariable "ANGDIR", 0 'Sets the direction of positive angles. Set to Counterclockwise&lt;br /&gt; &lt;br /&gt;    .SetVariable "ANGBASE", 0# ' Sets the base angle to 0 with respect to the current UCS.&lt;br /&gt; &lt;br /&gt;    .SetVariable "INSUNITS", 1 ' Specifies units for drag &amp; dropped blocks or images. Set to Inches&lt;br /&gt;  End With&lt;br /&gt;&lt;br /&gt;  setUnits = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  ' Insert error handler here&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;No real magic here, we're just setting a few system variables.  Call the above routine with the following line:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;If Not setUnits Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now we can focus on layer modification.  Layers can get a bit tricky so we have to be careful what we do.  I found out the hard way that you can set a layer's colour to black and it will be invisible if your workspace background is black.  Note to self: make a routine that loops through all layers and sets their colours to black to annoy coworkers.  We'll also create a few helper routines to set a layer current, check if a layer already exists and if it is locked.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function CreateLayer(strLay As String, _&lt;br /&gt;                       strLineType As String, _&lt;br /&gt;                       Optional setColor As Boolean = False, _&lt;br /&gt;                       Optional lngRed As Long, _&lt;br /&gt;                       Optional lngGreen As Long, _&lt;br /&gt;                       Optional lngBlue As Long, _&lt;br /&gt;                       Optional lyrLineWeight As ACAD_LWEIGHT = acLnWtByLayer, _&lt;br /&gt;                       Optional booPlottable As Boolean = True, _&lt;br /&gt;                       Optional booLock As Boolean = False, _&lt;br /&gt;                       Optional booFreeze As Boolean = False, _&lt;br /&gt;                       Optional booLayerOn As Boolean = True) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim newLayer As AcadLayer&lt;br /&gt;  Dim objLineType As AcadLineType&lt;br /&gt;  Dim objColor As AcadAcCmColor&lt;br /&gt;  Dim booFound As Boolean&lt;br /&gt;&lt;br /&gt;  Set newLayer = ThisDrawing.Layers.Add(strLay)&lt;br /&gt;&lt;br /&gt;  With newLayer&lt;br /&gt;    If setColor Then&lt;br /&gt;      Set objColor = AcadApplication.GetInterfaceObject("AutoCAD.AcCmColor.16")&lt;br /&gt;&lt;br /&gt;      If (lngRed = 0 And lngGreen = 0 And lngBlue = 0) Or _&lt;br /&gt;         (lngRed = 255 And lngGreen = 255 And lngBlue = 255) Then&lt;br /&gt;        objColor.ColorIndex = acWhite&lt;br /&gt;      Else&lt;br /&gt;        Call objColor.SetRGB(lngRed, lngGreen, lngBlue)&lt;br /&gt;      End If&lt;br /&gt;&lt;br /&gt;      .TrueColor = objColor&lt;br /&gt;    End If&lt;br /&gt;&lt;br /&gt;    .Lineweight = lyrLineWeight&lt;br /&gt;    .Plottable = booPlottable&lt;br /&gt;    .Lock = booLock&lt;br /&gt;    If Not StrComp(ThisDrawing.ActiveLayer.Name, strLay, vbTextCompare) = 0 Then .Freeze = booFreeze&lt;br /&gt;    .LayerOn = booLayerOn&lt;br /&gt;&lt;br /&gt;    For Each objLineType In ThisDrawing.Linetypes&lt;br /&gt;      If StrComp(objLineType.Name, strLineType, vbTextCompare) = 0 Then&lt;br /&gt;        booFound = True&lt;br /&gt;        Exit For&lt;br /&gt;      End If&lt;br /&gt;    Next&lt;br /&gt;&lt;br /&gt;    If Not booFound Then ThisDrawing.Linetypes.Load strLineType, "acadiso.lin"&lt;br /&gt;&lt;br /&gt;    .Linetype = strLineType&lt;br /&gt;  End With&lt;br /&gt;&lt;br /&gt;  Set newLayer = Nothing&lt;br /&gt;  Set objLineType = Nothing&lt;br /&gt;  If setColor Then Set objColor = Nothing&lt;br /&gt;&lt;br /&gt;  CreateLayer = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set newLayer = Nothing&lt;br /&gt;  Set objLineType = Nothing&lt;br /&gt;  If setColor Then Set objColor = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It seems more complicated than it should be (and it might be) but it works well.  If you only use the base 16 or 255 colours, you can rip out the entire "setColor" section and just pass the routine a colour code. Call the above routine with the following line:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;  If Not CreateLayer("Building-Columns", _&lt;br /&gt;                     "Continuous", _&lt;br /&gt;                     True, _&lt;br /&gt;                     255, 191, 0, _&lt;br /&gt;                     acLnWtByLwDefault, _&lt;br /&gt;                     True, False, False, True) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;  If Not CreateLayer("Building", _&lt;br /&gt;                     "Continuous", _&lt;br /&gt;                     True, _&lt;br /&gt;                     204, 51, 0, _&lt;br /&gt;                     acLnWtByLwDefault, _&lt;br /&gt;                     True, False, False, True) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;  If Not CreateLayer("Building-Columns", _&lt;br /&gt;                     "Continuous", _&lt;br /&gt;                     True, _&lt;br /&gt;                     255, 191, 0, _&lt;br /&gt;                     acLnWtByLwDefault, _&lt;br /&gt;                     True, False, False, True) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;  If Not CreateLayer("Building-Column-Lines", _&lt;br /&gt;                     "Continuous", _&lt;br /&gt;                     True, _&lt;br /&gt;                     102, 204, 0, _&lt;br /&gt;                     acLnWtByLwDefault, _&lt;br /&gt;                     True, False, False, True) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;  If Not CreateLayer("Building-Drains", _&lt;br /&gt;                     "Continuous", _&lt;br /&gt;                     True, _&lt;br /&gt;                     132, 132, 132, _&lt;br /&gt;                     acLnWtByLwDefault, _&lt;br /&gt;                     True, False, False, True) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Be sure to use the helper routines I mentioned earlier whenever you need to create or modify a layer.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function LayerExists(strLay As String) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim oLayers As AcadLayers&lt;br /&gt;  Dim oLayer As AcadLayer&lt;br /&gt;&lt;br /&gt;  Set oLayers = ThisDrawing.Layers&lt;br /&gt;&lt;br /&gt;  For Each oLayer In oLayers&lt;br /&gt;    If StrComp(oLayer.Name, strLay, vbTextCompare) = 0 Then&lt;br /&gt;      LayerExists = True&lt;br /&gt;      Exit For&lt;br /&gt;    End If&lt;br /&gt;  Next&lt;br /&gt;&lt;br /&gt;  Set oLayers = Nothing&lt;br /&gt;  Set oLayer = Nothing&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set oLayers = Nothing&lt;br /&gt;  Set oLayer = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;Public Function LayerLocked(strLay As String) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim oLayers As AcadLayers&lt;br /&gt;  Dim oLayer As AcadLayer&lt;br /&gt;&lt;br /&gt;  Set oLayers = ThisDrawing.Layers&lt;br /&gt;&lt;br /&gt;  For Each oLayer In oLayers&lt;br /&gt;    If StrComp(oLayer.Name, strLay, vbTextCompare) = 0 Then&lt;br /&gt;      If oLayer.Lock = True Then LayerLocked = True&lt;br /&gt;      Exit For&lt;br /&gt;    End If&lt;br /&gt;  Next&lt;br /&gt;&lt;br /&gt;  Set oLayers = Nothing&lt;br /&gt;  Set oLayer = Nothing&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set oLayers = Nothing&lt;br /&gt;  Set oLayer = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;One final pitfall to watch out for, don't try to lock or delete the current layer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110745217008250719?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110745217008250719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110745217008250719&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110745217008250719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110745217008250719'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/02/i-hate-cad-standards-part-2.html' title='I hate CAD standards. Part 2'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110736166117078420</id><published>2005-02-01T20:26:00.000-05:00</published><updated>2005-02-11T06:48:36.956-05:00</updated><title type='text'>I hate CAD standards.  Part 1</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.mymcad.com/area31/IHateCADStandards.zip"&gt;IHateCADStandards.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have a confession; I hate CAD standards.  It's not that I don't like following rules, I hate all the steps involved in having to add the standards.&lt;br /&gt;&lt;br /&gt;I deal with a lot of third party drawings, about 95% or more of the drawings I work in come from a customer or consultant so having a perfect template to start from isn't a luxury I can work with.  Now before anyone says “but Autodesk has given us many tools to enforce standards”, I know…but I'm very lazy when it comes to adding standards, like I mentioned, I hate them.&lt;br /&gt;&lt;br /&gt;So, instead of complaining, I've made a single-click solution.  I can now add all of my text styles, dimension styles, layers and units with a single click of a button.  If you find yourself in the same situation, read on for some invaluable routines.&lt;br /&gt;&lt;br /&gt;The first routine will add a new text style with RomanS as the font and the width specified in dblWidth:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function AddTextStyle(dblWidth As Double) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  Dim oTextStyle As AcadTextStyle&lt;br /&gt;&lt;br /&gt;  Set oTextStyle = ThisDrawing.TextStyles.Add("MY_ROMANS")&lt;br /&gt;&lt;br /&gt;  With oTextStyle&lt;br /&gt;    .fontFile = "C:/Program Files/AutoCAD 2004/Fonts/romans.shx"&lt;br /&gt;    .Width = dblWidth&lt;br /&gt;  End With&lt;br /&gt;&lt;br /&gt;  ThisDrawing.ActiveTextStyle = oTextStyle&lt;br /&gt;&lt;br /&gt;  Set oTextStyle = Nothing&lt;br /&gt;&lt;br /&gt;  AddTextStyle = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set oTextStyle = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Be sure to add in some code to confirm that "romans.shx" exists.  Call the above routine with the following line:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;  If Not AddTextStyle(1#) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now that we have our required text styles added into the drawing, we can add our dimension styles.  The problem with creating a dimension style is that we don't know the status of any of the variables, so we have to set EVERY variable.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Private Function createDimStyle(dblScale As Double) As Boolean&lt;br /&gt;On Error GoTo ErrorHandler&lt;br /&gt;  ' Create dimension style&lt;br /&gt;  Dim oDimStyle As AcadDimStyle&lt;br /&gt;  Dim oTextStyle As AcadTextStyle&lt;br /&gt;&lt;br /&gt;  ' Set system variables&lt;br /&gt;  With ThisDrawing&lt;br /&gt;    .SetVariable "DIMCLRD", 140&lt;br /&gt;    .SetVariable "DIMLWD", -2&lt;br /&gt;    .SetVariable "DIMDLI", 0.08&lt;br /&gt;    .SetVariable "DIMCLRE", 140&lt;br /&gt;    .SetVariable "DIMLWE", -2&lt;br /&gt;    .SetVariable "DIMEXE", 0.08&lt;br /&gt;    .SetVariable "DIMEXO", 0.08&lt;br /&gt;    .SetVariable "DIMASZ", 0.08&lt;br /&gt;    .SetVariable "DIMSD1", 0&lt;br /&gt;    .SetVariable "DIMSD2", 0&lt;br /&gt;    .SetVariable "DIMSE1", 0&lt;br /&gt;    .SetVariable "DIMSE2", 0&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMBLK1", "."&lt;br /&gt;    .SetVariable "DIMBLK2", "."&lt;br /&gt;    .SetVariable "DIMLDRBLK", "."&lt;br /&gt;    .SetVariable "DIMCEN", 0&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMTIH", 1&lt;br /&gt;    .SetVariable "DIMTOH", 1&lt;br /&gt;    .SetVariable "DIMTMOVE", 0&lt;br /&gt;&lt;br /&gt;    ' Confirm that my TestStyle is there before setting&lt;br /&gt;    For Each oTextStyle In .TextStyles&lt;br /&gt;      If StrComp(oTextStyle.Name, "MY_ROMANS", vbTextCompare) = 0 Then&lt;br /&gt;        .SetVariable "DIMTXSTY", "MY_ROMANS"&lt;br /&gt;        Exit For&lt;br /&gt;      End If&lt;br /&gt;    Next&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMCLRT", 120&lt;br /&gt;    .SetVariable "DIMTXT", 0.08&lt;br /&gt;    &lt;br /&gt;    .SetVariable "DIMATFIT", 3&lt;br /&gt;    .SetVariable "DIMTIX", 0&lt;br /&gt;    .SetVariable "DIMSOXD", 0&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMUPT", 0&lt;br /&gt;    .SetVariable "DIMTOFL", 0&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMTAD", 0&lt;br /&gt;    .SetVariable "DIMJUST", 0&lt;br /&gt;    .SetVariable "DIMGAP", 0.08&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMLUNIT", 2&lt;br /&gt;    .SetVariable "DIMTFAC", 1&lt;br /&gt;    .SetVariable "DIMDEC", 3&lt;br /&gt;    .SetVariable "DIMFRAC", 0&lt;br /&gt;    .SetVariable "DIMDSEP", "."&lt;br /&gt;    .SetVariable "DIMRND", 0&lt;br /&gt;    .SetVariable "DIMPOST", ""&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMLFAC", 1&lt;br /&gt;    .SetVariable "DIMZIN", 0&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMAUNIT", 0&lt;br /&gt;    .SetVariable "DIMADEC", 3&lt;br /&gt;    .SetVariable "DIMAZIN", 0&lt;br /&gt;    &lt;br /&gt;    .SetVariable "DIMALT", 0&lt;br /&gt;    &lt;br /&gt;    .SetVariable "DIMTOL", 0&lt;br /&gt;    .SetVariable "DIMLIM", 0&lt;br /&gt;    .SetVariable "DIMTDEC", 3&lt;br /&gt;    .SetVariable "DIMTP", 0&lt;br /&gt;    .SetVariable "DIMTM", 0&lt;br /&gt;    .SetVariable "DIMTFAC", 1&lt;br /&gt;    .SetVariable "DIMTOLJ", 1&lt;br /&gt;&lt;br /&gt;    .SetVariable "DIMALTTD", 2&lt;br /&gt;    .SetVariable "DIMALTTZ", 0&lt;br /&gt;  &lt;br /&gt;    ' Set scale to dblScale&lt;br /&gt;    .SetVariable "DIMSCALE", dblScale&lt;br /&gt;&lt;br /&gt;    ' Create Descon dimstyle&lt;br /&gt;    Set oDimStyle = .DimStyles.Add("MyDimStyle" &amp; CStr(CLng(dblScale)))&lt;br /&gt;    oDimStyle.CopyFrom ThisDrawing&lt;br /&gt;    .ActiveDimStyle = oDimStyle&lt;br /&gt;  End With&lt;br /&gt;&lt;br /&gt;  Set oDimStyle = Nothing&lt;br /&gt;  Set oTextStyle = Nothing&lt;br /&gt;&lt;br /&gt;  createDimStyle = True&lt;br /&gt;&lt;br /&gt;  Exit Function&lt;br /&gt;ErrorHandler:&lt;br /&gt;  Set oDimStyle = Nothing&lt;br /&gt;  Set oTextStyle = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Just to clarify, all we've done with the routine above is set a whole bunch of style overrides on the current dimension style and then copied our modified style into a new dimension style.  Odd way of doing it, but we work with the tools we have.  Call the above routine with the following line:&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;  If Not createDimStyle(48#) Then GoTo ErrorHandler&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This will create a dimension style, the way we like with a scale appropriate for a 1/4"=1'-0" PaperSpace viewport.&lt;br /&gt;&lt;br /&gt;Check out Part 2 of this article to find out how to create layers and set the default units in your drawing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110736166117078420?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110736166117078420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110736166117078420&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110736166117078420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110736166117078420'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/02/i-hate-cad-standards-part-1.html' title='I hate CAD standards.  Part 1'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110684148310559230</id><published>2005-01-27T10:58:00.000-05:00</published><updated>2005-02-11T16:48:36.150-05:00</updated><title type='text'>Going Off on a Tangent</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Platform:&lt;/span&gt; AutoCAD 2004&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Download:&lt;/span&gt; &lt;a target="_blank" href="http://www.mymcad.com/area31/DrawInsideTangent.zip"&gt;DrawInsideTangent.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://photos1.blogger.com/img/296/3223/200/Tangent%20Problem.jpg" align="right" border="0" /&gt;I recently had a problem where I needed to find the inside tangent points between two circles. See the image to the right for clarity. I knew where the two centers were (X and Y) and I knew the radius of both circles...but how to find the tangents. The other problem I had was that I needed a routine that was flexible enough to handle a wide range of values, point X and point Y can vary in position and the two radii can vary. The only thing I knew for sure was that point Y was below point X.&lt;br /&gt;&lt;br /&gt;The AutoCAD API didn't have much to help me out so I headed to the web in search of an answer. There was one very descriptive article on how to solve this problem but the solution was written in C++ and was simply too complex to be ported to VB.&lt;br /&gt;&lt;br /&gt;In the end a co-worker pointed me down the right path (thanks Mike!).  Take a look at the code below; if you have any questions after trying it out, let me know.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Const PI = 3.14159265358979 ' 3.1415926535897932384626433832795 or atn(1.0)*4&lt;br /&gt;&lt;br /&gt;Public Sub DrawTangent()&lt;br /&gt;  Dim objLine As AcadLine&lt;br /&gt;  Dim objArc As AcadArc&lt;br /&gt;&lt;br /&gt;  Dim pt1(0 To 2) As Double&lt;br /&gt;  Dim pt2(0 To 2) As Double&lt;br /&gt;  Dim pt3 As Variant&lt;br /&gt;  Dim pt4 As Variant&lt;br /&gt;&lt;br /&gt;  Dim rad1 As Double&lt;br /&gt;  Dim rad2 As Double&lt;br /&gt;&lt;br /&gt;  Dim dblLength As Double&lt;br /&gt;  Dim dblOffset As Double&lt;br /&gt;  Dim dblValue As Double&lt;br /&gt;  Dim dblAngle As Double&lt;br /&gt;  Dim dblTanAngle As Double&lt;br /&gt;  Dim dblStartAngle As Double&lt;br /&gt;&lt;br /&gt;  ' Center of first circle&lt;br /&gt;  pt1(0) = 0#&lt;br /&gt;  pt1(1) = 0#&lt;br /&gt;&lt;br /&gt;  ' Center of second circle&lt;br /&gt;  pt2(0) = 30#&lt;br /&gt;  pt2(1) = -3#&lt;br /&gt;&lt;br /&gt;  ' Radius of first circle&lt;br /&gt;  rad1 = 10#&lt;br /&gt;&lt;br /&gt;  ' Radius of second circle&lt;br /&gt;  rad2 = 1.5&lt;br /&gt;&lt;br /&gt;  ' Distance between two centers (hypotenuse of triangle)&lt;br /&gt;  dblLength = GetDistance(pt1, pt2)&lt;br /&gt;&lt;br /&gt;  ' Add both radii (opposite length of triangle)&lt;br /&gt;  dblOffset = rad1 + rad2&lt;br /&gt;&lt;br /&gt;  ' Length of the adjacent side of the triangle between centers&lt;br /&gt;  dblValue = Sqr((dblLength ^ 2) - (dblOffset ^ 2))&lt;br /&gt;&lt;br /&gt;  ' Angle between hypotenuse and adjacent side&lt;br /&gt;  dblTanAngle = Atn(dblOffset / dblValue)&lt;br /&gt;&lt;br /&gt;  ' Add hypotenuse side of triangle&lt;br /&gt;  Set objLine = ThisDrawing.ModelSpace.AddLine(pt1, pt2)&lt;br /&gt;&lt;br /&gt;  ' Angle of hypotenuse from zero&lt;br /&gt;  dblStartAngle = ThisDrawing.Utility.AngleFromXAxis(pt1, pt2)&lt;br /&gt;&lt;br /&gt;  ' Angle of adjacent from zero&lt;br /&gt;  If pt2(1) &gt;= pt1(0) Then&lt;br /&gt;    dblAngle = (360# * (PI / 180#)) - Abs(dblStartAngle - dblTanAngle)&lt;br /&gt;  Else&lt;br /&gt;    dblAngle = dblStartAngle - dblTanAngle&lt;br /&gt;  End If&lt;br /&gt;&lt;br /&gt;  ' Find end point of adjacent side&lt;br /&gt;  pt3 = ThisDrawing.Utility.PolarPoint(pt1, dblAngle, dblValue)&lt;br /&gt;&lt;br /&gt;  ' Add adjacent side of triangle&lt;br /&gt;  Set objLine = ThisDrawing.ModelSpace.AddLine(pt1, pt3)&lt;br /&gt;&lt;br /&gt;  ' Add opposite side of triangle&lt;br /&gt;  Set objLine = ThisDrawing.ModelSpace.AddLine(pt3, pt2)&lt;br /&gt;&lt;br /&gt;  ' Angle from zero to first tangent&lt;br /&gt;  dblAngle = dblAngle + (90# * (PI / 180#))&lt;br /&gt;&lt;br /&gt;  ' Start of infeed angle&lt;br /&gt;  pt3 = ThisDrawing.Utility.PolarPoint(pt1, dblAngle, rad1 + rad2)&lt;br /&gt;&lt;br /&gt;  ' Add start arc&lt;br /&gt;  Set objArc = ThisDrawing.ModelSpace.AddArc(pt1, rad1 + rad2, dblAngle, 90# * (PI / 180#))&lt;br /&gt;&lt;br /&gt;  ' Start of end angle&lt;br /&gt;  pt4 = ThisDrawing.Utility.PolarPoint(pt2, dblAngle + (180# * (PI / 180#)), rad2)&lt;br /&gt;&lt;br /&gt;  ' Add end arc&lt;br /&gt;  Set objArc = ThisDrawing.ModelSpace.AddArc(pt2, rad2, dblAngle + (180# * (PI / 180#)), 270# * (PI / 180#))&lt;br /&gt;&lt;br /&gt;  ' Add line between arcs&lt;br /&gt;  Set objLine = ThisDrawing.ModelSpace.AddLine(pt3, pt4)&lt;br /&gt;End Sub&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You'll also need the "GetDistance" function.  It calculates the distance between two points in all three axis of AutoCAD space.&lt;br /&gt;&lt;br /&gt;&lt;div class='codeblock'&gt;&lt;br /&gt;Public Function GetDistance(distPnt1 As Variant, distPnt2 As Variant) As Double&lt;br /&gt;  Dim Xval  As Double&lt;br /&gt;  Dim Yval  As Double&lt;br /&gt;  Dim Zval  As Double&lt;br /&gt;&lt;br /&gt;  Xval = distPnt1(0) - distPnt2(0) 'Difference between x values&lt;br /&gt;  Yval = distPnt1(1) - distPnt2(1) 'Difference between y values&lt;br /&gt;  Zval = distPnt1(2) - distPnt2(2) 'Difference between z values&lt;br /&gt;&lt;br /&gt;  ' Calc distance using Pythagorean Theorum&lt;br /&gt;  GetDistance = Sqr((Sqr((Xval ^ 2) + (Yval ^ 2)) ^ 2) + (Zval ^ 2))&lt;br /&gt;End Function&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Try copying both functions into VBA and run the "DrawTangent" routine you should see two arcs with a perfect tangent between them.  It also draws the triangle we needed to calculate the tangent points.  If you need to draw tangents in other directions, the angles will have to be modified to suit but the theory above will work for any two circles as long as they don't overlap.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110684148310559230?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110684148310559230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110684148310559230&amp;isPopup=true' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110684148310559230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110684148310559230'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/01/going-off-on-tangent.html' title='Going Off on a Tangent'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10436678.post-110696074014277896</id><published>2005-01-26T20:01:00.000-05:00</published><updated>2005-02-03T08:51:45.766-05:00</updated><title type='text'>Welcome</title><content type='html'>Hello to new friends and old. This is my second attempt at a blog focusing on creating custom code for AutoCAD and Inventor by Autodesk. For the next little while, most articles will focus on AutoCAD, as that is what I'm currently working in. If things go well, I'll be joining the ADN later this year and then the real fun will begin. (insert evil laughter here). If you have any bits of code you're having trouble with or ideas for posts, let me know. I'll try to post something every couple of days (or more) but no guarantees.&lt;br /&gt;&lt;br /&gt;And now a bit about me: I've been working in drafting/CAD since 1998. Like a few others here, I started out on paper and moved to CAD as quickly as possible. A few systems I've worked with over the years are AutoCAD (r9 to current), SolidWorks, Inventor, ACAD MDT, ACAD Mechanical, ACAD Electrical, ADH800 (no mouse required, don't even ask!), VisionAEL, ME10 and One Space Designer.&lt;br /&gt;&lt;br /&gt;Despite the list above, my true love is programming... still not sure why I went for Mech. Eng. in college. I program in numerous languages (16 last time I counted) and have been customizing and extending various CAD systems for more than a decade.&lt;br /&gt;&lt;br /&gt;I've worked in a wide range of industries including (but not limited to) automotive, beef processing, telecommunications, safe/vault manufacturing and was even an AE for an Autodesk VAR for a stint before I was enticed back into the real world to automate conveyor systems.&lt;br /&gt;&lt;br /&gt;If anyone is interested, I am available for after-hours freelance work/training/etc.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10436678-110696074014277896?l=area31.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://area31.blogspot.com/feeds/110696074014277896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10436678&amp;postID=110696074014277896&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110696074014277896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10436678/posts/default/110696074014277896'/><link rel='alternate' type='text/html' href='http://area31.blogspot.com/2005/01/welcome.html' title='Welcome'/><author><name>Jim Dowthwaite</name><uri>http://www.blogger.com/profile/01086449508529412807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/img/296/3223/200/me.jpg'/></author><thr:total>4</thr:total></entry></feed>
