How do I check "Include Model sketches" via iLogic

How do I check "Include Model sketches" via iLogic

jeremiasfriesen
Contributor Contributor
1,056 Views
13 Replies
Message 1 of 14

How do I check "Include Model sketches" via iLogic

jeremiasfriesen
Contributor
Contributor

Hi Inventor Community!

I have a very specific problem:
For some of our assemblies, we always create a drawing sheet that includes two section views. The "lines" for these section views are embedded in the assembly itself. I already created a functioning rule that creates these section views for me if the sketches are made visible by me beforehand. That means I include them in the drawing view and make them visible. 
So now here is my problem: I managed to include the sketches in the drawing view but I can´t select them via iLogic. I can only filter them out as DrawingCurves when I check the "Include Model sketches" checkbox in the model tree. Only then can I select the sketch lines to use them to create section views. Can I automate this process of clicking the "Include model sketches" button via iLogic?
Thanks in advance!

0 Likes
Accepted solutions (1)
1,057 Views
13 Replies
Replies (13)
Message 2 of 14

WCrihfield
Mentor
Mentor
Accepted solution

Hi @jeremiasfriesen.  Below is some code that can be used in an iLogic rule to execute the same command that gets executed when you click that option.  

Dim oCD As ControlDefinition = ThisApplication.CommandManager.ControlDefinitions.Item("DrawingGetModelSketchesCtxCmd")
oCD.Execute2(False)

However, I believe that the BrowserNode for the model document that is under the BrowserNode for the DrawingView, will need to be selected before this will work.  There are two ways to select something like that by code, but most likely the one way that would work best in this situation would be to navigate the model browser tree by code, then once you have found the BrowserNode for that model reference under the specific view you want to effect, you can use its BrowserNode.DoSelect method.  The other way involves using the DrawingDocument.SelectSet.Select method to add the model reference to the document's SelectSet, but I am not sure how that work in this situation, since that would not be directly associated with a specific DrawingView, if there were multiple views with the same model reference.  Of course you could just manually pre-select, or use the Pick method to select a view or the model node under the view, but that would eliminate most of the automation advantage.

 

Another way to include the sketches geometry in a DrawingView, is to use the DrawingView.SetIncludeStatus method.  And if the geometry is already included, but not visible, you can use the DrawingView.SetVisibility method.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 14

jeremiasfriesen
Contributor
Contributor

That looks promising! I´ve never gotten to playing around with the ControlDefinitions but I figured it would work with that. Is there any list with all the internal names for the control definitions?
Regarding the selection of the browser node, I think that should be doable as there is only one view on the sheet by the time the section views will be created. I will try to incorporate your solution in the code and will report on how it worked out, but for now thanks in advance!

0 Likes
Message 4 of 14

jeremiasfriesen
Contributor
Contributor
Quick update: It worked like a charm! The only thing that was holding me off was that I wanted to execute that command for two different browser nodes and using "Execute2" only did one for me. I changed it to just "Execute" and it somehow worked, that´s just iLogic I guess!
0 Likes
Message 5 of 14

WCrihfield
Mentor
Mentor

Hi @jeremiasfriesen.  I'm glad you were able to use the command.  Sometimes choosing the right Execute, Execute2(True), or Execute2(False) option makes all the difference, and sometimes it just takes some trial & error testing to figure out which one works best in your exact situation.  As for a list of all ControlDefinitions...that list sort of exists, but it is not necessarily officially posted anywhere by Autodesk.  We all just use a bit of code to list them all out as we want to see them.  For instance, perhaps the simplest way to get a list all their InternalNames is with the following code.

Dim oCDs As ControlDefinitions = ThisApplication.CommandManager.ControlDefinitions
For Each oCD As ControlDefinition In oCDs
	Logger.Info(oCD.InternalName)
Next

But there are lots of variations of this technique...some that get very detailed, and write all aspects of each one to an Excel spreadsheet file.  Attached is one such Excel spreadsheet file made that way.  And the I believe I have attached the iLogic rule that can create a file like that too, in case you are interested.  I have a few similar codes though, and I'm not sure if that is the exact one or not.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 14

brotherhogue
Contributor
Contributor

Can you show me a snippet of how you did it please?

0 Likes
Message 7 of 14

WCrihfield
Mentor
Mentor

Hi @brotherhogue.  Below is just one possible example of how something like this can be done.  This example is using the 'SetIncludeStatus' method of the view, instead of trying to select a browser node, then executing a command on it.  However, this is just a basic / simplistic example, so you may need to customize it to better suit your specific needs.  For instance, this example is just getting the first view on the active sheet, then getting the model document it references, then finding all 'planar' sketches within it that are currently visible, and including those in the view, then updating the drawing.  You may want it to iterate through all sheets, or iterate through all views, or only one specific  view, by its name, then only one specific sketch, by its name.  There are too many numerous ways it could be customized further to list here, or show examples of.  I did test this code on a drawing just before posting it, and it worked OK for me (using Inventor Pro 2024.3.3).

Dim oDDoc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)
If oDDoc Is Nothing Then Return
Dim oViews As DrawingViews = oDDoc.ActiveSheet.DrawingViews
Dim oView As DrawingView = oViews.Item(1)
Dim oViewModelDoc As Inventor.Document = oView.ReferencedDocumentDescriptor.ReferencedDocument
For Each oPSketch As PlanarSketch In oViewModelDoc.ComponentDefinition.Sketches
	If oPSketch.Visible Then
		oView.SetIncludeStatus(oPSketch, True)
	End If
Next
oDDoc.Update2(True)

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

EESignature

(Not an Autodesk Employee)

Message 8 of 14

brotherhogue
Contributor
Contributor

I tried it and wasn't successful. I'm specifically trying to target Flat Pattern sketches here:

brotherhogue_0-1738162529229.png

 

When I wasn't successful, I adjusted the code to this:

 

Dim oDDoc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)
If oDDoc Is Nothing Then Return
Dim oViews As DrawingViews = oDDoc.ActiveSheet.DrawingViews
Dim oView As DrawingView = oViews.Item(1)
Dim oViewModelDoc As Inventor.Document = oView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oFlatPattern As FlatPattern = oViewModelDoc.ComponentDefinition.FlatPattern
For Each oPSketch As PlanarSketch In oFlatPattern.Sketches
    oView.SetIncludeStatus(oPSketch, True)
Next
oDDoc.Update2(True)

 

It still didn't work. I found a way to make it work by targeting browser nodes and running the command, but it's really not optimal. Here's what it looks like:

 

AddReference "System.Windows.Forms"
AddReference "System.Drawing"

Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Drawing
Imports Inventor
Imports System

Public Class BrowserNodeTest
    Private inventorApp As Inventor.Application
    Private DrawingDoc As Inventor.DrawingDocument
    Private _commandDefinition As Inventor.ControlDefinition
    Private _loggerDelegate As Action(Of String)
    Private ViewNode As BrowserNode
    Private ModelNode As BrowserNode

    Public Sub New(app As Inventor.Application, loggerDelegate As Action(Of String))
        inventorApp = app
        DrawingDoc = TryCast(inventorApp.ActiveDocument, Inventor.DrawingDocument)
        _loggerDelegate = loggerDelegate
    End Sub

    Private Sub LogInfo(message As String)
        If _loggerDelegate IsNot Nothing Then
            _loggerDelegate("INFO: " & message)
        End If
    End Sub

    Private Sub LogError(message As String)
        If _loggerDelegate IsNot Nothing Then
            _loggerDelegate("ERROR: " & message)
        End If
    End Sub

    Public Sub ProcessView(view As Inventor.DrawingView)
        LogInfo("Processing view: " & view.Name)
        
        Dim browserPane As Inventor.BrowserPane = Nothing
        For Each pane As Inventor.BrowserPane In DrawingDoc.BrowserPanes
            LogInfo("Found browser pane: " & pane.Name)
            If pane.Name = "Model" Then
                browserPane = pane
                Exit For
            End If
        Next
        
        If browserPane Is Nothing Then
            LogError("Model browser pane not found")
            Return
        End If

        inventorApp.CommandManager.ControlDefinitions.Item("AppBrowserExpandAllCmd").Execute()
        LogInfo("Expanded all browser nodes")

        Dim validPairs As New List(Of Tuple(Of BrowserNode, BrowserNode))
        
        For Each sheetNode As Inventor.BrowserNode In browserPane.TopNode.BrowserNodes
            If sheetNode.BrowserNodeDefinition.Label = "Drawing Resources" Then Continue For
            
            If TypeName(sheetNode.BrowserNodeDefinition.NativeObject) = "Sheet" Then
                LogInfo("Found sheet node: " & sheetNode.BrowserNodeDefinition.Label)
                
                For Each viewNode As Inventor.BrowserNode In sheetNode.BrowserNodes
                    LogInfo("Checking view node: " & viewNode.BrowserNodeDefinition.Label)
                    
                    For Each modelNode As Inventor.BrowserNode In viewNode.BrowserNodes
                        If TypeName(modelNode.BrowserNodeDefinition.NativeObject) = "SheetMetalComponentDefinition" Then
                            LogInfo("Found valid pair - View: " & viewNode.BrowserNodeDefinition.Label & ", Model: " & modelNode.BrowserNodeDefinition.Label)
                            validPairs.Add(New Tuple(Of BrowserNode, BrowserNode)(viewNode, modelNode))
                        End If
                    Next
                Next
            End If
        Next

        LogInfo("Processing " & validPairs.Count & " valid node pairs")
        
        For Each pair As Tuple(Of BrowserNode, BrowserNode) In validPairs
            DrawingDoc.SelectSet.Clear()
            LogInfo("Processing pair - View: " & pair.Item1.BrowserNodeDefinition.Label)
            
            Try
                pair.Item1.DoSelect()
                LogInfo("View node selected")
                pair.Item2.DoSelect()
                LogInfo("Model node selected")
                
                LogInfo("Selection count: " & DrawingDoc.SelectSet.Count)
                
                _commandDefinition = inventorApp.CommandManager.ControlDefinitions.Item("DrawingGetModelSketchesCtxCmd")
                _commandDefinition.Execute()
                LogInfo("Command executed for current pair")
                
            Catch ex As Exception
                LogError("Failed processing pair: " & ex.Message)
            End Try
        Next

        inventorApp.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute()
        LogInfo("Collapsed all browser nodes")
        
        DrawingDoc.SelectSet.Clear()
        LogInfo("Cleared final selection state")
    End Sub
End Class

Public Sub Main()
    If ThisApplication.ActiveDocument.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
        MessageBox.Show("Please activate a drawing document before using this tool.",
                      "Invalid Document Type",
                      MessageBoxButtons.OK,
                      MessageBoxIcon.Warning)
        Return
    End If
    
    If String.IsNullOrEmpty(ThisApplication.ActiveDocument.FullFileName) Then
        MessageBox.Show("Please save the document before running this rule.",
                      "Drawing Export",
                      MessageBoxButtons.OK,
                      MessageBoxIcon.Information)
        Return
    End If
    
    Dim test As New BrowserNodeTest(ThisApplication, AddressOf LogMessage)
    test.ProcessView(ThisApplication.ActiveDocument.ActiveSheet.DrawingViews.Item(1))
End Sub

Public Sub LogMessage(message As String)
    If message.StartsWith("INFO:") Then
        Logger.Info(message.Substring(5).Trim())
    ElseIf message.StartsWith("ERROR:") Then
        Logger.Error(message.Substring(6).Trim())
    Else
        Logger.Info(message)
    End If
End Sub

 

If you have any other ideas I'd love to hear them. Thanks for replying.

Message 9 of 14

WCrihfield
Mentor
Mentor

As it seems you already know, the sketches that were created / defined within the flat pattern, or while the model was in flat pattern editing mode, can only be accessed from within that alternate 'definition' of the model.  So, normally this would only be possible if the view itself were a flat pattern view of the model (DrawingView.IsFlatPatternView).  When that is the case, the view is already viewing that 'definition' of the model directly, and so the sketches defined within that definition would be readily available for direct 'inclusion'.  They may need to be 'visible' in the model first though.  But if the view is of the 'folded' definition of the part, it can naturally only include stuff that exists within the folded definition.  There may be exceptions to that rule, but those are the basics.  If the BrowserNode selection and command execution route worked for you, and the view was of a folded model, then that command must obviously do more than I had in mind, which is not a surprise.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 10 of 14

brotherhogue
Contributor
Contributor

Thanks for clarifying the subject. I'll keep going with what I have so far.

0 Likes
Message 11 of 14

WCrihfield
Mentor
Mentor

Nice code example.  Very thorough.  And relatively rare to see successful / proper use of Tuple type variables here in this forum.  I only dabble with them on rare occasions, and usually in cases where more than 2 pieces of data need to be kept in each sub-set, but don't want to deal with Dictionary or List(Of KeyValuePair()) type variables.  👍

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 12 of 14

brotherhogue
Contributor
Contributor

Thanks, but I can't really take any credit. I'm using AI to help me learn how to code. I also discovered that the approach I was taking by targeting browser nodes, simulating a selection click and executing the command won't work with my overall grand scheme of things, because the actual script I'm trying to build with these samples programmatically builds an IDW out of view before exporting it as a DXF. And I can't target the browser nodes and select them if the IDW is out of view. If you really want to see the code I'm working with, it's attached. Warning though, it's pretty enormous. I'm not skilled enough to break this up into multiple classes across multiple documents.

 

Do you think there's any possibility of revisiting the approach you suggested and seeing if we could somehow make it work to target the sketches on flat patterns?

0 Likes
Message 13 of 14

WCrihfield
Mentor
Mentor

Is this code going to be used exclusively within iLogic rules, or will it be used within something like an Inventor Add-In, or something like a standalone external EXE type application, or 'other'?  In my example, and your fist edited version of my example, within the first line of code, we are using the "ThisDoc.Document" code phrase.  That is unique to the iLogic add-in, within Inventor, and will only work within iLogic rules.  The 'ThisDoc' term being used there is very dynamic, and works differently in different situations, so that it is referring to the most appropriate source.  It is what is known as a Rule Object, and is essentially a variable that has been assigned a value that is a ICadDoc Interface.  I can't explain 100% about how it works differently in different situations here in this reply, but it is very interesting and useful.  If your code will be used anywhere else, then you may have to switch that to something like Application.ActiveDocument or Application.ActiveEditDocument, or something like that, which are Inventor API based, instead of uniquely iLogic based.  Everything else in those first couple example codes is entirely Inventor API based, and not unique to iLogic.

If you have an assembly open, then your code is working with other, referenced documents, or perhaps creating other documents, the assembly will likely remain the 'active' document, because it was the 'active' one when the code process started.  Every Document type object does have an 'Activate' method, which is supposed to force it to become the 'active' document, and visibly show on your screen, with its own Document tab, but that does not always work in every situation.  And any code that either runs remotely, or due to events happening, or is interacting with 'other' documents, the way you refer to, and work with those documents in your code is extremely important, maybe even the most important thing.

 

Below is another version of that example, which is trying to use the 'active' document.  Not sure if that will work for you.  If not, try making the 'Sub Main' into its own custom Sub routine within your overall / larger code based project, which accepts a DrawingDocument type input variable, then uses that instead of trying to use the 'active' document.  Also, it is 'activating' each sheet as it iterates through them.  That may not be necessary, and may not even work in some situations, so you can try commenting or uncommenting that line of code, to see if it changes things for you.

Sub Main
	Dim oInvApp As Inventor.Application = ThisApplication
	Dim oDDoc As DrawingDocument = TryCast(oInvApp.ActiveDocument, Inventor.DrawingDocument)
	If oDDoc Is Nothing Then Return 'may want a feedback message here
	'start iterating all sheets
	For Each oSheet As Inventor.Sheet In oDDoc.Sheets
		'not usually necessary, but depends on what you are doing
		oSheet.Activate() '<<< MAYBE NOT BE NEEDED >>>
		'start iterating all views on that sheet
		For Each oView As DrawingView In oDDoc.ActiveSheet.DrawingViews
			IncludeFlatPatternSketchesInView(oView)
		Next 'oView
		oSheet.Update()
	Next 'oSheet
	oDDoc.Update2(True)
End Sub

Sub IncludeFlatPatternSketchesInView(oDView As Inventor.DrawingView)
	If (oDView Is Nothing) OrElse (Not oDView.IsFlatPatternView) Then Exit Sub
	Dim oSheet As Inventor.Sheet = oDView.Parent
	Dim oDDoc As DrawingDocument = oSheet.Parent
	If Not oDDoc.IsModifiable Then Exit Sub
	Dim oSMDoc As PartDocument = oDView.ReferencedDocumentDescriptor.ReferencedDocument
	Dim oSMDef As SheetMetalComponentDefinition = oSMDoc.ComponentDefinition
	Dim oFlatPattern As Inventor.FlatPattern = oSMDef.FlatPattern
	For Each oPSketch As PlanarSketch In oFlatPattern.Sketches
		If Not oPSketch.Visible Then Continue For
		Try
			oDView.SetIncludeStatus(oPSketch, True)
		Catch ex As Exception
			Logger.Error("Error including sketch named '" & oPSketch.Name & "'," _
			& vbCrLf & "into view named '" & oDView.Name _
			& vbCrLf & ex.Message)
		End Try
	Next 'oPSketch
End Sub

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 14 of 14

brotherhogue
Contributor
Contributor

This appears to be working. You're a wizard! I'm going to keep tinkering with it to see what I can do. Thank you very much.

0 Likes