Ilogic equivalent of move a constraint from one instance of a part to another instance of the same part

Ilogic equivalent of move a constraint from one instance of a part to another instance of the same part

briant.markham
Enthusiast Enthusiast
334 Views
4 Replies
Message 1 of 5

Ilogic equivalent of move a constraint from one instance of a part to another instance of the same part

briant.markham
Enthusiast
Enthusiast

What is the ilogic equivalent of editing a constraint on part1 instance 1 unselecting #1 and then reselecting the same face or edge on part1 instance 2 of the same part and hitting ok?

0 Likes
335 Views
4 Replies
Replies (4)
Message 2 of 5

J-Camper
Advisor
Advisor

@briant.markham,

 

All of the properties related to occurrences/entities/geometries for AssemblyConstraints are read only.  I think the only way to make this work is making a new constraint and deleting the old one.  This would heavily rely on the parts being constrained by origin planes/axes or the the component occurrences are truly the same document.  Here is what I'm thinking:

 

Sub Main
	Dim aDoc As AssemblyDocument = TryCast(ThisApplication.ActiveDocument, AssemblyDocument)
	If IsNothing(aDoc) Then Logger.Debug("Not Run In Assembly Document") : Exit Sub
		
	Dim DonorComponent As ComponentOccurrence = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Donor Occurrence")
	If IsNothing(DonorComponent) Then Logger.Debug("Component Occurrence Not Selected") : Exit Sub ' If nothing gets selected then we're done
	
	Dim MatchingOccurrences As ComponentOccurrencesEnumerator = aDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(DonorComponent.Definition.Document)
	If MatchingOccurrences.Count < 2 Then Logger.Debug("This rule will only work if there are multiple instances of the same document in this assembly") : Exit Sub
	
	Dim availableOccurrences As New List(Of ComponentOccurrence)
	
	For Each CollectedComponent As ComponentOccurrence In MatchingOccurrences
		If CollectedComponent Is DonorComponent Then Continue For
		availableOccurrences.Add(CollectedComponent)
	Next
	
	Dim TargetComponent As ComponentOccurrence
	
	If availableOccurrences.Count = 1 
		TargetComponent = availableOccurrences.Item(0)
	Else If availableOccurrences.Count > 1
		TargetComponent = GetComponentFromList(availableOccurrences)
	End If
	
	If IsNothing(TargetComponent) Then Logger.Debug("Target Component Occurrence Not Found") : Exit Sub ' If nothing gets selected then we're done
		
	If FreedomDegrees(TargetComponent) < 3 
		Answer = MessageBox.Show(TargetComponent.Name & " already has constraints, which restrict it's freedom.  Adding more may result in error.  Would you like to continue without deleting constraints?", "Possiblitity of Error",MessageBoxButtons.YesNoCancel)
		If Answer <> vbYes Then Logger.Debug("Terminating rule for now, because target occurrence has restricted freedom.") : Exit Sub
	End If
	
	Call TransferConstraints(aDoc, DonorComponent, TargetComponent)
		
End Sub

Sub TransferConstraints(ActiveAssembly As AssemblyDocument, SourceComponent As ComponentOccurrence, DestinationComponent As ComponentOccurrence)
	
	Dim transMan As TransactionManager = ThisApplication.TransactionManager
	Dim oTrans As Transaction = transMan.StartTransaction(ActiveAssembly, "TransferConstraints")
	On Error GoTo Errrr
	
	Dim holdTransform As Matrix = DestinationComponent.Transformation
	DestinationComponent.Transformation = SourceComponent.Transformation
	
	Dim copyName As String
	
	For Each currentConstraint As AssemblyConstraint In SourceComponent.Constraints
		Dim renamed As Boolean = Not currentConstraint.IsDefaultName
		If renamed Then copyName = currentConstraint.Name Else copyName = Nothing
		
		Select Case currentConstraint.Type
			
			Case ObjectTypeEnum.kMateConstraintObject
				EntityOne = currentConstraint.EntityOne
				EntityTwo = currentConstraint.EntityTwo
				Offset = currentConstraint.Offset.Value
				EntityOneInference = currentConstraint.EntityOneInferredType
				EntityTwoInference = currentConstraint.EntityTwoInferredType
				
				If currentConstraint.OccurrenceOne Is SourceComponent
					DestinationComponent.CreateGeometryProxy(EntityOne.NativeObject, tempObject)
					EntityOne = tempObject
				Else
					DestinationComponent.CreateGeometryProxy(EntityTwo.NativeObject, tempObject)
					EntityTwo = tempObject
				End If
				
				newConstraint = ActiveAssembly.ComponentDefinition.Constraints.AddMateConstraint(EntityOne, EntityTwo, Offset, EntityOneInference, EntityTwoInference)
				currentConstraint.Delete()
				If Not IsNothing(copyName) Then newConstraint.Name = copyName
					
				transMan.SetCheckPoint 'set checkpoints if desired, so not all work is lost
			
			Case ObjectTypeEnum.kFlushConstraintObject
				EntityOne = currentConstraint.EntityOne
				EntityTwo = currentConstraint.EntityTwo
				Offset = currentConstraint.Offset.Value
				
				If currentConstraint.OccurrenceOne Is SourceComponent
					DestinationComponent.CreateGeometryProxy(EntityOne.NativeObject, tempObject)
					EntityOne = tempObject
				Else
					DestinationComponent.CreateGeometryProxy(EntityTwo.NativeObject, tempObject)
					EntityTwo = tempObject
				End If
								
				newConstraint = ActiveAssembly.ComponentDefinition.Constraints.AddFlushConstraint(EntityOne, EntityTwo, Offset)
				currentConstraint.Delete()
				If Not IsNothing(copyName) Then newConstraint.Name = copyName
				
				transMan.SetCheckPoint 'set checkpoints if desired, so not all work is lost
					
			Case ObjectTypeEnum.kAngleConstraintObject	
				EntityOne = currentConstraint.EntityOne
				EntityTwo = currentConstraint.EntityTwo
				Angle = currentConstraint.Angle.Value
				SolutionType = currentConstraint.SolutionType
				ReferenceVectorEntity = currentConstraint.ReferenceVectorEntity
				
				If currentConstraint.OccurrenceOne Is SourceComponent
					DestinationComponent.CreateGeometryProxy(EntityOne.NativeObject, tempObject)
					EntityOne = tempObject
				Else
					DestinationComponent.CreateGeometryProxy(EntityTwo.NativeObject, tempObject)
					EntityTwo = tempObject
				End If
				
				newConstraint = ActiveAssembly.ComponentDefinition.Constraints.AddAngleConstraint(EntityOne, EntityTwo, Angle, SolutionType, ReferenceVectorEntity)
				currentConstraint.Delete()
				If Not IsNothing(copyName) Then newConstraint.Name = copyName
				
				transMan.SetCheckPoint 'set checkpoints if desired, so not all work is lost
				
			Case Else
				Logger.Debug(CType(currentConstraint.Type, ObjectTypeEnum).ToString & " has not been programmed")
		End Select
	Next
	
	SourceComponent.Transformation = holdTransform
	
	oTrans.End 'Typical transaction end
	
	Exit Sub 'Finish the Sub routine before Error Handling code
Errrr :
	Logger.Debug("Error in: " & transMan.CurrentTransaction.DisplayName)
	If transMan.CurrentTransaction.CheckPoints.Count < 1 Then Logger.Debug("Aborted: " & transMan.CurrentTransaction.DisplayName) : transMan.CurrentTransaction.Abort 
	transMan.GoToCheckPoint(transMan.CurrentTransaction.CheckPoints.Item(transMan.CurrentTransaction.CheckPoints.Count))
	transMan.CurrentTransaction.End
	
End Sub

Function GetComponentFromList(allOccurrences As List(Of ComponentOccurrence))
	Dim NamesList As New List(Of String)
	
	For Each comp As ComponentOccurrence In allOccurrences
		NamesList.Add(comp.Name)
	Next
	
	UserSelected = InputListBox("Select an occurrnence to recieve constraints:", NamesList, NamesList.Item(0), Title := "Target Occurrence", ListName := "Available Occurrences")
	
	For Each comp As ComponentOccurrence In allOccurrences
		If comp.Name = UserSelected Then Return comp
	Next
	
	Return Nothing
	
End Function

Function FreedomDegrees(co As ComponentOccurrence) As Long
	
	Dim OutputLong(1) As Long
	Dim TranslationVectors As ObjectsEnumerator
	Dim RotationVectors As ObjectsEnumerator
	Dim DOFpoint As Point
	
	Call co.GetDegreesOfFreedom(OutputLong(0), TranslationVectors, OutputLong(1), RotationVectors, DOFpoint) 
	Result = OutputLong(0)
	Return Result
	
End Function

 

Since Constraints have different options between them, I think you would need to program in a case for each intended Constraint type.  This also assumes no imates/joints/grounded relationships will be swapped.

 

Let me know if you have any questions, or if this is not working as intended.

 

 

 

 

Message 3 of 5

briant.markham
Enthusiast
Enthusiast

As far as I tell that worked like a charm, I'm going to dig into it on Monday. I appreciated your help greatly. Thanks

0 Likes
Message 4 of 5

WCrihfield
Mentor
Mentor

Just so you know, even though the properties of the AssemblyConstraint object are ReadOnly, you can use the Methods for conversion to 'edit' existing constraint.  Just use the method for conversion that matches the type of constraint you are already working with, so it will not actually change the constraint type.  It mentions this little detail right in the online help documentation for those methods listed under the AssemblyConstraint object.  But to use this, you must know the more specific Type of constraint you are actually working with.  On that same web page for the AssemblyConstraint it tells you that the AssemblyConstraint object is a 'base class', and if you scroll down the page you can see a list of the more specific types (derived classes) that are derived from this base type.  For instance, you can only get to the Parameter controlling the offset/angle/distance/ratio part of a constraint though its more specific type.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 5

J-Camper
Advisor
Advisor

I didn't even think to use the convert methods that way. 

 

I think that will let you replace the Create/Delete combo in favor of matching convert methods.  The rest of the framework should allow for that change.

0 Likes