cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Button To Duplicate Controlled Component Rotation After Insertion

Button To Duplicate Controlled Component Rotation After Insertion

I want a built-in tool button that will replicate the same (or much better) functionality as when you have chosen a component to insert into an assembly, then you right-click just before placing it (as seen in the image below).  But this tool button can be used later, after you have already placed the component into the assembly (such as if you copy / pasted it in, or drag & dropped it in, missing out on this behavior).

WCrihfield_0-1710441921460.png

So, I want to be able to pre-select an unconstrained component, or click the button to start the command, then select the component, then have these options readily available to quickly rotate the component around any of its axes.  Having more options than just 90 degree rotations would be great too.  I know we can use the 'Free Rotate' command, but that is 'free', so it does not allow precise rotation by a set amount of degrees, and does not allow you to choose one of the component's own axes to control its rotation by.  That component insertion behavior is super useful, but sometimes I copy and paste a bunch of components into an assembly quickly or I drag and drop multiple components into the assembly directly from a file browser screen.  In those cases, this functionality is 'missed' (does not happen automatically for each one as they are added).  Most of the time my components are already 'squarely' aligned with the assembly's coordinate system, just not always originally designed to already be in the perfect orientation for inserting into every assembly I might use it in.  A tool like this would be super helpful and increase work flow greatly.  Maybe add a several other component orientation related options into the right-click menu while that command is active too, as this tool develops further over time.

 

3 Comments

I think this may be a development of the Free Rotation tool.

WCrihfield
Mentor

If they did further develop the Free Rotate tool to add this additional functionality / behavior, that would be fine with me.  I just want to be able to initiate this mode / behavior / functionality after the component has already been placed into the assembly, one way or another.  Even if they did have to make a new tool though, and it did not have a visible button on the ribbon to start with, but was only available as an option within the right-click menu when an unconstrained component was selected in an assembly, that would still be at least a good start.

WCrihfield
Mentor

Just wanted to post an external iLogic rule based solution that I created for enabling this behavior at the click of a button.  It would be nice if we could just attach a text file, because that would be simpler & cleaner, but since we can not, I will copy / paste it into a code window below, so that others can copy / paste it into their own external rule for local use.

 

This could probably be put into an Inventor Add-In also, with a custom button in the assembly environment, on the View tab, or wherever you want.

 

In the early stages of development, I was showing an InputListBox for rotation axis selection, then another InputListBox for choosing an angle to rotate it, and a follow-up question to ask if they wanted to rotate it again.  That was more cumbersome than I wanted it to be, so I switched to using a MiniToolbar with labels and Buttons for rotating around specific axes by 90 degrees at a time, which was far smoother.  It also shows the 'UCS Triad' at the component's origin, aligned with the origin's own origin geometry, as a visual aid, to make choosing the correct axis simple.   I know that I could have used the radial marking menu, and may still create an alternate version for that, but this works just fine for me, and is super convenient, so I use it all the time.

'overall code originally developed by Wesley Crihfield
'and originally posted publicly on the Inventor Ideas forum on June 4, 2025.
'https://forums.autodesk.com/t5/inventor-ideas/button-to-duplicate-controlled-component-rotation-after/idi-p/12641371
Sub Main
	oApp = ThisApplication
	'set value of shared variable
	oTG = oApp.TransientGeometry
	Dim oDoc As Inventor.Document = oApp.ActiveDocument
	'<<< try to get any 'pre-selected' components
	oOccs = oDoc.SelectSet.OfType(Of Inventor.ComponentOccurrence).ToList()
	If oOccs Is Nothing OrElse oOccs.Count = 0 Then
		'initialize the List for storing selected components (shared variable)
		oOccs = New List(Of Inventor.ComponentOccurrence)
		Dim oCM As Inventor.CommandManager = oApp.CommandManager
		Dim oPickedOcc As Inventor.ComponentOccurrence = Nothing
		Dim oFilter = SelectionFilterEnum.kAssemblyOccurrenceFilter
		Dim sPrompt As String = "Select component to rotate - or press ESC key to exit."
		Do
			oPickedOcc = Nothing
			oPickedOcc = oCM.Pick(oFilter, sPrompt)
			If oPickedOcc IsNot Nothing Then oOccs.Add(oPickedOcc)
		Loop Until oPickedOcc Is Nothing
	End If
	If oOccs Is Nothing OrElse oOccs.Count = 0 Then Return
	'<<< END OF SELECTION PROCESS>>>

	'start a Transaction to record component rotation actions, so we can use UNDO on them
	Dim oTrans As Inventor.Transaction
	oTrans = oApp.TransactionManager.StartTransaction(oDoc, "Rotate Component (iLogic)")
	'<<< create temporary assembly level UCSs at component origins as visual aid
	'this help user know which axis to rotate it around
	Dim oUCSs As UserCoordinateSystems = oDoc.ComponentDefinition.UserCoordinateSystems
	Dim oTempUCSs As New List(Of Inventor.UserCoordinateSystem)
	For Each oOcc As Inventor.ComponentOccurrence In oOccs
		Dim oUCSDef As UserCoordinateSystemDefinition = oUCSs.CreateDefinition()
		oUCSDef.Transformation = oOcc.Transformation
		Dim oUCS As UserCoordinateSystem = oUCSs.Add(oUCSDef)
		oTempUCSs.Add(oUCS)
	Next oOcc
	oApp.ActiveView.Update()
	
	'<<< create New instance of custom Class helper
	oMTBUtil = New MiniToolbarUtil(oApp)
	'<<< set which component(s) for it to act upon
	oMTBUtil.ComponentsToRotate = oOccs
	'<<< set what action (code routine) to do to each of them
	oMTBUtil.DelegateRoutineReference = AddressOf RotateComponent
	'<<< initialize its user interface helper (a MiniToolbar)
	oMTBUtil.InitializeMiniToolbar()
	
	'<<< wait for user to finish using the custom Class MiniToobar helper
	Do
		oApp.UserInterfaceManager.DoEvents()
	Loop Until oMTBUtil.CanceledOrDone
	'<<< delete temporary UCSs >>>
	For Each oTempUCS As Inventor.UserCoordinateSystem In oTempUCSs
		oTempUCS.Delete(False, False)
	Next
	'<<< release reference to custom Class helper >>>
	oMTBUtil = Nothing
	'<<< end the Transaction >>>
	oTrans.End()
End Sub

Dim oApp As Inventor.Application
Dim oTG As Inventor.TransientGeometry
Public oOccs As List(Of Inventor.ComponentOccurrence)
'Dim oIE As Inventor.InteractionEvents
Dim oMTBUtil As MiniToolbarUtil

Public Sub RotateComponent(oOcc As Inventor.ComponentOccurrence, _
	cAxisLetter As Char, _
	dAngleInDegrees As Double)
	If oOcc Is Nothing Then
		Logger.Debug("No component supplied to 'RotateComponent' method!")
		Return
	End If
	If cAxisLetter = vbNullChar OrElse (Not Char.IsLetter(cAxisLetter)) Then
		Logger.Debug("Axis Letter not supplied, or not recognized in 'RotateComponent' method!")
		Return
	End If
	Dim oTG As Inventor.TransientGeometry = oOcc.Application.TransientGeometry
	Dim oMatrix As Inventor.Matrix = oOcc.Transformation
	Dim oPt As Inventor.Point, oXAxis, oYAxis, oZAxis As Inventor.Vector
	oMatrix.GetCoordinateSystem(oPt, oXAxis, oYAxis, oZAxis)
	Dim oRotationAxis As Inventor.Vector = Nothing
	If cAxisLetter = "X" OrElse cAxisLetter = "x" Then
		oRotationAxis = oXAxis
	ElseIf cAxisLetter = "Y" OrElse cAxisLetter = "y" Then
		oRotationAxis = oYAxis
	ElseIf cAxisLetter = "Z" OrElse cAxisLetter = "z" Then
		oRotationAxis = oZAxis
	End If
	If oRotationAxis Is Nothing Then
		Logger.Debug("Rotation Axis could not be determined for 'RotateComponent' method!")
		Return
	End If
	Dim oNewMatrix As Inventor.Matrix = oTG.CreateMatrix()
	Dim dAngleInRadians As Double = (dAngleInDegrees * (Math.PI / 180))
	oNewMatrix.SetToRotation(dAngleInRadians, oRotationAxis, oPt)
	oMatrix.TransformBy(oNewMatrix)
	Try
		oOcc.Transformation = oMatrix
	Catch oEx As Exception
		Logger.Error("RotateComponent method failed to rotate component!" _
		& vbCrLf & oEx.Message & vbCrLf & oEx.StackTrace)
	End Try
End Sub

Class MiniToolbarUtil
	
	Private _InvApp As Inventor.Application
	'Private _CDs As Inventor.ControlDefinitions
	'Private _RotateX90, _RotateY90, _RotateZ90 As ControlDefinition
	Private _Finished As Boolean
	Private WithEvents _MTB As Inventor.MiniToolbar
	Private WithEvents oOKBtn As Inventor.MiniToolbarButton
	Private WithEvents oCancelBtn As Inventor.MiniToolbarButton
	Private WithEvents oOptionsDropDown As Inventor.MiniToolbarDropdown
	Private WithEvents oXRotateBtn As Inventor.MiniToolbarButton
	Private WithEvents oYRotateBtn As Inventor.MiniToolbarButton
	Private WithEvents oZRotateBtn As Inventor.MiniToolbarButton
	Public ComponentsToRotate As List(Of Inventor.ComponentOccurrence)
	Public DelegateRoutineReference As Action(Of Inventor.ComponentOccurrence, String, Double)
	'Private _Logger As IRuleLogger
	
	Public Sub New(InventorApp As Inventor.Application)
		_InvApp = InventorApp
		'_Logger = iLogicRuleLogger
		'_CDs = _InvApp.CommandManager.ControlDefinitions
		'_RotateX90 = _CDs.Item("AssemblyPlaceCompRotateX90Cmd")
		'_RotateY90 = _CDs.Item("AssemblyPlaceCompRotateY90Cmd")
		'_RotateZ90 = _CDs.Item("AssemblyPlaceCompRotateZ90Cmd")
	End Sub
	
	Public Property CanceledOrDone As Boolean
		Get
			Return _Finished
		End Get
		Set
			_Finished = value
		End Set
	End Property
	
	Public Sub InitializeMiniToolbar()
		_MTB = _InvApp.CommandManager.CreateMiniToolbar()
		_Finished = False
		_MTB.ShowHandle = True
		_MTB.EnableOK = True
		_MTB.EnableApply = False
		_MTB.ShowApply = False
		_MTB.ShowCancel = True
		
		Dim oCtrls As MiniToolbarControls = _MTB.Controls
		
		'oOKBtn = oCtrls.Item("Common_Ok")
		'oCancelBtn = oCtrls.Item("Common_Cancel")
		'oOptionsDropDown = oCtrls.Item("MTB_Options")

		oXRotateBtn = oCtrls.AddButton("Rotate 90 Deg. Around X-Axis Button", "Rotate Around X", "Rotate 90 Deg. Around X-Axis")
		oXRotateBtn.Enabled = True
		oXRotateBtn.Visible = True
		
		oYRotateBtn = oCtrls.AddButton("Rotate 90 Deg. Around Y-Axis Button", "Rotate Around Y", "Rotate 90 Deg. Around Y-Axis")
		oYRotateBtn.Enabled = True
		oYRotateBtn.Visible = True
		
		oZRotateBtn = oCtrls.AddButton("Rotate 90 Deg. Around Z-Axis Button", "Rotate Around Z", "Rotate 90 Deg. Around Z-Axis")
		oZRotateBtn.Enabled = True
		oZRotateBtn.Visible = True
		
		_MTB.Visible = True
	End Sub

	Private Sub oXRotateBtn_OnClick() Handles oXRotateBtn.OnClick
		If _bFinished Then
			Me.CanceledOrDone = True
			MiniToolbar_OnCancel()
		End If
		'_RotateX90.Execute()
		For Each oOcc As Inventor.ComponentOccurrence In ComponentsToRotate
			DelegateRoutineReference(oOcc, "X", 90)
		Next
	End Sub
	
	Private Sub oYRotateBtn_OnClick() Handles oYRotateBtn.OnClick
		If _bFinished Then
			Me.CanceledOrDone = True
			MiniToolbar_OnCancel()
		End If
		'_RotateY90.Execute()
		For Each oOcc As Inventor.ComponentOccurrence In ComponentsToRotate
			DelegateRoutineReference(oOcc, "Y", 90)
		Next
	End Sub
	
	Private Sub oZRotateBtn_OnClick() Handles oZRotateBtn.OnClick
		If _bFinished Then
			Me.CanceledOrDone = True
			MiniToolbar_OnCancel()
		End If
		'_RotateZ90.Execute()
		For Each oOcc As Inventor.ComponentOccurrence In ComponentsToRotate
			DelegateRoutineReference(oOcc, "Z", 90)
		Next
	End Sub
	
	Private Sub MiniToolbar_OnOK() Handles _MTB.OnOK
		DisposeMiniToolbar()
	End Sub

	Private Sub MiniToolbar_OnCancel() Handles _MTB.OnCancel
		DisposeMiniToolbar()
	End Sub
	
	Private Sub DisposeMiniToolbar()
		_bFinished = True
		Me.CanceledOrDone = True
		_MTB.Delete()
	End Sub
End Class

Below are a couple screenshots to show the visual difference.  The first image was taken while using the 'Add Component' command, after file selection, but before clicking to place the component, when I right-click, showing the commands available within that radial marking menu.

Place Component - UCS Part - Radial Marking Menu - Component Rotation Tools.png

Next is a screenshot taken after the component has been 'drag & drop' added, then my tool has been started, the that component has been selected.  It shows the same 'UCS Triad' as the built-in method, but uses a MiniToolbar to present the 3 options for rotating the component.

Place Component - UCS Part - MiniToolbar Component Rotation Tool.png

Can't find what you're looking for? Ask the community or share your knowledge.

Submit Idea