public void LoadFromFile(string filename) { var p = new XMLSerializer(); Scene scene; try { scene = p.DeserializeFromFile(filename); } catch (Exception) { return; } ClearScene(); var catPoints = new List <CatPoint>(scene.Points.Length); for (int i = 0; i < scene.Points.Length; i++) { var pos = scene.Points[i].Position; var pt = CreateCatPoint(new Vector3(pos.X, pos.Y, pos.Z), false); pt.Name = scene.Points[i].Name; catPoints.Add(pt); } foreach (var bezierCurveC0 in scene.BezierCurvesC0) { var curve = new Bezier(bezierCurveC0.Points.Select(x => catPoints[x]), this) { Name = bezierCurveC0.Name }; if (bezierCurveC0.DisplayPolygonSpecified) { curve.ShowPolygon = bezierCurveC0.DisplayPolygon; } AddNewModel(curve); } foreach (var bezierCurveC2 in scene.BezierCurvesC2) { var curve = new BezierC2(bezierCurveC2.Points.Select(x => catPoints[x]), this) { Name = bezierCurveC2.Name }; if (bezierCurveC2.DisplayPolygonSpecified) { curve.ShowPolygon = bezierCurveC2.DisplayPolygon; } AddNewModel(curve); } foreach (var interpolationBezierCurveC2 in scene.InterpolationBezierCurvesC2) { var curve = new BsplineInterpolator(interpolationBezierCurveC2.Points.Select(x => catPoints[x]), this) { Name = interpolationBezierCurveC2.Name }; if (interpolationBezierCurveC2.DisplayPolygonSpecified) { curve.ShowPolygon = interpolationBezierCurveC2.DisplayPolygon; } AddNewModel(curve); } foreach (var bezierSurfaceC0 in scene.BezierSurfacesC0) { var patches = new List <Patch>(); var ptches = new Patch[bezierSurfaceC0.PatchesV, bezierSurfaceC0.PatchesU]; foreach (var bezierSurfaceC0Patch in bezierSurfaceC0.Patches) { var pts = new CatPoint[4, 4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { pts[i, j] = catPoints[bezierSurfaceC0Patch.Points[j, i]]; } } var patch = new BezierPatch(pts) { ShowPolygon = false, HeightDiv = bezierSurfaceC0Patch.SurfaceDivisionsV, WidthDiv = bezierSurfaceC0Patch.SurfaceDivisionsU, Name = bezierSurfaceC0Patch.Name, VPos = bezierSurfaceC0Patch.PatchU, UPos = bezierSurfaceC0Patch.PatchV }; AddNewModel(patch); patches.Add(patch); ptches[bezierSurfaceC0Patch.PatchV, bezierSurfaceC0Patch.PatchU] = patch; } var surfacePoints = patches.SelectMany(x => x.EnumerateCatPoints()).Distinct().ToList(); var surface = new Surface(SurfaceType.Bezier, ptches, surfacePoints, this, false, false) { Name = bezierSurfaceC0.Name, PatchesU = bezierSurfaceC0.PatchesU, PatchesV = bezierSurfaceC0.PatchesV, }; AddNewModel(surface); } foreach (var bezierSurfaceC2 in scene.BezierSurfacesC2) { var patches = new List <Patch>(); var ptches = new Patch[bezierSurfaceC2.PatchesV, bezierSurfaceC2.PatchesU]; foreach (var bezierSurfaceC2Patch in bezierSurfaceC2.Patches) { var pts = new CatPoint[4, 4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { pts[i, j] = catPoints[bezierSurfaceC2Patch.Points[j, i]]; } } var patch = new BSplinePatch(pts) { ShowPolygon = false, HeightDiv = bezierSurfaceC2Patch.SurfaceDivisionsV, WidthDiv = bezierSurfaceC2Patch.SurfaceDivisionsU, Name = bezierSurfaceC2Patch.Name, UPos = bezierSurfaceC2Patch.PatchU, VPos = bezierSurfaceC2Patch.PatchV }; AddNewModel(patch); patches.Add(patch); ptches[bezierSurfaceC2Patch.PatchV, bezierSurfaceC2Patch.PatchU] = patch; } var loopedV = true; var loopedU = true; for (int i = 0; i < 3; i++) { var pat = ptches[0, 0].GetCatPoint(i, 0); var pat2 = ptches[0, bezierSurfaceC2.PatchesU - 1].GetCatPoint(i + 1, 0); if (pat != pat2 || ptches[0, 0].GetCatPoint(i, 1) != ptches[0, bezierSurfaceC2.PatchesU - 1].GetCatPoint(i + 1, 1) || ptches[0, 0].GetCatPoint(i, 2) != ptches[0, bezierSurfaceC2.PatchesU - 1].GetCatPoint(i + 1, 2)) { loopedU = false; break; } } if (loopedU) { for (int i = 0; i < ptches.GetLength(0); i++) { if (ptches[i, 0].GetCatPoint(0, 3) != ptches[i, bezierSurfaceC2.PatchesU - 1].GetCatPoint(1, 3) || ptches[i, 0].GetCatPoint(1, 3) != ptches[i, bezierSurfaceC2.PatchesU - 1].GetCatPoint(2, 3) || ptches[i, 0].GetCatPoint(2, 3) != ptches[i, bezierSurfaceC2.PatchesU - 1].GetCatPoint(3, 3)) { loopedU = false; break; } } } for (int i = 0; i < 3; i++) { if (ptches[0, 0].GetCatPoint(0, i) != ptches[bezierSurfaceC2.PatchesV - 1, 0].GetCatPoint(0, i + 1) || ptches[0, 0].GetCatPoint(0, i) != ptches[bezierSurfaceC2.PatchesV - 1, 0].GetCatPoint(0, i + 1) || ptches[0, 0].GetCatPoint(0, i) != ptches[bezierSurfaceC2.PatchesV - 1, 0].GetCatPoint(0, i + 1)) { loopedV = false; break; } } if (loopedV) { for (int i = 0; i < ptches.GetLength(1); i++) { if (ptches[0, i].GetCatPoint(3, 0) != ptches[bezierSurfaceC2.PatchesV - 1, i].GetCatPoint(3, 1) || ptches[0, i].GetCatPoint(3, 1) != ptches[bezierSurfaceC2.PatchesV - 1, i].GetCatPoint(3, 2) || ptches[0, i].GetCatPoint(3, 2) != ptches[bezierSurfaceC2.PatchesV - 1, i].GetCatPoint(3, 3)) { loopedV = false; break; } } } if (loopedU == loopedV) { Console.WriteLine($"Surf: {bezierSurfaceC2.Name}"); } var surfacePoints = patches.SelectMany(x => x.EnumerateCatPoints()).Distinct().ToList(); var surface = new Surface(SurfaceType.BSpline, ptches, surfacePoints, this, loopedU, loopedV) { Name = bezierSurfaceC2.Name, PatchesU = bezierSurfaceC2.PatchesU, PatchesV = bezierSurfaceC2.PatchesV }; AddNewModel(surface); } }
private void ConvertToBSpline(SceneData scene) { int widthPoints = UDensity + 3; int heightPoints = VDensity + 3; if (changed || points.Count < 1) { GenerateModel(); } var pts = new Vector3[heightPoints - 2, widthPoints - 2]; for (int i = 0; i < UDensity + 1; i++) { for (int j = 0; j < VDensity + 1; j++) { pts[j, i] = points[i * 3 * (VDensity * 3 + 1) + j * 3]; } } var catPoints = new CatPoint[heightPoints, widthPoints]; var matrix = GetMatrix(false, new Vector3()); if (!Curved) { for (int i = 1; i < widthPoints - 1; i++) { for (int j = 1; j < heightPoints - 1; j++) { var pt = pts[(j - 1), (i - 1)]; catPoints[j, i] = scene.CreateCatPoint((matrix * new Vector4(pt)).ClipToVector3()); } } for (int i = 1; i < widthPoints - 1; i++) { int j = 0; var pt = pts[0, i - 1] * 2 - pts[1, i - 1]; catPoints[j, i] = scene.CreateCatPoint((matrix * new Vector4(pt)).ClipToVector3()); j = heightPoints - 1; pt = pts[j - 2, i - 1] * 2 - pts[j - 3, i - 1]; catPoints[j, i] = scene.CreateCatPoint((matrix * new Vector4(pt)).ClipToVector3()); } for (int j = 1; j < heightPoints - 1; j++) { int i = 0; var pt = pts[j - 1, 0] * 2 - pts[j - 1, 1]; catPoints[j, i] = scene.CreateCatPoint((matrix * new Vector4(pt)).ClipToVector3()); i = widthPoints - 1; pt = pts[j - 1, i - 2] * 2 - pts[j - 1, i - 3]; catPoints[j, i] = scene.CreateCatPoint((matrix * new Vector4(pt)).ClipToVector3()); } catPoints[0, 0] = scene.CreateCatPoint((matrix * new Vector4(pts[0, 0] * 2 - pts[1, 1])).ClipToVector3()); catPoints[heightPoints - 1, widthPoints - 1] = scene.CreateCatPoint( (matrix * new Vector4(pts[pts.GetLength(0) - 1, pts.GetLength(1) - 1] * 2 - pts[pts.GetLength(0) - 2, pts.GetLength(1) - 2])).ClipToVector3()); catPoints[0, widthPoints - 1] = scene.CreateCatPoint((matrix * new Vector4(pts[0, pts.GetLength(1) - 1] * 2 - pts[1, pts.GetLength(1) - 2])) .ClipToVector3()); catPoints[heightPoints - 1, 0] = scene.CreateCatPoint((matrix * new Vector4(pts[pts.GetLength(0) - 1, 0] * 2 - pts[pts.GetLength(0) - 2, 1])) .ClipToVector3()); } else { int curvePoints = widthPoints - (IsCylinder ? 3 : 0); Real angleStep = CurvatureAngle / curvePoints; Real heightStep = Height / (heightPoints - 1); //r * (4sqrt(2) / (6n)) Real newRadius = Radius * (1 + 2 * System.Math.Sqrt(2) / (3.0 * (double)(UDensity - 2))); for (int i = 0; i < curvePoints; i++) //u { Real angle = Utils.DegToRad(i * angleStep - CurvatureAngle / 2); Real x = newRadius * System.Math.Sin(angle); for (int j = 0; j < heightPoints; j++) //v { Real y = heightStep * j - Height / 2; Real z = newRadius * System.Math.Cos(angle); catPoints[j, i] = scene.CreateCatPoint((matrix * new Vector4(x, y, z, 1.0)).ClipToVector3()); } } if (IsCylinder) { for (int j = 0; j < heightPoints; j++) { catPoints[j, widthPoints - 3] = catPoints[j, 0]; catPoints[j, widthPoints - 2] = catPoints[j, 1]; catPoints[j, widthPoints - 1] = catPoints[j, 2]; } } } scene.RemoveModel(this); var subArray = new CatPoint[4, 4]; var ptches = new Patch[VDensity, UDensity]; for (int i = 0; i < UDensity; i++) //u { for (int j = 0; j < VDensity; j++) //v { for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { subArray[y, x] = catPoints[j + y, i + x]; } } var patch = new BSplinePatch(subArray) { UPos = i, VPos = j }; scene.AddNewModel(patch); ptches[j, i] = patch; } } var catPointsList = new List <CatPoint>(catPoints.GetLength(0) * catPoints.GetLength(1)); foreach (var catPoint in catPoints) { catPointsList.Add(catPoint); } scene.AddNewModel(new Surface(SurfaceType.BSpline, ptches, catPointsList, scene, IsCylinder, false) { PatchesU = UDensity, PatchesV = VDensity }); }