public void Rotate_ZAxis() { var famSym = FamilyType.ByName("Box"); var pt = Point.ByCoordinates(0, 1, 2); var famInst = FamilyInstance.ByPoint(famSym, pt); Assert.NotNull(famInst); var transform = famInst.InternalFamilyInstance.GetTransform(); double[] rotationAngles; TransformUtils.ExtractEularAnglesFromTransform(transform, out rotationAngles); Assert.AreEqual(0.0, rotationAngles[0]); RevitServices.Persistence.DocumentManager.Instance.CurrentDBDocument.Regenerate(); famInst.SetRotation(30); transform = famInst.InternalFamilyInstance.GetTransform(); TransformUtils.ExtractEularAnglesFromTransform(transform, out rotationAngles); Assert.AreEqual(30.0, rotationAngles[0] * 180 / Math.PI, 1.0e-6); famInst.SetRotation(60); transform = famInst.InternalFamilyInstance.GetTransform(); TransformUtils.ExtractEularAnglesFromTransform(transform, out rotationAngles); Assert.AreEqual(60.0, rotationAngles[0] * 180 / Math.PI, 1.0e-6); }
/// <summary> /// Sets the Euler angle of the family instance around its local Z-axis. /// </summary> /// <param name="degree">The Euler angle around Z-axis.</param> /// <returns>The result family instance.</returns> public FamilyInstance SetRotation(double degree) { if (this == null) { throw new ArgumentNullException("familyInstance"); } TransactionManager.Instance.EnsureInTransaction(Document); // Rotate the element. var oldTransform = InternalFamilyInstance.GetTransform(); double[] oldRotationAngles; TransformUtils.ExtractEularAnglesFromTransform(oldTransform, out oldRotationAngles); Double newRotationAngle = degree * Math.PI / 180; if (!oldRotationAngles[0].AlmostEquals(newRotationAngle, 1.0e-6)) { double rotateAngle = newRotationAngle - oldRotationAngles[0]; var axis = Line.CreateUnbound(oldTransform.Origin, oldTransform.BasisZ); ElementTransformUtils.RotateElement(Document, new ElementId(Id), axis, -rotateAngle); } TransactionManager.Instance.TransactionTaskDone(); return(this); }
private double GetRotationFromCS(CoordinateSystem fromCS, CoordinateSystem contextCS) { var elementTransform = this.InternalFamilyInstance.GetTransform(); var newTransform = contextCS.ToTransform() as Autodesk.Revit.DB.Transform; var oldTransform = fromCS.ToTransform() as Autodesk.Revit.DB.Transform; double[] oldRotationAngles; TransformUtils.ExtractEularAnglesFromTransform(oldTransform, out oldRotationAngles); double[] newRotationAngles; TransformUtils.ExtractEularAnglesFromTransform(newTransform, out newRotationAngles); return(ConvertEularToAngleDegrees(newRotationAngles.FirstOrDefault())); }
/// <summary> /// Place a Revit FamilyInstance given the FamilyType (also known as the FamilySymbol in the Revit API) and its coordinate system. /// </summary> /// <param name="familyType">Family Type. Also called Family Symbol.</param> /// <param name="coordinateSystem">Coordinates system to place the new family instance in.</param> /// <returns>New family instance.</returns> public static FamilyInstance ByCoordinateSystem(FamilyType familyType, CoordinateSystem coordinateSystem) { var transform = coordinateSystem.ToTransform() as Autodesk.Revit.DB.Transform; double[] newRotationAngles; TransformUtils.ExtractEularAnglesFromTransform(transform, out newRotationAngles); double rotation = ConvertEularToAngleDegrees(newRotationAngles.FirstOrDefault()); Point location = transform.ToCoordinateSystem().Origin; FamilyInstance familyInstance = ByPoint(familyType, location); familyInstance.SetRotation(rotation); return(familyInstance); }
public void Rotation_MAGN_8056() { // Additional Info: https://git.autodesk.com/Dynamo/DynamoRevit/commit/4517b56ff369488a2279e1a5510dd0d2b4c60549 // FamilyInstance.SetRotation is not working correctly for the first element in a sliced list var model = ViewModel.Model; string filePath = Path.Combine(workingDirectory, @".\Bugs\MAGN_8056.dyn"); string testPath = Path.GetFullPath(filePath); ViewModel.OpenCommand.Execute(testPath); AssertNoDummyNodes(); RunCurrentModel(); string locationNodeId = "8c9dbf40-73d7-4788-84b2-ccf015fa47de"; var locations = GetPreviewCollection(locationNodeId); var point = locations[0] as Point; point.X.ShouldBeApproximately(2.0); string numberSliderNodeId = "971b7986-59e2-4ad1-b087-0e9e4158506a"; DoubleSlider slider = GetNode <DoubleSlider>(numberSliderNodeId) as DoubleSlider; slider.Value = 10.0; // Set the new rotation RunCurrentModel(); locations = GetPreviewCollection(locationNodeId); point = locations[0] as Point; point.X.ShouldBeApproximately(2.0); // The x coordination of the column should not change point.Y.ShouldBeApproximately(0.0); // The x coordination of the column should not change point.Z.ShouldBeApproximately(0.0); // The x coordination of the column should not change //After updating the rotation angle, check that all family instances are rotated for 10.0 degrees var objects = GetPreviewCollection("2af2362b-38a7-4db7-976d-39f4e74c8e07"); foreach (var obj in objects) { var instance = obj as Revit.Elements.FamilyInstance; Assert.IsNotNull(instance); double[] rotationAngles; var familyInstance = instance.InternalElement as Autodesk.Revit.DB.FamilyInstance; var transform = familyInstance.GetTransform(); TransformUtils.ExtractEularAnglesFromTransform(transform, out rotationAngles); (10.0).ShouldBeApproximately(rotationAngles[0] * 180 / Math.PI); } }
/// <summary> /// Set the Euler angle of the family instance around its local Z-axis. /// </summary> /// <param name="degree">The Euler angle around Z-axis.</param> /// <returns>The result family instance.</returns> public FamilyInstance SetRotation(double degree) { if (this == null) { throw new ArgumentNullException("degree"); } var oldTransform = InternalGetTransform(); double[] oldRotationAngles; TransformUtils.ExtractEularAnglesFromTransform(oldTransform, out oldRotationAngles); var newRotationAngle = degree * Math.PI / 180; if (!oldRotationAngles[0].AlmostEquals(newRotationAngle, 1.0e-6)) { var rotateAngle = newRotationAngle - oldRotationAngles[0]; var axis = Autodesk.Revit.DB.Line.CreateUnbound(oldTransform.Origin, oldTransform.BasisZ); Autodesk.Revit.DB.ElementTransformUtils.RotateElement(Document, new Autodesk.Revit.DB.ElementId(Id), axis, -rotateAngle); } TransactionManager.Instance.TransactionTaskDone(); return(this); }
/// <summary> /// /// </summary> /// <param name="duct"></param> /// <param name="point"></param> /// <param name="damperType"></param> /// <param name="damperWidth"></param> /// <param name="damperHeight"></param> public static void InsertDamper( Element duct, Point point, FamilyType damperType, string damperWidth = "Duct Width", string damperHeight = "Duct Height") { if (!(duct.InternalElement is Autodesk.Revit.DB.Mechanical.Duct duct1)) { throw new ArgumentNullException(nameof(duct)); } if (point == null) { throw new ArgumentNullException(nameof(point)); } if (damperType == null) { throw new ArgumentNullException(nameof(damperType)); } if (!(duct1.Location is Autodesk.Revit.DB.LocationCurve location)) { throw new ArgumentException("Duct is not curve based."); } var doc = duct1.Document; var xyz = point.ToRevitType(); var curve = location.Curve; var result = curve.Project(xyz); var pt = result.XYZPoint; var symbol = damperType.InternalElement as Autodesk.Revit.DB.FamilySymbol; TransactionManager.Instance.EnsureInTransaction(doc); // (Konrad) Create new Damper instance and split duct into two. var id = Autodesk.Revit.DB.Mechanical.MechanicalUtils.BreakCurve(doc, duct1.Id, pt); if (!(doc.GetElement(id) is Autodesk.Revit.DB.Mechanical.Duct duct2)) { throw new ArgumentException("Failed to split Duct."); } var fi = doc.Create.NewFamilyInstance(pt, symbol, duct1, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); doc.Regenerate(); // (Konrad) Rotate Damper. var start = curve.GetEndPoint(0).ToPoint(); var end = curve.GetEndPoint(1).ToPoint(); var direction = Vector.ByTwoPoints(start, end); var up = Vector.ZAxis(); var perpendicular = direction.Cross(up); var cs = CoordinateSystem.ByOriginVectors(pt.ToPoint(), direction, perpendicular); var transform = cs.ToTransform(); TransformUtils.ExtractEularAnglesFromTransform(transform, out var newRotationAngles); var rotation = ConvertEularToAngleDegrees(newRotationAngles.FirstOrDefault()); var oldTransform = fi.GetTransform(); TransformUtils.ExtractEularAnglesFromTransform(oldTransform, out var oldRotationAngles); var newRotationAngle = rotation * Math.PI / 180; var rotateAngle = newRotationAngle - oldRotationAngles.FirstOrDefault(); var axis = Autodesk.Revit.DB.Line.CreateUnbound(oldTransform.Origin, oldTransform.BasisZ); Autodesk.Revit.DB.ElementTransformUtils.RotateElement(doc, fi.Id, axis, -rotateAngle); // (Konrad) Set Damper Width/Height to match Duct. var sourceWidth = duct1.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble(); var sourceHeight = duct1.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).AsDouble(); fi.GetParameters(damperWidth).FirstOrDefault()?.Set(sourceWidth); fi.GetParameters(damperHeight).FirstOrDefault()?.Set(sourceHeight); // (Konrad) Connect Damper to Ducts. var c1 = FindClosest(duct1.ConnectorManager.Connectors, xyz); // duct1 endpoint var c1Other = FindOther(duct1.ConnectorManager.Connectors, c1); var c1A = FindClosest(fi.MEPModel.ConnectorManager.Connectors, c1Other); c1.ConnectTo(c1A); var c2 = FindClosest(duct2.ConnectorManager.Connectors, xyz); // duct2 endpoint var c2Other = FindOther(duct2.ConnectorManager.Connectors, c2); var c2A = FindClosest(fi.MEPModel.ConnectorManager.Connectors, c2Other); c2.ConnectTo(c2A); TransactionManager.Instance.TransactionTaskDone(); }