Having trouble converting a VBA Macro into iLogic

Having trouble converting a VBA Macro into iLogic

They_Call_Me_Jake
Advocate Advocate
1,450 Views
9 Replies
Message 1 of 10

Having trouble converting a VBA Macro into iLogic

They_Call_Me_Jake
Advocate
Advocate

I found code that I want to use but it is a VBA Macro and I need to use it in ilogic. It copies a component in an assembly and duplicates it along with it's constraints. I was able to do 90% of the conversion and it saves fine but it errors out when I try to run it. Can someone help me. Here is the code I adjusted.

Sub Main()
	Call DupeSelectionWithConstraints()
End Sub

Private oNewlyInsertedColl As Collection
Private oOriginalItemColl As Collection

Sub DupeSelectionWithConstraints()
    If ThisApplication.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then MsgBox ("Rule not valid for non-assembly files!"): Exit Sub
    
    Dim oDoc As AssemblyDocument = ThisApplication.ActiveDocument
    
    Dim oSS As SelectSet = oDoc.SelectSet
    
    If oSS.Count < 1 Then MsgBox ("Rule Requires a Select Set!"): Exit Sub
    
    Call DuplicateSS(oDoc, oSS)
End Sub


Private Sub DuplicateSS(oParentDoc As Document, oSS As SelectSet)
    Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
    
    oPasteMatrix = oTG.CreateMatrix()
    
    oOriginalItemColl = New Collection
    oNewlyInsertedColl = New Collection
    
    For Each oItem In oSS
        oPasteMatrix = oItem.Transformation
        oNewOcc = oParentDoc.ComponentDefinition.Occurrences.Add(oItem.Definition.Document.FullDocumentName, oPasteMatrix)
        oOriginalItemColl.Add(oItem)
        oNewlyInsertedColl.Add(oNewOcc)
    Next
    
    Dim oTestoOcc1 As Object
    Dim oTestoOcc2 As Object
    
    Dim oOcc1 As ComponentOccurrence
    Dim oOcc2 As ComponentOccurrence
    
    Dim oEntityOne As Object
    Dim oEntityTwo As Object
    
    For Each oConstraint In oParentDoc.ComponentDefinition.Constraints
    'Grab entities for new constraint to create
            oTestoOcc1 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceOne)
            oTestoOcc2 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceTwo)
            
            If oTestoOcc1 Is Nothing And oTestoOcc2 Is Nothing Then GoTo NextConstraint
            
            If oTestoOcc1 Is Nothing Then
                oEntityOne = oConstraint.EntityOne
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc1.Definition Then
                        oOcc1 = oPossibleOcc
                    End If
                Next
                Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)
            End If
            
            If oTestoOcc2 Is Nothing Then
                oEntityTwo = oConstraint.EntityTwo
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc2.Definition Then
                        oOcc2 = oPossibleOcc
                    End If
                Next
                Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
            End If
        'End Grab entities
        
        
        'Check type of constraint
        Select Case oConstraint.Type
            Case 100665088 'kAngleConstraintObject
                'oParentDoc.Constraints.AddAngleConstraint(EntityOne As Object,
                '                                          EntityTwo As Object,
                '                                          Angle As Variant,
                '                                          [SolutionType] As AngleConstraintSolutionTypeEnum,
                '                                          [ReferenceVectorEntity] As Variant,
                '                                          [BiasPointOne] As Variant,
                '                                          [BiasPointTwo] As Variant )
                '                                      As AngleConstraint
                Call oParentDoc.ComponentDefinition.Constraints.AddAngleConstraint(oEntityOne, oEntityTwo, oConstraint.Angle, oConstraint.SolutionType, oConstraint.ReferenceVectorEntity)
                
            Case 100707840 'kAssemblySymmetryConstraintObject
                'oParentDoc.AddSymmetryConstraint( EntityOne As Object,
                '                                  EntityTwo As Object,
                '                                  SymmetryPlane As Object,
                '                                  [EntityOneInferredType] As InferredTypeEnum,
                '                                  [EntityTwoInferredType] As InferredTypeEnum,
                '                                  [NormalsOpposed] As Boolean )
                '                                 As AssemblySymmetryConstraint
                Call oParentDoc.ComponentDefinition.Constraints.AddSymmetryConstraint(oEntityOne, oEntityTwo, oConstraint.SymmetryPlane, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType, oConstraint.NormalsOpposed)
                
            Case 100666368 'kFlushConstraintObject
                'oParentDoc.AddFlushConstraint( EntityOne As Object,
                '                               EntityTwo As Object,
                '                               Offset As Variant,
                '                               [BiasPointOne] As Variant,
                '                               [BiasPointTwo] As Variant )
                '                            As FlushConstraint
                Call oParentDoc.ComponentDefinition.Constraints.AddFlushConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression)
                
                
            Case 100665344 'kInsertConstraintObject
                'oParentDoc.AddInsertConstraint( EntityOne As Object,
                '                                EntityTwo As Object,
                '                                AxesOpposed As Boolean,
                '                                Distance As Variant,
                '                                [BiasPointOne] As Variant,
                '                                [BiasPointTwo] As Variant )
                '                             As InsertConstraint
                Call oParentDoc.ComponentDefinition.Constraints.AddInsertConstraint(oEntityOne, oEntityTwo, oConstraint.AxesOpposed, oConstraint.Distance.Expression)
                
            Case 100665856 'kMateConstraintObject
                'oParentDoc.AddMateConstraint( EntityOne As Object,
                '                               EntityTwo As Object,
                '                               Offset As Variant,
                '                               [EntityOneInferredType] As InferredTypeEnum,
                '                               [EntityTwoInferredType] As InferredTypeEnum,
                '                               [BiasPointOne] As Variant,
                '                               [BiasPointTwo] As Variant )
                '                             As MateConstraint
                Call oParentDoc.ComponentDefinition.Constraints.AddMateConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType)
                
            Case 100665600 'kTangentConstraintObject
                '.AddTangentConstraint( EntityOne As Object,
                '                       EntityTwo As Object,
                '                       InsideTangency As Boolean,
                '                       Offset As Variant,
                '                       [BiasPointOne] As Variant,
                '                       [BiasPointTwo] As Variant )
                '                     As TangentConstraint
                Call oParentDoc.ComponentDefinition.Constraints.AddTangentConstraint(oEntityOne, oEntityTwo, oConstraint.InsideTangency, oConstraint.Offset.Expression)
            
        End Select
NextConstraint:
    Next 'constraint
    
    
End Sub

Private Function GrabObjectFromColl(ByVal oColl As Collection, ByVal oObj As Object) As Object
    For Each oItem In oColl
        If oItem Is oObj Then
            GrabObjectFromColl = oObj
            Exit Function
        End If
    Next
    GrabObjectFromColl = Nothing
End Function

Private Function GetProxy(ByRef Prxy As Object, ByRef ContOcc As ComponentOccurrence) As Object
    Dim TempPrxy As Object
    Dim Occ As Object
    If Prxy.ContainingOccurrence.Type = kComponentOccurrenceObject Then
        Occ = ContOcc
    Else
        On Error Resume Next
            Occ = ContOcc.Definition.Occurrences.ItemByName(Prxy.ContainingOccurrence.Name)
            
        If Err.Number <> 0 Then
            On Error GoTo 0
            TempPrxy = Prxy.ContainingOccurrence
            Call ContOcc.CreateGeometryProxy(GetProxy(TempPrxy, ContOcc), Occ)
        End If
    End If
    Call Occ.CreateGeometryProxy(Prxy.NativeObject, GetProxy)
End Function
0 Likes
Accepted solutions (2)
1,451 Views
9 Replies
Replies (9)
Message 2 of 10

They_Call_Me_Jake
Advocate
Advocate

It seems to be choking on the code that grabs the constraint info. When I select a part and run the code I get the "Type mismatch" error but it still copies the part only without the constraints. If I run the code a second time I think the copied part is now the current selected part and since it doesn't have any constraints I do not get any errors 

0 Likes
Message 3 of 10

chandra.shekar.g
Autodesk Support
Autodesk Support

@They_Call_Me_Jake,

 

Can you please provide sample assembly with part constraints to investigate? Please make that files are non confidential.

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 4 of 10

They_Call_Me_Jake
Advocate
Advocate

@chandra.shekar.g Here is an example assembly with parts. There is a cube with a hole in it and a shaft with a head. The Shaft is constrained to the Cube using an insert constraint. If you select the Shaft and then run rule "Copy part with Constraints" it copies the part but errors out with a "Type mismatch" when it tries to select the constraint so the part is copied without any constraints. 

0 Likes
Message 5 of 10

chandra.shekar.g
Autodesk Support
Autodesk Support
Accepted solution

@They_Call_Me_Jake,

 

Try below iLogic code which copies selected part with constraints. Code is working fine with attached sample assembly.

 

Sub Main()
	DupeSelectionWithConstraints()
End Sub
Private oNewlyInsertedColl As Collection
Private oOriginalItemColl As Collection

Public Sub DupeSelectionWithConstraints()
    If ThisApplication.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then MsgBox ("Rule not valid for non-assembly files!"): Exit Sub
    
    Dim oDoc As AssemblyDocument
    oDoc = ThisApplication.ActiveDocument
    
    Dim oSS As SelectSet
    oSS = oDoc.SelectSet
    
    If oSS.Count < 1 Then MsgBox ("Rule Requires a Select Set!"): Exit Sub
    
    Call DuplicateSS(oDoc, oSS)
End Sub


Private Sub DuplicateSS(oParentDoc As Document, oSS As SelectSet)
     
	Dim oDoc As AssemblyDocument
	oDoc = oParentDoc
	 
	Dim oTG As TransientGeometry
    oTG = ThisApplication.TransientGeometry
    
    oPasteMatrix = oTG.CreateMatrix()
    
	Dim oDef As AssemblyComponentDefinition 
	oDef = oDoc.ComponentDefinition 
	
    oOriginalItemColl = New Collection
    oNewlyInsertedColl = New Collection
	 
    For Each oItem In oSS  
        oPasteMatrix = oItem.Transformation
        oNewOcc = oDef.Occurrences.Add(oItem.Definition.Document.FullDocumentName, oPasteMatrix)        
		oOriginalItemColl.Add(oItem)
        oNewlyInsertedColl.Add(oNewOcc)	 
    Next
    
    Dim oTestoOcc1 As Object
    Dim oTestoOcc2 As Object
    
    Dim oOcc1 As ComponentOccurrence
    Dim oOcc2 As ComponentOccurrence
    
    Dim oEntityOne As Object
    Dim oEntityTwo As Object
    
    For Each oConstraint In oDef.Constraints
    'Grab entities for new constraint to create
			 
            oTestoOcc1 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceOne)
            oTestoOcc2 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceTwo)
            
            If oTestoOcc1 Is Nothing And oTestoOcc2 Is Nothing Then GoTo NextConstraint
            
            If oTestoOcc1 Is Nothing Then
                 oEntityOne = oConstraint.EntityOne
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc1.Definition Then
                         oOcc1 = oPossibleOcc
                    End If
                Next				
                Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)
            End If
            
            If oTestoOcc2 Is Nothing Then
                oEntityTwo = oConstraint.EntityTwo
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc2.Definition Then
                        oOcc2 = oPossibleOcc
                    End If
                Next
                Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
            End If
        'End Grab entities
        
        
        'Check type of constraint
        Select Case oConstraint.Type
            Case ObjectTypeEnum.kAngleConstraintObject 'kAngleConstraintObject
                'oParentDoc.Constraints.AddAngleConstraint(EntityOne As Object,
                '                                          EntityTwo As Object,
                '                                          Angle As Variant,
                '                                          [SolutionType] As AngleConstraintSolutionTypeEnum,
                '                                          [ReferenceVectorEntity] As Variant,
                '                                          [BiasPointOne] As Variant,
                '                                          [BiasPointTwo] As Variant )
                '                                      As AngleConstraint
                Call oDef.Constraints.AddAngleConstraint(oEntityOne, oEntityTwo, oConstraint.Angle, oConstraint.SolutionType, oConstraint.ReferenceVectorEntity)
                
            Case ObjectTypeEnum.kAssemblySymmetryConstraintObject  'kAssemblySymmetryConstraintObject
                'oParentDoc.AddSymmetryConstraint( EntityOne As Object,
                '                                  EntityTwo As Object,
                '                                  SymmetryPlane As Object,
                '                                  [EntityOneInferredType] As InferredTypeEnum,
                '                                  [EntityTwoInferredType] As InferredTypeEnum,
                '                                  [NormalsOpposed] As Boolean )
                '                                 As AssemblySymmetryConstraint
                Call oDef.Constraints.AddSymmetryConstraint(oEntityOne, oEntityTwo, oConstraint.SymmetryPlane, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType, oConstraint.NormalsOpposed)
                
            Case ObjectTypeEnum.kFlushConstraintObject 'kFlushConstraintObject
                'oParentDoc.AddFlushConstraint( EntityOne As Object,
                '                               EntityTwo As Object,
                '                               Offset As Variant,
                '                               [BiasPointOne] As Variant,
                '                               [BiasPointTwo] As Variant )
                '                            As FlushConstraint
                Call oDef.Constraints.AddFlushConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression)
                
                
            Case ObjectTypeEnum.kInsertConstraintObject 'kInsertConstraintObject
                'oParentDoc.AddInsertConstraint( EntityOne As Object,
                '                                EntityTwo As Object,
                '                                AxesOpposed As Boolean,
                '                                Distance As Variant,
                '                                [BiasPointOne] As Variant,
                '                                [BiasPointTwo] As Variant )
                '                             As InsertConstraint
                Call oDef.Constraints.AddInsertConstraint(oEntityOne, oEntityTwo, oConstraint.AxesOpposed, oConstraint.Distance.Expression)
                
            Case ObjectTypeEnum.kMateConstraintObject 'kMateConstraintObject
                'oParentDoc.AddMateConstraint( EntityOne As Object,
                '                               EntityTwo As Object,
                '                               Offset As Variant,
                '                               [EntityOneInferredType] As InferredTypeEnum,
                '                               [EntityTwoInferredType] As InferredTypeEnum,
                '                               [BiasPointOne] As Variant,
                '                               [BiasPointTwo] As Variant )
                '                             As MateConstraint
                Call oDef.Constraints.AddMateConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType)
                
            Case ObjectTYpeEnum.kTangentConstraintObject 'kTangentConstraintObject
                '.AddTangentConstraint( EntityOne As Object,
                '                       EntityTwo As Object,
                '                       InsideTangency As Boolean,
                '                       Offset As Variant,
                '                       [BiasPointOne] As Variant,
                '                       [BiasPointTwo] As Variant )
                '                     As TangentConstraint
                Call oDef.Constraints.AddTangentConstraint(oEntityOne, oEntityTwo, oConstraint.InsideTangency, oConstraint.Offset.Expression)
            
        End Select
NextConstraint:
    Next 'constraint
    
    
End Sub

Private Function GrabObjectFromColl(ByVal oColl As Collection, ByVal oObj As Object) As Object
    For Each oItem In oColl
        If oItem Is oObj Then
            GrabObjectFromColl = oObj
            Exit Function
        End If
    Next
    GrabObjectFromColl = Nothing
End Function

Private Function GetProxy(ByRef Prxy As Object, ByRef ContOcc As ComponentOccurrence) As Object
	
    Dim TempPrxy As Object
    Dim Occ As ComponentOccurrence
    If Prxy.ContainingOccurrence.Type = ObjectTypeEnum.kComponentOccurrenceObject Then         
		Occ = ContOcc		 
    Else
        On Error Resume Next
             Occ = ContOcc.Definition.Occurrences.ItemByName(Prxy.ContainingOccurrence.Name)
            
        If Err.Number <> 0 Then
            On Error GoTo 0
            TempPrxy = Prxy.ContainingOccurrence
            Call ContOcc.CreateGeometryProxy(GetProxy(TempPrxy, ContOcc), Occ)
        End If
    End If 
    Call Occ.CreateGeometryProxy(Prxy.NativeObject, GetProxy)
End Function 

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



Message 6 of 10

neodd70
Enthusiast
Enthusiast

@chandra.shekar.g That worked perfectly....Thank you very much for your help.

0 Likes
Message 7 of 10

They_Call_Me_Jake
Advocate
Advocate

@chandra.shekar.g Sorry.....I replied to your solution when I was in my personal AutoDesk account instead of my work account. It works as expected....thanks again for your help. Now I'm going to try and figure out how to add the code I need so I can select new entities for the constraints to attach to so the copied parts move to the new locations I want. 

0 Likes
Message 8 of 10

They_Call_Me_Jake
Advocate
Advocate

@chandra.shekar.g So now I'm onto the next portion of the code I'm trying to figure out but I'm finding myself spinning my wheels. I have successfully added to the code so that after I have selected my part that I want to copy and then run the rule I have it ask to select a new entity to move the part to. and it works but after thinking about how I had it written I realized that it would only work if when the original part that is being copied had it's entity as the first selection in the constraint process, if it was the second selection my code would error out. Realizing this I tried to add some error correction in the code by using an if statement to compare the name of the newly created part with the  name of occurrence1 in the constraint, (I am most likely going about this completely wrong). To test this I have an If statement that checks the names and if they are equal I have a MessageBox pop up saying "This is the copied part" and if they are not equal then the Messagebox says "This is not the copied part". I have also adjusted the assembly so there are 2 shafts in 2 different holes in the cube. The shaft on the front of the cube has the entity on the shaft as the first selection in the constraint and the shaft on the top of the cube has the entity on the cube as the first selection in the constraint. When I select the shaft on the front of the cube and run the rule the messagebox pops up as expected and says "This is the copied part" but if I select the shaft on the top of the cube and run the rule I get an error that the "Object reference not set to an instance of an object". This seems odd to me because all I am doing is comparing the same 2 names in both parts of the if statement and just displaying a message box. I have tried moving my added code to different areas and also tried comparing the names of different variables but of the ones that work at all I get the same error. Another error I am getting is when I select 2 parts to copy at the same time, it copies both parts but puts the constraints from each part on only 1 of the copied parts and no constraints on the other copied part. Could you look at what I have and help me figure this part out. I apologize for my lack of programming skills but I am trying to search and find existing code I can use or try and figure it out for myself. Any help you could give is greatly appreciated. Here is the the code I have and my assembly with all the parts in it. Thanks again.   

 

Sub Main()
	DupeSelectionWithConstraints()
End Sub
Private oNewlyInsertedColl As Collection
Private oOriginalItemColl As Collection

Public Sub DupeSelectionWithConstraints()
    If ThisApplication.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then MsgBox ("Rule not valid for non-assembly files!"): Exit Sub
    
    Dim oDoc As AssemblyDocument
    oDoc = ThisApplication.ActiveDocument
    
    Dim oSS As SelectSet
    oSS = oDoc.SelectSet
    
    If oSS.Count < 1 Then MsgBox ("Rule Requires a Select Set!"): Exit Sub
    
    Call DuplicateSS(oDoc, oSS)
End Sub


Private Sub DuplicateSS(oParentDoc As Document, oSS As SelectSet)
     
	Dim oDoc As AssemblyDocument
	oDoc = oParentDoc
	 
	Dim oTG As TransientGeometry
    oTG = ThisApplication.TransientGeometry
    
    oPasteMatrix = oTG.CreateMatrix()
    
	Dim oDef As AssemblyComponentDefinition 
	oDef = oDoc.ComponentDefinition 
	
    oOriginalItemColl = New Collection
    oNewlyInsertedColl = New Collection
	 
    For Each oItem In oSS  
        oPasteMatrix = oItem.Transformation
        oNewOcc = oDef.Occurrences.Add(oItem.Definition.Document.FullDocumentName, oPasteMatrix)        
		oOriginalItemColl.Add(oItem)
        oNewlyInsertedColl.Add(oNewOcc)	 
    Next
	
'    Dim oNewEntity As Object = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllEntitiesFilter, "Please select a new constraint entity")
	
    Dim oTestoOcc1 As Object
    Dim oTestoOcc2 As Object
    
    Dim oOcc1 As ComponentOccurrence
    Dim oOcc2 As ComponentOccurrence
    
    Dim oEntityOne As Object
    Dim oEntityTwo As Object
    
    For Each oConstraint In oDef.Constraints
    'Grab entities for new constraint to create
			 
            oTestoOcc1 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceOne)
            oTestoOcc2 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceTwo)
			
            
            If oTestoOcc1 Is Nothing And oTestoOcc2 Is Nothing Then GoTo NextConstraint
            
            If oTestoOcc1 Is Nothing Then
                 oEntityOne = oConstraint.EntityOne
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc1.Definition Then
                         oOcc1 = oPossibleOcc
                    End If
                Next
'				If oOcc1.Name = oNewOcc.Name Then
'					Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)
'				Else If Not oOcc1.Name = oNewOcc.Name Then
'                	Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oNewEntity)
'				End If
				Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)
            End If
            
            If oTestoOcc2 Is Nothing Then
                oEntityTwo = oConstraint.EntityTwo
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc2.Definition Then
                        oOcc2 = oPossibleOcc
                    End If
                Next
'				If oOcc2.Name = oNewOcc.Name Then
'					Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
'				Else If Not oOcc2.Name = oNewOcc.Name Then
'                	Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oNewEntity)
'				End If
                Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
            End If
			
			If oNewOcc.Name = oOcc1.Name Then 'This is the one that works
'				oEntityOne = oNewEntity
				MessageBox.Show("Occurence 1 is the Copied Part", "iLogic")
			Else If Not oNewOcc.Name = oOcc1.Name Then 'This is the one that returns an error
'				oEntityTwo = oNewEntity
				MessageBox.Show("Occurence 1 is Not the Copied Part", "iLogic")
			End If
			
			
        'End Grab entities
        
        
        'Check type of constraint
        Select Case oConstraint.Type
            Case ObjectTypeEnum.kAngleConstraintObject 
                Call oDef.Constraints.AddAngleConstraint(oEntityOne, oEntityTwo, oConstraint.Angle, oConstraint.SolutionType, oConstraint.ReferenceVectorEntity)
                
            Case ObjectTypeEnum.kAssemblySymmetryConstraintObject 
                Call oDef.Constraints.AddSymmetryConstraint(oEntityOne, oEntityTwo, oConstraint.SymmetryPlane, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType, oConstraint.NormalsOpposed)
                
            Case ObjectTypeEnum.kFlushConstraintObject
                Call oDef.Constraints.AddFlushConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression)
                
                
            Case ObjectTypeEnum.kInsertConstraintObject 
                Call oDef.Constraints.AddInsertConstraint(oEntityOne, oEntityTwo, oConstraint.AxesOpposed, oConstraint.Distance.Expression)
                
            Case ObjectTypeEnum.kMateConstraintObject 
                Call oDef.Constraints.AddMateConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType)
                
            Case ObjectTypeEnum.kTangentConstraintObject 
                Call oDef.Constraints.AddTangentConstraint(oEntityOne, oEntityTwo, oConstraint.InsideTangency, oConstraint.Offset.Expression)
            
        End Select
NextConstraint :
    Next 'constraint
    
    
End Sub

Private Function GrabObjectFromColl(ByVal oColl As Collection, ByVal oObj As Object) As Object
    For Each oItem In oColl
        If oItem Is oObj Then
            GrabObjectFromColl = oObj
            Exit Function
        End If
    Next
    GrabObjectFromColl = Nothing
End Function

Private Function GetProxy(ByRef Prxy As Object, ByRef ContOcc As ComponentOccurrence) As Object
	
    Dim TempPrxy As Object
    Dim Occ As ComponentOccurrence
    If Prxy.ContainingOccurrence.Type = ObjectTypeEnum.kComponentOccurrenceObject Then         
		Occ = ContOcc		 
    Else
        On Error Resume Next
             Occ = ContOcc.Definition.Occurrences.ItemByName(Prxy.ContainingOccurrence.Name)
            
        If Err.Number <> 0 Then
            On Error GoTo 0
            TempPrxy = Prxy.ContainingOccurrence
            Call ContOcc.CreateGeometryProxy(GetProxy(TempPrxy, ContOcc), Occ)
        End If
    End If 
    Call Occ.CreateGeometryProxy(Prxy.NativeObject, GetProxy)
End Function
0 Likes
Message 9 of 10

chandra.shekar.g
Autodesk Support
Autodesk Support
Accepted solution

@They_Call_Me_Jake,

 

Try below iLogic code to know which occurrence is selected.

If Not oOcc1 Is Nothing  Then 'This is the one that works
'				oEntityOne = oNewEntity
				MessageBox.Show("Occurence 1 is the Copied Part", "iLogic")
			Else If Not  oOcc2 Is Nothing  Then 'This is the one that returns an error
'				oEntityTwo = oNewEntity
				MessageBox.Show("Occurence 1 is Not the Copied Part", "iLogic")
			End If

Modified full code looks like below.

 

Sub Main()
	DupeSelectionWithConstraints()
End Sub
Private oNewlyInsertedColl As Collection
Private oOriginalItemColl As Collection

Public Sub DupeSelectionWithConstraints()
    If ThisApplication.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then MsgBox ("Rule not valid for non-assembly files!"): Exit Sub
    
    Dim oDoc As AssemblyDocument
    oDoc = ThisApplication.ActiveDocument
    
    Dim oSS As SelectSet
    oSS = oDoc.SelectSet
    
    If oSS.Count < 1 Then MsgBox ("Rule Requires a Select Set!"): Exit Sub
    
    Call DuplicateSS(oDoc, oSS)
End Sub


Private Sub DuplicateSS(oParentDoc As Document, oSS As SelectSet)
     
	Dim oDoc As AssemblyDocument
	oDoc = oParentDoc
	 
	Dim oTG As TransientGeometry
    oTG = ThisApplication.TransientGeometry
    
    oPasteMatrix = oTG.CreateMatrix()
    
	Dim oDef As AssemblyComponentDefinition 
	oDef = oDoc.ComponentDefinition 
	
    oOriginalItemColl = New Collection
    oNewlyInsertedColl = New Collection
	 
    For Each oItem In oSS  
        oPasteMatrix = oItem.Transformation
        oNewOcc = oDef.Occurrences.Add(oItem.Definition.Document.FullDocumentName, oPasteMatrix)        
		oOriginalItemColl.Add(oItem)
        oNewlyInsertedColl.Add(oNewOcc)	 
    Next
	
'    Dim oNewEntity As Object = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllEntitiesFilter, "Please select a new constraint entity")
	
    Dim oTestoOcc1 As Object
    Dim oTestoOcc2 As Object
    
    Dim oOcc1 As ComponentOccurrence
    Dim oOcc2 As ComponentOccurrence
    
    Dim oEntityOne As Object
    Dim oEntityTwo As Object
    
    For Each oConstraint In oDef.Constraints
    'Grab entities for new constraint to create
			 
            oTestoOcc1 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceOne)
            oTestoOcc2 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceTwo)
			
            
            If oTestoOcc1 Is Nothing And oTestoOcc2 Is Nothing Then GoTo NextConstraint
            
            If oTestoOcc1 Is Nothing Then
                 oEntityOne = oConstraint.EntityOne
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc1.Definition Then
                         oOcc1 = oPossibleOcc
                    End If
                Next
'				If oOcc1.Name = oNewOcc.Name Then
'					Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)
'				Else If Not oOcc1.Name = oNewOcc.Name Then
'                	Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oNewEntity)
'				End If
				Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)
            End If
            
            If oTestoOcc2 Is Nothing Then
                oEntityTwo = oConstraint.EntityTwo
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc2.Definition Then
                        oOcc2 = oPossibleOcc
                    End If
                Next
'				If oOcc2.Name = oNewOcc.Name Then
'					Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
'				Else If Not oOcc2.Name = oNewOcc.Name Then
'                	Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oNewEntity)
'				End If
                Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
            End If 		
			 
			
			If Not oOcc1 Is Nothing  Then 'This is the one that works
'				oEntityOne = oNewEntity
				MessageBox.Show("Occurence 1 is the Copied Part", "iLogic")
			Else If Not  oOcc2 Is Nothing  Then 'This is the one that returns an error
'				oEntityTwo = oNewEntity
				MessageBox.Show("Occurence 1 is Not the Copied Part", "iLogic")
			End If
			
			
        'End Grab entities
        
        
        'Check type of constraint
        Select Case oConstraint.Type
            Case ObjectTypeEnum.kAngleConstraintObject 
                Call oDef.Constraints.AddAngleConstraint(oEntityOne, oEntityTwo, oConstraint.Angle, oConstraint.SolutionType, oConstraint.ReferenceVectorEntity)
                
            Case ObjectTypeEnum.kAssemblySymmetryConstraintObject 
                Call oDef.Constraints.AddSymmetryConstraint(oEntityOne, oEntityTwo, oConstraint.SymmetryPlane, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType, oConstraint.NormalsOpposed)
                
            Case ObjectTypeEnum.kFlushConstraintObject
                Call oDef.Constraints.AddFlushConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression)
                
                
            Case ObjectTypeEnum.kInsertConstraintObject 
                Call oDef.Constraints.AddInsertConstraint(oEntityOne, oEntityTwo, oConstraint.AxesOpposed, oConstraint.Distance.Expression)
                
            Case ObjectTypeEnum.kMateConstraintObject 
                Call oDef.Constraints.AddMateConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType)
                
            Case ObjectTypeEnum.kTangentConstraintObject 
                Call oDef.Constraints.AddTangentConstraint(oEntityOne, oEntityTwo, oConstraint.InsideTangency, oConstraint.Offset.Expression)
            
        End Select
NextConstraint :
    Next 'constraint
    
    
End Sub

Private Function GrabObjectFromColl(ByVal oColl As Collection, ByVal oObj As Object) As Object
    For Each oItem In oColl
        If oItem Is oObj Then
            GrabObjectFromColl = oObj
            Exit Function
        End If
    Next
    GrabObjectFromColl = Nothing
End Function

Private Function GetProxy(ByRef Prxy As Object, ByRef ContOcc As ComponentOccurrence) As Object
	
    Dim TempPrxy As Object
    Dim Occ As ComponentOccurrence
    If Prxy.ContainingOccurrence.Type = ObjectTypeEnum.kComponentOccurrenceObject Then         
		Occ = ContOcc		 
    Else
        On Error Resume Next
             Occ = ContOcc.Definition.Occurrences.ItemByName(Prxy.ContainingOccurrence.Name)
            
        If Err.Number <> 0 Then
            On Error GoTo 0
            TempPrxy = Prxy.ContainingOccurrence
            Call ContOcc.CreateGeometryProxy(GetProxy(TempPrxy, ContOcc), Occ)
        End If
    End If 
    Call Occ.CreateGeometryProxy(Prxy.NativeObject, GetProxy)
End Function

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 10 of 10

They_Call_Me_Jake
Advocate
Advocate

@chandra.shekar.g Thanks again....Sorry for the delayed response....got pulled from this for a little bit but now I'm back at it. So I have added somethings that let the user select which constraints they want to re-select and after the first copy it doesn't ask again and just allows them to just select each of the locations. One thing I've had to do tho is have a message box pop up on each copy to ask if they want to continue or stop but this takes up time when the user has 50 or 100 places they need to copy the part to. I can't figure out how to have it loop thru the process until the user hits the Escape key or even a right mouse button click to be used as the escape from the loop. Is there something that would allow for this. Another thing I noticed is that with the original Macro it would allow the part to have 3 constraints and there could be multiple parts selected to copy after the adjustment of the code so it would work as iLogic code now it will only allow one part to be copied (I commented out the multiple part selection and added just a single part selection to the code) otherwise I get an error and also if there are more than 2 constraints it errors out when trying to get the information on the 3rd constraint. Any help you could give would be much appreciated. Here is the code I have with my additions to it. Please forgive me if what I have done is the wrong way to go about it as I am still trying to learn the right way to organize things. Thanks again for your help. Test parts and assembly are also attatched.

Sub Main()
	DupeSelectionWithConstraints()
End Sub
Private oNewlyInsertedColl As Collection
Private oOriginalItemColl As Collection

Public Sub DupeSelectionWithConstraints()
    If ThisApplication.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then MsgBox ("Rule not valid for non-assembly files!"): Exit Sub
    
    Dim oDoc As AssemblyDocument
    oDoc = ThisApplication.ActiveDocument
	
	Dim oSelection As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oSelected As Object = Nothing
	
	Dim oSS As SelectSet = oDoc.SelectSet
	
	If oSS.Count < 1 Then
		oSelected = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Please select a component to copy")
		oSelection.Add(oSelected)
	Else If oSS.Count >= 1 Then
		oSelection.Add(oSS(1))
	End If
    
    Call DuplicateSS(oDoc, oSelection)

End Sub


Private Sub DuplicateSS(oParentDoc As Document, oSelection As ObjectCollection)

	
	Dim oOriginalPart As Object = oSelection(1)
	Dim oCancel As Boolean = False
	
	'New locations for constraints of copied components
	'for each constraint if constraint was selected to
	'be moved to a new location
	Dim oNewEntSelOne As Object
	Dim oNewEntSelTwo As Object
	Dim oNewEntSelThree As Object
	
	'Flag to see if the user has choosen
	'which constraints they want to 
	'relocate
	Dim oSelNew As Boolean = True
	
	'Flag to see if the user wants to change
	'the location of any one of the three
	'constraints
	Dim oTestConstOne As Boolean =  False
	Dim oTestConstTwo As Boolean = False
	Dim oTestConstThree As Boolean = False
	
	'Flag for each constraint the user selected as one
	'that needed to have a new entity selected.
	Dim oConstOne As String = "Empty"
	Dim oConstTwo As String = "Empty"
	Dim oConstThree As String = "Empty"
	
    Dim i=1
	
	While oCancel = False
		
		Dim oDoc As AssemblyDocument
		oDoc = oParentDoc
		
		Dim oTG As TransientGeometry
	    oTG = ThisApplication.TransientGeometry
	    
	    oPasteMatrix = oTG.CreateMatrix()
	    
		Dim oDef As AssemblyComponentDefinition 
		oDef = oDoc.ComponentDefinition 
		
	    oOriginalItemColl = New Collection
	    oNewlyInsertedColl = New Collection
		
		'Single part duplication
		oPastMatrix = oOriginalPart.Transformation
		oNewOcc = oDef.Occurrences.Add(oOriginalPart.Definition.Document.FullDocumentName, oPasteMatrix)        
		oOriginalItemColl.Add(oOriginalPart)
	    oNewlyInsertedColl.Add(oNewOcc)
		'End of Single part duplication
		
		'Multiple part duplication 
'	    For Each oItem In oSelection  
'	        oPasteMatrix = oItem.Transformation
'	        oNewOcc = oDef.Occurrences.Add(oItem.Definition.Document.FullDocumentName, oPasteMatrix)        
'			oOriginalItemColl.Add(oItem)
'	        oNewlyInsertedColl.Add(oNewOcc)	 
'	    Next
		'End of Multiple part duplication
		

		Dim oNewEnt As Object = Nothing	

	    Dim oTestoOcc1 As Object
	    Dim oTestoOcc2 As Object
	    
	    Dim oOcc1 As ComponentOccurrence
	    Dim oOcc2 As ComponentOccurrence
	    
	    Dim oEntityOne As Object
	    Dim oEntityTwo As Object
		
	    For Each oConstraint In oDef.Constraints
	    'Grab entities for new constraint to create	
				 
            oTestoOcc1 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceOne)
            oTestoOcc2 = GrabObjectFromColl(oOriginalItemColl, oConstraint.OccurrenceTwo)
            If oTestoOcc1 Is Nothing And oTestoOcc2 Is Nothing Then GoTo NextConstraint


            If oTestoOcc1 Is Nothing Then 
				oEntityOne = oConstraint.EntityOne
				 
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc1.Definition Then
                         oOcc1 = oPossibleOcc
                    End If
                Next

				Call oOcc1.CreateGeometryProxy(GetProxy(oConstraint.EntityOne, oOcc1), oEntityOne)	
				If i = 1 Then
					oConstOne = oConstraint.Name
				Else If i = 2 Then
					oConstTwo = oConstraint.Name
				Else If i = 3 Then
					oConstThree = oConstraint.Name
				End If

				If oSelNew = True Then				
					oNewSelect = MessageBox.Show("Do you want to select a new location for " & oConstraint.Name, "New Constraint Selection", MessageBoxButtons.YesNo)
					If oNewSelect = vbYes Then
						If i = 1 Then
							oTestConstOne = True
						Else If i = 2 Then
							oTestConstTwo = True
						Else If i = 3 Then
							oTestConstThree = True
						End If
					End If
					If oNewSelect = vbNo Then
						If i = 1 Then
							oTestConstOne = False 
						Else If i = 2 Then
							oTestConstTwo = False
						Else If i = 3 Then
							oTestConstThree = False
						End If
					End If
				End If

            End If
            
            If oTestoOcc2 Is Nothing Then
                oEntityTwo = oConstraint.EntityTwo
            Else
                For Each oPossibleOcc In oNewlyInsertedColl
                    If oPossibleOcc.Definition Is oTestoOcc2.Definition Then
                        oOcc2 = oPossibleOcc
                    End If
                Next

                Call oOcc2.CreateGeometryProxy(GetProxy(oConstraint.EntityTwo, oOcc2), oEntityTwo)
				MessageBox.Show("Base Part is first Selected","iLogic")
            End If
'			MessageBox.Show(oConstOneSelNew,"iLogic")
			If oConstraint.Name = oConstOne Then
				If oTestConstOne = True Then
					oEntityTwo = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllEntitiesFilter, "Please select a new constraint entity")
				End If
			Else If oConstraint.Name = oConstTwo Then
				If oTestConstTwo = True Then
					oEntityTwo = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllEntitiesFilter, "Please select a new constraint entity")
				End If
			End If

		
		i = i + 1				
				
	        'End Grab entities
	        
	        
	        'Check type of constraint
	        Select Case oConstraint.Type
	            Case ObjectTypeEnum.kAngleConstraintObject 
	                Call oDef.Constraints.AddAngleConstraint(oEntityOne, oEntityTwo, oConstraint.Angle, oConstraint.SolutionType, oConstraint.ReferenceVectorEntity)
	                
	            Case ObjectTypeEnum.kAssemblySymmetryConstraintObject 
	                Call oDef.Constraints.AddSymmetryConstraint(oEntityOne, oEntityTwo, oConstraint.SymmetryPlane, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType, oConstraint.NormalsOpposed)
	                
	            Case ObjectTypeEnum.kFlushConstraintObject
	                Call oDef.Constraints.AddFlushConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression)
	                
	                
	            Case ObjectTypeEnum.kInsertConstraintObject 
	                Call oDef.Constraints.AddInsertConstraint(oEntityOne, oEntityTwo, oConstraint.AxesOpposed, oConstraint.Distance.Expression)
	                
	            Case ObjectTypeEnum.kMateConstraintObject 
	                Call oDef.Constraints.AddMateConstraint(oEntityOne, oEntityTwo, oConstraint.Offset.Expression, oConstraint.EntityOneInferredType, oConstraint.EntityTwoInferredType)
	                
	            Case ObjectTypeEnum.kTangentConstraintObject 
	                Call oDef.Constraints.AddTangentConstraint(oEntityOne, oEntityTwo, oConstraint.InsideTangency, oConstraint.Offset.Expression)
	            
	        End Select
	
			
	NextConstraint :	
	
	
    Next 'constraint
	oSelNew = False
	i = 1
	
	oQuestion = MessageBox.Show("Continue Copy Operation?", "Copy Part", MessageBoxButtons.YesNo)
		If oQuestion = vbYes Then
			oCancel = False
		Else If oQuestion = vbNo Then
			oCancel = True
		End If
	End While 
    
End Sub

Private Function GrabObjectFromColl(ByVal oColl As Collection, ByVal oObj As Object) As Object
    For Each oItem In oColl
        If oItem Is oObj Then
            GrabObjectFromColl = oObj
            Exit Function
        End If
    Next
    GrabObjectFromColl = Nothing
End Function

Private Function GetProxy(ByRef Prxy As Object, ByRef ContOcc As ComponentOccurrence) As Object
	
    Dim TempPrxy As Object
    Dim Occ As ComponentOccurrence
    If Prxy.ContainingOccurrence.Type = ObjectTypeEnum.kComponentOccurrenceObject Then         
		Occ = ContOcc		 
    Else
        On Error Resume Next
             Occ = ContOcc.Definition.Occurrences.ItemByName(Prxy.ContainingOccurrence.Name)
            
        If Err.Number <> 0 Then
            On Error GoTo 0
            TempPrxy = Prxy.ContainingOccurrence
            Call ContOcc.CreateGeometryProxy(GetProxy(TempPrxy, ContOcc), Occ)
        End If
    End If 
    Call Occ.CreateGeometryProxy(Prxy.NativeObject, GetProxy)
End Function