.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How can I rotate an inserted 3D object

6 REPLIES 6
Reply
Message 1 of 7
airpierre
1209 Views, 6 Replies

How can I rotate an inserted 3D object

I am making a call to acadDoc.ModelSpace.InsertBlock()

Then I want to get the newly inserted block and rotate it on a specific axis.

 

I see that InsertBlock returns an AcadBlockReference object, but if I try a Rotate3D() or TransformBy() on it, then I get this error:

 

************* Exception Text **************
System.ArgumentException: Value does not fall within the expected range.
   at Autodesk.AutoCAD.Interop.Common.AcadBlockReferenceClass.Rotate3D(Object Point1, Object Point2, Double RotationAngle)

  

As a different test, I am able to create a new box from a Solid3d object and use Transform By() on it, so as an alternative, is there a way to get my AcadBlockReference to behave like a Solid3d?

 

Does it have anything to with UCS coordinates?

  

thanks.

6 REPLIES 6
Message 2 of 7
chiefbraincloud
in reply to: airpierre

TransformBy is a member of the Entity Class, and so is Inherited by All things derived from Entity. 

Dave O.                                                                  Sig-Logos32.png
Message 3 of 7
airpierre
in reply to: chiefbraincloud

I don't understand what you are getting at. AcadBlockReference is derived from Entity correct?

But calling TransformBy() off of the AcadBlockReference object that comes back from InsertBlock() causes the error about the value not in the expected range.

Message 4 of 7
chiefbraincloud
in reply to: airpierre

Sorry, I glazed over the first part of your post too quickly and didn't notice the COM objects.  using the AcadBlockReference is completely different than the managed BlockReference object.   The Solid3D object is a managed object, so the TransformBy that you call on a Solid3D object is different from the TransformBy on a COM object.

 

The Rotate3D method says it wants Object for the first two arguments, but my (very old) COM code used to pass a 3 element array of Double for each point parameter.  That code was ported to .NET from VBA in ACAD 2007, and was completely migrated to the managed API by 2009. 

 

the COM TransformBy method says it wants object as well, but if you have successfully used the Managed Solid3D.TransformBy Method then you must have managed to create the Matrix3D object required by that function.  If so, you could try creating a Matrix3d object and passing Matrix3d.ToArray to the COM TransformBy function.

 

I know that Rotate3D works, so the problem must be in the way you are passing the args.  If none of this helps solve the problem, you should post the pertinent lines of code.

 

 

Dave O.                                                                  Sig-Logos32.png
Message 5 of 7
airpierre
in reply to: airpierre

No problem.. thanks for the help so far.  I tried the ToArray with TansformBy() and creating Object Arrays for Rotated3D.. bothe had erros as shown below.  Note: My AddBlock() function calls InsertBlock() and returns what it returns.

Here is the relative part of the code:

 


AcadBlockReference BlockRef;

 

BlockRef = AddBlock("beam1", "crossbars", new Point3d(0, Tip_Radius, HeightAboveGL), new Scale3d(Length, Width, Height));


AcadEntity ent = BlockRef as AcadEntity;

Matrix3d mtrx = Matrix3d.Rotation(45, Vector3d.YAxis, new Point3d(0, 0, 0));

BlockRef.TransformBy(mtrx.ToArray());  // ERROR: System.Runtime.InteropServices.COMException (0x8021000F): Incorrect SafeArray dimension

 

Object[] array1 = new Object[3];
Object[] array2 = new Object[3];

array1[0]=0;
array1[1]=0;
array1[2]=0;
array2[0]=0;
array2[1]=0;
array2[2]=0;

 

BlockRef.Rotate3D(array1, array2, 45);  // ERROR: Value does not fall within the expected range.

 

Message 6 of 7
chiefbraincloud
in reply to: airpierre

I'm not sure about the Incorrect SafeArray dimension.

 

As far as the Rotate3D, if you are actually passing (0,0,0) to both points, then you are creating a Zero Length Axis of rotation, which shouldn't work.  To duplicate the Matrix3D you have shown with a axis of rotation = Y-Axis, pass (0,1,0) as the second point.

 

Just in case the (0,0,0)'s are a by-product of you editing down your code for posting, I'll take a step back and return to your original question:

is there a way to get my AcadBlockReference to behave like a Solid3d?

 

You can use the .FromAcadObject method to get an ObjectID for the managed object, then open it with a transaction (which returns DBObject, you'll have to cast it up to Entity in C#) Then you can use the TransformBy method with a Matrix3D argument just like with Solid3D.

 

Dim ObjID As ObjectId = Entity.FromAcadObject(BlockRef)

Using trans As Transaction = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction

Dim dbObj As DBObject = trans.GetObject(ObjID, OpenMode.ForWrite, False, True)

Dim ent As Entity = CType(dbObj, Entity)

ent.TransformBy(mtrx)

....

the forum garbled my Paste

Dave O.                                                                  Sig-Logos32.png
Message 7 of 7
airpierre
in reply to: airpierre

Thank you so much!  I got it working (after some confusion becuase I needed to use radians and not degrees).  I had actually something similar a few days ago but it was with an AcadEntity not just Entity, (so close).  Anyway here is the function I ended up with:

 

       public static void RotateObject(AcadBlockReference BlockRef, Double Angle, Vector3d Axis, Point3d RotationPoint)
        {
            if (Angle < 0)
                Angle += 360;

 

            Angle = Angle * PI / 180;   // Convert from Degrees to Radians

 

            Matrix3d mtrx = Matrix3d.Rotation(Angle, Axis, RotationPoint);
            ObjectId ObjID = Entity.FromAcadObject(BlockRef);

 

            using (Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
            {
                DBObject dbObj = trans.GetObject(ObjID, OpenMode.ForWrite, false, true);
                Entity ent = (Entity)dbObj;
                ent.TransformBy(mtrx);
                trans.Commit();
            }
        }

 

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost