I have an assembly where I'm placed a plate onto a subassembly.
The plate has a falt surface and two bolt holes, there are reciprocal holes in one of the components of the subassembly.
I'm trying to programatically swap the axial relationships on the holes so the plates can rotate 180° based on user input on a form.
I've been able to identify the relations and interrogate the appropriate relation3D objects, I can see Occurrances, GetGeometry and GetEntity but I can't see how I'm able to identify the references that would used to add an axial reference.
I say to add an axial refrence because the only solution I can see so far is to delete the current relationships and create new ones using the same references but in a different sequence.
Does anyone know how this can be done?
Solved! Go to Solution.
I can think of a much simpler solution for that. If you simply wanna get a 180º rotation, you can just use a sketch or some geometry which suits your needs on both parts and replace your two axial alignment with a "central" alignment and an angular relation.
Simply changing the angle numerical value you can rotate the part. From my point of view has much abstract sense. You'll have to select a good center of rotation so your holes match for both positions. The best way would be to draw a sketch wich a circunference in which the diameter of that circunference would be a line connecting the center of both holes. with that circunference in both parts, you'll have a valid center of rotation.
Of course, this approach don't guarantee that the drills match, so you'll have to be careful when modeling bot parts. Maybe you can Reference Copy a part inside another to ensure that holes are at the same distance always; it depends of the complexity of your model...
As a note: I have deal into problems when using redundant matches, like two axial alignments for holes. Obviously, if those holes move their relative positions, SE will generate an error in the relationships. Unfortunately, SE is quite weak tracing errors, and not always will be clear were the mismatching is happening. It's easy that you end with dozens of parts showing red relationship and wondering what did you do wrong in your past life to deserve that...
Hope this helps!
Thanks for the reply.
Unfortunately I have to work with the assemblies as they are now so adding sketches or changing the 400 assemblies isn't viable. If I could I would follow something similar by generating planes between the holes and applying a relationship to those planes which could be flipped.
I did some extra work based on a post at http://community.plm.automation.siemens.com/t5/Solid-Edge-Developer-Forum/Adding-planar-align-betwee...
The part I'm trying to rotate is what I call an adapter plate. Below is the code I have so far. It is incomplete, it just tries to repeat one of the axial relations but it fails at the point of adding the relation.
''' <summary> ''' Looks for an adapter plate in the assembly and then swaps the axial relations to rotate it ''' </summary> ''' <param name="objAdapterOccurrance">The occurrence of the adapter plate in the assembly</param> ''' <param name="objApplication">The Solid Edge application object that has the assembly open</param> ''' <param name="objAssembly">The assembly that holds the adapter plate</param> ''' <remarks></remarks> Private Sub RotateAdapter(ByVal objAdapterOccurrance As SolidEdgeAssembly.Occurrence, _ ByVal objApplication As SolidEdgeFramework.Application, _ ByVal objAssembly As SolidEdgeAssembly.AssemblyDocument) 'Declare the variables '3D Relations, the assembly container and the two axial relations that will be swapped Dim objRels3D As SolidEdgeAssembly.Relations3d = Nothing Dim objAxialRel1 As SolidEdgeAssembly.AxialRelation3d = Nothing Dim objAxialRel2 As SolidEdgeAssembly.AxialRelation3d = Nothing 'The Reference objects, one for each reference of each axial relation and one 'for the plate in the suboccurrence Dim objRef1 As SolidEdgeFramework.Reference = Nothing Dim objRef2 As SolidEdgeFramework.Reference = Nothing Dim objSubObjRef As SolidEdgeFramework.Reference = Nothing Dim objRef3 As SolidEdgeFramework.Reference = Nothing Dim objRef4 As SolidEdgeFramework.Reference = Nothing 'Occurrence objects Dim objAssyOcc As SolidEdgeAssembly.Occurrence = Nothing Dim objAssyOccDoc As SolidEdgeAssembly.AssemblyDocument = Nothing Dim objChildOcc As SolidEdgeAssembly.Occurrence = Nothing Dim objSubOccs As SolidEdgeAssembly.Occurrences = Nothing Dim objSubOcc As SolidEdgeAssembly.Occurrence = Nothing 'The feature variables Dim objFace1 As SolidEdgeGeometry.Face Dim objFace2 As SolidEdgeGeometry.Face Dim objFaces As SolidEdgeGeometry.Faces Dim objHoles As SolidEdgePart.Holes Dim objHole As SolidEdgePart.Hole Try 'Collect the relationships in the adapter plate objRels3D = objAdapterOccurrance.Relations3d 'Collect the axial relationships For Each objRel3D In objRels3D Select Case objRel3D.type 'Skip non-axial relaions Case SolidEdgeFramework.ObjectType.igAxialRelation3d 'Check to see if either of the occurrences is the mating assy If CType(objRel3D, SolidEdgeAssembly.AxialRelation3d).Occurrence1. _ Name.Contains("MatingAssy") Or _ CType(objRel3D, SolidEdgeAssembly.AxialRelation3d).Occurrence2. _ Name.Contains("MatingAssy") Then 'There are two axial relations that meet to the same plate, on the first 'pass cast the axial relation to objAxialRel1 and on the second pass cast 'it to objAxialRel2. Suppress both relations each time to ensure they cause 'a conflict when trying to apply new relations If objAxialRel1 Is Nothing Then objAxialRel1 = objRel3D objAxialRel1.Suppress = True Else objAxialRel2 = objRel3D objAxialRel2.Suppress = True Exit For End If End If End Select Next 'Check to ensure we don't try and align two cylindrical faces on the same part If objAxialRel1.Occurrence1.Name = objAxialRel2.Occurrence1.Name Then 'Collect the holes face for the first occurrence of the first axial reference objHoles = objAxialRel1.Occurrence1.OccurrenceDocument.Models.Item(1).Holes objHole = objHoles.Item(1) objFaces = objHole.Faces(SolidEdgeGeometry.FeatureTopologyQueryTypeConstants.igQueryAll) objFace1 = objFaces.Item(1) 'Collect the holes face for the second occurrence of the first axial reference, which lies 'in the face of a part of the subassembly objAssyOcc = objAxialRel1.Occurrence2 objAssyOccDoc = objAssyOcc.OccurrenceDocument objSubOccs = objAssyOccDoc.Occurrences For Each objSubOcc In objSubOccs If objSubOcc.Name.Contains("MatingPart") Then objChildOcc = objSubOcc Exit For End If Next objHoles = objChildOcc.OccurrenceDocument.Models.Item(1).Holes objHole = objHoles.Item(1) objFaces = objHole.Faces(SolidEdgeGeometry.FeatureTopologyQueryTypeConstants.igQueryAll) objFace2 = objFaces.Item(1) 'Create the references. For the assembly we must create a reference for assembled part 'and hole face and include this reference in the assembly reference objRef1 = objAssembly.CreateReference(objAxialRel1.Occurrence1, objFace1) objSubObjRef = objAssembly.CreateReference(objChildOcc, objFace2) objRef2 = objAssembly.CreateReference(objAxialRel1.Occurrence2, objSubObjRef) 'Add the axial reference objRels3D.AddAxial(objRef1, objRef2, False) Else End If Catch ex As Exception Console.WriteLine(ex.Message) MessageBox.Show(ex.Message) Finally 'Release all the COM objects If Not (objRels3D Is Nothing) Then Marshal.ReleaseComObject(objRels3D) objRels3D = Nothing End If 'Revoke the message filter MessageFilter.Revoke() End Try MessageBox.Show("Adapter Plate Rotated") End Sub
The following code is exchanging the two axial relations by recreating them using the other topology of each:
Dim objAsmDoc As AssemblyDocument = objApp.ActiveDocument ' Find the two axial relations of the selected occurrence (must be toplevel occurrence in this code!) Dim objAxialRel(1) As AxialRelation3d Dim objSelOcc As Occurrence = objAsmDoc.SelectSet.Item(1) objAsmDoc.SelectSet.RemoveAll() Dim idx As Integer = 0 For Each objRel In objSelOcc.Relations3d Dim relType As ObjectType = objRel.GetType().InvokeMember("Type", Reflection.BindingFlags.GetProperty, Nothing, objRel, Nothing) If relType = ObjectType.igAxialRelation3d Then objAxialRel(idx) = objRel idx += 1 If idx >= 2 Then Exit For End If Next If idx < 2 Then MessageBox.Show("The selected occurrence has less than 2 axial relations!") Exit Sub End If ' Retrieve the axis of each relation Dim axis1(1) As Object Dim axis2(1) As Object Dim isTopoRef As Boolean For i As Integer = 0 To 1 axis1(i) = objAxialRel(i).GetElement1(isTopoRef) axis2(i) = objAxialRel(i).GetElement2(isTopoRef) Next ' Delete both relations objAxialRel(0).Delete() objAxialRel(1).Delete() ' Create new axial relations with the second element exchanged objAsmDoc.Relations3d.AddAxial(axis1(0), axis2(1), True) objAsmDoc.Relations3d.AddAxial(axis1(1), axis2(0), True)