Exemplo n.º 1
0
        /**
         * Split an individual face
         *
         * @param facePos face position on the array of faces
         * @param segment1 segment representing the intersection of the face with the plane
         * of another face
         * @return segment2 segment representing the intersection of other face with the
         * plane of the current face plane
         */
        private void splitFace(int facePos, Segment segment1, Segment segment2)
        {
            Vertex  startPosVertex, endPosVertex;
            Point3d startPos, endPos;
            int     startType, endType, middleType;
            double  startDist, endDist;

            Face   face        = getFace(facePos);
            Vertex startVertex = segment1.getStartVertex();
            Vertex endVertex   = segment1.getEndVertex();

            //starting point: deeper starting point
            if (segment2.getStartDistance() > segment1.getStartDistance() + TOL)
            {
                startDist = segment2.getStartDistance();
                startType = segment1.getIntermediateType();
                startPos  = segment2.getStartPosition();
            }
            else
            {
                startDist = segment1.getStartDistance();
                startType = segment1.getStartType();
                startPos  = segment1.getStartPosition();
            }

            //ending point: deepest ending point
            if (segment2.getEndDistance() < segment1.getEndDistance() - TOL)
            {
                endDist = segment2.getEndDistance();
                endType = segment1.getIntermediateType();
                endPos  = segment2.getEndPosition();
            }
            else
            {
                endDist = segment1.getEndDistance();
                endType = segment1.getEndType();
                endPos  = segment1.getEndPosition();
            }
            middleType = segment1.getIntermediateType();

            //set vertex to BOUNDARY if it is start type
            if (startType == Segment.VERTEX)
            {
                startVertex.setStatus(Vertex.BOUNDARY);
            }

            //set vertex to BOUNDARY if it is end type
            if (endType == Segment.VERTEX)
            {
                endVertex.setStatus(Vertex.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) < TOL && Math.Abs(segmentVector.Y) < TOL && Math.Abs(segmentVector.Z) < TOL)
                {
                    breakFaceInThree(facePos, startPos);
                    return;
                }

                //gets the vertex more lined with the intersection segment
                int      linedVertex;
                Point3d  linedVertexPos;
                Vector3d vertexVector = Vector3d.Normalize(new Vector3d(endPos.X - face.v1.X, endPos.Y - face.v1.Y, endPos.Z - face.v1.Z));

                double dot1 = Math.Abs(Vector3d.Dot(segmentVector, vertexVector));
                vertexVector = Vector3d.Normalize(new Vector3d(endPos.X - face.v2.X, endPos.Y - face.v2.Y, endPos.Z - face.v2.Z));

                double dot2 = Math.Abs(Vector3d.Dot(segmentVector, vertexVector));
                vertexVector = Vector3d.Normalize(new Vector3d(endPos.X - face.v3.X, endPos.Y - face.v3.Y, endPos.Z - face.v3.Z));

                double dot3 = Math.Abs(Vector3d.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.distance(startPos) > linedVertexPos.distance(endPos)) {
                if (Vector3d.DistanceSquared(linedVertexPos, startPos) > Vector3d.DistanceSquared(linedVertexPos, endPos))
                {
                    breakFaceInFive(facePos, startPos, endPos, linedVertex);
                }
                else
                {
                    breakFaceInFive(facePos, endPos, startPos, linedVertex);
                }
            }
        }