コード例 #1
0
    public Mesh CreateMeshFromPoints(bool combine)
    {
        if (spriteRenderer != null && points.Length > 2)
        {
            int pointNum = points.Length;
            if (combine && combineMesh != null)
            {
                pointNum = points.Length + combineMesh.vertices.Length;
            }

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(pointNum);


            geometry.AddPolygon(points);


            if (combine && combineMesh != null)
            {
                geometry.AddPolygon(combineMesh.vertices.Select(x => (Vector2)x).ToArray());
            }

            //Triangulate
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            triangleMesh.Triangulate(geometry);

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector2[] uvs      = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] normals  = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach (TriangleNet.Data.Vertex v in triangleMesh.Vertices)
            {
                points[n]   = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n]  = new Vector3(0, 0, -1);

                n++;
            }

            //transform triangles
            int[] triangles = triangleMesh.Triangles.ToUnityMeshTriangleIndices();

            mesh.Clear();
            mesh           = new Mesh();
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.uv        = genUV(mesh.vertices);
            mesh.normals   = normals;

            return(mesh);
        }
        else
        {
            return(null);
        }
    }
コード例 #2
0
    // Use this for initialization
    void Start()
    {
        TriMesh = new TriangleNet.Mesh();
        /*_mesh.Triangulate("Assets/Plugins/Data/superior.poly");*/

        var geometry = FileReader.ReadPolyFile("Assets/Plugins/Data/superior.poly");

        TriMesh.behavior.Quality  = true;
        TriMesh.behavior.MinAngle = 33.8f;
        TriMesh.Triangulate(geometry);
        //TriMesh.Refine(true);
        // Get mesh statistics.
        var statistic = new Statistic();

        statistic.Update(TriMesh, 1);

        // Refine by setting a custom maximum area constraint.
        TriMesh.Refine(statistic.LargestArea / 4);
        TriMesh.Smooth();

        Debug.Log(string.Format("width {0:0.00}, height {1:0.00}; min {2:0.00}, {3:0.00}; max {4:0.00}, {5:0.00}",
                                TriMesh.Bounds.Width, TriMesh.Bounds.Height,
                                TriMesh.Bounds.Xmin, TriMesh.Bounds.Ymin,
                                TriMesh.Bounds.Xmax, TriMesh.Bounds.Ymax));

        OnRender(TriMesh);
    }
コード例 #3
0
    // Use this for initialization
    void Start()
    {
        TriMesh = new TriangleNet.Mesh();
        /*_mesh.Triangulate("Assets/Plugins/Data/superior.poly");*/

        var geometry = FileReader.ReadPolyFile("Assets/Plugins/Data/superior.poly");

        TriMesh.behavior.Quality  = true;
        TriMesh.behavior.MinAngle = 30;
        TriMesh.Triangulate(geometry);

        Debug.Log("Size : " + TriMesh.Vertices.Count);

        int i = 0;

        foreach (var pt in TriMesh.Vertices)
        {
            Debug.Log(i++ + " : " + pt.X + "," + pt.Y);
        }

        foreach (var tri in TriMesh.Triangles)
        {
            /*Debug.Log(tri.)*/
        }

        FileWriter.Write(TriMesh, "Assets/Plugins/Data/superior_mesh.ele");
    }
コード例 #4
0
        /// <summary>
        /// Add a polygon ring to the geometry and make it a hole.
        /// </summary>
        /// <remarks>
        /// WARNING: This works for convex polygons, but not for non-convex regions in general.
        /// </remarks>
        /// <param name="points">List of points which make up the hole.</param>
        /// <param name="mark">Common boundary mark for all segments of the hole.</param>
        public static void AddRingAsHole(this InputGeometry geometry, IEnumerable<TriangleNet.Geometry.Point> points, int mark = 0)
        {
            // Save the current number of points.
            int N = geometry.Count;
            int m = 0;

            foreach (var pt in points)
            {
                geometry.AddPoint(pt.X, pt.Y, pt.Boundary, pt.Attributes);
                m++;
            }

            for (int i = 0; i < m; i++)
            {
                geometry.AddSegment(N + i, N + ((i + 1) % m), mark);
            }

            //a lényeg az hogy kell egy a lyukon lévő pont,hogy jelezze hogy az egy lyuk poligon... a legegyszerübb trükk a következő, az egybefüggő (akár konkáv) poligont háromszögesítem, ezzel nincs gond, ezután kiválasztok egy testzőleges háromszöget, és veszem annak a középpontját..ez már tuti hogy a nagy poligon belső pontja
            TriangleNetMesh mesh = new TriangleNetMesh();
            var inputGeometry = new InputGeometry();
            inputGeometry.AddRing(points);
            mesh.Triangulate(inputGeometry);
            var firstTriangle = new List<Triangle>(mesh.Triangles)[0];

            double x = 0.0;
            double y = 0.0;
            for (int iii = 0; iii < 3; iii++)
            {
                var vertex = firstTriangle.GetVertex(iii);
                x += vertex.X;
                y += vertex.Y;
            }

            geometry.AddHole(x / 3, y / 3);
        }
コード例 #5
0
        public static UnityEngine.Mesh Mesh(this Polygon this_, string name = "")
        {
            // Create geometry.
            InputGeometry geometry = this_.InputGeometry();

            // Triangulate.
            TriangleNet.Mesh triangulatedMesh = new TriangleNet.Mesh();
            triangulatedMesh.Triangulate(geometry);

            // Counts.
            int vertexCount   = triangulatedMesh.vertices.Count;
            int triangleCount = triangulatedMesh.triangles.Count;

            // Debug.Log("Mesh.vertexCount ("+vertexCount+")"); // NumberOfInputPoints
            // Debug.Log("Mesh.triangleCount ("+triangleCount+")"); // NumberOfInputPoints

            // Mesh store.
            Vector3[] _vertices  = new Vector3[vertexCount];
            Vector2[] _uv        = new Vector2[vertexCount];
            Vector3[] _normals   = new Vector3[vertexCount];
            int[]     _triangles = new int[triangleCount * 3];

            foreach (KeyValuePair <int, TriangleNet.Data.Vertex> eachEntry in triangulatedMesh.vertices)
            {
                int index = eachEntry.Key;
                TriangleNet.Data.Vertex eachVertex = eachEntry.Value;

                _vertices[index] = new Vector3(
                    (float)eachVertex.x,
                    (float)eachVertex.y,
                    0.0f                     // As of 2D
                    );

                _uv[index]      = _vertices[index];
                _normals[index] = Vector3.forward;
            }

            int cursor = 0;

            foreach (KeyValuePair <int, TriangleNet.Data.Triangle> eachPair in triangulatedMesh.triangles)
            {
                TriangleNet.Data.Triangle eachTriangle = eachPair.Value;
                _triangles[cursor]     = eachTriangle.P2;
                _triangles[cursor + 1] = eachTriangle.P1;
                _triangles[cursor + 2] = eachTriangle.P0;
                cursor += 3;
            }

            // Create / setup mesh.
            Mesh mesh = new Mesh();

            mesh.vertices     = _vertices;
            mesh.uv           = _uv;
            mesh.normals      = _normals;
            mesh.subMeshCount = 1;
            mesh.SetTriangles(_triangles, 0);
            mesh.name = name;

            return(mesh);
        }
コード例 #6
0
        public static TriangleNet.Mesh Generate(IEnumerable <Vector2> circuit)
        {
            var mesh = new TriangleNet.Mesh(Behavior);

            var geometry = GetGeometryFor(circuit);

            mesh.Triangulate(geometry);

            return(mesh);
        }
コード例 #7
0
    Mesh generateFaceMesh(ShapePoints shape)
    {
        var mesh  = new Mesh();
        var verts = new List <Vector3>();
        var tris  = new List <int>();
        var uvs   = new List <Vector2>();
        var uv2   = new List <Vector2>();

        var geometry = new InputGeometry();

        for (int i = 0; i < shape.edge.Length; ++i)
        {
            var pt = shape.edge[i];
            geometry.AddPoint(pt.x, pt.y);
            verts.Add(pt.p.AsVector3(-pt.groundness * _groundPull));
            uvs.Add(pt.p);
            uv2.Add(new Vector2(pt.groundness * pt.groundness, 0));
            geometry.AddSegment(i, (i + 1) % shape.edge.Length);
        }

        for (int i = 0; i < shape.interior.Length; ++i)
        {
            var pt = shape.interior[i];
            geometry.AddPoint(pt.x, pt.y);
            verts.Add(pt.p.AsVector3(-pt.groundness * _groundPull + UnityEngine.Random.value * 0.4f));
            uvs.Add(pt.p);
            uv2.Add(new Vector2(pt.groundness * pt.groundness, 0));
        }

        var behave = new TriangleNet.Behavior();

        behave.Algorithm = TriangleNet.TriangulationAlgorithm.Incremental;

        var meshRepresentation = new TriangleNet.Mesh(behave);

        meshRepresentation.Triangulate(geometry);

        foreach (var tri in meshRepresentation.Triangles)
        {
            tris.Add(tri.GetVertex(2).ID);
            tris.Add(tri.GetVertex(1).ID);
            tris.Add(tri.GetVertex(0).ID);
        }

        mesh.vertices  = verts.ToArray();
        mesh.triangles = tris.ToArray();
        mesh.uv        = uvs.ToArray();
        mesh.uv2       = uv2.ToArray();
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        return(mesh);
    }
コード例 #8
0
    private Mesh TriangulateMesh()
    {
        if (verts.Count > 2)
        {
            var tnMesh = new TriangleNet.Mesh();
            var input  = new TriangleNet.Geometry.InputGeometry();

            var localVertices = verts.Select(v => spriteRenderer.transform.InverseTransformPoint(v.position)).ToArray();

            for (int i = 0; i < verts.Count; i++)
            {
                verts[i].index = i;
                input.AddPoint(verts[i].position.x, verts[i].position.y);
            }

            foreach (var seg in segments)
            {
                if (!seg.IsDeleted())
                {
                    input.AddSegment(seg.first.index, seg.second.index);
                }
            }

            foreach (var hole in holes)
            {
                input.AddHole(hole.x, hole.y);
            }

            tnMesh.Triangulate(input);

            try {
                Mesh mesh = new Mesh();
                mesh.vertices  = localVertices;
                mesh.triangles = tnMesh.Triangles.ToUnityMeshTriangleIndices();
                mesh.uv        = genUV(mesh.vertices);
                mesh.RecalculateBounds();
                mesh.RecalculateNormals();
                return(mesh);
            }
            catch {
                Debug.LogError("Mesh topology was wrong. Make sure you dont have intersecting edges.");
                throw;
            }
        }
        else
        {
            return(null);
        }
    }
コード例 #9
0
        public void Triangulate()
        {
            indices.Clear();

            if (texVertices.Count >= 3)
            {
                InputGeometry inputGeometry = new InputGeometry(texVertices.Count);

                for (int i = 0; i < texVertices.Count; ++i)
                {
                    Vector2 vertex = texVertices[i].vertex;
                    inputGeometry.AddPoint(vertex.x, vertex.y);
                }

                for (int i = 0; i < edges.Count; ++i)
                {
                    Edge edge = edges[i];
                    inputGeometry.AddSegment(texVertices.IndexOf(edge.vertex1),
                                             texVertices.IndexOf(edge.vertex2));
                }

                for (int i = 0; i < holes.Count; ++i)
                {
                    Vector2 hole = holes[i].vertex;
                    inputGeometry.AddHole(hole.x, hole.y);
                }

                TriangleNet.Mesh trangleMesh = new TriangleNet.Mesh();

                trangleMesh.Triangulate(inputGeometry);


                foreach (TriangleNet.Data.Triangle triangle in trangleMesh.Triangles)
                {
                    if (triangle.P0 >= 0 && triangle.P0 < texVertices.Count &&
                        triangle.P0 >= 0 && triangle.P1 < texVertices.Count &&
                        triangle.P0 >= 0 && triangle.P2 < texVertices.Count)
                    {
                        indices.Add(triangle.P0);
                        indices.Add(triangle.P2);
                        indices.Add(triangle.P1);
                    }
                }
            }

            isDirty = true;
        }
コード例 #10
0
        public static void Triangulate(List <Vector2> vertices, List <IndexedEdge> edges, List <Hole> holes,
                                       ref List <int> indices)
        {
            indices.Clear();

            if (vertices.Count >= 3)
            {
                InputGeometry inputGeometry = new InputGeometry(vertices.Count);

                for (int i = 0; i < vertices.Count; ++i)
                {
                    Vector2 position = vertices[i];
                    inputGeometry.AddPoint(position.x, position.y);
                }

                for (int i = 0; i < edges.Count; ++i)
                {
                    IndexedEdge edge = edges[i];
                    inputGeometry.AddSegment(edge.index1, edge.index2);
                }

                for (int i = 0; i < holes.Count; ++i)
                {
                    Vector2 hole = holes[i].vertex;
                    inputGeometry.AddHole(hole.x, hole.y);
                }

                TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

                triangleMesh.Triangulate(inputGeometry);

                foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles)
                {
                    if (triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
                        triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
                        triangle.P0 >= 0 && triangle.P2 < vertices.Count)
                    {
                        indices.Add(triangle.P0);
                        indices.Add(triangle.P2);
                        indices.Add(triangle.P1);
                    }
                }
            }
        }
コード例 #11
0
        /// <summary>
        /// Creates a surface from the given points.
        /// </summary>
        /// <param name="points">Input points</param>
        /// <param name="surface">The type of surface being operated on</param>
        public void SurfaceFromPoints(Point3dCollection points, SurfaceType surface)
        {
            TriangleNet.Mesh mesh = new TriangleNet.Mesh();
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(points.Count);
            foreach (Point3d point in points)
            {
                geometry.AddPoint(point.X, point.Y, 0, point.Z);
            }
            mesh.Triangulate(geometry);

            if (surface == SurfaceType.Original)
            {
                originalSurface = mesh;
            }
            else
            {
                proposedSurface = mesh;
            }
        }
コード例 #12
0
ファイル: TriangleNET.cs プロジェクト: furaga/Magic2D_rev3
        public static TriangleNet.Mesh TriangulateMesh(List <PointF> path, float minAngle, float maxAngle, bool conformingDelaunay, bool quality, bool convex)
        {
            if (path == null)
            {
                return(null);
            }
            if (path.Count <= 2)
            {
                return(null);
            }

            List <FTriangle> outTris = new List <FTriangle>();

            MeshRenderer.Core.RenderData       renderData    = new MeshRenderer.Core.RenderData();
            MeshRenderer.Core.RenderManager    renderManager = new MeshRenderer.Core.RenderManager();
            TriangleNet.Geometry.InputGeometry input         = new TriangleNet.Geometry.InputGeometry(path.Count);
            TriangleNet.Mesh mesh = new TriangleNet.Mesh();

            input.AddPoint(path[0].X, path[0].Y);
            for (int i = 1; i < path.Count; i++)
            {
                input.AddPoint(path[i].X, path[i].Y);
                input.AddSegment(i - 1, i);
            }
            input.AddSegment(path.Count - 1, 0);

            renderData.SetInputGeometry(input);

            renderManager.CreateDefaultControl();
            renderManager.SetData(renderData);

            mesh.Behavior.MinAngle           = FMath.Clamp(0, 40, minAngle);
            mesh.Behavior.MaxAngle           = FMath.Clamp(80, 180, maxAngle);
            mesh.Behavior.ConformingDelaunay = conformingDelaunay;
            mesh.Behavior.Quality            = quality;
            mesh.Behavior.Convex             = convex;

            mesh.Triangulate(input);

            return(mesh);
        }
コード例 #13
0
        private void RunTessellation(List <SampleVertexData> lVerts, MTMeshData.LOD lod)
        {
            if (lVerts.Count < 3)
            {
                ++curIdx;
                return;
            }
            InputGeometry geometry = new InputGeometry();

            for (int i = 0; i < lVerts.Count; i++)
            {
                geometry.AddPoint(lVerts[i].Position.x, lVerts[i].Position.z, 0);
            }
            TriangleNet.Mesh meshRepresentation = new TriangleNet.Mesh();
            meshRepresentation.Triangulate(geometry);
            int vIdx = 0;

            lod.vertices = new Vector3[meshRepresentation.Vertices.Count];
            lod.normals  = new Vector3[meshRepresentation.Vertices.Count];
            lod.uvs      = new Vector2[meshRepresentation.Vertices.Count];
            lod.faces    = new int[meshRepresentation.triangles.Count * 3];
            foreach (var v in meshRepresentation.Vertices)
            {
                lod.vertices[vIdx] = new Vector3(v.x, lVerts[vIdx].Position.y, v.y);
                lod.normals[vIdx]  = lVerts[vIdx].Normal;
                lod.uvs[vIdx]      = lVerts[vIdx].UV;
                ++vIdx;
            }
            vIdx = 0;
            foreach (var t in meshRepresentation.triangles.Values)
            {
                lod.faces[vIdx]     = t.P2;
                lod.faces[vIdx + 1] = t.P1;
                lod.faces[vIdx + 2] = t.P0;
                vIdx += 3;
            }
        }
コード例 #14
0
    public void CreateSubdividedMesh(Vector2[] vertsToCopy, Transform transform, int smoothLevel)
    {
        Sprite          spr             = transform.GetComponent <SpriteRenderer>().sprite;
        Rect            rec             = spr.rect;
        Vector3         bound           = transform.renderer.bounds.max - transform.renderer.bounds.min;
        TextureImporter textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;

        //Create triangle.NET geometry
        TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(vertsToCopy.Length);

        //Add vertices
        foreach (Vector2 p in vertsToCopy)
        {
            geometry.AddPoint(p.x, p.y);
        }
        //Add segments
        for (int i = 0; i < vertsToCopy.Length - 1; i++)
        {
            geometry.AddSegment(i, i + 1);
        }
        geometry.AddSegment(vertsToCopy.Length - 1, 0);

        //Triangulate, refine and smooth
        TriangleNet.Mesh triangleNetMesh = new TriangleNet.Mesh();
        triangleNetMesh.behavior.MinAngle = 10;
        triangleNetMesh.Triangulate(geometry);
        if (smoothLevel > 1)
        {
            triangleNetMesh.Refine(true);
        }
        TriangleNet.Tools.Statistic statistic = new TriangleNet.Tools.Statistic();
        statistic.Update(triangleNetMesh, 1);
        // Refine by setting a custom maximum area constraint.
        if (smoothLevel > 2)
        {
            triangleNetMesh.Refine(statistic.LargestArea / 8);
        }

        try
        {
            triangleNetMesh.Smooth();
        }
        catch
        {
            //Debug.LogWarning("unable to smooth");
        }
        triangleNetMesh.Renumber();

        //transform vertices
        Vector3[] vertices = new Vector3[triangleNetMesh.Vertices.Count];
        Vector2[] uvs      = new Vector2[triangleNetMesh.Vertices.Count];
        Vector3[] normals  = new Vector3[triangleNetMesh.Vertices.Count];

        int idx = 0;

        foreach (TriangleNet.Data.Vertex v in triangleNetMesh.Vertices)
        {
            vertices[idx] = new Vector3((float)v.X, (float)v.Y, 0);
            normals[idx]  = new Vector3(0, 0, -1);


            Vector2 newUv = new Vector2(((float)v.X / bound.x) + 0.5f, ((float)v.Y / bound.y) + 0.5f);

            newUv.x *= rec.width / spr.texture.width;
            newUv.y *= rec.height / spr.texture.height;
            //Debug.Log(spr.textureRectOffset);
            newUv.x += (rec.x) / spr.texture.width;
            newUv.y += (rec.y) / spr.texture.height;

            SpriteMetaData[] smdArray = textureImporter.spritesheet;
            Vector2          pivot    = new Vector2(.0f, .0f);;

            for (int i = 0; i < smdArray.Length; i++)
            {
                if (smdArray[i].name == spr.name)
                {
                    switch (smdArray[i].alignment)
                    {
                    case (0):
                        smdArray[i].pivot = Vector2.zero;
                        break;

                    case (1):
                        smdArray[i].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                        break;

                    case (2):
                        smdArray[i].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                        break;

                    case (3):
                        smdArray[i].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                        break;

                    case (4):
                        smdArray[i].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                        break;

                    case (5):
                        smdArray[i].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                        break;

                    case (6):
                        smdArray[i].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                        break;

                    case (7):
                        smdArray[i].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                        break;

                    case (8):
                        smdArray[i].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                        break;

                    case (9):
                        smdArray[i].pivot -= new Vector2(.5f, .5f);
                        break;
                    }
                    pivot = smdArray[i].pivot;
                }
            }
            if (textureImporter.spriteImportMode == SpriteImportMode.Single)
            {
                pivot = textureImporter.spritePivot - new Vector2(.5f, .5f);
            }
            newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
            newUv.y += ((pivot.y) * rec.height) / spr.texture.height;


            uvs[idx] = newUv;
            idx++;
        }

        //transform triangles
        int[] triangles = new int[triangleNetMesh.Triangles.Count * 3];
        idx = 0;
        foreach (TriangleNet.Data.Triangle t in triangleNetMesh.Triangles)
        {
            triangles[idx++] = t.P1;
            triangles[idx++] = t.P0;
            triangles[idx++] = t.P2;
        }

        finalVertices  = vertices;
        finalTriangles = triangles;
        finalUvs       = uvs;
        finalNormals   = normals;
    }
コード例 #15
0
ファイル: Slice.cs プロジェクト: zhangzheng1205/PathCAM
        /// <summary>
        /// Get a list of triangles which will fill the area described by the slice
        /// </summary>
        public IEnumerable <Triangle> Triangles()
        {
            TriangleNet.Behavior behavior = new TriangleNet.Behavior();
            behavior.ConformingDelaunay = true;

            foreach (var poly in IndividualPolygons())
            {
                PolyNode      node     = polyTree.GetFirst();
                InputGeometry geometry = new InputGeometry();
                while (node != null)
                {
                    var offset = geometry.Points.Count();
                    var index  = 0;
                    foreach (IntPoint point in node.Contour)
                    {
                        geometry.AddPoint(point.X, point.Y);
                        if (index > 0)
                        {
                            geometry.AddSegment(index - 1 + offset, index + offset);
                        }
                        index++;
                    }
                    geometry.AddSegment(index - 1 + offset, offset);

                    if (node.IsHole)
                    {
                        // To describe a hole, AddHole must be called with a location inside the hole.
                        IntPoint last         = new IntPoint(0, 0);
                        bool     lastKnown    = false;
                        double   longest      = 0;
                        IntPoint longestAlong = new IntPoint(0, 0);
                        IntPoint from         = new IntPoint(0, 0);
                        foreach (IntPoint point in node.Contour)
                        {
                            if (lastKnown)
                            {
                                IntPoint along  = new IntPoint(point.X - last.X, point.Y - last.Y);
                                double   length = Math.Sqrt(along.X * along.X + along.Y * along.Y);
                                if (length > longest)
                                {
                                    longest      = length;
                                    longestAlong = along;
                                    from         = last;
                                }
                            }
                            last      = point;
                            lastKnown = true;
                        }
                        if (longest > 0)
                        {
                            double perpendicularX = ((double)longestAlong.Y * (double)scale * 0.001d) / longest;
                            double perpendicularY = -((double)longestAlong.X * (double)scale * 0.001d) / longest;
                            geometry.AddHole(perpendicularX + from.X + longestAlong.X / 2.0d,
                                             perpendicularY + from.Y + longestAlong.Y / 2.0d);
                        }
                        else
                        {
                        }
                    }
                    node = node.GetNext();
                }

                if (geometry.Points.Count() > 0)
                {
                    var mesh = new TriangleNet.Mesh(behavior);
                    mesh.Triangulate(geometry);
                    mesh.Renumber();
                    foreach (Triangle t in this.GetMeshTriangles(mesh))
                    {
                        yield return(t);
                    }
                }
            }
        }
コード例 #16
0
ファイル: DelaunayDemo.cs プロジェクト: CodeMoshete/albatross
    // Use this for initialization
    void Start()
    {
        geometry = new InputGeometry();

        List <Point> shape = new List <Point> ();

        shape.Add(new Point(0f, 0f));
        shape.Add(new Point(2f, 2f));
        shape.Add(new Point(1f, 4f));
        shape.Add(new Point(3f, 5f));
        shape.Add(new Point(-3f, 5f));
        shape.Add(new Point(-1f, 4f));
        shape.Add(new Point(-2f, 2f));
        geometry.AddRing(shape);

        //it is necessary to put a border around all the points in order to get triangulation to work correctly when holes are used
//        List<Point> border = new List<Point>();
//        border.Add(new Point(distance, verticalDistance));
//        border.Add(new Point(distance, -verticalDistance));
//        border.Add(new Point(-distance, -verticalDistance));
//        border.Add(new Point(-distance, verticalDistance));
//        geometry.AddRing(border);

//        List<Point> outlinePoints = new List<Point>(logoOutline.points.Length);
//        foreach (Vector2 coordinates in logoOutline.points)
//        {
//            outlinePoints.Add(new Point(coordinates));
//        }
//
//        geometry.AddRingAsHole(outlinePoints, 0);
//
//
//        foreach(UPolygon hole in holes)
//        {
//            List<Point> holePoints = new List<Point>(hole.points.Length);
//
//            foreach (Vector2 coordinates in hole.points)
//                holePoints.Add(new Point(coordinates));
//
//            geometry.AddRing(holePoints, 0);
//        }


//        List<Point> points = new List<Point>();
//        for (float offsetX = -distance; offsetX < distance; offsetX += boxDistance)
//        {
//            for (float offsetY = -verticalDistance; offsetY < verticalDistance; offsetY += boxDistance)
//            {
//                Vector2 offset = new Vector2(offsetX, offsetY) + Vector2.one * boxDistance * 0.5f;
//
//                float radians = Random.RandomRange(0, 2 * Mathf.PI);
//                float length = Random.RandomRange(0, circleDistance);
//
//                Vector2 pos = new Vector2(Mathf.Cos(radians), Mathf.Sin(radians)) * length;
//                pos += offset;
//
//                bool insideOutline = logoOutline.PointInPolygon(pos);
//
//                bool stillAlloved = false;
//                for (int i = 0; i < holes.Length; i++ )
//                {
//                    if (holes[i].PointInPolygon(pos))
//                        stillAlloved = true;
//                }
//
//                if (!insideOutline || stillAlloved)
//                    geometry.AddPoint((float)pos.x, (float)pos.y, 0);
//            }
//        }

        meshRepresentation = new TriangleNet.Mesh();
        meshRepresentation.Triangulate(geometry);

        //generate mesh based on triangulation

        Dictionary <int, float> zOffsets = new Dictionary <int, float>();

//        foreach(KeyValuePair<int, TriangleNet.Data.Vertex> pair in meshRepresentation.vertices)
//        {
//            zOffsets.Add(pair.Key, Random.RandomRange(-zOffset, zOffset));
//        }

        int            triangleIndex   = 0;
        List <Vector3> vertices        = new List <Vector3>(meshRepresentation.triangles.Count * 3);
        List <int>     triangleIndices = new List <int>(meshRepresentation.triangles.Count * 3);

        foreach (KeyValuePair <int, TriangleNet.Data.Triangle> pair in meshRepresentation.triangles)
        {
            TriangleNet.Data.Triangle triangle = pair.Value;

            TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0);
            TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1);
            TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2);

            Vector3 p0 = new Vector3(vertex0.x, vertex0.y, 0);
            Vector3 p1 = new Vector3(vertex1.x, vertex1.y, 0);
            Vector3 p2 = new Vector3(vertex2.x, vertex2.y, 0);

            vertices.Add(p0);
            vertices.Add(p1);
            vertices.Add(p2);

            triangleIndices.Add(triangleIndex + 2);
            triangleIndices.Add(triangleIndex + 1);
            triangleIndices.Add(triangleIndex);

            triangleIndex += 3;
        }

        mesh           = new Mesh();
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();
        mesh.RecalculateNormals();
        GetComponent <MeshFilter>().mesh = mesh;
    }
コード例 #17
0
ファイル: GameMapRender.cs プロジェクト: astrellon/cbt
    // Use this for initialization
    void Start()
    {
        Map             = new GameMap();
        Map.TerrainData = LowPolyTerrainData.GetRandomMap();

        var building = new Building();

        building.Positions.Add(new Vector2Int(6, 1));
        building.Positions.Add(new Vector2Int(7, 1));
        building.Positions.Add(new Vector2Int(8, 1));
        building.Positions.Add(new Vector2Int(9, 1));
        building.Positions.Add(new Vector2Int(10, 1));
        building.Positions.Add(new Vector2Int(11, 1));
        building.Positions.Add(new Vector2Int(12, 1));
        building.Positions.Add(new Vector2Int(13, 1));
        building.Positions.Add(new Vector2Int(14, 1));
        building.Positions.Add(new Vector2Int(11, 2));
        building.Positions.Add(new Vector2Int(12, 2));
        building.Positions.Add(new Vector2Int(12, 3));
        building.Positions.Add(new Vector2Int(13, 3));
        building.Positions.Add(new Vector2Int(13, 4));
        building.Positions.Add(new Vector2Int(14, 4));
        building.Positions.Add(new Vector2Int(14, 5));
        building.Positions.Add(new Vector2Int(15, 5));
        building.RemoveTrees(Map.TerrainData);
        //Map.Buildings.Add(building);

        building = new Building();
        //building.Positions.Add(new Vector2Int(6, 2));
        building.Positions.Add(new Vector2Int(7, 2));
        building.Positions.Add(new Vector2Int(8, 2));
        building.Positions.Add(new Vector2Int(9, 2));
        building.Positions.Add(new Vector2Int(10, 2));
        building.Positions.Add(new Vector2Int(5, 3));
        building.Positions.Add(new Vector2Int(6, 3));
        building.Positions.Add(new Vector2Int(7, 3));
        building.Positions.Add(new Vector2Int(8, 3));
        building.Positions.Add(new Vector2Int(9, 3));
        building.Positions.Add(new Vector2Int(10, 3));
        building.Positions.Add(new Vector2Int(11, 3));
        //building.Positions.Add(new Vector2Int(5, 4));
        building.Positions.Add(new Vector2Int(6, 4));
        building.Positions.Add(new Vector2Int(7, 4));
        building.Positions.Add(new Vector2Int(8, 4));
        building.Positions.Add(new Vector2Int(9, 4));
        building.Positions.Add(new Vector2Int(10, 4));
        building.Positions.Add(new Vector2Int(11, 4));
        building.Positions.Add(new Vector2Int(10, 6));
        building.Positions.Add(new Vector2Int(11, 6));
        building.Positions.Add(new Vector2Int(12, 6));
        building.Type = "house";
        building.RemoveTrees(Map.TerrainData);
        //Map.Buildings.Add(building);

        building = new Building();

        var floor = new BuildingFloor();

        floor.Positions.Add(new Vector2Int(13, 2));
        floor.Positions.Add(new Vector2Int(14, 2));
        floor.Positions.Add(new Vector2Int(15, 2));
        floor.Positions.Add(new Vector2Int(16, 2));
        floor.Positions.Add(new Vector2Int(14, 3));
        floor.Positions.Add(new Vector2Int(15, 3));
        floor.Positions.Add(new Vector2Int(16, 3));

        floor.WallEdges.Add(new WallEdge(new Vector2Int(13, 2), 2));
        floor.WallEdges.Add(new WallEdge(new Vector2Int(13, 2), 0));

        floor.BaseHeight  = 20.0f;
        floor.FloorHeight = 0.2f;
        floor.Height      = 10.0f;
        floor.Map         = Map;

        building.Floors.Add(floor);

        floor = new BuildingFloor();
        floor.Positions.Add(new Vector2Int(14, 2));
        floor.Positions.Add(new Vector2Int(15, 2));
        floor.Positions.Add(new Vector2Int(16, 2));
        floor.Positions.Add(new Vector2Int(14, 3));
        floor.Positions.Add(new Vector2Int(15, 3));
        floor.Positions.Add(new Vector2Int(16, 3));

        floor.WallEdges.Add(new WallEdge(new Vector2Int(14, 2), 2));
        floor.WallEdges.Add(new WallEdge(new Vector2Int(15, 2), 2));

        floor.BaseHeight  = 30.0f;
        floor.FloorHeight = 0.2f;
        floor.Height      = 10.0f;
        floor.Map         = Map;
        building.Floors.Add(floor);

        floor = new BuildingFloor();
        floor.Positions.Add(new Vector2Int(15, 4));
        floor.Positions.Add(new Vector2Int(16, 4));
        floor.Positions.Add(new Vector2Int(17, 4));
        floor.Positions.Add(new Vector2Int(17, 3));
        floor.Positions.Add(new Vector2Int(18, 3));

        floor.WallEdges.Add(new WallEdge(new Vector2Int(15, 4), 0));
        floor.WallEdges.Add(new WallEdge(new Vector2Int(16, 4), 0));
        floor.WallEdges.Add(new WallEdge(new Vector2Int(17, 4), 1, 2));

        floor.BaseHeight  = 22.0f;
        floor.FloorHeight = 0.2f;
        floor.Height      = 10.0f;
        floor.Map         = Map;
        building.Floors.Add(floor);

        building.Type = "generic";

        building.RemoveTrees(Map.TerrainData);
        Map.Buildings.Add(building);

        Init(Map);

        var geometry = new InputGeometry();

        //it is necessary to put a border around all the points in order to get triangulation to work correctly when holes are used
        var border = new List <Point>();

        border.Add(new Point(10, 6));
        border.Add(new Point(10, -6));
        border.Add(new Point(-10, -6));
        border.Add(new Point(-10, 6));
        geometry.AddRing(border);

        border = new List <Point>();
        border.Add(new Point(7, 4));
        border.Add(new Point(7, 2));
        border.Add(new Point(5, 2));
        border.Add(new Point(5, 4));
        geometry.AddRingAsHole(border);

        border = new List <Point>();
        border.Add(new Point(3, 2));
        border.Add(new Point(3, -6));
        border.Add(new Point(-3, -6));
        border.Add(new Point(-3, 2));
        geometry.AddRingAsHole(border);

        var meshRepresentation = new TriangleNet.Mesh();

        meshRepresentation.Triangulate(geometry);

        var triangleIndex   = 0;
        var vertices        = new List <Vector3>(meshRepresentation.triangles.Count * 3);
        var triangleIndices = new List <int>(meshRepresentation.triangles.Count * 3);

        foreach (var pair in meshRepresentation.triangles)
        {
            var triangle = pair.Value;

            var vertex0 = triangle.GetVertex(0);
            var vertex1 = triangle.GetVertex(1);
            var vertex2 = triangle.GetVertex(2);

            var p0 = new Vector3(vertex0.x, vertex0.y, 0);
            var p1 = new Vector3(vertex1.x, vertex1.y, 0);
            var p2 = new Vector3(vertex2.x, vertex2.y, 0);

            vertices.Add(p0);
            vertices.Add(p1);
            vertices.Add(p2);

            triangleIndices.Add(triangleIndex + 2);
            triangleIndices.Add(triangleIndex + 1);
            triangleIndices.Add(triangleIndex);

            triangleIndex += 3;
        }

        var mesh = new Mesh();

        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();
        mesh.RecalculateNormals();

        var newObj = new GameObject();

        newObj.name             = "Test";
        newObj.transform.parent = transform;
        newObj.AddComponent <MeshFilter>();
        newObj.AddComponent <MeshRenderer>();
        newObj.GetComponent <MeshFilter>().mesh = mesh;

        /*
         * var path = new List<ClipperLib.IntPoint>();
         * path.Add(new ClipperLib.IntPoint(-3000, 0));
         * path.Add(new ClipperLib.IntPoint(1000, 0));
         * path.Add(new ClipperLib.IntPoint(6000, 3000));
         * path.Add(new ClipperLib.IntPoint(6000, -3000));
         * path.Add(new ClipperLib.IntPoint(1000, 0));
         * //path.Add(new ClipperLib.IntPoint(5000, 0));
         * //path.Add(new ClipperLib.IntPoint(1000, -3500));
         * //path.Add(new ClipperLib.IntPoint(-3000, 0));
         *
         * var co = new ClipperLib.ClipperOffset();
         * co.AddPath(path, ClipperLib.JoinType.jtSquare, ClipperLib.EndType.etClosedLine);
         *
         * var result = new List<List<ClipperLib.IntPoint>>();
         * co.Execute(ref result, 500);
         * foreach (var intpoint in path)
         * {
         *  var point = new Vector3((float)intpoint.X / 1000.0f, 0, (float)intpoint.Y / 1000.0f);
         *  Debug.DrawLine(point, point + Vector3.up * 3, Color.cyan, 100);
         * }
         *
         * foreach (var intpath in result)
         * {
         *  foreach (var intpoint in intpath)
         *  {
         *      var point = new Vector3((float)intpoint.X / 1000.0f, 0, (float)intpoint.Y / 1000.0f);
         *      Debug.DrawLine(point, point + Vector3.up * 3, Color.red, 100);
         *  }
         * }
         */
    }
コード例 #18
0
    public static void CreateMesh(GameObject meshContainer, string path, string path2, string adfname)
    {
        var subgraphs = _LoadMarkerToSubgraph(path, path2);

        meshContainer.name = adfname + "Mesh";

        InputGeometry geometry = new InputGeometry();

        TriangleNet.Mesh meshRepresentation;
        MeshFilter       mf = meshContainer.GetComponent <MeshFilter> () as MeshFilter;
        Mesh             mesh;
        float            zOffset = 0.1f;

        float[] maxArea = new float[2] {
            0, 0
        };

        List <List <Point> > clusters = new List <List <Point> > ();

        foreach (Graph <Node> s in subgraphs)
        {
            List <Point> points = new List <Point> ();
            foreach (Node n in s.Nodes)
            {
                Point tmp = new Point(n.position.x, n.position.z);
                zOffset = n.position.y;
                points.Add(tmp);
            }
            if (points.Count > 2)
            {
                clusters.Add(points);

                // Calculate areas of the clusters. The largest is the external ring, while the others must be holes.
                float num = CalculateArea(points);
                if (num > maxArea [0])
                {
                    maxArea [0] = num;
                    maxArea [1] = clusters.Count - 1;
                }
            }
            Debug.Log(clusters [clusters.Count - 1].Count);
        }

        geometry.AddRing(clusters[(int)maxArea[1]]);
        clusters.RemoveAt((int)maxArea [1]);

        foreach (List <Point> c in clusters)
        {
            geometry.AddRingAsHole(c);
        }
        meshRepresentation = new TriangleNet.Mesh();
        meshRepresentation.Triangulate(geometry);

        //		Dictionary<int, float> zOffsets = new Dictionary<int, float>();
        //
        //		foreach(KeyValuePair<int, TriangleNet.Data.Vertex> pair in meshRepresentation.vertices)
        //		{
        //			zOffsets.Add(pair.Key, Random.RandomRange(-zOffset, zOffset));
        //		}

        int            triangleIndex   = 0;
        List <Vector3> vertices        = new List <Vector3>(meshRepresentation.triangles.Count * 3);
        List <int>     triangleIndices = new List <int>(meshRepresentation.triangles.Count * 3);

        foreach (KeyValuePair <int, TriangleNet.Data.Triangle> pair in meshRepresentation.triangles)
        {
            TriangleNet.Data.Triangle triangle = pair.Value;

            TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0);
            TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1);
            TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2);

            Vector3 p0 = new Vector3(vertex0.x, zOffset, vertex0.y);
            Vector3 p1 = new Vector3(vertex1.x, zOffset, vertex1.y);
            Vector3 p2 = new Vector3(vertex2.x, zOffset, vertex2.y);

            //			Vector3 p0 = new Vector3( vertex0.x, vertex0.y, zOffsets[vertex0.id]);
            //			Vector3 p1 = new Vector3( vertex1.x, vertex1.y, zOffsets[vertex1.id]);
            //			Vector3 p2 = new Vector3( vertex2.x, vertex2.y, zOffsets[vertex2.id]);

            vertices.Add(p0);
            vertices.Add(p1);
            vertices.Add(p2);

            triangleIndices.Add(triangleIndex + 2);
            triangleIndices.Add(triangleIndex + 1);
            triangleIndices.Add(triangleIndex);

            triangleIndex += 3;
        }
        mesh           = new Mesh();
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();
        mesh.RecalculateNormals();
        //GetComponent<MeshFilter>().mesh = mesh;
        mf.mesh = mesh;

        Exporter e = meshContainer.GetComponent <Exporter> () as Exporter;

        e.DoExport(true);
//
//		File.WriteAllBytes(Application.persistentDataPath + "/" + adfname + "Mesh", MeshSerializer.WriteMesh (mesh, true));

        meshContainer.SetActive(true);
        meshContainer.GetComponent <NavMeshSurface> ().BuildNavMesh();

        Debug.Log("NavMesh created");

        //MeshSaverEditor.SaveMesh (mesh, "meshtest", true, true);

        //ObjExporterScript.MeshToString(GetComponent<MeshFilter>(),
    }
コード例 #19
0
    // returns list of list of vertices, each one being a triangle
    public static List <List <Vector2> > MakeTriangles(List <List <Vector2> > loops)
    {
        //Debug.LogFormat("loop1 = {0}, loopL = {1}", loops[0].Count, loops[loops.Count - 1].Count);

        // first off, the loops should be sorted by area, so we can just go from the start expecting the first polygon to be the largest one and last the smallest.
        List <List <Vector2> > polygons = new List <List <Vector2> >();
        Dictionary <List <Vector2>, List <List <Vector2> > > holes = new Dictionary <List <Vector2>, List <List <Vector2> > >();

        //for (int i = loops.Count - 1; i >= 0; i--)
        for (int i = 0; i < loops.Count; i++)
        {
            List <Vector2> loop = loops[i];
            // first we check if this loop intersects any polygon. if it does, add hole to dictionary. if it doesn't, just add polygon.
            bool anyHole = false;

            for (int j = 0; j < polygons.Count; j++)
            {
                if (CheckIntersection(polygons[j], loop))
                {
                    //Debug.LogFormat("adding hole (len = {0}) to polygon (len = {1})", loop.Count, polygons[j].Count);
                    //Debug.LogFormat("polygon {0} intersects loop {1}", j, i);
                    if (!holes.ContainsKey(polygons[j]))
                    {
                        holes[polygons[j]] = new List <List <Vector2> >();
                    }
                    holes[polygons[j]].Add(((IEnumerable <Vector2>)loop).Reverse().ToList());
                    anyHole = true;
                    break;
                }
            }

            if (!anyHole)
            {
                //Debug.LogFormat("adding polygon (len = {0})", loop.Count);
                polygons.Add(loop);
            }
            //break;
        }

        List <List <Vector2> > output = new List <List <Vector2> >();

        for (int i = 0; i < polygons.Count; i++)
        {
            List <Vector2> polygon = polygons[i];

            if (polygon.Count < 3)
            {
                continue;
            }
            //Debug.LogFormat("polygon points = {0}", polygon.Count);

            InputGeometry input = new InputGeometry();
            for (int j = 0; j < polygon.Count; j++)
            {
                input.AddPoint(polygon[j].x, polygon[j].y);
            }

            // add segments
            for (int j = 0; j < polygon.Count; j++)
            {
                input.AddSegment(j, (j + 1) % polygon.Count, 0);
            }

            if (holes.ContainsKey(polygon))
            {
                for (int j = 0; j < holes[polygon].Count; j++)
                {
                    List <Vector2> hole = holes[polygon][j];

                    // add holes segments
                    int   basePt = input.points.Count;
                    float cx     = 0;
                    float cy     = 0;
                    for (int k = 0; k < hole.Count; k++)
                    {
                        input.AddPoint(hole[k].x, hole[k].y);
                        cx += hole[k].x; cy += hole[k].y;
                    }
                    cx /= hole.Count;
                    cy /= hole.Count;
                    for (int k = 0; k < hole.Count; k++)
                    {
                        input.AddSegment(basePt + k, basePt + ((k + 1) % hole.Count), j + 1);
                    }
                    input.AddHole(cx, cy);
                }
            }

            if (input.points.Count < 3)
            {
                continue;
            }

            //
            TriangleNet.Mesh mesh = new TriangleNet.Mesh();
            mesh.Triangulate(input);

            // put triangles to output
            for (int j = 0; j < mesh.Triangles.Count; j++)
            {
                Triangle       mtri     = mesh.Triangles.ElementAt(j);
                List <Vector2> triangle = new List <Vector2>();
                for (int k = 0; k < 3; k++)
                {
                    triangle.Add(new Vector2((float)mtri.vertices[k].x, (float)mtri.vertices[k].y));
                }
                output.Add(triangle);
            }
        }

        return(output);
    }
コード例 #20
0
ファイル: TestScenarios.cs プロジェクト: septagon/demiurge
        public static void RunPopulationScenario()
        {
            WaterTableArgs args = new WaterTableArgs();
            Bitmap         bmp  = new Bitmap(args.inputPath + "rivers.png");

            IField2d <float> baseMap = new Utils.FieldFromBitmap(new Bitmap(args.inputPath + "base_heights.png"));

            baseMap = new ReResField(baseMap, (float)bmp.Width / baseMap.Width);

            var wtf = Utils.GenerateWaters(bmp, baseMap);

            Utils.OutputAsColoredMap(wtf, wtf.RiverSystems, bmp, args.outputPath + "colored_map.png");

            IField2d <float> rainfall = new Utils.FieldFromBitmap(new Bitmap(args.inputPath + "rainfall.png"));

            rainfall = new ReResField(rainfall, (float)wtf.Width / rainfall.Width);

            IField2d <float> wateriness = Utils.GetWaterinessMap(wtf, rainfall);

            Utils.OutputField(new NormalizedComposition2d <float>(wateriness), bmp, args.outputPath + "wateriness.png");

            var locations = Utils.GetSettlementLocations(wtf, wateriness);
            SparseField2d <float> settlementMap = new SparseField2d <float>(wtf.Width, wtf.Height, 0f);

            foreach (var loc in locations)
            {
                settlementMap.Add(loc, wateriness[loc.y, loc.x]);
            }
            Utils.OutputField(settlementMap, bmp, args.outputPath + "settlements.png");

            TriangleNet.Geometry.InputGeometry pointSet = new TriangleNet.Geometry.InputGeometry();
            foreach (var loc in locations)
            {
                pointSet.AddPoint(loc.x, loc.y);
            }
            TriangleNet.Mesh mesh = new TriangleNet.Mesh();
            mesh.Triangulate(pointSet);
            //TriangleNet.Tools.AdjacencyMatrix mat = new TriangleNet.Tools.AdjacencyMatrix(mesh);

            Field2d <float> meshField = new Field2d <float>(settlementMap);

            foreach (var e in mesh.Edges)
            {
                var v0 = mesh.GetVertex(e.P0);
                var v1 = mesh.GetVertex(e.P1);

                float distance = (float)Math.Sqrt(Math.Pow(v0.X - v1.X, 2) + Math.Pow(v0.Y - v1.Y, 2));

                for (float t = 0f; t <= 1f; t += 0.5f / distance)
                {
                    int x = (int)Math.Round((1f - t) * v0.X + t * v1.X);
                    int y = (int)Math.Round((1f - t) * v0.Y + t * v1.Y);

                    meshField[y, x] = 0.5f;
                }

                meshField[(int)v0.Y, (int)v0.X] = 1f;
                meshField[(int)v1.Y, (int)v1.X] = 1f;
            }
            Utils.OutputField(meshField, bmp, args.outputPath + "mesh.png");
        }
コード例 #21
0
ファイル: SpriteMeshUtils.cs プロジェクト: Kundara/project1
		public static void Tessellate(List<Vector2> vertices, List<IndexedEdge> indexedEdges, List<Hole> holes, List<int> indices, float tessellationAmount)
		{
			if(tessellationAmount <= 0f)
			{
				return;
			}
			
			indices.Clear();
			
			if(vertices.Count >= 3)
			{
				InputGeometry inputGeometry = new InputGeometry(vertices.Count);
				
				for(int i = 0; i < vertices.Count; ++i)
				{
					Vector2 vertex = vertices[i];
					inputGeometry.AddPoint(vertex.x,vertex.y);
				}
				
				for(int i = 0; i < indexedEdges.Count; ++i)
				{
					IndexedEdge edge = indexedEdges[i];
					inputGeometry.AddSegment(edge.index1,edge.index2);
				}
				
				for(int i = 0; i < holes.Count; ++i)
				{
					Vector2 hole = holes[i].vertex;
					inputGeometry.AddHole(hole.x,hole.y);
				}
				
				TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();
				TriangleNet.Tools.Statistic statistic = new TriangleNet.Tools.Statistic();
				
				triangleMesh.Triangulate(inputGeometry);
				
				triangleMesh.Behavior.MinAngle = 20.0;
				triangleMesh.Behavior.SteinerPoints = -1;
				triangleMesh.Refine(true);
				
				statistic.Update(triangleMesh,1);
				
				triangleMesh.Refine(statistic.LargestArea / tessellationAmount);
				triangleMesh.Renumber();
				
				vertices.Clear();
				indexedEdges.Clear();
				
				foreach(TriangleNet.Data.Vertex vertex in triangleMesh.Vertices)
				{
					vertices.Add(new Vector2((float)vertex.X,(float)vertex.Y));
				}
				
				foreach(TriangleNet.Data.Segment segment in triangleMesh.Segments)
				{
					indexedEdges.Add(new IndexedEdge(segment.P0,segment.P1));
				}
				
				foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles)
				{
					if(triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P2 < vertices.Count)
					{
						indices.Add(triangle.P0);
						indices.Add(triangle.P2);
						indices.Add(triangle.P1);
					}
				}
			}
		}
コード例 #22
0
ファイル: SpriteMeshUtils.cs プロジェクト: Kundara/project1
		public static void Triangulate(List<Vector2> vertices, List<IndexedEdge> edges, List<Hole> holes,ref List<int> indices)
		{
			indices.Clear();
			
			if(vertices.Count >= 3)
			{
				InputGeometry inputGeometry = new InputGeometry(vertices.Count);
				
				for(int i = 0; i < vertices.Count; ++i)
				{
					Vector2 position = vertices[i];
					inputGeometry.AddPoint(position.x,position.y);
				}
				
				for(int i = 0; i < edges.Count; ++i)
				{
					IndexedEdge edge = edges[i];
					inputGeometry.AddSegment(edge.index1,edge.index2);
				}
				
				for(int i = 0; i < holes.Count; ++i)
				{
					Vector2 hole = holes[i].vertex;
					inputGeometry.AddHole(hole.x,hole.y);
				}
				
				TriangleNet.Mesh trangleMesh = new TriangleNet.Mesh();
				
				trangleMesh.Triangulate(inputGeometry);
				
				foreach (TriangleNet.Data.Triangle triangle in trangleMesh.Triangles)
				{
					if(triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
					   triangle.P0 >= 0 && triangle.P2 < vertices.Count)
					{
						indices.Add(triangle.P0);
						indices.Add(triangle.P2);
						indices.Add(triangle.P1);
					}
				}
			}
		}
コード例 #23
0
    public Mesh CreateMeshFromVerts(Vector3[] vertsToCopy, Mesh mesh, List <int> pathSplitIds, Transform SpriteGO = null)
    {
        Sprite          spr             = new Sprite();
        Rect            rec             = new Rect();
        Vector3         bound           = Vector3.zero;
        TextureImporter textureImporter = new TextureImporter();

        if (SpriteGO != null && SpriteGO.GetComponent <SpriteRenderer>() && SpriteGO.GetComponent <SpriteRenderer>().sprite)
        {
            spr             = SpriteGO.GetComponent <SpriteRenderer>().sprite;
            rec             = spr.rect;
            bound           = SpriteGO.GetComponent <Renderer>().bounds.max - SpriteGO.GetComponent <Renderer>().bounds.min;
            textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;
        }

        //Create triangle.NET geometry
        TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(vertsToCopy.Length);

        //Add vertices
        foreach (Vector3 p in vertsToCopy)
        {
            geometry.AddPoint(p.x, p.y);
        }
        //Add segments
        int prevEnd = 0;

        for (int i = 0; i < vertsToCopy.Length - 1; i++)
        {
            if (!pathSplitIds.Contains(i + 1))
            {
                geometry.AddSegment(i, i + 1);
                //Debug.Log ("joining " + i + " to " + (i + 1));
            }
            else
            {
                geometry.AddSegment(i, prevEnd);
                prevEnd = i + 1;
            }
        }
        if (pathSplitIds.Count <= 1)
        {
            //Debug.Log ("joining " + (vertsToCopy.Length - 1) + " to 0");
            geometry.AddSegment(vertsToCopy.Length - 1, 0);
        }


        //Triangulate, refine and smooth
        TriangleNet.Mesh triangleNetMesh = new TriangleNet.Mesh();

        triangleNetMesh.Triangulate(geometry);

        //transform vertices
        Vector3[] vertices = new Vector3[triangleNetMesh.Vertices.Count];
        Vector2[] uvs      = new Vector2[triangleNetMesh.Vertices.Count];
        Vector3[] normals  = new Vector3[triangleNetMesh.Vertices.Count];

        int idx = 0;

        foreach (TriangleNet.Data.Vertex v in triangleNetMesh.Vertices)
        {
            vertices[idx] = new Vector3((float)v.X, (float)v.Y, 0);
            normals[idx]  = new Vector3(0, 0, -1);

            if (SpriteGO != null && SpriteGO.GetComponent <SpriteRenderer>())
            {
                Vector2 newUv = new Vector2(((float)v.X / bound.x) + 0.5f, ((float)v.Y / bound.y) + 0.5f);

                newUv.x *= rec.width / spr.texture.width;
                newUv.y *= rec.height / spr.texture.height;
                //Debug.Log(spr.textureRectOffset);
                newUv.x += (rec.x) / spr.texture.width;
                newUv.y += (rec.y) / spr.texture.height;

                SpriteMetaData[] smdArray = textureImporter.spritesheet;
                Vector2          pivot    = new Vector2(.0f, .0f);
                ;

                for (int i = 0; i < smdArray.Length; i++)
                {
                    if (smdArray [i].name == spr.name)
                    {
                        switch (smdArray [i].alignment)
                        {
                        case (0):
                            smdArray [i].pivot = Vector2.zero;
                            break;

                        case (1):
                            smdArray [i].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                            break;

                        case (2):
                            smdArray [i].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                            break;

                        case (3):
                            smdArray [i].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                            break;

                        case (4):
                            smdArray [i].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                            break;

                        case (5):
                            smdArray [i].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                            break;

                        case (6):
                            smdArray [i].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                            break;

                        case (7):
                            smdArray [i].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                            break;

                        case (8):
                            smdArray [i].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                            break;

                        case (9):
                            smdArray [i].pivot -= new Vector2(.5f, .5f);
                            break;
                        }
                        pivot = smdArray [i].pivot;
                    }
                }
                if (textureImporter.spriteImportMode == SpriteImportMode.Single)
                {
                    pivot = textureImporter.spritePivot - new Vector2(.5f, .5f);
                }
                newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
                newUv.y += ((pivot.y) * rec.height) / spr.texture.height;


                uvs [idx] = newUv;
            }


            idx++;
        }

        //transform triangles
        int[] triangles = new int[triangleNetMesh.Triangles.Count * 3];
        idx = 0;
        foreach (TriangleNet.Data.Triangle t in triangleNetMesh.Triangles)
        {
            triangles[idx++] = t.P1;
            triangles[idx++] = t.P0;
            triangles[idx++] = t.P2;
        }

        mesh.vertices  = vertices;
        mesh.triangles = triangles;
        mesh.uv        = uvs;
        mesh.normals   = normals;

        return(mesh);
    }
コード例 #24
0
    public Mesh TriangulateMesh(Vector3[] Vertices)
    {
        if (Vertices.Length < 3)
        {
            return(null);
        }

        geometry = new InputGeometry();

        foreach (Vector3 Vert in Vertices)
        {
            geometry.AddPoint(Vert.x, Vert.y);
        }

        List <Point> points = new List <Point>();

        for (float offsetX = -distance; offsetX < distance; offsetX += boxDistance)
        {
            for (float offsetY = -verticalDistance; offsetY < verticalDistance; offsetY += boxDistance)
            {
                Vector2 offset = new Vector2(offsetX, offsetY) + Vector2.one * boxDistance * 0.5f;

                float radians = Random.Range(0, 2 * Mathf.PI);
                float length  = Random.Range(0, circleDistance);

                Vector2 pos = new Vector2(Mathf.Cos(radians), Mathf.Sin(radians)) * length;
                pos += offset;
            }
        }

        meshRepresentation = new TriangleNet.Mesh();
        meshRepresentation.Triangulate(geometry);

        //generate mesh based on triangulation

        Dictionary <int, float> zOffsets = new Dictionary <int, float>();

        foreach (KeyValuePair <int, TriangleNet.Data.Vertex> pair in meshRepresentation.vertices)
        {
            zOffsets.Add(pair.Key, Random.Range(-zOffset, zOffset));
        }

        int            triangleIndex   = 0;
        List <Vector3> vertices        = new List <Vector3>(meshRepresentation.triangles.Count * 3);
        List <int>     triangleIndices = new List <int>(meshRepresentation.triangles.Count * 3);

        foreach (KeyValuePair <int, TriangleNet.Data.Triangle> pair in meshRepresentation.triangles)
        {
            TriangleNet.Data.Triangle triangle = pair.Value;

            TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0);
            TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1);
            TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2);

            Vector3 p0 = new Vector3(vertex0.x, vertex0.y, zOffsets[vertex0.id]);
            Vector3 p1 = new Vector3(vertex1.x, vertex1.y, zOffsets[vertex1.id]);
            Vector3 p2 = new Vector3(vertex2.x, vertex2.y, zOffsets[vertex2.id]);

            vertices.Add(p0);
            vertices.Add(p1);
            vertices.Add(p2);

            triangleIndices.Add(triangleIndex + 2);
            triangleIndices.Add(triangleIndex + 1);
            triangleIndices.Add(triangleIndex);

            triangleIndex += 3;
        }

        mesh           = new Mesh();
        mesh.name      = "Triangulated Terrain";
        mesh.vertices  = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();

        return(mesh);
    }
コード例 #25
0
    private void CreateMesh()
    {
        Sprite sprite = spriteRenderer.sprite;

        Rect bounds = GetBounds(polygon);

        TriangleNet.Mesh tnMesh = new TriangleNet.Mesh();
        TriangleNet.Geometry.InputGeometry input = new TriangleNet.Geometry.InputGeometry();

        input.AddPolygon(polygon);

        tnMesh.Triangulate(input);

        Mesh mesh = new Mesh();

        mesh.vertices = tnMesh.Vertices.Select(p => new Vector3((float)p.X, (float)p.Y, 0)).ToArray();

        // Not sure about winding
        // If there is an interesting error, It is probably because of cw/ccw windings
        int[] tris = tnMesh.Triangles.ToUnityMeshTriangleIndices();
        mesh.triangles = tris;

        List <Vector2> uv = new List <Vector2>();

        Vector3 lower = new Vector3(bounds.x, bounds.y);
        Vector3 size  = new Vector3(bounds.xMax, bounds.yMax) - lower;

        Rect uv_bounds = new Rect(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height, sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);

        float scalex = sprite.bounds.size.x / bounds.width;
        float scaley = sprite.bounds.size.y / bounds.height;

        Vector3[] scaled = mesh.vertices;

        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            Vector3 v   = scaled[i];
            Vector3 rel = v - lower;
            uv.Add(new Vector2(rel.x / size.x * uv_bounds.width, rel.y / size.y * uv_bounds.height) + new Vector2(uv_bounds.x, uv_bounds.y));

            scaled[i] = new Vector3(v.x * scalex, v.y * scaley, v.z) - ((Vector3)bounds.center * scalex) + sprite.bounds.center;
        }

        mesh.MarkDynamic();
        mesh.vertices = scaled;
        mesh.uv       = uv.ToArray();
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        mesh.Optimize();

        //GameObject go = new GameObject();
        //MeshFilter mf = go.AddComponent<MeshFilter>();
        //mf.sharedMesh = mesh;
        //MeshRenderer mr = go.AddComponent<MeshRenderer>();
        //mr.sharedMaterial = spriteRenderer.sharedMaterial;

        // Check if the Meshes directory exists, if not, create it.
        DirectoryInfo meshDir = new DirectoryInfo("Assets/Meshes");

        if (Directory.Exists(meshDir.FullName) == false)
        {
            Directory.CreateDirectory(meshDir.FullName);
        }
        ScriptableObjectUtility.CreateAsset(mesh, "Meshes/" + spriteRenderer.gameObject.name + ".Mesh");
    }
コード例 #26
0
    public void SubdivideMesh(int divisions)
    {
        if (spriteRenderer != null && points.Length > 2)
        {
            // Unparent the skin temporarily before adding the mesh
            Transform polygonParent = spriteRenderer.transform.parent;
            spriteRenderer.transform.parent = null;

            // Reset the rotation before creating the mesh so the UV's will align properly
            Quaternion localRotation = spriteRenderer.transform.localRotation;
            spriteRenderer.transform.localRotation = Quaternion.identity;

            // Reset the scale before creating the mesh so the UV's will align properly
            Vector3 localScale = spriteRenderer.transform.localScale;
            spriteRenderer.transform.localScale = Vector3.one;

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(points.Length);

            //Add vertices
            foreach (Vector2 point in points)
            {
                geometry.AddPoint(point.x, point.y);
            }

            int N   = geometry.Count;
            int end = 0;
            //Add vertices
            foreach (Vector2 point in points)
            {
                geometry.AddPoint(point.x, point.y);
                end++;
            }

            for (int i = 0; i < end; i++)
            {
                geometry.AddSegment(N + i, N + ((i + 1) % end));
            }

            //Triangulate and subdivide the mesh
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            if (divisions > 0)
            {
                triangleMesh.behavior.MinAngle = 10;
            }

            triangleMesh.Triangulate(geometry);
            if (divisions > 0)
            {
                if (divisions > 1)
                {
                    triangleMesh.Refine(true);
                }
                TriangleNet.Tools.Statistic stat = new TriangleNet.Tools.Statistic();
                stat.Update(triangleMesh, 1);
                // Refine by area
                if (divisions > 2)
                {
                    triangleMesh.Refine(stat.LargestArea / 8);
                }

                try {
                    triangleMesh.Smooth();
                } catch {
                    //Debug.Log("Cannot subdivide");
                }
                triangleMesh.Renumber();
            }

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector2[] uvs      = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] normals  = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach (TriangleNet.Data.Vertex v in triangleMesh.Vertices)
            {
                points[n]   = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n]  = new Vector3(0, 0, -1);
                n++;
            }

            //transform triangles
            int[] triangles = new int[triangleMesh.Triangles.Count * 3];
            n = 0;
            foreach (TriangleNet.Data.Triangle t in triangleMesh.Triangles)
            {
                triangles[n++] = t.P1;
                triangles[n++] = t.P0;
                triangles[n++] = t.P2;
            }

            mesh.Clear();
            mesh           = new Mesh();
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.uv        = genUV(mesh.vertices);
            mesh.normals   = normals;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            // Reset the rotations of the object
            spriteRenderer.transform.localRotation = localRotation;
            spriteRenderer.transform.localScale    = localScale;
            spriteRenderer.transform.parent        = polygonParent;

            meshCreated = true;
        }
    }
コード例 #27
0
ファイル: Slice.cs プロジェクト: JackTing/PathCAM
        /// <summary>
        /// Get a list of triangles which will fill the area described by the slice
        /// </summary>
        public IEnumerable<Triangle> Triangles()
        {
            TriangleNet.Behavior behavior = new TriangleNet.Behavior();
            behavior.ConformingDelaunay = true;

            foreach (var poly in IndividualPolygons())
            {
                PolyNode node = polyTree.GetFirst();
                InputGeometry geometry = new InputGeometry();
                while (node != null)
                {
                    var offset = geometry.Points.Count();
                    var index = 0;
                    foreach (IntPoint point in node.Contour)
                    {
                        geometry.AddPoint(point.X, point.Y);
                        if (index > 0)
                        {
                            geometry.AddSegment(index - 1 + offset, index + offset);
                        }
                        index++;
                    }
                    geometry.AddSegment(index - 1 + offset, offset);

                    if (node.IsHole)
                    {
                        // To describe a hole, AddHole must be called with a location inside the hole.
                        IntPoint last = new IntPoint(0, 0);
                        bool lastKnown = false;
                        double longest = 0;
                        IntPoint longestAlong = new IntPoint(0, 0);
                        IntPoint from = new IntPoint(0, 0);
                        foreach (IntPoint point in node.Contour)
                        {
                            if (lastKnown)
                            {
                                IntPoint along = new IntPoint(point.X - last.X, point.Y - last.Y);
                                double length = Math.Sqrt(along.X * along.X + along.Y * along.Y);
                                if (length > longest)
                                {
                                    longest = length;
                                    longestAlong = along;
                                    from = last;
                                }
                            }
                            last = point;
                            lastKnown = true;
                        }
                        if (longest > 0)
                        {
                            double perpendicularX = ((double)longestAlong.Y * (double)scale * 0.001d) / longest;
                            double perpendicularY = -((double)longestAlong.X * (double)scale * 0.001d) / longest;
                            geometry.AddHole(perpendicularX + from.X + longestAlong.X / 2.0d,
                                perpendicularY + from.Y + longestAlong.Y / 2.0d);
                        }
                        else
                        {
                        }
                    }
                    node = node.GetNext();
                }

                if (geometry.Points.Count() > 0)
                {
                    var mesh = new TriangleNet.Mesh(behavior);
                    mesh.Triangulate(geometry);
                    mesh.Renumber();
                    foreach (Triangle t in this.GetMeshTriangles(mesh))
                    {
                        yield return t;
                    }
                }
            }
        }
コード例 #28
0
        public static void Tessellate(List <Vector2> vertices, List <IndexedEdge> indexedEdges, List <Hole> holes, List <int> indices, float tessellationAmount)
        {
            if (tessellationAmount <= 0f)
            {
                return;
            }

            indices.Clear();

            if (vertices.Count >= 3)
            {
                InputGeometry inputGeometry = new InputGeometry(vertices.Count);

                for (int i = 0; i < vertices.Count; ++i)
                {
                    Vector2 vertex = vertices[i];
                    inputGeometry.AddPoint(vertex.x, vertex.y);
                }

                for (int i = 0; i < indexedEdges.Count; ++i)
                {
                    IndexedEdge edge = indexedEdges[i];
                    inputGeometry.AddSegment(edge.index1, edge.index2);
                }

                for (int i = 0; i < holes.Count; ++i)
                {
                    Vector2 hole = holes[i].vertex;
                    inputGeometry.AddHole(hole.x, hole.y);
                }

                TriangleNet.Mesh            triangleMesh = new TriangleNet.Mesh();
                TriangleNet.Tools.Statistic statistic    = new TriangleNet.Tools.Statistic();

                triangleMesh.Triangulate(inputGeometry);

                triangleMesh.Behavior.MinAngle      = 20.0;
                triangleMesh.Behavior.SteinerPoints = -1;
                triangleMesh.Refine(true);

                statistic.Update(triangleMesh, 1);

                triangleMesh.Refine(statistic.LargestArea / tessellationAmount);
                triangleMesh.Renumber();

                vertices.Clear();
                indexedEdges.Clear();

                foreach (TriangleNet.Data.Vertex vertex in triangleMesh.Vertices)
                {
                    vertices.Add(new Vector2((float)vertex.X, (float)vertex.Y));
                }

                foreach (TriangleNet.Data.Segment segment in triangleMesh.Segments)
                {
                    indexedEdges.Add(new IndexedEdge(segment.P0, segment.P1));
                }

                foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles)
                {
                    if (triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
                        triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
                        triangle.P0 >= 0 && triangle.P2 < vertices.Count)
                    {
                        indices.Add(triangle.P0);
                        indices.Add(triangle.P2);
                        indices.Add(triangle.P1);
                    }
                }
            }
        }
コード例 #29
0
        protected void GenerateTrisForShape()
        {
            if (vertices.Length >= 6 && vertices.Length % 2 == 0)
            {
                InputGeometry bottomGeometry = new InputGeometry();
                List <Point>  shape          = new List <Point> ();
                int           halfVertLen    = vertices.Length / 2;
                for (int i = 0; i < halfVertLen; i++)
                {
                    shape.Add(new Point(vertices[i].x, vertices[i].z));
                }
                bottomGeometry.AddRing(shape);

                TriangleNet.Mesh bottomMesh = new TriangleNet.Mesh();
                bottomMesh.Triangulate(bottomGeometry);

                List <Vector3> verts           = new List <Vector3>(bottomMesh.triangles.Count * 3);
                List <int>     triangleIndices = new List <int>(bottomMesh.triangles.Count * 3);
                foreach (KeyValuePair <int, TriangleNet.Data.Triangle> pair in bottomMesh.triangles)
                {
                    TriangleNet.Data.Triangle triangle = pair.Value;

                    TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0);
                    TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1);
                    TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2);

                    Vector3 p0 = new Vector3(vertex0.x, 0, vertex0.y);
                    Vector3 p1 = new Vector3(vertex1.x, 0, vertex1.y);
                    Vector3 p2 = new Vector3(vertex2.x, 0, vertex2.y);

                    verts.Add(p0);
                    verts.Add(p1);
                    verts.Add(p2);

                    triangleIndices.Add(GetIndexForVertex(p0));
                    triangleIndices.Add(GetIndexForVertex(p1));
                    triangleIndices.Add(GetIndexForVertex(p2));
                }

                // Create top Side
                List <int> triangleIndecesReversed = new List <int>();
                for (int i = triangleIndices.Count - 1; i >= 0; i--)
                {
                    triangleIndecesReversed.Add(triangleIndices[i] + halfVertLen);
                }
                triangleIndices.AddRange(triangleIndecesReversed);

                // Add edges
                List <int> edgeIndeces = new List <int>();
                for (int i = 0; i < halfVertLen; i++)
                {
                    int leftBottom  = i;
                    int rightBottom = (i == halfVertLen - 1 ? 0 : i + 1);
                    int leftTop     = i + halfVertLen;
                    int rightTop    = (i == halfVertLen - 1 ? halfVertLen : i + halfVertLen + 1);

                    edgeIndeces.Add(leftTop);
                    edgeIndeces.Add(rightTop);
                    edgeIndeces.Add(leftBottom);

                    edgeIndeces.Add(rightBottom);
                    edgeIndeces.Add(leftBottom);
                    edgeIndeces.Add(rightTop);
                }
                triangleIndices.AddRange(edgeIndeces);

                tris = triangleIndices.ToArray();
            }
            else
            {
                Debug.LogError("[BaseShape.GenerateTrisForShape] Invalid vertices set for shape!");
            }
        }