/// <summary> /// generates an edge in <see cref="Drawing3d.Model.Solid"/> model. The belonging <b>Face</b>, /// the start point, the end point and with the difference to <see cref="SolidEdge(Solid,Face, Vertex3d, Vertex3d,Curve3D)"/> /// the the paramcurve on the <b>Face</b> must be specified. /// </summary> /// <param name="Solid"><see cref="Solid"/>, in which the <see cref="Edge"/> should be generated.</param> /// <param name="Face">the <see cref="Face"/> for the <see cref="Edge"/>.</param> /// <param name="A">start point</param> /// <param name="B">end point</param> /// <param name="ParamCurve">paramcurve on the <b>Face</b></param> /// <returns>a <b>edge</b>in the <see cref="Drawing3d.Model.Solid"/> model.</returns> public static Edge SolidEdge(Solid Solid, Face Face, Vertex3d A, Vertex3d B, Curve ParamCurve) { Curve3D Curve3d = GetEdgeCurve(Solid, B, A); Edge Result = new Edge(); if (Curve3d == null) { Result.SameSense = true; Curve3d = Face.Surface.To3dCurve(ParamCurve); Result.ParamCurve = ParamCurve; Result.EdgeStart = A; Result.EdgeEnd = B; } else { Result.EdgeStart = B; Result.EdgeEnd = A; ParamCurve.Invert(); Result.ParamCurve = ParamCurve; Result.SameSense = false; } Result.EdgeCurve = Curve3d; // muss vor Edges.add stehen weil es dort in die sufacelist aufgenommen wird Solid.EdgeList.Add(Result); return(Result); }
/// <summary> /// copy the the edge <b>TargetSolid</b> and adds the copy to the EdgeList of the targetSolid . /// </summary> /// <param name="TargetSolid">solid, in which a copied edge should be created.</param> /// <returns>copy of the edge.</returns> public virtual Edge Copy(Solid TargetSolid) { Edge Result = Activator.CreateInstance(this.GetType()) as Edge; Vertex3d VStart = null; Vertex3d VEnd = null; { VStart = new Vertex3d(EdgeStart.Value); EdgeStart.Tag = VStart; if (TargetSolid != null) { TargetSolid.VertexList.Add(VStart); } } { VEnd = new Vertex3d(EdgeEnd.Value); EdgeEnd.Tag = VEnd; if (TargetSolid != null) { TargetSolid.VertexList.Add(VEnd); } } Result.EdgeStart = VStart; Result.EdgeEnd = VEnd; Curve3D ECurve = null; if (TargetSolid != null) { ECurve = GetEdgeCurve(TargetSolid, VStart, VEnd); if (ECurve == null) { ECurve = GetEdgeCurve(TargetSolid, VEnd, VStart); } } if (ECurve == null) { ECurve = EdgeCurve.Copy(); if (TargetSolid != null) { TargetSolid.EdgeCurveList.Add(ECurve); } } Result.EdgeCurve = ECurve; Result.ParamCurve = ParamCurve.Clone(); Result.CurveId = CurveId; Result.SameSense = SameSense; if (TargetSolid != null) { TargetSolid.EdgeList.Add(Result); } return(Result); }
/// <summary> /// static method, who generates a edge an arbitrary <see cref="Curve3D"/> in the <see cref="Drawing3d.Model.Shell"/> model. /// </summary> /// <param name="Curve">a <see cref="Curve3D"/></param> /// <returns>an edge.</returns> public static Edge ShellEdge(Curve3D Curve) { Edge Result = new Edge(); Result.EdgeStart = new Vertex3d(Curve.A); Result.EdgeEnd = new Vertex3d(Curve.B); Result.EdgeCurve = Curve; Result.SameSense = true; return(Result); }
/// <summary> /// Inserts a point at the position, which is given by Param. /// </summary> /// <param name="Param">Position, where a point will be inserted</param> /// <returns>The new part of the curve</returns> public Curve3D InsertPoint(double Param) { if (Utils.Equals(Param, 0)) { return(null); } if (Utils.Equals(Param, 1)) { return(null); } Curve3D Result = Clone(); Slice(0, Param); Result.Slice(Param, 1); return(Result); }
/// <summary> /// Copy the Curve. Some instances override this method. /// </summary> /// <returns>A copy of the curve.</returns> public virtual Curve3D Copy() { try { BinaryFormatter formatter = new BinaryFormatter(); System.IO.MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, this); stream.Position = 0; Curve3D result = formatter.Deserialize(stream) as Curve3D; stream.Close(); return(result); } catch (Exception E) { System.Windows.Forms.MessageBox.Show(E.Message); } return(null); }
/// <summary> /// generates in <see cref="Curve3D"/> in the <see cref="Drawing3d.Model.Solid"/> model an edge. /// It needs the belonging <b>Face</b>, the start point, the end point and the 3D-curve. /// </summary> /// <param name="Solid">solid, in which the edge should be generated.</param> /// <param name="Face"><see cref="Face"/>, in which the edge should be generated.</param> /// <param name="A">start point.</param> /// <param name="B">end point.</param> /// <param name="Curve">a 3D curve</param> /// <returns>an edge in the <see cref="Drawing3d.Model.Solid"/> model.</returns> public static Edge SolidEdge(Solid Solid, Face Face, Vertex3d A, Vertex3d B, Curve3D Curve) { bool Orientation = true; Curve3D SC = GetEdgeCurve(Solid, A, B); if (SC == null) { SC = GetEdgeCurve(Solid, B, A); if (SC != null) { Orientation = false; SC.Neighbors[1] = Face; } } if (SC == null) { Curve.Neighbors = new Face[2]; Curve.Neighbors[0] = Face; if (Solid != null) { Solid.EdgeCurveList.Add(Curve); } SC = Curve; } Edge Result = new Edge(); Result.EdgeCurve = SC; Result.EdgeStart = A; Result.EdgeEnd = B; Result.SameSense = Orientation; if (Solid != null) { Solid.EdgeList.Add(Result); } Result.ParamCurve = Face.Surface.To2dCurve(Curve); return(Result); }
/// <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); }
/// <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(); }
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); }