Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Auto constrain in current position with Origin Planes flush or mate

23 REPLIES 23
SOLVED
Reply
Message 1 of 24
SevInventor
2590 Views, 23 Replies

Auto constrain in current position with Origin Planes flush or mate

Auto constrain in current position with Origin Planes flush or mate

 

I’ve created or copy pasted  this Ilogic rule . It measures the distance of the origin planes of each occurrence to the origin planes of the active assembly. Then it creates a constraint of these two planes with the measured value.

With this rule we want to change existing assemblies to avoid sick constraints after model changes somewhere in the assembly structure  and maybe have a better performance (not yet tested) of big assemblies after every Occurrence has only 3 Constrains to the Origin Plane.

Most of the Occurrences in our assemblies have somehow parallel origin planes to the top level origin planes.

So the rule works but its quite slow.

 

Questions:

 

How can I make the decision if the constraint has to be flush/ mate and posive/negative value for the constraints quicker. Now the codes creates each constraint  flush, mate, positive, negative and deletes if the constraint is sick.-->this is only a bad workaround I think. I have tried something with Eulerian angles to get the orientation of the occurrence but I don’t know yet how this angle can make the decision flush/ mate and posive/negative value?

 

How can I create  constraints of Occurrences with unequal 90° to the origin? Without angle constraints.

 

Deleting the existing Constraints is very brutal. How could I make this more smart. Maybe a new LOD with the new Constraints and the old ones just suppressed.

 

Maybe somebody has use of my code

 

Sub Main
	
Dim oAsm As AssemblyDocument= ThisApplication.ActiveDocument
On Error Resume Next

'get the active assembly
Dim oAsmComp As AssemblyComponentDefinition= ThisApplication.ActiveDocument.ComponentDefinition
For Each oConstraint In oAsmComp.Constraints

oConstraint.Delete
Next
'set the Master LOD active
Dim oLODRep As LevelOfDetailRepresentation
oLODRep = oAsmComp.RepresentationsManager.LevelOfDetailRepresentations.Item("Master")
oLODRep.Activate

'Iterate through all of the top level occurrences
Dim oOccurrence As ComponentOccurrence
For Each oOccurrence In oAsmComp.Occurrences
'Try

'	'ground everything in the top level
	oOccurrence.Grounded = True
'Catch
'	end try
Next


	Dim oUM As UnitsOfMeasure = oAsm.UnitsOfMeasure
	Dim oOcc As ComponentOccurrence

	For Each oOcc In oAsm.ComponentDefinition.Occurrences


	'Create a proxy for Face0 (The face in the context of the assembly)
Dim Zähler As Integer = 1

'cycle each Origin plane in the top assembly
For Zähler = 1 To 3

Dim curAsmorPlane As WorkPlane = oAsmComp.WorkPlanes.Item(Zähler)

'Dim oComp1 As ComponentOccurrence = oADef.Occurrences.Item(1)

Dim oCompAsmDef As AssemblyComponentDefinition
Dim oCompPtDef As PartComponentDefinition
'cycle each Origin plane in the first level Occurence in the assembly
For Zähler2 = 1 To 3
	
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
	oCompAsmDef = oOcc.Definition
	oOcc.CreateGeometryProxy(oCompAsmDef.WorkPlanes.Item(Zähler2),curCompOriPlane)

ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
	oCompPtDef = oOcc.Definition
	oOcc.CreateGeometryProxy(oCompPtDef.WorkPlanes.Item(Zähler2),curCompOriPlane)
	
End If

	'Measure distance
	Dim oNV As NameValueMap
'	Dim Distance As Double

'	Try
'Dim angle As Double = ThisApplication.MeasureTools.
	Dim angle As Double = ThisApplication.MeasureTools.GetAngle(curAsmorPlane, curCompOriPlane)
	'Angle in deg 
'	MsgBox(angle)
	angle = (angle * 180) / PI

	If angle=0 Then
'
				'Convert distance from database units to default units of the document
				Dim Distance1 As Double = ThisApplication.MeasureTools.GetMinimumDistance(curAsmorPlane, curCompOriPlane)
				Dim Distance As Double 
				Dim oConstraint As AssemblyConstraint
				Distance = oUM.ConvertUnits(Distance1, UnitsTypeEnum.kDatabaseLengthUnits, oUM.LengthUnits)
				'Return the value in a messagebox just to control that it's right
				Distance= Round(Distance,3)
'				MsgBox(Distance)
				
				oConstraint=oAsmComp.Constraints.AddMateConstraint(curAsmorPlane, curCompOriPlane, Distance1)
				
		      If oConstraint.HealthStatus = oConstraint.HealthStatus.kInconsistentHealth Then
	          oConstraint.Delete
			  oConstraint = oAsmComp.Constraints.AddMateConstraint(curAsmorPlane, curCompOriPlane, -Distance1)
			  End If
		      If oConstraint.HealthStatus = oConstraint.HealthStatus.kInconsistentHealth Then
	          oConstraint.Delete
			  oConstraint = oAsmComp.Constraints.AddFlushConstraint(curAsmorPlane, curCompOriPlane, Distance1)
			  End If
		      If oConstraint.HealthStatus = oConstraint.HealthStatus.kInconsistentHealth Then
	          oConstraint.Delete
			  oConstraint = oAsmComp.Constraints.AddFlushConstraint(curAsmorPlane, curCompOriPlane, -Distance1)
			  End If
		      If oConstraint.HealthStatus = oConstraint.HealthStatus.kInconsistentHealth Then
	          oConstraint.Delete
			  End If
	  End If
'	Catch
'	End Try
	Next
	

Next	
'Try 
	oOcc.Grounded = False
'	Catch 
'		End try
Next
End Sub

second code for the Occurence eulerian angle adapted from her:

https://adndevblog.typepad.com/manufacturing/2013/01/inventor-eulerian-angles-of-assembly-component....

 

Sub Main()

   

    Dim oDoc As AssemblyDocument

     oDoc = ThisApplication.ActiveDocument

    Dim oOcc As ComponentOccurrence

     	oOcc = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select a oOcc plate")

    Dim oMat As Matrix

     oMat = oOcc.Transformation

 

    Dim aRotAngles(2) As Double

    Call CalculateRotationAngles(oMat, aRotAngles)

   

    ' Print results

'    Dim i As Integer

'    For i = 0 To 2

      msgbox(aRotAngles(0)  & vbCrLf & aRotAngles(1) & vbCrLf & aRotAngles(2))

'    Next i

    Beep

End Sub

 

 

Sub CalculateRotationAngles(ByVal oMatrix As Inventor.Matrix,ByRef aRotAngles() As Double)

    Const PI = 3.14159265358979

    Const TODEGREES As Double = 180 / PI

 

    Dim dB As Double

    Dim dC As Double

    Dim dNumer As Double

    Dim dDenom As Double

    Dim dAcosValue As Double

       

    Dim oRotate As Inventor.Matrix

    Dim oAxis As Inventor.Vector

    Dim oCenter As Inventor.Point

   

     oRotate = ThisApplication.TransientGeometry.CreateMatrix

     oAxis = ThisApplication.TransientGeometry.CreateVector

     oCenter = ThisApplication.TransientGeometry.CreatePoint

 

    oCenter.X = 0

    oCenter.Y = 0

    oCenter.Z = 0

 

    ' Choose aRotAngles[0] about x which transforms axes[2] onto the x-z plane

    '

    dB = oMatrix.Cell(2, 3)

    dC = oMatrix.Cell(3, 3)

 

    dNumer = dC

    dDenom = Sqrt(dB * dB + dC * dC)

 

    ' Make sure we can do the division.  If not, then axes[2] is already in the x-z plane

    If (Abs(dDenom) <= 0.000001) Then

        aRotAngles(0) = 0#

    Else

        If (dNumer / dDenom >= 1#) Then

            dAcosValue = 0#

        Else

            If (dNumer / dDenom <= -1#) Then

                dAcosValue = PI

            Else

                dAcosValue = Acos(dNumer / dDenom)

            End If

        End If

   

        aRotAngles(0) = Sign(dB) * dAcosValue

        oAxis.X = 1

        oAxis.Y = 0

        oAxis.Z = 0

 

        Call oRotate.SetToRotation(aRotAngles(0), oAxis, oCenter)

        Call oMatrix.PreMultiplyBy(oRotate)

    End If

 

    '

    ' Choose aRotAngles[1] about y which transforms axes[3] onto the z axis

    '

    If (oMatrix.Cell(3, 3) >= 1#) Then

        dAcosValue = 0#

    Else

        If (oMatrix.Cell(3, 3) <= -1#) Then

            dAcosValue = PI

        Else

            dAcosValue = Acos(oMatrix.Cell(3, 3))

        End If

    End If

 

    aRotAngles(1) = Math.Sign(-oMatrix.Cell(1, 3)) * dAcosValue

    oAxis.X = 0

    oAxis.Y = 1

    oAxis.Z = 0

    Call oRotate.SetToRotation(aRotAngles(1), oAxis, oCenter)

    Call oMatrix.PreMultiplyBy(oRotate)

 

    '

    ' Choose aRotAngles[2] about z which transforms axes[0] onto the x axis

    '

    If (oMatrix.Cell(1, 1) >= 1#) Then

        dAcosValue = 0#

    Else

        If (oMatrix.Cell(1, 1) <= -1#) Then

            dAcosValue = PI

        Else

            dAcosValue = Acos(oMatrix.Cell(1, 1))

        End If

    End If

 

    aRotAngles(2) = Math.Sign(-oMatrix.Cell(2, 1)) * dAcosValue

 

    'if you want to get the result in degrees

    aRotAngles(0) = Round(aRotAngles(0) * TODEGREES,4)

    aRotAngles(1) = Round(aRotAngles(1) * TODEGREES,4)

    aRotAngles(2) = Round(aRotAngles(2) * TODEGREES,4)

End Sub

 

 

Public Function Acos(value) As Double

    Acos = Math.Atan(-value / Math.Sqrt(-value * value + 1)) + 2 * Math.Atan(1)

End Function

 

Labels (5)
23 REPLIES 23
Message 21 of 24
Rich-T
in reply to: SevInventor

This is excellent, many thanks 

Message 22 of 24
Rich-T
in reply to: SevInventor

As another variation to this rule, can we constraint all parts to the active assembly's origin work planes - instead of selecting a base component ?

Or perhaps do this as a selection option for the 'base part' which allows the current assembly doc to be selected ?

Message 23 of 24
SevInventor
in reply to: Rich-T

@Rich-T 

Yes, my Code from 03-11-2022 07:23 AM is with Origin planes of the assembly instead of base component

Message 24 of 24
Rich-T
in reply to: SevInventor

oh yes, thank you.

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report