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(); }
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(); }
/// <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); }