Ejemplo n.º 1
0
        public void It_Refines_The_Curve_Knot(double val, int insertion)
        {
            // Arrange
            int degree = 3;

            List <double> newKnots = new List <double>();

            for (int i = 0; i < insertion; i++)
            {
                newKnots.Add(val);
            }

            List <Point3> pts = new List <Point3>();

            for (int i = 0; i <= 12 - degree - 2; i++)
            {
                pts.Add(new Point3(i, 0.0, 0.0));
            }

            NurbsCurve curve = new NurbsCurve(pts, degree);

            // Act
            NurbsBase curveAfterRefine = KnotVector.Refine(curve, newKnots);
            Point3    p0 = curve.PointAt(2.5);
            Point3    p1 = curveAfterRefine.PointAt(2.5);

            // Assert
            (curve.Knots.Count + insertion).Should().Be(curveAfterRefine.Knots.Count);
            (pts.Count + insertion).Should().Be(curveAfterRefine.ControlPointLocations.Count);
            (p0 == p1).Should().BeTrue();
        }
Ejemplo n.º 2
0
        public void It_Refines_The_Surface_In_The_V_Direction(double val, int insertion)
        {
            // Arrange
            List <double> newKnots = new List <double>();

            for (int i = 0; i < insertion; i++)
            {
                newKnots.Add(val);
            }
            NurbsSurface surface = NurbsSurfaceCollection.Loft();

            // Act
            NurbsSurface surfaceAfterRefine = KnotVector.Refine(surface, newKnots, SurfaceDirection.V);
            Point3       p0 = surface.PointAt(0.5, 0.25);
            Point3       p1 = surfaceAfterRefine.PointAt(0.5, 0.25);

            // Assert
            (surface.KnotsV.Count + insertion).Should().Be(surfaceAfterRefine.KnotsV.Count);
            (surface.ControlPointLocations[0].Count + insertion).Should().Be(surfaceAfterRefine.ControlPointLocations[0].Count);

            (p0 == p1).Should().BeTrue();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Splits (divides) the surface into two parts at the specified parameter
        /// </summary>
        /// <param name="surface">The NURBS surface to split.</param>
        /// <param name="parameter">The parameter at which to split the surface, parameter should be between 0 and 1.</param>
        /// <param name="direction">Where to split in the U or V direction of the surface.</param>
        /// <returns>If the surface is split vertically (U direction) the left side is returned as the first surface and the right side is returned as the second surface.<br/>
        /// If the surface is split horizontally (V direction) the bottom side is returned as the first surface and the top side is returned as the second surface.<br/>
        /// If the spit direction selected is both, the split computes first a U direction split and on the result a V direction split.</returns>
        internal static NurbsSurface[] Split(NurbsSurface surface, double parameter, SplitDirection direction)
        {
            KnotVector            knots      = surface.KnotsV;
            int                   degree     = surface.DegreeV;
            List <List <Point4> > srfCtrlPts = surface.ControlPoints;

            if (direction != SplitDirection.V)
            {
                srfCtrlPts = CollectionHelpers.Transpose2DArray(surface.ControlPoints);
                knots      = surface.KnotsU;
                degree     = surface.DegreeU;
            }

            List <double> knotsToInsert = CollectionHelpers.RepeatData(parameter, degree + 1);
            int           span          = knots.Span(degree, parameter);

            List <List <Point4> > surfPtsLeft  = new List <List <Point4> >();
            List <List <Point4> > surfPtsRight = new List <List <Point4> >();
            NurbsBase             result       = null;

            foreach (List <Point4> pts in srfCtrlPts)
            {
                NurbsCurve tempCurve = new NurbsCurve(degree, knots, pts);
                result = KnotVector.Refine(tempCurve, knotsToInsert);

                surfPtsLeft.Add(result.ControlPoints.GetRange(0, span + 1));
                surfPtsRight.Add(result.ControlPoints.GetRange(span + 1, span + 1));
            }

            if (result == null)
            {
                throw new Exception($"Could not split {nameof(surface)}.");
            }

            KnotVector knotLeft  = result.Knots.GetRange(0, span + degree + 2).ToKnot();
            KnotVector knotRight = result.Knots.GetRange(span + 1, span + degree + 2).ToKnot();

            NurbsSurface[] surfaceResult = Array.Empty <NurbsSurface>();

            switch (direction)
            {
            case SplitDirection.U:
            {
                surfaceResult = new NurbsSurface[]
                {
                    new NurbsSurface(degree, surface.DegreeV, knotLeft, surface.KnotsV.Copy(), CollectionHelpers.Transpose2DArray(surfPtsLeft)),
                    new NurbsSurface(degree, surface.DegreeV, knotRight, surface.KnotsV.Copy(), CollectionHelpers.Transpose2DArray(surfPtsRight))
                };
                break;
            }

            case SplitDirection.V:
            {
                surfaceResult = new NurbsSurface[]
                {
                    new NurbsSurface(surface.DegreeU, degree, surface.KnotsU.Copy(), knotLeft, surfPtsLeft),
                    new NurbsSurface(surface.DegreeU, degree, surface.KnotsU.Copy(), knotRight, surfPtsRight)
                };
                break;
            }

            case SplitDirection.Both:
            {
                NurbsSurface srf1 = new NurbsSurface(degree, surface.DegreeV, knotLeft, surface.KnotsV.Copy(), CollectionHelpers.Transpose2DArray(surfPtsLeft));
                NurbsSurface srf2 = new NurbsSurface(degree, surface.DegreeV, knotRight, surface.KnotsV.Copy(), CollectionHelpers.Transpose2DArray(surfPtsRight));

                NurbsSurface[] split1 = Split(srf1, parameter, SplitDirection.V);
                NurbsSurface[] split2 = Split(srf2, parameter, SplitDirection.V);

                surfaceResult = split2.Concat(split1).ToArray();
                break;
            }
            }

            return(surfaceResult);
        }