Wednesday, May 8, 2024

Open Drawing From Balloon





Issue:

You'd like to be able to open a component drawing by selecting a balloon from an assembly drawing.

Solution:

Here is an iLogic rule that uses a bit of API code to do this.


Dim oDoc As DrawingDocument = ThisApplication.ActiveDocument

While True

	'select Balloon
	Dim oBalloon As Balloon = Nothing
	oBalloon = ThisApplication.CommandManager.Pick _
	(SelectionFilterEnum.kDrawingBalloonFilter, _
	"Select a balloon to open it's drawing. " & " (press ESC To Exit selection)")

	If IsNothing(oBalloon) Then Exit While

	Dim oLeader As Leader
	If oBalloon IsNot Nothing Then oLeader = oBalloon.Leader
	Dim oLeaderNode As LeaderNode = oLeader.AllNodes(oLeader.AllNodes.Count)
	Dim oIntent As GeometryIntent = oLeaderNode.AttachedEntity
	Dim oCurve As DrawingCurve = oIntent.Geometry
	Dim oOcc As ComponentOccurrence = oCurve.ModelGeometry.ContainingOccurrence
	Dim oRefDoc As Document = oOcc.Definition.Document
	Dim oFilePath As String = oRefDoc.FullFileName()
	Dim oDrawingFilePath As String = Left(oFilePath, Len(oFilePath) -3) & "idw"

	Try
		oDrawDoc = ThisApplication.Documents.Open(oDrawingFilePath, True)
		Exit While
	Catch
		MsgBox("Could not open " & oDrawingFilePath, , "iLogic")
	End Try

End While

Thursday, September 7, 2023

Looking to create an Inventor Add-in? Wish there was a simpler template to get you started?

You can find a couple of simplified Inventor Add-In templates at this Autodesk University link:  

MFG601910 | Bridging the Gap Between iLogic Automation and Inventor Add-Ins


In this class, I walk you through the setup and use of a simplified add-in template to get you up and running quickly with an add-in template that comes with some preconfigured tools that will allow you to quickly and easily create your own tools and buttons.




Here is a direct link to the *.zip file that includes the Add-in templates, because on the AU page it is showing as a PDF icon for some reason? 

This class walks you how to spin up a basic add-in that comes with some simple buttons that you can configure to your liking.

And/or you can add to it and create you own.


There is also another add-in template included with some of the more advanced "button stacks" with dropdowns, etc. that you can also configure to your liking, and/or you can add to it and create your own:




Autodesk University 2023: Bridging the Gap Between iLogic Automation and Inventor Add-Ins, MFG601910 



Wednesday, February 1, 2023

iLogic : Set View Scale from Standard Preset Set List

 Issue:

You would like to set the view scale of your drawing views using the predefined scale list as found at Manage tab > Styles Editor button > Standard > Standard name > General tab > Preset Values > Scale




Solution:

Here is a quick bit of code to get this list and set the scale based on the scale selected from the input list box.

( Thank you! to Zach B. for the idea for the rule) 





Dim oDoc As DrawingDocument = ThisApplication.ActiveDocument
Dim oStyleManager As DrawingStylesManager = oDoc.StylesManager

Dim oActiveStandard As DrawingStandardStyle
oActiveStandard = oDoc.StylesManager.ActiveStandardStyle

Dim oList As New List(Of String)
For Each oItem In oActiveStandard.PresetScales
	oList.Add(oItem)
Next

Dim oView As DrawingView
oCurrentScale = oDoc.ActiveSheet.DrawingViews.Item(1).ScaleString

Dim oScale As String = InputListBox("Select a scale", _
oList, oCurrentScale, "iLogic", "Standard Scale List")

If String.IsNullOrWhiteSpace(oScale) Then Exit Sub

For Each oView In oDoc.ActiveSheet.DrawingViews
	If oView.ScaleFromBase = False Then
		oView.ScaleString = oScale
	End If
Next


Wednesday, November 16, 2022

iLogic Rule to Update Drawing Resources

 

iLogic Copy Drawing Resources Autodesk Inventor


Issue:
You have drawings that you want to update with a new border, title block, sketch symbol or other Drawing Resource item.

Solution:
Here is a quick iLogic rule to do this.


oBorderName = "My Border"
oTitleBlockName = "My Title Block"
oSymbolName = "My Symbol"

oResourceFile = "C:\Temp\MyDrawingResourceFile.idw"

'open source file
Dim oSourceFile As DrawingDocument
oSourceFile = ThisApplication.Documents.Open(oResourceFile, False)

Dim oDoc As DrawingDocument
oDoc = ThisDoc.Document

'copy the resources from the source file, replace existing
oSourceFile.BorderDefinitions.Item(oBorderName).CopyTo(oDoc, True)
oSourceFile.TitleBlockDefinitions.Item(oTitleBlockName).CopyTo(oDoc, True)
oSourceFile.SketchedSymbolDefinitions.Item(oSymbolName).CopyTo(oDoc, True)

'close source file
oSourceFile.Close(True)




 

Monday, October 10, 2022

Traverse Assembly to Turn Off all Work Features and Sketches with iLogic



Issue:
An update to an older post on this topic:
http://inventortrenches.blogspot.com/2013/03/turn-onoff-all-workfeatures-with-ilogic.html

Solution:
You can use this example iLogic rule to traverse the assembly (and subassemblies) to turn off all work features and sketches.


Sub Main

	Dim oDoc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim oOccs As ComponentOccurrences = oDoc.ComponentDefinition.Occurrences

	Dim sName As String
	sName = oDoc.DisplayName

	'set vis in the top level
	Call SetVis(oDoc, sName)

	Call TraverseAssembly(oOccs)

End Sub

Sub TraverseAssembly(oOccs As ComponentOccurrences)

	Dim oOcc As ComponentOccurrence
	For Each oOcc In oOccs

		Dim oDoc As Document
		oDoc = oOcc.Definition.Document

		Dim sName As String
		sName = oOcc.Name

		'set vis in the component
		Call SetVis(oOcc.Definition.Document, sName)

		'if sub assembly step into it's Occurrences collection
		If oOcc.DefinitionDocumentType = _
				DocumentTypeEnum.kAssemblyDocumentObject Then
			Logger.Info("Stepping into: " & sName)
			
			oSubOccs = oDoc.ComponentDefinition.Occurrences
			Call TraverseAssembly(oSubOccs)
		End If
	Next

End Sub

Sub SetVis(oDoc As Document, sName As String)

	Dim oDef As ComponentDefinition
	oDef = oDoc.ComponentDefinition


	For Each oItem In oDef.Workplanes
		Try
			oItem.visible = False
		Catch
			Logger.Info("Could not set work plane vis for: " & sName)
		End Try
	Next

	For Each oItem In oDef.WorkAxes
		Try
			oItem.visible = False
		Catch
			Logger.Info("Could not set work axis vis for: " & sName)
		End Try
	Next

	For Each oItem In oDef.WorkPoints
		Try
			oItem.visible = False
		Catch
			Logger.Info("Could not set work point vis for: " & sName)
		End Try
	Next

	For Each oItem In oDef.Sketches
		Try
			oItem.visible = False
		Catch
			Logger.Info("Could not set sketch vis for: " & sName)
		End Try
	Next

End Sub

Wednesday, May 18, 2022

iLogic: Custom Sort PartsList with Temporary Column

 



Issue: 

You have a parts list that has a challenging sort criteria, due to needing to sort for values that might or might not exist in the same column. 

In the example above we want to sort the description column based on all items with a mark number (MK) value, and then sort those without a mark number alphabetically.



Solution:

Although we can't accomplish this out of the box, here are 3 code examples to do this that use iLogic and some API calls.


--------------------------------------------------------------
V1: Version to handle single parts list on the active sheet
--------------------------------------------------------------
sSortColumnName = "KEYWORDS"

' Set a reference to the drawing document.
' This assumes a drawing document is active.
Dim oDrawDoc As DrawingDocument
oDrawDoc = ThisApplication.ActiveDocument

' Set a reference to the first parts list on the active sheet.
Dim oPartsList As PartsList
Try
	oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)
Catch
	Return 'exit rule
End Try

Dim oADoc As AssemblyDocument
oADoc = oPartsList.ReferencedDocumentDescriptor.ReferencedDocument
Dim oPropSet As PropertySet
oPropSet = oADoc.PropertySets.Item("Inventor Summary Information")

'add temporary column to the parts list
oID = oPropSet.Item(sSortColumnName).PropId
Try
	oPartsList.PartsListColumns.Add _
	(PropertyTypeEnum.kFileProperty, oPropSet.InternalName, oID)
Catch
End Try

' Iterate through the contents of the parts list.
Dim i As Long
For i = 1 To oPartsList.PartsListRows.Count

	'get the Description value
	oCell = oPartsList.PartsListRows.Item(i).Item("DESCRIPTION")

	'split the string at the comma
	'expecting a string like: 
	'		Bracket, MK B-114
	sArray = Split(oCell.Value, ",")
	sType = sArray(0)

	Try
		sMK = sArray(1)
	Catch 'error when no comma in string
		sMK = ""
	End Try


	'get the temp column cell
	oTempColumnCell = oPartsList.PartsListRows.Item(i).Item(sSortColumnName)

	'write to temp column
	If sMK.Contains("MK") Then
		'strip off the MK
		sMK = Replace(sMK, "MK ", "")
		oTempColumnCell.Value = sMK
	Else
		oTempColumnCell.Value = sType
	End If
Next

'sort and renumber
oPartsList.Sort(sSortColumnName)
oPartsList.Renumber
'remove temp column
oPartsList.PartsListColumns(sSortColumnName).remove

--------------------------------------------------------------
V2: Version for multiple sheets
--------------------------------------------------------------
sSortColumnName = "KEYWORDS"

' Set a reference to the drawing document.
' This assumes a drawing document is active.
Dim oDrawDoc As DrawingDocument
oDrawDoc = ThisApplication.ActiveDocument

Dim oCurrentSheet As Sheet
oCurrentSheet = oDrawDoc.ActiveSheet

Dim oSheet As Sheet
For Each oSheet In oDrawDoc.Sheets
	oSheet.Activate

	' Set a reference to the first parts list on the active sheet.
	Dim oPartsList As PartsList
	Try
		oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)
	Catch
		Return 'exit rule
	End Try

	Dim oADoc As AssemblyDocument
	oADoc = oPartsList.ReferencedDocumentDescriptor.ReferencedDocument
	Dim oPropSet As PropertySet
	oPropSet = oADoc.PropertySets.Item("Inventor Summary Information")

	'add temporary column to the parts list
	oID = oPropSet.Item(sSortColumnName).PropId
	Try
		oPartsList.PartsListColumns.Add _
		(PropertyTypeEnum.kFileProperty, oPropSet.InternalName, oID)
	Catch
	End Try

	' Iterate through the contents of the parts list.
	Dim i As Long
	For i = 1 To oPartsList.PartsListRows.Count

		'get the Description value
		oCell = oPartsList.PartsListRows.Item(i).Item("DESCRIPTION")

		'split the string at the comma
		'expecting a string like: 
		'		Bracket, MK B-114
		sArray = Split(oCell.Value, ",")
		sType = sArray(0)

		Try
			sMK = sArray(1)
		Catch 'error when no comma in string
			sMK = ""
		End Try


		'get the temp column cell
		oTempColumnCell = oPartsList.PartsListRows.Item(i).Item(sSortColumnName)

		'write to temp column
		If sMK.Contains("MK") Then
			'strip off the MK
			sMK = Replace(sMK, "MK ", "")
			oTempColumnCell.Value = sMK
		Else
			oTempColumnCell.Value = sType
		End If
	Next

	'sort and renumber
	oPartsList.Sort(sSortColumnName)
	oPartsList.Renumber
	'remove temp column
	oPartsList.PartsListColumns(sSortColumnName).Remove
Next
oCurrentSheet.activate
InventorVb.DocumentUpdate()



--------------------------------------------------------------
V3: Version for multiple parts list on the active sheet
--------------------------------------------------------------
sSortColumnName = "KEYWORDS"

' Set a reference to the drawing document.
' This assumes a drawing document is active.
Dim oDrawDoc As DrawingDocument
oDrawDoc = ThisApplication.ActiveDocument

Dim oPartsList As PartsList = ThisApplication.CommandManager.Pick _
(SelectionFilterEnum.kDrawingPartsListFilter, "Select a Parts List to sort.")

If oPartsList Is Nothing Then Return 'exit rule

Dim oADoc As AssemblyDocument
oADoc = oPartsList.ReferencedDocumentDescriptor.ReferencedDocument
Dim oPropSet As PropertySet
oPropSet = oADoc.PropertySets.Item("Inventor Summary Information")

'add temporary column to the parts list
oID = oPropSet.Item(sSortColumnName).PropId
Try
	oPartsList.PartsListColumns.Add _
	(PropertyTypeEnum.kFileProperty, oPropSet.InternalName, oID)
Catch
End Try

' Iterate through the contents of the parts list.
Dim i As Long
For i = 1 To oPartsList.PartsListRows.Count

	'get the Description value
	oCell = oPartsList.PartsListRows.Item(i).Item("DESCRIPTION")

	'split the string at the comma
	'expecting a string like: 
	'		Bracket, MK B-114
	sArray = Split(oCell.Value, ",")
	sType = sArray(0)

	Try
		sMK = sArray(1)
	Catch 'error when no comma in string
		sMK = ""
	End Try


	'get the temp column cell
	oTempColumnCell = oPartsList.PartsListRows.Item(i).Item(sSortColumnName)

	'write to temp column
	If sMK.Contains("MK") Then
		'strip off the MK
		sMK = Replace(sMK, "MK ", "")
		oTempColumnCell.Value = sMK
	Else
		oTempColumnCell.Value = sType
	End If
Next

'sort and renumber
oPartsList.Sort(sSortColumnName)
oPartsList.Renumber
'remove temp column
oPartsList.PartsListColumns(sSortColumnName).Remove

InventorVb.DocumentUpdate()

Tuesday, March 29, 2022

Inventor API: using UnitsOfMeasure.ConvertUnits

Issue:

You're writing a bit of code that might be used in Inventor documents of varying unit types. For instance maybe this code is sometimes used in inch based parts, other times it's used in millimeter based parts, and sometime centimeter based parts. Or maybe the part has some dimensions entered in inches and some entered in millimeters. In any case you want your code to handle all of this.


Recall that when we work with the API, inventor returns values in its internal units, which is always centimeters. So we often need to have our code apply a conversion factor. 

Because of this you want the code to detect the units and do the conversion automatically.

Note:
If we're working with straight iLogic and no API calls, then the conversion is *often* handled for us internally in the iLogic function.    

*I won't say always*


Solution:
Below is a quick example that you can use to do the units detection and conversion in your code.

Here is the basic function. It uses the document's length units and centimeters to determine the conversion factor, and displays this in a message box to return the conversion factor.


Dim oUOM As UnitsOfMeasure
oUOM = ThisDoc.Document.UnitsOfMeasure
oLenUnits = oUOM.GetStringFromType(UnitsTypeEnum.kDefaultDisplayLengthUnits)
oInvUnits = UnitsTypeEnum.kCentimeterLengthUnits
oInvUnitString = oUOM.GetStringFromType(oInvUnits)
oConversion = oUOM.ConvertUnits(1, oUOM.LengthUnits, oInvUnits)

MsgBox("Document Units = " & oLenUnits & vbLf & _
	"Inventor Internal Units = " & oInvUnitString & vbLf & _
	"Conversion factor = " & oConversion, , "Inventor")





And here is a quick example using it to return the value of a selected sketch dimension.
This part is set to inches (Tools tab > Document Setting button > Units tab > Length setting)



Here a sketch dimension/parameter named length is set to 70 mm, even though the part file is using Inches. And because our code is using the API to get the parameter value, we know that it's going to be returned in centimeters. 








Without the conversion factor, the code returns 7, which is the value in Inventor's internal units of centimeters.










So we use the UnitsOfMeasure.ConvertUnits function to handle all of this and return the expected value in the document units. 






With the conversion code, it returns 2.756, which is the value in inches.


Here's the working example:
Dim oUOM As UnitsOfMeasure
oUOM = ThisDoc.Document.UnitsOfMeasure
oConversion = oUOM.ConvertUnits(1, oUOM.LengthUnits, _
				UnitsTypeEnum.kCentimeterLengthUnits)

oMsg = "Select a sketch dimension(Press Esc to continue)"

While True
	Dim oDimension As DimensionConstraint
	oDimension = ThisApplication.CommandManager.Pick(
	SelectionFilterEnum.kSketchDimConstraintFilter, oMsg)
	
	' If nothing gets selected then we're done	
	If IsNothing(oDimension) Then Exit While
	oParam = oDimension.Parameter	
	oParamVal = Round(oParam.Value() / oConversion, 3)
	
	MsgBox(oParamVal,,"Inventor")	
End While