public static Plane GetPlaneFromCurve(Curve c, bool planarOnly) { //find the plane of the curve and generate a sketch plane double period = c.IsBound ? 0.0 : (c.IsCyclic ? c.Period : 1.0); var p0 = c.IsBound ? c.Evaluate(0.0, true) : c.Evaluate(0.0, false); var p1 = c.IsBound ? c.Evaluate(0.5, true) : c.Evaluate(0.25 * period, false); var p2 = c.IsBound ? c.Evaluate(1.0, true) : c.Evaluate(0.5 * period, false); if (IsLineLike(c)) { XYZ norm = null; //keep old plane computations if (Math.Abs(p0.Z - p2.Z) < Tolerance) { norm = XYZ.BasisZ; } else { var v1 = p1 - p0; var v2 = p2 - p0; var p3 = new XYZ(p2.X, p2.Y, p0.Z); var v3 = p3 - p0; norm = v1.CrossProduct(v3); if (norm.IsZeroLength()) { norm = v2.CrossProduct(XYZ.BasisY); } norm = norm.Normalize(); } return(Plane.CreateByNormalAndOrigin(norm, p0)); } var cLoop = new CurveLoop(); cLoop.Append(c.Clone()); if (cLoop.HasPlane()) { return(cLoop.GetPlane()); } if (planarOnly) { return(null); } // Get best fit plane using tesselation var points = c.Tessellate().Select(x => x.ToPoint(false)); var bestFitPlane = Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints(points); return(bestFitPlane.ToPlane(false)); }
public static Plane GetPlaneFromCurve(Curve c, bool planarOnly) { //find the plane of the curve and generate a sketch plane double period = c.IsBound ? 0.0 : (c.IsCyclic ? c.Period : 1.0); var p0 = c.IsBound ? c.Evaluate(0.0, true) : c.Evaluate(0.0, false); var p1 = c.IsBound ? c.Evaluate(0.5, true) : c.Evaluate(0.25 * period, false); var p2 = c.IsBound ? c.Evaluate(1.0, true) : c.Evaluate(0.5 * period, false); if (IsLineLike(c)) { XYZ norm = null; //keep old plane computations if (System.Math.Abs(p0.Z - p2.Z) < Tolerance) { norm = XYZ.BasisZ; } else { var v1 = p1 - p0; var v2 = p2 - p0; var p3 = new XYZ(p2.X, p2.Y, p0.Z); var v3 = p3 - p0; norm = v1.CrossProduct(v3); if (norm.IsZeroLength()) { norm = v2.CrossProduct(XYZ.BasisY); } norm = norm.Normalize(); } return new Plane(norm, p0); } var cLoop = new CurveLoop(); cLoop.Append(c.Clone()); if (cLoop.HasPlane()) { return cLoop.GetPlane(); } if (planarOnly) return null; // Get best fit plane using tesselation var points = c.Tessellate().Select(x => x.ToPoint(false)); var bestFitPlane = Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints(points); return bestFitPlane.ToPlane(false); }
/***************************************************/ /**** Public methods ****/ /***************************************************/ public static bool IsVerticalNonLinearCurve(this Curve revitCurve, RevitSettings settings) { if (!(revitCurve is Line)) { CurveLoop curveLoop = CurveLoop.Create(new Curve[] { revitCurve }); if (curveLoop.HasPlane()) { Plane curvePlane = curveLoop.GetPlane(); //Orientation angles are handled slightly differently for framing elements that have a curve fits in a plane that contains the z-vector if (Math.Abs(curvePlane.Normal.DotProduct(XYZ.BasisZ)) < settings.AngleTolerance) { return(true); } } } return(false); }
/// <summary> /// 获取一组连续封闭的模型线 /// </summary> /// <returns></returns> /// <remarks></remarks> private CurveLoop GetLoopedCurve(out List <ModelCurve> modelCurves) { Document Doc = this._uiDoc.Document; // IList <Reference> boundaries = Selector.SelectGeneralElements <ModelCurve>(_uiDoc, out modelCurves, "选择一组模型线"); // if (boundaries == null || !boundaries.Any()) { return(null); } CurveLoop cvLoop = new CurveLoop(); try { if (boundaries.Count == 1) // 要么是封闭的圆或圆弧,要么就不封闭 { Curve c = ((ModelCurve)Doc.GetElement(boundaries[0])).GeometryCurve; if ((c is Arc || c is Ellipse) && !c.IsBound) { cvLoop.Append(c); } else { throw new InvalidOperationException("选择的一条圆弧线或者椭圆线并不封闭。"); } } else { // 对于选择了多条曲线的情况 IList <Curve> cs = CurvesFormator.GetContiguousCurvesFromCurves(Doc, boundaries); if (cs != null) { foreach (Curve c in cs) { cvLoop.Append(c); } } else { throw new InvalidOperationException("所选择的曲线不连续。"); } if (cvLoop.IsOpen()) { throw new InvalidOperationException("所选择的曲线不能形成封闭的曲线。"); } else if (!cvLoop.HasPlane()) { throw new InvalidOperationException("所选择的曲线不在同一个平面上。"); } else { return(cvLoop); } } } catch (Exception ex) { DialogResult res = MessageBox.Show( ex.Message + " 点击是以重新选择,点击否以退出绘制。" + "\r\n" + "当前选择的曲线条数为:" + Convert.ToString(boundaries.Count) + "条。" + "\r\n" + ex.StackTrace, "Warnning", MessageBoxButtons.YesNo); if (res == DialogResult.Yes) { cvLoop = GetLoopedCurve(out modelCurves); } else { cvLoop = new CurveLoop(); return(cvLoop); } } return(cvLoop); }