Example #1
0
        internal void ReplaceFace(Face face)
        {
            var key = face.Handle;

            DictFaces[key] = face;
        }
Example #2
0
        /// <summary>
        /// Creates and returns a Pyramid as a DCEL with the specified dimensions centered in the worlds coordinate system.
        /// </summary>
        /// <param name="dimensionX">Width of the Pyramid in X-dimension</param>
        /// <param name="dimensionY">Height of the Pyramid in Y-dimension.</param>
        /// <param name="dimensionZ">Depth of the Pyramid in Z-dimension.</param>
        /// <returns></returns>
        public static Geometry CreatePyramidGeometry(float dimensionX, float dimensionY, float dimensionZ)
        {
            //check input
            if (dimensionX <= 0 || dimensionY <= 0 || dimensionZ <= 0)
            {
                throw new ArgumentException("The dimension values can not be <= 0");
            }

            var xPos = dimensionX / 2.0f;
            var yPos = dimensionY / 2.0f;
            var zPos = dimensionZ / 2.0f;

            var pyramid   = new Geometry();
            var positions = new float3[5];

            //stores all Vertices positions
            positions[0] = new float3(-xPos, -yPos, -zPos);
            positions[1] = new float3(xPos, -yPos, -zPos);
            positions[2] = new float3(xPos, -yPos, zPos);
            positions[3] = new float3(-xPos, -yPos, zPos);
            positions[4] = new float3(0, yPos, 0);

            var baseFace = new Face(6)
            {
                OuterHalfEdge = 4
            };

            //create nad add vertices
            for (var i = 0; i < 5; i++)
            {
                Vertex current = new Vertex(pyramid.CreateVertHandleId(), positions[i]);
                if (i < 4)
                {
                    current.IncidentHalfEdge = i * 4 + 1;
                }
                if (i == 4)
                {
                    current.IncidentHalfEdge = 3;
                }
                pyramid.DictVertices.Add(current.Handle, current);
            }

            //create add Edges and Faces
            for (var i = 0; i < 4; i++)
            {
                var h1 = new HalfEdge(i * 4 + 1);
                var h2 = new HalfEdge(i * 4 + 2);
                var h3 = new HalfEdge(i * 4 + 3);
                var h4 = new HalfEdge(i * 4 + 4);

                var sideFace = new Face(i + 2)
                {
                    OuterHalfEdge = h1.Handle
                };

                h1.IncidentFace = sideFace.Handle;
                h2.IncidentFace = sideFace.Handle;
                h3.IncidentFace = sideFace.Handle;
                h4.IncidentFace = baseFace.Handle;
                h1.NextHalfEdge = h2.Handle;
                h2.NextHalfEdge = h3.Handle;
                h3.NextHalfEdge = h1.Handle;
                h1.PrevHalfEdge = h3.Handle;
                h2.PrevHalfEdge = h1.Handle;
                h3.PrevHalfEdge = h2.Handle;
                h3.OriginVertex = pyramid.DictVertices[5].Handle;

                h1.TwinHalfEdge = h4.Handle;
                h4.TwinHalfEdge = h1.Handle;

                if (i < 3)
                {
                    h4.PrevHalfEdge = (i + 1) * 4 + 4;
                    h2.TwinHalfEdge = (i + 1) * 4 + 3;

                    h1.OriginVertex = pyramid.DictVertices[i + 1].Handle;
                    h2.OriginVertex = pyramid.DictVertices[i + 2].Handle;
                    h4.OriginVertex = pyramid.DictVertices[i + 2].Handle;
                }
                else
                {
                    h4.PrevHalfEdge = 4;
                    h2.TwinHalfEdge = 3;

                    h1.OriginVertex = pyramid.DictVertices[i + 1].Handle;
                    h2.OriginVertex = pyramid.DictVertices[1].Handle;
                    h4.OriginVertex = pyramid.DictVertices[1].Handle;
                }
                if (i > 0)
                {
                    h3.TwinHalfEdge = (i - 1) * 4 + 2;
                    h4.NextHalfEdge = (i - 1) * 4 + 4;
                }
                else
                {
                    h3.TwinHalfEdge = 3 * 4 + 2;
                    h4.NextHalfEdge = 3 * 4 + 4;
                }
                //add
                pyramid.DictHalfEdges.Add(h1.Handle, h1);
                pyramid.DictHalfEdges.Add(h2.Handle, h2);
                pyramid.DictHalfEdges.Add(h3.Handle, h3);
                pyramid.DictHalfEdges.Add(h4.Handle, h4);

                pyramid.DictFaces.Add(sideFace.Handle, sideFace);
            }
            pyramid.DictFaces.Add(baseFace.Handle, baseFace);
            pyramid.SetHighestHandles();

            var allFaces = pyramid.GetAllFaces().ToList();

            foreach (var face in allFaces)
            {
                var faceVertices = pyramid.GetFaceVertices(face.Handle).ToList();
                pyramid.SetFaceNormal(faceVertices, face);
            }

            return(pyramid);
        }
Example #3
0
        /// <summary>
        /// Creates and returns a UV-Sphere as a DCEL with the specified dimensions centered in the worlds coordinate system.
        /// </summary>
        /// <param name="radius">Radius of the sphere.</param>
        /// <param name="horizontalResolution">Lines of latitude, smallest value is 3.</param>
        /// <param name="verticalResolution">Lines of longitude, smallest value is 3.</param>
        /// <returns>A UV-Sphere centered in the world coordinate system as a DCEL.</returns>
        public static Geometry CreateSpehreGeometry(float radius, int horizontalResolution, int verticalResolution)
        {
            //check input
            if (radius <= 0)
            {
                throw new ArgumentException("Radius can not be <= 0");
            }
            if (horizontalResolution <= 3)
            {
                horizontalResolution = 3;
            }
            if (verticalResolution <= 2)
            {
                verticalResolution = 2;
            }

            var sphere    = new Geometry();
            var northPole = new Vertex(sphere.CreateVertHandleId(), new float3(0, radius, 0));
            var southPole = new Vertex(sphere.CreateVertHandleId(), new float3(0, -radius, 0));

            var horizontalAngleStep = System.Math.PI * 2 / horizontalResolution; // s
            var verrticalAngleStep  = System.Math.PI / verticalResolution;       // t

            var currentLatitudeVerticesHandles = new int[horizontalResolution];
            var lastLaitudeVerticesHandles     = new int[horizontalResolution]; //stores last vertices to connect them later with the next latidute vertices

            for (var i = 1; i < verticalResolution + 1; i++)
            {
                //create all vertices
                if (i < verticalResolution)
                {
                    for (var j = 0; j < horizontalResolution; j++)
                    {
                        //create all Vertices of current latitude
                        var xPos = (float)(radius * System.Math.Sin(horizontalAngleStep * j) * System.Math.Sin(verrticalAngleStep * i));
                        var yPos = (float)(radius * System.Math.Cos(verrticalAngleStep * (i)));
                        var zPos = (float)(radius * System.Math.Cos(horizontalAngleStep * j) * System.Math.Sin(verrticalAngleStep * i));

                        var circleVertex = new Vertex(sphere.CreateVertHandleId(), new float3(xPos, yPos, zPos));
                        sphere.DictVertices.Add(circleVertex.Handle, circleVertex);
                        currentLatitudeVerticesHandles[j] = circleVertex.Handle;
                    }
                }

                //create faces
                var topHeHandles = new int[horizontalResolution];
                for (var j = 0; j < horizontalResolution; j++)
                {
                    // bottom triangles of sphere
                    if (i == verticalResolution)
                    {
                        var bottomTriangle = new Face(sphere.CreateFaceHandleId());

                        var h1 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h2 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h3 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        topHeHandles[j] = h1.Handle;

                        h1.NextHalfEdge = h2.Handle;
                        h2.NextHalfEdge = h3.Handle;
                        h3.NextHalfEdge = h1.Handle;
                        h1.PrevHalfEdge = h3.Handle;
                        h2.PrevHalfEdge = h1.Handle;
                        h3.PrevHalfEdge = h2.Handle;
                        h1.IncidentFace = bottomTriangle.Handle;
                        h2.IncidentFace = bottomTriangle.Handle;
                        h3.IncidentFace = bottomTriangle.Handle;
                        h1.OriginVertex = currentLatitudeVerticesHandles[j];
                        h2.OriginVertex = j == horizontalResolution - 1 ? currentLatitudeVerticesHandles[0] : currentLatitudeVerticesHandles[j + 1];
                        h3.OriginVertex = southPole.Handle;
                        bottomTriangle.OuterHalfEdge = h1.Handle;

                        southPole.IncidentHalfEdge = h3.Handle;

                        //write changes
                        sphere.DictHalfEdges.Add(h1.Handle, h1);
                        sphere.DictHalfEdges.Add(h2.Handle, h2);
                        sphere.DictHalfEdges.Add(h3.Handle, h3);
                        sphere.DictFaces.Add(bottomTriangle.Handle, bottomTriangle);
                    }

                    // top triangles of sphere
                    else if (i == 1)
                    {
                        var topTriangle = new Face(sphere.CreateFaceHandleId());

                        var h1 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h2 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h3 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        topHeHandles[j] = h1.Handle;

                        h1.NextHalfEdge           = h2.Handle;
                        h2.NextHalfEdge           = h3.Handle;
                        h3.NextHalfEdge           = h1.Handle;
                        h1.PrevHalfEdge           = h3.Handle;
                        h2.PrevHalfEdge           = h1.Handle;
                        h3.PrevHalfEdge           = h2.Handle;
                        h1.IncidentFace           = topTriangle.Handle;
                        h2.IncidentFace           = topTriangle.Handle;
                        h3.IncidentFace           = topTriangle.Handle;
                        h1.OriginVertex           = j == horizontalResolution - 1 ? currentLatitudeVerticesHandles[0] : currentLatitudeVerticesHandles[j + 1];
                        h2.OriginVertex           = currentLatitudeVerticesHandles[j];
                        h3.OriginVertex           = northPole.Handle;
                        topTriangle.OuterHalfEdge = h1.Handle;

                        var currentVertex = sphere.GetVertexByHandle(currentLatitudeVerticesHandles[j]);
                        currentVertex.IncidentHalfEdge = h2.Handle;
                        northPole.IncidentHalfEdge     = h3.Handle;

                        //write changes
                        sphere.DictHalfEdges.Add(h1.Handle, h1);
                        sphere.DictHalfEdges.Add(h2.Handle, h2);
                        sphere.DictHalfEdges.Add(h3.Handle, h3);
                        sphere.DictFaces.Add(topTriangle.Handle, topTriangle);
                        sphere.ReplaceVertex(currentVertex);
                    }
                    // middle quads of sphere
                    else
                    {
                        var quad = new Face(sphere.CreateFaceHandleId());

                        var h1 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h2 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h3 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        var h4 = new HalfEdge(sphere.CreateHalfEdgeHandleId());
                        topHeHandles[j] = h1.Handle;

                        h1.NextHalfEdge    = h2.Handle;
                        h2.NextHalfEdge    = h3.Handle;
                        h3.NextHalfEdge    = h4.Handle;
                        h4.NextHalfEdge    = h1.Handle;
                        h1.PrevHalfEdge    = h4.Handle;
                        h2.PrevHalfEdge    = h1.Handle;
                        h3.PrevHalfEdge    = h2.Handle;
                        h4.PrevHalfEdge    = h3.Handle;
                        h1.IncidentFace    = quad.Handle;
                        h2.IncidentFace    = quad.Handle;
                        h3.IncidentFace    = quad.Handle;
                        h4.IncidentFace    = quad.Handle;
                        quad.OuterHalfEdge = h1.Handle;

                        h4.OriginVertex = currentLatitudeVerticesHandles[j];
                        h3.OriginVertex = j == horizontalResolution - 1 ? currentLatitudeVerticesHandles[0] : currentLatitudeVerticesHandles[j + 1];
                        h2.OriginVertex = j == horizontalResolution - 1 ? lastLaitudeVerticesHandles[0] : lastLaitudeVerticesHandles[j + 1];
                        h1.OriginVertex = lastLaitudeVerticesHandles[j];

                        var currentVertex = sphere.GetVertexByHandle(currentLatitudeVerticesHandles[j]);
                        currentVertex.IncidentHalfEdge = h4.Handle;

                        //write changes
                        sphere.DictFaces.Add(quad.Handle, quad);
                        sphere.DictHalfEdges.Add(h1.Handle, h1);
                        sphere.DictHalfEdges.Add(h2.Handle, h2);
                        sphere.DictHalfEdges.Add(h3.Handle, h3);
                        sphere.DictHalfEdges.Add(h4.Handle, h4);
                        sphere.ReplaceVertex(currentVertex);
                    }
                }

                //set twins
                for (int j = 0; j < horizontalResolution; j++)
                {
                    //set twins of adjacent triangles bottom
                    if (i == 1)
                    {
                        int nextH1Index;
                        nextH1Index = j == 0 ? horizontalResolution - 1 : j - 1;
                        var h1     = sphere.GetHalfEdgeByHandle(topHeHandles[j]);
                        var h2     = sphere.GetHalfEdgeByHandle(h1.NextHalfEdge);
                        var nextH1 = sphere.GetHalfEdgeByHandle(topHeHandles[nextH1Index]);
                        var nextH3 = sphere.GetHalfEdgeByHandle(nextH1.PrevHalfEdge);
                        nextH3.TwinHalfEdge = h2.Handle;
                        h2.TwinHalfEdge     = nextH3.Handle;

                        sphere.ReplaceHalfEdge(nextH3);
                        sphere.ReplaceHalfEdge(h2);
                    }
                    else if (i == verticalResolution)
                    {
                        int nextH1Index;
                        nextH1Index = j == 0 ? horizontalResolution - 1 : j - 1;
                        var h1     = sphere.GetHalfEdgeByHandle(topHeHandles[j]);
                        var h3     = sphere.GetHalfEdgeByHandle(h1.PrevHalfEdge);
                        var nextH1 = sphere.GetHalfEdgeByHandle(topHeHandles[nextH1Index]);
                        var nextH2 = sphere.GetHalfEdgeByHandle(nextH1.NextHalfEdge);
                        nextH2.TwinHalfEdge = h3.Handle;
                        h3.TwinHalfEdge     = nextH2.Handle;

                        sphere.ReplaceHalfEdge(nextH2);
                        sphere.ReplaceHalfEdge(h3);
                    }
                    else //set twins of adjacent quads
                    {
                        var h1 = sphere.GetHalfEdgeByHandle(topHeHandles[j]);
                        var h4 = sphere.GetHalfEdgeByHandle(h1.PrevHalfEdge);

                        int nextH1Index;

                        nextH1Index = j == 0 ? horizontalResolution - 1 : j - 1;

                        var nextH1 = sphere.GetHalfEdgeByHandle(topHeHandles[nextH1Index]);
                        var nextH2 = sphere.GetHalfEdgeByHandle(nextH1.NextHalfEdge);

                        nextH2.TwinHalfEdge = h4.Handle;
                        h4.TwinHalfEdge     = nextH2.Handle;

                        sphere.ReplaceHalfEdge(nextH2);
                        sphere.ReplaceHalfEdge(h4);
                    }

                    //set twin of face on top
                    if (i > 1)
                    {
                        var h1         = sphere.GetHalfEdgeByHandle(topHeHandles[j]);
                        var lastVertex = sphere.GetVertexByHandle(lastLaitudeVerticesHandles[j]);
                        var topH1      = sphere.GetHalfEdgeByHandle(lastVertex.IncidentHalfEdge);
                        while (true)
                        {
                            if (topH1.TwinHalfEdge == 0)
                            {
                                break;
                            }
                            topH1 = sphere.GetHalfEdgeByHandle(topH1.NextHalfEdge);
                        }
                        topH1.TwinHalfEdge = h1.Handle;
                        h1.TwinHalfEdge    = topH1.Handle;
                        sphere.ReplaceHalfEdge(h1);
                        sphere.ReplaceHalfEdge(topH1);
                    }
                }

                Array.Copy(currentLatitudeVerticesHandles, lastLaitudeVerticesHandles,
                           currentLatitudeVerticesHandles.Length);
            }
            sphere.DictVertices.Add(northPole.Handle, northPole);
            sphere.DictVertices.Add(southPole.Handle, southPole);

            //calculate normals
            var allFaces = sphere.GetAllFaces().ToList();

            foreach (var face in allFaces)
            {
                sphere.SetFaceNormal(sphere.GetFaceVertices(face.Handle).ToList(), face);
            }

            return(sphere);
        }
Example #4
0
        /// <summary>
        /// Creates and returns a cone with the given dimensions.
        /// </summary>
        /// <param name="baseRadius">The radiaus of the base circle.</param>
        /// <param name="dimensionY">The height of the cone.</param>
        /// <param name="sliceCount">The horizontal resulotion of the base circle. Min value is 3. For a basic cone 15.</param>
        /// <returns></returns>
        public static Geometry CreateConeGeometry(float baseRadius, float dimensionY, int sliceCount)
        {
            //check input
            if (sliceCount < 3)
            {
                sliceCount = 3;
            }
            if (baseRadius <= 0 || dimensionY <= 0)
            {
                throw new ArgumentException("You can not input paramaters <= 0");
            }

            var cone      = new Geometry();
            var northPole = new Vertex(cone.CreateVertHandleId(), new float3(0, dimensionY / 2, 0));
            var southPole = new Vertex(cone.CreateVertHandleId(), new float3(0, -dimensionY / 2, 0));

            var angleStep = System.Math.PI * 2 / sliceCount;
            var yPos      = -dimensionY / 2.0f;

            int[] firstHandles = null; //stores the handles of the first slice to connect it later with the last slice

            var lastH3     = new HalfEdge();
            var lastH2     = new HalfEdge();
            var lastVertex = southPole;

            for (var i = 1; i < sliceCount + 1; i++)
            {
                var x = (float)System.Math.Cos(angleStep * i) * baseRadius;
                var z = (float)System.Math.Sin(angleStep * i) * baseRadius;

                var tempVertex = new Vertex(cone.CreateVertHandleId(), new float3(x, yPos, z));

                //south to temp
                var h1 = new HalfEdge(cone.CreateHalfEdgeHandleId());
                var h2 = new HalfEdge(cone.CreateHalfEdgeHandleId()); //twin of h1

                tempVertex.IncidentHalfEdge = h2.Handle;
                h1.OriginVertex             = southPole.Handle;
                h2.OriginVertex             = tempVertex.Handle;
                h1.TwinHalfEdge             = h2.Handle;
                h2.TwinHalfEdge             = h1.Handle;

                //temp to north
                var h3 = new HalfEdge(cone.CreateHalfEdgeHandleId());
                var h4 = new HalfEdge(cone.CreateHalfEdgeHandleId());

                northPole.IncidentHalfEdge = h3.Handle;
                southPole.IncidentHalfEdge = h1.Handle;

                h3.OriginVertex = northPole.Handle;
                h4.OriginVertex = tempVertex.Handle;
                h3.TwinHalfEdge = h4.Handle;
                h4.TwinHalfEdge = h3.Handle;

                if (lastVertex == southPole)
                {
                    firstHandles = new[] { tempVertex.Handle, h1.Handle, h4.Handle };
                    lastH3       = h3;
                    lastH2       = h2;
                    cone.DictVertices.Add(tempVertex.Handle, tempVertex);
                    cone.DictHalfEdges.Add(h1.Handle, h1);
                    cone.DictHalfEdges.Add(h2.Handle, h2);
                    cone.DictHalfEdges.Add(h3.Handle, h3);
                    cone.DictHalfEdges.Add(h4.Handle, h4);
                    lastVertex = tempVertex;
                    continue;
                }

                //temp to last
                var h5 = new HalfEdge(cone.CreateHalfEdgeHandleId());
                var h6 = new HalfEdge(cone.CreateHalfEdgeHandleId());

                h5.OriginVertex = lastVertex.Handle;
                h6.OriginVertex = tempVertex.Handle;
                h5.TwinHalfEdge = h6.Handle;
                h6.TwinHalfEdge = h5.Handle;

                //create top triangles south-temp-last
                var triangle1 = new Face(cone.CreateFaceHandleId());
                h5.NextHalfEdge         = h4.Handle;
                triangle1.OuterHalfEdge = h5.Handle;
                h4.NextHalfEdge         = lastH3.Handle;
                lastH3.NextHalfEdge     = h5.Handle;
                h5.IncidentFace         = triangle1.Handle;
                h4.IncidentFace         = triangle1.Handle;
                lastH3.IncidentFace     = triangle1.Handle;
                h5.PrevHalfEdge         = lastH3.Handle;
                lastH3.PrevHalfEdge     = h4.Handle;
                h4.PrevHalfEdge         = h5.Handle;

                //north-last-temp
                var triangle2 = new Face(cone.CreateFaceHandleId());
                h6.NextHalfEdge         = lastH2.Handle;
                triangle2.OuterHalfEdge = h6.Handle;
                lastH2.NextHalfEdge     = h1.Handle;
                h1.NextHalfEdge         = h6.Handle;
                h6.IncidentFace         = triangle2.Handle;
                lastH2.IncidentFace     = triangle2.Handle;
                h1.IncidentFace         = triangle2.Handle;
                h6.PrevHalfEdge         = h1.Handle;
                h1.PrevHalfEdge         = lastH2.Handle;
                lastH2.PrevHalfEdge     = h6.Handle;

                //write
                cone.DictVertices.Add(tempVertex.Handle, tempVertex);
                cone.DictHalfEdges.Add(h1.Handle, h1);
                cone.DictHalfEdges.Add(h2.Handle, h2);
                cone.DictHalfEdges.Add(h3.Handle, h3);
                cone.DictHalfEdges.Add(h4.Handle, h4);
                cone.DictHalfEdges.Add(h5.Handle, h5);
                cone.DictHalfEdges.Add(h6.Handle, h6);
                cone.ReplaceHalfEdge(lastH2);
                cone.ReplaceHalfEdge(lastH3);
                cone.DictFaces.Add(triangle1.Handle, triangle1);
                cone.DictFaces.Add(triangle2.Handle, triangle2);


                lastH2     = h2;
                lastH3     = h3;
                lastVertex = tempVertex;
            }
            //add south and northpole
            cone.DictVertices.Add(southPole.Handle, southPole);
            cone.DictVertices.Add(northPole.Handle, northPole);

            //create last 2 traingles
            var firstVertex = cone.GetVertexByHandle(firstHandles[0]);
            var firtstH1    = cone.GetHalfEdgeByHandle(firstHandles[1]);
            var firstH4     = cone.GetHalfEdgeByHandle(firstHandles[2]);

            var lastH5 = new HalfEdge(cone.CreateHalfEdgeHandleId());
            var lastH6 = new HalfEdge(cone.CreateHalfEdgeHandleId());

            lastH5.OriginVertex = lastVertex.Handle;
            lastH6.OriginVertex = firstVertex.Handle;
            lastH5.TwinHalfEdge = lastH6.Handle;
            lastH6.TwinHalfEdge = lastH5.Handle;

            //create to triangles south-temp-last, north-last-temp
            var triangleL1 = new Face(cone.CreateFaceHandleId())
            {
                OuterHalfEdge = lastH5.Handle
            };

            lastH5.NextHalfEdge  = firstH4.Handle;
            firstH4.NextHalfEdge = lastH3.Handle;
            lastH3.NextHalfEdge  = lastH5.Handle;
            lastH5.IncidentFace  = triangleL1.Handle;
            firstH4.IncidentFace = triangleL1.Handle;
            lastH3.IncidentFace  = triangleL1.Handle;
            lastH5.PrevHalfEdge  = lastH3.Handle;
            lastH3.PrevHalfEdge  = firstH4.Handle;
            firstH4.PrevHalfEdge = lastH5.Handle;

            var triangleL2 = new Face(cone.CreateFaceHandleId())
            {
                OuterHalfEdge = lastH6.Handle
            };

            lastH6.NextHalfEdge   = lastH2.Handle;
            lastH2.NextHalfEdge   = firtstH1.Handle;
            firtstH1.NextHalfEdge = lastH6.Handle;
            lastH6.IncidentFace   = triangleL2.Handle;
            lastH2.IncidentFace   = triangleL2.Handle;
            firtstH1.IncidentFace = triangleL2.Handle;
            lastH6.PrevHalfEdge   = firtstH1.Handle;
            firtstH1.PrevHalfEdge = lastH2.Handle;
            lastH2.PrevHalfEdge   = lastH6.Handle;

            //write
            cone.ReplaceHalfEdge(firtstH1);
            cone.DictHalfEdges.Add(lastH5.Handle, lastH5);
            cone.DictHalfEdges.Add(lastH6.Handle, lastH6);
            cone.ReplaceHalfEdge(lastH2);
            cone.ReplaceHalfEdge(lastH3);
            cone.ReplaceHalfEdge(firstH4);
            cone.DictFaces.Add(triangleL1.Handle, triangleL1);
            cone.DictFaces.Add(triangleL2.Handle, triangleL2);

            //face normals
            var allFaces = cone.GetAllFaces().ToList();

            foreach (var face in allFaces)
            {
                cone.SetFaceNormal(cone.GetFaceVertices(face.Handle).ToList(), face);
            }

            return(cone);
        }