c# part rotaton

c# part rotaton

Anonymous
Not applicable
1,431 Views
5 Replies
Message 1 of 6

c# part rotaton

Anonymous
Not applicable

HI guys,

 got the basics for the plugin working but need one thing.....

 

currently I have a assembally with several parts constrained to a grounded part with the INSERT constraint.

these other parts can rotate in circles along the constraint axis when i click and drag with the mouse...

 

I need to do the same kind of rotation with code, preferabally using degrees,

 

but i dont know what to search for

 

so please if someone knows what it is called that im trying to do, or sample code ....

 

would be great

thanks!

 

0 Likes
1,432 Views
5 Replies
Replies (5)
Message 2 of 6

Anonymous
Not applicable
ohya.....autodesk inventor
0 Likes
Message 3 of 6

ekinsb
Alumni
Alumni

Here's a little VBA program I wrote that I believe does what you want.

 

Public Sub RotatePart()
    ' Get a reference to the TransientGeometry object.
    Dim tg As TransientGeometry
    Set tg = ThisApplication.TransientGeometry
    
    ' Get a reference to the active assembly.
    Dim asmDoc As AssemblyDocument
    Set asmDoc = ThisApplication.ActiveDocument
    
    ' Have the occurrence to rotate selected.
    Dim rotateOcc As ComponentOccurrence
    Set rotateOcc = ThisApplication.CommandManager.Pick(kAssemblyOccurrenceFilter, "Select part to rotate.")
    
    ' Prompt for the angle of rotation.  This uses the UnitsOfMeasure object so they can
    ' enter any valid angle input, including equations and referenced to paramaeters.
    ' For example "360/8" or "angle" if there's a parameter named "angle".
    Dim angleInput As String
    angleInput = InputBox("Enter the angle", "Angle", "45 deg")
    Dim angle As Double
    angle = asmDoc.UnitsOfMeasure.GetValueFromExpression(angleInput, "deg")
    
    ' Check that the part only has a single insert constraint.
    If rotateOcc.Constraints.Count = 1 And TypeOf rotateOcc.Constraints.Item(1) Is InsertConstraint And rotateOcc.Joints.Count = 0 And Not rotateOcc.Grounded Then
        Dim insert As InsertConstraint
        Set insert = rotateOcc.Constraints.Item(1)
                
        ' Get the geometry from the geometry the constraint is tied to.
        ' This assumes it is a circle or arc, which I believe will always be the case.
        Dim circOrArc As Object
        Set circ = insert.GeometryOne
        
        '** Define a transformation matrix based on the constraint geometry.
        
        ' Use the geometry to define the center and Z axis of the coordinate system.
        Dim origin As Point
        Set origin = circ.Center
        Dim zAxis As UnitVector
        Set zAxis = circ.normal
        
        ' Create a temporary X axis in an arbitrary direction.
        Dim xAxis As UnitVector
        Set xAxis = tg.CreateUnitVector(zAxis.x + 1, zAxis.y + 1, zAxis.Z + 1)
        
        ' Cross the two existing vectors to create the Y axis.
        Dim yAxis As UnitVector
        Set yAxis = zAxis.CrossProduct(xAxis)
        
        ' Now create the correct X axis by crossing the Y and Z axes.
        Set xAxis = yAxis.CrossProduct(zAxis)
        
        ' Create a matrix using the coordinate system defined above.  This defines
        ' a coordinate system positioned at the current location of the selected
        ' part where the Z axis lies along the rotation axis.
        Dim originalTrans As matrix
        Set originalTrans = tg.CreateMatrix
        Call originalTrans.SetCoordinateSystem(origin, xAxis.AsVector, yAxis.AsVector, zAxis.AsVector)
        
        ' Invert the matrix to get a matrix that defines a transform to go from the current position
        ' of the part to the origin where the defined coordinate system lines up with the model coordinate system.
        Dim inverseTrans As matrix
        Set inverseTrans = originalTrans.Copy
        inverseTrans.Invert
        
        ' Create the matrix that goes from the current position to the origin.
        Dim newTrans As matrix
        Set newTrans = rotateOcc.Transformation
        Call newTrans.TransformBy(inverseTrans)
        
        ' Define a matrix that defines the rotation around the Z axis.
        Dim rotateTrans As matrix
        Set rotateTrans = tg.CreateMatrix
        Call rotateTrans.SetToRotation(angle, tg.CreateVector(0, 0, 1), tg.CreatePoint(0, 0, 0))
        
        ' Apply the rotation to the full tranform.
        Call newTrans.TransformBy(rotateTrans)
        
        ' Apply the original transform to the full transform to move the part back into it's original position.
        Call newTrans.TransformBy(originalTrans)
        
        ' Apply the matrix to the part.
        rotateOcc.Transformation = newTrans
    Else
        MsgBox "The selected part must have a single insert constraint."
    End If
End Sub

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 4 of 6

Anonymous
Not applicable

thanks, but i seem to have problem in translation to c# with this line:

 

 If rotateOcc.Constraints.Count = 1 And TypeOf rotateOcc.Constraints.Item(1) Is InsertConstraint And rotateOcc.Joints.Count = 0 And Not rotateOcc.Grounded Then
        Dim insert As InsertConstraint
        Set insert = rotateOcc.Constraints.Item(1)
  

 

it is easy enough to trim down the if statement, but more of a problem is   "Item" is not defined when "set" - ing ......

 

also if i recall vba is excel macro?  I get undefined type errors when using DIM for most those refrences in excel, is there a plugin i need to add?

 

also if i understand the hiarchy insert is extention of parts,   is there a way to get the parts list from array , instead of selecting?

 

....my part list wont be changing so things can be static if it helps

 

thanks!

 

0 Likes
Message 5 of 6

ekinsb
Alumni
Alumni

About your second question of getting the occurrence you want to rotate.  You don't have to use a user selection but can get it from traversing the model hierarchy.  The code below will get an occurrence named "RotateTest" at the top level of the assembly.  There are other techniques that you can use to label something and find it later using "attributes" but it sounds like just using the name of the occurrence as you see it in the browser will probably work in your case.

 

Inventor.ComponentOccurrence occ = asmDoc.ComponentDefinition.Occurrences.ItemByName["RotateTest"];

 

Below is a C# version of the previous program.  I converted it into a function so you just pass in the occurence and the angle you want to rotate it.

 

public bool rotateOcc(Inventor.ComponentOccurrence occ, double angle)
{
    try
    {
        Inventor.Application invApp = occ.Application;

        // Get a reference to the TransientGeometry object.
        Inventor.TransientGeometry tg = invApp.TransientGeometry;

        // Check that the part only has a single insert constraint.
        if( (occ.Constraints.Count == 1) && (occ.Constraints[1] is Inventor.InsertConstraint) && (occ.Joints.Count == 0) && !occ.Grounded)
        {
            Inventor.InsertConstraint insert = (Inventor.InsertConstraint) occ.Constraints[1];

            // Get the geometry from the geometry the constraint is tied to.
            Inventor.Point origin = null;
            Inventor.UnitVector zAxis = null;
            if (insert.GeometryOne is Inventor.Circle)
            {
                Inventor.Circle circle = (Inventor.Circle)insert.GeometryOne;
                origin = circle.Center;
                zAxis = circle.Normal;
            }
            else if (insert.GeometryOne is Inventor.Arc3d)
            {
                Inventor.Arc3d arc = (Inventor.Arc3d)insert.GeometryOne;
                origin = arc.Center;
                zAxis = arc.Normal;
            }

            //** Define a transformation matrix based on the constraint geometry.

            // Create a temporary X axis in an arbitrary direction.
            Inventor.UnitVector xAxis = tg.CreateUnitVector(zAxis.X + 1, zAxis.Y + 1, zAxis.Z + 1);

            // Cross the two existing vectors to create the Y axis.
            Inventor.UnitVector yAxis = zAxis.CrossProduct(xAxis);

            // Now create the correct X axis by crossing the Y and Z axes.
            xAxis = yAxis.CrossProduct(zAxis);

            // Create a matrix using the coordinate system defined above.  This defines
            // a coordinate system positioned at the current location of the selected
            // part where the Z axis lies along the rotation axis.
            Inventor.Matrix originalTrans = tg.CreateMatrix();
            originalTrans.SetCoordinateSystem(origin, xAxis.AsVector(), yAxis.AsVector(), zAxis.AsVector());

            // Invert the matrix to get a matrix that defines a transform to go from the current position
            // of the part to the origin where the defined coordinate system lines up with the model coordinate system.
            Inventor.Matrix inverseTrans = originalTrans.Copy();
            inverseTrans.Invert();

            // Create the matrix that goes from the current position to the origin.
            Inventor.Matrix newTrans = occ.Transformation;
            newTrans.TransformBy(inverseTrans);

            // Define a matrix that defines the rotation around the Z axis.
            Inventor.Matrix rotateTrans = tg.CreateMatrix();
            rotateTrans.SetToRotation(angle, tg.CreateVector(0.0, 0.0, 1.0), tg.CreatePoint(0.0, 0.0, 0.0));

            // Apply the rotation to the full tranform.
            newTrans.TransformBy(rotateTrans);

            // Apply the original transform to the full transform to move the part back into it's original position.
            newTrans.TransformBy(originalTrans);

            // Apply the matrix to the part.
            occ.Transformation = newTrans;

            return true;
        }
        else
        {
            return false;
        }            }
    catch (Exception)
    {
        return false;
    }
}

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 6 of 6

Anonymous
Not applicable

hey thanks, that was a great model to show me how the hiarchy worked, with a small revision was able to step perfectly!

 


        public bool rotateOcc(Inventor.ComponentOccurrence occ1, double angle)
        {
            try
            {
                invApp = occ1.Application;
                Inventor.TransientGeometry tg = invApp.TransientGeometry;
                if ((occ1.Constraints.Count == 1) && (occ1.Constraints[1] is Inventor.InsertConstraint) && !occ1.Grounded)
                {
                    Inventor.InsertConstraint insert = (Inventor.InsertConstraint)occ1.Constraints[1];
                    Inventor.Point origin = null;
                    Inventor.UnitVector zAxis = null;
                    if (insert.GeometryOne is Inventor.Circle)
                    {
                        Inventor.Circle circle = (Inventor.Circle)insert.GeometryOne;
                        origin = circle.Center;
                        zAxis = circle.Normal;
                    }
                    else if (insert.GeometryOne is Inventor.Arc3d)
                    {
                        Inventor.Arc3d arc = (Inventor.Arc3d)insert.GeometryOne;
                        origin = arc.Center;
                        zAxis = arc.Normal;
                    }

                    Inventor.UnitVector xAxis = tg.CreateUnitVector(zAxis.X + 1, zAxis.Y + 1, zAxis.Z + 1);
                    Inventor.UnitVector yAxis = zAxis.CrossProduct(xAxis);
                    xAxis = yAxis.CrossProduct(zAxis);
                    Inventor.Matrix originalTrans = tg.CreateMatrix();
                    originalTrans.SetCoordinateSystem(origin, xAxis.AsVector(), yAxis.AsVector(), zAxis.AsVector());
                    Inventor.Matrix newTrans = occ1.Transformation;
                    Inventor.Matrix rotateTrans = tg.CreateMatrix();
                    rotateTrans.SetToRotation((angle * 0.0174520069808028), tg.CreateVector(0.0, 1.0, 0.0), tg.CreatePoint(0.0, 0.0, 0.0));
                    newTrans.TransformBy(rotateTrans);
                    occ1.Transformation = newTrans;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }


        public void RotateObject360()
        {
            Inventor.ComponentOccurrence occ = oAssDoc.ComponentDefinition.Occurrences.ItemByName[PartName[partnumber1-1]];
            for (double ctr = 1; ctr < 361; ctr += partstep1)
            {
                rotateOcc(occ, partstep1);
                cur_Angle[partnumber1 - 1] += partstep1;

            }
        }

        public void RotateObject(double endPos, int partnumber)
        {
            occ = oAssDoc.ComponentDefinition.Occurrences.ItemByName[PartName[partnumber-1]];
            rotateOcc(occ, (endPos - cur_Angle[partnumber-1]));
            cur_Angle[partnumber-1] = endPos;
        }

0 Likes