API: GetCorresponding dans vue en coupe

Bonjour à tous,

Je suis à la recherche de la méthode permettant, à partir d'une référence de type IFace2 dans le contexte d'une vue en coupe, de retrouver la référence correspondante IFace2 dans le contexte de la vue parente (IView::GetBaseView) et dans le contexte du document de référence (IView::ReferencedDocument). Les méthodes IView::GetCorresponding(Entity) ainsi que IModelDocExtention::GetCorresponding(Entity)2 me retournent des références nulles.

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

 

Dans le code ci-dessus, je commence par obtenir les faces hachurées générées par la coupe. Ensuite, j'obtiens le corps associé à cette face hachurée. Enfin, je teste la correspondance avec toutes les faces de ce corps dans la vue parente et dans le document de référence pour voir s'il trouve un résultat.

Malheureusement, aucun résultat n'est trouvé. Une petite aide serait la bienvenue.

Cordialement


getcorresponding.zip

Bonjour,

Je n'ai jamais utiliser GetFaceHatches et ne sais pas qu'est ce qu'elle est sensée retourner, mais si je rajoute :

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

après :

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

en lançant la macro avec Coupe A-A sélectionnée, ca sélectionne la face du cube de droite sur la vue plan1, donc GetCorrespondingEntity à l'air de retourner quelque chose.

3 « J'aime »

Bonjour Jerome,

Merci beaucoup pour votre aide, je vais faire plus de tests et reviens vous dire ce qu'il en est.

Cordialement.

view.GetFaceHatches

Retourne les faces hachurées crées dans la vue en coupe.

Ce que je souhaite faire c'est: à partir d'une référence Entity dans le contexte d'une vue en coupe, trouver la référence Entity dans le contexte de la vue parente.

Je ne sais pour quelle raison, la méthode View::GetCorrespondingEntity retourne une référence non nulle pour la première Face, puis plus rien pour les autres.

Votre solution n'a donc pas permis de résoudre mon problème.

Cordialement

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.

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.

(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.

1 « J'aime »
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.

 Absolument, c'est la raison pour laquelle je demande la correspondance de toutes les faces du corps de chaque face hachurée:

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)

Ces faces, qui elles ont une correspondance dans la vue parente, ne retournent aucun résultat.

 

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.

Je ne comprends pas ce qua vous voulez dire, je ne compare pas de faces, je demande la référence correspondante dans la vue parente.

 

(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.

Tout à fait d'accord.

Tel que je lis la macro:

1- GetFaceHatches => retourne 3 faces hachuré de la vue A-A

2- Pour chacune de ces faces : GetBody => retourne 1 corps volumique (c-a-d: 1 cube- 3 au total)

3- GetFaces => retourne toutes les faces du corps indépendament de la vue (c-a-d: les 6 faces du cube - 18 au total)

4- GetCorrespondingEntity => Pas sûr de qu'est ce que c'est sensé accomplir, car comme dit précédement les 6 faces retournées au point 3 sont indépendantes de la vue. Donc au mieux les mêmes faces sont retournées (c-a-d: 6 faces - 18 au total)

5- GetBody encore une fois, suivit de body.Name => écrit 6 fois le nom de chaques corps volumique - 3 corps au total

 

Au final, je ne suis toujours pas sûr de qu' est ce que vous chercher à faire.

Encore une fois, merci beaucoup pour votre aide.

1-OK avec vous

2-OK avec vous

3-Dans mon esprit, chaque corps (volumique ou surfacique) est copié + modifié de contexte en contexte, par exemple si je compare les références d'un corps dans le contexte d'une vue et celui qui lui correspond dans le contexte 3D (assemblage ou pièce référencé par la vue), alors j'obtiendrais un False, les corps ne sont pas les mêmes instance Body2. Donc lorsque vous dites indépendament de la vue, mon expérience avec l'API ne me permet pas de partager cette affirmation. Les corps ont selon moi une référence distincte dans chaque contexte (avec leurs faces correspondantes ou non), et ce, totalement dépendant de la vue. Un autre exemple: une vue en coupe peut segmenter un corps de la vue parente en deux corps distincts. Il ne peut donc s'agir des mêmes références de corps. Il y a donc un lien de dépendance entre corps et vues.

4-J'ai souvent utilisé ModelDocExtention::GetCorrespondingEntity pour trouver des faces correspondantes du contexte de la vue vers le contexte du modèle 3D. En revanche je n'ai jamais réussi à utiliser View::GetCorrespondingEntity pour trouver des faces correspondantes du contexte du modèle 3D vers le contexte de la vue. Je ne comprend pas très bien son cas d'utilisation idéal.

5-OK avec vous, le body.Name n'est présent qu'à titre de debug, pour savoir de quel corps il s'agit

Au final, ce que je cherche précisément à faire est:

A partir d'une vue en coupe active, sélectionner tous les corps de la vue parente qui ont été coupés.

Je suis d'accord que c'est difficile de comprendre les différents corps et contextes.

Après avoir fait quelques recherches, il semble que les corps de la vue de coupe sont des corps différents de la vue de base (par exemple GetArea de chaque surface montre que chaque corps est en fait une moitié de cube)

Je ne sais pas comment réconcilier cela avec les corps de la vue de base. En revanche il y a un moyen détourné car chaque corps a au moins une face non-coupée. Donc on peut retrouver le corps en sauvegardant les propriétés de chaque faces et les comparer avec celles chaque faces de la vue de base.

La macro ci-jointe sélectionnera le(s) corps coupé(s) dans la vue parente (fonctionne avec la vue A-A ou B-B)


selectionne_corps_coupes.swp

Bonjour Jérôme,

Je me suis laissé le temps d'assimiler votre réponse et tester différentes choses avant de vous répondre. Votre approche géométrique (point le plus proche, calcul de surface, ...) peut paraitre démesurée à première vue mais elle semble être l'ultime solution là où l'API n'en laisse pas de plus évidente. Merci pour le temps que vous y avez consacré. Cependant, son cadre d'utilisation est limité, fonctionnel sur cette mise en plan demo mais ses limites se font vite ressentir, et ne me permet pas de l'intégrer dans le cadre d'un projet de développement plus généraliste (ça ne concerne en rien la qualité de votre code soyons clair, mais juste des limitations de la méthode géométrique).

Cependant, j'ai légèrement avancé sur mon problème, sans toutefois le résoudre, je vous partage ce bout de 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

 

Cette macro permet de comparer les références de corps des faces sélectionnées (2 ou plus) entre différentes vues d'une mise en plan, vues en coupe comprises.

Je recherche maintenant le moyen de la coupler aux faces hachurées d'une vue active (non aux faces sélectionnées).

Cordialement.

Je commence à me rapprocher du but sérieusement (nécessite des tests de fiabilité), je partage:

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 « J'aime »