@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.