static CrossList CrossWithLine(xy A, xy B, CurveArray Array, EdgeLoop E) { xyArray xyArray = Array.getxyArray(); if (xyArray[xyArray.Count - 1].dist(xyArray[0]) > 0.0001) // 17.6 ausgeklammert?----------- { xyArray.Add(xyArray[0]); } CrossList CL = CrossWithLine(A, B, xyArray, E); for (int i = 0; i < CL.Count; i++) { Curve C = E[i].ParamCurve; CL[i].Param1 = Array.xyArrayIndexToCurveArrayIndex(CL[i].Param1); if (CL[i].Param1 == 4) { } int First = (int)CL[i].Param1; int Second = First + 1; if (Second >= Array.Count) { Second = 0; } CL[i].A = Array.Value(First); CL[i].B = Array.Value(Second); } return(CL); }
/// <summary> /// creates new <see cref="Face.ParamCurves"/> by calling <see cref="Surface.To2dCurve(Curve3D)"/> for every EdgeCurve of all <see cref="Face"/>s. /// Finately will be called <see cref="RefreshParamCurves"/>, /// </summary> public void NewParamCurves() { for (int i = 0; i < this.FaceList.Count; i++) { Face F = FaceList[i]; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; if (E.EdgeCurve.Neighbors[0] == null) { E.EdgeCurve.Neighbors[0] = F; } else if (E.EdgeCurve.Neighbors[1] == null) { E.EdgeCurve.Neighbors[1] = F; } if (E.ParamCurve == null) { E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); } if (!E.SameSense) { E.ParamCurve.Invert(); } } } } RefreshParamCurves(); }
/// <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> /// <param name="Surface"><see cref="Loxyz"/> which gives the points of the plane <see cref="Face"/>.</param> /// <returns>plane Face.</returns> static Face ShellFace(Loxyz Pts, Surface Surface) { if (Pts.Count == 0) { return(null); } Face Result = new Face(); for (int i = 0; i < Pts.Count; i++) { EdgeLoop Edgeloop = new EdgeLoop(); Result.Bounds.Add(Edgeloop); for (int j = 0; j < Pts[i].Count; j++) { xyz A = Pts[i][j]; xyz B = xyz.Null; if (j == Pts[i].Count - 1) { B = Pts[i][0]; } else { B = Pts[i][j + 1]; } Edge E = Edge.ShellLineEdge(A, B); E.SameSense = true; Edgeloop.Add(E); } } Result.Surface = Surface; return(Result); }
/// <summary> /// creates a <see cref="Face"/> for a <see cref="Solid"/> with <see cref="Model.Solid"/>. /// <b>Curves</b> /// /// /// /// /// Erstell ein massives <see cref="Face"/>. Wenn <b>Solid</b> nicht null ist, wird dieses Face eingebaut in /// <b>Solid</b>. <b>Curves</b> spezifizieren einee Liste von Curve3d-Lists. Sie werden als <see cref="Edge.EdgeCurve"/> /// in jede <see cref="Edge"/> gesetzt. <b>Curves</b> müssen von der Struktur identisch sein wie Bounds, /// d.h. die selbe Länge und jeder Eintrag in Bounds ( Bounds[i] ) muss die selbe Länge haben wie /// der entsprechende Eintrag in <b>Curves</b> (Curves[i]). /// gesetzt /// </summary> /// <param name="Solid"><see cref="Solid"/> in which the result<see cref="Face"/> will be integrated.</param> /// <param name="Surface"><see cref="Surface"/> belonging to the new <see cref="Face"/>.</param> /// <param name="Bounds">list of <see cref="Vertex3dArray"/>, who contains the start and end points of the <see cref="Edge"/>s.</param> /// <param name="Curves"><see cref="Curve3D"/>, which are the new <see cref="Edge.EdgeCurve"/>s. Their start points and their end point must correspond to /// the parameter Bounds start and end points.</param> /// <returns>a <see cref="Face"/>, which will be added to the <b>Solid</b>.</returns> public static Face SolidFace(Solid Solid, Surface Surface, Vertex3dArray_2 Bounds, Loca3D Curves) { if (Bounds.Count == 0) { return(null); } Face Result = new Face(); Result.Surface = Surface; 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, Curves[j][i]); Edgeloop.Add(E); } } return(Result); }
private void insertVertexToSameSenseEdge(Face Fa, int Bounds, int Edge, Vertex3d V) { EdgeLoop EL = Fa.Bounds[Bounds]; Edge E = EL[Edge]; Face Neigbhbor = null; int outloop = -1; double d = Face.GetDualEdge(Fa, Bounds, Edge + 0.5, ref outloop, ref Neigbhbor); EdgeLoop DualEL = Neigbhbor.Bounds[outloop]; int DualEdge = (int)d; Edge F = DualEL[DualEdge]; // Zuerst die neue Kante Edge NewEdge = new Edge(); EdgeList.Add(NewEdge); NewEdge.SameSense = true; NewEdge.EdgeStart = E.EdgeStart; NewEdge.EdgeEnd = V; Line3D L = new Line3D(NewEdge.EdgeStart.Value, V.Value); EdgeCurveList.Add(L); L.Neighbors = new Face[2]; L.Neighbors[0] = E.EdgeCurve.Neighbors[0]; L.Neighbors[1] = E.EdgeCurve.Neighbors[1]; NewEdge.EdgeCurve = L; VertexList.Add(V); E.EdgeStart = V; E.EdgeCurve.A = V.Value; EL.Insert(Edge, NewEdge); // Duale NewEdge = new Edge(); NewEdge.SameSense = false; EdgeList.Add(NewEdge); if (DualEdge + 1 < DualEL.Count) { DualEL.Insert(DualEdge + 1, NewEdge); } else { DualEL.Insert(0, NewEdge); } NewEdge.EdgeStart = V; NewEdge.EdgeEnd = F.EdgeEnd; F.EdgeEnd = V; NewEdge.EdgeCurve = L; }
/// <summary> /// copies a list of <see cref="Edge"/>s in a <see cref="Solid"/> Targetsolid. /// </summary> /// <param name="TargetSolid">target, in which the edges will be copied.</param> /// <returns>a list of copied <see cref="Edge"/>s.</returns> public virtual EdgeLoop Copy(Solid TargetSolid) { EdgeLoop Result = new EdgeLoop(); for (int i = 0; i < Count; i++) { Result.Add(this[i].Copy(TargetSolid)); } return(Result); }
/// <summary> /// refreshes the <see cref="Edge.ParamCurve"/> of the <see cref="EdgeList"/>. /// <see cref="ParamCurves"/>-liste. Diese doppelte Verwaltung der ParamCurves wird lediglich aus Performancegründen gemacht. /// </summary> public virtual void RefreshParamCurves() { Solid P = Parent; DrawPoints = new Loxyz(); DrawPoints.Count = Bounds.Count; if (ParamCurves == null) { Surface.BoundedCurves = new Loca(); } ParamCurves.Clear(); for (int i = 0; i < Bounds.Count; i++) { EdgeLoop EL = Bounds[i]; CurveArray CA = new CurveArray(); ParamCurves.Add(CA); for (int j = 0; j < EL.Count; j++) { Edge E = EL[j]; if (!DrawRelativToSurfaceBase) { DrawPoints[i].Add(E.EdgeStart.Value); } Curve c = Surface.To2dCurve(EL[j].EdgeCurve); if (!EL[j].SameSense) { c.Invert(); } EL[j].ParamCurve = c; CA.Add(c); } xyArray A = CA.getxyArrayClosed(false); DrawPoints[i] = A.ToxyzArray(); } }
void LinkFaces() { for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop E = F.Bounds[j]; for (int k = 0; k < E.Count; k++) { Edge Edge = E[k]; if (Edge.SameSense) { Edge.EdgeCurve.Neighbors[0] = F; } else { Edge.EdgeCurve.Neighbors[1] = F; } } } } }
/// <summary> /// gets the neighbor which is has the <see cref="Edge"/> Bounds[EdgeLoop][Edge] common. /// </summary> /// <param name="EdgeLoop">is the first parameter from Bounds[EdgeLoop][Edge].</param> /// <param name="Edge">is the second parameter from Bounds[EdgeLoop][Edge].</param> /// <returns>a neighbor <b>Face</b></returns> public Face Neighbor(int EdgeLoop, int Edge) { EdgeLoop EL = Bounds[EdgeLoop]; if (EL.Count <= Edge) { return(null); } if (EL[Edge].EdgeCurve.Neighbors[0] == this) { return(EL[Edge].EdgeCurve.Neighbors[1] as Face); } else { if (EL[Edge].EdgeCurve.Neighbors[1] == this) { return(EL[Edge].EdgeCurve.Neighbors[0] as Face); } } return(null); }
/// <summary> /// copies the <b>Face</b> to the <b>TargetSolid</b>. /// </summary> /// <param name="TargetSolid">is the target solid, in which the <see cref="Face"/> will be copied. /// If <b>TargetSolid</b> is null a simply copy of the face will be returned.</param> /// <returns>a copy of <b>Face</b>.</returns> public virtual Face Copy(Solid TargetSolid) { Face Result = Activator.CreateInstance(this.GetType()) as Face; Tag = Result; Result.Bounds = this.Bounds.Copy(TargetSolid); Result._ParamCurves = this.ParamCurves.Copy(); Result.Surface = this.Surface.Copy(); for (int i = 0; i < Result.Bounds.Count; i++) { EdgeLoop EL = Result.Bounds[i]; for (int j = 0; j < EL.Count; j++) { Edge E = EL[j]; Curve3D C = E.EdgeCurve; // if (Result is Face) { if (C.Neighbors == null) { C.Neighbors = new Face[2]; C.Neighbors[0] = Result as Face; } else { C.Neighbors[1] = Result as Face; } } } } if (TargetSolid != null) { TargetSolid.FaceList.Add(Result); } Result.RefreshParamCurves(); 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); }
bool Check() { int FC = FaceList.Count; int KC = EdgeCurveList.Count; int EC = VertexList.Count; int CT = EC - KC + FC - 2; // Euler if (CT == 0) { int ED = EdgeList.Count; if (ED == 2 * KC) { /* Ok*/ } else {// return false; } } else { // return false; for (int i = 0; i < EdgeCurveList.Count; i++) { Edge[] Edges = EdgeCurveList[i].Tag as Edge[]; if (Edges != null) { if ((Edges[0] == null) || (Edges[1] == null)) { } else { if (EdgeList.IndexOf(Edges[0]) == -1) { } if (EdgeList.IndexOf(Edges[1]) == -1) { } } } if (EdgeCurveList[i].A.dist(EdgeCurveList[i].B) < 0.0001) { } } } if (!CheckEdges()) { } ; // return false; for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; int OutLoop = -1; if ((E.SameSense) && ( (E.EdgeCurve.A.dist(E.EdgeStart.Value) > 0.0001) || (E.EdgeCurve.B.dist(E.EdgeEnd.Value) > 0.0001))) { return(false); } if ((!E.SameSense) && ( (E.EdgeCurve.B.dist(E.EdgeStart.Value) > 0.0001) || (E.EdgeCurve.A.dist(E.EdgeEnd.Value) > 0.0001))) { return(false); } Face FF = null; if (E.EdgeCurve.Neighbors[0] == null) { return(false); } if (E.EdgeCurve is Line3D) { Line3D Curve3d = E.EdgeCurve as Line3D; xyz _A = F.Surface.Base.Relativ(Curve3d.A); xyz _B = F.Surface.Base.Relativ(Curve3d.B); if (System.Math.Abs(_A.z) > 0.001) { return(false); } double g = F.Surface.Base.BaseX.length(); double h = F.Surface.Base.BaseY.length(); xyz AA = F.Surface.Base.Absolut(_A); xyz BB = F.Surface.Base.Absolut(_B); if (AA.dist(Curve3d.A) > 0.001) { return(false); } } if (E.EdgeCurve.Neighbors[0] == E.EdgeCurve.Neighbors[1]) { return(false); } if (!FaceList.Contains(E.EdgeCurve.Neighbors[0])) { } if (!FaceList.Contains(E.EdgeCurve.Neighbors[1])) { return(false); } double d = Face.GetDualEdge(F, j, k + 0.01, ref OutLoop, ref FF); } } } return(true); }
/// <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); }
/// <summary> /// overrides <see cref="Solid.Refresh"/>. /// </summary> public override void Refresh() { Clear(); Torus TorusSurface = new Torus(); TorusSurface.VResolution = VResolution; TorusSurface.UResolution = UResolution; TorusSurface.InnerRadius = InnerRadius; TorusSurface.OuterRadius = OuterRadius; Vertex3d[,] Points = new Vertex3d[TorusSurface.UResolution, TorusSurface.VResolution]; xyz[,] Normals = new xyz[TorusSurface.UResolution, TorusSurface.VResolution]; Line3D[,] HorzCurves = new Line3D[TorusSurface.UResolution, TorusSurface.VResolution]; Line3D[,] VertCurves = new Line3D[TorusSurface.UResolution, TorusSurface.VResolution]; for (int i = 0; i < TorusSurface.UResolution; i++) { for (int j = 0; j < TorusSurface.VResolution; j++) { Normals[i, j] = TorusSurface.Normal(((float)i / (float)TorusSurface.UResolution), (float)j / (float)TorusSurface.VResolution); Points[i, j] = new Vertex3d(TorusSurface.Value((float)i / (float)TorusSurface.UResolution, (float)j / (float)TorusSurface.VResolution)); VertexList.Add(Points[i, j]); } } for (int i = 0; i < TorusSurface.UResolution; i++) { for (int j = 0; j < TorusSurface.VResolution; j++) { if (i + 1 < TorusSurface.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 + 1 < TorusSurface.VResolution) { VertCurves[i, j] = new Line3D(Points[i, j].Value, Points[i, j + 1].Value); } else { VertCurves[i, j] = new Line3D(Points[i, j].Value, Points[i, 0].Value); } VertCurves[i, j].Neighbors = new Face[2]; EdgeCurveList.Add(VertCurves[i, j]); } } for (int i = 0; i < TorusSurface.UResolution; i++) { for (int j = 0; j < TorusSurface.VResolution; j++) { int jIndex = -1; if (j + 1 < TorusSurface.VResolution) { jIndex = j + 1; } else { jIndex = 0; } int iIndex = -1; if (i + 1 < TorusSurface.UResolution) { iIndex = i + 1; } else { iIndex = 0; } Vertex3d A = Points[i, j]; Vertex3d B = null; B = Points[i, jIndex]; Vertex3d C = null; C = Points[iIndex, jIndex]; Vertex3d D = null; D = Points[iIndex, j]; Face F = new Face(); FaceList.Add(F); F.Surface = new SmoothPlane(Points[i, j].Value, Points[iIndex, jIndex].Value, Points[i, jIndex].Value, Points[iIndex, j].Value, Normals[i, j], Normals[iIndex, jIndex], Normals[i, jIndex], Normals[iIndex, j]);; EdgeLoop EL = new EdgeLoop(); F.Bounds.Add(EL); if (A != B) { 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); } else { } if (B != C) { Edge E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = B; E.EdgeEnd = C; if (j + 1 < TorusSurface.VResolution) { E.EdgeCurve = HorzCurves[i, j + 1]; } else { E.EdgeCurve = HorzCurves[i, 0]; } if (E.EdgeCurve.A.dist(B.Value) > 0.001) { } E.EdgeCurve.Neighbors[0] = F; E.SameSense = true; E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); } else { } if (C != D) { Edge E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = C; E.EdgeEnd = D; if (i + 1 < TorusSurface.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(); } else { } if (A != D) { Edge 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(); } else { } } } RefreshParamCurves(); }
void RefreshNormals() { Normals = new Loxyz(); Normals.Count = Bounds.Count; DrawPoints = new Loxyz(); DrawPoints.Count = ParamCurves.Count; if (!DrawRelativToSurfaceBase) { for (int i = 0; i < Bounds.Count; i++) { EdgeLoop EL = Bounds[i]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; DrawPoints[i].Add(E.EdgeStart.Value); } } } for (int i = 0; i < ParamCurves.Count; i++) { xyArray A = ParamCurves[i].getxyArrayClosed(false); if (DrawRelativToSurfaceBase) { DrawPoints[i] = A.ToxyzArray(); } int ct = 0; for (int t = 0; t < ParamCurves[i].Count; t++) { ct = ct + ParamCurves[i][t].Resolution; } xyzArray NormalsLoop = new xyzArray(ct); Normals[i] = NormalsLoop; int id = 0; for (int j = 0; j < ParamCurves[i].Count; j++) { List <Face> L = GetFaces(this, i, j); Edge E = Bounds[i][j]; if (L == null) { Normals = null; DrawPoints = null; return; } double SmoothAngle = Parent.SmoothAngle; xyz N = Surface.Normal(0, 0).normalized(); xyz N1 = Surface.Normal(0, 0).normalized(); for (int k = 0; k < L.Count; k++) { if (System.Math.Abs((N1 * L[k].Surface.Normal(0, 0).normalized())) > System.Math.Cos(SmoothAngle)) { N = N + L[k].Surface.Normal(0, 0).normalized(); } } N = N.normalized(); if (DrawRelativToSurfaceBase) { Matrix M = Surface.Base.ToMatrix().invert(); N = M * N - M * new xyz(0, 0, 0); } NormalsLoop[id] = N; id++; } } }
/// <summary> /// activates a <b>CatMull</b> division. /// </summary> public void CatMull() { for (int i = 0; i < VertexList.Count; i++) { Vertex3d V = VertexList[i]; V.Tag = new SubDivisionDescriptor(); } for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; F.DrawRelativToSurfaceBase = false; int n = 0; for (int j = 0; j < F.Bounds.Count; j++) { xyz subDivCenter = new xyz(0, 0, 0); EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { n++; Edge E = EL[k]; subDivCenter = subDivCenter + E.EdgeStart.Value; } F.Tag = subDivCenter * (1f / (float)EL.Count); } } for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; int n = 0; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { n++; Edge E = EL[k]; Face Neighbor = null; if (E.SameSense) { Neighbor = E.EdgeCurve.Neighbors[1] as Face; } else { Neighbor = E.EdgeCurve.Neighbors[0] as Face; } E.Tag = ((xyz)(E.EdgeCurve.Neighbors[1] as Face).Tag + (xyz)(E.EdgeCurve.Neighbors[0] as Face).Tag + E.EdgeStart.Value + E.EdgeEnd.Value) * (1f / 4f); // Mittelwert der Facepunkte und der Anfangs und Endpunkte im Tag speichern // E.Tag = ((xyz)F.Tag + (xyz)Neighbor.Tag + E.EdgeStart.Value + E.EdgeEnd.Value) * 0.25; // // den Descriptor im Vertex E.EdgeEnd.Tag updaten SubDivisionDescriptor SDD = E.EdgeEnd.Tag as SubDivisionDescriptor; SDD.Edges.Add(E); SDD.Faces.Add(F); } } } // Update Vertixlist xyz Q = new xyz(0, 0, 0); xyz R = new xyz(0, 0, 0); for (int i = 0; i < VertexList.Count; i++) { Vertex3d V = VertexList[i]; SubDivisionDescriptor SDV = V.Tag as SubDivisionDescriptor; int n = SDV.Faces.Count; if (n == 0) { return; } Q = new xyz(0, 0, 0); R = new xyz(0, 0, 0); for (int j = 0; j < SDV.Faces.Count; j++) { Q = (xyz)SDV.Faces[j].Tag + Q; } Q = Q * (1f / (float)SDV.Faces.Count); for (int j = 0; j < SDV.Edges.Count; j++) { R = (xyz)SDV.Edges[j].Tag + R; } R = R * (1f / (float)SDV.Edges.Count); xyz S = V.Value; V.Value = (Q + R * 2 + S * (n - 3)) * (1f / (float)n); } // Kanten Ersetzen for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; if (E.SameSense) { E.EdgeCurve.A = E.EdgeStart.Value; E.EdgeCurve.B = E.EdgeEnd.Value; } } } } // Kanten Ersetzen for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; if (E.SameSense) { Vertex3d V = new Vertex3d((xyz)E.Tag); insertVertexToSameSenseEdge(F, j, k, V); k++; } } } } FaceList Temp = new FaceList(); for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; for (int x = 0; x < F.Bounds.Count; x++) { EdgeLoop EL = F.Bounds[x]; Edge E2 = null; Vertex3d V1 = new Vertex3d(); V1.Value = (xyz)F.Tag; VertexList.Add(V1); Vertex3d V4 = null; Vertex3d V2 = null; int startIndex = 1; if (EL[0].EdgeStart.Tag == null) // StartPunkt ist eingefügt { startIndex = 0; } int id = startIndex; int counter = 0; Edge First = null; Edge Last = null; while (id >= 0) { counter++; EdgeLoop newEl = new EdgeLoop(); V2 = EL[id].EdgeStart; if (id + 1 < EL.Count) { V4 = EL[id + 1].EdgeEnd; } else { V4 = EL[0].EdgeEnd; } Face newF = new Face(); newF.Parent = F.Parent; Temp.Add(newF); EdgeLoop ELF = new EdgeLoop(); List <xyz> Pt = new List <xyz>(); newF.Surface = new PlaneSurface(V1.Value, V2.Value, V4.Value); // newF.Surface = new PlaneSurface(V1.Value, V2.Value, V4.Value); Edge EA = new Edge(); ELF.Add(EA); EdgeList.Add(EA); EA.EdgeStart = V1; EA.EdgeEnd = V2; if (Last == null) { EA.EdgeCurve = new Line3D(V1.Value, V2.Value); Pt.Add(V1.Value); EdgeCurveList.Add(EA.EdgeCurve); EA.EdgeCurve.Neighbors = new Face[2]; EA.SameSense = true; EA.EdgeCurve.Neighbors[0] = newF; if (id == startIndex) { First = EA; } } else { EA.EdgeStart = Last.EdgeEnd; Pt.Add(EA.EdgeStart.Value); EA.EdgeEnd = Last.EdgeStart; EA.EdgeCurve = Last.EdgeCurve; EA.EdgeCurve.Neighbors[1] = newF; EA.SameSense = false; } newF.Bounds.Add(ELF); E2 = EL[id]; if (E2.SameSense) { E2.EdgeCurve.Neighbors[0] = newF; } else { E2.EdgeCurve.Neighbors[1] = newF; } Pt.Add(E2.EdgeStart.Value); ELF.Add(E2); Edge E3 = null; if (id + 1 < EL.Count) { E3 = EL[id + 1]; } else { E3 = EL[0]; } Pt.Add(E3.EdgeStart.Value); if (E3.SameSense) { E3.EdgeCurve.Neighbors[0] = newF; } else { E3.EdgeCurve.Neighbors[1] = newF; } ELF.Add(E3); Edge EE = new Edge(); EdgeList.Add(EE); EE.EdgeStart = V4; EE.EdgeEnd = V1; ELF.Add(EE); Pt.Add(V4.Value); if (counter < 4) { EE.EdgeCurve = new Line3D(EE.EdgeStart.Value, EE.EdgeEnd.Value); EdgeCurveList.Add(EE.EdgeCurve); EE.EdgeCurve.Neighbors = new Face[2]; EE.EdgeCurve.Neighbors[0] = newF; EE.SameSense = true; } else { EE.EdgeCurve = First.EdgeCurve; EE.EdgeStart = First.EdgeEnd; EE.EdgeEnd = First.EdgeStart; EE.EdgeCurve.Neighbors[1] = newF; EE.SameSense = false; } Last = EE; id++; id++; // newF.Surface = new SmoothPlane(Pt[0],Pt[1],Pt[2],Pt[3], new xyz(1, 0, 0), new xyz(1, 0, 0), new xyz(1, 0, 0), new xyz(1, 0, 0)); // newF.Surface = new SmoothPlane(Pt[0], Pt[1], Pt[2], Pt[3], (Pt[0] - Pt[1]) & (Pt[0] - Pt[3]), (Pt[1] - Pt[0]) & (Pt[1] - Pt[2]), (Pt[2] - Pt[1]) & (Pt[3] - Pt[1]), (Pt[0] - Pt[3]) & (Pt[2] - Pt[3])); if (id + 1 > EL.Count) { break; } // newF.Surface = new PlaneSurface(V1.Value, V2.Value, V4.Value); } } } FaceList = Temp; for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; F.Surface.BoundedCurves = new Loca(); List <xyz> P = new List <xyz>(); xyz P1 = new xyz(0, 0, 0); xyz P2 = new xyz(0, 0, 0); xyz P3 = new xyz(0, 0, 0); xyz P4 = new xyz(0, 0, 0); for (int k = 0; k < F.Bounds.Count; k++) { CurveArray CA = new CurveArray(); F.Surface.BoundedCurves.Add(CA); for (int l = 0; l < F.Bounds[k].Count; l++) { Edge E = F.Bounds[k][l]; CA.Add(new Line(F.Surface.ProjectPoint(E.EdgeStart.Value), F.Surface.ProjectPoint(E.EdgeEnd.Value))); if (l < 4) { P.Add(E.EdgeStart.Value); } } if (i == 3) { List <Edge> L1 = new List <Edge>(); for (int j = 0; j < 3; j++) { for (int m = 0; m < FaceList[j].Bounds.Count; m++) { xyz A = new xyz(0, 0, 0); for (int h = 0; h < FaceList[j].Bounds[m].Count; h++) { Edge E = FaceList[j].Bounds[m][h]; L1.Add(E); } } } for (int h = 0; h < L1.Count; h++) { for (int m = 0; m < L1.Count; m++) { if ((L1[h].EdgeStart.Value.dist(L1[m].EdgeStart.Value) < 0.001) && (h != m)) { } } } } } xyz n = ((P[2] - P[0]) & (P[1] - P[0])); xyz m1 = ((P[3] - P[0]) & (P[2] - P[0])); Loca L = F.Surface.BoundedCurves; if (i / 2 * 2 == i) { F.Surface = new SmoothPlane(P[0], P[1], P[2], P[3], n); } else { F.Surface = new SmoothPlane(P[0], P[1], P[2], P[3], m1); } F.Surface.BoundedCurves = L; // (P[1] - P[0]) & (P[1] - P[2]), (P[2] - P[1]) & (P[2] - P[3]), (P[3] - P[0]) & (P[3] - P[2])); F.DrawRelativToSurfaceBase = false; } }
/// <summary> /// overrides the <see cref="Solid.Refresh"/> method and creates the extruder from the base <see cref="Loxy"/> and the <see cref="Height"/>. /// </summary> public override void Refresh() { if (Polygon.Count == 0) { return; } this.VertexList.Clear(); this.EdgeCurveList.Clear(); this.FaceList.Clear(); List <List <Vertex3d> > DownVertices = new List <List <Vertex3d> >(); List <List <Vertex3d> > UpVertices = new List <List <Vertex3d> >(); List <List <Curve3D> > VertCurves = new List <List <Curve3D> >(); List <List <Curve3D> > DownCurves = new List <List <Curve3D> >(); List <List <Curve3D> > UpCurves = new List <List <Curve3D> >(); List <List <PlaneSurface> > PlaneSurfaces = new List <List <PlaneSurface> >(); for (int i = 0; i < _Polygon.Count; i++) { DownVertices.Add(new List <Vertex3d>()); UpVertices.Add(new List <Vertex3d>()); VertCurves.Add(new List <Curve3D>()); DownCurves.Add(new List <Curve3D>()); UpCurves.Add(new List <Curve3D>()); PlaneSurfaces.Add(new List <PlaneSurface>()); for (int j = 0; j < _Polygon[i].Count; j++) { if (_Polygon[i][0].dist(_Polygon[i][_Polygon[i].Count - 1]) < 0.00001) { _Polygon[i].RemoveAt(_Polygon[i].Count - 1); } } for (int j = 0; j < _Polygon[i].Count; j++) { Vertex3d V = new Vertex3d(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, 0)); VertexList.Add(V); DownVertices[i].Add(V); Curve3D C = null; if (j < _Polygon[i].Count - 1) { C = new Line3D(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, 0), new xyz(_Polygon[i][j + 1].x, _Polygon[i][j + 1].y, 0)); } else { C = new Line3D(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, 0), new xyz(_Polygon[i][0].x, _Polygon[i][0].y, 0)); } DownCurves[i].Add(C); if (!EdgeCurveList.Contains(C)) { this.EdgeCurveList.Add(C); } if (j < _Polygon[i].Count - 1) { C = new Line3D(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, Height), new xyz(_Polygon[i][j + 1].x, _Polygon[i][j + 1].y, Height)); } else { C = new Line3D(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, Height), new xyz(_Polygon[i][0].x, _Polygon[i][0].y, Height)); } UpCurves[i].Add(C); if (!EdgeCurveList.Contains(C)) { EdgeCurveList.Add(C); } V = new Vertex3d(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, Height)); UpVertices[i].Add(V); VertexList.Add(V); C = new Line3D(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, 0), new xyz(_Polygon[i][j].x, _Polygon[i][j].y, Height)); VertCurves[i].Add(C); if (!EdgeCurveList.Contains(C)) { EdgeCurveList.Add(C); } if (j < _Polygon[i].Count - 1) { PlaneSurfaces[i].Add(new PlaneSurface(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, 0), new xyz(_Polygon[i][j + 1].x, _Polygon[i][j + 1].y, 0), new xyz(_Polygon[i][j + 1].x, _Polygon[i][j + 1].y, Height) )); } else { PlaneSurfaces[i].Add(new PlaneSurface(new xyz(_Polygon[i][j].x, _Polygon[i][j].y, 0), new xyz(_Polygon[i][0].x, _Polygon[i][0].y, 0), new xyz(_Polygon[i][0].x, _Polygon[i][0].y, Height) )); } } } for (int i = 0; i < _Polygon.Count; i++) { for (int j = 0; j < _Polygon[i].Count; j++) { Face Face = new Face(); FaceList.Add(Face); Face.Surface = PlaneSurfaces[i][j]; Face.Bounds = new Bounds(); EdgeLoop Loop = new EdgeLoop(); Face.Bounds.Add(Loop); // Von unten nach oben Edge E = new Edge(); EdgeList.Add(E); E.EdgeStart = DownVertices[i][j]; E.EdgeEnd = UpVertices[i][j]; E.EdgeCurve = VertCurves[i][j]; E.SameSense = true; if (j > 0) { VertCurves[i][j].Neighbors[1] = Face; } else { VertCurves[i][0].Neighbors = new Face[2]; VertCurves[i][j].Neighbors[1] = Face; } Loop.Add(E); // Oben E = new Edge(); EdgeList.Add(E); E.SameSense = true; E.EdgeStart = UpVertices[i][j]; if (j < _Polygon[i].Count - 1) { E.EdgeEnd = UpVertices[i][j + 1]; } else { E.EdgeEnd = UpVertices[i][0]; } E.EdgeCurve = UpCurves[i][j]; E.EdgeCurve.Neighbors = new Face[2]; E.EdgeCurve.Neighbors[0] = Face; Loop.Add(E); // Rechts nach unten E = new Edge(); EdgeList.Add(E); int n = j + 1; if (n == _Polygon[i].Count) { n = 0; } E.EdgeStart = UpVertices[i][n]; E.EdgeEnd = DownVertices[i][n]; E.EdgeCurve = VertCurves[i][n]; if (j < _Polygon[i].Count - 1) { E.EdgeCurve.Neighbors = new Face[2]; } E.EdgeCurve.Neighbors[0] = Face; E.SameSense = false; Loop.Add(E); // unten nach links E = new Edge(); EdgeList.Add(E); if (j < _Polygon[i].Count - 1) { E.EdgeStart = DownVertices[i][j + 1]; } else { E.EdgeStart = DownVertices[i][0]; } E.EdgeEnd = DownVertices[i][j]; E.EdgeCurve = DownCurves[i][j]; E.EdgeCurve.Neighbors = new Face[2]; E.EdgeCurve.Neighbors[0] = Face; E.SameSense = false; Loop.Add(E); } } // Boden Face _Face = new Face(); FaceList.Add(_Face); // Face.Surface = PlaneSurfaces[i][j]; _Face.Bounds = new Bounds(); _Face.Surface = new PlaneSurface(DownVertices[0][0].Value, DownVertices[0][2].Value, DownVertices[0][1].Value); for (int i = 0; i < _Polygon.Count; i++) { EdgeLoop Loop = new EdgeLoop(); _Face.Bounds.Add(Loop); for (int j = 0; j < _Polygon[i].Count; j++) { // Von unten nach oben Edge E = new Edge(); EdgeList.Add(E); E.EdgeStart = DownVertices[i][j]; if (j + 1 < _Polygon[i].Count) { E.EdgeEnd = DownVertices[i][j + 1]; } else { E.EdgeEnd = DownVertices[i][0]; } E.EdgeCurve = DownCurves[i][j]; E.SameSense = true; E.EdgeCurve.Neighbors[1] = _Face; Loop.Add(E); } } // Deckel _Face = new Face(); FaceList.Add(_Face); // Face.Surface = PlaneSurfaces[i][j]; _Face.Bounds = new Bounds(); _Face.Surface = new PlaneSurface(UpVertices[0][0].Value, UpVertices[0][1].Value, UpVertices[0][2].Value); for (int i = 0; i < _Polygon.Count; i++) { EdgeLoop Loop = new EdgeLoop(); _Face.Bounds.Add(Loop); for (int j = _Polygon[i].Count - 1; j >= 0; j--) { Edge E = new Edge(); EdgeList.Add(E); E.EdgeEnd = UpVertices[i][j]; if (j + 1 < _Polygon[i].Count) { E.EdgeStart = UpVertices[i][j + 1]; } else { E.EdgeStart = UpVertices[i][0]; } E.EdgeCurve = UpCurves[i][j]; E.SameSense = false; E.EdgeCurve.Neighbors[1] = _Face; Loop.Add(E); } } this.NewParamCurves(); }
/// <summary> /// overrides <see cref="Solid.Refresh"/>. /// </summary> public override void Refresh() { Clear(); Sphere SphereSurface = new Sphere(); SphereSurface.VResolution = VResolution; SphereSurface.UResolution = UResolution; SphereSurface.Radius = Radius; Vertex3d NP = new Vertex3d(new xyz(0, 0, Radius)); Vertex3d SP = new Vertex3d(new xyz(0, 0, -Radius)); Vertex3d[,] Points = new Vertex3d[SphereSurface.UResolution + 1, SphereSurface.VResolution + 1]; Line3D[,] HorzCurves = new Line3D[SphereSurface.UResolution, SphereSurface.VResolution]; Line3D[,] VertCurves = new Line3D[SphereSurface.UResolution, SphereSurface.VResolution]; xyz[,] Normals = new xyz[SphereSurface.UResolution + 1, SphereSurface.VResolution + 1]; VertexList.Add(NP); VertexList.Add(SP); for (int i = 0; i < SphereSurface.UResolution + 1; i++) { for (int j = 0; j < SphereSurface.VResolution + 1; j++) { Normals[i, j] = SphereSurface.Normal(((float)i / (float)SphereSurface.UResolution), (float)j / (float)SphereSurface.VResolution); if (j == 0) { Points[i, j] = SP; continue; } if (j == SphereSurface.VResolution) { Points[i, j] = NP; continue; } if (i == SphereSurface.UResolution) { Points[i, j] = Points[0, j]; continue; } Points[i, j] = new Vertex3d(SphereSurface.Value((float)i / (float)SphereSurface.UResolution, (float)j / (float)SphereSurface.VResolution)); VertexList.Add(Points[i, j]); } } for (int i = 0; i < SphereSurface.UResolution; i++) { for (int j = 0; j < SphereSurface.VResolution; j++) { if (i < SphereSurface.UResolution) { if (i + 1 < SphereSurface.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]; if (HorzCurves[i, j].A.dist(HorzCurves[i, j].B) > 0.0001) { EdgeCurveList.Add(HorzCurves[i, j]); } } if (j < SphereSurface.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]); } } } // if (false) for (int i = 0; i < SphereSurface.UResolution; i++) { for (int j = 0; j < SphereSurface.VResolution; j++) { Vertex3d A = Points[i, j]; Vertex3d B = Points[i, j + 1]; Vertex3d C = null; if (i + 1 < SphereSurface.UResolution) { C = Points[i + 1, j + 1]; } else { C = Points[0, j + 1]; } Vertex3d D = null; if (i + 1 < SphereSurface.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[i + 1, j + 1].Value, Points[i, j + 1].Value, Points[i + 1, j].Value, Normals[i, j], Normals[i + 1, j + 1], Normals[i, j + 1], Normals[i + 1, j]);; EdgeLoop EL = new EdgeLoop(); F.Bounds.Add(EL); if (A != B) { 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); } if (B != C) { Edge E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = B; E.EdgeEnd = C; if (j + 1 < SphereSurface.VResolution) { E.EdgeCurve = HorzCurves[i, j + 1]; } else { E.EdgeCurve = HorzCurves[i, 0]; } if (E.EdgeCurve.A.dist(B.Value) > 0.001) { } E.EdgeCurve.Neighbors[0] = F; E.SameSense = true; E.ParamCurve = F.Surface.To2dCurve(E.EdgeCurve); } if (C != D) { Edge E = new Edge(); EL.Add(E); EdgeList.Add(E); E.EdgeStart = C; E.EdgeEnd = D; if (i + 1 < SphereSurface.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(); } if (A != D) { Edge 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(); } } } RefreshParamCurves(); // base.Refresh(); //if (!Check()) //{ //} }
/// <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(); }
static CrossList CrossWithLine(xy A, xy B, xyArray Array, EdgeLoop E) { CrossList Result = new CrossList(); double Lam = -1; double Mue = -1; _Array1 = Array; xy Last = Array[Array.Count - 1]; for (int i = 0; i < Array.Count - 1; i++) { if (i < Array.Count - 1) { if (Array[i].dist(Array[i + 1]) < LuckyEpsilon) { continue; } } int Nexti = Succ(i); xy Next = Array[Nexti]; if (!(TwoLines(A, B, Array[i], Next, ref Lam, ref Mue))) { continue; } Lam = System.Math.Round(Lam, 8); Mue = System.Math.Round(Mue, 8); double D1 = Distance(Next, A, B); double D2 = Distance(Array[i], A, B); int Prv = Prev(i); double D3 = Distance(Array[Prv], A, B); if ((System.Math.Abs(D1) < EdgeTolerance) && (System.Math.Abs(D2) < EdgeTolerance)) { Last = Array[i]; continue; } if ((System.Math.Abs(D1) >= EdgeTolerance) && (System.Math.Abs(D2) < EdgeTolerance)) { if ((System.Math.Abs(D3) < EdgeTolerance)) { CrossItem CI = new CrossItem(i + LuckyEpsilon, Lam, -1);// FromBorder if (D1 > 0) { CI.CrossKind = 1; } else { CI.CrossKind = -1; } CI.Border1 = BorderBehavior.BorderEnd; Result.Add(CI); continue; } } if ((System.Math.Abs(D1) < EdgeTolerance) && (System.Math.Abs(D2) >= EdgeTolerance)) { int succ = Succ(Nexti); double SuccDistance = System.Math.Abs(Distance(Array[succ], A, B)); if (SuccDistance <= EdgeTolerance) { // ToBorder CrossItem CI = new CrossItem(i + (1 - LuckyEpsilon), Lam, -1);// ToBorder CI.CrossKind = 1; if (D2 < 0) { CI.CrossKind = 1; } else { CI.CrossKind = -1; } CI.Border1 = BorderBehavior.BorderBegin; Result.Add(CI); Last = Array[i]; } continue; } if ((System.Math.Abs(D2) < EdgeTolerance) && (D1 * D3 < 0)) { // Mue ==0 Durchgehend int kk = ToSide; if (D1 < 0) { kk = -ToSide; } CrossItem CI = new CrossItem(i - Mue - 0.000000001, Lam, -1); CI.CrossKind = 1; if (D1 < 0) { CI.CrossKind = -1; } Result.Add(CI); Last = Array[i]; continue; } else //else // neu------------------------------------------------------------ if ((System.Math.Abs(D2) < EdgeTolerance) && (D1 * D3 > 0)) { if ((Mue >= -LuckyEpsilon) && ((Mue < 1 - LuckyEpsilon) && (Lam >= -LuckyEpsilon) && ((Lam <= 1 + LuckyEpsilon)))) { xy v1 = Array[i] - Array[Prv]; xy v2 = Next - Array[i]; double kk = v1 & v2; if (kk * D1 < 0) { } //D1 = v1 & v2; //D1 = -D1; CrossItem CI = null; // new CrossItem(i + Mue, Lam, -1);// ToBorder if (D1 > 0) { CI = new CrossItem(i + Mue - LuckyEpsilon, Lam + LuckyEpsilon, -1); // FromBorder } else { CI = new CrossItem(i + Mue - LuckyEpsilon, Lam - LuckyEpsilon, -1); // FromBorder } if (D1 < 0) { CI.CrossKind = 1; } else { CI.CrossKind = -1; } CI.Border1 = BorderBehavior.BorderBegin; Result.Add(CI); if (D1 < 0) { CI = new CrossItem(i + Mue + LuckyEpsilon, Lam + LuckyEpsilon, -1); // FromBorder } else { CI = new CrossItem(i + Mue + LuckyEpsilon, Lam - LuckyEpsilon, -1); // FromBorder } if (D1 > 0) { CI.CrossKind = 1; } else { CI.CrossKind = -1; } CI.Border1 = BorderBehavior.BorderEnd; Result.Add(CI); continue; } } if (D1 * D2 < 0) { CrossItem CI = new CrossItem(i + Mue, Lam, -1); CI.CrossKind = 1; if (D1 < 0) { CI.CrossKind = -1; } Result.Add(CI); Last = Array[i]; continue; } } return(Result); }