Skip to main content

Overview of SOLIDWORKS Assembly context and usage from API

Assembly and Model contexts{ width=450 }

All SOLIDWORKS entities in 3D models (parts and assemblies) can be presented in 2 different contexts:

  • Model context - this is the context the entity is created in. For example feature created in the part document, dimension added in the part. Solid body with the faces generated by boss-extrude feature
  • Assembly context - this is the context where the models (and all their entities) are instantiated. For example the same part can be added twice into the assembly, so the elements of this part would have two different sets of pointers in the assembly which correspond to the corresponding components.

It is important to use the correct contexts when working with elements from SOLIDWORKS API. When assembly in-context editing is performed all the pointers must be provided in the assembly context.

Adding features into part in the context of the assembly

It is required to always use the pointer to active assembly document (ISldWorks::ActiveDoc) while editing or adding new features in the feature tree even if component is in editing state.

Editing the component in the context{ width=250 }

For example to insert the extruded feature into the part document from the image above which is edited in the context the IFeatureManager::FeatureExtrusion2 must be called on the IModelDoc2 which is an active assembly but not the model of the component being edited.

Dim swApp As SldWorks.SldWorks

Sub main()

Set swApp = Application.SldWorks

Dim swAssy As SldWorks.AssemblyDoc

Set swAssy = swApp.ActiveDoc

If Not swAssy Is Nothing Then

Dim swComp As SldWorks.Component2

swAssy.InsertNewVirtualPart Nothing, swComp

swComp.Select4 False, Nothing, False

swAssy.EditPart

Debug.Assert swComp.GetModelDoc2() Is swAssy.GetEditTarget() 'current editing model equals to the component's model
Debug.Assert Not swComp.GetModelDoc2() Is swAssy 'component's model doesn't equal to the assembly model

Dim swRefPlaneFeat As SldWorks.Feature
Set swRefPlaneFeat = FindStandardPlane(swComp)

Dim swSketchFeat As SldWorks.Feature

'Creating circle in the context of the current editing model via the main assembly model
Set swSketchFeat = CreateCircle(swRefPlaneFeat, swAssy)

'Creating extrude in the context of the current editing model via the main assembly model
CreateExtrude swSketchFeat, swAssy

swAssy.EditAssembly
swAssy.EditRebuild

Else
MsgBox "Please open assembly"
End If

End Sub

Function FindStandardPlane(comp As SldWorks.Component2) As SldWorks.Feature

Dim swCompModel As SldWorks.ModelDoc2
Set swCompModel = comp.GetModelDoc2

Dim i As Integer
i = 1
Dim swRefPlaneFeat As SldWorks.Feature

Do
Set swRefPlaneFeat = swCompModel.FeatureByPositionReverse(i)
i = i + 1
Loop While swRefPlaneFeat.GetTypeName2() <> "RefPlane"

'converting the pointer of the feature into the assembly context so it can be selected in the assembly
Set FindStandardPlane = comp.GetCorresponding(swRefPlaneFeat)

End Function

Function CreateCircle(plane As SldWorks.Feature, model As SldWorks.ModelDoc2) As SldWorks.Feature

plane.Select2 False, -1

model.SketchManager.InsertSketch True
model.SketchManager.AddToDB = True

Set CreateCircle = model.SketchManager.ActiveSketch

model.ClearSelection2 True
model.SketchManager.CreateCircleByRadius 0, 0, 0, 0.01
model.SketchManager.AddToDB = False

model.ClearSelection2 True
model.SketchManager.InsertSketch True

End Function

Sub CreateExtrude(sketch As SldWorks.Feature, model As SldWorks.ModelDoc2)

sketch.Select2 False, 0

model.FeatureManager.FeatureExtrusion2 True, False, False, 0, 0, 0.01, 0.01, False, False, False, False, 0, 0, False, False, False, False, True, True, True, 0, 0, False
model.ClearSelection2 True

End Sub

Converting the pointers

SOLIDWORKS API provides the method to convert the pointers between contexts:

Model operations in the context of the assembly

3D Sketch with a sketch point within the component{ width=350 }

The following test cases will demonstrate different approaches and results while working with context in assembly. Download Sample Assembly. This assembly consists of a single virtual component (this can be an external components as well). There is a 3D Sketch (3DSketch1) with a point in the component's model. For simplicity another sketch called Reference is added to the assembly which displays current point coordinate.

The purposes of the following cases is to move the point in the 3D Sketch in XYZ by 10 mm from the assembly.

Test Case 1: Moving by acquiring the pointers directly from the assembly context

When assembly is opened pointer to any object retrieved directly from the assembly or from the component will have the active assembly context.

For example:

These pointers are safe to work with within the context of this assembly. For example face colour can be changed, feature can be renamed, point coordinate can be modified.

  • Open downloaded sample assembly
  • Select the 3DSketch1 feature in the tree
  • Run the following macro
Dim swApp As SldWorks.SldWorks

Sub main()

Set swApp = Application.SldWorks

Dim swAssy As SldWorks.AssemblyDoc

Set swAssy = swApp.ActiveDoc

If Not swAssy Is Nothing Then

Dim swFeat As SldWorks.Feature
Set swFeat = swAssy.SelectionManager.GetSelectedObject6(1, -1)

MoveSketchPoints swFeat, swAssy

'exit edit in context model
swAssy.ClearSelection2 True
swAssy.EditAssembly

Else
MsgBox "Please open assembly document"
End If

End Sub

Sub MoveSketchPoints(sketchFeat As SldWorks.Feature, editModel As SldWorks.ModelDoc2)

Dim swSketch As SldWorks.Sketch
Set swSketch = sketchFeat.GetSpecificFeature2

Debug.Print "Sketch Feature Selected: " & sketchFeat.Select2(False, -1)

editModel.SketchManager.Insert3DSketch True

Dim vSkPts As Variant
vSkPts = swSketch.GetSketchPoints2()

Dim i As Integer

For i = 0 To UBound(vSkPts)
Dim swSkPt As SldWorks.SketchPoint
Set swSkPt = vSkPts(i)
swSkPt.X = swSkPt.X + 0.01
swSkPt.Y = swSkPt.Y + 0.01
swSkPt.Z = swSkPt.Z + 0.01
Next

editModel.SketchManager.Insert3DSketch True

End Sub

As the result sketch point is moved by 10 mm in XYZ directions.

Sketch point updated its location{ width=250 }

Test Case 2: Accessing the objects from the underlying model context in the context of the assembly

It is not always possible to retrieve the pointer to the required object directly from the assembly context. If out of context object (i.e. object which was retrieved or converted to the underlying component's model) is used within the assembly context this may produce unexpected results.

Using of out of context object equivalent of invoking the APIs on the invisible model. In some cases this will produce correct behaviour, in some cases it may fail or even cause the crash.

The following example demonstrates the result of using out of context pointers by converting the context from assembly to the underlying document via IModelDocExtension::GetCorresponding

Follow the steps from previous test case and run the following macro

Dim swApp As SldWorks.SldWorks

Sub main()

Set swApp = Application.SldWorks

Dim swAssy As SldWorks.AssemblyDoc

Set swAssy = swApp.ActiveDoc

If Not swAssy Is Nothing Then

Dim swFeat As SldWorks.Feature
Set swFeat = swAssy.SelectionManager.GetSelectedObject6(1, -1)

Dim swComp As SldWorks.Component2
Set swComp = swFeat.GetComponent

Dim swCorrFeat As SldWorks.Feature
Dim swCompModel As SldWorks.ModelDoc2
Set swCompModel = swComp.GetModelDoc2
Set swCorrFeat = swCompModel.Extension.GetCorresponding(swFeat)

Dim swCorrFeatByName As SldWorks.Feature
Set swCorrFeatByName = swCompModel.FeatureByName(swFeat.Name)

Debug.Print "Pointers are equal: " & (swCorrFeat Is swCorrFeatByName)

MoveSketchPoints swCorrFeat, swCompModel

Else
MsgBox "Please open assembly document"
End If

End Sub

Sub MoveSketchPoints(sketchFeat As SldWorks.Feature, editModel As SldWorks.ModelDoc2)

Dim swSketch As SldWorks.Sketch
Set swSketch = sketchFeat.GetSpecificFeature2

Debug.Print "Sketch Feature Selected: " & sketchFeat.Select2(False, -1)

editModel.SketchManager.Insert3DSketch True

Dim vSkPts As Variant
vSkPts = swSketch.GetSketchPoints2()

Dim i As Integer

For i = 0 To UBound(vSkPts)
Dim swSkPt As SldWorks.SketchPoint
Set swSkPt = vSkPts(i)
swSkPt.X = swSkPt.X + 0.01
swSkPt.Y = swSkPt.Y + 0.01
swSkPt.Z = swSkPt.Z + 0.01
Next

editModel.SketchManager.Insert3DSketch True

End Sub

As the result sketch points are not moved despite the output window displays the success

Sketch point is not moved despite no errors displayed{ width=250 }

The reason of this behaviour caused by the fact that sketch cannot be edited if the model is not opened in its own window.

Now, open the component in its own window

Open part in its own window from the component{ width=250 }

Activate the assembly and rerun the macro. Now slightly different result is displayed. Component is marked as modified and needs rebuilding. If model rebuilt sketch is updated accordingly.

Component needs rebuilding after out of the context modification{ width=200 }

Test Case 3: Converting the context of objects

In many cases the initial pointer is available in the context of the underlying model. And if modifications required in the context of assembly it is required to convert the pointer via IComponent2::GetCorresponding method.

  • Close all models and reopen sample assembly
  • Open the part component in its own window.

Open part in its own window from the component{ width=250 }

  • Select the 3DSketch1 in the active part document
  • Run the following macro
Dim swApp As SldWorks.SldWorks

Sub main()

Set swApp = Application.SldWorks

Dim swModel As SldWorks.ModelDoc2

Set swModel = swApp.ActiveDoc

If Not swModel Is Nothing Then

Dim swFeat As SldWorks.Feature
Set swFeat = swModel.SelectionManager.GetSelectedObject6(1, -1)

Stop 'Activate assembly and select the component

Dim swAssy As SldWorks.AssemblyDoc
Set swAssy = swApp.ActiveDoc

Dim swComp As SldWorks.Component2
Set swComp = swAssy.SelectionManager.GetSelectedObjectsComponent4(1, -1)
Dim swCompFeat As SldWorks.Feature
Set swCompFeat = swComp.GetCorresponding(swFeat)

Dim swCompFeatByName As SldWorks.Feature
Set swCompFeatByName = swComp.FeatureByName(swFeat.Name)

Debug.Print "Pointers are equal: " & (swCompFeat Is swCompFeatByName)

MoveSketchPoints swCompFeat, swAssy

Else
MsgBox "Please open assembly document"
End If

End Sub

Sub MoveSketchPoints(sketchFeat As SldWorks.Feature, editModel As SldWorks.ModelDoc2)

Dim swSketch As SldWorks.Sketch
Set swSketch = sketchFeat.GetSpecificFeature2

Debug.Print "Sketch Feature Selected: " & sketchFeat.Select2(False, -1)

editModel.SketchManager.Insert3DSketch True

Dim vSkPts As Variant
vSkPts = swSketch.GetSketchPoints2()

Dim i As Integer

For i = 0 To UBound(vSkPts)
Dim swSkPt As SldWorks.SketchPoint
Set swSkPt = vSkPts(i)
swSkPt.X = swSkPt.X + 0.01
swSkPt.Y = swSkPt.Y + 0.01
swSkPt.Z = swSkPt.Z + 0.01
Next

editModel.SketchManager.Insert3DSketch True

End Sub
  • Macro stops execution
  • Activate the assembly (you can just close the part document)
  • Select the component and continue the macro

Macro will convert the context and change the coordinate so the coordinates can be successfully updated in the context of the assembly

Summary

  • When adding or editing features of the components in the context of the assembly call IAssemblyDoc::EditPart2/IAssemblyDoc::EditAssembly to start/finish editing the component in the context

  • It is not required to explicitly set the Edit In Context state to perform certain operations (for example editing the sketch points location, deleting features etc.). The behaviour matches the user interface behaviour (i.e. if it is required to call Edit Part command to perform certain operation it is required to call corresponding API as well)

  • Do not use the pointer of the component's underlying model (IComponent2::GetModelDoc2) to perform the operation of the current editing target component. Use the pointer to top level document (i.e. active assembly)

  • Avoid using the incorrect context. This may result in unexpected behaviour.

  • Use ::GetCorresponding functions to convert the pointer between contexts when needed