Alesandar,
I was able to come up with a bit of iLogic that would iterate through all view on all sheets in a drawing and compare the components in it to a given file which I called 'SearchPart'.
If geometry was found which corresponded with the SearchPart it sets the visibility of the occurrence in the drawingview to False, i.e. not-visible
You should only have to revise the SearchPart Value (perhaps with an input box or other method) to have the program work with YOUR parts.
SearchPart = "Cylinder1.ipt" oDoc = ThisApplication.ActiveDocument If oDoc.DocumentType = kDrawingDocumentObject Then Dim oDrawDoc As DrawingDocument oDrawDoc = oDoc Dim oSheets As Sheets oSheets = oDrawDoc.Sheets For Each oSheet As Sheet In oSheets For Each oView As DrawingView In oSheet.DrawingViews For Each oViewCurve As DrawingCurve In oView.DrawingCurves Try Dim oCurveModelGeom As EdgeProxy = oViewCurve.ModelGeometry Dim oCurveCompOcc As ComponentOccurrence = oCurveModelGeom.ContainingOccurrence Dim oCurveDoc As Document = oCurveCompOcc.Definition.Document Dim sCurveDocName As String = System.IO.Path.GetFileName(oCurveDoc.FullFileName) If sCurveDocName = SearchPart Call oView.SetVisibility(oCurveCompOcc,False) Exit For 'oViewCurves End If Catch End Try Next Next Next Else MessageBox.Show("Not Drawing Document") End If
I would like to piggyback on this topic. I'm looking for ilogic that builds on this idea for an IDW. My goal is to be able to insert a model in an IDW and then using ilogic, turn off all parts except for parts that start with specific letters/numbers. I dont even mind adding the part number, running the code, adding a different part number, running the code again.
Something like this:
SearchPart = (""&(Left(iProperties.Value("Project", "Part Number"),3))&"P-100.ipt")
@Anonymous
The code provided by @NSBowser is something that is referring to the drawing curves for a specific occurrence, I came up with a bit different idea, rather than turning of the drawing curves, an occurrence or a part can directly be made visible/invisible. Check the below sample.
Dim oDrawingView As DrawingView oDrawingView = ThisDrawing.ActiveSheet.View("VIEW1").View ' You can replace View1 with the view name you want Dim oRefDoc As AssemblyDocument oRefDoc = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oAssDef As AssemblyComponentDefinition oAssDef = oRefDoc.ComponentDefinition
PartName = InputBox("Part dispay name", "Title", "Default Entry") 'Write the displayname of the part that you see in browser in the input box when prompted.
Dim oOcc As ComponentOccurrence oOcc = oAssDef.Occurrences.ItemByName(PartName)
oDrawingView.SetVisibility(oOcc, False) 'You can change here to True/False to turn visibility on/off
InventorVb.DocumentUpdate
Hope this will help you.
@dutt.thakar - thank you for your response. I really like the inputbox. But I have two problems.
1. I would prefer to not change the view name, as this will apply to multiple drawings when finished.
2. As in my example, I am in need of only using a couple of characters from the part name. For example, I need to hide the following parts with one click:
L-100
L-101
L-102
L-103
Instead of using the entire part name, or display name, I would like to type in the inputbox "L-1" and it would hide all instances of the L-1 in the entire view.
Hopefully this makes sense.
Perhaps this will work better for you then. It loops through all sheets, and all views on each sheet, gets the model (assembly) within the view, loops through all its components looking for any who's name starts with the text you supply in the InputBox. When found, it turns their visibility off for that view.
If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
MsgBox("A Drawing Document must be active for this rule to work. Exiting.",vbOKOnly+vbCritical, "WRONG DOCUMENT TYPE")
Exit Sub
End If
Dim oDDoc As DrawingDocument = ThisApplication.ActiveDocument
Dim oStr As String = InputBox("Enter text to search for.")
For Each oSheet As Inventor.Sheet In oDDoc.Sheets
For Each oView As DrawingView In oSheet.DrawingViews
If oView.ReferencedDocumentDescriptor.ReferencedDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim oADoc As AssemblyDocument = oView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
For Each oOcc As ComponentOccurrence In oADef.Occurrences
If oOcc.Name.StartsWith(oStr) Then
oView.SetVisibility(oOcc, False)
End If
Next
End If
Next
Next
oDDoc.Update
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.
If you have time, please... Vote For My IDEAS 💡or you can Explore My CONTRIBUTIONS
Inventor 2021 Help | Inventor Forum | Inventor Customization Forum | Inventor Ideas Forum
Wesley Crihfield
(Not an Autodesk Employee)
This is amazing... I have one problem that I hope is very easy.
If I insert an assembly with an assembly inside of it, this doesnt work. It seems to only work one level deep. So I guess adding code that will go one deeper?
Thanks so much for your help!
OK. I think I may have a solution that will dig deeper in its search for you.
It uses a 'recursive' Sub routine, which:
This should be able to dig as deep as needed. But be careful and save your documents before running this, because recursive routines can be taxing on your System and may cause Inventor to crash unexpectedly. If this causes Inventor to crash, we may have to try it in a different way.
Also, when attempting to change visibility of stuff in drawing views, there are a number of factors to be aware of, that may cause something like this not to work. If the DrawingView is set to a specific 'View Representation', 'Positional Representation', or 'Level of Detail Representation', those may or may not interfere with this. Especially if you have a custom View Representation set, and you have the checkbox next to the 'Associative' setting. That means it is live-linked to that view representation within the model, and therefore will always show exactly as the model shows, while it is in that representation. When that 'Associative' setting is turned on, you most likely won't be able to modify the visibility of things in the view. To do this while maintaining the Associative setting, you would have to make the changes at the model level, while that view rep is active, then save the model, then update the drawing, so the view will match the model again.
Anyways, here's the code:
Sub Main
If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
MsgBox("A Drawing Document must be active for this rule to work. Exiting.",vbOKOnly+vbCritical, "WRONG DOCUMENT TYPE")
Exit Sub
End If
Dim oDDoc As DrawingDocument = ThisApplication.ActiveDocument
Dim oStr As String = InputBox("Enter text to search for.")
For Each oSheet As Inventor.Sheet In oDDoc.Sheets
For Each oView As DrawingView In oSheet.DrawingViews
If oView.ReferencedDocumentDescriptor.ReferencedDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim oADoc As AssemblyDocument = oView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
For Each oOcc As ComponentOccurrence In oADef.Occurrences
'run recursive Sub here
'checks this component, and checks any sub-components
ProcessAndIterate(oOcc, oStr, oView)
Next
End If
Next
Next
oDDoc.Update
End Sub
Sub ProcessAndIterate(oCom As ComponentOccurrence, oSt As String, oDView As DrawingView)
'just creating new variables here to enable 'Intellisense' recognition
'and so that recursive calls are using different input variables
Dim oComp As ComponentOccurrence = oCom
Dim oStr As String = oSt
Dim oView As DrawingView = oDView
If oComp.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
If oComp.Name.StartsWith(oSt) Then
Try
oView.SetVisibility(oComp, False)
Catch
MsgBox("Failed to turn off visibility to component [" & oComp.Name & "] within the view named [" & oView.Name, , "")
End Try
End If
ElseIf oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
For Each oOcc As ComponentOccurrence In oComp.Definition.Document.ComponentDefinition.Occurrences
ProcessAndIterate(oOcc, oStr, oView)
Next
End If
End Sub
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.
Wesley Crihfield
(Not an Autodesk Employee)
This looked like it would work at first but unfortunately, it's not working.
If I enter the name of the level-two assembly, it hides that part and also hides the level-one assembly with it, which is fine at times but I need more control than that. If I enter the name of the level-one assembly, it hides everything but that part. Currently, in a drawing that requires 5-6 levels deep, the code does nothing. Also, if I abort, it locks up.
That's good to know about the custom view thing!
Thanks for your time on this!!
Upon further review, if I have a drawing of an assembly that has both parts and assemblies in it, your code works for all of the stand alone parts, but not for any of the assemblies within the assembly.
OK. I guess I just assumed you were only targeting part documents within the various levels to 'hide', and not any assembly documents themselves. This can be adjusted for. Within the 'iteration' sub, we can move the 'name check' to above the document type check, then after checking document type, if it is a Part, don't try to dig deeper, but if it's an assembly, do try to dig deeper. I'm also suspicious that we may need to create a ComponentOccurrenceProxy object (at the top level) to represent any ComponentOccurrence objects that are any deeper than the top level, for use within the View.SetVisibility() call. Either that, or we may need to go the longer route of getting each DrawingCurve/DrawingCurveSegment belonging to the target sub-components within the view, and turn them off individually, which is usually is very time and system resources consuming.
Here is a modified version of the 'ProcessAndIterate' Sub code that checks all document types (without trying the Proxy thing yet):
Sub ProcessAndIterate(oCom As ComponentOccurrence, oSt As String, oDView As DrawingView)
'just creating new variables here to enable 'Intellisense' recognition
'and so that recursive calls are using different input variables
Dim oComp As ComponentOccurrence = oCom
Dim oStr As String = oSt
Dim oView As DrawingView = oDView
If oComp.Name.StartsWith(oSt) Then
Try
oView.SetVisibility(oComp, False)
Catch
MsgBox("Failed to turn off visibility to component [" & oComp.Name & "] within the view named [" & oView.Name, , "")
End Try
End If
If oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
For Each oOcc As ComponentOccurrence In oComp.Definition.Document.ComponentDefinition.Occurrences
ProcessAndIterate(oOcc, oStr, oView)
Next
End If
End Sub
Wesley Crihfield
(Not an Autodesk Employee)
@WCrihfield Yeah this is giving me the same result as before. Its not digging deeper. Also, the bigger problem now is that it crashes or hides everything if you try to cancel out of running the rule.
@WCrihfield Just wondering if you made any progress on this? Thanks so much!
I did do a little more work on your project, but I still don't think I have a working solution, so I've pretty much given up on it. This time I attempted to create a ComponentOccurrenceProxy of any components that are below top level, and tried using that within the oView.SetVisibility() call, but something is still not working correctly when trying it out on my test assembly.
I'm thinking that if you want your drawing view to only be showing certain components, then you should just do it the normal way. Create new (custom) design view representations within each assembly (and sub-assembly) document, then adjust which components you want visible within those representations. Then within any parent assembly's, set the design view representations, of those sub-assemblies the way you want them. Then in the drawing view, set the design view representation to the custom one that is set-up right.
Here's the further modified (but still not perfect) code that I ended up with. Hopefully either you or someone else here on the forum can pick it up from here and fix it the way you want it, if it's possible.
Sub Main
If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
MsgBox("A Drawing Document must be active for this rule to work. Exiting.",vbOKOnly+vbCritical, "WRONG DOCUMENT TYPE")
Exit Sub
End If
Dim oDDoc As DrawingDocument = ThisApplication.ActiveDocument
Dim oStr As String = InputBox("Enter text to search for.")
For Each oSheet As Inventor.Sheet In oDDoc.Sheets
For Each oView As DrawingView In oSheet.DrawingViews
If oView.ReferencedDocumentDescriptor.ReferencedDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
Dim oADoc As AssemblyDocument = oView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
For Each oOcc As ComponentOccurrence In oADef.Occurrences
'run recursive Sub here
'checks this component, and checks any sub-components
ProcessAndIterate(oADef, oOcc, oStr, oView)
Next
End If
Next
Next
oDDoc.Update
End Sub
Sub ProcessAndIterate(oTopAsmDef As AssemblyComponentDefinition, oCom As ComponentOccurrence, oSt As String, oDView As DrawingView)
'just creating new variables here to enable 'Intellisense' recognition
'and so that recursive calls are using different input variables
Dim oADef As AssemblyComponentDefinition = oTopAsmDef
Dim oComp As ComponentOccurrence = oCom
Dim oStr As String = oSt
Dim oView As DrawingView = oDView
If oComp.Name.StartsWith(oSt) Then
'call other Function here to get top level component occurrence proxy to work with, if applicable
Dim oTopLevelOccProxy As ComponentOccurrenceProxy = MakeTopLevelProxy(oTopAsmDef, oComp)
If oTopLevelOccProxy Is Nothing Then
Try
oView.SetVisibility(oComp, False)
Catch
MsgBox("Failed to turn off visibility to component [" & oComp.Name & "] within the view named [" & oView.Name, , "")
End Try
ElseIf oTopLevelOccProxy IsNot Nothing Then
Try
oView.SetVisibility(oTopLevelOccProxy, False)
Catch
MsgBox("Failed to turn off visibility to component [" & oComp.Name & "] within the view named [" & oView.Name, , "")
End Try
End If
End If
If oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
For Each oOcc As ComponentOccurrence In oComp.Definition.Document.ComponentDefinition.Occurrences
ProcessAndIterate(oADef, oOcc, oStr, oView)
Next
End If
End Sub
Function MakeTopLevelProxy(oTopADef As AssemblyComponentDefinition, oOcc As ComponentOccurrence) As ComponentOccurrenceProxy
Dim oADef As AssemblyComponentDefinition = oTopADef
Dim oComp As ComponentOccurrence = oOcc
Dim oPComp As ComponentOccurrence 'parent component, if there is one
Dim oCompProxy As ComponentOccurrenceProxy 'mid-level proxy object
If oComp.Parent Is oADef Then
'This is a top level component, so no proxy is needed
'maybe return Nothing, then in the calling Sub, check for Nothing
Return Nothing
Exit Function
ElseIf oComp.ParentOccurrence IsNot Nothing Then
oPComp = oComp.ParentOccurrence
oPComp.CreateGeometryProxy(oComp, oCompProxy)
Dim oTopLevelCompProxy As ComponentOccurrenceProxy
'attempt to create a ComponentOccurrenceProxy within the top assembly
oTopLevelCompProxy = oADef.AdjustProxyContext(oCompProxy)
Return oTopLevelCompProxy
End If
End Function
Wesley Crihfield
(Not an Autodesk Employee)
@WCrihfield After setting a few representations, I like that method much better than screwing around with ilogic. Thank you so much for your time on this. Maybe it will inspire someone to take it further if necessary. Cheers!
I found and adapted some code from Clint Brown blog, it's rough but it works
Sub Main
'iLogic Code by Jhoel Forshav - originally posted at https://clintbrown.co.uk/ilogic-occurrence-selection-filter-in-drawings/
Try
Dim oView As DrawingView
Dim oOccioV As DrawingCurveSegment
oOccioV = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Seleziona Componente")
oView = oOccioV.Parent.Parent
Dim oCurves As DrawingCurvesEnumerator
oCurves = oView.DrawingCurves
Dim oToccoH As Object
oToccoH = oOccioV.Parent.ModelGeometry.Parent.Parent
oView.SetVisibility( oToccoH, False )
Catch
End Try
End Sub
Yes, that code does allow you to select a single drawing view curve segment, then turns off visibility of all other geometry in the same view belonging to the same component as the selected geometry. I've used similar code before too when working with multi-body part drawings, to turn off visibility of specific solid bodies.
Since it is very efficient and combines many things in few lines, it can be a bit difficult for others to follow, so I had a variation of that 'assembly' version of the code, that includes some very helpful comments to help understand how it all works, that you (and others) might find helpful.
Sub Main
Dim oSeg As DrawingCurveSegment = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Seleziona Componente")
'get view
'DrawingCurveSegment.Parent is a DrawingCurve
'DrawingCurve.Parent is a DrawingView
Dim oView As DrawingView = oSeg.Parent.Parent
'get the component
'DrawingCurve.ModelGeometry is either an 'Edge' or an 'EdgeProxy'
'Edge.Parent & EdgeProxy.Parent are both a SurfaceBody
'SurfaceBody.Parent is either a ComponentOccurrence or ComponentOccurrenceProxy (in an assembly drawing)
Dim oComp As Object = oSeg.Parent.ModelGeometry.Parent.Parent
'turn it off
Try
oView.SetVisibility(oComp, False)
Catch
End Try
End Sub
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.
Wesley Crihfield
(Not an Autodesk Employee)
Here is the Multi-Body Part version of that code. It allows you to select a drawing curve segment in a view, then gets the 'SurfaceBody' it belongs to, and turns off all geometry for that body. Nearly identical to the assembly version, but one step simpler.
Sub Main
Dim oSeg As DrawingCurveSegment = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Seleziona Componente")
'get view
'DrawingCurveSegment.Parent is a DrawingCurve
'DrawingCurve.Parent is a DrawingView
Dim oView As DrawingView = oSeg.Parent.Parent
'get the body
'DrawingCurve.ModelGeometry is an 'Edge'
'Edge.Parent is a SurfaceBody
Dim oBody As Object = oSeg.Parent.ModelGeometry.Parent
'turn it off
Try
oView.SetVisibility(oBody, False)
Catch
End Try
End Sub
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.
Wesley Crihfield
(Not an Autodesk Employee)
Great!
Much more elegant...