コード例 #1
0
        public static Curve Flatten3dCurveOnPlane(Curve c, Plane plane)
        {
            XYZ        meanPt = null;
            List <XYZ> orderedEigenvectors;
            XYZ        normal;

            if (c is HermiteSpline)
            {
                var hs = c as HermiteSpline;
                if (plane == null)
                {
                    plane = GetPlaneFromCurve(c, false);
                }
                var projPoints = new List <XYZ>();
                foreach (var pt in hs.ControlPoints)
                {
                    var proj = pt - (pt - plane.Origin).DotProduct(plane.Normal) * plane.Normal;
                    projPoints.Add(proj);
                }

                return(dynRevitSettings.Revit.Application.Create.NewHermiteSpline(projPoints, false));
            }

            if (c is NurbSpline)
            {
                var ns = c as NurbSpline;
                BestFitLine.PrincipalComponentsAnalysis(ns.CtrlPoints.ToList(), out meanPt, out orderedEigenvectors);
                normal = orderedEigenvectors[0].CrossProduct(orderedEigenvectors[1]).Normalize();
                if (plane == null)
                {
                    plane = dynRevitSettings.Doc.Application.Application.Create.NewPlane(normal, meanPt);
                }

                var projPoints = new List <XYZ>();
                foreach (var pt in ns.CtrlPoints)
                {
                    var proj = pt - (pt - plane.Origin).DotProduct(plane.Normal) * plane.Normal;
                    projPoints.Add(proj);
                }

                return(dynRevitSettings.Revit.Application.Create.NewNurbSpline(projPoints, ns.Weights, ns.Knots, ns.Degree, ns.isClosed, ns.isRational));
            }

            return(c);
        }
コード例 #2
0
        public static Plane GetPlaneFromCurve(Curve c, bool planarOnly)
        {
            //cases to handle
            //straight line - normal will be inconclusive

            //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 (c is Line)
            {
                var v1   = p1 - p0;
                var v2   = p2 - p0;
                XYZ norm = null;

                //keep old plane computations
                if (Math.Abs(p0.Z - p2.Z) < 0.0001)
                {
                    norm = XYZ.BasisZ;
                }
                else
                {
                    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));
            }

            CurveLoop cLoop = new CurveLoop();

            cLoop.Append(c.Clone());
            if (cLoop.HasPlane())
            {
                return(cLoop.GetPlane());
            }
            if (planarOnly)
            {
                return(null);
            }

            IList <XYZ> points = c.Tessellate();
            List <XYZ>  xyzs   = new List <XYZ>();

            for (int iPoint = 0; iPoint < points.Count; iPoint++)
            {
                xyzs.Add(points[iPoint]);
            }

            //var v1 = p1 - p0;
            //var v2 = p2 - p0;
            //var norm = v1.CrossProduct(v2).Normalize();

            ////Normal can be zero length in the case of a straight line
            ////or a curve whose three parameter points as measured above
            ////happen to lie along the same line. In this case, project
            ////the last point down to a plane and use the projected vector
            ////and one of the vectors from above to calculate a normal.
            //if (norm.IsZeroLength())
            //{
            //    if (p0.Z == p2.Z)
            //    {
            //        norm = XYZ.BasisZ;
            //    }
            //    else
            //    {
            //        var p3 = new XYZ(p2.X, p2.Y, p0.Z);
            //        var v3 = p3 - p0;
            //        norm = v1.CrossProduct(v3);
            //    }
            //}

            //var curvePlane = new Plane(norm, p0);

            XYZ        meanPt;
            List <XYZ> orderedEigenvectors;

            BestFitLine.PrincipalComponentsAnalysis(xyzs, out meanPt, out orderedEigenvectors);
            var normal = orderedEigenvectors[0].CrossProduct(orderedEigenvectors[1]);
            var plane  = dynRevitSettings.Doc.Application.Application.Create.NewPlane(normal, meanPt);

            return(plane);
        }