Esempio n. 1
0
        private void CreateNewFaces(ref List <int> foundFaces, ref List <int> horzionEdges, ref List <PointList> pointList, ref List <int> freeFaces, ref List <int> freePointLists, int vertex)
        {
            int edgeCount = horzionEdges.Count;
            int i;

            HalfEdge newEdge = new HalfEdge();
            Face     newFace = new Face();

            int tmpCount         = freeFaces.Count < horzionEdges.Count ? freeFaces.Count : horzionEdges.Count;
            int offset           = freeFaces.Count > horzionEdges.Count ? freeFaces.Count - horzionEdges.Count : 0;
            int doneHorizonEdges = 0;

            int iOffset;
            int opposite;
            int tmpHalfEdgeIdx;

            if (tmpCount > 3)
            {
                newEdge = newEdge;
            }
            for (i = 0; i < tmpCount; ++i)
            {
                iOffset        = i + offset;
                tmpHalfEdgeIdx = faces[freeFaces[iOffset]].halfEdge;

                newEdge.vertex        = edges[horzionEdges[i]].vertex;
                newEdge.opposite      = edges[horzionEdges[i]].opposite;
                newEdge.face          = freeFaces[iOffset];
                edges[tmpHalfEdgeIdx] = newEdge;

                opposite         = newEdge.opposite;
                newEdge          = edges[opposite];
                newEdge.opposite = tmpHalfEdgeIdx;
                edges[opposite]  = newEdge;

                newEdge.vertex            = vertex;
                newEdge.face              = freeFaces[iOffset];
                opposite                  = ((i == tmpCount - 1) ? (freeFaces.Count < horzionEdges.Count ? edges.Count : (faces[freeFaces[offset]].halfEdge)) : faces[freeFaces[iOffset + 1]].halfEdge) + 2;
                newEdge.opposite          = opposite;
                edges[tmpHalfEdgeIdx + 1] = newEdge;

                newEdge.vertex            = edges[faces[edges[horzionEdges[i]].face].halfEdge + (horzionEdges[i] + 2) % 3].vertex;
                newEdge.face              = freeFaces[iOffset];
                opposite                  = (i == 0 ? (freeFaces.Count < horzionEdges.Count ? (edges.Count + (horzionEdges.Count - freeFaces.Count - 1) * 3 + 1) : faces[freeFaces[offset + tmpCount - 1]].halfEdge + 1) : faces[freeFaces[iOffset - 1]].halfEdge + 1);
                newEdge.opposite          = opposite;
                edges[tmpHalfEdgeIdx + 2] = newEdge;

                newFace        = faces[freeFaces[iOffset]];
                newFace.normal = ((points[edges[faces[freeFaces[iOffset]].halfEdge + 2].vertex] - points[edges[faces[freeFaces[iOffset]].halfEdge].vertex]).Cross(points[edges[faces[freeFaces[iOffset]].halfEdge + 1].vertex] - points[edges[faces[freeFaces[iOffset]].halfEdge].vertex]));
                newFace.normal.Normalize();
                newFace.pointList         = -1;
                faces[freeFaces[iOffset]] = newFace;

                ++doneHorizonEdges;
            }

            int count;
            int oldEdgeCount = edges.Count;
            int totalCountEdges;

            for (i = doneHorizonEdges; i < edgeCount; ++i)
            {
                count            = horzionEdges[i];
                newEdge.vertex   = edges[count].vertex;
                newEdge.face     = faces.Count;
                newEdge.opposite = edges[count].opposite;
                edges.Add(newEdge);

                opposite         = newEdge.opposite;
                newEdge          = edges[opposite];
                newEdge.opposite = edges.Count - 1;
                edges[opposite]  = newEdge;

                newEdge.vertex   = vertex;
                newEdge.face     = faces.Count;
                newEdge.opposite = (i == (edgeCount - 1) ? (doneHorizonEdges != 0 ? faces[freeFaces[offset]].halfEdge + 2 : oldEdgeCount + 2) : (edges.Count + 4));
                edges.Add(newEdge);

                newEdge.vertex   = edges[faces[edges[count].face].halfEdge + ((count + 2) % 3)].vertex;
                newEdge.face     = faces.Count;
                newEdge.opposite = (i == doneHorizonEdges ? (doneHorizonEdges != 0 ? faces[freeFaces[tmpCount + offset - 1]].halfEdge + 1 : oldEdgeCount + (3 * edgeCount) - 2) : edges.Count - 4);
                edges.Add(newEdge);

                totalCountEdges  = edges.Count;
                newFace.halfEdge = totalCountEdges - 3;
                newFace.normal   = ((points[edges[totalCountEdges - 1].vertex] - points[edges[totalCountEdges - 3].vertex]).Cross(points[edges[totalCountEdges - 2].vertex] - points[edges[totalCountEdges - 3].vertex]));
                newFace.normal.Normalize();
                newFace.pointList = -1;
                faces.Add(newFace);
            }

            PointList  newPointList = new PointList();
            Vec3       normal;
            Vec3       vertexVec;
            int        numPointInList;
            List <int> pointListPoints;
            float      magnitude;

            for (i = 0; i < doneHorizonEdges; ++i)
            {
                iOffset                       = i + offset;
                normal                        = faces[freeFaces[iOffset]].normal;
                vertexVec                     = points[edges[faces[freeFaces[iOffset]].halfEdge].vertex];
                newPointList.Face             = freeFaces[iOffset];
                newPointList.points           = new List <int>();
                newPointList.idxDistance      = 0;
                newPointList.greatestDistance = -10;

                for (int j = 0; j < foundFaces.Count; ++j)
                {
                    if (faces[foundFaces[j]].pointList > -1)
                    {
                        pointListPoints = pointList[faces[foundFaces[j]].pointList].points;
                        numPointInList  = pointListPoints.Count;
                        for (int k = 0; k < numPointInList; ++k)
                        {
                            if (pointListPoints[k] != -1)
                            {
                                magnitude = normal.dot(points[pointListPoints[k]] - vertexVec);
                                if (magnitude > 0 + epsilon)
                                {
                                    newPointList.points.Add(pointListPoints[k]);
                                    if (magnitude > newPointList.greatestDistance)
                                    {
                                        newPointList.greatestDistance = magnitude;
                                        newPointList.idxDistance      = pointListPoints[k];
                                    }
                                    pointListPoints[k] = -1;
                                }
                            }
                        }
                    }
                }
                if (newPointList.points.Count > 0)
                {
                    newFace.halfEdge = faces[freeFaces[iOffset]].halfEdge;
                    newFace.normal   = faces[freeFaces[iOffset]].normal;
                    if (freePointLists.Count > 0)
                    {
                        newFace.pointList            = freePointLists[freePointLists.Count - 1];
                        pointList[newFace.pointList] = newPointList;
                        freePointLists.RemoveAt(freePointLists.Count - 1);
                    }
                    else
                    {
                        newFace.pointList = pointList.Count;
                        pointList.Add(newPointList);
                    }
                    faces[freeFaces[iOffset]] = newFace;
                }
            }

            freeFaces.RemoveRange(offset, doneHorizonEdges);
            int faceCount = faces.Count;

            for (i = edgeCount - doneHorizonEdges; i > 0; --i)
            {
                normal                        = faces[faceCount - i].normal;
                vertexVec                     = points[edges[faces[faceCount - i].halfEdge].vertex];
                newPointList.Face             = faces.Count - i;
                newPointList.points           = new List <int>();
                newPointList.idxDistance      = 0;
                newPointList.greatestDistance = -10;

                for (int j = 0; j < foundFaces.Count; ++j)
                {
                    if (faces[foundFaces[j]].pointList > -1)
                    {
                        pointListPoints = pointList[faces[foundFaces[j]].pointList].points;
                        numPointInList  = pointListPoints.Count;
                        for (int k = 0; k < numPointInList; ++k)
                        {
                            if (pointListPoints[k] != -1)
                            {
                                magnitude = normal.dot(points[pointListPoints[k]] - vertexVec);
                                if (magnitude > 0 + epsilon)
                                {
                                    newPointList.points.Add(pointListPoints[k]);
                                    if (magnitude > newPointList.greatestDistance)
                                    {
                                        newPointList.greatestDistance = magnitude;
                                        newPointList.idxDistance      = newPointList.points[newPointList.points.Count - 1];
                                    }
                                    pointListPoints[k] = -1;
                                }
                            }
                        }
                    }
                }
                if (newPointList.points.Count > 0)
                {
                    newFace.halfEdge = faces[faceCount - i].halfEdge;
                    newFace.normal   = faces[faceCount - i].normal;
                    if (freePointLists.Count > 0)
                    {
                        newFace.pointList            = freePointLists[freePointLists.Count - 1];
                        pointList[newFace.pointList] = newPointList;
                        freePointLists.RemoveAt(freePointLists.Count - 1);
                    }
                    else
                    {
                        newFace.pointList = pointList.Count;
                        pointList.Add(newPointList);
                    }
                    faces[faceCount - i] = newFace;
                }
            }

            for (i = 0; i < foundFaces.Count; ++i)
            {
                newFace = faces[foundFaces[i]];
                if (newFace.pointList >= 0)
                {
                    freePointLists.Add(newFace.pointList);
                }
                newFace.pointList = -2;
                freeFaces.Add(foundFaces[i]);
                faces[foundFaces[i]] = newFace;
            }
        }
Esempio n. 2
0
        private void CreateStart()
        {
            float lowestX = points[0].x, highestX = points[0].x;
            float lowestY = points[0].y, highestY = points[0].y;
            float lowestZ = points[0].z, highestZ = points[0].z;

            int[] lowest  = new int[3];
            int[] highest = new int[3];

            int  listSize = points.Count;
            Vec3 point;

            for (int i = 0; i < listSize; ++i)
            {
                point = points[i];
                if (point.x < lowestX)
                {
                    lowestX   = point.x;
                    lowest[0] = i;
                }
                if (point.x > highestX)
                {
                    highestX   = point.x;
                    highest[0] = i;
                }
                if (point.y < lowestY)
                {
                    lowestY   = point.y;
                    lowest[1] = i;
                }
                if (point.y > highestY)
                {
                    highestY   = point.y;
                    highest[1] = i;
                }
                if (point.z < lowestZ)
                {
                    lowestZ   = point.z;
                    lowest[2] = i;
                }
                if (point.z > highestZ)
                {
                    highestZ   = point.z;
                    highest[2] = i;
                }
            }

            int   greatestDistanceUp   = lowest[0];
            int   greatestDistanceDown = highest[0];
            Vec3  distanceVec          = points[greatestDistanceDown] - points[greatestDistanceUp];
            float maxDistance          = distanceVec.dot(distanceVec);
            float tmpDistance          = 0;

            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    distanceVec = points[lowest[i]] - points[highest[j]];
                    tmpDistance = distanceVec.dot(distanceVec);
                    if (tmpDistance > maxDistance)
                    {
                        greatestDistanceUp   = lowest[i];
                        greatestDistanceDown = highest[j];
                        maxDistance          = tmpDistance;
                    }
                }
            }

            distanceVec = points[greatestDistanceDown] - points[greatestDistanceUp];
            int   distanceIdx = 0;
            Vec3  tmpVec;
            float newMaxDistance = 0;

            for (int i = 0; i < 3; ++i)
            {
                tmpVec      = distanceVec.Cross(points[greatestDistanceUp] - points[lowest[i]]);
                tmpDistance = (tmpVec).dot(tmpVec) / maxDistance;
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx    = lowest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            for (int i = 0; i < 3; ++i)
            {
                tmpVec      = distanceVec.Cross(points[greatestDistanceUp] - points[highest[i]]);
                tmpDistance = (tmpVec).dot(tmpVec) / maxDistance;
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx    = highest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            Vec3 normal = (distanceVec.Cross(points[greatestDistanceDown] - points[distanceIdx]));

            normal.Normalize();

            newMaxDistance = 0;
            int distanceIdx2 = 0;

            for (int i = 0; i < 3; ++i)
            {
                tmpDistance = Math.Abs(normal.dot(points[distanceIdx] - points[lowest[i]]));
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx2   = lowest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            for (int i = 0; i < 3; ++i)
            {
                tmpDistance = Math.Abs(normal.dot(points[distanceIdx] - points[highest[i]]));
                if (tmpDistance > newMaxDistance)
                {
                    distanceIdx2   = highest[i];
                    newMaxDistance = tmpDistance;
                }
            }

            if (normal.dot(points[distanceIdx2] - points[distanceIdx]) > 0)
            {
                //Face 0
                HalfEdge newHalfEdge = new HalfEdge();
                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 3;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 6;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 9;
                edges.Add(newHalfEdge);

                //Face 1
                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 0;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 11;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 7;
                edges.Add(newHalfEdge);

                //Face2
                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 1;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 5;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 10;
                edges.Add(newHalfEdge);

                //Face3
                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 2;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 8;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 4;
                edges.Add(newHalfEdge);
            }

            else
            {
                //Face 0
                HalfEdge newHalfEdge = new HalfEdge();
                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 11;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 8;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 0;
                newHalfEdge.opposite = 5;
                edges.Add(newHalfEdge);

                //Face 1
                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 7;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 9;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 1;
                newHalfEdge.opposite = 2;
                edges.Add(newHalfEdge);

                //Face2
                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 10;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceUp;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 3;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 2;
                newHalfEdge.opposite = 1;
                edges.Add(newHalfEdge);

                //Face3
                newHalfEdge.vertex   = distanceIdx2;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 4;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = distanceIdx;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 6;
                edges.Add(newHalfEdge);

                newHalfEdge.vertex   = greatestDistanceDown;
                newHalfEdge.face     = 3;
                newHalfEdge.opposite = 0;
                edges.Add(newHalfEdge);
            }

            Face newFace = new Face();

            for (int i = 0; i < 4; ++i)
            {
                newFace.halfEdge = i * 3;
                newFace.normal   = ((points[edges[i * 3 + 2].vertex] - points[edges[i * 3].vertex]).Cross(points[edges[i * 3 + 1].vertex] - points[edges[i * 3].vertex]));
                newFace.normal.Normalize();
                newFace.pointList = -1;
                faces.Add(newFace);
            }
        }