Assembly and Model contexts
Assembly and Model contexts

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
Editing the component in the context

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
3D Sketch with a sketch point within the component

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
Sketch point updated its location

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
Sketch point is not moved despite no errors displayed

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
Open part in its own window from the component

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
Component needs rebuilding after out of the context modification

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
Open part in its own window from the component
  • 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