7 Mistakes New SolidWorks API Programmers Make

Blog 5.10.2012 6 Comments

For those who don’t know, SolidSmack.com, the largest CAD/CAM blog in the world, recently ran an article on CADSharp.com in which I answered three questions about the SolidWorks API. The third question was perhaps the most insightul: “What advice do you have for aspiring API progammers?” This question is so important that I decided to expand upon my answer in more depth in this blog post.

Even though this post is geared toward beginners, those who have many macros under their belt but still don’t quite feel like they’ve “got it” should find great insight. So without further adieu, here are 7 warnings I offer to every engineer who wants to program seriously with the SolidWorks API.

1. Not learning the SolidWorks API with Visual Basic for Applications (VBA)

VB.NET, C#, and C++ are very powerful languages. However, for macros of low to medium complexity, that power is completely unnecessary. If you’re an aspiring API programmer, you probably care about just one thing: automating your work. Then why fight the steeper learning curve of those other languages? Learn the API with VBA so you can spend less time learning the programming language itself and more time learning the SolidWorks API. The API works roughly the same in each language, so once you’re ready to move on to a more complex language, you already have the important stuff under your belt.

Ready to learn VBA programming basics? Check out the free lessons from Unit 1 of our VBA course.

2. Relying On the Macro Recorder

For an API novice, it makes perfect sense to use the macro recorder. Here’s a tool, it would seem, that gives you all of the API calls you need to create a macro. Right? Wrong. For starters, the macro recorder can’t record certain tasks at all. Working with custom properties is an example. Second, relying on the macro recorder is dangerous because keeps you in the mindset that the API performs tasks the same way you would perform them “manually”. Again, this couldn’t be further from the truth. The steps required to create a section view or change a face’s color, for example, are entirely different when using the API versus using SolidWorks normally. Third, the code the macro recorder produces is incredibly sloppy. Its formatted poorly and typically contains arguments you may or may not want. A much better practice is to use the macro recorder to “discover” an API call when you know it might take a while to find in the API Help. Nevertheless, the API Help, not the macro recorder, should be your ‘go-to’ resource, as we’ll discuss in the next mistake.

Want to learn more about the uses and limitations of the macro recorder? Check out Lesson 2.1 in our VBA course.

3. Not understanding how to use the API Help

If you think the API Help is just a stuffy reference for hardcore developers, think again. If you don’t know how to navigate your way around the API Help, your macros will never move beyond what you create with the macro recorder or what you copy and paste from someone else’s code. Using the Index tab of the local API Help, you can search topically until you find the API call or interface you need. Every single API call and interface has its own page describing how to use it properly—from arguments to return values to examples to other useful tidbits of info that you need to know.

Ready to learn how to use the API Help? Check out Lesson 2.2 from our VBA course.

4. Not understanding the SolidWorks API object model

If you really want to go to the next level as an API programmer, you MUST understand the SolidWorks API Object Model. What is this “object model”, you ask? Basically, everything you interact with in SolidWorks is considered an object by the SolidWorks API—a face, an edge, a drawing view, a component, the FeatureManager tree, a part document, the SolidWorks application itself, and so on. Each of these objects has a corresponding “interface” that lets the API talk with that object. Now here’s the important part: these objects are arranged in a hierarchy. So, for example, before you can change the color of a face, you need access to that face’s body. Before you have access to the body, however, you need access to the part document. Before you have access to the part document, you need access to the SolidWorks application. Get the idea?

To access different interfaces you need to use special API calls known as “accessors”. Here’s the great thing: every interface page in the API Help has a list of the accessors that can be used to access that interface. Hence the importance of knowing how to use the API Help well.

Ready to learn the SolidWorks API Object Model in conjunction with the API Help? Check out Lesson 2.3 from our VBA course.

5. Not modularizing your code

Modularizing code allows you to easily re-use code. It also makes you a faster programmer and makes your code less error-prone. Let me explain. Say that you write lots of macros that require you to pull out the value of a custom property called “PartNo”. Instead of re-writing that bit of code over and over again, you should create a separate function (called something like “GetPartNo”) that is called by your main code. Once you’ve written “GetPartNo” once, you don’t need to keep writing it. Instead you can place that function in its own module that you can import easily to other macros. Since you know it works, you don’t have to worry about debugging it in the future.

Ready to learn how to modularize your code? Check out Lesson 1.7 from our VBA course.

6. Not documenting or formatting your code properly

This isn’t just a mistake committed by API programmers but programmers in general. However the mistake is so serious that I have to mention it again, even if you’ve heard it before: take the time to format and document your code properly. Formatting code properly means using appropriate indentation when you “nest” layers of code within sub-procedures, conditional statements, loops, and so on. By not doing this you are making your code very difficult to read.

Documenting your code means using comments to explain the purpose of each section of code. For example, if you check out any of the macros in our Macro Library, you’ll notice three things: 1) at the top, an explanation of what the code does (including preconditions necessary for running the code), 2) comments throughout the macro explaining what role each portion of code plays, and 3) often times at the time you’ll see additional notes giving more insight into a certain API call. The result is code that is much easier for the author and others to understand. If you don’t believe me, just wait until you have to edit a macro that you wrote two years ago. You’ll have no clue what the variables do and will have to spend a large portion of time re-familiarizing yourself with the code. Its even worse if you weren’t the one who wrote the code originally.

Ready to learn more about formatting and documenting code? Check out the first four lessons of our VBA course, or check out our one-hour intro to the API, Taking Macros to the People.

7. Giving up too quickly

As with anything else in life that’s worth doing, becoming a good SolidWorks API programmer requires perseverance. As a programmer, you’re going to hit obstacles constantly. With every obstacle, however, is the opportunity for another victory. Learn to love these small victories. Keep your eye fixed on prize—automating your project, impressing your co-workers, expanding your professional repertoire, or whatever it might be. Again, as with anything else that’s challenging, programming with the API gets easier as you practice it more. Once you understand the API Help and Object Model, you’ll truly be amazed at how quickly you can write macros. You’ll love it! So stick with it, and enjoy the results.

Whether you’re a novice presently committing these mistakes or an expert that has long moved past them, I’d love to hear your insight! Share in the comments below.

Keith

Want to stay up-to-date with new CADSharp.com content? Sign up for our newsletter.


Leave Comment

Mating Automation Techniques: Pros and Cons

Blog 4.30.2012 1 Comment


You can’t talk about assemblies long without talking about mating. Consequently, if we’re going to automate assembly creation then we better have a darn good strategy for automating the mating process. While I can’t say that automating mating is easy, it is definitely possible. Best of all, several options are available to us to pull it off. Before we look at those options, however, lets consider what steps are actually necessary to add mates via the API:

1. Finding the entities used in the mate
2. Selecting those entities using IEntity::Select4 or IModelDocExtension::SelectByID2
3. Creating the mate with IAssemblyDoc::AddMate3

Note that step 2 is necessary because IAssemblyDoc::AddMate3 requires that the entities be selected.

Locating Entities

The first step is quite possibly the most difficult, or at least the most intimidating. Let’s say we need to mate two flanges together. This will require a coincident and concentric mate. Since each of those mates requires two entities, we will need to programmatically find four entities total for mating. Here’s four ways to do that.

Search for geometry/topology

If finding entities is analogous to cracking someone’s password, we might call this method the “brute force attack”. If we need to locate a face, for example, our code needs to search every single face in a component until it finds one that matches a particular geometric criteria. Considering the above example, coming up with a criterion is pretty easy: the largest cylindrical face on each component. Eyeing the flange, it isn’t obvious whether that face is the inside face or the outside face, but the great thing is that it doesn’t matter. Both are concentric about the same axis, so either one would work. Next, for the coincident mates, we need to locate the hub face that extends ever slightly past the flange. It is pretty easy to see that this face is the second largest planar face on the component, so that will be our criterion.

Pros: Doesn’t require any additional work on the part of the designer to prepare the part for mating.
Cons: Makes many assumptions about the component geometry. Our code may work fine if we keep using flanges of roughly the same proportions, but if your code needs more versatility then check out the next option.

Note that this is the method used to mate handles to a drawer front in Lesson 5.1 of our VBA course.

Search for named entities

If the first approach is not practical, an excellent alternative is to have the part designer or part automation macro name the entities used to create the mates. (Tip: To manually name an entity such as an edge or face, just right click, go to Edge/Face Properties, and specify a name. To programmatically name an entity, use IPartDoc::SetEntityName.) For example, in our flange example, the circular faces could be named “concentric” since they are used to create the concentric mate. The assembly automation macro can then traverse all edges/faces in a component until it finds the edge/face with the name “concentric”. This is done using IModelDoc2::GetEntityName.

Pros: Greater reliability during the mating process than searching geometry/topology.
Cons: Requires additional work for the part designer or the programmer who is creating the part automation macro. Moreover, existing parts will require modification before they can be used in the assembly automation process.

Note that this is the method used to mate the handle to the arm in the “99 Must Know Members of the SolidWorks API” video tutorial.

Get named reference geometry

This approach is similar to the second approach, or could be used in combination with any of the other approaches. If one or more of the mate entities could be reference geometry, then the second step of finding the mate entity can be eliminated entirely by using IModelDocExtension::SelectByID2. Consider our flange example. Inside of creating a concentric mate between the faces, center axes with known names could be used instead. So, for example, if this axis is called Axis1 then steps two and tree are accomplished in one line:

swModel.Extension.SelectByID2 "Axis1", "AXIS", 0, 0, 0, False, 0, Nothing, 0

Pros: Simpler code, greater reliability than searching geometry/topology.
Cons: More work on the part of the designer.

Get mate reference entities

This approach is similar to the second except the entities necessary for mating are found in the mate references. Extracting this data is somewhat complex, which is why I would not recommend this approach unless the assembly automation process involves a large number of existing parts with the needed entities contained in the mate references. See this example for a macro that could form the basis for mate automation using mate references.

Also note that programmatically inserting a component with mate references does not cause it to instantly “snap” into place, which happens sometimes when such a component is manually inserted and a possible entity match for the mate reference is found.

Pros: No advantage over the earlier techniques, unless mate references already exist in the part or the other techniques aren’t an option.
Cons: Complex code.

Transforms + fixing

“Wait a second… I thought we were only covering four mating techniques?” That’s because the fifth technique doesn’t involve mating but might still solve your problem. A lot of engineers mate components together not because they actually care about the mate relationships themselves but just because they need to get components in a particular position quickly so it looks in a drawing or a rendered image. If that’s the case, mates might be overkill. After all, adding and rebuilding is very performance instensive, plus mates make the assembly file MUCH larger. So why not consider this option: instead of using the cumbersome IAssemblyDoc::AddMate3 to position components, why not use transforms to move them in position and then fix them in place using IAssemblyDoc::FixComponent? Your likely answer is, “Because I don’t know how to use transforms!” Well, head on over to Lesson 5.3 and change that. You’ll end up with a macro that finishes much faster. This approach also has the advantage of not requiring you to search for entities anymore. Instead, transforming a component only requires its IComponent2 pointer, which is very easy to get using IAssemblyDoc::GetComponentByName.

Pros: Faster automation process, less bulky assembly files, faster rebuild times.
Cons: Complex code. Doesn’t actually add mates, which might be necessary.

Alignment Issues

Another issue encountered in mating automation is proper alignment. Alignment is controlled in IAssemblyDoc::AddMate3 through the AlignFromEnum argument, which gives us three options: swMateAlignALIGNED, swMateAlignANTI_ALIGNED, and swMateAlignCLOSEST. The last, as I understand it, will simply default to the easiest alignment solution depending on the current rotation of the components, although this has no value in assembly automation. Using the swMateAlignALIGNED option, then, our code to add a coincident mate between two selected planar faces looks like this:

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Sub main()
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    Set swAssy = swModel
    swAssy.AddMate3 swMateCOINCIDENT, swMateAlignALIGNED, False, Empty, Empty, Empty, _
        Empty, Empty, Empty, Empty, Empty, False, Empty
    swModel.EditRebuild3
End Sub

Try running this code on two components. Did you get the alignment you wanted? If not, then you must need swMateAlignANTI_ALIGNED, so you would modify the above code. This is pretty standard procedure for programming macros that automate mating: test what works and modify the code accordingly. This procedure has two significant assumptions, however. First, it is assumes that we know the direction (e.g., +Y) of the base extrude. If this assumption is unreliable, however, then we can’t consistently use the same alignment and expect good results.

The solution, then, is to programmatically determine whether the alignment was correct. For example, let’s consider our flange example again. If IAssemblyDoc::AddMate3 executed and both mating faces were pointing in the same direction then those face normals would have the exact same values. If we wanted the X axis going through the center of the flanges, then both flanges would have normal values of <1,0,0> or <1,0,0>, whereas if our alignment was correct then one should have <1,0,0> and the other should have <1,0,0>. So what we need is code that tests the normals of those faces, and if they are identical in the X direction, flips the alignment of the coincident mate.

To get the face normal we use IFace2::Normal. However, that gives us the normal in part coordinates. We need to use transforms to convert it to assembly coordinates. Once we’ve ran a comparison showing that the X values are identical, we need to use IAssemblyDoc::EditMate2 to flip the mate alignment. If you want to see a step-by-step tutorial on mating and alignment automation then check out Lesson 5.1 of our course Automating SolidWorks With VBA. Here is a clip of that macro in action. Note that if I did not have the code in place to flip the alignment, the handle would have been upside down the second time I ran the macro.

Happy automating,

Keith

Want to keep up with new blog posts, videos, and macros we create each month? Sign up for our newsletter!


Leave Comment

Video: The 99 Must-Know SolidWorks API Calls

Blog 4.19.2012 No Comments

Did you know that there are probably over 10,000 API calls available in SolidWorks? Yet less than 1% of them are necessary for creating even very complicated automation macros and add-ins. To prove this, I created a macro that would satisfy the specifications of a mock case study involving part, assembly, and drawing automation using only 99 unique SolidWorks API calls. A line-by-line look at how this macro works was presented At SolidWorks World 2012 in a session called “Goldmember: 99 Must-Know Methods and Properties of the SolidWorks API”.

Here is a list of those API calls, in the order that they are first used. (Some of them are used more than once.)

1. ISldWorks::GetOpenFileName
2. ISldWorks::SendMsgToUser2
3. ISldWorks::ActiveDoc
4. IModelDoc2::GetType
5. IModelDoc2::ActiveView
6. IModelView::EnableGraphicsUpdate
7. ISketchManager::AddToDB
8. ISldWorks::SetUserPreferenceToggle
9. IModelDocExtension::SelectByID2
10. ISketchManager::InsertSketch
11. ISketchManager::CreateCircleByRadius
12. IModelDoc2::AddDimension2
13. IFeatureManager::FeatureExtrusion2
14. IModelDoc2::FirstFeature
15. IFeature::GetTypeName
16. IFeature::GetNextFeature
17. IFeature::Select2
18. IFeatureManager::FeatureCut3
19. IPartDoc::GetBodies2
20. IBody2::GetFaces
21. IFace2::GetSurface
22. ISurface::IsCylinder
23. IFace2::GetArea
24. IEntity::Select4
25. IFeatureMananger::FeatureFillet
26. IPartDoc::SetEntityName
27. IBody2::GetEdges
28. IEdge::GetCurveParams3
29. ICurveParamData::StartPoint
30. IModelDoc2::AddConfiguration3
31. IModelDoc2::DeleteConfiguration2
32. IPartDoc::SetMaterialPropertyName2
33. IModelDocExtension::SetMaterialPropertyValues
34. IModelDocExtension::CustomPropertyManager
35. ICustomPropertyManager::GetNames
36. ICustomPropertyManager::Get3
37. ICustomPropertyManager::Set
38. ICustomPropertyManager::Add2
39. IModelDocExtension::SaveAs
40. IModelDoc2::OpenDoc6
41. IAssemblyDoc::AddComponent4
42. IAssemblyDoc::GetComponentByName
43. IComponent2::GetBodies3
44. IModelDoc2::GetEntityName
45. IAssemblyDoc::AddMate3
46. IAssemblyDoc::GetComponents
47. IEntity::GetComponent
48. IComponent2::ReferencedConfiguration
49. IComponent2::FeatureByName
50. IComponent2::Select4
51. IAssemblyDoc::EditPart2
52. IFeature::GetDefinition
53. IExtrudeFeatureData2::GetDepth
54. IExtrudeFeatureData2::SetDepth
55. IFeature::ModifyDefinition
56. IAssemblyDoc::EditAssembly
57. IComponent2::GetModelDoc2
58. IModelDoc2::SelectionManager
59. ISelectionManager::GetSelectedObjectType3
60. ISelectionManager::GetSelectedObject6
61. IDisplayDimension::GetDimension2
62. IDimension::SetSystemValue3
63. IModelDoc2::ForceRebuild3
64. IModelDoc2::ShowNamedView2
65. IModelDoc2::ViewZoomtofit2
66. ISldWorks::GetUserPreferenceStringValue
67. ISldWorks::NewDocument
68. IDrawingDoc::SetupSheet5
69. IDrawingDoc::CreateDrawViewFromModelView3
70. IDrawingDoc::ViewDisplayShaded
71. IView::ScaleDecimal
72. IDrawingDoc::FeatureByName
73. IDrawingDoc::AutoBalloon4
74. INote::GetAnnotation
75. IAnnotation::GetPosition
76. IAnnotation::SetPosition
77. IView::InsertBomTable3
78. IView::GetVisibleComponents
79. IDrawingDoc::NewSheet3
80. IDrawingDoc::GetSheetNames
81. IDrawingDoc::Sheet
82. IDrawingDoc::ActivateSheet
83. ISheet::SetName
84. IComponent2::Name2
85. IDrawingDoc::Create3rdAngleViews2
86. ISheet::GetViews
87. IView::GetReferencedModelName
88. IView::ReferencedConfiguration
89. IDrawingDoc::InsertModelAnnotations3
90. IModelDoc2::ClearSelection2
91. IView::GetFirstDisplayDimension5
92. IDisplayDimension::GetNameForSelection
93. IDisplayDimension::GetNext5
94. IModelDocExtension::AlignDimensions
95. IModelDocExtension::GetPackAndGo
96. IModelDoc2::GetPathName
97. IPackAndGo::SetSaveToName
98. IModelDocExtension::SavePackAndGo
99. ISldWorks::CloseAllDocuments

The presentation was very well received. Here is some of the feedback emailed to me afterward:

Your “Goldmember” presentation was the best API session I’ve attended in 8 SWW events!”

James, UtilX

Just left your “Goldmember” class you gave at Solidworks World 2012.  Thank you for coming and offering these classes!  You have opened a new world to me that I feel I can dive into…  Thank you!

Steve, Harsco Industrial

Hello Keith.  I was in your excellent course on Tuesday.  I was pretty impressed with how you got through all 99 right in the allotted time.  Thanks for the great course and insight.

Michael, WL Gore & Associates

This presentation also works as a great refresher for those who have worked with the API in the past but may need to quickly brush-up on the API by hitting only the highlights.

Although it was not recorded at SolidWorks World, I later recorded myself giving the entire presentation again. Premium members can watch it here. The lesson page also includes the code itself.

What API calls do you consider “must-know”? Please share in the comments below!

Keith

Want to keep up with new blog posts, videos, and macros we create each month? Sign up for our newsletter!


Leave Comment