Beispiel #1
0
    public static void renderTree(ClipperLib.PolyNode node, List <Vector3> verts, List <Vector3> norms, List <Vector2> uvs, List <int> faces, ref int idx)
    {
        Poly2Tri.Polygon p = new Poly2Tri.Polygon(node.Contour.ConvertAll <Poly2Tri.PolygonPoint>(PP));
        //p.RemoveDuplicateNeighborPoints();
        //p.MergeParallelEdges(1e-3);

        foreach (ClipperLib.PolyNode child in node.Childs)
        {
            if (child.IsHole)
            {
                Poly2Tri.Polygon h = new Poly2Tri.Polygon(child.Contour.ConvertAll <Poly2Tri.PolygonPoint>(PP));
                h.RemoveDuplicateNeighborPoints();
                h.MergeParallelEdges(1e-3);

                p.AddHole(h);
            }
            else
            {
                renderTree(child, verts, norms, uvs, faces, ref idx);
            }
        }

        Poly2Tri.DTSweepContext ctx = new Poly2Tri.DTSweepContext();
        ctx.PrepareTriangulation(p);
        Poly2Tri.DTSweep.Triangulate(ctx);

        foreach (Poly2Tri.DelaunayTriangle dt in p.Triangles)
        {
            faces.Add(idx); uvs.Add(UV(dt.Points[2])); norms.Add(Vector3.back); verts.Add(V3(dt.Points[2])); idx++;
            faces.Add(idx); uvs.Add(UV(dt.Points[1])); norms.Add(Vector3.back); verts.Add(V3(dt.Points[1])); idx++;
            faces.Add(idx); uvs.Add(UV(dt.Points[0])); norms.Add(Vector3.back); verts.Add(V3(dt.Points[0])); idx++;
        }
    }
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
	public  static List<int> GetIndices           (ref List<Vector2> aPoints, bool aTreatAsPath, bool aInvert, float aVertGridSpacing = 0) {
		
		Vector4 bounds = GetBounds(aPoints);
		
        if (aVertGridSpacing > 0) {
            SplitEdges(ref aPoints, aVertGridSpacing);
        }

		List<PolygonPoint> verts = new List<PolygonPoint>(aPoints.Count);
		for (int i = 0; i < aPoints.Count; i++) {
			verts.Add(new PolygonPoint( aPoints[i].x, aPoints[i].y));
		}

		Polygon poly;
		if (aInvert) {
			aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 4
			aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 3
			aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 2
			aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 1
			List<PolygonPoint> outer = new List<PolygonPoint>(4);
			for (int i = 0; i < 4; i++) {
				outer.Add( new PolygonPoint( aPoints[(aPoints.Count - 4) + i].x, aPoints[(aPoints.Count - 4) + i].y) );
			}
			poly = new Polygon(outer);
			poly.AddHole(new Polygon(verts));
		} else {
			poly = new Polygon(verts);
		}
		
		if (aVertGridSpacing > 0) {
			if (aInvert) bounds = GetBounds(aPoints);
			for (float y = bounds.w + aVertGridSpacing; y <= bounds.y; y+=aVertGridSpacing) {
				for (float x = bounds.x + aVertGridSpacing; x <= bounds.z; x+=aVertGridSpacing) {
					TriangulationPoint pt     = new TriangulationPoint(x, y);
					bool               inside = poly.IsPointInside(pt);
					if (inside) poly.AddSteinerPoint(pt);
				}
			}
		}
		P2T.Triangulate(poly);
		 
		aPoints.Clear();
		List<int> result= new List<int>(poly.Triangles.Count * 3);
		int       ind   = 0;
		foreach (DelaunayTriangle triangle in poly.Triangles) {
			TriangulationPoint p1 = triangle.Points[0];
			TriangulationPoint p2 = triangle.PointCWFrom(p1);
			TriangulationPoint p3 = triangle.PointCWFrom(p2);
			
			aPoints.Add(new Vector2(p1.Xf, p1.Yf));
			aPoints.Add(new Vector2(p2.Xf, p2.Yf));
			aPoints.Add(new Vector2(p3.Xf, p3.Yf));
			result.Add(ind++);
			result.Add(ind++);
			result.Add(ind++);
		}
		return result;
	}
        private void DrawFill(List <Vector> fillVertices)
        {
            if (m_mesh.Vertices.Count <= 2 || m_mesh.FillMode == FillMode.None || m_mesh.UvMapping.FillTexture == null)
            {
                return;
            }

            if (!m_mesh.IsClosed)
            {
                fillVertices.Add(m_mesh.FillMode != FillMode.Inverted ? m_mesh.Vertices.Last().Position : m_mesh.Vertices.First().Position);
            }


            var polygon = new Polygon(fillVertices.Select(v => new PolygonPoint(v.X, v.Y)));

            if (IsInverted)
            {
                var center = polygon.GetCentroid();
                var size   = new Size(polygon.BoundingBox.Width, polygon.BoundingBox.Height);

                var topLeft     = new Point(center.X - size.Width, center.Y + size.Height);
                var topRight    = new Point(center.X + size.Width, center.Y + size.Height);
                var bottomLeft  = new Point(center.X - size.Width, center.Y - size.Height);
                var bottomRight = new Point(center.X + size.Width, center.Y - size.Height);

                var invertedPolygon = new Polygon(
                    new PolygonPoint(bottomLeft.X, bottomLeft.Y),
                    new PolygonPoint(topLeft.X, topLeft.Y),
                    new PolygonPoint(topRight.X, topRight.Y),
                    new PolygonPoint(bottomRight.X, bottomRight.Y));

                invertedPolygon.AddHole(polygon);

                polygon = invertedPolygon;
            }

            try
            {
                P2T.Triangulate(polygon);
            }
            catch (Exception)
            {
                return;
            }

            var unitsPerFill = CalculateUnitsPerFillUv();

            foreach (var triangle in polygon.Triangles)
            {
                MeshFillData.AddTriangle(
                    new Point3D(triangle.Points._0.X, triangle.Points._0.Y, 0.0),
                    new Point3D(triangle.Points._1.X, triangle.Points._1.Y, 0.0),
                    new Point3D(triangle.Points._2.X, triangle.Points._2.Y, 0.0),
                    new Point(triangle.Points._0.X / unitsPerFill.X, triangle.Points._0.Y / unitsPerFill.Y),
                    new Point(triangle.Points._1.X / unitsPerFill.X, triangle.Points._1.Y / unitsPerFill.Y),
                    new Point(triangle.Points._2.X / unitsPerFill.X, triangle.Points._2.Y / unitsPerFill.Y));
            }
        }
 static Polygon CleanClone(Polygon polygon)
 {
     var n = new Polygon(polygon.Points.Select(p => new PolygonPoint(p.X, p.Y)));
     if (polygon.Holes != null)
     {
         foreach (var hole in polygon.Holes)
         {
             n.AddHole(CleanClone(hole));
         }
     }
     return n;
 }
Beispiel #5
0
        static Polygon CleanClone(Polygon polygon)
        {
            var n = new Polygon(polygon.Points.Select(p => new PolygonPoint(p.X, p.Y)));

            if (polygon.Holes != null)
            {
                foreach (var hole in polygon.Holes)
                {
                    n.AddHole(CleanClone(hole));
                }
            }
            return(n);
        }
        public List<DelaunayTriangle> TriangulateComplex(
         PolyTree polyTree,
         bool ignoreFills = false, bool ignoreHoles = true)
        {
            PolyNode rootNode;
             if (polyTree.Total == 0) {
            Console.WriteLine(0);
            rootNode = new PolyNode();
             } else {
            rootNode = polyTree.GetFirst().Parent;
             }

             // Equivalent to rootNode.Contour = bounds;
             var contourField = rootNode.GetType().GetField("m_polygon", BindingFlags.Instance | BindingFlags.NonPublic);
             if (contourField == null) {
            throw new Exception("Could not find field contour backing field.");
             }
             contourField.SetValue(rootNode, kTriangulatorBounds);

             var result = new List<DelaunayTriangle>();
             int i = 0;
             for (var currentNode = rootNode; currentNode != null; currentNode = currentNode.GetNext()) {
            if ((ignoreHoles && currentNode.IsHole) || (ignoreFills && !currentNode.IsHole)) continue;
            var polyline = DownscalePolygon(currentNode.Contour);
            var finalPolygon = new Polygon(polyline);
            foreach (var child in currentNode.Childs) {
               var shrunkContour = EdgeShrink(child.Contour);
               var holePoints = DownscalePolygon(shrunkContour);
               var holePoly = new Polygon(holePoints);
               finalPolygon.AddHole(holePoly);
            }
            P2T.Triangulate(finalPolygon);
            result.AddRange(finalPolygon.Triangles);
             }
             return result;
        }
Beispiel #7
0
        protected override Polygon GetPolygon()
        {
            Polygon poly = new Polygon(GetPoints());

            if (thickness > 1)
            {
                List<PolygonPoint> points = GetPoints();
                Vector2 center = GetCentroid(points);
                float[] angles = { AngleA(a, b, c), AngleB(a, b, c), AngleC(a, b, c) };
                int count = points.Count;

                for (int i = count; --i >= 0;)
                {
                    PolygonPoint point = points[i];

                    double vecX = center.X - point.X;
                    double vecY = center.Y - point.Y;
                    double invLen = 1d / Math.Sqrt((vecX * vecX) + (vecY * vecY));
                    vecX = vecX * invLen;
                    vecY = vecY * invLen;

                    float ratio = 1 - (angles[i] / 180);
                    float angleThickness = ratio * thickness;
                    point.X += vecX * angleThickness;
                    point.Y += vecY * angleThickness;
                }

                Polygon hole = new Polygon(points);
                poly.AddHole(hole);
            }

            return poly;
        }
Beispiel #8
0
    /// <summary>
    /// Create a Mesh from a given Polygon.
    /// </summary>
    /// <returns>The freshly minted mesh.</returns>
    /// <param name="polygon">Polygon you want to triangulate.</param>
    public static Mesh CreateMesh(Polygon polygon)
    {
        // Ensure we have the rotation properly calculated
        if (polygon.rotation == Quaternion.identity) polygon.CalcRotation();

        // Rotate 1 point and note where it ends up in Z
        float z = (polygon.rotation * polygon.outside[0]).z;

        // Convert the outside points (throwing out Z at this point)
        Poly2Tri.Polygon poly = new Poly2Tri.Polygon(ConvertPoints(polygon.outside, polygon.rotation));

        // Convert each of the holes
        foreach (List<Vector3> hole in polygon.holes) {
            poly.AddHole(new Poly2Tri.Polygon(ConvertPoints(hole, polygon.rotation)));
        }

        // Triangulate it!  Note that this may throw an exception if the data is bogus.
        DTSweepContext tcx = new DTSweepContext();
        tcx.PrepareTriangulation(poly);
        DTSweep.Triangulate(tcx);
        tcx = null;

        // Create the Vector3 vertices (undoing the rotation),
        // and also build a map of vertex codes to indices
        Quaternion invRot = Quaternion.Inverse(polygon.rotation);
        Dictionary<uint, int> codeToIndex = new Dictionary<uint, int>();
        List<Vector3> vertexList = new List<Vector3>();
        foreach (DelaunayTriangle t in poly.Triangles) {
            foreach (var p in t.Points) {
                if (codeToIndex.ContainsKey(p.VertexCode)) continue;
                codeToIndex[p.VertexCode] = vertexList.Count;
                Vector3 pos = new Vector3(p.Xf, p.Yf, z);	// (restore the Z we saved earlier)
                vertexList.Add(invRot * pos);
            }
        }

        // Create the indices array
        int[] indices = new int[poly.Triangles.Count * 3];
        {
            int i = 0;
            foreach (DelaunayTriangle t in poly.Triangles) {
                indices[i++] = codeToIndex[t.Points[0].VertexCode];
                indices[i++] = codeToIndex[t.Points[1].VertexCode];
                indices[i++] = codeToIndex[t.Points[2].VertexCode];
            }
        }

        // Create the UV list, by looking up the closest point for each in our poly
        Mesh msh = new Mesh();
        msh.vertices = vertexList.ToArray();
        Vector2[] uvs = new Vector2[msh.vertices.Length];
        for (int i=0; i < uvs.Length; i++) {
            uvs[i] = new Vector2(msh.vertices[i].x, msh.vertices[i].y);
        }
        msh.uv = uvs;
        /*if (polygon.OutsideUVs != null) {
            uv = new Vector2[vertexList.Count];
            for (int i=0; i<vertexList.Count; i++) {
                uv[i] = polygon.ClosestUV(vertexList[i]);
            }
        }*/

        // Create the mesh

        msh.triangles = indices;
        msh.RecalculateNormals();
        msh.RecalculateBounds();
        return msh;
    }
Beispiel #9
0
    static bool TryInsertHole(Polygon parent, Polygon hole)
    {
        //Can't go in.
        if (!parent.IsPointInside(hole[0]))
            return false;

        if (parent.Holes != null)
            foreach (var item in parent.Holes)
            {
                if (TryInsertHole(item, hole))
                    return true;
            }
        //it doesn't fit into any of the daughter holes.
        parent.AddHole(hole);
        return true;
    }
Beispiel #10
0
        protected override Polygon GetPolygon()
        {
            Polygon poly = new Polygon( GetPoints() );

            if( thickness > 0 )
            {
                List<PolygonPoint> holePoints = new List<PolygonPoint>();

                float x;
                float y;
                float radAngle;
                float degreeStep = 360f / sides;
                float r = radius - thickness;

                for( int i = 0; i < sides; i++ )
                {
                    radAngle = MathUtil.DegreesToRadians( degreeStep * i );
                    x = (float)( Math.Cos( radAngle ) * r );
                    y = (float)( Math.Sin( radAngle ) * r );

                    holePoints.Add( new PolygonPoint( x, y ) );
                }

                Polygon hole = new Polygon( holePoints );
                poly.AddHole( hole );
            }

            return poly;
        }
Beispiel #11
0
        /// <summary>
        /// triangulate polygon, algorithm from wiki is fast enough
        /// http://wiki.unity3d.com/index.php?title=Triangulator
        /// </summary>
        /// <returns></returns>
        public List<int> Triangulate()
        {
            // no holes supported
            if (holes.Count == 0)
            {
                var indices = new List<int>(Points.Length);

                int n = Points.Length;
                if (n < 3)
                    return indices;

                var V = new int[n];
                if (Area > 0)
                {
                    for (int v = 0; v < n; v++)
                        V[v] = v;
                }
                else
                {
                    for (int v = 0; v < n; v++)
                        V[v] = (n - 1) - v;
                }

                int nv = n;
                int count = 2*nv;
                for (int m = 0, v = nv - 1; nv > 2;)
                {
                    if ((count--) <= 0)
                        return indices;

                    int u = v;
                    if (nv <= u)
                        u = 0;
                    v = u + 1;
                    if (nv <= v)
                        v = 0;
                    int w = v + 1;
                    if (nv <= w)
                        w = 0;

                    if (Snip(u, v, w, nv, V))
                    {
                        int a, b, c, s, t;
                        a = V[u];
                        b = V[v];
                        c = V[w];
                        indices.Add(a);
                        indices.Add(b);
                        indices.Add(c);
                        m++;
                        for (s = v, t = v + 1; t < nv; s++, t++)
                            V[s] = V[t];
                        nv--;
                        count = 2*nv;
                    }
                }

                indices.Reverse();
                return indices;
            }
            else
            {
                // use poly2tri library to triangulate mesh with holes

                var p2tPoints = new List<Poly2Tri.PolygonPoint>(Points.Length);

                foreach (var point in Points)
                {
                    p2tPoints.Add(new Poly2Tri.PolygonPoint(point.x, point.y));
                }

                // create p2t polygon
                var p2tPolygon = new Poly2Tri.Polygon(p2tPoints);

                // add holes
                foreach (var polygonHole in holes)
                {
                    var p2tHolePoints = new List<Poly2Tri.PolygonPoint>(polygonHole.Points.Length);

                    foreach (var polygonPoint in polygonHole.Points)
                    {
                        p2tHolePoints.Add(new Poly2Tri.PolygonPoint(polygonPoint.x, polygonPoint.y));
                    }

                    p2tPolygon.AddHole(new Poly2Tri.Polygon(p2tHolePoints));
                }

                try
                {
                    Poly2Tri.P2T.Triangulate(p2tPolygon);
                }
                catch (Exception ex)
                {
                    ExploderUtils.Log("P2T Exception: " + ex);
                    return null;
                }

                var triangles = p2tPolygon.Triangles.Count;

                var indices = new List<int>(triangles*3);
                Points = new Vector2[triangles*3];
                var j = 0;

                // recalc min max
                Min.x = float.MaxValue;
                Min.y = float.MaxValue;
                Max.x = float.MinValue;
                Max.y = float.MinValue;

                for (int i = 0; i < triangles; i++)
                {
                    indices.Add((j + 0));
                    indices.Add((j + 1));
                    indices.Add((j + 2));

                    Points[j + 2].x = (float)p2tPolygon.Triangles[i].Points._0.X;
                    Points[j + 2].y = (float)p2tPolygon.Triangles[i].Points._0.Y;

                    Points[j + 1].x = (float)p2tPolygon.Triangles[i].Points._1.X;
                    Points[j + 1].y = (float)p2tPolygon.Triangles[i].Points._1.Y;

                    Points[j + 0].x = (float)p2tPolygon.Triangles[i].Points._2.X;
                    Points[j + 0].y = (float)p2tPolygon.Triangles[i].Points._2.Y;

                    // recalc min max
                    for (int k = 0; k < 3; k++)
                    {
                        if (Points[j + k].x < Min.x)
                        {
                            Min.x = Points[j + k].x;
                        }
                        if (Points[j + k].y < Min.y)
                        {
                            Min.y = Points[j + k].y;
                        }
                        if (Points[j + k].x > Max.x)
                        {
                            Max.x = Points[j + k].x;
                        }
                        if (Points[j + k].y > Max.y)
                        {
                            Max.y = Points[j + k].y;
                        }
                    }

                    j += 3;
                }

                return indices;
            }
        }
Beispiel #12
0
    public static Mesh CreateXYMesh(Polygon polygon)
    {
        //AML Maybe pass this as arg and reduce coords to XY
        float z = polygon.outside[0].z;

        // Check for the easy case (a triangle)
        if (polygon.holes.Count == 0 && (polygon.outside.Count == 3 ||
                                         (polygon.outside.Count == 4 && polygon.outside[3] == polygon.outside[0])))
        {
            return(CreateTriangle(polygon));
        }
        // Convert the outside points (throwing out Z at this point)
        Poly2Tri.Polygon poly = new Poly2Tri.Polygon(ConvertPoints(polygon.outside));
        // Convert each of the holes
        foreach (List <Vector3> hole in polygon.holes)
        {
            poly.AddHole(new Poly2Tri.Polygon(ConvertPoints(hole)));
        }
        // Triangulate it!  Note that this may throw an exception if the data is bogus.
        try {
            DTSweepContext tcx = new DTSweepContext();
            tcx.PrepareTriangulation(poly);
            DTSweep.Triangulate(tcx);
            tcx = null;
        } catch (System.Exception e) {
            //Profiler.Exit(profileID);
            throw e;
        }
        // Create the indices array
        Dictionary <uint, int> codeToIndex = new Dictionary <uint, int>();
        List <Vector3>         vertexList  = new List <Vector3>();

        foreach (DelaunayTriangle t in poly.Triangles)
        {
            foreach (var p in t.Points)
            {
                if (codeToIndex.ContainsKey(p.VertexCode))
                {
                    continue;
                }
                codeToIndex[p.VertexCode] = vertexList.Count;
                vertexList.Add(new Vector3(p.Xf, p.Yf, z));
            }
        }
        int[] indices = new int[poly.Triangles.Count * 3];
        {
            int i = 0;
            foreach (DelaunayTriangle t in poly.Triangles)
            {
                indices[i++] = codeToIndex[t.Points[0].VertexCode];
                indices[i++] = codeToIndex[t.Points[1].VertexCode];
                indices[i++] = codeToIndex[t.Points[2].VertexCode];
            }
        }

        // Create the UV list, by looking up the closest point for each in our poly
        Vector2[] uv = null;
        if (polygon.outsideUVs != null)
        {
            uv = new Vector2[vertexList.Count];
            for (int i = 0; i < vertexList.Count; i++)
            {
                uv[i] = polygon.ClosestUV(vertexList[i]);
            }
        }

        // Create the mesh
        Mesh msh = new Mesh();

        msh.vertices  = vertexList.ToArray();
        msh.triangles = indices;
        msh.uv        = uv;
        msh.RecalculateNormals();
        msh.RecalculateBounds();
        return(msh);
    }
Beispiel #13
0
        private List<Polygon> TriangulatePolyTree(PolyTree tree)
        {
            List<Polygon> polygonsGenerated = new List<Polygon>();
            List<PolygonPoint> AllPoints = new List<PolygonPoint>();
            foreach (PolyNode islands in tree.Childs)
            {
                List<PolygonPoint> floorPoints = new List<PolygonPoint>();
                foreach (IntPoint point in SubdividePolygon(islands.Contour))
                {
                    floorPoints.Add(new PolygonPoint(point.X / GenerationInformation.CalculationScaleFactor, point.Y / GenerationInformation.CalculationScaleFactor));
                }

                AllPoints.AddRange(floorPoints);
                Polygon floorPolygon = new Polygon(floorPoints);

                foreach (PolyNode nextNode in islands.Childs)
                {
                    if (nextNode.IsHole)
                    {
                        List<PolygonPoint> holePoints = new List<PolygonPoint>();
                        foreach (IntPoint point in SubdividePolygon(nextNode.Contour))
                        {
                            holePoints.Add(new PolygonPoint(point.X / GenerationInformation.CalculationScaleFactor, point.Y / GenerationInformation.CalculationScaleFactor));
                        }
                        AllPoints.AddRange(holePoints);
                        floorPolygon.AddHole(new Polygon(holePoints));
                    }
                }
                if (GenerationInformation.UseGrid)
                {
                    List<TriangulationPoint> steinerPoints = new List<TriangulationPoint>();
                    for (float x = (float)floorPolygon.BoundingBox.MinX - ((float)floorPolygon.BoundingBox.MinX % GenerationInformation.GridSize.x); x < floorPolygon.BoundingBox.MaxX; x += GenerationInformation.GridSize.x)
                    {
                        for (float y = (float)floorPolygon.BoundingBox.MinY - ((float)floorPolygon.BoundingBox.MinY % GenerationInformation.GridSize.y); y < floorPolygon.BoundingBox.MaxY; y += GenerationInformation.GridSize.y)
                        {
                            TriangulationPoint p = new TriangulationPoint(x, y);
                            if (floorPolygon.IsPointInside(p))
                                steinerPoints.Add(p);
                        }
                    }

                    CullSteinerPoints(ref steinerPoints, AllPoints, 0.1f);

                    floorPolygon.AddSteinerPoints(steinerPoints);
                }

                floorPolygon.Prepare(P2T.CreateContext(TriangulationAlgorithm.DTSweep));
                P2T.Triangulate(floorPolygon);
                polygonsGenerated.Add(floorPolygon);

            }

            return polygonsGenerated;
        }
Beispiel #14
0
        protected virtual Polygon GetPolygon()
        {
            Polygon poly = new Polygon(GetPoints());

            if (thickness > 0)
            {
                Polygon hole = new Polygon(GetPoints(thickness));
                poly.AddHole(hole);
            }

            return poly;
        }
Beispiel #15
0
    /// <summary>
    /// Create a Mesh from a given Polygon.
    /// </summary>
    /// <returns>The freshly minted mesh.</returns>
    /// <param name="polygon">Polygon you want to triangulate.</param>
    public static Mesh CreateMesh(Polygon polygon)
    {
        // Ensure we have the rotation properly calculated
        if (polygon.rotation == Quaternion.identity)
        {
            polygon.CalcRotation();
        }

        // Rotate 1 point and note where it ends up in Z
        float z = (polygon.rotation * polygon.outside[0]).z;

        // Convert the outside points (throwing out Z at this point)
        Poly2Tri.Polygon poly = new Poly2Tri.Polygon(ConvertPoints(polygon.outside, polygon.rotation));

        // Convert each of the holes
        foreach (List <Vector3> hole in polygon.holes)
        {
            poly.AddHole(new Poly2Tri.Polygon(ConvertPoints(hole, polygon.rotation)));
        }

        // Triangulate it!  Note that this may throw an exception if the data is bogus.
        DTSweepContext tcx = new DTSweepContext();

        tcx.PrepareTriangulation(poly);
        DTSweep.Triangulate(tcx);
        tcx = null;

        // Create the Vector3 vertices (undoing the rotation),
        // and also build a map of vertex codes to indices
        Quaternion             invRot      = Quaternion.Inverse(polygon.rotation);
        Dictionary <uint, int> codeToIndex = new Dictionary <uint, int>();
        List <Vector3>         vertexList  = new List <Vector3>();

        foreach (DelaunayTriangle t in poly.Triangles)
        {
            foreach (var p in t.Points)
            {
                if (codeToIndex.ContainsKey(p.VertexCode))
                {
                    continue;
                }
                codeToIndex[p.VertexCode] = vertexList.Count;
                Vector3 pos = new Vector3(p.Xf, p.Yf, z);                       // (restore the Z we saved earlier)
                vertexList.Add(invRot * pos);
            }
        }

        // Create the indices array
        int[] indices = new int[poly.Triangles.Count * 3];
        {
            int i = 0;
            foreach (DelaunayTriangle t in poly.Triangles)
            {
                indices[i++] = codeToIndex[t.Points[0].VertexCode];
                indices[i++] = codeToIndex[t.Points[1].VertexCode];
                indices[i++] = codeToIndex[t.Points[2].VertexCode];
            }
        }

        // Create the UV list, by looking up the closest point for each in our poly
        Vector2[] uv = null;
//		if (polygon.outsideUVs != null) {
//			uv = new Vector2[vertexList.Count];
//			for (int i=0; i<vertexList.Count; i++) {
//				uv[i] = polygon.ClosestUV(vertexList[i]);
//			}
//		}

        // Create the mesh
        Mesh msh = new Mesh();

        msh.vertices  = vertexList.ToArray();
        msh.triangles = indices;
        msh.uv        = uv;
        msh.RecalculateNormals();
        msh.RecalculateBounds();
        return(msh);
    }
        public void UpdateNavigationMesh()
        {
            var visitedBlockedCells = new HashSet<NavigationGridletCell>();
             var blobs = new List<List<NavigationGridletCell>>();
             foreach (var cell in Cells) {
            if (!cell.Flags.HasFlag(CellFlags.Blocked)) {
               continue;
            }
            if (visitedBlockedCells.Contains(cell)) {
               continue;
            }

            var s = new Stack<NavigationGridletCell>();
            s.Push(cell);
            var blob = new List<NavigationGridletCell>();
            while (s.Any()) {
               var node = s.Pop();
               blob.Add(node);
               visitedBlockedCells.Add(node);
               var derps = new List<NavigationGridletCell>();
               if (node.X > 0) {
                  derps.Add(node.Gridlet.Cells[node.Index - 1]);
               }
               if (node.X < node.Gridlet.XLength - 1) {
                  derps.Add(node.Gridlet.Cells[node.Index + 1]);
               }
               if (node.Y > 0) {
                  derps.Add(node.Gridlet.Cells[node.Index - node.Gridlet.XLength]);
               }
               if (node.Y < node.Gridlet.YLength - 1) {
                  derps.Add(node.Gridlet.Cells[node.Index + node.Gridlet.XLength]);
               }
               var blockedNeighbors = derps.Where(n => n.Flags.HasFlag(CellFlags.Blocked)).ToArray();
               blockedNeighbors.Where(n => !visitedBlockedCells.Contains(n)).ForEach(s.Push);
            }
            blobs.Add(blob);
             }

             // derp
             var cps = new Polygon(new List<PolygonPoint> {
            new PolygonPoint(-XLength / 2.0f - 5, -YLength / 2.0f - 5),
            new PolygonPoint(XLength / 2.0f + 5, -YLength / 2.0f - 5),
            new PolygonPoint(XLength / 2.0f + 5, YLength / 2.0f + 5),
            new PolygonPoint(-XLength / 2.0f - 5, YLength / 2.0f + 5)
             });

             foreach (var blob in blobs) {
            var chull = GeometryUtilities.ConvexHull(blob.SelectMany(x => new[] { new ItzWarty.Geometry.Point2D(x.X, x.Y), new ItzWarty.Geometry.Point2D(x.X + 1, x.Y), new ItzWarty.Geometry.Point2D(x.X + 1, x.Y + 1), new ItzWarty.Geometry.Point2D(x.X, x.Y + 1) }).ToArray());
            cps.AddHole(
               new Polygon(
                  chull.Select(p => new PolygonPoint(p.X - XLength / 2.0f, p.Y - YLength / 2.0f)).ToArray()
               )
            );
             }

             var handledNeighborCells = new HashSet<NavigationGridletCell>();
             foreach (var edgeCell in EdgeCells.Where(x => x.Flags.HasFlag(CellFlags.Connector))) {
            var thisObb = this.OrientedBoundingBox;
            foreach (var neighbor in edgeCell.Neighbors) {
               if (handledNeighborCells.Contains(neighbor)) {
                  continue;
               } else {
                  handledNeighborCells.Add(neighbor);
               }

            //               var neighborObb = neighbor.OrientedBoundingBox;
            //               var neighborToLocal = OrientedBoundingBox.GetBoxToBoxMatrix(ref thisObb, ref neighborObb);
            //               Vector3 zero = new Vector3(0, 0, 0);
            //               Vector3 neighborRelativePosition;
            //               Vector3.Transform(ref zero, ref neighborToLocal, out neighborRelativePosition);
            //               var p = new PolygonPoint((neighborRelativePosition.X), (neighborRelativePosition.Y));
            //               var q = new PolygonPoint((neighborRelativePosition.X + 0.05), (neighborRelativePosition.Y + 0.05));
            //               cps.AddConstraint(new TriangulationConstraint(p, q));
            }
            //            var p = new PolygonPoint((edgeCell.X + 0.45) * 0.998f - XLength / 2.0f, (edgeCell.Y + 0.45f) * 0.98f - YLength / 2.0f);
            //            var q = new PolygonPoint((edgeCell.X + 0.55) * 0.999f - XLength / 2.0f, (edgeCell.Y + 0.55f) * 0.99f - YLength / 2.0f);
            //            cps.AddConstraint(new TriangulationConstraint(p, q));
             }
             //         cps.AddHole(
            //            new List<TriangulationPoint> {
            //               new TriangulationPoint(-XLength / 2 + 2, -YLength / 2 + 2),
            //               new TriangulationPoint(XLength / 2 - 2, -YLength / 2 + 2),
            //               new TriangulationPoint(XLength / 2 - 2, YLength / 2 - 2),
            //               new TriangulationPoint(-XLength / 2 + 2, YLength / 2 - 2)
            //            }, "hole");
             P2T.Triangulate(cps);
             Console.WriteLine(cps.Triangles.Count);
             Mesh = cps.Triangles;
            //         for (var x = 0; x < XLength; x++) {
            //            for (var y = 0; y < YLength; y++) {
            //               var cellIndex = x + y * XLength;
            //               if (Cells[cellIndex].Flags.HasFlag(CellFlags.Connector)) {
            //
            //               }
            //            }
            //         }
        }
Beispiel #17
0
        public IEnumerable <MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var width   = box.Width;
            var length  = Math.Max(1, Math.Abs((int)box.Length));
            var height  = box.Height;
            var flatten = (float)_flattenFactor.Value;
            var text    = _text.GetValue();

            var family = _fontChooser.GetFontFamily();
            var style  = Enum.GetValues(typeof(FontStyle)).OfType <FontStyle>().FirstOrDefault(fs => family.IsStyleAvailable(fs));

            if (!family.IsStyleAvailable(style))
            {
                family = FontFamily.GenericSansSerif;
            }

            var set = new PolygonSet();

            var sizes = new List <RectangleF>();

            using (var bmp = new Bitmap(1, 1))
            {
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    using (var font = new Font(family, length, style, GraphicsUnit.Pixel))
                    {
                        for (var i = 0; i < text.Length; i += 32)
                        {
                            using (var sf = new StringFormat(StringFormat.GenericTypographic))
                            {
                                var rem   = Math.Min(text.Length, i + 32) - i;
                                var range = Enumerable.Range(0, rem).Select(x => new CharacterRange(x, 1)).ToArray();
                                sf.SetMeasurableCharacterRanges(range);
                                var reg = g.MeasureCharacterRanges(text.Substring(i, rem), font, new RectangleF(0, 0, float.MaxValue, float.MaxValue), sf);
                                sizes.AddRange(reg.Select(x => x.GetBounds(g)));
                            }
                        }
                    }
                }
            }

            var xOffset = box.Start.DX;
            var yOffset = box.End.DY;

            for (var ci = 0; ci < text.Length; ci++)
            {
                var c    = text[ci];
                var size = sizes[ci];

                var gp = new GraphicsPath();
                gp.AddString(c.ToString(CultureInfo.InvariantCulture), family, (int)style, length, new PointF(0, 0), StringFormat.GenericTypographic);
                gp.Flatten(new System.Drawing.Drawing2D.Matrix(), flatten);

                var polygons = new List <Polygon>();
                var poly     = new List <PolygonPoint>();

                for (var i = 0; i < gp.PointCount; i++)
                {
                    var type  = gp.PathTypes[i];
                    var point = gp.PathPoints[i];

                    poly.Add(new PolygonPoint(point.X + xOffset, -point.Y + yOffset));

                    if ((type & 0x80) == 0x80)
                    {
                        polygons.Add(new Polygon(poly));
                        poly.Clear();
                    }
                }

                var     tri     = new List <Polygon>();
                Polygon polygon = null;
                foreach (var p in polygons)
                {
                    if (polygon == null)
                    {
                        polygon = p;
                        tri.Add(p);
                    }
                    else if (p.CalculateWindingOrder() != polygon.CalculateWindingOrder())
                    {
                        polygon.AddHole(p);
                    }
                    else
                    {
                        polygon = null;
                        tri.Add(p);
                    }
                }

                foreach (var pp in tri)
                {
                    try
                    {
                        P2T.Triangulate(pp);
                        set.Add(pp);
                    }
                    catch
                    {
                        // Ignore
                    }
                }

                xOffset += size.Width;
            }

            var zOffset = box.Start.Z;

            foreach (var polygon in set.Polygons)
            {
                foreach (var t in polygon.Triangles)
                {
                    var points = t.Points.Select(x => new Coordinate((decimal)x.X, (decimal)x.Y, zOffset).Round(roundDecimals)).ToList();

                    var faces = new List <Coordinate[]>();

                    // Add the vertical faces
                    var z = new Coordinate(0, 0, height).Round(roundDecimals);
                    for (var j = 0; j < points.Count; j++)
                    {
                        var next = (j + 1) % points.Count;
                        faces.Add(new[] { points[j], points[j] + z, points[next] + z, points[next] });
                    }
                    // Add the top and bottom faces
                    faces.Add(points.ToArray());
                    faces.Add(points.Select(x => x + z).Reverse().ToArray());

                    // Nothing new here, move along
                    var solid = new Solid(generator.GetNextObjectID())
                    {
                        Colour = Colour.GetRandomBrushColour()
                    };
                    foreach (var arr in faces)
                    {
                        var face = new Face(generator.GetNextFaceID())
                        {
                            Parent  = solid,
                            Plane   = new Plane(arr[0], arr[1], arr[2]),
                            Colour  = solid.Colour,
                            Texture = { Texture = texture }
                        };
                        face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                        face.UpdateBoundingBox();
                        face.AlignTextureToFace();
                        solid.Faces.Add(face);
                    }
                    solid.UpdateBoundingBox();
                    yield return(solid);
                }
            }
        }
Beispiel #18
0
        /// <summary>
        /// triangulate polygon, algorithm from wiki is fast enough
        /// http://wiki.unity3d.com/index.php?title=Triangulator
        /// </summary>
        /// <returns></returns>
        public List <int> Triangulate()
        {
            // no holes supported
            if (holes.Count == 0)
            {
                var indices = new List <int>(Points.Length);

                int n = Points.Length;
                if (n < 3)
                {
                    return(indices);
                }

                var V = new int[n];
                if (Area > 0)
                {
                    for (int v = 0; v < n; v++)
                    {
                        V[v] = v;
                    }
                }
                else
                {
                    for (int v = 0; v < n; v++)
                    {
                        V[v] = (n - 1) - v;
                    }
                }

                int nv    = n;
                int count = 2 * nv;
                for (int m = 0, v = nv - 1; nv > 2;)
                {
                    if ((count--) <= 0)
                    {
                        return(indices);
                    }

                    int u = v;
                    if (nv <= u)
                    {
                        u = 0;
                    }
                    v = u + 1;
                    if (nv <= v)
                    {
                        v = 0;
                    }
                    int w = v + 1;
                    if (nv <= w)
                    {
                        w = 0;
                    }

                    if (Snip(u, v, w, nv, V))
                    {
                        int a, b, c, s, t;
                        a = V[u];
                        b = V[v];
                        c = V[w];
                        indices.Add(a);
                        indices.Add(b);
                        indices.Add(c);
                        m++;
                        for (s = v, t = v + 1; t < nv; s++, t++)
                        {
                            V[s] = V[t];
                        }
                        nv--;
                        count = 2 * nv;
                    }
                }

                indices.Reverse();
                return(indices);
            }
            else
            {
                // use poly2tri library to triangulate mesh with holes

                var p2tPoints = new List <Poly2Tri.PolygonPoint>(Points.Length);

                foreach (var point in Points)
                {
                    p2tPoints.Add(new Poly2Tri.PolygonPoint(point.x, point.y));
                }

                // create p2t polygon
                var p2tPolygon = new Poly2Tri.Polygon(p2tPoints);

                // add holes
                foreach (var polygonHole in holes)
                {
                    var p2tHolePoints = new List <Poly2Tri.PolygonPoint>(polygonHole.Points.Length);

                    foreach (var polygonPoint in polygonHole.Points)
                    {
                        p2tHolePoints.Add(new Poly2Tri.PolygonPoint(polygonPoint.x, polygonPoint.y));
                    }

                    p2tPolygon.AddHole(new Poly2Tri.Polygon(p2tHolePoints));
                }

                try
                {
                    Poly2Tri.P2T.Triangulate(p2tPolygon);
                }
                catch (Exception ex)
                {
                    ExploderUtils.Log("P2T Exception: " + ex);
                    return(null);
                }

                var triangles = p2tPolygon.Triangles.Count;

                var indices = new List <int>(triangles * 3);
                Points = new Vector2[triangles * 3];
                var j = 0;

                // recalc min max
                Min.x = float.MaxValue;
                Min.y = float.MaxValue;
                Max.x = float.MinValue;
                Max.y = float.MinValue;

                for (int i = 0; i < triangles; i++)
                {
                    indices.Add((j + 0));
                    indices.Add((j + 1));
                    indices.Add((j + 2));

                    Points[j + 2].x = (float)p2tPolygon.Triangles[i].Points._0.X;
                    Points[j + 2].y = (float)p2tPolygon.Triangles[i].Points._0.Y;

                    Points[j + 1].x = (float)p2tPolygon.Triangles[i].Points._1.X;
                    Points[j + 1].y = (float)p2tPolygon.Triangles[i].Points._1.Y;

                    Points[j + 0].x = (float)p2tPolygon.Triangles[i].Points._2.X;
                    Points[j + 0].y = (float)p2tPolygon.Triangles[i].Points._2.Y;

                    // recalc min max
                    for (int k = 0; k < 3; k++)
                    {
                        if (Points[j + k].x < Min.x)
                        {
                            Min.x = Points[j + k].x;
                        }
                        if (Points[j + k].y < Min.y)
                        {
                            Min.y = Points[j + k].y;
                        }
                        if (Points[j + k].x > Max.x)
                        {
                            Max.x = Points[j + k].x;
                        }
                        if (Points[j + k].y > Max.y)
                        {
                            Max.y = Points[j + k].y;
                        }
                    }

                    j += 3;
                }

                return(indices);
            }
        }
Beispiel #19
0
    /// <summary>
    /// Create a Mesh from a given Polygon.
    /// </summary>
    /// <returns>The freshly minted mesh.</returns>
    /// <param name="polygon">Polygon you want to triangulate.</param>
    public static Mesh CreateMesh(Polygon polygon)
    {
        // Check for the easy case (a triangle)
        if (polygon.holes.Count == 0 && (polygon.outside.Count == 3 ||
                                         (polygon.outside.Count == 4 && polygon.outside[3] == polygon.outside[0])))
        {
            return(CreateTriangle(polygon));
        }

        // Ensure we have the rotation properly calculated, and have a valid normal
        if (polygon.rotation == Quaternion.identity)
        {
            polygon.CalcRotation();
        }
        if (polygon.planeNormal == Vector3.zero)
        {
            return(null);                                                       // bad data
        }
        // Rotate 1 point and note where it ends up in Z
        float z = (polygon.rotation * polygon.outside[0]).z;

        // Prepare a map from vertex codes to 3D positions.
        Dictionary <uint, Vector3> codeToPosition = new Dictionary <uint, Vector3>();

        // Convert the outside points (throwing out Z at this point)
        Poly2Tri.Polygon poly = new Poly2Tri.Polygon(ConvertPoints(polygon.outside, polygon.rotation, codeToPosition));

        // Convert each of the holes
        foreach (List <Vector3> hole in polygon.holes)
        {
            poly.AddHole(new Poly2Tri.Polygon(ConvertPoints(hole, polygon.rotation, codeToPosition)));
        }

        // Triangulate it!  Note that this may throw an exception if the data is bogus.
        try {
            DTSweepContext tcx = new DTSweepContext();
            tcx.PrepareTriangulation(poly);
            DTSweep.Triangulate(tcx);
            tcx = null;
        } catch (System.Exception e) {
            throw e;
        }

        // Now, to get back to our original positions, use our code-to-position map.  We do
        // this instead of un-rotating to be a little more robust about noncoplanar polygons.

        // Create the Vector3 vertices (undoing the rotation),
        // and also build a map of vertex codes to indices
        Quaternion?            invRot      = null;
        Dictionary <uint, int> codeToIndex = new Dictionary <uint, int>();
        List <Vector3>         vertexList  = new List <Vector3>();

        foreach (DelaunayTriangle t in poly.Triangles)
        {
            foreach (var p in t.Points)
            {
                if (codeToIndex.ContainsKey(p.VertexCode))
                {
                    continue;
                }
                codeToIndex[p.VertexCode] = vertexList.Count;
                Vector3 pos;
                if (!codeToPosition.TryGetValue(p.VertexCode, out pos))
                {
                    // This can happen in rare cases when we're hitting limits of floating-point precision.
                    // Rather than fail, let's just do the inverse rotation.
                    if (!invRot.HasValue)
                    {
                        invRot = Quaternion.Inverse(polygon.rotation);
                    }
                    pos = invRot.Value * new Vector3(p.Xf, p.Yf, z);
                }
                vertexList.Add(pos);
            }
        }

        // Create the indices array
        int[] indices = new int[poly.Triangles.Count * 3];
        {
            int i = 0;
            foreach (DelaunayTriangle t in poly.Triangles)
            {
                indices[i++] = codeToIndex[t.Points[0].VertexCode];
                indices[i++] = codeToIndex[t.Points[1].VertexCode];
                indices[i++] = codeToIndex[t.Points[2].VertexCode];
            }
        }

        // Create the UV list, by looking up the closest point for each in our poly
        Vector2[] uv = null;
        if (polygon.outsideUVs != null)
        {
            uv = new Vector2[vertexList.Count];
            for (int i = 0; i < vertexList.Count; i++)
            {
                uv[i] = polygon.ClosestUV(vertexList[i]);
            }
        }

        // Create the mesh
        Mesh msh = new Mesh();

        msh.vertices  = vertexList.ToArray();
        msh.triangles = indices;
        msh.uv        = uv;
        msh.RecalculateNormals();
        msh.RecalculateBounds();
        return(msh);
    }
Beispiel #20
0
    /// <summary>
    /// Create a Mesh from a given Polygon.
    /// </summary>
    /// <returns>The freshly minted mesh.</returns>
    /// <param name="polygon">Polygon you want to triangulate.</param>
    public static bool CreateMesh(List <Poly2Mesh.Polygon> polygons, ref Mesh dstMesh)
    {
        // TODO: use vertex indices instead of actual vertices to find original vertices

        var poly2TriPolygons = new List <Poly2Tri.Polygon>();
        var codeToPositions  = new List <Dictionary <uint, Vector3> >();
        var zs = new List <float>();

        // Ensure we have the rotation properly calculated, and have a valid normal
        for (int p = 0; p < polygons.Count; p++)
        {
            if (polygons[p].rotation == Quaternion.identity)
            {
                polygons[p].CalcRotation();
            }
            if (polygons[p].planeNormal == Vector3.zero)
            {
                Debug.Log("polygons[p].planeNormal == Vector3.zero");
                return(false);       // bad data
            }

            // Rotate 1 point and note where it ends up in Z
            float z = (polygons[p].rotation * polygons[p].outside[0]).z;

            // Prepare a map from vertex codes to 3D positions.
            Dictionary <uint, Vector3> codeToPosition = new Dictionary <uint, Vector3>();

            // Convert the outside points (throwing out Z at this point)
            Poly2Tri.Polygon poly = new Poly2Tri.Polygon(ConvertPoints(polygons[p].outside, polygons[p].rotation, codeToPosition));


            // Convert each of the holes
            if (polygons[p].holes != null)
            {
                foreach (List <Vector3> hole in polygons[p].holes)
                {
                    poly.AddHole(new Poly2Tri.Polygon(ConvertPoints(hole, polygons[p].rotation, codeToPosition)));
                }
            }

            codeToPositions.Add(codeToPosition);
            poly2TriPolygons.Add(poly);
            zs.Add(z);
        }

        // Triangulate it!  Note that this may throw an exception if the data is bogus.
        for (int p = 0; p < poly2TriPolygons.Count; p++)
        {
            try
            {
                DTSweepContext tcx = new DTSweepContext();
                tcx.PrepareTriangulation(poly2TriPolygons[p]);
                DTSweep.Triangulate(tcx);
                tcx = null;
            } catch (System.Exception e) {
                //Profiler.Exit(profileID);
                Debug.LogException(e);
                //throw e;
            }
        }

        // Now, to get back to our original positions, use our code-to-position map.  We do
        // this instead of un-rotating to be a little more robust about noncoplanar polygons.

        // Create the Vector3 vertices (undoing the rotation),
        // and also build a map of vertex codes to indices
        Quaternion?            invRot      = null;
        Dictionary <uint, int> codeToIndex = new Dictionary <uint, int>();
        List <Vector3>         vertexList  = new List <Vector3>();
        List <int>             indexList   = new List <int>();
        int triangleCount = 0;

        for (int p = 0; p < polygons.Count; p++)
        {
            var poly           = poly2TriPolygons[p];
            var polygon        = polygons[p];
            var z              = zs[p];
            var codeToPosition = codeToPositions[p];
            triangleCount += poly.Triangles.Count;
            codeToIndex.Clear();
            foreach (DelaunayTriangle t in poly.Triangles)
            {
                foreach (var point in t.Points)
                {
                    if (codeToIndex.ContainsKey(point.VertexCode))
                    {
                        continue;
                    }
                    codeToIndex[point.VertexCode] = vertexList.Count;
                    Vector3 pos;
                    if (!codeToPosition.TryGetValue(point.VertexCode, out pos))
                    {
                        // This can happen in rare cases when we're hitting limits of floating-point precision.
                        // Rather than fail, let's just do the inverse rotation.
                        Debug.LogWarning("Vertex code lookup failed; using inverse rotation.");
                        if (!invRot.HasValue)
                        {
                            invRot = Quaternion.Inverse(polygon.rotation);
                        }
                        pos = invRot.Value * new Vector3(point.Xf, point.Yf, z);
                    }
                    vertexList.Add(pos);
                }
            }
            if (polygon.inverse)
            {
                foreach (DelaunayTriangle t in poly.Triangles)
                {
                    indexList.Add(codeToIndex[t.Points[2].VertexCode]);
                    indexList.Add(codeToIndex[t.Points[1].VertexCode]);
                    indexList.Add(codeToIndex[t.Points[0].VertexCode]);
                }
            }
            else
            {
                foreach (DelaunayTriangle t in poly.Triangles)
                {
                    indexList.Add(codeToIndex[t.Points[0].VertexCode]);
                    indexList.Add(codeToIndex[t.Points[1].VertexCode]);
                    indexList.Add(codeToIndex[t.Points[2].VertexCode]);
                }
            }
        }

        // Create the indices array
        var indices = indexList.ToArray();

        // Create the mesh
        dstMesh.vertices  = vertexList.ToArray();
        dstMesh.triangles = indices;
        dstMesh.RecalculateNormals();
        return(true);
    }