Detect visibility of objects in drawing

Detect visibility of objects in drawing

WK-VA
Contributor Contributor
1,548 Views
8 Replies
Message 1 of 9

Detect visibility of objects in drawing

WK-VA
Contributor
Contributor

Hi all,

 

I'm completely lost, having tried so many different approaches to what I want to achieve...

 

What's the goal?

I want to check for a given view on a drawing, whether there are objects (parts, assemblies, pattern features of parts/assemblies) not visible. This applies only to drawing views that are not associative to any DesignViewRep. Later on I'd like to have a list of these objects, right now I only want to detect if there are such objects.

 

What I tried in the first place

I tried traversal of the ReferencedDocument's Occurrences and SubOccurrences, then get the visibility of the Occurrence in question via DrawingView.GetVisibility(Occurrence). The method GetVisibility fails (more on that later). I thought, this method would fail, as I didn't use proxies so far, which is not trivial. Then I tried to use Proxies, but...

  • I'm not sure, whether I would need to build a chain of proxies (proxy for part in subassy2, proxy for subassy2 in subassy1, proxy for subassy1 in mainassy, proxy for  mainassy in view...)
  • I couldn't find any information on how to create proxies for ComponentOccurrences or if that is possible at all
    • Creating proxies via ComponentOccurrence.CreateGeometryProxy() on itself doesn't work.
    • For parts I tried to circumvent this by iterating over the SurfaceBodies (for which proxies can be created), yet GetVisibility did fail on these as well sometimes... that's been the point where I gave up with that approach...
    • For assemblies...? No idea...

 

Alternative approach

In order to circumvent the proxy issue, I thought of traversing the tree. This is cumbersome, as I would have to specify, which types of nodes are interesting. I don't know exactly, how to specify assemblies and patterns, but so far at least that part of the code works. The idea was, that the tree should provide the "context" (part/assembly somewhere deep down in the tree but depicted in the view) so no proxies would be needed. The following code is, what I've got so far:

 

Private Function CheckBrowserNodeVisRecursive(oBrowserNode As BrowserNode) As Boolean
  
  If bailOut = True Then Exit Function
  
  CheckBrowserNodeVisRecursive = False
  
  Dim oSubBrowserNode As BrowserNode
  Dim oCompOcc As ComponentOccurrence
  Dim bVis As Boolean
  Dim sbVis As String

  bVis = True
  
  If Not (oBrowserNode.NativeObject Is Nothing) Then

    If (TypeName(oBrowserNode.NativeObject) = "DrawingView") Or _
      (TypeName(oBrowserNode.NativeObject) = "ComponentOccurrence") Or _
      (TypeName(oBrowserNode.NativeObject) = "AssemblyComponentDefinition") Then
      '' Need to include AssemblyComponentDefinition in order to go deeper later on...
      
      If (TypeName(oBrowserNode.NativeObject) = "ComponentOccurrence") Then
        Set oCompOcc = oBrowserNode.NativeObject
        On Error Resume Next
        bVis = oDoc.Sheets(1).DrawingViews(1).GetVisibility(oCompOcc)
        If Err.Number <> 0 Then
          sbVis = "GetVisibility-Error"
          Err.Clear
        Else
          sbVis = CStr(bVis)
        End If
        On Error GoTo 0
        MsgReturn = MsgBox("BrowserNode: " + vbCrLf + oBrowserNode.FullPath + vbCrLf + vbCrLf + _
          "Type: " + TypeName(oBrowserNode.NativeObject) + vbCrLf + vbCrLf + _
          "BrowserNode visible? " + CStr(oBrowserNode.Visible) + vbCrLf + vbCrLf + _
          "BrowserNode.NativeObject visible? " + CStr(oBrowserNode.NativeObject.Visible) + vbCrLf + vbCrLf + _
          "oCompOcc GetVisibility result: " + sbVis, vbOKCancel, "DEBUG")
        Set oCompOcc = Nothing
        If MsgReturn = vbCancel Then
          bailOut = True
          Exit Function
        End If
        If bVis = False Then
          CheckBrowserNodeVisRecursive = True
          Exit Function
        End If
      End If
            
      If oBrowserNode.BrowserNodes.Count <> 0 Then
        For Each oSubBrowserNode In oBrowserNode.BrowserNodes
          If (CheckBrowserNodeVisRecursive(oSubBrowserNode) = True) Then
            CheckBrowserNodeVisRecursive = True
            Exit Function
          End If
        Next
      End If
      
    End If '' check for relevant types of oBrowserNode.NativeObject
  End If '' oBrowserNode.NativeObject is not nothing
End Function

 

Notes:

  • bailOut is used to get out of the whole thing quickly, not having to click 10000 ok buttons or killing Inventor...
  • sbVis is just a string to contain either bVis (result of GetVisibility) or an error message
  • Error handling of GetVisibility should be clear, runtime error (see below) will not appear with that error handling
  • At this point I only need to know if there is ANYTHING not visible, so I get out of the whole recursion if I detect something invisible.
  • Function is initially called with the respective view's browser node as argument

 

BrowserNode.Visible

This is obviously not, what I want. Example:

In an assembly, there are (read: exist) browser nodes for constraints and representations.

If this assembly is depicted in a drawing view, the assembly's browser nodes itself still exist, but they're not visible in the tree in context of the drawing.

 

BrowserNode.NativeObject.Visible

I thought this would be the holy grail... however it isn't. Either Inventor lies to me and returns plain wrong values or the .visible property isn't what I think it is. Example:

nativeobjectvisible.png

 

DrawingView.GetVisibility

As you can see by the above screenshot, I tried to use DrawingView.GetVisibility on a ComponentOccurrence that I retrieved from BrowserNode.NativeObject once again. This seems to work in THIS very situation, however the method fails every now and then, throwing a runtime error (comment out error handling to see this!):

 getvisruntimeerror.png

 

The situation this happened in looks like that:

getvisruntimeerrorsituation.png

 

And the moment the runtime error comes up, we're processing the correct object:

getvisruntimeerrorcompocc.png

 

Funny enough, the ComponentOccurrence has a .visible property of its own, holding no useful (or wrong) information anyway (yes, in this case, it's right, however there seems to be no reliable relation to what I'm interested in... can say true when invisible, can say false when visible, can say anything...) :

getvisruntimeerrorcompoccvis.png

 

Now what's even worse, the GetVisibility method seems to fail reproducibly under certain (unclear) circumstances.

Have a look at the above depicted tree: If I set everything to be visible, the method fails on the first two parts of each instance of the subassembly. Notice the third part is exactly the same as the second part in that subassembly and with this Occurrence (and all others) however, GetVisibility doesn't fail.

If I set only the very first part in the main assembly to be "not visible", the method provides the correct result - notice this part is exactly the same as the first part in all subassemblies (where the method fails, as per last paragraph). So it seems to be not a problem of the object itself... but rather something "situational"...?

 

Conclusion

All I want to do is: Get to know, which ComponentOccurrences in the tree are not visible / "greyed out".

How to do that?

Am I using the method GetVisibility wrongly? Why doesn't that work?

Am I checking the wrong objects or properties? Why is BrowserNode.NativeObject.Visible telling lies?

 

Thank you in advance

W. Kretzschmar

0 Likes
1,549 Views
8 Replies
Replies (8)
Message 2 of 9

WK-VA
Contributor
Contributor

This is getting really strange...

 

This is a model tree of a drawing, the above code executed on.

I paint-copied an excel sheet to the right side and scaled it so that every line matches a browser node...

testcase.png

 

Conclusions for *.visible properties

  • BrowserNode.visible is obviously not what we want
  • BrowserNode.NativeObject.visible is ALWAYS true
    • false positives are highlighted in orange
  • Occurrence.visible is ALWAYS true
    • false positives are highlighted in orange
  • Occurrence is derived from BrowserNode.NativeObject, which might most likely be the cause for the results (including false positives) are the same
  • All *.visible properties seem to be completely useless... either their purpose and meaning is something else than what I expected or they simply return true no matter what...

 

Conclusions on GetVisibility

  • Runtime error occurs for all 1st and 2nd occurrences of a subassembly.
  • green: correct negative matches (Might be accidential, though!)
  • yellow: correct positive matches (Might be accidential, though!)
  • red: false negative matches!!!
  • In this scenaio: no false positive matches (Might be accidential, though!)
  • Conclusion from this scenario: Whenever there's a runtime error or the result of GetVisibility is false, the result is highly questionable. Whether a positive result is always correct... I don't know.

 

I really don't know, what I should think of that...

 

EDIT:

The problem seems to exist since 2013!!!!

DrawingView.GetVisibility returns an error - Autodesk Community - Inventor

 

See also this blog posting at adndevblog... they seem to try the same as I want to achieve, so I guess my approach can't be that wrong...

Inventor API: Check Visibility of Components in Drawing View - Manufacturing DevBlog (typepad.com) 

0 Likes
Message 3 of 9

johnsonshiue
Community Manager
Community Manager

Hi! I thought you posted a similar topic yesterday and I moved it to Inventor Customization forum. I am moving this one too since there are more API experts on that forum to help.

Many thanks!



Johnson Shiue (johnson.shiue@autodesk.com)
Software Test Engineer
0 Likes
Message 4 of 9

WK-VA
Contributor
Contributor

Hi Johnson,

 

no, I didn't post a similar topic, I just replied to a similar topic on that issue from 2013... as a colleague pointed me towards that. Thanks for moving anyway...

 

Could somebody from Autodesk please confirm or comment on the following?

 

 

Dim MsgReturn As Integer

' Assume it's a drawing...
Dim oDoc As Inventor.DrawingDocument
Set oDoc = ThisApplication.ActiveDocument

Dim oSheet As Sheet
Set oSheet = oDoc.Sheets(1)

Dim oDrawingView As DrawingView
Set oDrawingView = oSheet.DrawingViews(1)

Dim oModelDoc As Document
Set oModelDoc = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument

Dim oCompDef As ComponentDefinition
Set oCompDef = oModelDoc.ComponentDefinition

Dim oCompOcc As ComponentOccurrence

For Each oCompOcc in oCompDef.Occurrences
  MsgReturn = MsgBox(CStr(oDrawingView.GetVisibility(oCompOcc)), vbOKOnly, "DEBUG")
Next

 

 

 

Would this yield...

  • reliably true for all visible occurrences on first level (no recursion in the above code!)
  • reliably false for all non-visible occurrences on first level (no recursion in the above code!)
  • reliably a runtime error, if the occurrence is an assembly with some sub-occurrences not visible, making the assembly itself "partially visible"

 

The runtime error could thus be interpreted as something in between true and false, meaning that the assembly itself is in fact visible (Is that correct?) but something on a deeper level is definitely non-visible (Is that correct?). Confirmation of the above would help to implement at least a basic functionality for my larger problem.

 

Detection of visibility state of non-first-level occurrences would be the remaining question. Is that possible at all? Should this better be done via Occurrences of the assembly in question or via traversal of the tree? Can it be done at all?

 

Best regards

W. Kretzschmar

 

0 Likes
Message 5 of 9

WK-VA
Contributor
Contributor

Hi everybody,

 

very funny Autodesk... could you please stop sending me emails to ask for "marking the topic as solved" unless you don't care to even read or take part?

 

Things get worse: I receive a runtime error with GetVisibility, if a subassembly is marked dirty

And here we go again: Infinite update loops!

 

Scenario:

- drawing depicts assembly 1

- drawing also depicts assembly 2

- assembly 2 contains a substitute LOD of assembly 1

- (some stuff deep down in the structure is in released state, so can't and won't be properly updated)

 

How many decades will it take to sort that out, since it's a known problem for soooo long? Will I see this fixed prior to my retirement in somewhen about 2050 or prior to switching the CAD system?

0 Likes
Message 6 of 9

_dscholtes_
Advocate
Advocate

First thing I thought of as an approach:
When an occurrence is visible in a drawing view, you can get its drawing curves (see various posts / blogs on coloring items in a drawing, e.g. this one: https://modthemachine.typepad.com/my_weblog/2010/10/changing-drawing-curves-to-match-assembly-color.... ). So if an occurrence is not visible, the amount of returned drawing curves should be 0. 

The below code can be found in above link, although I modified the If-Else-EndIf part for clarity.

 

' Get all of the curves associated with this occurrence.
On Error Resume Next
Dim drawcurves As DrawingCurvesEnumerator
Set drawcurves = drawView.DrawingCurves(occ)

If Err.Number = 0 Then
   ' Object is visible, because no error occurred during retreival of curves
Else
   ' Error occurred, there are no curves for this occurrence so it's not visible
End If

 

 

Message 7 of 9

WK-VA
Contributor
Contributor

Thank you very much, that's a very nice idea and approach!

 

I'll have to think about this especially with respect to section views etc...

 

Basically I'm interested in "Did the user choose to set something to be invisible in a non-associative view".

Hence the query of visibility state in terms of the given method...

 

With your approach, everything in front of the sectioning plane would be considered "not visible" (which it is - literally), but has not been explicitly made "not visible". It's a more implicit result of the sectioning (could be detail view or cropping feature as well). 

 

But anyway, very neat idea! Thank you for that one!

0 Likes
Message 8 of 9

_dscholtes_
Advocate
Advocate

@WK-VA wrote:

Basically I'm interested in "Did the user choose to set something to be invisible in a non-associative view".

That is a very important distinction and it renders my approach invalid as a solution to your problem.
Oh well, by removing an option that doesn't work, you should get closer to one that will, right?
I'm interested, so *bookmarked*

Message 9 of 9

WK-VA
Contributor
Contributor

Yes, indeed! I try to use different combinations of approaches to get things done.

 

Background information:

Currently we have a very severe issue with drawings not updating (Literally!). We filed a case with Autodesk as well as with the supplier of the Inventor-PDM interface software. But this is a tedious process...

 

So until they provide a fix, I try to build a macro to force an update. For that, I need 100% associative views in order not to accidentially generate awkward results. So if the stock data (thousands of files!) doesn't meet that requirement, I'll try to MAKE the drawing meet that requirement without changing what's depicted. So if I detect a "bad" view, I'll search for adequate DesignViewRepresentations and set the views to be associative to these. I do as well generate adequate DVRs if none of the existing ones fit the view in question. However the whole thing strongly depends on visibility detection of the occurrences in the drawing view. Thus the GetVisibility method should be the method of choice - if this would only work as expected...

 

Currently I do get along very well, but have to avoid section views and detail views due to Inventor's concept of "visibility". So in that case, the user will have to account for associativity by himself.

 

Cropped views are a PITA, as the cropping features are not at all exposed to the API. This is a bad thing, as this would produce bad stuff with my macro but I can't even intercept cropped views.

 

And then again, I stumble opon infinite update loops, dirty stuff, ghost occurrences of substitute LODs (Don't exist anymore, but are still in the occurrences of an assembly but with no surface bodies?!?) and the like...

The last weeks make me think Inventor is one of the most dirty coded piece of software that I've ever got to work with...

 

The whole thing is going on for about 5 months now... and we're producing possibly incorrect (because not up-to-date) drawings every day. Possibly affected: Thousands of documents since about the last 10 months! Just think of all the consequences for a company...  

0 Likes