//Функция расстановки семейства относительно Точки доступа public void CreateEquip( double xOffset, double yOffset, double zOffset, bool inRoom, string familyName, double ugoY = 0.0) { double angle; XYZ eqLocation = null; Line rotAxis = null; var fs = Util.GetFamilySymbolByFamilyName(doc, familyName); if (!fs.IsActive) { fs.Activate(); } if (inRoom) { if (fFlipped) { angle = tdFO.Negate().AngleTo(new XYZ(0, 1, 0)) + Math.PI; } else { angle = tdFO.AngleTo(new XYZ(0, 1, 0)); } eqLocation = tdLocation.Add(tdFO.Negate().Multiply(tdD / 2 + yOffset / 304.8)).Add(tdHO.Negate().Multiply(tdW / 2 + xOffset / 304.8)); } else { if (fFlipped) { angle = tdFO.Negate().AngleTo(new XYZ(0, 1, 0)); } else { angle = tdFO.AngleTo(new XYZ(0, 1, 0)) + Math.PI; } eqLocation = tdLocation.Add(tdFO.Multiply(tdD / 2 + yOffset / 304.8)).Add(tdHO.Negate().Multiply(tdW / 2 + xOffset / 304.8)); } rotAxis = Line.CreateBound(eqLocation, new XYZ(eqLocation.X, eqLocation.Y, eqLocation.Z + 1.0)); var eq = doc.Create.NewFamilyInstance(eqLocation, fs, level, StructuralType.NonStructural); ElementTransformUtils.RotateElement(doc, eq.Id, rotAxis, angle); eq.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).Set(zOffset / 304.8 + tdZShift); eq.LookupParameter("Смещение УГО по Y")?.Set(ugoY / 304.8); }
internal static XYZ OletP1Point(Cons cons) { XYZ endPointOriginOletPrimary = cons.Primary.Origin; XYZ endPointOriginOletSecondary = cons.Secondary.Origin; //get reference elements var refCons = MepUtils.GetAllConnectorsFromConnectorSet(cons.Primary.AllRefs); Connector refCon = refCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault(); if (refCon == null) { throw new Exception("refCon Owner cannot find a Pipe for element!"); } Pipe refPipe = (Pipe)refCon.Owner; Cons refPipeCons = Shared.MepUtils.GetConnectors(refPipe); //Following code is ported from my python solution in Dynamo. //The olet geometry is analyzed with congruent rectangles to find the connection point on the pipe even for angled olets. XYZ B = endPointOriginOletPrimary; XYZ D = endPointOriginOletSecondary; XYZ pipeEnd1 = refPipeCons.Primary.Origin; XYZ pipeEnd2 = refPipeCons.Secondary.Origin; XYZ BDvector = D - B; XYZ ABvector = pipeEnd1 - pipeEnd2; double angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); if (angle > 90) { ABvector = -ABvector; angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); } Line refsLine = Line.CreateBound(pipeEnd1, pipeEnd2); XYZ C = refsLine.Project(B).XYZPoint; double L3 = B.DistanceTo(C); XYZ E = refsLine.Project(D).XYZPoint; double L4 = D.DistanceTo(E); double ratio = L4 / L3; double L1 = E.DistanceTo(C); double L5 = L1 / (ratio - 1); XYZ A; if (angle < 89) { XYZ ECvector = C - E; ECvector = ECvector.Normalize(); double L = L1 + L5; ECvector = ECvector.Multiply(L); A = E.Add(ECvector); } else { A = E; } return(A); }
/// <summary> /// 按XY的点的Z轴旋转 /// </summary> /// <param name="point"></param> /// <param name="xyz"></param> /// <param name="verticalVector"></param> public static void RotateByXY(this Location point, XYZ xyz, XYZ verticalVector) { Line axis = Line.CreateBound(xyz, xyz.Add(new XYZ(0, 0, 10))); if (verticalVector.X > VLConstraintsForCSA.MiniValueForXYZ) { point.Rotate(axis, 2 * Math.PI - verticalVector.AngleTo(new XYZ(0, 1, verticalVector.Z))); } else { point.Rotate(axis, verticalVector.AngleTo(new XYZ(0, 1, verticalVector.Z))); } }
private bool LineRelation(XYZ i, XYZ j, XYZ k) { bool LC = true; XYZ l = k - j; if (l.AngleTo(i) > maxangle) { if (l.AngleTo(i) < Math.PI - maxangle) { LC = false; } } return(LC); }
public static void DrawLine(XYZ p1, XYZ p2) { Transaction t = null; if (_doc.IsModifiable == false) { t = new Transaction(_doc, "Draw Line"); t.Start(); } Line ln = Line.CreateBound(p1, p2); if (p1.DistanceTo(p2) < 1.0 / 32.0) { return; // too small! } XYZ v1 = p2.Subtract(p1).Normalize(); XYZ other = XYZ.BasisX; double ang = (v1.AngleTo(other)); if ((ang > 0.9 * Math.PI) || (ang < 0.1)) { other = XYZ.BasisY; } XYZ norm = v1.CrossProduct(other).Normalize(); Plane p = Plane.CreateByNormalAndOrigin(norm, p1); SketchPlane sp = SketchPlane.Create(_doc, p); _doc.Create.NewModelCurve(ln, sp); if (t != null) { t.Commit(); } }
static public DuctOrientation GetDuctOrientation(ConnectorManager conMngr) { XYZ orientation = GetDuctDirection(conMngr); double angleToZ = orientation.AngleTo(XYZ.BasisZ); if (orientation.IsAlmostEqualTo(XYZ.BasisZ) || orientation.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { return(DuctOrientation.StraightVertical); } else if (orientation.IsAlmostEqualTo(new XYZ(orientation.X, orientation.Y, 0))) { return(DuctOrientation.Horizontal); } // угол между Z и вектором от 60 до 120 градусов else if (angleToZ > (Math.PI / 3) && angleToZ < (2 * Math.PI / 3)) { return(DuctOrientation.AlmostHorizontal); } // угол между Z и вектором больше 150 градусов или меньше 30 else if (angleToZ > (5 * Math.PI / 6) || angleToZ < (Math.PI / 6)) { return(DuctOrientation.AlmostVertical); } else { return(DuctOrientation.Angled); } }
/// <summary> /// 把两个相交L、V型线段,如果不是,则基于交点进行裁剪 只留下L、V型,进行倒角处理 /// </summary> /// <param name="_line1"></param> /// <param name="_line2"></param> /// <param name="radius"></param> /// <param name="_newline1"></param> /// <param name="_newline2"></param> /// <returns></returns> public static Arc Chamfer(Line _line1, Line _line2, double radius, out Line _newline1, out Line _newline2) { List <Line> lines = CutOffTwoLineByIntersectionPoint(_line1, _line2); //把两个相交线段,基于交点进行裁剪 只留下L、V型,进行倒角处理 该处处理,可以保证线的起点与终点的先后位置 XYZ intersectionPoint = GetIntersetionPointFromTwoLines(_line1, _line2); //求出L or V交点 XYZ direction_line1 = lines[0].Direction; //求方向,再求角度 XYZ direction_line2 = lines[1].Direction; double angle = direction_line1.AngleTo(direction_line2); if (angle > Math.PI) { angle = Math.PI * 2 - angle; } //求圆弧的三角函数问题,需要深究—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— XYZ point_arc_start = intersectionPoint.Add(direction_line1.Multiply(radius / (Math.Tan(angle / 2))));//使用正切三角函数,求出,圆弧与倒角直线相切点的位置 XYZ point_arc_end = intersectionPoint.Add(direction_line2.Multiply(radius / (Math.Tan(angle / 2)))); XYZ direction_line3 = direction_line1.Add(direction_line2).Normalize(); XYZ point_arc_middle = intersectionPoint.Add(direction_line3.Multiply((radius / Math.Sin(angle / 2)) - radius));// 使用正弦三角函数,求出,圆弧与倒角直线相切点的位置 Arc arc = Arc.Create(point_arc_start, point_arc_end, point_arc_middle); _newline1 = Line.CreateBound(point_arc_start, lines[0].GetEndPoint(1)); _newline2 = Line.CreateBound(point_arc_end, lines[1].GetEndPoint(1)); return(arc); }
/// <summary> /// Check whether two vectors are parallel /// </summary> static bool XyzParallel(XYZ a, XYZ b) { double angle = a.AngleTo(b); return(_eps > angle || DoubleEqual(angle, Math.PI)); }
/// <summary> /// Rotates the element based only on the direction of the placement connector. /// </summary> private static void RotateElementInPosition(XYZ placementPoint, Connector conOnFamilyToConnect, Connector startCon, Element element) { #region Geometric manipulation //http://thebuildingcoder.typepad.com/blog/2012/05/create-a-pipe-cap.html XYZ start = startCon.Origin; XYZ end = start - startCon.CoordinateSystem.BasisZ * 2; XYZ dirToAlignTo = (start - end); XYZ dirToRotate = -conOnFamilyToConnect.CoordinateSystem.BasisZ; double rotationAngle = dirToAlignTo.AngleTo(dirToRotate); XYZ normal = dirToAlignTo.CrossProduct(dirToRotate); //Case: Normal is 0 vector -> directions are already aligned, but may need flipping if (normal.Equalz(new XYZ(), 1.0e-6)) { //Subcase: Element needs flipping if (rotationAngle > 0) { Line axis2; if (dirToRotate.X.Equalz(1, 1.0e-6) || dirToRotate.Y.Equalz(1, 1.0e-6)) { axis2 = Line.CreateBound(placementPoint, placementPoint + new XYZ(0, 0, 1)); } else { axis2 = Line.CreateBound(placementPoint, placementPoint + new XYZ(1, 0, 0)); } ElementTransformUtils.RotateElement(element.Document, element.Id, axis2, rotationAngle); return; } //Subcase: Element already in correct alignment return; } Transform trf = Transform.CreateRotationAtPoint(normal, rotationAngle, placementPoint); XYZ testRotation = trf.OfVector(dirToAlignTo).Normalize(); if (testRotation.DotProduct(dirToAlignTo) < 0.00001) { rotationAngle = -rotationAngle; } Line axis = Line.CreateBound(placementPoint, placementPoint + normal); ElementTransformUtils.RotateElement(element.Document, element.Id, axis, rotationAngle); #endregion }
/// <summary> 判断两个方向向量是否指向同一个方向(不包括方向相反的情况) </summary> /// <param name="vectorA">The vector A.</param> /// <param name="vectorB">The vector B.</param> public static bool IsSameDirection(XYZ vectorA, XYZ vectorB) { var angle = vectorA.AngleTo(vectorB); if (angle <= AngleTolerance) { return(true); } return(false); }
/// <summary> /// 指定的曲线是否位于指定的平面内。 /// </summary> /// <param name="c"></param> /// <param name="planNormal"></param> /// <returns>空间三维曲线可能并不会在任何一个平面内,此时其自然是返回False。</returns> private static bool InPlan(Curve c, XYZ planNormal) { XYZ vec1 = default(XYZ); XYZ vec2 = default(XYZ); if (!c.IsBound) { c.MakeBound(0, 1); } // if (c is Line) { vec1 = c.GetEndPoint(0) - c.GetEndPoint(1); if (Math.Abs(vec1.AngleTo(planNormal) - 0.5 * Math.PI) < GeoHelper.AngleTolerance) { return(true); } else { return(false); } } else if (!(c is Arc) || c is Ellipse || c is NurbSpline) { vec1 = c.GetEndPoint(0) - c.Evaluate(0.5, true); vec2 = c.Evaluate(0.5, true) - c.Evaluate(1, true); if ((Math.Abs(vec1.AngleTo(planNormal) - 0.5 * Math.PI) < GeoHelper.AngleTolerance) && (Math.Abs(vec2.AngleTo(planNormal) - 0.5 * Math.PI) < GeoHelper.AngleTolerance)) { return(true); } else { return(false); } } else if (c is CylindricalHelix) // 圆柱螺旋线 { return(false); } // return(false); }
/// <summary> /// 取向量在指定方向上的投影长度 /// </summary> /// <param name="vector"></param> /// <param name="sideVector"></param> /// <returns></returns> public static double GetLengthBySide(this XYZ vector, XYZ sideVector) { var v = new XYZ(vector.X, vector.Y, 0); var sv = new XYZ(sideVector.X, sideVector.Y, 0); if (Math.Abs(v.DotProduct(sv)) < AnnotationConstaints.MiniValueForXYZ) { return(0); } return(v.GetLength() * Math.Cos(v.AngleTo(sv))); }
/// <summary> /// Calculate an angle between the given vector <code>v0</code> and <code>v1</code>. /// The <code>axis</code> gives the direction of measurement according to the Right-hand rule. /// The angle is ranged from -PI to PI. /// </summary> /// <remarks>The result of XYZ.AngleTo() is ranged from 0 to PI.</remarks> /// <param name="v0">A vector</param> /// <param name="v1">Another vector</param> /// <param name="axis">The axis perpendicular to both vectors</param> /// <returns>Angle between the two vectors</returns> public static double GetAngleBetween(XYZ v0, XYZ v1, XYZ axis) { XYZ cross = v0.CrossProduct(v1); if (cross.IsAlmostEqualTo(XYZ.Zero)) { return(0.0); } double sign = axis.Normalize().DotProduct(cross.Normalize()); return(sign * v0.AngleTo(v1)); }
/// <summary> /// Get the rotation of the crop element of a view. The rotation is expressed in degrees, counter clockwise. /// </summary> /// <param name="view"></param> /// <returns></returns> public static double GetRotation(Revit.Elements.Views.View view) { XYZ rightDirection = (view.InternalElement as Autodesk.Revit.DB.View).RightDirection; int sign = 1; if (rightDirection.Y < 0) { sign = -1; } return(rightDirection.AngleTo(XYZ.BasisX) * 180.0 / Math.PI * sign); }
private double ExtractAngleInX(XYZ CurrentPoint, XYZ NextPoint) { XYZ NormalVector = (NextPoint - CurrentPoint).Normalize(); if (NextPoint.Y > CurrentPoint.Y) { double Angle = NormalVector.AngleTo(XYZ.BasisX) + (Math.PI / 2); return(Angle); } else if (NextPoint.Y < CurrentPoint.Y) { double Angle = (Math.PI / 2) - NormalVector.AngleTo(XYZ.BasisX); return(Angle); } else if (NextPoint.Y == CurrentPoint.Y) { double Angle = NormalVector.AngleTo(XYZ.BasisX); return(Angle); } return(0); }
/// <summary> /// If true, the dir1 and the dir2 are same. /// </summary> /// <param name="dir1"></param> /// <param name="dir2"></param> /// <returns></returns> public static bool IsSameDirection(this XYZ dir1, XYZ dir2) { if (dir1 is null) { throw new ArgumentNullException(nameof(dir1)); } if (dir2 is null) { throw new ArgumentNullException(nameof(dir2)); } return(dir1.AngleTo(dir2) < 1e-6); }
public void Execute(UIApplication uiapp) { Document doc = uiapp.ActiveUIDocument.Document; UIDocument uidoc = uiapp.ActiveUIDocument; Element activeView = uidoc.ActiveView as Element; try { Reference pickedFace = uidoc.Selection.PickObject(ObjectType.Face); double famInstanceRot = 0; if ((doc.GetElement(pickedFace.ElementId).Location as LocationPoint) != null) { famInstanceRot = (doc.GetElement(pickedFace.ElementId).Location as LocationPoint).Rotation; } //based on the PyRevit method GeometryObject faceGeo = doc.GetElement(pickedFace).GetGeometryObjectFromReference(pickedFace); XYZ faceNorm = (faceGeo as Face).ComputeNormal(new UV(0, 0)); BoundingBoxXYZ bbox = (activeView as View3D).GetSectionBox(); XYZ normal = bbox.Transform.get_Basis(0).Normalize(); double angle = faceNorm.AngleTo(normal); XYZ axis = new XYZ(0, 0, 1); XYZ midPoint = new XYZ((bbox.Min.X + bbox.Max.X) / 2, (bbox.Min.Y + bbox.Max.Y) / 2, 0); if (faceNorm.X < 0) { Transform rotate = Transform.CreateRotationAtPoint(axis, Math.PI - (angle + famInstanceRot), midPoint); bbox.Transform = bbox.Transform.Multiply(rotate); } else { Transform rotate = Transform.CreateRotationAtPoint(axis, (angle + famInstanceRot), midPoint); bbox.Transform = bbox.Transform.Multiply(rotate); } Transaction bboxRot = new Transaction(doc, "bboxRot"); bboxRot.Start(); (activeView as View3D).SetSectionBox(bbox); bboxRot.Commit(); } catch { } }
/// <summary> /// 根据线管的位置与方向,以及设备中连接件的位置,得到此线管发出的射线与设备连接件的某竖向平面的交点 /// </summary> /// <param name="conduit"></param> /// <param name="cabinet"></param> /// <returns></returns> private XYZ GetRayPoint(Transform conduit, Transform cabinet) { XYZ o1 = conduit.Origin; XYZ o2 = cabinet.Origin; XYZ v1 = conduit.BasisZ; XYZ v2 = o2.Subtract(o1); // double angle = v1.AngleTo(v2); double distDiagnal = o1.DistanceTo(o2); // 直角三角形中斜边的长度 // double dist = distDiagnal * Math.Cos(angle); // return(o1 + v1.Normalize() * dist); }
/// <summary> /// Offset the control points by specified distance. /// </summary> /// <param name="controlPoints">Control point to offset</param> /// <param name="offset">offset distance</param> /// <returns>Control points after offsetting</returns> static IList <XYZ> CalculateOffset(IList <XYZ> controlPoints, double offset) { IList <XYZ> innerPnts = new List <XYZ>(); for (int i = 1; i < controlPoints.Count - 1; i++) { XYZ dir1 = (controlPoints[i] - controlPoints[i - 1]).Normalize(); XYZ dir2 = (controlPoints[i + 1] - controlPoints[i]).Normalize(); // Calculate the bisect direction of the corner. XYZ bisectDir = (dir2 - dir1).Normalize(); // Calculate the step direction of the fist line. XYZ stepInside1stDir = new XYZ(-dir1.Y, dir1.X, 0.0); if (stepInside1stDir.DotProduct(bisectDir) < 0.0) { stepInside1stDir = stepInside1stDir.Negate(); } if (i == 1) { innerPnts.Add(controlPoints[i - 1] + stepInside1stDir * offset); } // Calculate the step direction of the second line. XYZ stepInside2ndDir = new XYZ(-dir2.Y, dir2.X, 0.0); if (stepInside2ndDir.DotProduct(bisectDir) < 0.0) { stepInside2ndDir = stepInside2ndDir.Negate(); } double semiAngle = bisectDir.AngleTo(dir2); double slopDist = offset / Math.Sin(semiAngle); // Calculate the corner points XYZ innerCornerPnt = controlPoints[i] + bisectDir * slopDist; innerPnts.Add(innerCornerPnt); if (i == controlPoints.Count - 2) { innerPnts.Add(controlPoints[i + 1] + stepInside2ndDir * offset); } } return(innerPnts); }
/// <summary> /// Yield the rotation transform according to current 2D point in canvas. /// </summary> /// <param name="currentPosition">2D point in canvas</param> private void Track(Point currentPosition) { XYZ currentPosition3D = ProjectToTrackball( m_canvasWidth, m_canvasHeight, currentPosition); XYZ axis = m_previousPosition3D.CrossProduct(currentPosition3D); if (axis.GetLength() == 0) { return; } double angle = m_previousPosition3D.AngleTo(currentPosition3D); m_rotation = Transform.CreateRotation(axis, -angle); m_previousPosition3D = currentPosition3D; }
//求Arc的切线的交点. public XYZ GetIntersectionByArcTangent(Arc arc) { XYZ center = arc.Center; XYZ start = arc.GetEndPoint(0); XYZ end = arc.GetEndPoint(1); Line line_start = Line.CreateBound(center, start); Line line_end = Line.CreateBound(center, end); XYZ direction_start = line_start.Direction; XYZ direction_end = line_end.Direction; XYZ direction_center = direction_start.Add(direction_end).Normalize(); double angle = direction_start.AngleTo(direction_center); double radius = arc.Radius; double length = radius / (Math.Cos(angle)); XYZ result = center.Add(direction_center.Multiply(length)); return(result); }
public static double GetAngle(XYZ targetVec, XYZ vecX, XYZ vecY) { vecX = vecX.Normalize(); vecY = vecY.Normalize(); XYZ vecZ = vecX.CrossProduct(vecY); double dot = vecZ.DotProduct(targetVec); if (!IsEqual(vecX.DotProduct(vecY), 0)) { throw new Exception("Two basis is not perpecular!"); } if (!IsEqual(vecX.CrossProduct(vecY).DotProduct(targetVec), 0)) { throw new Exception("TargetVector is not planar with two basis!"); } double angle = 0; double angle1 = vecX.AngleTo(targetVec); double angle2 = Math.PI - angle1; XYZ assVec = vecX * Math.Cos(angle1) + vecY * Math.Sin(angle1); if (IsSameDirection(assVec, targetVec)) { angle = angle1; } else if (IsOppositeDirection(assVec, targetVec)) { angle = -angle2; } else { assVec = vecX * Math.Cos(angle2) + vecY * Math.Sin(angle2); if (IsSameDirection(assVec, targetVec)) { angle = angle2; } else if (IsOppositeDirection(assVec, targetVec)) { angle = -angle1; } else { throw new Exception("The code should never go here!"); } } return(angle); }
public void RotateText(Document doc, TextElement textElement, Dimension dimension) { XYZ updirectiontext = Getupdirectionoftext(textElement); XYZ directionofdim = Getdirectiondim(dimension); double angle = directionofdim.AngleTo(updirectiontext); double Convertrado = UnitUtils.Convert(angle, DisplayUnitType.DUT_RADIANS, DisplayUnitType.DUT_DECIMAL_DEGREES); using (Transaction tran = new Transaction(doc, "Rotate Text")) { tran.Start(); if (Math.Round(Convertrado, 0) < 90) { double gocquay = 180 - Convertrado; var gh = UnitUtils.Convert(gocquay, DisplayUnitType.DUT_DECIMAL_DEGREES, DisplayUnitType.DUT_RADIANS); BoundingBoxXYZ boxXYZ = textElement.get_BoundingBox(doc.ActiveView); XYZ p1 = (boxXYZ.Max + boxXYZ.Min) / 2; XYZ p2 = p1 + 2 * doc.ActiveView.ViewDirection; Line line = Line.CreateBound(p1, p2); ElementTransformUtils.RotateElement(doc, textElement.Id, line, gh); var sau = Getupdirectionoftext(textElement); if (!sau.IsParallel(directionofdim)) { ElementTransformUtils.RotateElement(doc, textElement.Id, line, -2 * gh); } } else if (Math.Round(Convertrado, 0) > 90 || Math.Round(Convertrado, 0) == 90) { double gocquay = 180 - Convertrado; var gh = UnitUtils.Convert(gocquay, DisplayUnitType.DUT_DECIMAL_DEGREES, DisplayUnitType.DUT_RADIANS); BoundingBoxXYZ boxXYZ = textElement.get_BoundingBox(doc.ActiveView); XYZ p1 = (boxXYZ.Max + boxXYZ.Min) / 2; XYZ p2 = p1 + 2 * doc.ActiveView.ViewDirection; Line line = Line.CreateBound(p1, p2); ElementTransformUtils.RotateElement(doc, textElement.Id, line, gh); var sau = Getupdirectionoftext(textElement); if (!sau.IsParallel(directionofdim)) { ElementTransformUtils.RotateElement(doc, textElement.Id, line, -2 * gh); } } tran.Commit(); } }
public List <double> angleplan_anglevert(double PK, IList <XYZ> list_pts) { List <double> sortie = new List <double>(); List <double> list_PK = new List <double>(); double inc_PK = 0; for (int i = 0; i < list_pts.Count - 1; i++) { double distance = (new XYZ(list_pts[i].X, list_pts[i].Y, 0)).DistanceTo(new XYZ(list_pts[i + 1].X, list_pts[i + 1].Y, 0)); inc_PK += distance; list_PK.Add(inc_PK); } for (int i = 0; i < list_PK.Count; i++) { if (list_PK[i] > PK) { XYZ n_plan = (new XYZ(list_pts[i + 1].X - list_pts[i].X, list_pts[i + 1].Y - list_pts[i].Y, 0)).Normalize(); XYZ axe_Y = new XYZ(0, 1, 0); double angleplan = n_plan.AngleTo(axe_Y); sortie.Add(angleplan); double opp = list_pts[i + 1].Z - list_pts[i].Z; double hyp = list_pts[i].DistanceTo(list_pts[i + 1]); double anglevert = Math.Asin(Math.Abs(opp) / hyp); if (opp >= 0) { sortie.Add(anglevert); } else { sortie.Add(-anglevert); } return(sortie); } } return(sortie); }
/// <summary> /// calculates the transformed location of four vertices (<code>top_left</code>, <code>top_right</code>, <code>bottom_left</code>, <code>bottom_right</code>) defining a plane to be axis-aligned. /// </summary> /// <param name="top_left"></param> /// <param name="top_right"></param> /// <param name="bottom_left"></param> /// <param name="bottom_right"></param> /// <param name="axis_aligned_top_left"></param> /// <param name="axis_aligned_top_right"></param> /// <param name="axis_aligned_bottom_left"></param> /// <param name="axis_aligned_bottom_right"></param> /// <param name="rotation_axis"></param> /// <param name="rotation_angle"></param> /// <param name="translation_offset"></param> protected static void GetAxisAlignedPlane( XYZ top_left, XYZ top_right, XYZ bottom_left, XYZ bottom_right, out XYZ axis_aligned_top_left, out XYZ axis_aligned_top_right, out XYZ axis_aligned_bottom_left, out XYZ axis_aligned_bottom_right, out XYZ rotation_axis, out double rotation_angle, out XYZ translation_offset) { translation_offset = -(top_left + top_right + bottom_left + bottom_right) / 4; Transform translate = Transform.CreateTranslation(translation_offset); XYZ u = (bottom_right - bottom_left).Normalize(); XYZ v = (top_left - bottom_left).Normalize(); XYZ normal = u.CrossProduct(v); rotation_angle = normal.AngleTo(XYZ.BasisZ); rotation_axis = normal.CrossProduct(XYZ.BasisZ); Transform rotate = Transform.CreateRotation(rotation_axis, rotation_angle); axis_aligned_top_left = rotate.OfPoint(translate.OfPoint(top_left)); axis_aligned_top_right = rotate.OfPoint(translate.OfPoint(top_right)); axis_aligned_bottom_left = rotate.OfPoint(translate.OfPoint(bottom_left)); axis_aligned_bottom_right = rotate.OfPoint(translate.OfPoint(bottom_right)); }
// Absolute angle from curve to curve ONLY on basic horizontal plan public static double AngleBetweenCrv(Curve crv1, Curve crv2, XYZ axis) { XYZ pt_origin = new XYZ(); Line line1 = crv1 as Line; Line line2 = crv2 as Line; XYZ vec1 = line1.Direction.Normalize(); XYZ vec2 = line2.Direction.Normalize(); //XYZ vec1 = crv1.ComputeDerivatives(crv1.GetEndParameter(0), true).OfPoint(pt_origin); //XYZ vec2 = crv2.ComputeDerivatives(crv2.GetEndParameter(0), true).OfPoint(pt_origin); XYZ testVec = vec1.CrossProduct(vec2).Normalize(); double testAngle = vec1.AngleTo(vec2); if (testVec.IsAlmostEqualTo(axis.Normalize())) { return(testAngle); } else { return(2 * Math.PI - testAngle); } }
public void Add(Pipe pipe) { var parallelVector = ((pipe.Location as LocationCurve).Curve as Line).Direction; parallelVector = new XYZ(parallelVector.X, parallelVector.Y, 0); parallelVector = LocationHelper.GetVectorByQuadrant(parallelVector, QuadrantType.OneAndFour); var slope = Math.Round(parallelVector.AngleTo(ReferenceDirection), 2); var slopePipes = this.FirstOrDefault(c => c.Slope == slope); if (slopePipes == null) { Add(new SlopePipes(slope, pipe)); } else { var pipePoint = LocationHelper.ToSameZ((pipe.Location as LocationCurve).Curve.GetEndPoint(0), slopePipes.ReferencePoint0); var projectPoint = slopePipes.ReferenceLine.Project(pipePoint).XYZPoint; var line = pipePoint - projectPoint; var skew = new XYZ(line.X, line.Y, 0).GetLength(); slopePipes.SkewPipes.Add(new SkewPipe(skew, pipe)); } }
public double GetAngleViewtoWall(XYZ elevViewSectionNormal, Wall w) { LocationCurve wallCurve = w.Location as LocationCurve; Arc wallCurveAsArc = wallCurve.Curve as Arc; Double angleViewtoWall; if ((wallCurveAsArc) != null) { double curveNormal = NormalofCurvedWall(w, out bool concave); angleViewtoWall = curveNormal - Math.PI; } else { XYZ wallNormal = w.Orientation; angleViewtoWall = Math.PI - wallNormal.AngleTo(elevViewSectionNormal); if (w.CurtainGrid != null) { angleViewtoWall -= Math.PI; } if (wallNormal.Y < 0) { angleViewtoWall = -angleViewtoWall; } } if (angleViewtoWall < 0) { angleViewtoWall += 2 * Math.PI; } return(angleViewtoWall); }
public Arc Chamfer(Line line1, Line line2, double radius, out Line newline1, out Line newline2) { List <Line> lines = TwoLineOneOrigin(line1, line2); //get intersection XYZ intersection = GetIntersection(line1, line2); if (intersection == null) { newline1 = null; newline2 = null; return(null); } XYZ direction_line1 = lines[0].Direction; XYZ direction_line2 = lines[1].Direction; double angle = direction_line1.AngleTo(direction_line2); if (angle > Math.PI) { angle = Math.PI * 2 - angle; } XYZ point_arc_start = intersection.Add(direction_line1.Multiply(radius / (Math.Tan(angle / 2)))); XYZ point_arc_end = intersection.Add(direction_line2.Multiply(radius / (Math.Tan(angle / 2)))); XYZ direction_line3 = direction_line1.Add(direction_line2).Normalize(); XYZ point_arc_middle = intersection.Add(direction_line3.Multiply((radius / Math.Sin(angle / 2)) - radius)); Arc arc = Arc.Create(point_arc_start, point_arc_end, point_arc_middle); newline1 = Line.CreateBound(point_arc_start, lines[0].GetEndPoint(1)); newline2 = Line.CreateBound(point_arc_end, lines[1].GetEndPoint(1)); return(arc); }
//method to find all the parallel tray/duct to element public ICollection <ElementId> ParallelElements(Document m_doc, Element ele) { try { const double _eps = 1.0e-9; ICollection <ElementId> parallel = new List <ElementId>(); Line eleLine = ((LocationCurve)ele.Location).Curve as Line; XYZ eleNormal = (eleLine.GetEndPoint(0) - eleLine.GetEndPoint(1)).CrossProduct(XYZ.BasisZ).Normalize(); foreach (Element e in trayDuctlist) { if (ele != e) { Line tempLine = ((LocationCurve)e.Location).Curve as Line; XYZ normal = (tempLine.GetEndPoint(0) - tempLine.GetEndPoint(1)).CrossProduct(XYZ.BasisZ).Normalize(); double angle = normal.AngleTo(eleNormal); if ((_eps > angle || Math.Abs(angle - Math.PI) < _eps) && eleLine.GetEndPoint(0).Z != tempLine.GetEndPoint(0).Z) { parallel.Add(e.Id); } } } return(parallel); } catch { throw new Exception(); } }
private void ModifyObjects(List<RevitObject> existingObjects, List<ElementId> existingElems, Document doc, Guid uniqueId, bool profileWarning, string nickName, int runId) { // Create new Revit objects. //List<LyrebirdId> newUniqueIds = new List<LyrebirdId>(); // Determine what kind of object we're creating. RevitObject ro = existingObjects[0]; #region Normal Origin based FamilyInstance // Modify origin based family instances if (ro.Origin != null) { // Find the FamilySymbol FamilySymbol symbol = FindFamilySymbol(ro.FamilyName, ro.TypeName, doc); LevelType lt = FindLevelType(ro.TypeName, doc); GridType gt = FindGridType(ro.TypeName, doc); if (symbol != null || lt != null) { // Get the hosting ID from the family. Family fam = null; Parameter hostParam = null; int hostBehavior = 0; try { fam = symbol.Family; hostParam = fam.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR); hostBehavior = hostParam.AsInteger(); } catch{} //FamilyInstance existingInstance = doc.GetElement(existingElems[0]) as FamilyInstance; using (Transaction t = new Transaction(doc, "Lyrebird Modify Objects")) { t.Start(); try { Schema instanceSchema = null; try { instanceSchema = Schema.Lookup(instanceSchemaGUID); } catch (Exception ex) { Debug.WriteLine(ex.Message); } if (instanceSchema == null) { SchemaBuilder sb = new SchemaBuilder(instanceSchemaGUID); sb.SetWriteAccessLevel(AccessLevel.Vendor); sb.SetReadAccessLevel(AccessLevel.Public); sb.SetVendorId("LMNA"); // Create the field to store the data in the family FieldBuilder guidFB = sb.AddSimpleField("InstanceID", typeof(string)); guidFB.SetDocumentation("Component instance GUID from Grasshopper"); // Create a filed to store the run number FieldBuilder runIDFB = sb.AddSimpleField("RunID", typeof(int)); runIDFB.SetDocumentation("RunID for when multiple runs are created from the same data"); // Create a field to store the GH component nickname. FieldBuilder nickNameFB = sb.AddSimpleField("NickName", typeof(string)); nickNameFB.SetDocumentation("Component NickName from Grasshopper"); sb.SetSchemaName("LMNAInstanceGUID"); instanceSchema = sb.Finish(); } FamilyInstance fi = null; XYZ origin = XYZ.Zero; if (lt != null) { for (int i = 0; i < existingObjects.Count; i++) { RevitObject obj = existingObjects[i]; Level lvl = doc.GetElement(existingElems[i]) as Level; if (lvl.ProjectElevation != (UnitUtils.ConvertToInternalUnits(obj.Origin.Z, lengthDUT))) { double offset = lvl.Elevation - lvl.ProjectElevation; lvl.Elevation = (UnitUtils.ConvertToInternalUnits(obj.Origin.Z + offset, lengthDUT)); } SetParameters(lvl, obj.Parameters, doc); } } else if (hostBehavior == 0) { for (int i = 0; i < existingObjects.Count; i++) { RevitObject obj = existingObjects[i]; fi = doc.GetElement(existingElems[i]) as FamilyInstance; // Change the family and symbol if necessary if (fi != null && (fi.Symbol.Family.Name != symbol.Family.Name || fi.Symbol.Name != symbol.Name)) { try { fi.Symbol = symbol; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } try { // Move family origin = new XYZ(UnitUtils.ConvertToInternalUnits(obj.Origin.X, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Z, lengthDUT)); if (fi != null) { LocationPoint lp = fi.Location as LocationPoint; if (lp != null) { XYZ oldLoc = lp.Point; XYZ translation = origin.Subtract(oldLoc); ElementTransformUtils.MoveElement(doc, fi.Id, translation); } } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } // Rotate if (obj.Orientation != null) { if (Math.Round(Math.Abs(obj.Orientation.Z - 0), 10) < double.Epsilon) { XYZ orientation = fi.FacingOrientation; orientation = orientation.Multiply(-1); XYZ incomingOrientation = new XYZ(obj.Orientation.X, obj.Orientation.Y, obj.Orientation.Z); XYZ normalVector = new XYZ(0, -1, 0); double currentAngle = 0; if (orientation.X < 0 && orientation.Y < 0) { currentAngle = (2 * Math.PI) - normalVector.AngleTo(orientation); } else if (orientation.Y == 0 && orientation.X < 0) { currentAngle = 1.5 * Math.PI; } else if (orientation.X < 0) { currentAngle = (Math.PI - normalVector.AngleTo(orientation)) + Math.PI; } else { currentAngle = normalVector.AngleTo(orientation); } double incomingAngle = 0; if (incomingOrientation.X < 0 && incomingOrientation.Y < 0) { incomingAngle = (2 * Math.PI) - normalVector.AngleTo(incomingOrientation); } else if (incomingOrientation.Y == 0 && incomingOrientation.X < 0) { incomingAngle = 1.5 * Math.PI; } else if (incomingOrientation.X < 0) { incomingAngle = (Math.PI - normalVector.AngleTo(incomingOrientation)) + Math.PI; } else { incomingAngle = normalVector.AngleTo(incomingOrientation); } double angle = incomingAngle - currentAngle; //TaskDialog.Show("Test", "CurrentAngle: " + currentAngle.ToString() + "\nIncoming Angle: " + incomingAngle.ToString() + "\nResulting Rotation: " + angle.ToString() + // "\nFacingOrientation: " + orientation.ToString() + "\nIncoming Orientation: " + incomingOrientation.ToString()); Line axis = Line.CreateBound(origin, origin + XYZ.BasisZ); ElementTransformUtils.RotateElement(doc, fi.Id, axis, angle); } } SetParameters(fi, obj.Parameters, doc); } } else { for (int i = 0; i < existingObjects.Count; i++) { RevitObject obj = existingObjects[i]; fi = doc.GetElement(existingElems[i]) as FamilyInstance; // Change the family and symbol if necessary if (fi.Symbol.Family.Name != symbol.Family.Name || fi.Symbol.Name != symbol.Name) { try { fi.Symbol = symbol; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } origin = new XYZ(UnitUtils.ConvertToInternalUnits(obj.Origin.X, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Z, lengthDUT)); // Find the level List<LyrebirdPoint> lbPoints = new List<LyrebirdPoint> { obj.Origin }; Level lvl = GetLevel(lbPoints, doc); // Get the host if (hostBehavior == 5) { // Face based family. Find the face and create the element XYZ normVector = new XYZ(obj.Orientation.X, obj.Orientation.Y, obj.Orientation.Z); XYZ faceVector; if (obj.FaceOrientation != null) { faceVector = new XYZ(obj.FaceOrientation.X, obj.FaceOrientation.Y, obj.FaceOrientation.Z); } else { faceVector = XYZ.BasisZ; } Face face = FindFace(origin, normVector, doc); if (face != null) { if (face.Reference.ElementId == fi.HostFace.ElementId) { //fi = doc.Create.NewFamilyInstance(face, origin, faceVector, symbol); // Just move the host and update the parameters as needed. LocationPoint lp = fi.Location as LocationPoint; if (lp != null) { XYZ oldLoc = lp.Point; XYZ translation = origin.Subtract(oldLoc); ElementTransformUtils.MoveElement(doc, fi.Id, translation); } SetParameters(fi, obj.Parameters, doc); } else { FamilyInstance origInst = fi; fi = doc.Create.NewFamilyInstance(face, origin, faceVector, symbol); foreach (Parameter p in origInst.Parameters) { try { Parameter newParam = fi.get_Parameter(p.GUID); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Delete the original instance of the family doc.Delete(origInst.Id); // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); } } } else { // typical hosted family. Can be wall, floor, roof or ceiling. ElementId host = FindHost(origin, hostBehavior, doc); if (host != null) { if (host.IntegerValue != fi.Host.Id.IntegerValue) { // We'll have to recreate the element FamilyInstance origInst = fi; fi = doc.Create.NewFamilyInstance(origin, symbol, doc.GetElement(host), lvl, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); foreach (Parameter p in origInst.Parameters) { try { Parameter newParam = fi.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Delete the original instance of the family doc.Delete(origInst.Id); // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); } else { // Just move the host and update the parameters as needed. LocationPoint lp = fi.Location as LocationPoint; if (lp != null) { XYZ oldLoc = lp.Point; XYZ translation = origin.Subtract(oldLoc); ElementTransformUtils.MoveElement(doc, fi.Id, translation); } // Assign the parameters SetParameters(fi, obj.Parameters, doc); } } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); } // delete the host finder ElementId hostFinderFamily = hostFinder.Symbol.Family.Id; doc.Delete(hostFinder.Id); doc.Delete(hostFinderFamily); hostFinder = null; } } catch (Exception ex) { Debug.WriteLine(ex.Message); } t.Commit(); } } } #endregion #region Adaptive Components FamilyInstance adaptInst; try { adaptInst = doc.GetElement(existingElems[0]) as FamilyInstance; } catch { adaptInst = null; } if (adaptInst != null && AdaptiveComponentInstanceUtils.IsAdaptiveComponentInstance(adaptInst)) { // Find the FamilySymbol FamilySymbol symbol = FindFamilySymbol(ro.FamilyName, ro.TypeName, doc); if (symbol != null) { using (Transaction t = new Transaction(doc, "Lyrebird Modify Objects")) { t.Start(); try { // Create the Schema for the instances to store the GH Component InstanceGUID and the path Schema instanceSchema = null; try { instanceSchema = Schema.Lookup(instanceSchemaGUID); } catch (Exception ex) { Debug.WriteLine(ex.Message); } if (instanceSchema == null) { SchemaBuilder sb = new SchemaBuilder(instanceSchemaGUID); sb.SetWriteAccessLevel(AccessLevel.Vendor); sb.SetReadAccessLevel(AccessLevel.Public); sb.SetVendorId("LMNA"); // Create the field to store the data in the family FieldBuilder guidFB = sb.AddSimpleField("InstanceID", typeof(string)); guidFB.SetDocumentation("Component instance GUID from Grasshopper"); // Create a filed to store the run number FieldBuilder runIDFB = sb.AddSimpleField("RunID", typeof(int)); runIDFB.SetDocumentation("RunID for when multiple runs are created from the same data"); // Create a field to store the GH component nickname. FieldBuilder nickNameFB = sb.AddSimpleField("NickName", typeof(string)); nickNameFB.SetDocumentation("Component NickName from Grasshopper"); sb.SetSchemaName("LMNAInstanceGUID"); instanceSchema = sb.Finish(); } try { for (int i = 0; i < existingElems.Count; i++) { RevitObject obj = existingObjects[i]; FamilyInstance fi = doc.GetElement(existingElems[i]) as FamilyInstance; // Change the family and symbol if necessary if (fi.Symbol.Family.Name != symbol.Family.Name || fi.Symbol.Name != symbol.Name) { try { fi.Symbol = symbol; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } IList<ElementId> placePointIds = new List<ElementId>(); placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(fi); for (int ptNum = 0; ptNum < obj.AdaptivePoints.Count; ptNum++) { try { ReferencePoint rp = doc.GetElement(placePointIds[ptNum]) as ReferencePoint; XYZ pt = new XYZ(UnitUtils.ConvertToInternalUnits(obj.AdaptivePoints[ptNum].X, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.AdaptivePoints[ptNum].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.AdaptivePoints[ptNum].Z, lengthDUT)); XYZ vector = pt.Subtract(rp.Position); ElementTransformUtils.MoveElement(doc, rp.Id, vector); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } t.Commit(); } } } #endregion #region Curve based components if (ro.Curves != null && ro.Curves.Count > 0) { // Find the FamilySymbol FamilySymbol symbol = null; WallType wallType = null; FloorType floorType = null; RoofType roofType = null; GridType gridType = null; bool typeFound = false; FilteredElementCollector famCollector = new FilteredElementCollector(doc); if (ro.CategoryId == -2000011) { famCollector.OfClass(typeof(WallType)); foreach (WallType wt in famCollector) { if (wt.Name == ro.TypeName) { wallType = wt; typeFound = true; break; } } } else if (ro.CategoryId == -2000032) { famCollector.OfClass(typeof(FloorType)); foreach (FloorType ft in famCollector) { if (ft.Name == ro.TypeName) { floorType = ft; typeFound = true; break; } } } else if (ro.CategoryId == -2000035) { famCollector.OfClass(typeof(RoofType)); foreach (RoofType rt in famCollector) { if (rt.Name == ro.TypeName) { roofType = rt; typeFound = true; break; } } } else if (ro.CategoryId == -2000220) { famCollector.OfClass(typeof(GridType)); foreach (GridType gt in famCollector) { if (gt.Name == ro.TypeName) { gridType = gt; typeFound = true; break; } } } else { symbol = FindFamilySymbol(ro.FamilyName, ro.TypeName, doc); if (symbol != null) typeFound = true; } if (typeFound) { using (Transaction t = new Transaction(doc, "Lyrebird Modify Objects")) { t.Start(); try { // Create the Schema for the instances to store the GH Component InstanceGUID and the path Schema instanceSchema = null; try { instanceSchema = Schema.Lookup(instanceSchemaGUID); } catch (Exception ex) { Debug.WriteLine(ex.Message); } if (instanceSchema == null) { SchemaBuilder sb = new SchemaBuilder(instanceSchemaGUID); sb.SetWriteAccessLevel(AccessLevel.Vendor); sb.SetReadAccessLevel(AccessLevel.Public); sb.SetVendorId("LMNA"); // Create the field to store the data in the family FieldBuilder guidFB = sb.AddSimpleField("InstanceID", typeof(string)); guidFB.SetDocumentation("Component instance GUID from Grasshopper"); // Create a filed to store the run number FieldBuilder runIDFB = sb.AddSimpleField("RunID", typeof(int)); runIDFB.SetDocumentation("RunID for when multiple runs are created from the same data"); // Create a field to store the GH component nickname. FieldBuilder nickNameFB = sb.AddSimpleField("NickName", typeof(string)); nickNameFB.SetDocumentation("Component NickName from Grasshopper"); sb.SetSchemaName("LMNAInstanceGUID"); instanceSchema = sb.Finish(); } FamilyInstance fi = null; Grid grid = null; try { bool supress = Properties.Settings.Default.suppressWarning; bool supressedReplace = false; bool supressedModify = true; for (int i = 0; i < existingObjects.Count; i++) { RevitObject obj = existingObjects[i]; if (obj.CategoryId != -2000011 && obj.CategoryId != -2000032 && obj.CategoryId != -2000035 && obj.CategoryId != -2000220) { fi = doc.GetElement(existingElems[i]) as FamilyInstance; // Change the family and symbol if necessary if (fi.Symbol.Family.Name != symbol.Family.Name || fi.Symbol.Name != symbol.Name) { try { fi.Symbol = symbol; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } } else if (obj.CategoryId == -2000220) { grid = doc.GetElement(existingElems[i]) as Grid; // Get the grid location and compare against the incoming curve Curve gridCrv = grid.Curve; LyrebirdCurve lbc = obj.Curves[0]; try { Arc arc = gridCrv as Arc; if (arc != null && lbc.CurveType == "Arc") { // Test that the arcs are similar XYZ startPoint = arc.GetEndPoint(0); XYZ endPoint = arc.GetEndPoint(1); XYZ centerPoint = arc.Center; double rad = arc.Radius; XYZ lbcStartPt = new XYZ(lbc.ControlPoints[0].X, lbc.ControlPoints[0].Y, lbc.ControlPoints[0].Z); XYZ lbcEndPt = new XYZ(lbc.ControlPoints[1].X, lbc.ControlPoints[1].Y, lbc.ControlPoints[1].Z); XYZ lbcMidPt = new XYZ(lbc.ControlPoints[2].X, lbc.ControlPoints[2].Y, lbc.ControlPoints[2].Z); Arc lbcArc = Arc.Create(lbcStartPt, lbcEndPt, lbcMidPt); XYZ lbcCenterPt = lbcArc.Center; double lbcRad = lbcArc.Radius; if (centerPoint.DistanceTo(lbcCenterPt) < 0.001 && lbcRad == rad && startPoint.DistanceTo(lbcStartPt) < 0.001) { // Do not create } else { // Delete the grid and rebuild it with the new curve. } } else { // Probably need to rebuild the curve } } catch { } try { Line line = gridCrv as Line; if (line != null && lbc.CurveType == "Line") { // Test that the arcs are similar XYZ startPoint = line.GetEndPoint(0); XYZ endPoint = line.GetEndPoint(1); XYZ lbcStartPt = new XYZ(lbc.ControlPoints[0].X, lbc.ControlPoints[0].Y, lbc.ControlPoints[0].Z); XYZ lbcEndPt = new XYZ(lbc.ControlPoints[1].X, lbc.ControlPoints[1].Y, lbc.ControlPoints[1].Z); if (endPoint.DistanceTo(lbcEndPt) < 0.001 && startPoint.DistanceTo(lbcStartPt) < 0.001) { // Do not create } else { // Delete the grid and rebuild it with the new curve. } } else { // Probably need to rebuild the curve } } catch { } if (grid.GridType.Name != gridType.Name) { try { grid.GridType = gridType; } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); Debug.WriteLine(ex.Message); } } } #region single line based family if (obj.Curves.Count == 1 && obj.Curves[0].CurveType != "Circle") { LyrebirdCurve lbc = obj.Curves[0]; List<LyrebirdPoint> curvePoints = lbc.ControlPoints.OrderBy(p => p.Z).ToList(); // linear // can be a wall or line based family. // Wall objects if (obj.CategoryId == -2000011) { // draw a wall Curve crv = null; if (lbc.CurveType == "Line") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(pt1, pt2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); crv = Arc.Create(pt1, pt3, pt2); } if (crv != null) { // Find the level Level lvl = GetLevel(lbc.ControlPoints, doc); double offset = 0; if (Math.Abs(UnitUtils.ConvertToInternalUnits(curvePoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = lvl.Elevation - UnitUtils.ConvertToInternalUnits(curvePoints[0].Z, lengthDUT); } // Modify the wall Wall w = null; try { w = doc.GetElement(existingElems[i]) as Wall; LocationCurve lc = w.Location as LocationCurve; lc.Curve = crv; // Change the family and symbol if necessary if (w.WallType.Name != wallType.Name) { try { w.WallType = wallType; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } } catch (Exception ex) { TaskDialog.Show("ERROR", ex.Message); } // Assign the parameters SetParameters(w, obj.Parameters, doc); } } // See if it's a structural column else if (obj.CategoryId == -2001330) { if (symbol != null && lbc.CurveType == "Line") { Curve crv = null; XYZ origin = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(origin, pt2); // Find the level //Level lvl = GetLevel(lbc.ControlPoints, doc); // Create the column //fi = doc.Create.NewFamilyInstance(origin, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.Column); // Change it to a slanted column Parameter slantParam = fi.get_Parameter(BuiltInParameter.SLANTED_COLUMN_TYPE_PARAM); // SlantedOrVerticalColumnType has 3 options, CT_Vertical (0), CT_Angle (1), or CT_EndPoint (2) // CT_EndPoint is what we want for a line based column. slantParam.Set(2); // Set the location curve of the column to the line LocationCurve lc = fi.Location as LocationCurve; if (lc != null) { lc.Curve = crv; } // Change the family and symbol if necessary if (fi.Symbol.Name != symbol.Name) { try { fi.Symbol = symbol; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); } } else if (obj.CategoryId == -2000220) { // draw a grid Curve crv = null; if (lbc.CurveType == "Line") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(pt1, pt2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); crv = Arc.Create(pt1, pt3, pt2); } if (crv != null && grid != null) { // Determine if it's possible to edit the grid curve or if it needs to be deleted/replaced. // Assign the parameters SetParameters(grid, obj.Parameters, doc); } } // Otherwise create a family it using the line else { if (symbol != null) { Curve crv = null; if (lbc.CurveType == "Line") { XYZ origin = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(origin, pt2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); crv = Arc.Create(pt1, pt3, pt2); } // Change the family and symbol if necessary if (fi.Symbol.Name != symbol.Name) { try { fi.Symbol = symbol; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } try { LocationCurve lc = fi.Location as LocationCurve; lc.Curve = crv; } catch (Exception ex) { Debug.WriteLine(ex.Message); } // Assign the parameters SetParameters(fi, obj.Parameters, doc); } } } #endregion #region Closed Curve Family else { bool replace = false; if (supress) { if (supressedReplace) { replace = true; } else { replace = false; } } if (profileWarning && !supress) { TaskDialog warningDlg = new TaskDialog("Warning") { MainInstruction = "Profile based Elements warning", MainContent = "Elements that require updates to a profile sketch may not be updated if the number of curves in the sketch differs from the incoming curves." + " In such cases the element and will be deleted and replaced with new elements." + " Doing so will cause the loss of any elements hosted to the original instance. How would you like to proceed" }; warningDlg.AddCommandLink(TaskDialogCommandLinkId.CommandLink1, "Replace the existing elements, understanding hosted elements may be lost"); warningDlg.AddCommandLink(TaskDialogCommandLinkId.CommandLink2, "Only updated parameter information and not profile or location information"); warningDlg.AddCommandLink(TaskDialogCommandLinkId.CommandLink3, "Cancel"); //warningDlg.VerificationText = "Supress similar warnings"; TaskDialogResult result = warningDlg.Show(); if (result == TaskDialogResult.CommandLink1) { replace = true; supressedReplace = true; supressedModify = true; //supress = warningDlg.WasVerificationChecked(); } if (result == TaskDialogResult.CommandLink2) { supressedReplace = false; supressedModify = true; //supress = warningDlg.WasVerificationChecked(); } if (result == TaskDialogResult.CommandLink3) { supressedReplace = false; supressedModify = false; //supress = warningDlg.WasVerificationChecked(); } } // A list of curves. These should equate a closed planar curve from GH. // Determine category and create based on that. #region walls if (obj.CategoryId == -2000011) { // Create line based wall // Find the level Level lvl = null; double offset = 0; List<LyrebirdPoint> allPoints = new List<LyrebirdPoint>(); foreach (LyrebirdCurve lc in obj.Curves) { foreach (LyrebirdPoint lp in lc.ControlPoints) { allPoints.Add(lp); } } allPoints.Sort((x, y) => x.Z.CompareTo(y.Z)); lvl = GetLevel(allPoints, doc); if (Math.Abs(allPoints[0].Z - lvl.Elevation) > double.Epsilon) { offset = allPoints[0].Z - lvl.Elevation; } // Generate the curvearray from the incoming curves List<Curve> crvArray = new List<Curve>(); try { foreach (LyrebirdCurve lbc in obj.Curves) { if (lbc.CurveType == "Circle") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); XYZ pt4 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].Z, lengthDUT)); XYZ pt5 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].Z, lengthDUT)); Arc arc1 = Arc.Create(pt1, pt3, pt2); Arc arc2 = Arc.Create(pt3, pt5, pt4); crvArray.Add(arc1); crvArray.Add(arc2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); Arc arc = Arc.Create(pt1, pt3, pt2); crvArray.Add(arc); } else if (lbc.CurveType == "Line") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); Line line = Line.CreateBound(pt1, pt2); crvArray.Add(line); } else if (lbc.CurveType == "Spline") { List<XYZ> controlPoints = new List<XYZ>(); List<double> weights = lbc.Weights; List<double> knots = lbc.Knots; foreach (LyrebirdPoint lp in lbc.ControlPoints) { XYZ pt = new XYZ(UnitUtils.ConvertToInternalUnits(lp.X, lengthDUT), UnitUtils.ConvertToInternalUnits(lp.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lp.Z, lengthDUT)); controlPoints.Add(pt); } NurbSpline spline; if (lbc.Degree < 3) spline = NurbSpline.Create(controlPoints, weights); else spline = NurbSpline.Create(controlPoints, weights, knots, lbc.Degree, false, true); crvArray.Add(spline); } } } catch (Exception ex) { TaskDialog.Show("ERROR", ex.Message); } // Create the wall Wall w = null; if (replace) { Wall origWall = doc.GetElement(existingElems[i]) as Wall; // Find the model curves for the original wall ICollection<ElementId> ids; using (SubTransaction st = new SubTransaction(doc)) { st.Start(); ids = doc.Delete(origWall.Id); st.RollBack(); } List<ModelCurve> mLines = new List<ModelCurve>(); foreach (ElementId id in ids) { Element e = doc.GetElement(id); if (e is ModelCurve) { mLines.Add(e as ModelCurve); } } // Walls don't appear to be updatable like floors and roofs //if (mLines.Count != crvArray.Count) //{ w = Wall.Create(doc, crvArray, wallType.Id, lvl.Id, false); foreach (Parameter p in origWall.Parameters) { try { Parameter newParam = w.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { //TaskDialog.Show("Errorsz", ex.Message); Debug.WriteLine(ex.Message); } } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = w.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET); p.Set(offset); } doc.Delete(origWall.Id); // Assign the parameters SetParameters(w, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(w, uniqueId, instanceSchema, runId, nickName); } else if (supressedModify) // Just update the parameters and don't change the wall { w = doc.GetElement(existingElems[i]) as Wall; // Change the family and symbol if necessary if (w.WallType.Name != wallType.Name) { try { w.WallType = wallType; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(w, obj.Parameters, doc); } } #endregion #region floors else if (obj.CategoryId == -2000032) { // Create a profile based floor // Find the level Level lvl = GetLevel(obj.Curves[0].ControlPoints, doc); double offset = 0; if (Math.Abs(UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation; } // Generate the curvearray from the incoming curves CurveArray crvArray = GetCurveArray(obj.Curves); // Create the floor Floor flr = null; if (replace) { Floor origFloor = doc.GetElement(existingElems[i]) as Floor; // Find the model curves for the original wall ICollection<ElementId> ids; using (SubTransaction st = new SubTransaction(doc)) { st.Start(); ids = doc.Delete(origFloor.Id); st.RollBack(); } // Get only the modelcurves List<ModelCurve> mLines = new List<ModelCurve>(); foreach (ElementId id in ids) { Element e = doc.GetElement(id); if (e is ModelCurve) { mLines.Add(e as ModelCurve); } } // Floors have an extra modelcurve for the SpanDirection. Remove the last Item to get rid of it. mLines.RemoveAt(mLines.Count - 1); if (mLines.Count != crvArray.Size) // The sketch is different from the incoming curves so floor is recreated { if (obj.CurveIds != null && obj.CurveIds.Count > 0) { // get the main profile int crvCount = obj.CurveIds[0]; List<LyrebirdCurve> primaryCurves = obj.Curves.GetRange(0, crvCount); crvArray = GetCurveArray(primaryCurves); flr = doc.Create.NewFloor(crvArray, floorType, lvl, false); } else { flr = doc.Create.NewFloor(crvArray, floorType, lvl, false); } foreach (Parameter p in origFloor.Parameters) { try { Parameter newParam = flr.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = flr.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM); p.Set(offset); } doc.Delete(origFloor.Id); // Assign the parameters SetParameters(flr, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(flr, uniqueId, instanceSchema, runId, nickName); } else // The curves coming in should match the floor sketch. Let's modify the floor's locationcurves to edit it's location/shape { try { int crvCount = 0; foreach (ModelCurve l in mLines) { LocationCurve lc = l.Location as LocationCurve; lc.Curve = crvArray.get_Item(crvCount); crvCount++; } // Change the family and symbol if necessary if (origFloor.FloorType.Name != floorType.Name) { try { origFloor.FloorType = floorType; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Set the incoming parameters SetParameters(origFloor, obj.Parameters, doc); } catch // There was an error in trying to recreate it. Just delete the original and recreate the thing. { flr = doc.Create.NewFloor(crvArray, floorType, lvl, false); // Assign the parameters in the new floor to match the original floor object. foreach (Parameter p in origFloor.Parameters) { try { Parameter newParam = flr.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception exception) { Debug.WriteLine(exception.Message); } } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = flr.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM); p.Set(offset); } doc.Delete(origFloor.Id); // Set the incoming parameters SetParameters(flr, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(flr, uniqueId, instanceSchema, runId, nickName); } } } else if (supressedModify) // Just modify the floor and don't risk replacing it. { flr = doc.GetElement(existingElems[i]) as Floor; // Change the family and symbol if necessary if (flr.FloorType.Name != floorType.Name) { try { flr.FloorType = floorType; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(flr, obj.Parameters, doc); } } #endregion else if (obj.CategoryId == -2000035) { // Create a RoofExtrusion // Find the level Level lvl = GetLevel(obj.Curves[0].ControlPoints, doc); double offset = 0; if (Math.Abs(UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation; } // Generate the curvearray from the incoming curves CurveArray crvArray = GetCurveArray(obj.Curves); // Create the roof FootPrintRoof roof = null; ModelCurveArray roofProfile = new ModelCurveArray(); if (replace) // Try to modify or create a new roof. { FootPrintRoof origRoof = doc.GetElement(existingElems[i]) as FootPrintRoof; // Find the model curves for the original wall ICollection<ElementId> ids; using (SubTransaction st = new SubTransaction(doc)) { st.Start(); ids = doc.Delete(origRoof.Id); st.RollBack(); } // Get the sketch curves for the roof object. List<ModelCurve> mLines = new List<ModelCurve>(); foreach (ElementId id in ids) { Element e = doc.GetElement(id); if (e is ModelCurve) { mLines.Add(e as ModelCurve); } } if (mLines.Count != crvArray.Size) // Sketch curves qty doesn't match up with the incoming cuves. Just recreate the roof. { roof = doc.Create.NewFootPrintRoof(crvArray, lvl, roofType, out roofProfile); // Match parameters from the original roof to it's new iteration. foreach (Parameter p in origRoof.Parameters) { try { Parameter newParam = roof.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = roof.get_Parameter(BuiltInParameter.ROOF_LEVEL_OFFSET_PARAM); p.Set(offset); } doc.Delete(origRoof.Id); // Set the new parameters SetParameters(roof, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(roof, uniqueId, instanceSchema, runId, nickName); } else // The curves qty lines up, lets try to modify the roof sketch so we don't have to replace it. { if (obj.CurveIds != null && obj.CurveIds.Count > 0) { // Just recreate the roof roof = doc.Create.NewFootPrintRoof(crvArray, lvl, roofType, out roofProfile); // Match parameters from the original roof to it's new iteration. foreach (Parameter p in origRoof.Parameters) { try { Parameter newParam = roof.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = roof.get_Parameter(BuiltInParameter.ROOF_LEVEL_OFFSET_PARAM); p.Set(offset); } // Set the parameters from the incoming data SetParameters(roof, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(roof, uniqueId, instanceSchema, runId, nickName); doc.Delete(origRoof.Id); } else { try { int crvCount = 0; foreach (ModelCurve l in mLines) { LocationCurve lc = l.Location as LocationCurve; lc.Curve = crvArray.get_Item(crvCount); crvCount++; } // Change the family and symbol if necessary if (origRoof.RoofType.Name != roofType.Name) { try { origRoof.RoofType = roofType; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } SetParameters(origRoof, obj.Parameters, doc); } catch // Modificaiton failed, lets just create a new roof. { roof = doc.Create.NewFootPrintRoof(crvArray, lvl, roofType, out roofProfile); // Match parameters from the original roof to it's new iteration. foreach (Parameter p in origRoof.Parameters) { try { Parameter newParam = roof.LookupParameter(p.Definition.Name); if (newParam != null) { switch (newParam.StorageType) { case StorageType.Double: newParam.Set(p.AsDouble()); break; case StorageType.ElementId: newParam.Set(p.AsElementId()); break; case StorageType.Integer: newParam.Set(p.AsInteger()); break; case StorageType.String: newParam.Set(p.AsString()); break; default: newParam.Set(p.AsString()); break; } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = roof.get_Parameter(BuiltInParameter.ROOF_LEVEL_OFFSET_PARAM); p.Set(offset); } // Set the parameters from the incoming data SetParameters(roof, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(roof, uniqueId, instanceSchema, runId, nickName); doc.Delete(origRoof.Id); } } } } else if (supressedModify) // Only update the parameters { roof = doc.GetElement(existingElems[i]) as FootPrintRoof; // Change the family and symbol if necessary if (roof.RoofType.Name != roofType.Name) { try { roof.RoofType = roofType; } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(roof, obj.Parameters, doc); } } } #endregion } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } t.Commit(); } } } #endregion //return succeeded; }
private void CreateObjects(List<RevitObject> revitObjects, Document doc, Guid uniqueId, int runId, string nickName) { // Create new Revit objects. //List<LyrebirdId> newUniqueIds = new List<LyrebirdId>(); // Get the levels from the project FilteredElementCollector lvlCollector = new FilteredElementCollector(doc); lvlCollector.OfClass(typeof(Level)).ToElements().OfType<Level>(); // Determine what kind of object we're creating. RevitObject ro = revitObjects[0]; #region Normal Origin based Family Instance if (ro.Origin != null) { // Find the FamilySymbol FamilySymbol symbol = FindFamilySymbol(ro.FamilyName, ro.TypeName, doc); LevelType lt = FindLevelType(ro.TypeName, doc); if (symbol != null || lt != null) { // Get the hosting ID from the family. Family fam = null; Parameter hostParam = null; int hostBehavior = 0; try { fam = symbol.Family; hostParam = fam.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR); hostBehavior = hostParam.AsInteger(); } catch{} using (Transaction t = new Transaction(doc, "Lyrebird Create Objects")) { t.Start(); try { // Create the Schema for the instances to store the GH Component InstanceGUID and the path Schema instanceSchema = null; try { instanceSchema = Schema.Lookup(instanceSchemaGUID); } catch (Exception ex) { Debug.WriteLine(ex.Message); } if (instanceSchema == null) { SchemaBuilder sb = new SchemaBuilder(instanceSchemaGUID); sb.SetWriteAccessLevel(AccessLevel.Vendor); sb.SetReadAccessLevel(AccessLevel.Public); sb.SetVendorId("LMNA"); // Create the field to store the data in the family FieldBuilder guidFB = sb.AddSimpleField("InstanceID", typeof(string)); guidFB.SetDocumentation("Component instance GUID from Grasshopper"); // Create a filed to store the run number FieldBuilder runIDFB = sb.AddSimpleField("RunID", typeof(int)); runIDFB.SetDocumentation("RunID for when multiple runs are created from the same data"); // Create a field to store the GH component nickname. FieldBuilder nickNameFB = sb.AddSimpleField("NickName", typeof(string)); nickNameFB.SetDocumentation("Component NickName from Grasshopper"); sb.SetSchemaName("LMNAInstanceGUID"); instanceSchema = sb.Finish(); } FamilyInstance fi = null; XYZ origin = XYZ.Zero; if (lt != null) { // Create a level for the object. foreach (RevitObject obj in revitObjects) { try { Level lvl = doc.Create.NewLevel(UnitUtils.ConvertToInternalUnits(obj.Origin.Z, lengthDUT)); lvl.LevelType = lt; // Set the parameters. SetParameters(lvl, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(lvl, uniqueId, instanceSchema, runId, nickName); } catch { } } } else if (hostBehavior == 0) { int x = 0; foreach (RevitObject obj in revitObjects) { try { List<LyrebirdPoint> originPts = new List<LyrebirdPoint>(); Level lvl = GetLevel(originPts, doc); origin = new XYZ(UnitUtils.ConvertToInternalUnits(obj.Origin.X, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Z, lengthDUT)); if (symbol.Category.Id.IntegerValue == -2001330) { if (lvl != null) { // Structural Column fi = doc.Create.NewFamilyInstance(origin, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.Column); fi.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(origin.Z - lvl.Elevation); double topElev = ((Level)doc.GetElement(fi.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).AsElementId())).Elevation; if (lvl.Elevation + (origin.Z - lvl.Elevation) > topElev) { fi.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set((lvl.Elevation + (origin.Z - lvl.Elevation)) - topElev + 10.0); } } else { TaskDialog.Show("error", "Null level"); } } else { // All Else fi = doc.Create.NewFamilyInstance(origin, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } // Rotate if (obj.Orientation != null) { if (Math.Round(Math.Abs(obj.Orientation.Z - 0), 10) < double.Epsilon) { Line axis = Line.CreateBound(origin, origin + XYZ.BasisZ); XYZ normalVector = new XYZ(0, -1, 0); XYZ orient = new XYZ(obj.Orientation.X, obj.Orientation.Y, obj.Orientation.Z); double angle = 0; if (orient.X < 0 && orient.Y < 0) { angle = (2 * Math.PI) - normalVector.AngleTo(orient); } else if (orient.X < 0) { angle = (Math.PI - normalVector.AngleTo(orient)) + Math.PI; } else if (orient.Y == 0) { angle = 1.5 * Math.PI; } else { angle = normalVector.AngleTo(orient); } ElementTransformUtils.RotateElement(doc, fi.Id, axis, angle); } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); x++; } } else { foreach (RevitObject obj in revitObjects) { origin = new XYZ(UnitUtils.ConvertToInternalUnits(obj.Origin.X, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.Origin.Z, lengthDUT)); // Find the level List<LyrebirdPoint> lbPoints = new List<LyrebirdPoint> { obj.Origin }; Level lvl = GetLevel(lbPoints, doc); // Get the host if (hostBehavior == 5) { // Face based family. Find the face and create the element XYZ normVector = new XYZ(obj.Orientation.X, obj.Orientation.Y, obj.Orientation.Z); XYZ faceVector; if (obj.FaceOrientation != null) { faceVector = new XYZ(obj.FaceOrientation.X, obj.FaceOrientation.Y, obj.FaceOrientation.Z); } else { faceVector = XYZ.BasisZ; } Face face = FindFace(origin, normVector, doc); if (face != null) { fi = doc.Create.NewFamilyInstance(face, origin, faceVector, symbol); } } else { // typical hosted family. Can be wall, floor, roof or ceiling. ElementId host = FindHost(origin, hostBehavior, doc); if (host != null) { fi = doc.Create.NewFamilyInstance(origin, symbol, doc.GetElement(host), lvl, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); } // delete the host finder ElementId hostFinderFamily = hostFinder.Symbol.Family.Id; doc.Delete(hostFinder.Id); doc.Delete(hostFinderFamily); hostFinder = null; } } catch (Exception ex) { TaskDialog.Show("Error", ex.Message); } t.Commit(); } } else { TaskDialog.Show("Error", "Could not find the desired family type"); } } #endregion #region Adaptive Components else if (ro.AdaptivePoints != null && ro.AdaptivePoints.Count > 0) { // Find the FamilySymbol FamilySymbol symbol = FindFamilySymbol(ro.FamilyName, ro.TypeName, doc); if (symbol != null) { using (Transaction t = new Transaction(doc, "Lyrebird Create Objects")) { t.Start(); try { // Create the Schema for the instances to store the GH Component InstanceGUID and the path Schema instanceSchema = null; try { instanceSchema = Schema.Lookup(instanceSchemaGUID); } catch (Exception ex) { Debug.WriteLine(ex.Message); } if (instanceSchema == null) { SchemaBuilder sb = new SchemaBuilder(instanceSchemaGUID); sb.SetWriteAccessLevel(AccessLevel.Vendor); sb.SetReadAccessLevel(AccessLevel.Public); sb.SetVendorId("LMNA"); // Create the field to store the data in the family FieldBuilder guidFB = sb.AddSimpleField("InstanceID", typeof(string)); guidFB.SetDocumentation("Component instance GUID from Grasshopper"); // Create a filed to store the run number FieldBuilder runIDFB = sb.AddSimpleField("RunID", typeof(int)); runIDFB.SetDocumentation("RunID for when multiple runs are created from the same data"); // Create a field to store the GH component nickname. FieldBuilder nickNameFB = sb.AddSimpleField("NickName", typeof(string)); nickNameFB.SetDocumentation("Component NickName from Grasshopper"); sb.SetSchemaName("LMNAInstanceGUID"); instanceSchema = sb.Finish(); } try { foreach (RevitObject obj in revitObjects) { FamilyInstance fi = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, symbol); IList<ElementId> placePointIds = new List<ElementId>(); placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(fi); for (int ptNum = 0; ptNum < obj.AdaptivePoints.Count; ptNum++) { try { ReferencePoint rp = doc.GetElement(placePointIds[ptNum]) as ReferencePoint; XYZ pt = new XYZ(UnitUtils.ConvertToInternalUnits(obj.AdaptivePoints[ptNum].X, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.AdaptivePoints[ptNum].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(obj.AdaptivePoints[ptNum].Z, lengthDUT)); if (rp != null) { XYZ vector = pt.Subtract(rp.Position); ElementTransformUtils.MoveElement(doc, rp.Id, vector); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } t.Commit(); } } } #endregion #region Curve based else if (ro.Curves != null && ro.Curves.Count > 0) { // Find the FamilySymbol FamilySymbol symbol = null; WallType wallType = null; FloorType floorType = null; RoofType roofType = null; GridType gridType = null; bool typeFound = false; FilteredElementCollector famCollector = new FilteredElementCollector(doc); if (ro.CategoryId == -2000011) { famCollector.OfClass(typeof(WallType)); foreach (WallType wt in famCollector) { if (wt.Name == ro.TypeName) { wallType = wt; typeFound = true; break; } } } else if (ro.CategoryId == -2000032) { famCollector.OfClass(typeof(FloorType)); foreach (FloorType ft in famCollector) { if (ft.Name == ro.TypeName) { floorType = ft; typeFound = true; break; } } } else if (ro.CategoryId == -2000035) { famCollector.OfClass(typeof(RoofType)); foreach (RoofType rt in famCollector) { if (rt.Name == ro.TypeName) { roofType = rt; typeFound = true; break; } } } else if (ro.CategoryId == -2000220) { famCollector.OfClass(typeof(GridType)); foreach (GridType gt in famCollector) { if (gt.Name == ro.TypeName) { gridType = gt; typeFound = true; break; } } } else { symbol = FindFamilySymbol(ro.FamilyName, ro.TypeName, doc); if (symbol != null) typeFound = true; } if (typeFound) { using (Transaction t = new Transaction(doc, "Lyrebird Create Objects")) { t.Start(); try { // Create the Schema for the instances to store the GH Component InstanceGUID and the path Schema instanceSchema = null; try { instanceSchema = Schema.Lookup(instanceSchemaGUID); } catch (Exception ex) { Debug.WriteLine(ex.Message); } if (instanceSchema == null) { SchemaBuilder sb = new SchemaBuilder(instanceSchemaGUID); sb.SetWriteAccessLevel(AccessLevel.Vendor); sb.SetReadAccessLevel(AccessLevel.Public); sb.SetVendorId("LMNA"); // Create the field to store the data in the family FieldBuilder guidFB = sb.AddSimpleField("InstanceID", typeof(string)); guidFB.SetDocumentation("Component instance GUID from Grasshopper"); // Create a filed to store the run number FieldBuilder runIDFB = sb.AddSimpleField("RunID", typeof(int)); runIDFB.SetDocumentation("RunID for when multiple runs are created from the same data"); // Create a field to store the GH component nickname. FieldBuilder nickNameFB = sb.AddSimpleField("NickName", typeof(string)); nickNameFB.SetDocumentation("Component NickName from Grasshopper"); sb.SetSchemaName("LMNAInstanceGUID"); instanceSchema = sb.Finish(); } FamilyInstance fi = null; try { foreach (RevitObject obj in revitObjects) { #region single line based family if (obj.Curves.Count == 1 && obj.Curves[0].CurveType != "Circle") { LyrebirdCurve lbc = obj.Curves[0]; List<LyrebirdPoint> curvePoints = lbc.ControlPoints.OrderBy(p => p.Z).ToList(); // linear // can be a wall or line based family. if (obj.CategoryId == -2000011) { // draw a wall Curve crv = null; if (lbc.CurveType == "Line") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(pt1, pt2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); crv = Arc.Create(pt1, pt3, pt2); } if (crv != null) { // Find the level Level lvl = GetLevel(lbc.ControlPoints, doc); double offset = 0; if (Math.Abs(UnitUtils.ConvertToInternalUnits(curvePoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = UnitUtils.ConvertToInternalUnits(curvePoints[0].Z, lengthDUT) - lvl.Elevation; } // Create the wall Wall w = null; try { w = Wall.Create(doc, crv, wallType.Id, lvl.Id, 10.0, offset, false, false); } catch (Exception ex) { TaskDialog.Show("ERROR", ex.Message); } // Assign the parameters SetParameters(w, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(w, uniqueId, instanceSchema, 0, nickName); } } // See if it's a structural column else if (obj.CategoryId == -2001330) { if (symbol != null && lbc.CurveType == "Line") { XYZ origin = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); Curve crv = Line.CreateBound(origin, pt2); // Find the level Level lvl = GetLevel(lbc.ControlPoints, doc); // Create the column fi = doc.Create.NewFamilyInstance(origin, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.Column); // Change it to a slanted column Parameter slantParam = fi.get_Parameter(BuiltInParameter.SLANTED_COLUMN_TYPE_PARAM); // SlantedOrVerticalColumnType has 3 options, CT_Vertical (0), CT_Angle (1), or CT_EndPoint (2) // CT_EndPoint is what we want for a line based column. slantParam.Set(2); // Set the location curve of the column to the line LocationCurve lc = fi.Location as LocationCurve; if (lc != null) { lc.Curve = crv; } // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); } } else if (obj.CategoryId == -2000220) { // draw a grid Grid g = null; if (lbc.CurveType == "Line") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); Line line = Line.CreateBound(pt1, pt2); try { g = doc.Create.NewGrid(line); } catch { } } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); Arc arc = Arc.Create(pt1, pt3, pt2); try { g = doc.Create.NewGrid(arc); } catch { } } if (g != null) { g.ExtendToAllLevels(); ; // Assign the parameters SetParameters(g, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(g, uniqueId, instanceSchema, 0, nickName); } } else if (obj.CategoryId == -2000051) { // Draw a line Curve crv = null; Curve crv2 = null; if (lbc.CurveType == "Line") { XYZ origin = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(origin, pt2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); crv = Arc.Create(pt1, pt3, pt2); } else if (lbc.CurveType == "Circle") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); XYZ pt4 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].Z, lengthDUT)); XYZ pt5 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].Z, lengthDUT)); Arc arc1 = Arc.Create(pt1, pt3, pt2); Arc arc2 = Arc.Create(pt3, pt5, pt4); crv = arc1; crv2 = arc2; } else if (lbc.CurveType == "Spline") { List<XYZ> controlPoints = new List<XYZ>(); List<double> weights = lbc.Weights; List<double> knots = lbc.Knots; foreach (LyrebirdPoint lp in lbc.ControlPoints) { XYZ pt = new XYZ(UnitUtils.ConvertToInternalUnits(lp.X, lengthDUT), UnitUtils.ConvertToInternalUnits(lp.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lp.Z, lengthDUT)); controlPoints.Add(pt); } NurbSpline spline; if (lbc.Degree < 3) spline = NurbSpline.Create(controlPoints, weights); else spline = NurbSpline.Create(controlPoints, weights, knots, lbc.Degree, false, true); crv = spline; } // Check for model or detail if (obj.FamilyName == "Model Lines") { // We need a plane } else if (obj.FamilyName == "Detail Lines") { // we need the active view. } } // Otherwise create a family it using the line else { if (symbol != null) { Curve crv = null; if (lbc.CurveType == "Line") { XYZ origin = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); crv = Line.CreateBound(origin, pt2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); crv = Arc.Create(pt1, pt3, pt2); } // Find the level Level lvl = GetLevel(lbc.ControlPoints, doc); // Create the family if (symbol.Category.Id.IntegerValue == -2002000) { try { Line line = crv as Line; fi = doc.Create.NewFamilyInstance(line, symbol, doc.ActiveView); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } else if (symbol.Category.Id.IntegerValue == -2001320) { try { if (lbc.CurveType == "Arc") { XYZ origin = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); fi = doc.Create.NewFamilyInstance(origin, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.Beam); // Set the location curve of the column to the line LocationCurve lc = fi.Location as LocationCurve; if (lc != null) { lc.Curve = crv; } } else { fi = doc.Create.NewFamilyInstance(crv, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.Beam); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } else { try { fi = doc.Create.NewFamilyInstance(crv, symbol, lvl, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } // Assign the parameters SetParameters(fi, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(fi, uniqueId, instanceSchema, runId, nickName); } } } #endregion #region Closed Curve Family else { // A list of curves. These should equate a closed planar curve from GH. //TODO: For each profile type, determine if the offset is working correctly or inverted // Then determine category and create based on that. if (obj.CategoryId == -2000011) { // Create line based wall // Find the level double offset = 0; List<LyrebirdPoint> allPoints = new List<LyrebirdPoint>(); foreach (LyrebirdCurve lc in obj.Curves) { foreach (LyrebirdPoint lp in lc.ControlPoints) { allPoints.Add(lp); } } allPoints.Sort((x, y) => x.Z.CompareTo(y.Z)); Level lvl = GetLevel(allPoints, doc); if (Math.Abs(UnitUtils.ConvertToInternalUnits(allPoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = UnitUtils.ConvertToInternalUnits(allPoints[0].Z, lengthDUT) - lvl.Elevation; } // Generate the curvearray from the incoming curves List<Curve> crvArray = new List<Curve>(); try { foreach (LyrebirdCurve lbc in obj.Curves) { if (lbc.CurveType == "Circle") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); XYZ pt4 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[3].Z, lengthDUT)); XYZ pt5 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[4].Z, lengthDUT)); Arc arc1 = Arc.Create(pt1, pt3, pt2); Arc arc2 = Arc.Create(pt3, pt5, pt4); crvArray.Add(arc1); crvArray.Add(arc2); } else if (lbc.CurveType == "Arc") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); XYZ pt3 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[2].Z, lengthDUT)); Arc arc = Arc.Create(pt1, pt3, pt2); crvArray.Add(arc); } else if (lbc.CurveType == "Line") { XYZ pt1 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[0].Z, lengthDUT)); XYZ pt2 = new XYZ(UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].X, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lbc.ControlPoints[1].Z, lengthDUT)); Line line = Line.CreateBound(pt1, pt2); crvArray.Add(line); } else if (lbc.CurveType == "Spline") { List<XYZ> controlPoints = new List<XYZ>(); List<double> weights = lbc.Weights; List<double> knots = lbc.Knots; foreach (LyrebirdPoint lp in lbc.ControlPoints) { XYZ pt = new XYZ(UnitUtils.ConvertToInternalUnits(lp.X, lengthDUT), UnitUtils.ConvertToInternalUnits(lp.Y, lengthDUT), UnitUtils.ConvertToInternalUnits(lp.Z, lengthDUT)); controlPoints.Add(pt); } NurbSpline spline; if (lbc.Degree < 3) spline = NurbSpline.Create(controlPoints, weights); else spline = NurbSpline.Create(controlPoints, weights, knots, lbc.Degree, false, true); crvArray.Add(spline); } } } catch (Exception ex) { TaskDialog.Show("ERROR", ex.Message); } // Create the floor Wall w = Wall.Create(doc, crvArray, wallType.Id, lvl.Id, false); if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = w.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET); p.Set(offset); } // Assign the parameters SetParameters(w, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(w, uniqueId, instanceSchema, 0, nickName); } else if (obj.CategoryId == -2000032) { // Create a profile based floor // Find the level Level lvl = GetLevel(obj.Curves[0].ControlPoints, doc); double offset = 0; if (Math.Abs(UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation; } // Generate the curvearray from the incoming curves CurveArray crvArray; Floor flr; List<Opening> flrOpenings = new List<Opening>(); if (obj.CurveIds != null && obj.CurveIds.Count > 0) { // get the main profile int crvCount = obj.CurveIds[0]; List<LyrebirdCurve> primaryCurves = obj.Curves.GetRange(0, crvCount); crvArray = GetCurveArray(primaryCurves); flr = doc.Create.NewFloor(crvArray, floorType, lvl, false); // TODO: You cannot create holes in an element with the API without using openings rather than interior closed curves. // Evaluate with later versions if it's worth creating the openings and updating them // Create the openings associated with it. //int start = crvCount - 1; //for (int i = 1; i < obj.CurveIds.Count; i++) //{ // List<LyrebirdCurve> interiorCurves = obj.Curves.GetRange(start, obj.CurveIds[i]); // start += interiorCurves.Count; // CurveArray openingArray = GetCurveArray(interiorCurves); // try // { // SubTransaction st2 = new SubTransaction(doc); // st2.Start(); // Opening opening = doc.Create.NewOpening(flr, openingArray, false); // st2.Commit(); // flrOpenings.Add(opening); // } // catch (Exception ex) // { // TaskDialog.Show("TEST", ex.Message); // } //} } else { crvArray = GetCurveArray(obj.Curves); flr = doc.Create.NewFloor(crvArray, floorType, lvl, false); } // Create the floor //flr = doc.Create.NewFloor(crvArray, floorType, lvl, false); if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = flr.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM); p.Set(offset); } // Assign the parameters SetParameters(flr, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(flr, uniqueId, instanceSchema, 0, nickName); } else if (obj.CategoryId == -2000035) { // Create a RoofExtrusion // Find the level Level lvl = GetLevel(obj.Curves[0].ControlPoints, doc); double offset = 0; if (Math.Abs(UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation) > double.Epsilon) { offset = UnitUtils.ConvertToInternalUnits(obj.Curves[0].ControlPoints[0].Z, lengthDUT) - lvl.Elevation; } // Generate the curvearray from the incoming curves CurveArray crvArray = GetCurveArray(obj.Curves); // Create the roof FootPrintRoof roof = null; ModelCurveArray roofProfile = new ModelCurveArray(); try { roof = doc.Create.NewFootPrintRoof(crvArray, lvl, roofType, out roofProfile); } catch (Exception ex) { TaskDialog.Show("ERROR", ex.Message); } if (Math.Abs(offset - 0) > double.Epsilon) { Parameter p = roof.get_Parameter(BuiltInParameter.ROOF_LEVEL_OFFSET_PARAM); p.Set(offset); } // Assign the parameters SetParameters(roof, obj.Parameters, doc); // Assign the GH InstanceGuid AssignGuid(roof, uniqueId, instanceSchema, 0, nickName); } } #endregion } } catch (Exception ex) { TaskDialog.Show("Error", ex.ToString()); Debug.WriteLine(ex.Message); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } t.Commit(); } } } #endregion }
/// <summary> /// Check whether two vectors are parallel /// </summary> static bool XyzParallel( XYZ a, XYZ b ) { double angle = a.AngleTo( b ); return _eps > angle || DoubleEqual( angle, Math.PI ); }
/// <summary> /// Gets the biggest face which faces the user. Assumes that the element is a wall, or floor, or other "2-sided" element, and that /// one of the two biggest faces will be facing roughly towards the viewer. /// </summary> /// <param name="element">The element.</param> /// <param name="viewDirection">The view direction.</param> /// <returns>The face. Face.Reference will also be populated.</returns> private static Face GetBiggestFaceFacingUser(Element element, XYZ viewDirection) { // Holds the faces sorted by area SortedDictionary<double, List<Face>> faceAreas = new SortedDictionary<double, List<Face>>(); // Get the element geometry Options options = new Options(); options.ComputeReferences = true; GeometryElement geomElem = element.get_Geometry(options); // Look at the faces in each solid foreach (GeometryObject geomObj in geomElem.Objects) { Solid solid = geomObj as Solid; if (solid != null) { foreach (Face face in solid.Faces) { double area = face.Area; // Save the face to the collection if (faceAreas.ContainsKey(area)) { faceAreas[area].Add(face); } else { List<Face> faces = new List<Face>(); faces.Add(face); faceAreas.Add(area, faces); } } } } // Get biggest two faces. There might be two faces in the last item, or one face in the last item. int count = faceAreas.Count; KeyValuePair<double, List<Face>> faceCollection1 = faceAreas.ElementAt<KeyValuePair<double, List<Face>>>(count - 1); KeyValuePair<double, List<Face>> faceCollection2 = faceAreas.ElementAt<KeyValuePair<double, List<Face>>>(count - 2); Face face1 = null; Face face2 = null; // Two or more equal faces. Use the first two. if (faceCollection1.Value.Count > 1) { face1 = faceCollection1.Value[0]; face2 = faceCollection1.Value[1]; } // One largest face. Use the first face from the next item for comparison. else { face1 = faceCollection1.Value[0]; face2 = faceCollection2.Value[0]; } // Compute face normal BoundingBoxUV box = face1.GetBoundingBox(); UV faceCenter = (box.Max + box.Min) / 2; XYZ faceNormal = face1.ComputeNormal(faceCenter).Normalize(); // Compute angle to the view direction. If less than 90 degrees, keep this face. double angle = viewDirection.AngleTo(faceNormal); Face biggestFace = null; if (Math.Abs(angle) < Math.PI / 2) biggestFace = face1; else biggestFace = face2; return biggestFace; }
/// <summary> /// Identifies if a particular direction is "south-facing". This means within a range of -45 degrees to 45 degrees /// to the south vector (the negative Y axis). /// </summary> /// <param name="direction">The normalized direction to test.</param> /// <returns>True if the vector is in the designated range.</returns> protected bool IsSouthFacing(XYZ direction) { double angleToSouth = direction.AngleTo(-XYZ.BasisY); return Math.Abs(angleToSouth) < Math.PI / 4; }