API: GetCorresponding in section view

Hi all

I'm looking for a method to use an IFace2 reference in the context of a cross-sectional view to find the corresponding IFace2 reference in the context of the parent view (IView::GetBaseView) and in the context of the reference document (IView::ReferencedDocument). The IView::GetCorresponding(Entity) methods as well as IModelDocExtention::GetCorresponding(Entity)2 return null references to me.

Option Explicit

Sub main()
    Dim app As SldWorks.SldWorks
    Dim doc As SldWorks.ModelDoc2
    Dim dwg As SldWorks.DrawingDoc
    Dim view As SldWorks.view
    Dim baseView As SldWorks.view
    Dim vHatches As Variant
    Dim vHatch As Variant
    Dim hatch As SldWorks.FaceHatch
    Dim vFaces As Variant
    Dim vFace As Variant
    Dim face As SldWorks.Face2
    Dim body As SldWorks.Body2
    
    Set app = Application.SldWorks
    If app Is Nothing Then Exit Sub
    Set doc = app.ActiveDoc
    If doc Is Nothing Then Exit Sub
    If Not doc.GetType = SwConst.swDocumentTypes_e.swDocDRAWING Then Exit Sub
    Set dwg = doc
    Set view = dwg.ActiveDrawingView
    If view Is Nothing Then Exit Sub
    Set baseView = view.GetBaseView
    If baseView Is Nothing Then Exit Sub
    vHatches = view.GetFaceHatches
    If IsEmpty(vHatches) Then Exit Sub
    For Each vHatch In vHatches
        Set hatch = vHatch
        If hatch Is Nothing Then GoTo Next_vHatch
        Set face = hatch.face
        If face Is Nothing Then GoTo Next_vHatch
        Set body = face.GetBody
        If body Is Nothing Then GoTo Next_vHatch
        vFaces = body.GetFaces
        If IsEmpty(vFaces) Then GoTo Next_vHatch
        For Each vFace In vFaces
            
            Set face = vFace
            If face Is Nothing Then GoTo Next_test
            Set face = baseView.GetCorrespondingEntity(face)
            If face Is Nothing Then GoTo Next_test
            ' Breakpoint: correspondance nulle, ce point ne sera jamais atteint '
            Set body = face.GetBody
            If body Is Nothing Then GoTo Next_test
            Debug.Print body.Name
            
Next_test:
            
            Set face = vFace
            If face Is Nothing Then GoTo Next_vFace
            Set face = view.ReferencedDocument.Extension.GetCorrespondingEntity2(face)
            If face Is Nothing Then GoTo Next_vFace
            ' Breakpoint: correspondance nulle, ce point ne sera jamais atteint '
            Set body = face.GetBody
            If body Is Nothing Then GoTo Next_vFace
            Debug.Print body.Name
            
Next_vFace:
        Next vFace
Next_vHatch:
    Next vHatch
End Sub

 

In the code above, I start by getting the hatched faces generated by the cut. Then I get the body associated with this hatched side. Finally, I test the match with all the faces of this body in the parent view and in the reference document to see if it finds a result.

Unfortunately, no results were found. A little help would be welcome.

Kind regards


getcorresponding.zip

Hello

I've never used GetFaceHatches and don't know what it's supposed to return, but if I add:

            Dim swEnt As SldWorks.Entity
            Set swEnt = face
            swEnt.Select4 True, Nothing

after:

            Set face = baseView.GetCorrespondingEntity(face)
            If face Is Nothing Then GoTo Next_test

by running the macro with A-A Cut selected, it selects the face of the cube on the right on the plan1 view, so GetCorrespondingEntity looks like it 's returning something.

3 Likes

Hello Jerome,

Thank you very much for your help, I will do more tests and come back to tell you what it is.

Kind regards.

view.GetFaceHatches

Returns the hatched faces created in the section view.

What I want to do is: from an Entity reference in the context of a section view, find the Entity reference in the context of the parent view.

I don't know why, the View::GetCorrespondingEntity method returns a non-zero reference for the first face, then nothing for the others.

So your solution didn't solve my problem.

Kind regards

The hatched side exists only in the context of the view under consideration.

In your case, it is a virtual and internal face that would be in the middle of the cube.

Use "vFaces = body. GetFaces" returns the 6 outer faces  of the cube.

Comparing each of these 6 faces to the virtual face should not return any results.

(The fact that it returns one, is an error either due to the reuse of "face" in input and output of the GetCorresponding function or an error of this function itself )

In any case: the hatched side does not exist in the main view.

1 Like
La face hachurée n'existe que dans le contexte de la vue considérée.
Dans votre cas c'est une face virtuelle et interne qui serait au milieu du cube.

 Absolutely, this is the reason why I ask for the correspondence of all the body faces of each hatched face:

vHatches = view.GetFaceHatches
For Each vHatch In vHatches
    Set hatch = vHatch
    Set face = hatch.face
    Set body = face.GetBody
    vFaces = body.GetFaces
    For Each vFace In vFaces
        Set face = vFace
        Set face = baseView.GetCorrespondingEntity(face)

These faces, which have a match in the parent view, do not return any results.

 

Utiliser "vFaces = body.GetFaces" retourne les 6 faces externes du cube.
Comparer chacune de ces 6 faces à la face virtuelle ne devrait retourner aucun résultats.

I don't understand what you mean, I don't compare faces, I ask for the corresponding reference in the parent view.

 

(Le fait que ca en retourne une, est une erreur soit due à la réutilisation de "face" en entrée et sortie de la fonction GetCorresponding ou une erreur de cette fonction elle-même )
Dans tous les cas: la face hachurée n'existe pas dans la vue principale.

Totally agree.

As I read the macro:

1- GetFaceHatches => returns 3 hatched faces from view A-A

2- For each of these faces: GetBody => returns 1 volume body (i.e.: 1 cube- 3 in total)

3- GetFaces => returns all the faces of the body independently of the view (i.e.: the 6 faces of the cube - 18 in total)

4- GetCorrespondingEntity => Not sure what this is supposed to accomplish, because as said before the 6 faces returned at point 3 are independent of the view. So at best the same faces are flipped (i.e.: 6 faces - 18 in total)

5- GetBody again, followed by body. Name => written the name of each volume body 6 times - 3 bodies in total

 

In the end, I'm still not sure what you're looking to do.

Again, thank you very much for your help.

1-OK with you

2-OK with you

3-In my mind, each body (volume or surface) is copied + modified from context to context, for example if I compare the references of a body in the context of a view and the one that corresponds to it in the 3D context (assembly or part referenced by the view), then I would get a False, the bodies are not the same Body2 instance. So when you say view independent, my experience with the API doesn't allow me to share that statement. In my opinion, bodies have a distinct reference in each context (with their corresponding faces or not), and this, totally dependent on the view. Another example: a section view can segment a body of the parent view into two separate bodies. They cannot therefore be the same body references. There is therefore a link of dependence between bodies and views.

4-I often used ModelDocExtention::GetCorrespondingEntity to find matching faces from the view context to the 3D model context. However, I have never been able to use View::GetCorrespondingEntity to find matching faces from the context of the 3D model to the context of the view. I don't quite understand his ideal use case.

5-OK with you, the bodysuit. Name is only present as a debug, to know which body it is

In the end, what I am trying to do is:

From an active cross-sectional view, select all the bodies in the parent view that have been cut.

I agree that it's difficult to understand the different bodies and contexts.

After doing some research, it seems that the bodies in the section view are different bodies from the base view (e.g. GetArea of each surface shows that each body is actually half a cube)

I don't know how to reconcile this with the bodies of the basic view. On the other hand, there is a roundabout way because each body has at least one uncut side. So we can find the body by saving the properties of each face and compare them with those of each face in the basic view.

The attached macro will select the cut body(s) in the parent view (works with A-A or B-B view)


selectionne_corps_coupes.swp

Hello Jérôme,

I gave myself time to assimilate your answer and test different things before answering you. Your geometric approach (nearest point, surface calculation, etc.) may seem disproportionate at first glance but it seems to be the ultimate solution where the API leaves no more obvious one. Thank you for your time. However, its scope of use is limited, functional on this demo plan but its limits are quickly felt, and does not allow me to integrate it into a more generalist development project (this has nothing to do with the quality of your code, let's be clear, but just the limitations of the geometric method).

However, I have made some progress on my problem, without solving it, I share with you this piece of code:

Option Explicit

Sub main()
    
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swSelMgr As SldWorks.SelectionMgr
    Dim lSelCount As Long
    Dim lRefCount As Long
    Dim lSelIndex As Long
    Dim swSelType As SwConst.swSelectType_e
    Dim swSelDcpn As SldWorks.DrawingComponent
    Dim swSelFace As SldWorks.Face2
    Dim swRefModel As SldWorks.ModelDoc2
    Dim swRefFace As SldWorks.Face2
    Dim swRefBody As SldWorks.Body2
    Dim vRefIds() As String
    Dim lRefIndex As Long
    
    Dim vRefBody As Variant
    Dim sSelId As String
    
    Set swApp = Application.SldWorks
    If swApp Is Nothing Then GoTo Next_0
    
    Set swModel = swApp.ActiveDoc
    If swModel Is Nothing Then GoTo Next_0
    
    Set swSelMgr = swModel.SelectionManager
    If swSelMgr Is Nothing Then GoTo Next_0
    
    lSelCount = swSelMgr.GetSelectedObjectCount2(-1)
    If lSelCount = 0 Then GoTo Next_0
    
    lRefCount = 0
    
    For lSelIndex = 1 To lSelCount
        
        swSelType = swSelMgr.GetSelectedObjectType3(lSelIndex, -1)
        If swSelType <> swSelFACES Then GoTo Next_1
        
        Set swSelDcpn = swSelMgr.GetSelectedObjectsComponent4(lSelIndex, -1)
        If swSelDcpn Is Nothing Then GoTo Next_1
        
        Set swSelFace = swSelMgr.GetSelectedObject6(lSelIndex, -1)
        If swSelFace Is Nothing Then GoTo Next_1
        
        Set swRefModel = swSelDcpn.View.ReferencedDocument
        If swRefModel Is Nothing Then GoTo Next_1
        
        Set swRefFace = swRefModel.Extension.GetCorrespondingEntity2(swSelFace)
        If swRefFace Is Nothing Then GoTo Next_1
        
        Set swRefBody = swRefFace.GetBody
        If swRefBody Is Nothing Then GoTo Next_1
        
        If lRefCount = 0 Then
            ReDim vRefIds(lRefCount)
        Else
            ReDim Preserve vRefIds(lRefCount)
        End If
        
        vRefIds(lRefCount) = swRefBody.GetSelectionId
        lRefCount = lRefCount + 1
        
Next_1:
        
    Next lSelIndex
    
    If lRefCount < 2 Then GoTo Next_0
    
    For lRefIndex = 1 To lRefCount - 1
        If vRefIds(lRefIndex) = vRefIds(0) Then GoTo Next_2
        Debug.Print lRefCount & " selected faces are different body references"
        GoTo Next_0
Next_2:
    Next lRefIndex
    
    Debug.Print lRefCount & " selected faces are corresponding body references"
    
Next_0:
    
End Sub

 

This macro allows you to compare the body references of the selected faces (2 or more) between different views of a drawing, including section views.

I'm now looking for a way to couple it to the hatched faces of an active view (not to the selected faces).

Kind regards.

I'm starting to get closer to the goal seriously (requires reliability tests), I share:

Option Explicit

Sub main()
    
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swDocType As SwConst.swDocumentTypes_e
    Dim swDrawing As SldWorks.DrawingDoc
    Dim swView As SldWorks.View
    Dim lFaceId As Long
    Dim vViewCpns As Variant
    Dim vViewCpn As Variant
    Dim swViewCpn As SldWorks.Component2
    Dim vViewFaces As Variant
    Dim vViewFace As Variant
    Dim swViewFace As SldWorks.Face2
    Dim swRefFace As SldWorks.Face2
    Dim cRefFaces As New Collection
    Dim vViewHatches As Variant
    Dim vViewHatch As Variant
    Dim swViewHatch As SldWorks.FaceHatch
    Dim swRefBody As SldWorks.Body2
    Dim sRefBodyId As String
    Dim cRefBodyIds As New Collection
    Dim swBaseView As SldWorks.View
    Dim vBaseViewCpns As Variant
    Dim vBaseViewCpn As Variant
    Dim swBaseViewCpn As SldWorks.Component2
    Dim vBaseViewFaces As Variant
    Dim vBaseViewFace As Variant
    Dim swBaseViewFace As SldWorks.Face2
    Dim vRefBodyId As Variant
    Dim swBaseViewEntity As SldWorks.Entity
    
    Set swApp = Application.SldWorks
    If swApp Is Nothing Then GoTo End_Sub
    
    Set swModel = swApp.ActiveDoc
    If swModel Is Nothing Then GoTo End_Sub
    
    swDocType = swModel.GetType
    If Not swDocType = swDocDRAWING Then GoTo End_Sub
    
    Set swDrawing = swModel
    If swDrawing Is Nothing Then GoTo End_Sub
    
    Set swView = swDrawing.ActiveDrawingView
    If swView Is Nothing Then GoTo End_Sub
    
    lFaceId = 1
    
    vViewCpns = swView.GetVisibleComponents
    If IsEmpty(vViewCpns) Then GoTo End_Sub
    
    For Each vViewCpn In vViewCpns
        
        Set swViewCpn = vViewCpn
        If swViewCpn Is Nothing Then GoTo Next_vViewCpn
        
        vViewFaces = swView.GetVisibleEntities2(swViewCpn, swViewEntityType_e.swViewEntityType_Face)
        If IsEmpty(vViewFaces) Then GoTo Next_vViewCpn
        
        For Each vViewFace In vViewFaces
            
            Set swViewFace = vViewFace
            If swViewFace Is Nothing Then GoTo Next_vViewFace
            
            Set swRefFace = swView.ReferencedDocument.Extension.GetCorrespondingEntity2(swViewFace)
            If swRefFace Is Nothing Then GoTo Next_vViewFace
            
            cRefFaces.Add swRefFace
            swRefFace.SetFaceId lFaceId
            lFaceId = lFaceId + 1
            
Next_vViewFace:
        Next vViewFace
        
Next_vViewCpn:
    Next vViewCpn
    
    vViewHatches = swView.GetFaceHatches
    If IsEmpty(vViewHatches) Then GoTo End_Sub
    
    For Each vViewHatch In vViewHatches
        
        Set swViewHatch = vViewHatch
        If swViewHatch Is Nothing Then GoTo Next_vViewHatch
        
        Set swViewFace = swViewHatch.Face
        If swViewFace Is Nothing Then GoTo Next_vViewHatch
        
        lFaceId = swViewFace.GetFaceId
        
        Set swRefFace = cRefFaces(lFaceId)
        If swRefFace Is Nothing Then GoTo Next_vViewHatch
        
        Set swRefBody = swRefFace.GetBody
        If swRefBody Is Nothing Then GoTo Next_vViewHatch
        
        sRefBodyId = swRefBody.GetSelectionId
        cRefBodyIds.Add sRefBodyId
        
Next_vViewHatch:
    Next vViewHatch
    
    swDrawing.ForceRebuild
    
    Set swBaseView = swView.GetBaseView
    If swBaseView Is Nothing Then GoTo End_Sub
    
    vBaseViewCpns = swBaseView.GetVisibleComponents
    If IsEmpty(vBaseViewCpns) Then GoTo End_Sub
    
    For Each vBaseViewCpn In vBaseViewCpns
        
        Set swBaseViewCpn = vBaseViewCpn
        If swBaseViewCpn Is Nothing Then GoTo Next_vBaseViewCpn
        
        vBaseViewFaces = swBaseView.GetVisibleEntities2(swBaseViewCpn, swViewEntityType_e.swViewEntityType_Face)
        If IsEmpty(vBaseViewFaces) Then GoTo Next_vBaseViewCpn
        
        For Each vBaseViewFace In vBaseViewFaces
            
            Set swBaseViewFace = vBaseViewFace
            If swBaseViewFace Is Nothing Then GoTo Next_vBaseViewFace
            
            Set swRefFace = swBaseView.ReferencedDocument.Extension.GetCorrespondingEntity2(swBaseViewFace)
            If swRefFace Is Nothing Then GoTo Next_vBaseViewFace
            
            Set swRefBody = swRefFace.GetBody
            If swRefBody Is Nothing Then GoTo Next_vBaseViewFace
            
            sRefBodyId = swRefBody.GetSelectionId
            
            For Each vRefBodyId In cRefBodyIds
                
                If Not sRefBodyId = vRefBodyId Then GoTo Next_vRefBodyId
                
                Set swBaseViewEntity = swBaseViewFace
                If swBaseViewEntity Is Nothing Then GoTo Next_vRefBodyId
                
                swBaseViewEntity.Select4 True, Nothing
                
Next_vRefBodyId:
            Next vRefBodyId
            
Next_vBaseViewFace:
        Next vBaseViewFace
        
Next_vBaseViewCpn:
    Next vBaseViewCpn
    
End_Sub:
End Sub

 

1 Like