/// <summary> /// Convert a generic Circle to a Revit Curve /// </summary> /// <param name="crvCurve"></param> /// <returns></returns> private static Autodesk.Revit.DB.Curve Convert(Autodesk.DesignScript.Geometry.Curve crvCurve) { Autodesk.DesignScript.Geometry.Curve[] curves = crvCurve.ApproximateWithArcAndLineSegments(); if (curves.Length == 1) { //line or arc? var point0 = crvCurve.PointAtParameter(0.0); var point1 = crvCurve.PointAtParameter(1.0); var pointMid = crvCurve.PointAtParameter(0.5); if (point0.DistanceTo(point1) > 1e-7) { var line = Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint(point0, point1); if (pointMid.DistanceTo(line) < 1e-7) { return(Convert(line)); } } //then arc if (point0.DistanceTo(point1) < 1e-7) { point1 = crvCurve.PointAtParameter(0.9); } var arc = Autodesk.DesignScript.Geometry.Arc.ByThreePoints(point0, pointMid, point1); return(Convert(arc)); } return(Convert(crvCurve.ToNurbsCurve())); }
public static DS.Ellipse GetAsEllipse(this DS.Curve curve) { if (!curve.IsClosed) { throw new ArgumentException("Curve is not closed, cannot be an Ellipse"); } double[] parameters = new double[4] { 0, 0.25, 0.5, 0.75 }; DS.Point[] points = parameters.Select(p => curve.PointAtParameter(p)).ToArray(); double a = points[0].DistanceTo(points[2]) * 0.5; // Max Radius double b = points[1].DistanceTo(points[3]) * 0.5; // Min Radius using (DS.Point centre = DS.Point.ByCoordinates(Median(points[0].X, points[2].X), Median(points[0].Y, points[2].Y), Median(points[0].Z, points[2].Z))) { points.ForEach(p => p.Dispose()); return(DS.Ellipse.ByPlaneRadii( DS.Plane.ByOriginNormalXAxis(centre, curve.Normal, DS.Vector.ByTwoPoints(centre, curve.StartPoint)), a, b )); } }
public static bool IsEllipse(this DS.Curve curve) { try { if (!curve.IsClosed) { return(false); } //http://www.numericana.com/answer/ellipse.htm double[] parameters = new double[4] { 0, 0.25, 0.5, 0.75 }; DS.Point[] points = parameters.Select(p => curve.PointAtParameter(p)).ToArray(); double a = points[0].DistanceTo(points[2]) * 0.5; // Max Radius double b = points[1].DistanceTo(points[3]) * 0.5; // Min Radius points.ForEach(p => p.Dispose()); double h = Math.Pow(a - b, 2) / Math.Pow(a + b, 2); double perimeter = Math.PI * (a + b) * (1 + (3 * h / (10 + Math.Sqrt(4 - 3 * h)))); return(Threshold(curve.Length, perimeter, 1e-5)); //Ellipse perimeter is an approximation } catch (Exception e) { return(false); } }
public static DS.Arc GetAsArc(this DS.Curve curve) { if (curve.IsClosed) { throw new ArgumentException("Curve is closed, cannot be an Arc"); } using (DS.Point midPoint = curve.PointAtParameter(0.5)) { return(DS.Arc.ByThreePoints(curve.StartPoint, midPoint, curve.EndPoint)); } }
public static DS.Circle GetAsCircle(this DS.Curve curve) { if (!curve.IsClosed) { throw new ArgumentException("Curve is not closed, cannot be a Circle"); } DS.Point start = curve.StartPoint; using (DS.Point midPoint = curve.PointAtParameter(0.5)) using (DS.Point centre = DS.Point.ByCoordinates(Median(start.X, midPoint.X), Median(start.Y, midPoint.Y), Median(start.Z, midPoint.Z))) { return(DS.Circle.ByCenterPointRadiusNormal( centre, centre.DistanceTo(start), curve.Normal )); } }
public static bool IsCircle(this DS.Curve curve) { try { if (!curve.IsClosed) { return(false); } using (DS.Point midPoint = curve.PointAtParameter(0.5)) { double radius = curve.StartPoint.DistanceTo(midPoint) * 0.5; return(Threshold(radius, (curve.Length) / (2 * Math.PI))); } } catch (Exception e) { return(false); } }
public static bool IsArc(this DS.Curve curve) { try { if (curve.IsClosed) { return(false); } using (DS.Point midPoint = curve.PointAtParameter(0.5)) using (DS.Arc arc = DS.Arc.ByThreePoints(curve.StartPoint, midPoint, curve.EndPoint)) { return(Threshold(arc.Length, curve.Length)); } } catch (Exception e) { return(false); } }
/// <summary> /// This function creates a list of cut planes; /// Initial cut plane is normal plane to curve at given origin /// and the rest of the planes are generated from the initial plane /// and the given spacing. /// </summary> /// <param name="curve"></param> /// <param name="origin"></param> /// <returns>List containing all cut planes</returns> public List<Plane> GenerateCutPlanes(Curve curve, double origin) { List<Plane> Planes = new List<Plane>(); if (origin > 0) Planes.Add(Plane.ByOriginNormal(curve.PointAtParameter(origin), curve.TangentAtParameter(origin))); else Planes.Add(Plane.ByOriginNormal((Point)Solid.Intersect(curve)[0], curve.TangentAtParameter(curve.ParameterAtPoint((Point)Solid.Intersect(curve)[0])))); return Planes; }
/// <summary> /// Constructs a point at a given parameter on the input curve. /// </summary> /// <param name="contextCurve">Input curve</param> /// <param name="parameter">Parameter value.</param> /// <returns>Point</returns> public static Point AtParameter(Curve contextCurve, double parameter) { if (contextCurve == null) { throw new ArgumentNullException("contextCurve"); } var pt = contextCurve.PointAtParameter(parameter); if (null == pt) return null; pt.Context = contextCurve; pt.T = parameter; pt.Distance = contextCurve.DistanceAtParameter(parameter); pt.Persist(); return pt; }
Result IExternalCommand.Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Document revitDoc = commandData.Application.ActiveUIDocument.Document; //取得文档 Application revitApp = commandData.Application.Application; //取得应用程序 UIDocument uiDoc = commandData.Application.ActiveUIDocument; //取得当前活动文档 Document document = commandData.Application.ActiveUIDocument.Document; Window1 window1 = new Window1(); //载入族 FamilySymbol familySymbol; using (Transaction tran = new Transaction(uiDoc.Document)) { tran.Start("载入族"); //载入弦杆族 string file = @"C:\Users\zyx\Desktop\2RevitArcBridge\CrossBeam\CrossBeam\source\crossBeam.rfa"; familySymbol = loadFaimly(file, commandData); familySymbol.Activate(); tran.Commit(); } //把这组模型线通过获取首尾点,生成dynamo里的curve List <XYZ> ps = new List <XYZ>(); using (Transaction transaction = new Transaction(uiDoc.Document)) { transaction.Start("选取模型线生成Curve"); Selection sel = uiDoc.Selection; IList <Reference> modelLines = sel.PickObjects(ObjectType.Element, "选一组模型线"); foreach (Reference reference in modelLines) { Element elem = revitDoc.GetElement(reference); ModelLine modelLine = elem as ModelLine; Autodesk.Revit.DB.Curve c = modelLine.GeometryCurve; ps.Add(c.GetEndPoint(0)); ps.Add(c.GetEndPoint(1)); } for (int i = ps.Count - 1; i > 0; i--) { XYZ p1 = ps[i]; XYZ p2 = ps[i - 1]; //注意此处重合点有一个闭合差 if (p1.DistanceTo(p2) < 0.0001) { ps.RemoveAt(i); } } transaction.Commit(); } //做一个revit和dynamo点的转换 DG.CoordinateSystem coordinateSystem = DG.CoordinateSystem.ByOrigin(0, 0, 0);//标准坐标系 List <DG.Point> DGps = new List <DG.Point>(); foreach (XYZ p in ps) { DGps.Add(p.ToPoint(false)); } DG.PolyCurve polyCurve = DG.PolyCurve.ByPoints(DGps); DG.Curve curve = polyCurve as DG.Curve; List <DG.Point> DGCBps = new List <DG.Point>();//横梁的放置点位列表 double StartLength = 0; if (window1.ShowDialog() == true) { //窗口打开并停留,只有点击按键之后,窗口关闭并返回true } //按键会改变window的属性,通过对属性的循环判断来实现对按键的监测 while (!window1.Done) { //选择起点 if (window1.StartPointSelected) { using (Transaction transaction = new Transaction(uiDoc.Document)) { transaction.Start("选择起点"); double r1 = SelectPoint(commandData); DG.Point dgp1 = curve.PointAtParameter(r1); DGCBps.Add(dgp1); StartLength = curve.SegmentLengthAtParameter(r1); transaction.Commit(); } //2、重置window1.StartPointSelected window1.StartPointSelected = false; } if (window1.ShowDialog() == true) { //窗口打开并停留,只有点击按键之后,窗口关闭并返回true } } //在这里根据间距获取到各个点 for (int i = 1; i < window1.cbNumber; i++) { double L = StartLength + window1.cbDistance * i; DG.Point point = curve.PointAtSegmentLength(L); DGCBps.Add(point); MessageBox.Show(i.ToString()); } List <FamilyInstance> instances = new List <FamilyInstance>(); using (Transaction transaction = new Transaction(uiDoc.Document)) { transaction.Start("创建横梁实例"); foreach (DG.Point p in DGCBps) { FamilyInstance familyInstance; familyInstance = CreateFamlyInstance(p, curve, familySymbol, commandData); instances.Add(familyInstance); } transaction.Commit(); } //给每个族实例设置参数 using (Transaction transaction = new Transaction(uiDoc.Document)) { transaction.Start("族实例参数设置"); foreach (FamilyInstance instance in instances) { double h1 = instance.LookupParameter("l1/2").AsDouble(); instance.LookupParameter("l1/2").Set(window1.l1 / 2); instance.LookupParameter("l2").Set(window1.l2); //instance.LookupParameter("h1").Set(window1.l1); //instance.LookupParameter("h2").Set(window1.l1); } transaction.Commit(); } return(Result.Succeeded); }