User interfaces are built for clicking and selecting things. But when you try to automate a task via an API, you need other ways of selecting objects.
In this blog post, I’ll share everything I know about selecting objects in the SOLIDWORKS API, plus how to get the objects that a user selected.
Every object that the user can select via the user interface, you can select via the API. The best overview is on the help page of the swSelectType enumeration.
The list includes geometry like faces and edges, features in the feature tree, sketch segments and assembly components.
There are four main ways of selecting objects and I will talk about each one, from most-used to least-used:
You will do this often. You call SelectByID2 on the ModelExtension object, pass the name and type of the object and set the position to the default (0,0,0). The method call will look something like this in C#:
var success = swModel.Extension.SelectById2(name, type, 0, 0, 0, append, mark, callout, option);
There are nine parameters:
A few objects have a Select method (or a newer version with Select2, Select3…), so if you already have access to the object, you can call that method directly. These are the ones I use the most:
I don’t know why some objects have a Select method and others don’t.
When the two methods above don’t work for your application, you can try selecting an object by its position. Since you only have a point and no direction, I only use this method when working with drawings.
You call the same SelectById2 method, but you pass an empty string for the object name and three coordinates:
var success = swModel.Extension.SelectById2("", type, x, y, z, append, mark, callout, option);
This method does have a position, whereas selecting an object by position didn’t have one. You can only use it to select geometry, though:
var success = swModel.Extension.SelectByRay(posX, posY, posZ, dirX, dirY, dirZ, radius, type, append, mark, option);
The twelve parameters are the following:
I only use this method when all of these conditions are true:
I do this in the software that creates our Fastener Models library, where I select edges (and sometimes silhouette edges) in an isometric view so I can add mate references to them.
Be aware, though, this method is very hard to get right consistently.
If you have access to the IComponent2 object, you can always call Select4 directly. But if you want to select the component by its name, you need to call the GetSelectByIDString method to get the full component name that includes all sub-assembly levels. Pass that string as the name when you call SelectById2.
Make sure you get the component from the top-level assembly directly. If you have the ModelDoc2 of a sub-assembly and get the components from there, the component objects are different and will behave unpredictably.
There are five object types that are secretly entities, and therefore implement IEntity:
A Face2 object has no Select method, but Entity has. So to select these objects directly, cast them to an Entity, then call Select4.
To learn more about working with entities in the API, check out part seven of this series: Entities and GetCorresponding in the SOLIDWORKS API.
Mates are features, so if you want to select a mate, you first need to cast it to a feature and get the name of that feature. But when you ultimately call SelectById2, you have to pass “MATE” as the type.
Origins are points, so the correct name is “[email protected]” and the type is “EXTSKETCHPOINT”. When no sketch is active, this selects the model’s origin. If a sketch is active, you can select the sketch origin this way, although you may have to pass “SKETCHPOINT” as the type. See the next section.
If a sketch is active, you can select a sketch segment by its name and the type “SKETCHSEGMENT”.
But if no sketch is active and you want to select a segment within a sketch feature, you need to add the name of the sketch and use the type “EXTSKETCHSEGMENT”. For example:
var success = swModel.Extension.SelectById2("[email protected]", "EXTSKETCHSEGMENT", 0, 0, 0, append, mark, callout, option);
Be careful when selecting sketch points. If you use the argument “SKETCHSEGMENT” and not “SKETCHPOINT”, SOLIDWORKS may crash.
With IModelDocExtension.MultiSelect2, you can select multiple objects at once. I don’t use this method very often, but when I need it, it’s really useful and fast. Just pass an array of objects, they don’t even have to be of the same type, and call MultiSelect2.
I don’t think you need to wrap these objects in a Dispatch Wrapper, but if you call this method and it crashes SOLIDWORKS, you should try that.
You don’t often need this one, but when you do, call:
Every select method has an Append parameter. To append means to add, so if you have an existing selection and want to add an object to that selection, set the Append parameter to true.
If you want to select multiple objects without using MultiSelect2, you can do something like this:
var append = false;
foreach (var items in items)
append = true;
You may have already noticed that SelectByID2 has a Mark integer parameter. It lets you share your intention for each selected item with SOLIDWORKS.
SOLIDWORKS also uses marks for Property Manager Pages, for example the one you see when you create a Revolve feature. Every geometry input box has its own mark setting, which you can read about in the docs.
The default value is minus one (-1), which says “I don’t care what this selection is for”. The other one I remember is one (1), for when you select objects to create a Mate.
Where SelectById2 uses a Mark integer parameter, all the objects that have their own Select method (see Select an object by its Select method) have a ISelectData parameter.
The SelectData object has a Mark property, but that is the only property that I have ever used on this object.
To work with selected objects, you use the IModelDoc2.SelectionMgr (SelectionManager) object. There are four methods I use often:
Using the methods mentioned previously, it’s easy to create a for loop to iterate over the selected objects:
var selectionManager = swModel.ISelectionManager;
var mark = -1;
for (int index = 1; index <= selectionManager.GetSelectedObjectCount2(mark); index++)
var type = selectionManager.GetSelectedObjectType3(index, mark);
var selectedObject = selectionManager.GetSelectedObject6(index, mark);
Please note that when these methods take an Index parameter, this index starts from one, not zero! That’s why we use “index <=” as well.
This one is easy. Just select a bunch of objects and call IModelDocExtension.DeleteSelection2. You can pass an integer parameter to do advanced stuff like deleting child objects, but usually, a zero is all you need.