How to hide Surface Bodies in a Drawing using the API

How to hide Surface Bodies in a Drawing using the API

Anonymous
Not applicable
2,303 Views
6 Replies
Message 1 of 7

How to hide Surface Bodies in a Drawing using the API

Anonymous
Not applicable

Task:

I want to make a custom function using the inventor API that enables us to programmatically hide all Surface Bodies in a drawing.

 

Using the GUI:

It is possible to hide Surface Bodies by right clicking on the "Surface Bodies (1)" node in the "Model Tree" and then toggle visibility by clicking on "Visibility". In the screen snap below "Surface Bodies" on the first part has been hidden.

The "Surface Bodies" is the circular Extrusion of Srf1. It is visble on the second part and hidden on the first.

SurfaceBodies.png

 

Problem:

How can I achieve this through the API.

I need to make a C# function that can do this - but for a start we try using VBA.

 

First I tried to use the DrawingView Objects in the ActiveDocument but I was not able find the "Surface Bodies" by browsing the view object hierarchy.

 

Next i tried acces via the BrowserNodes - but faild to find the object that actually controls the visibility of the "Surface Bodies". 

Failed attempt:

 

Sub HideSurfaceBodies()
    Dim oDrawDoc As DrawingDocument
    Set oDrawDoc = ThisApplication.ActiveDocument
    
    For Each Item In oDrawDoc.BrowserPanes
        If Item.Name = "Model" Then
            For Each Level2Item In Item.TopNode.BrowserNodes
               Debug.Print Level2Item.FullPath
               DumpLevel 1, Level2Item
            Next Level2Item
        End If
    Next Item
    
    oDrawDoc.Update
    oDrawDoc.Update2

End Sub


Sub DumpLevel(level, itemN)

    If InStr(1, itemN.FullPath, "Surface Bodies") > 0 Then
        Debug.Print Left("                                 ", level * 3) _
                    & itemN.FullPath
        If Not itemN.NativeObject Is Nothing Then
            If itemN.NativeObject.Type = kWorkSurfaceObject Then
                
                If Not itemN.NativeObject.SurfaceBodies Is Nothing Then
                    If itemN.NativeObject.SurfaceBodies.Count > 0 Then
                        For Each Body In itemN.NativeObject.SurfaceBodies
                            Debug.Print Body.Name & "  " & Body.Visible & " parent: " _
                                        & Body.Parent.Visible
                            Body.Visible = False
                        Next Body
                   End If
                End If
            End If

        End If
    End If
    
    If itemN.BrowserNodes.Count > 0 Then
        For Each nextLevelItem In itemN.BrowserNodes
            DumpLevel level + 1, nextLevelItem
        Next nextLevelItem
    End If

End Sub

 

The debug output from the above code looks like this:

 

SurfaceBodyTest.dwg:Drawing Resources
SurfaceBodyTest.dwg:Sheet:1
               SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:1:Surface Bodies
                  SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:1:Surface Bodies:Srf1
Srf1  False parent: False
                     SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:1:Surface Bodies:Srf1:ExtrusionSrf1
                        SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:1:Surface Bodies:Srf1:ExtrusionSrf1:Sketch5
               SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:2:Surface Bodies
                  SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:2:Surface Bodies:Srf1
Srf1  False parent: False
                     SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:2:Surface Bodies:Srf1:ExtrusionSrf1
                        SurfaceBodyTest.dwg:Sheet:1:VIEW1:201587.iam:201587.iam:201586:2:Surface Bodies:Srf1:ExtrusionSrf1:Sketch5

 

 

I am at a loss here.  I suspect that i need to find some sort of Proxy Object but I don't know how.

 

Any suggestions would be highly appreciated.

 

Thanks in advance

 

Lars Lund Hansen

0 Likes
Accepted solutions (1)
2,304 Views
6 Replies
Replies (6)
Message 2 of 7

xiaodong_liang
Autodesk Support
Autodesk Support
Hi Lars Lund Hansen,

I wrote a blog for your question. Actually API provides the direct way: DrawingView.SetVisibility
http://adndevblog.typepad.com/manufacturing/2016/03/inventor-api-hide-surface-bodies-of-drawing-view...
Message 3 of 7

Anonymous
Not applicable

Hi Xiaodong Liang ,

 

Thanks for your answer.
It does not solve my problem – but it gave me a vital hint.


The problem with your solution is that it applied on my drawing only hides the “Solid Bodies”. It is strange since the VBA code is “Set oSB1 = oPartDef.SurfaceBodies(1)”.

 

Here is the VBA code I used:

Sub toggleSBVisibleinDrawing()

    Dim oDoc As DrawingDocument
    Set oDoc = ThisApplication.ActiveDocument
    
    
    'Set a reference to the active sheet.
    Dim oSheet As Sheet
    Set oSheet = oDoc.ActiveSheet
    

    For Each oView In oSheet.DrawingViews
    
    'assume we only want to toggle the surface bodies presenation
    'Dim oView As DrawingView
    'Set oView = oDoc.SelectSet(1)
    
        'assume the reference document is an assembly
        Dim oRefDoc As AssemblyDocument
        Set oRefDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
         
        'check one part
        Dim oOnePartOcc As ComponentOccurrence
        Set oOnePartOcc = oRefDoc.ComponentDefinition.Occurrences(1)
         
        Dim oPartDef As PartComponentDefinition
        Set oPartDef = oOnePartOcc.Definition
        
        'assume we want to make one surface body invisible.
        'Note: one part can have more than 1 surface bodies
        
        Dim oSB1 As SurfaceBody
        Set oSB1 = oPartDef.SurfaceBodies(1)
        
        Dim oSB1Proxy As SurfaceBodyProxy
        Call oOnePartOcc.CreateGeometryProxy(oSB1, oSB1Proxy)
        
        'toggle the visibility of this object
        Call oView.SetVisibility(oSB1Proxy, False)
    
    Next oView
    
End Sub

 

 

 

 

Before:

 

 before.png

 

After:

 

after.png

 

It is the Surface Body shown as "Srf1" (the ring) that i want to hide.

If i break the code and inspect "oPartDef.SurfaceBodies" i can't find or reach the Surface Body "Srf1" but can only find "Solid1".

 

 

inspect.png

 

 

 

My solution is to use the BrowserPane Node tree for access to the "Srf1".

The code is not very nice - but it works.

The hint that helped me was the call of the CreateGeometryProxy(body, out proxy); method that gives me access to the "live" view object.

But i order to do this I had to have both the View object and the Occurrence object for the Srf1".

 

 

        internal void setVisibilityOfAllSurfaceBodies(Boolean visible)
        {

            foreach (BrowserPane pane in inventorWrapper.DrawingDocument.BrowserPanes)
            {
                if (pane.Name == "Model")
                {
                     foreach (BrowserNode node in pane.TopNode.BrowserNodes) {
                         visitNodesAndSetSurfaceBodyVisibility(node, null, null, visible);
                     }
                }
            }

        }

        private void visitNodesAndSetSurfaceBodyVisibility(BrowserNode node, Inventor.DrawingView view, Inventor.ComponentOccurrence occ, bool visible)
        {
            if (node.NativeObject != null) {
                if (node.NativeObject.Type == (int)Inventor.ObjectTypeEnum.kDrawingViewObject)
                {
                    view = node.NativeObject as Inventor.DrawingView;
                }
                else if (node.NativeObject.Type == (int)Inventor.ObjectTypeEnum.kComponentOccurrenceObject)
                {
                    occ = node.NativeObject as Inventor.ComponentOccurrence;
                }
                if (node.FullPath.IndexOf("Surface Bodies") >= 0)
                {
                    if (node.NativeObject.Type == (int)Inventor.ObjectTypeEnum.kWorkSurfaceObject)
                    {
                        Inventor.SurfaceBodies surfaceBodies = node.NativeObject.SurfaceBodies as Inventor.SurfaceBodies;
                        if (surfaceBodies != null)
                        {
                            foreach (SurfaceBody body in surfaceBodies)
                            {
                                object proxy = null;
                                occ.CreateGeometryProxy(body, out proxy);
                                Inventor.SurfaceBodyProxy surfaceProxy = proxy as Inventor.SurfaceBodyProxy;
                                if (surfaceProxy != null)
                                {
                                    view.SetVisibility(proxy, visible);
                                }
                            }
                        }
                    }
                }
            }

            if (node.BrowserNodes.Count > 0)
            {
                foreach (BrowserNode subNode in node.BrowserNodes)
                {
                    visitNodesAndSetSurfaceBodyVisibility(subNode, view, occ, visible);
                }
            }
        }
    }

 

 

Thanks again for your fast reply.

 

With Kind regards

 

Lars Lund Hansen

0 Likes
Message 4 of 7

xiaodong_liang
Autodesk Support
Autodesk Support
Accepted solution

Hi Lars,

 

That is stored as a WorkSurface in the collection of PartComponentDefinition.WorkSurfaces. You might be a bit confused with the name 'surface body'. it is a kind of legacy name that refers to solid body. So. the code could be adjusted as below:

 

Dim oWS1 As WorkSurface
Set oWS1 = oPartDef.WorkSurfaces(1)

Dim oWS1Proxy As WorkSurfaceProxy
Call oOnePartOcc.CreateGeometryProxy(oWS1, oWS1Proxy)

'toggle the visibility of this object
Call oView.SetVisibility(oWS1Proxy, False)

Message 5 of 7

Anonymous
Not applicable

Hi Xiaodong Liang,

 

thanks for the solution.  The resulting code was much more clear and didn't need access to the Browser Pane.

 

One other user asked me to post some example VBA code that shows how it could be done:

 

Sub HideSurfaceBodiesInDrawing()

    Dim oDoc As DrawingDocument
    Set oDoc = ThisApplication.ActiveDocument
    
    
    'Set a reference to the active sheet.
    Dim oSheet As Sheet
    Set oSheet = oDoc.ActiveSheet
    

    For Each oView In oSheet.DrawingViews
    
        'assume the reference document is an assembly
        Dim oRefDoc As AssemblyDocument
        Set oRefDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
         
        Dim oOnePartOcc As ComponentOccurrence
        Set oOnePartOcc = oRefDoc.ComponentDefinition.Occurrences(1)
        For Each oOnePartOcc In oRefDoc.ComponentDefinition.Occurrences
        
        Dim oPartDef As PartComponentDefinition
        Set oPartDef = oOnePartOcc.Definition
    
         Dim oWS1 As WorkSurface
         Set oWS1 = oPartDef.WorkSurfaces(1)
        
         Dim oWS1Proxy As WorkSurfaceProxy
         Call oOnePartOcc.CreateGeometryProxy(oWS1, oWS1Proxy)
        
         'toggle the visibility of this object
         Call oView.SetVisibility(oWS1Proxy, False)
         
        Next oOnePartOcc
         
    Next oView
    
End Sub

 

 

Best Regards

Lars Lund Hansen

0 Likes
Message 6 of 7

Anonymous
Not applicable

... correction. I was a bit hasty when I posted.  A more complete and less confusing version of the code:

Sub HideSurfaceBodiesInDrawing()

    Dim oDoc As DrawingDocument
    Set oDoc = ThisApplication.ActiveDocument
    
    'Set a reference to the active sheet.
    Dim oSheet As Sheet
    Set oSheet = oDoc.ActiveSheet
    
    For Each oView In oSheet.DrawingViews
    
        'assume the reference document is an assembly
        Dim oRefDoc As AssemblyDocument
        Set oRefDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
         
        For Each oOnePartOcc In oRefDoc.ComponentDefinition.Occurrences
        
            Dim oPartDef As PartComponentDefinition
            Set oPartDef = oOnePartOcc.Definition
    
            For Each oWS1 In oPartDef.WorkSurfaces
                Dim oWS1Proxy As WorkSurfaceProxy
                Call oOnePartOcc.CreateGeometryProxy(oWS1, oWS1Proxy)
            
                'Set the visibility of this object
                Call oView.SetVisibility(oWS1Proxy, False)
            Next oWS1
            
        Next oOnePartOcc
         
    Next oView
    
End Sub

 

Best Regards

Lars Lund Hansen

0 Likes
Message 7 of 7

ramji.m
Participant
Participant

 

 

 

  TRY this simple step

For Each oView In oSheet.DrawingViews oView.IncludeSurfaceBodies = False Next oView

 

0 Likes