API: GetCorresponding w widoku przekroju

Cze wszystkim

Szukam metody użycia odwołania IFace2 w kontekście widoku przekrojowego, aby znaleźć odpowiednie odniesienie IFace2 w kontekście widoku nadrzędnego (IView::GetBaseView) oraz w kontekście dokumentu referencyjnego (IView::ReferencedDocument). Metody IView::GetCorresponding(Entity) oraz IModelDocExtention::GetCorresponding(Entity)2 zwracają do mnie odwołania o wartości null.

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

 

W powyższym kodzie zaczynam od uzyskania zakreskowanych powierzchni wygenerowanych przez cięcie. Następnie dostaję ciało związane z tą wykrzywioną stroną. Na koniec testuję dopasowanie ze wszystkimi powierzchniami tego ciała w widoku nadrzędnym i w dokumencie referencyjnym, aby sprawdzić, czy znajdzie wynik.

Niestety nie znaleziono żadnych wyników. Niewielka pomoc byłaby mile widziana.

Pozdrowienia


getcorresponding.zip

Witam

Nigdy nie używałem GetFaceHatches i nie wiem, co ma zwrócić, ale jeśli dodam:

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

po:

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

uruchamiając makro z zaznaczoną opcją A-A Cut, wybiera powierzchnię sześcianu po prawej stronie w widoku plan1, więc GetCorrespondingEntity wygląda, jakby coś zwracało.

3 polubienia

Witaj Hieronim,

Bardzo dziękuję za pomoc, zrobię więcej testów i wrócę, aby opowiedzieć o czym to jest.

Pozdrowienia.

view.GetFaceHatches

Zwraca kreskowane powierzchnie utworzone w widoku przekroju.

To, co chcę zrobić, to: z odniesienia do elementu w kontekście widoku przekroju znajdź odniesienie do elementu w kontekście widoku nadrzędnego.

Nie wiem dlaczego, metoda View::GetCorrespondingEntity zwraca niezerowe odwołanie dla pierwszej twarzy, a następnie nic dla pozostałych.

Więc twoje rozwiązanie nie rozwiązało mojego problemu.

Pozdrowienia

Zakreskowana strona istnieje tylko w kontekście rozważanego widoku.

W twoim przypadku jest to wirtualna i wewnętrzna ściana, która znajdowałaby się w środku sześcianu.

Użyj "vFaces = ciało. GetFaces" zwraca 6 zewnętrznych ścian  modułu.

Porównanie każdej z tych 6 twarzy z twarzą wirtualną nie powinno dać żadnych wyników.

(Fakt, że zwraca jeden, jest błędem spowodowanym ponownym użyciem "twarzy" w danych wejściowych i wyjściowych funkcji GetCorresponding lub błędem samej funkcji)

W każdym razie: zakreskowana strona nie istnieje w widoku głównym.

1 polubienie
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.

 Oczywiście, to jest powód, dla którego proszę o zgodność wszystkich twarzy każdej zakreskowanej twarzy:

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)

Te powierzchnie, które mają dopasowanie w widoku macierzystym, nie zwracają żadnych wyników.

 

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.

Nie rozumiem o co Ci chodzi, nie porównuję twarzy, proszę o odpowiednie odniesienie w widoku rodzica.

 

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

Całkowicie się zgadzam.

Jak czytam makro:

1- GetFaceHatches => zwraca 3 kreskowane ściany z widoku A-A

2- Dla każdej z tych ścian: GetBody => zwraca 1 ciało woluminu (tj.: 1 sześcian - w sumie 3)

3- GetFaces => zwraca wszystkie ściany ciała niezależnie od widoku (tj.: 6 ścian sześcianu - w sumie 18)

4- GetCorrespondingEntity => Nie jestem pewien, co to ma osiągnąć, ponieważ, jak wspomniano wcześniej, 6 twarzy zwróconych w punkcie 3 jest niezależnych od widoku. Tak więc w najlepszym przypadku te same ściany są odwracane (tj.: 6 ścian - w sumie 18)

5- Ponownie GetBody, a następnie treść. Name => wpisano nazwę każdej treści tomu 6 razy - w sumie 3 treści

 

W końcu nadal nie jestem pewien, czego chcesz zrobić.

Jeszcze raz bardzo dziękuję za pomoc.

1-W porządku z tobą

2-W porządku z tobą

3-W moim umyśle każda bryła (objętość lub powierzchnia) jest kopiowana + modyfikowana z kontekstu na kontekst, na przykład, jeśli porównuję referencje  bryły w kontekście widoku i tej, która odpowiada mu w kontekście 3D (zespół lub część, do której odwołuje się widok), wtedy otrzymałbym False, ciała nie są tą samą instancją Body2. Więc kiedy mówisz o niezależnym widoku, moje doświadczenie z API nie pozwala mi podzielić się tym stwierdzeniem. Moim zdaniem, ciała mają wyraźne odniesienie w każdym kontekście (z odpowiadającymi im twarzami lub nie), a to jest całkowicie zależne od widoku. Inny przykład: widok przekroju może segmentować bryłę widoku macierzystego na dwie oddzielne bryły. Nie mogą to być zatem te same odniesienia do treści. Istnieje zatem związek zależności między ciałami i poglądami.

4-Często używałem ModelDocExtention::GetCorrespondingEntity , aby znaleźć pasujące twarze z kontekstu widoku do kontekstu modelu 3D. Jednak nigdy nie byłem w stanie użyć View::GetCorrespondingEntity do znalezienia pasujących twarzy z kontekstu modelu 3D do kontekstu widoku. Nie do końca rozumiem jego idealny przypadek użycia.

5-OK z tobą, body. Nazwa jest obecna tylko jako debugowanie, aby wiedzieć, która to treść

W końcu to, co próbuję zrobić, to:

Z aktywnego widoku przekroju poprzecznego wybierz wszystkie obiekty w widoku macierzystym, które zostały wycięte.

Zgadzam się, że trudno jest zrozumieć różne ciała i konteksty.

Po przeprowadzeniu pewnych badań wydaje się, że bryły w widoku przekroju są różnymi bryłami niż w widoku bazowym (np. GetArea każdej powierzchni pokazuje, że każda bryła jest w rzeczywistości połową sześcianu)

Nie wiem, jak to pogodzić z treścią poglądu podstawowego. Z drugiej strony istnieje okrężna droga, ponieważ każde ciało ma co najmniej jedną nieprzeciętą stronę. Możemy więc znaleźć ciało, zapisując właściwości każdej twarzy i porównać je z właściwościami każdej twarzy w widoku podstawowym.

Załączone makro wybierze wycięte obiekty w widoku macierzystym (działa z widokiem A-A lub B-B)


selectionne_corps_coupes.swp

Witaj Jérôme,

Dałem sobie czas na przyswojenie twojej odpowiedzi i przetestowanie różnych rzeczy, zanim ci odpowiem. Twoje podejście geometryczne (najbliższy punkt, obliczenia powierzchni itp.) może wydawać się nieproporcjonalne na pierwszy rzut oka, ale wydaje się, że jest to ostateczne rozwiązanie, w którym API nie pozostawia bardziej oczywistego rozwiązania. Dziękuję za poświęcony czas. Jednak jego zakres użycia jest ograniczony, funkcjonalny na tym planie demonstracyjnym, ale jego ograniczenia są szybko odczuwalne i nie pozwalają mi zintegrować go z bardziej ogólnym projektem rozwojowym (nie ma to nic wspólnego z jakością twojego kodu, powiedzmy sobie jasno, ale tylko z ograniczeniami metody geometrycznej).

Zrobiłem jednak pewien postęp w moim problemie, nie rozwiązując go, dzielę się z Wami tym fragmentem kodu:

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

 

To makro umożliwia porównanie odniesień do bryły wybranych powierzchni (2 lub więcej) między różnymi widokami rysunku, w tym widokami przekroju.

Szukam teraz sposobu, aby połączyć go z zakreskowanymi powierzchniami aktywnego widoku (nie z wybranymi powierzchniami).

Pozdrowienia.

Na poważnie zaczynam zbliżać się do celu (wymaga testów niezawodności), dzielę się:

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 polubienie