/// <summary> /// draws a list of 2D curves. See also <see cref="CurveArray"/> /// </summary> /// <param name="CA"><see cref="CurveArray"/></param> public void drawPolyCurve(CurveArray CA) { xyArray A = CA.getxyArray(); Object Handle = null; if ((RenderKind == RenderKind.SnapBuffer)) { Handle = Selector.RegisterSnapItem(new PolyCurveSnappItem(CA)); } drawPolyLine(A); if ((RenderKind == RenderKind.SnapBuffer)) { Selector.UnRegisterSnapItem(Handle); } }
/// <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(); } }
private ArrayList GetConnections() { ArrayList Result = new ArrayList(); if (Count == 0) { return(Result); } int i = 0; do { CurveArray CA = new CurveArray(); Result.Add(CA); CA.Add(this[i]); while ((i < Count - 1) && ((Curve)this[i]).B.Equals(((Curve)this[i + 1]).A)) { CA.Add(this[i + 1]); i++; } i++; } while (i < Count); if (Result.Count > 1) { CurveArray First = (CurveArray)Result[0]; CurveArray Last = (CurveArray)Result[Result.Count - 1]; if (((Curve)First[0]).A.Equals(((Curve)Last[Last.Count - 1]).B)) { for (i = Last.Count - 1; i >= 0; i--) { First.Insert(0, Last[i]); } Result.Remove(Last); } } return(Result); }
/// <summary> /// It`s the same as the overloaded method, but you can set, whether Tangential points /// should be taken or not. /// </summary> /// <param name="value">An other CurveArray</param> /// <param name="TangentialPoints">True, if the tangential points are taken</param> /// <returns>A Crosslist</returns> public CrossList getCrossList(CurveArray value, bool TangentialPoints) { ArrayList L1 = GetConnections(); ArrayList L2 = value.GetConnections(); int StartJ; CrossList CL; CrossList Result = new CrossList(); Result.AllowMultiCross = TangentialPoints;// for instant int AIndex = 0; for (int i = 0; i < L1.Count; i++) { CurveArray CA = (CurveArray)L1[i]; xyArray A = CA.getxyArray(); int BIndex = 0; StartJ = 0; for (int j = StartJ; j < L2.Count; j++) { CurveArray CB = (CurveArray)L2[j]; xyArray B = CB.getxyArray(); CL = A.getCrossList(B, TangentialPoints); for (int k = 0; k < CL.Count; k++) { CrossItem CI = CL[k]; double aID = CA.xyArrayIndexToCurveArrayIndex(CI.Param1); double bID = CB.xyArrayIndexToCurveArrayIndex(CI.Param2); CI.Param1 = (float)AIndex + CA.xyArrayIndexToCurveArrayIndex(CI.Param1); CI.Param2 = (float)BIndex + CB.xyArrayIndexToCurveArrayIndex(CI.Param2); Curve C1 = CA[Utils.trunc(aID)]; Curve C2 = CB[Utils.trunc(bID)]; double Lam = CI.Param1 - Utils.trunc(CI.Param1); double Mue = CI.Param2 - Utils.trunc(CI.Param2); CI.Param1 = IndexOf(C1) + Lam; CI.Param2 = value.IndexOf(C2) + Mue; Mue = CI.Param2 - Utils.trunc(CI.Param2); Lam = CI.Param1 - Utils.trunc(CI.Param1); if (C1.Cross(C2, Lam, Mue, out Lam, out Mue)) { if ((Lam < 0) && ((System.Math.Abs(Lam) < 0.000001))) { Lam = 0; } if (System.Math.Abs(Lam - 1) < 0.00001) { Lam = 0.999999; } CI.Param1 = Utils.trunc(CI.Param1) + Lam; if ((Mue < 0) && ((System.Math.Abs(Mue) < 0.000001))) { Mue = 0; } if (System.Math.Abs(Mue - 1) < 0.00001) { Mue = 0.999999; } CI.Param2 = Utils.trunc(CI.Param2) + Mue; } else { Lam = 0; if (C1.Equals(C2)) { Lam = 1; } } if ((Utils.trunc(CI.Param1) < 0) && (System.Math.Abs(CI.Param1) < 0.00001)) { CI.Param1 = 0; } if ((Utils.trunc(CI.Param2) < 0) && (System.Math.Abs(CI.Param2) < 0.00001)) { CI.Param2 = 0; } //if (((Utils.trunc(System.Math.Round(CI.Param1,3)) !=System.Math.Round(CI.Param1,3))) // || // ((Utils.trunc(System.Math.Round(CI.Param1,3)) !=System.Math.Round(CI.Param1,3)))) Result.Add(CI); } BIndex += CB.Count; } AIndex += CA.Count; } return(Result); }
/// <summary> /// Calucalates a <see cref="CrossList"/> for this CurveArray with an other CurveArray. /// The CrossItemparameter <see cref="CrossItem.Param1"/> is relative to this CurveArray /// and the parameter <see cref="CrossItem.Param2"/> relative to the "value"-CurveArray. /// </summary> /// <param name="value">An other CurveArray</param> /// <returns>A CrossList</returns> public CrossList getCrossList(CurveArray value) { return(getCrossList(value, false)); }
/// <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; } }
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); }