/// <summary> /// Method used to add a vertex properly for internal methods /// </summary> /// <param name="pos">vertex position</param> /// <param name="status">vertex status</param> /// <returns>The vertex inserted (if a similar vertex already exists, this is returned).</returns> private Vertex AddVertex(Vector3d pos, Status status) { int i; //if already there is an equal vertex, it is not inserted Vertex vertex = new Vertex(pos, status); for (i = 0; i < Vertices.Count; i++) { if (vertex.Equals(Vertices[i])) { break; } } if (i == Vertices.Count) { Vertices.Add(vertex); return(vertex); } else { vertex = Vertices[i]; vertex.SetStatus(status); return(vertex); } }
/// <summary> /// Method used to add a vertex properly for internal methods /// </summary> /// <param name="pos">vertex position</param> /// <param name="status">vertex status</param> /// <returns>The vertex inserted (if a similar vertex already exists, this is returned).</returns> private Vertex AddVertex(Vector3 pos, Status status) { Vertex vertex = new Vertex(pos, status); for (int i = 0; i < vertices.Count; i++) { if (vertex.Equals(vertices[i])) { // if the vertex is already there, it is not inserted vertex = vertices[i]; vertex.SetStatus(status); return(vertex); } } vertices.Add(vertex); return(vertex); }
/// <summary> /// Split an individual face /// </summary> /// <param name="faceIndex">face index in the array of faces</param> /// <param name="segment1">segment representing the intersection of the face with the plane</param> /// <param name="segment2">segment representing the intersection of other face with the plane of the current face plane</param> private bool SplitFace(int faceIndex, Segment segment1, Segment segment2) { Vector3 startPos, endPos; int startType, endType, middleType; double startDist, endDist; Face face = GetFace(faceIndex); Vertex startVertex = segment1.GetStartVertex(); Vertex endVertex = segment1.GetEndVertex(); //starting point: deeper starting point if (segment2.StartDist > segment1.StartDist + EqualityTolerance) { startDist = segment2.StartDist; startType = segment1.GetIntermediateType(); startPos = segment2.GetStartPosition(); } else { startDist = segment1.StartDist; startType = segment1.GetStartType(); startPos = segment1.GetStartPosition(); } //ending point: deepest ending point if (segment2.GetEndDistance() < segment1.GetEndDistance() - EqualityTolerance) { endDist = segment2.GetEndDistance(); endType = segment1.GetIntermediateType(); endPos = segment2.GetEndPosition(); } else { endDist = segment1.GetEndDistance(); endType = segment1.GetEndType(); endPos = segment1.GetEndPosition(); } middleType = segment1.GetIntermediateType(); if (startType == Segment.VERTEX) { //set vertex to BOUNDARY if it is start type startVertex.SetStatus(Status.BOUNDARY); } if (endType == Segment.VERTEX) { //set vertex to BOUNDARY if it is end type endVertex.SetStatus(Status.BOUNDARY); } if (startType == Segment.VERTEX && endType == Segment.VERTEX) { //VERTEX-_______-VERTEX return(false); } else if (middleType == Segment.EDGE) { //______-EDGE-______ //gets the edge int splitEdge; if ((startVertex == face.v1 && endVertex == face.v2) || (startVertex == face.v2 && endVertex == face.v1)) { splitEdge = 1; } else if ((startVertex == face.v2 && endVertex == face.v3) || (startVertex == face.v3 && endVertex == face.v2)) { splitEdge = 2; } else { splitEdge = 3; } if (startType == Segment.VERTEX) { //VERTEX-EDGE-EDGE return(BreakFaceInTwo(faceIndex, endPos, splitEdge)); } else if (endType == Segment.VERTEX) { //EDGE-EDGE-VERTEX return(BreakFaceInTwo(faceIndex, startPos, splitEdge)); } else if (startDist == endDist) { // EDGE-EDGE-EDGE return(BreakFaceInTwo(faceIndex, endPos, splitEdge)); } else { if ((startVertex == face.v1 && endVertex == face.v2) || (startVertex == face.v2 && endVertex == face.v3) || (startVertex == face.v3 && endVertex == face.v1)) { return(BreakFaceInThree(faceIndex, startPos, endPos, splitEdge)); } else { return(BreakFaceInThree(faceIndex, endPos, startPos, splitEdge)); } } } //______-FACE-______ else if (startType == Segment.VERTEX && endType == Segment.EDGE) { //VERTEX-FACE-EDGE return(BreakFaceInTwo(faceIndex, endPos, endVertex)); } else if (startType == Segment.EDGE && endType == Segment.VERTEX) { //EDGE-FACE-VERTEX return(BreakFaceInTwo(faceIndex, startPos, startVertex)); } else if (startType == Segment.VERTEX && endType == Segment.FACE) { //VERTEX-FACE-FACE return(BreakFaceInThree(faceIndex, endPos)); } else if (startType == Segment.FACE && endType == Segment.VERTEX) { //FACE-FACE-VERTEX return(BreakFaceInThree(faceIndex, startPos)); } else if (startType == Segment.EDGE && endType == Segment.EDGE) { //EDGE-FACE-EDGE return(BreakFaceInThree(faceIndex, startPos, endPos, startVertex, endVertex)); } else if (startType == Segment.EDGE && endType == Segment.FACE) { //EDGE-FACE-FACE return(BreakFaceInFour(faceIndex, startPos, endPos, startVertex)); } else if (startType == Segment.FACE && endType == Segment.EDGE) { //FACE-FACE-EDGE return(BreakFaceInFour(faceIndex, endPos, startPos, endVertex)); } else if (startType == Segment.FACE && endType == Segment.FACE) { //FACE-FACE-FACE Vector3 segmentVector = new Vector3(startPos.x - endPos.x, startPos.y - endPos.y, startPos.z - endPos.z); //if the intersection segment is a point only... if (Math.Abs(segmentVector.x) < EqualityTolerance && Math.Abs(segmentVector.y) < EqualityTolerance && Math.Abs(segmentVector.z) < EqualityTolerance) { return(BreakFaceInThree(faceIndex, startPos)); } //gets the vertex more lined with the intersection segment int linedVertex; Vector3 linedVertexPos; Vector3 vertexVector = new Vector3(endPos.x - face.v1.Position.x, endPos.y - face.v1.Position.y, endPos.z - face.v1.Position.z); vertexVector.Normalize(); double dot1 = Math.Abs(Vector3.Dot(segmentVector, vertexVector)); vertexVector = new Vector3(endPos.x - face.v2.Position.x, endPos.y - face.v2.Position.y, endPos.z - face.v2.Position.z); vertexVector.Normalize(); double dot2 = Math.Abs(Vector3.Dot(segmentVector, vertexVector)); vertexVector = new Vector3(endPos.x - face.v3.Position.x, endPos.y - face.v3.Position.y, endPos.z - face.v3.Position.z); vertexVector.Normalize(); double dot3 = Math.Abs(Vector3.Dot(segmentVector, vertexVector)); if (dot1 > dot2 && dot1 > dot3) { linedVertex = 1; linedVertexPos = face.v1.GetPosition(); } else if (dot2 > dot3 && dot2 > dot1) { linedVertex = 2; linedVertexPos = face.v2.GetPosition(); } else { linedVertex = 3; linedVertexPos = face.v3.GetPosition(); } // Now find which of the intersection endpoints is nearest to that vertex. if ((linedVertexPos - startPos).Length > (linedVertexPos - endPos).Length) { return(BreakFaceInFive(faceIndex, startPos, endPos, linedVertex)); } else { return(BreakFaceInFive(faceIndex, endPos, startPos, linedVertex)); } } return(false); }
/// <summary> /// Split an individual face /// </summary> /// <param name="facePos">face position on the array of faces</param> /// <param name="segment1">segment representing the intersection of the face with the plane</param> /// <param name="segment2">segment representing the intersection of other face with the plane of the current face plane</param> private void SplitFace(int facePos, Segment segment1, Segment segment2) { Vector3d startPos, endPos; int startType, endType, middleType; double startDist, endDist; Face face = GetFace(facePos); Vertex startVertex = segment1.StartVertex; Vertex endVertex = segment1.EndVertex; //starting point: deeper starting point if (segment2.StartDist > segment1.StartDist + EqualityTolerance) { startDist = segment2.StartDist; startType = segment1.IntermediateType; startPos = segment2.StartPosition; } else { startDist = segment1.StartDist; startType = segment1.StartType; startPos = segment1.StartPosition; } //ending point: deepest ending point if (segment2.EndDistance < segment1.EndDistance - EqualityTolerance) { endDist = segment2.EndDistance; endType = segment1.IntermediateType; endPos = segment2.EndPosition; } else { endDist = segment1.EndDistance; endType = segment1.EndType; endPos = segment1.EndPosition; } middleType = segment1.IntermediateType; //set vertex to BOUNDARY if it is start type if (startType == Segment.VERTEX) { startVertex.SetStatus(Status.BOUNDARY); } //set vertex to BOUNDARY if it is end type if (endType == Segment.VERTEX) { endVertex.SetStatus(Status.BOUNDARY); } //VERTEX-_______-VERTEX if (startType == Segment.VERTEX && endType == Segment.VERTEX) { return; } //______-EDGE-______ else if (middleType == Segment.EDGE) { //gets the edge int splitEdge; if ((startVertex == face.V1 && endVertex == face.V2) || (startVertex == face.V2 && endVertex == face.V1)) { splitEdge = 1; } else if ((startVertex == face.V2 && endVertex == face.V3) || (startVertex == face.V3 && endVertex == face.V2)) { splitEdge = 2; } else { splitEdge = 3; } //VERTEX-EDGE-EDGE if (startType == Segment.VERTEX) { BreakFaceInTwo(facePos, endPos, splitEdge); return; } //EDGE-EDGE-VERTEX else if (endType == Segment.VERTEX) { BreakFaceInTwo(facePos, startPos, splitEdge); return; } // EDGE-EDGE-EDGE else if (startDist == endDist) { BreakFaceInTwo(facePos, endPos, splitEdge); } else { if ((startVertex == face.V1 && endVertex == face.V2) || (startVertex == face.V2 && endVertex == face.V3) || (startVertex == face.V3 && endVertex == face.V1)) { BreakFaceInThree(facePos, startPos, endPos, splitEdge); } else { BreakFaceInThree(facePos, endPos, startPos, splitEdge); } } return; } //______-FACE-______ //VERTEX-FACE-EDGE else if (startType == Segment.VERTEX && endType == Segment.EDGE) { BreakFaceInTwo(facePos, endPos, endVertex); } //EDGE-FACE-VERTEX else if (startType == Segment.EDGE && endType == Segment.VERTEX) { BreakFaceInTwo(facePos, startPos, startVertex); } //VERTEX-FACE-FACE else if (startType == Segment.VERTEX && endType == Segment.FACE) { BreakFaceInThree(facePos, endPos, startVertex); } //FACE-FACE-VERTEX else if (startType == Segment.FACE && endType == Segment.VERTEX) { BreakFaceInThree(facePos, startPos, endVertex); } //EDGE-FACE-EDGE else if (startType == Segment.EDGE && endType == Segment.EDGE) { BreakFaceInThree(facePos, startPos, endPos, startVertex, endVertex); } //EDGE-FACE-FACE else if (startType == Segment.EDGE && endType == Segment.FACE) { BreakFaceInFour(facePos, startPos, endPos, startVertex); } //FACE-FACE-EDGE else if (startType == Segment.FACE && endType == Segment.EDGE) { BreakFaceInFour(facePos, endPos, startPos, endVertex); } //FACE-FACE-FACE else if (startType == Segment.FACE && endType == Segment.FACE) { Vector3d segmentVector = new Vector3d(startPos.X - endPos.X, startPos.Y - endPos.Y, startPos.Z - endPos.Z); //if the intersection segment is a point only... if (Math.Abs(segmentVector.X) < EqualityTolerance && Math.Abs(segmentVector.Y) < EqualityTolerance && Math.Abs(segmentVector.Z) < EqualityTolerance) { BreakFaceInThree(facePos, startPos); return; } //gets the vertex more lined with the intersection segment int linedVertex; Vector3d linedVertexPos; Vector3d vertexVector = new Vector3d(endPos.X - face.V1._Position.X, endPos.Y - face.V1._Position.Y, endPos.Z - face.V1._Position.Z); vertexVector.Normalize(); double Dot1 = Math.Abs(Vector3d.Dot(segmentVector, vertexVector)); vertexVector = new Vector3d(endPos.X - face.V2._Position.X, endPos.Y - face.V2._Position.Y, endPos.Z - face.V2._Position.Z); vertexVector.Normalize(); double Dot2 = Math.Abs(Vector3d.Dot(segmentVector, vertexVector)); vertexVector = new Vector3d(endPos.X - face.V3._Position.X, endPos.Y - face.V3._Position.Y, endPos.Z - face.V3._Position.Z); vertexVector.Normalize(); double Dot3 = Math.Abs(Vector3d.Dot(segmentVector, vertexVector)); if (Dot1 > Dot2 && Dot1 > Dot3) { linedVertex = 1; linedVertexPos = face.V1.Position; } else if (Dot2 > Dot3 && Dot2 > Dot1) { linedVertex = 2; linedVertexPos = face.V2.Position; } else { linedVertex = 3; linedVertexPos = face.V3.Position; } // Now find which of the intersection endpoints is nearest to that vertex. if ((linedVertexPos - startPos).Length > (linedVertexPos - endPos).Length) { BreakFaceInFive(facePos, startPos, endPos, linedVertex); } else { BreakFaceInFive(facePos, endPos, startPos, linedVertex); } } }