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:
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
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Solved by SevInventor. Go to Solution.
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 ?
Can't find what you're looking for? Ask the community or share your knowledge.