How to get A ImportInstance's rotate angle?

How to get A ImportInstance's rotate angle?

Anonymous
Not applicable
957 Views
9 Replies
Message 1 of 10

How to get A ImportInstance's rotate angle?

Anonymous
Not applicable

How to get A ImportInstance rotate angle?

 

Hi, everyone, I imported a CAD file, and Partial Explode it. I want to get the door or window's rotate angle?  They are all dwg block, How to get it in revit API ? Thanks!

0 Likes
958 Views
9 Replies
Replies (9)
Message 2 of 10

Mustafa.Salaheldin
Collaborator
Collaborator

Please provide a sample project file and any trial of your sample code so that I may can help.


¯\_(ツ)_/¯
Let it work like a charm.

Mustafa Salaheldin


EESignature




Digital Integration Manager, DuPod

Facebook | Twitter | LinkedIn

0 Likes
Message 3 of 10

btmsoftware
Advocate
Advocate

I've got the same query. Any chance you found the solution and would share it with us?

0 Likes
Message 4 of 10

alim3263
Explorer
Explorer

Please provide a sample project file and any trial of your sample code so that I may can help.

0 Likes
Message 5 of 10

btmsoftware
Advocate
Advocate

running my project in debug mode, I couldn't find any property/parameter for a selected ImportInstance and all its sub types that mentions anything about it's rotation. I also looked with the Building Coder's Revit Lookup tool but it also doesn't give that information

 

PS: I'm in Revit 2016

0 Likes
Message 6 of 10

Noetie.nibi
Participant
Participant

Did anyone manage to find a solution?
I can find things like scale and location etc but I can't find anything about rotation from blocks.
Here's my example code and an example cad file.

UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;
            Autodesk.Revit.DB.Options geomOption = uiapp.Application.Create.NewGeometryOptions();
            Autodesk.Revit.DB.View activeView = doc.ActiveView;

            FilteredElementCollector importedDrawing = (new FilteredElementCollector(doc, activeView.Id)
                .WhereElementIsNotElementType()
                .OfClass(typeof(ImportInstance)));

            try
            {
                foreach (Element elem in importedDrawing)
                {
                    GeometryElement geomElem = elem.get_Geometry(geomOption);
                    foreach (GeometryObject geomObj in geomElem)
                    {
                        GeometryInstance geomInst = geomObj as GeometryInstance;
                        GeometryElement symbolGeom = geomInst.GetSymbolGeometry();
                        foreach (GeometryObject gObj in symbolGeom)
                        {
                            GraphicsStyle gStyle = doc.GetElement(gObj.GraphicsStyleId) as GraphicsStyle;
                            GeometryInstance blockInstance = gObj as GeometryInstance;
                        }
                    }
                }
            }
            catch { }
            return Result.Succeeded;



0 Likes
Message 7 of 10

aignatovich
Advisor
Advisor

Hi, I have partial solution for you, this code returns Euler angles (https://en.wikipedia.org/wiki/Euler_angles) in XYZ order for given transform. ImportInstance has GetTransform / GetTotalTransform methods.

Limitations: won't work if transform matrix represents mirror operation (Determinant will be negative or check Transform.HasReflection property). If the matrix represents scale you should also normalize it (not sure if it's applicable to ImportInstance):

public static class TransformExtensions
{
	/// <summary>
	/// Gets Euler angles in X-Y-Z order. Assuming that <paramref name="transform"/> is unscaled and doesn't represent mirror operations
	/// </summary>
	/// <param name="transform"></param>
	/// <returns></returns>
	public static XYZ ToEulerAngles(this Transform transform)
	{
		var y = Math.Asin(transform.BasisZ.X);

		if (y.IsLessThan(1, 1e-5))
		{
			var x = Math.Atan2(-transform.BasisZ.Y, transform.BasisZ.Z);

			var z = Math.Atan2(-transform.BasisY.X, transform.BasisX.X);

			return new XYZ(x, y, z);
		}

		return new XYZ(Math.Atan2(transform.BasisY.Z, transform.BasisY.Y), y, 0);
	}
}
0 Likes
Message 8 of 10

aignatovich
Advisor
Advisor

Forget, IsLessThan is also an extension method. A part of my extension class:

public static class DoubleExtensions
{
	private const double DefaultTolerance = 0.00000001;

	[DebuggerStepThrough]
	public static bool IsLessThan(this double x, double value) => !IsAlmostEqualTo(x, value) && x < value;

	[DebuggerStepThrough]
	public static bool IsLessThan(this double x, double value, double tolerance) => !IsAlmostEqualTo(x, value, tolerance) && x < value;

	[DebuggerStepThrough]
	public static bool IsAlmostEqualTo(this double x, double value) => IsAlmostEqualTo(x, value, DefaultTolerance);

	[DebuggerStepThrough]
	public static bool IsAlmostEqualTo(this double x, double value, double tolerance) => Math.Abs(x - value) < tolerance;
}

 

In Revit 2021 or higher you can use MathComparisonUtils instead

0 Likes
Message 9 of 10

aignatovich
Advisor
Advisor

GeometryInstance also has transform, so this approach is also applicable in this case.

0 Likes
Message 10 of 10

Noetie.nibi
Participant
Participant

Hey thanks for the reply, your solution is indeed helpfull.
I found another solution from stackoverflow c# - Revit Get Point(X,Y,Z) from Cad - Stack Overflow

XYZ vectorTran = transform.OfVector(transform.BasisX.Normalize());
double rot = transform.BasisX.AngleOnPlaneTo(vectorTran, transform.BasisZ.Normalize()); // angle in radians

 

0 Likes