/// <summary> /// creates a <see cref="Face"/> in the <see cref="Model.Shell"/> with the points <b>Pts</b>. /// </summary> /// <param name="Pts"><see cref="Loxyz"/> which gives the points of the plane <see cref="Face"/>.</param> /// <returns>plane Face.</returns> public static Face ShellPlane(Loxyz Pts) { if (Pts.Count == 0) { return(null); } Plane _Plane = Pts[0].GetPlane(); Base Base = Base.UnitBase; Base.BaseO = _Plane.P; Base.BaseZ = _Plane.NormalUnit.normalized() * (-1); if ((Base.BaseZ & new xyz(1, 0, 0)).dist(xyz.Null) > 0.01) { Base.BaseY = (Base.BaseZ & (new xyz(1, 0, 0))).normalized(); Base.BaseX = Base.BaseY & Base.BaseZ; } else { Base.BaseY = (Base.BaseZ & (new xyz(0, 1, 0))).normalized(); Base.BaseX = Base.BaseY & Base.BaseZ; } PlaneSurface Surface = new PlaneSurface(); Surface.Base = Base; return(ShellFace(Pts, Surface)); }
/// <summary> /// overrides the <see cref="Surface.Copy"/> method and sets the belonging fields. /// </summary> /// <returns>the copied surface</returns> public override Surface Copy() { PlaneSurface Result = base.Copy() as PlaneSurface; Result.Width = Width; Result.Length = Length; return(Result); }
static List <CrossItem> CreateSortedParams(Face F1, Face F2) { //------ Erstelle Schnittgerade von F1 und F2--------------- PlaneSurface S1 = F1.Surface as PlaneSurface; PlaneSurface S2 = F2.Surface as PlaneSurface; Curve3D Curve3D = null; Curve3D = GetCrossCurve3D(F1, F2); // Schnittgerade der Ebenen if (Curve3D == null) { return(null); // Parallel } //----------------------------------------------------------- List <CrossItem> SortedParams = new List <CrossItem>(); //---------- Schneide im Parameterraum Face1 mit Schnittgeraden Line L2D = S1.To2dCurve(Curve3D) as Line; // Die Schnittgerade wird auf die Ebene Face1 Projiziert CurveArray Ca2 = new CurveArray(); Ca2.Add(L2D); // und in den zweiten CurveArray gestellt Loca Loca = F1.ParamCurves; // die ParamCurves dieser Ebene werden in die Loca gestellt double GlobalIndex = 0; List <CrossItem> CrossList = new List <CrossItem>(); for (int i = 0; i < Loca.Count; i++) { CurveArray Ca = Loca[i]; EdgeLoop EL = F1.Bounds[i]; CrossList CL = CrossWithLine(L2D.A, L2D.B, Ca, EL); for (int g = 0; g < CL.Count; g++) { if (CL[g].Param1 == EL.Count) { CL[g].Param1 = 0; } } if (CL.Count == 0) { continue; } // Offener Array oder kein schnittpunkt for (int k = 0; k < CL.Count; k++) // Schittpunke der geraden mit Face 1 { CL[k].Tag = 1; CL[k].Bound = i; CL[k].Param1 += GlobalIndex; CL[k].Intern = Ca; CL[k].Face = F1; if (!( (CL[k].Border1 == BorderBehavior.BorderEnd) && (CL[k].CrossKind == -1) || (CL[k].Border1 == BorderBehavior.BorderBegin) && (CL[k].CrossKind == 1) )) { ToSortedParams(CrossList, CL[k]); // werden nach Param2 einsortiert } } GlobalIndex += Loca[i].Count; } // Analog für Face 2 // Analog für Face2 //---------- Schneide um Parameterraum Face2 mit Schnittgeraden L2D = S2.To2dCurve(Curve3D) as Line; // Die Schnittgerade wird auf die Ebene Face2 Projiziert Ca2 = new CurveArray(); Ca2.Add(L2D); // und in den zweiten CurveArray gestellt // die ParamCurves dieser Ebene werden in die Loca gestellt Loca = F2.ParamCurves; GlobalIndex = 0; for (int j = 0; j < Loca.Count; j++) { EdgeLoop EL = F2.Bounds[j]; CurveArray Ca = Loca[j]; CrossList CL = CrossWithLine(L2D.A, L2D.B, Ca, EL); for (int g = 0; g < CL.Count; g++) { if (CL[g].Param1 == EL.Count) { CL[g].Param1 = 0; } } if (CL.Count == 0) { continue; } // Offener Array oder kein schnittpunkt for (int k = 0; k < CL.Count; k++) // Schittpunke der geraden mit Face 2 { CL[k].Tag = 2; CL[k].Bound = j; CL[k].Param1 += GlobalIndex; CL[k].Intern = Ca; CL[k].Face = F2; if (!( (CL[k].Border1 == BorderBehavior.BorderEnd) && (CL[k].CrossKind == -1) || (CL[k].Border1 == BorderBehavior.BorderBegin) && (CL[k].CrossKind == 1) )) { ToSortedParams(CrossList, CL[k]); // werden nach Param1 einsortiert } else { } } GlobalIndex += Loca[j].Count; } if (CrossList.Count > 4) { } int Face1Status = 0; int Face2Status = 0; int id = 0; while (id < CrossList.Count) { if ((int)CrossList[id].Tag == 1) { Face1Status += CrossList[id].CrossKind; } if ((int)CrossList[id].Tag == 2) { Face2Status += CrossList[id].CrossKind; } //if (id < CrossList.Count-1) if ((Face2Status == 0) && (Face1Status == 0)) { if (id > 0) { if ((int)CrossList[id - 1].Tag == (int)CrossList[id].Tag) { if (id + 1 < CrossList.Count) { if (System.Math.Abs(CrossList[id + 1].Param2 - CrossList[id].Param2) > 0.000001) { CrossList.RemoveAt(id - 1); CrossList.RemoveAt(id - 1); id--; } else { id++; } } } else { id++; } } } else { id++; } } return(CrossList); }
/// <summary> /// overrides <see cref="Solid.Refresh()"/>. /// </summary> public override void Refresh() { Clear(); Cone ConeSurface = new Cone(); ConeSurface.VResolution = VResolution; ConeSurface.UResolution = UResolution; ConeSurface.Radius = Radius; ConeSurface.HalfAngle = HalfAngle; ConeSurface.Height = Height; Vertex3d[,] Points = new Vertex3d[ConeSurface.UResolution, ConeSurface.VResolution + 1]; Line3D[,] HorzCurves = new Line3D[ConeSurface.UResolution, ConeSurface.VResolution + 1]; Line3D[,] VertCurves = new Line3D[ConeSurface.UResolution, ConeSurface.VResolution]; Vertex3d[,] Normals = new Vertex3d[ConeSurface.UResolution + 1, ConeSurface.VResolution + 1]; for (int i = 0; i < ConeSurface.UResolution; i++) { for (int j = 0; j <= ConeSurface.VResolution; j++) { Points[i, j] = new Vertex3d(ConeSurface.Value((float)i / (float)ConeSurface.UResolution, (float)j / (float)ConeSurface.VResolution)); VertexList.Add(Points[i, j]); Normals[i, j] = new Vertex3d(ConeSurface.Normal((float)i / (float)ConeSurface.UResolution, (float)j / (float)ConeSurface.VResolution)); } } for (int i = 0; i < ConeSurface.UResolution; i++) { for (int j = 0; j <= ConeSurface.VResolution; j++) { if (i < ConeSurface.UResolution) { if (i + 1 < ConeSurface.UResolution) { HorzCurves[i, j] = new Line3D(Points[i, j].Value, Points[i + 1, j].Value); } else { HorzCurves[i, j] = new Line3D(Points[i, j].Value, Points[0, j].Value); } HorzCurves[i, j].Neighbors = new Face[2]; EdgeCurveList.Add(HorzCurves[i, j]); } if (j < ConeSurface.VResolution) { VertCurves[i, j] = new Line3D(Points[i, j].Value, Points[i, j + 1].Value); VertCurves[i, j].Neighbors = new Face[2]; EdgeCurveList.Add(VertCurves[i, j]); } } } for (int i = 0; i < ConeSurface.UResolution; i++) { for (int j = 0; j < ConeSurface.VResolution; j++) { int IInd = -1; Vertex3d A = Points[i, j]; Vertex3d B = Points[i, j + 1]; Vertex3d C = null; if (i + 1 < ConeSurface.UResolution) { IInd = i + 1; C = Points[i + 1, j + 1]; } else { IInd = 0; C = Points[0, j + 1]; } Vertex3d D = null; if (i + 1 < ConeSurface.UResolution) { D = Points[i + 1, j]; } else { D = Points[0, j]; } Face F = new Face(); FaceList.Add(F); F.Surface = new SmoothPlane(Points[i, j].Value, Points[IInd, j].Value, Points[i, j + 1].Value, Points[IInd, j + 1].Value, Normals[i, j].Value, Normals[IInd, j + 1].Value, Normals[i, j + 1].Value, Normals[IInd, j].Value); EdgeLoop EL = new EdgeLoop(); F.Bounds.Add(EL); Edge E = new Edge(); EdgeList.Add(E); EL.Add(E); E.EdgeStart = A; E.EdgeEnd = B; E.EdgeCurve = VertCurves[i, j]; E.EdgeCurve.Neighbors[0] = F; E.SameSense = true; E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = B; E.EdgeEnd = C; E.EdgeCurve = HorzCurves[i, j + 1]; E.EdgeCurve.Neighbors[0] = F; E.SameSense = true; E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = C; E.EdgeEnd = D; if (i + 1 < ConeSurface.UResolution) { E.EdgeCurve = VertCurves[i + 1, j]; } else { E.EdgeCurve = VertCurves[0, j]; } E.EdgeCurve.Neighbors[1] = F; E.SameSense = false; E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); E.ParamCurve.Invert(); E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = D; E.EdgeEnd = A; E.EdgeCurve = HorzCurves[i, j]; E.EdgeCurve.Neighbors[1] = F; E.SameSense = false; E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); E.ParamCurve.Invert(); } } // Boden Base BodenBase = Base.From4Points(Points[0, 0].Value, Points[2, 0].Value, Points[1, 0].Value, Points[3, 0].Value); // Base BodenBase = Base.UnitBase; BodenBase.BaseO = Points[0, 0].Value; { Face F = new Face(); FaceList.Add(F); PlaneSurface S = null; S = new PlaneSurface(); S.Base = BodenBase; F.Surface = S; EdgeLoop EL = new EdgeLoop(); F.Bounds.Add(EL); for (int i = 0; i < ConeSurface.UResolution; i++) { Edge E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = Points[i, 0]; if (i + 1 < ConeSurface.UResolution) { E.EdgeEnd = Points[i + 1, 0]; } else { E.EdgeEnd = Points[0, 0]; } E.EdgeCurve = HorzCurves[i, 0]; E.EdgeCurve.Neighbors[0] = F; E.SameSense = true; E.ParamCurve = S.To2dCurve(E.EdgeCurve); } } // Deckel { PlaneSurface S = null; S = new PlaneSurface(); BodenBase.BaseO = Points[0, ConeSurface.VResolution].Value; //S.Base = BodenBase; try { S.Base = Base.From4Points(Points[0, ConeSurface.VResolution].Value, Points[2, ConeSurface.VResolution].Value, Points[3, ConeSurface.VResolution].Value, Points[1, ConeSurface.VResolution].Value); } catch (Exception) { Base B = Base.UnitBase; B.BaseO = Points[0, ConeSurface.VResolution].Value; S.Base = B; } Face F = new Face(); FaceList.Add(F); F.Surface = S; EdgeLoop EL = new EdgeLoop(); F.Bounds.Add(EL); for (int i = ConeSurface.UResolution - 1; i >= 0; i--) // for (int i = 0; i < ConeSurface.UResolution; i++) { Edge E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = Points[i, ConeSurface.VResolution]; //if (i + 1 < ConeSurface.UResolution) // E.EdgeEnd = Points[i + 1, ConeSurface.VResolution]; //else // E.EdgeEnd = Points[0, ConeSurface.VResolution]; E.EdgeEnd = Points[i, ConeSurface.VResolution]; if (i + 1 < ConeSurface.UResolution) { E.EdgeStart = Points[i + 1, ConeSurface.VResolution]; } else { E.EdgeStart = Points[0, ConeSurface.VResolution]; } E.EdgeCurve = HorzCurves[i, ConeSurface.VResolution]; if (E.EdgeStart.Value.dist(E.EdgeCurve.B) > 0.001) { } E.EdgeCurve.Neighbors[1] = F; E.SameSense = false; E.ParamCurve = S.To2dCurve(E.EdgeCurve); E.ParamCurve.Invert(); } } RefreshParamCurves(); base.Refresh(); }
/// <summary> /// creates a <see cref="Face"/> for a <see cref="Solid"/> in the <see cref="Model.Solid"/>. /// The Curves are all <see cref="Line3D"/>. The <see cref="Face"/> is plane and has as <see cref="Face.Surface"/> a <see cref="PlaneSurface"/>. /// </summary> /// <param name="Solid">is the target in which the <see cref="Face"/> will be posed.</param> /// <param name="Bounds">contains the <see cref="Vertex3d"/> for the <see cref="Line3D"/>.</param> /// <returns>a <see cref="Face"/></returns> public static Face SolidPlane(Solid Solid, Vertex3dArray_2 Bounds) { if (Bounds.Count == 0) { return(null); } xyz N = new xyz(0, 0, 0); xyz P = Bounds[0][0].Value; for (int i = 1; i < Bounds[0].Count - 1; i++) { xyz A = Bounds[0][i].Value; xyz B = Bounds[0][i + 1].Value; xyz M = N; N = N + ((A - P) & (B - P)); } N = N.normalized() * (-1); Base Base = Base.UnitBase; Base.BaseO = P; Base.BaseZ = N; if ((Base.BaseZ & new xyz(1, 0, 0)).dist(xyz.Null) > 0.01) { Base.BaseY = (Base.BaseZ & (new xyz(1, 0, 0))).normalized(); Base.BaseX = Base.BaseY & Base.BaseZ; } else { Base.BaseY = (Base.BaseZ & (new xyz(0, 1, 0))).normalized(); Base.BaseX = Base.BaseY & Base.BaseZ; } PlaneSurface Surface = new PlaneSurface(); Surface.Base = Base; //------------------------------------- //-------- Create the Face Face Result = new Face(); // ---- With Plane Surface Result.Surface = Surface; if (Solid != null) { Solid.FaceList.Add(Result); } //----- Set the Edges for (int i = 0; i < Bounds.Count; i++) { EdgeLoop Edgeloop = new EdgeLoop(); Result.Bounds.Add(Edgeloop); for (int j = 0; j < Bounds[i].Count; j++) { Vertex3d A = Bounds[i][j]; Vertex3d B = null; if (j == Bounds[i].Count - 1) { B = Bounds[i][0]; } else { B = Bounds[i][j + 1]; } Edge E = Edge.SolidEdge(Solid, Result, A, B, new Line3D(A.Value, B.Value)); Edgeloop.Add(E); } } Result.RefreshParamCurves(); return(Result); }