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 »