示例#1
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            // Number of points on the outer circle
            int n = GetParamValueInt(0, param0);
            int count, npoints;

            double radius = GetParamValueInt(1, param1);

            // Step size on the outer circle
            double h = 2 * Math.PI * radius / n;

            // Current radius and step size
            double r, dphi;

            InputGeometry input = new InputGeometry(n + 1);

            // Inner cirlce (radius = 1)
            r       = 1;
            npoints = (int)(2 * Math.PI * r / h);
            dphi    = 2 * Math.PI / npoints;
            for (int i = 0; i < npoints; i++)
            {
                input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 1);
                input.AddSegment(i, (i + 1) % npoints, 1);
            }

            count = input.Count;

            // Center cirlce
            r       = (radius + 1) / 2.0;
            npoints = (int)(2 * Math.PI * r / h);
            dphi    = 2 * Math.PI / npoints;
            for (int i = 0; i < npoints; i++)
            {
                input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 2);
                input.AddSegment(count + i, count + (i + 1) % npoints, 2);
            }

            count = input.Count;

            // Outer cirlce
            r       = radius;
            npoints = (int)(2 * Math.PI * r / h);
            dphi    = 2 * Math.PI / npoints;
            for (int i = 0; i < npoints; i++)
            {
                input.AddPoint(r * Math.Cos(i * dphi), r * Math.Sin(i * dphi), 3);
                input.AddSegment(count + i, count + (i + 1) % npoints, 3);
            }

            input.AddHole(0, 0);

            // Regions: |++++++|++++++|---|
            //          r             1   0

            input.AddRegion((r + 3.0) / 4.0, 0, 1);
            input.AddRegion((3 * r + 1.0) / 4.0, 0, 2);

            return(input);
        }
示例#2
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int numRays = GetParamValueInt(0, param0);

            InputGeometry input = new InputGeometry(numRays + 4);

            input.AddPoint(0, 0); // Center

            double x, y, r, e, step = 2 * Math.PI / numRays;

            for (int i = 0; i < numRays; i++)
            {
                e = Util.Random.NextDouble() * step * 0.7;
                r = (Util.Random.NextDouble() + 0.7) * 0.5;
                x = r * Math.Cos(i * step + e);
                y = r * Math.Sin(i * step + e);

                input.AddPoint(x, y, 2);
                input.AddSegment(0, i + 1, 2);
            }

            input.AddPoint(-1, -1, 1); // Box
            input.AddPoint(1, -1, 1);
            input.AddPoint(1, 1, 1);
            input.AddPoint(-1, 1, 1);

            numRays = input.Count;
            input.AddSegment(numRays - 1, numRays - 2, 1);
            input.AddSegment(numRays - 2, numRays - 3, 1);
            input.AddSegment(numRays - 3, numRays - 4, 1);
            input.AddSegment(numRays - 4, numRays - 1, 1);

            return(input);
        }
示例#3
0
    public WaterSurfacePolygon(List<Point> points)
    {
        mesh = new TriangleNet.Mesh();
        mesh.Behavior.Quality = true;

        this.points = points;

        triangleNormals = new List<Point>();
        trianglePlaneEquationDs = new List<double>();

        InputGeometry geomtery = new InputGeometry();

        for (int i = 0; i < points.Count; i++)
        {
            Point p = points[i];

            if (i == 0)
            {
                minX = maxX = p.X;
                minY = maxY = p.Y;
                minZ = maxZ = p.Z;
            }
            else
            {
                minX = Math.Min(p.X, minX);
                maxX = Math.Max(p.X, maxX);
                minY = Math.Min(p.Y, minY);
                maxY = Math.Max(p.Y, maxY);
                minZ = Math.Min(p.Z, minZ);
                maxZ = Math.Max(p.Z, maxZ);
            }

            geomtery.AddPoint(p.X, p.Y, 0, p.Z);

            //add segments
            if (i > 0)
            {
                geomtery.AddSegment(i - 1, i, 0);
            }

            if (i == points.Count - 1)
            {
                geomtery.AddSegment(i, 0, 0);
            }
        }

        mesh.Triangulate(geomtery);
        triangles = new List<TriangleNet.Data.Triangle>();

        foreach (TriangleNet.Data.Triangle tr in mesh.Triangles)
        {
            if (tr.P0 < points.Count && tr.P1 < points.Count && tr.P2 < points.Count)
            {
                triangles.Add(tr);
            }
        }

        calculateNormalsAndDs();
    }
    /// <summary> Inserts points and segments of the given polygon to the input geometry </summary>
    static public void AddPolygon(this InputGeometry input, IList <Vector2> polygon)
    {
        int inputCount = input.Count;

        input.AddPoint(polygon[0].x, polygon[0].y);
        for (int i = 1, j = 0; i < polygon.Count; j = i++)
        {
            input.AddPoint(polygon[i].x, polygon[i].y);
            input.AddSegment(inputCount + j, inputCount + i);
        }
        input.AddSegment(input.Count - 1, inputCount);
    }
        private int CreateRoofTriangulation(List <Vector3> corners, float height, MeshData data)
        {
            _mesh = new TriangleNet.Mesh();
            var inp = new InputGeometry(corners.Count);

            for (int i = 0; i < corners.Count; i++)
            {
                var v = corners[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % corners.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            var vertsStartCount = data.Vertices.Count;

            data.Vertices.AddRange(corners.Select(x => new Vector3(x.x, height, x.z)).ToList());

            foreach (var tri in _mesh.Triangles)
            {
                data.Indices.Add(vertsStartCount + tri.P1);
                data.Indices.Add(vertsStartCount + tri.P0);
                data.Indices.Add(vertsStartCount + tri.P2);
            }
            return(vertsStartCount);
        }
		public static InputGeometry InputGeometry(this Polygon this_)
		{
			InputGeometry geometry = new InputGeometry();
			int boundary;

			// Add points.
			boundary = 1;
			int pointIndexOffset = 0;
			this_.EnumeratePolygons((Polygon eachPolygon) =>
			{
				// Add points.
				this_.EnumeratePoints((Vector2 eachPoint) =>
				{
					geometry.AddPoint(
						(double)eachPoint.x,
						(double)eachPoint.y,
						boundary);
				});

				this_.EnumerateEdges((EPPZ.Geometry.Edge eachEdge) =>
				{
					int index_a = eachEdge.vertexA.index + pointIndexOffset;
					int index_b = eachEdge.vertexB.index + pointIndexOffset;
					geometry.AddSegment(index_a, index_b, boundary);
				});

				pointIndexOffset += eachPolygon.vertexCount; // Track point offsets.
				boundary++;
			});

			return geometry;
		}
示例#7
0
        /// <summary>
        /// Rebuild the input geometry.
        /// </summary>
        private InputGeometry Rebuild()
        {
            InputGeometry geometry = new InputGeometry(mesh.vertices.Count);

            foreach (var vertex in mesh.vertices.Values)
            {
                geometry.AddPoint(vertex.x, vertex.y, vertex.mark);
            }

            foreach (var segment in mesh.subsegs.Values)
            {
                geometry.AddSegment(segment.P0, segment.P1, segment.Boundary);
            }

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

            foreach (var region in mesh.regions)
            {
                geometry.AddRegion(region.point.x, region.point.y, region.id);
            }

            return(geometry);
        }
示例#8
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 <Point> points, int mark = 0)
    {
        // Save the current number of points.
        int N = geometry.Count;

        // Hole coordinates
        float x = 0.0f;
        float y = 0.0f;

        int m = 0;

        foreach (var pt in points)
        {
            x += pt.X;
            y += pt.Y;

            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);
        }

        geometry.AddHole(x / m, y / m);
    }
示例#9
0
        private void CreatePolygonMesh(Vector2d[] points, ref UnityEngine.Mesh mesh)
        {
            var inp = new InputGeometry(points.Length);
            int i   = 0;

            foreach (var p in points)
            {
                var localMercPos = p - Tile.Rect.Center;
                inp.AddPoint(localMercPos.x, localMercPos.y);
                inp.AddSegment(i, (i + 1) % points.Length);
                i++;
            }

            var md = new MeshData();

            CreateMesh(inp, md);

            //I want object center to be in the middle of object, not at the corner of the tile
            var center = ChangeToRelativePositions(md.Vertices);

            transform.localPosition = center;

            mesh.vertices  = md.Vertices.ToArray();
            mesh.triangles = md.Indices.ToArray();
            mesh.SetUVs(0, md.UV);
            mesh.RecalculateNormals();
        }
示例#10
0
        static void SearchTree(InputGeometry inputGeometry, ref int pointIndex, PolyNode node)
        {
            foreach (PolyNode childNode in node.Childs)
            {
                int startIndex = pointIndex;

                foreach (Vector2 point in childNode.Contour)
                {
                    inputGeometry.AddPoint(point.X, point.Y);
                    if (pointIndex > startIndex)
                    {
                        inputGeometry.AddSegment(pointIndex - 1, pointIndex);
                    }
                    pointIndex++;
                }
                inputGeometry.AddSegment(pointIndex - 1, startIndex);

                if (childNode.IsHole)
                {
                    for (int i = 0, j = childNode.Contour.Count - 1, k = childNode.Contour.Count - 2; i < childNode.Contour.Count; k = j, j = i, i++)
                    {
                        Vector2 a1 = childNode.Contour[k];
                        Vector2 a2 = childNode.Contour[j];
                        Vector2 a3 = childNode.Contour[i];

                        if (Vector2.VectorProduct(a2 - a1, a3 - a1) < 0)
                        {
                            Vector2 c = (a1 + a3) / 2;
                            Vector2 d = a2 - c;
                            float   x = c.Length * 2;
                            Vector2 hole;
                            do
                            {
                                x   /= 2;
                                hole = c + (1 - x) * d;
                            } while (!IsInside(childNode, hole));
                            x   /= 512;
                            hole = c + (1 - x) * d;
                            inputGeometry.AddHole(hole.X, hole.Y);
                            break;
                        }
                    }
                }

                SearchTree(inputGeometry, ref pointIndex, childNode);
            }
        }
示例#11
0
        protected override GameObject CreateLayer(Tile tile, List<JSONObject> items)
        {
            var main = new GameObject("Earth Layer");
            var meshes = new Dictionary<EarthType, MeshData>();
            foreach (var geo in items.Where(x => Query(x)))
            {
                var kind = geo["properties"].HasField("kind")
                ? geo["properties"]["kind"].str.ConvertToEarthType()
                : EarthType.Earth;

                var typeSettings = FactorySettings.GetSettingsFor<EarthSettings>(kind);

                //if we dont have a setting defined for that, it'Ll be merged to "unknown" 
                if (!FactorySettings.HasSettingsFor(kind))
                    kind = EarthType.Earth;

                if (!meshes.ContainsKey(kind))
                    meshes.Add(kind, new MeshData());

                foreach (var bb in geo["geometry"]["coordinates"].list)
                {
                    var jo = (bb.list[0].list[0].IsArray) ? bb.list[0] : bb;
                    var count = jo.list.Count - 1;
                    if (count < 3)
                        continue;

                    var inp = new InputGeometry(count);

                    for (int i = 0; i < count; i++)
                    {
                        var c = jo.list[i];
                        var dotMerc = GM.LatLonToMeters(c[1].f, c[0].f);
                        var localMercPos = dotMerc - tile.Rect.Center;
                        inp.AddPoint(localMercPos.x, localMercPos.y);
                        inp.AddSegment(i, (i + 1) % count);
                    }
                    
                    //create mesh, actually just to get vertice&indices
                    //filling last two parameters, horrible call yea
                    CreateMesh(inp, meshes[kind]);

                    //unity cant handle more than 65k on single mesh
                    //so we'll finish current and start a new one
                    if (meshes[kind].Vertices.Count > 64000)
                    {
                        CreateGameObject(kind, meshes[kind], main.transform);
                        meshes[kind] = new MeshData();
                    }
                }
            }

            foreach (var group in meshes)
            {
                CreateGameObject(group.Key, group.Value, main.transform);
            }

            return main;
        }
示例#12
0
        protected override GameObject CreateLayer(Tile tile, List <JSONObject> items)
        {
            var main = new GameObject("Landuse Layer");

            var _meshes = new Dictionary <LanduseKind, MeshData>();

            foreach (var geo in items.Where(x => Query(x)))
            {
                var kind = geo["properties"]["kind"].str.ConvertToLanduseType();
                if (!FactorySettings.HasSettingsFor(kind) && !JustDrawEverythingFam)
                {
                    continue;
                }

                //var typeSettings = FactorySettings.GetSettingsFor<LanduseSettings>(kind);
                if (!_meshes.ContainsKey(kind))
                {
                    _meshes.Add(kind, new MeshData());
                }

                //foreach (var bb in geo["geometry"]["coordinates"].list)
                //{
                var bb    = geo["geometry"]["coordinates"].list[0]; //this is wrong but cant fix it now
                var count = bb.list.Count - 1;

                if (count < 3)
                {
                    continue;
                }

                var inp = new InputGeometry(count);

                for (int i = 0; i < count; i++)
                {
                    var c            = bb.list[i];
                    var dotMerc      = GM.LatLonToMeters(c[1].f, c[0].f);
                    var localMercPos = dotMerc - tile.Rect.Center;
                    inp.AddPoint(localMercPos.x, localMercPos.y);
                    inp.AddSegment(i, (i + 1) % count);
                }

                CreateMesh(inp, _meshes[kind]);

                if (_meshes[kind].Vertices.Count > 64000)
                {
                    CreateGameObject(kind, _meshes[kind], main.transform);
                    _meshes[kind] = new MeshData();
                }
                //}
            }

            foreach (var group in _meshes)
            {
                CreateGameObject(group.Key, group.Value, main.transform);
            }

            return(main);
        }
示例#13
0
        void SearchTree(InputGeometry inputGeometry, ref int pointIndex, PolyNode node)
        {
            foreach (PolyNode childNode in node.Childs)
            {
                int startIndex = pointIndex;

                foreach (ControlPoint point in childNode.Contour)
                {
                    inputGeometry.AddPoint(point.X, point.Y);
                    if (pointIndex > startIndex)
                    {
                        inputGeometry.AddSegment(pointIndex - 1, pointIndex);
                    }
                    pointIndex++;
                }
                inputGeometry.AddSegment(pointIndex - 1, startIndex);

                if (childNode.IsHole)
                {
                    for (int i = 0, j = childNode.Contour.Count - 1, k = childNode.Contour.Count - 2; i < childNode.Contour.Count; k = j, j = i, i++)
                    {
                        ControlPoint a1 = childNode.Contour[k];
                        ControlPoint a2 = childNode.Contour[j];
                        ControlPoint a3 = childNode.Contour[i];

                        if (ControlPoint.VectorProduct(a2 - a1, a3 - a1) < 0)
                        {
                            ControlPoint c = ((a1 + a3) / 2) - a2;
                            double       x = 2;
                            ControlPoint hole;
                            do
                            {
                                x   /= 2;
                                hole = a2 + (c * x);
                            } while (!IsInside(childNode, hole));

                            inputGeometry.AddHole(hole.X, hole.Y);
                            break;
                        }
                    }
                }

                SearchTree(inputGeometry, ref pointIndex, childNode);
            }
        }
示例#14
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int n = GetParamValueInt(0, param0);
            int m = n / 2;

            InputGeometry input = new InputGeometry(n + 1);

            double ro, r = 10;
            double step = 2 * Math.PI / m;

            // Inner ring
            for (int i = 0; i < m; i++)
            {
                input.AddPoint(r * Math.Cos(i * step), r * Math.Sin(i * step));
                input.AddSegment(i, (i + 1) % m);
            }

            r = 1.5 * r;


            step = 2 * Math.PI / n;
            double offset = step / 2;

            // Outer ring
            for (int i = 0; i < n; i++)
            {
                ro = r;

                if (i % 2 == 0)
                {
                    ro = r + r * Util.Random.NextDouble() * (param1 / 100);
                }

                input.AddPoint(ro * Math.Cos(i * step + offset), ro * Math.Sin(i * step + offset));
                input.AddSegment(m + i, m + ((i + 1) % n));
            }

            input.AddHole(0, 0);

            return(input);
        }
示例#15
0
        protected override IEnumerable <MonoBehaviour> Create(Tile tile, JSONObject geo)
        {
            var kind = geo["properties"]["kind"].str.ConvertToLanduseType();

            if (!FactorySettings.HasSettingsFor(kind) && !JustDrawEverythingFam)
            {
                yield break;
            }

            var bb = geo["geometry"]["coordinates"].list[0]; //this is wrong but cant fix it now

            if (bb == null || bb.list == null)
            {
                yield break;
            }

            var count = bb.list.Count - 1;

            if (count < 3)
            {
                yield break;
            }

            var inp = new InputGeometry(count);

            for (var i = 0; i < count; i++)
            {
                var c            = bb.list[i];
                var dotMerc      = GM.LatLonToMeters(c[1].f, c[0].f);
                var localMercPos = dotMerc - tile.Rect.Center;
                inp.AddPoint(localMercPos.x, localMercPos.y);
                inp.AddSegment(i, (i + 1) % count);
            }

            var landuse = new GameObject("Landuse").AddComponent <Landuse>();
            var md      = new MeshData();
            var mesh    = landuse.GetComponent <MeshFilter>().mesh;

            SetProperties(geo, landuse, kind);
            CreateMesh(inp, md);

            //I want object center to be in the middle of object, not at the corner of the tile
            var landuseCenter = ChangeToRelativePositions(md.Vertices);

            landuse.transform.localPosition = landuseCenter;

            mesh.vertices  = md.Vertices.ToArray();
            mesh.triangles = md.Indices.ToArray();
            mesh.SetUVs(0, md.UV);
            mesh.RecalculateNormals();

            yield return(landuse);
        }
示例#16
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);
    }
示例#17
0
        public static InputGeometry Generate(int n, double bounds = 10.0)
        {
            var geometry = new InputGeometry((n + 1) * (n + 1));

            double x, y, d = 2 * bounds / n;

            int mark = 0;

            for (int i = 0; i <= n; i++)
            {
                y = -bounds + i * d;

                for (int j = 0; j <= n; j++)
                {
                    x = -bounds + j * d;

                    geometry.AddPoint(x, y, mark);
                }
            }

            // Add boundary segments
            for (int i = 0; i < n; i++)
            {
                // Bottom
                geometry.AddSegment(i, i + 1);

                // Right
                geometry.AddSegment(i * (n + 1) + n, (i + 1) * (n + 1) + n);

                // Top
                geometry.AddSegment(n * (n + 1) + i, n * (n + 1) + (i + 1));

                // Left
                geometry.AddSegment(i * (n + 1), (i + 1) * (n + 1));
            }

            return(geometry);
        }
示例#18
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;
        }
示例#19
0
        /// <summary>
        /// Add a polygon ring to the geometry.
        /// </summary>
        /// <param name="points">List of points which make up the polygon.</param>
        /// <param name="mark">Common boundary mark for all segments of the polygon.</param>
        public static void AddRing(this InputGeometry geometry, IEnumerable <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);
            }
        }
        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);
                    }
                }
            }
        }
示例#21
0
        private void ReadSegments(InputGeometry geometry, Dictionary <string, object> segments, int count)
        {
            ArrayList data = segments["data"] as ArrayList;

            ArrayList markers = null;

            if (segments.ContainsKey("markers"))
            {
                markers = segments["markers"] as ArrayList;
            }

            if (data != null)
            {
                int mark, n = data.Count;

                if (n % 2 != 0)
                {
                    throw new Exception("JSON format error (segments).");
                }

                int p0, p1;

                for (int i = 0; i < n; i += 2)
                {
                    mark = 0;

                    if (markers != null && markers.Count == n)
                    {
                        mark = int.Parse(markers[i / 2].ToString());
                    }

                    p0 = int.Parse(data[i].ToString());
                    p1 = int.Parse(data[i + 1].ToString());

                    if (p0 < 0 || p0 >= count || p1 < 0 || p1 >= count)
                    {
                        throw new Exception("JSON format error (segment index).");
                    }

                    geometry.AddSegment(p0, p1, mark);
                }
            }
        }
示例#22
0
        protected override IEnumerable <MonoBehaviour> Create(Tile tile, JSONObject geo)
        {
            var kind         = geo["properties"]["kind"].str.ConvertToWaterType();
            var typeSettings = FactorySettings.GetSettingsFor <WaterSettings>(kind);

            var go    = new GameObject("water");
            var water = go.AddComponent <Water>();
            var mesh  = water.GetComponent <MeshFilter>().mesh;
            var md    = new MeshData();

            SetProperties(geo, water, typeSettings);

            foreach (var bb in geo["geometry"]["coordinates"].list)
            {
                var jo    = (bb.list[0].list[0].IsArray) ? bb.list[0] : bb;
                var count = jo.list.Count - 1;
                if (count < 3)
                {
                    continue;
                }

                var inp = new InputGeometry(count);

                for (int i = 0; i < count; i++)
                {
                    var c            = jo.list[i];
                    var dotMerc      = GM.LatLonToMeters(c[1].f, c[0].f);
                    var localMercPos = dotMerc - tile.Rect.Center;
                    inp.AddPoint(localMercPos.x, localMercPos.y);
                    inp.AddSegment(i, (i + 1) % count);
                }

                CreateMesh(inp, md);
            }

            mesh.vertices  = md.Vertices.ToArray();
            mesh.triangles = md.Indices.ToArray();
            mesh.SetUVs(0, md.UV);
            mesh.RecalculateNormals();

            yield return(water);
        }
        public override void Run(VectorFeatureUnity feature, MeshData md)
        {
            if (md.Vertices.Distinct().Count() < 3)
            {
                return;
            }

            var data  = new List <int>();
            var _mesh = new TriangleNet.Mesh();
            var inp   = new InputGeometry(md.Vertices.Count);

            for (int i = 0; i < md.Vertices.Count; i++)
            {
                var v = md.Vertices[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % md.Vertices.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            foreach (var tri in _mesh.Triangles)
            {
                data.Add(tri.P1);
                data.Add(tri.P0);
                data.Add(tri.P2);
            }

            if (_mesh.Vertices.Count != md.Vertices.Count)
            {
                md.Vertices.Clear();
                using (var sequenceEnum = _mesh.Vertices.GetEnumerator())
                {
                    while (sequenceEnum.MoveNext())
                    {
                        md.Vertices.Add(new Vector3((float)sequenceEnum.Current.x, 0, (float)sequenceEnum.Current.y));
                    }
                }
            }
            md.Triangles.Add(data);
        }
示例#24
0
        private InputGeometry Rebuild()
        {
            InputGeometry inputGeometry = new InputGeometry(this.mesh.vertices.Count);

            foreach (Vertex value in this.mesh.vertices.Values)
            {
                inputGeometry.AddPoint(value.x, value.y, value.mark);
            }
            foreach (Segment segment in this.mesh.subsegs.Values)
            {
                inputGeometry.AddSegment(segment.P0, segment.P1, segment.Boundary);
            }
            foreach (Point hole in this.mesh.holes)
            {
                inputGeometry.AddHole(hole.x, hole.y);
            }
            foreach (RegionPointer region in this.mesh.regions)
            {
                inputGeometry.AddRegion(region.point.x, region.point.y, region.id);
            }
            return(inputGeometry);
        }
示例#25
0
        private List <int> CreateRoofTriangulation(List <Vector3> corners)
        {
            var data  = new List <int>();
            var _mesh = new TriangleNet.Mesh();
            var inp   = new InputGeometry(corners.Count);

            for (int i = 0; i < corners.Count; i++)
            {
                var v = corners[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % corners.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            foreach (var tri in _mesh.Triangles)
            {
                data.Add(tri.P1);
                data.Add(tri.P0);
                data.Add(tri.P2);
            }
            return(data);
        }
示例#26
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);
                    }
                }
            }
        }
示例#27
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);
    }
示例#28
0
        public void RegenerateMesh(Vector3[] verts)
        {
            //convert passed in vertices to relative positioning
            MeshFilter myFilter = GetComponent <MeshFilter>();

            for (int i = 0; i < verts.Length; i++)
            {
                verts[i] = transform.InverseTransformPoint(verts[i]);
            }

            var input = new InputGeometry(verts.Length);

            {
                var __array1       = verts;
                var __arrayLength1 = __array1.Length;
                for (int __i1 = 0; __i1 < __arrayLength1; ++__i1)
                {
                    var vector3 = __array1[__i1];
                    {
                        input.AddPoint(vector3.x, vector3.z);
                    }
                }
            }
            for (int i = 0; i < verts.Length; i++)
            {
                input.AddSegment(i, (i + 1) % verts.Length);
            }

            var mesh = new TriangleNet.Mesh();

            mesh.Behavior.ConformingDelaunay = true;

            mesh.Behavior.Quality = true;

            mesh.Behavior.MinAngle = 0;
            mesh.Behavior.MaxAngle = 180;

            mesh.Behavior.MaxArea = 0.5;

            try
            {
                //sw.Start();
                mesh.Triangulate(input);

                for (int i = 0; i < 3; i++)
                {
                    mesh.Refine(true);
                }

                //sw.Stop();
            }
            catch (Exception ex)
            {
                Debug.LogError(ex.ToString());
            }


            Vector3[] vertex = new Vector3[mesh.Vertices.Count];
            int       index  = 0;

            {
                // foreach(var vertex1 in mesh.Vertices)
                var __enumerator2 = (mesh.Vertices).GetEnumerator();
                while (__enumerator2.MoveNext())
                {
                    var vertex1 = __enumerator2.Current;
                    {
                        vertex[index] = new Vector3((float)vertex1.X, GetSceneHeight((float)vertex1.X, (float)vertex1.Y),
                                                    (float)vertex1.Y);
                        ++index;
                    }
                }
            }

            Vector2[] uvs = new Vector2[vertex.Length];
            for (int i = 0; i < vertex.Length; i++)
            {
                if ((i % 2) == 0)
                {
                    uvs[i] = new Vector2(0, 0);
                }
                else
                {
                    uvs[i] = new Vector2(1, 1);
                }
            }

            int[] tris = new int[mesh.Triangles.Count * 3 * 2];
            index = 0;
            {
                // foreach(var triangle in mesh.Triangles)
                var __enumerator3 = (mesh.Triangles).GetEnumerator();
                while (__enumerator3.MoveNext())
                {
                    var triangle = __enumerator3.Current;
                    {
                        tris[index]     = triangle.P0;
                        tris[index + 1] = triangle.P1;
                        tris[index + 2] = triangle.P2;
                        index          += 3;
                    }
                }
            }

            var e = mesh.Triangles.Reverse();

            {
                // foreach(var triangle in e)
                var __enumerator4 = (e).GetEnumerator();
                while (__enumerator4.MoveNext())
                {
                    var triangle = __enumerator4.Current;
                    {
                        tris[index]     = triangle.P2;
                        tris[index + 1] = triangle.P1;
                        tris[index + 2] = triangle.P0;
                        index          += 3;
                    }
                }
            }

            myFilter.sharedMesh.Clear();

            myFilter.sharedMesh.vertices  = vertex;
            myFilter.sharedMesh.uv        = uvs;
            myFilter.sharedMesh.triangles = tris;
        }
示例#29
0
        private void CreateMesh(List <Vector3> corners, float height, BuildingSettings typeSettings, MeshData data, Vector2 min, Vector2 size)
        {
            _mesh = new TriangleNet.Mesh();

            var inp = new InputGeometry(corners.Count);

            for (int i = 0; i < corners.Count; i++)
            {
                var v = corners[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % corners.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            var vertsStartCount = data.Vertices.Count;

            data.Vertices.AddRange(corners.Select(x => new Vector3(x.x, height, x.z)).ToList());

            foreach (var tri in _mesh.Triangles)
            {
                data.Indices.Add(vertsStartCount + tri.P1);
                data.Indices.Add(vertsStartCount + tri.P0);
                data.Indices.Add(vertsStartCount + tri.P2);
            }

            foreach (var c in corners)
            {
                data.UV.Add(new Vector2((c.x - min.x), (c.z - min.y)));
            }

            if (typeSettings.IsVolumetric)
            {
                float   d = 0f;
                Vector3 v1;
                Vector3 v2;
                int     ind = 0;
                for (int i = 1; i < corners.Count; i++)
                {
                    v1  = data.Vertices[vertsStartCount + i - 1];
                    v2  = data.Vertices[vertsStartCount + i];
                    ind = data.Vertices.Count;
                    data.Vertices.Add(v1);
                    data.Vertices.Add(v2);
                    data.Vertices.Add(new Vector3(v1.x, 0, v1.z));
                    data.Vertices.Add(new Vector3(v2.x, 0, v2.z));

                    d = (v2 - v1).magnitude;

                    data.UV.Add(new Vector2(0, 0));
                    data.UV.Add(new Vector2(d, 0));
                    data.UV.Add(new Vector2(0, height));
                    data.UV.Add(new Vector2(d, height));

                    data.Indices.Add(ind);
                    data.Indices.Add(ind + 2);
                    data.Indices.Add(ind + 1);

                    data.Indices.Add(ind + 1);
                    data.Indices.Add(ind + 2);
                    data.Indices.Add(ind + 3);
                }

                v1  = data.Vertices[vertsStartCount];
                v2  = data.Vertices[vertsStartCount + corners.Count - 1];
                ind = data.Vertices.Count;
                data.Vertices.Add(v1);
                data.Vertices.Add(v2);
                data.Vertices.Add(new Vector3(v1.x, 0, v1.z));
                data.Vertices.Add(new Vector3(v2.x, 0, v2.z));

                d = (v2 - v1).magnitude;

                data.UV.Add(new Vector2(0, 0));
                data.UV.Add(new Vector2(d, 0));
                data.UV.Add(new Vector2(0, height));
                data.UV.Add(new Vector2(d, height));

                data.Indices.Add(ind);
                data.Indices.Add(ind + 1);
                data.Indices.Add(ind + 2);

                data.Indices.Add(ind + 1);
                data.Indices.Add(ind + 3);
                data.Indices.Add(ind + 2);
            }
        }
示例#30
0
        public override InputGeometry Generate(double param0, double param1, double param2)
        {
            int numPoints = GetParamValueInt(1, param1);

            InputGeometry input = new InputGeometry(numPoints + 4);

            double x, y, step = 2 * Math.PI / numPoints;

            double r = GetParamValueInt(2, param2);

            // Generate circle
            for (int i = 0; i < numPoints; i++)
            {
                x = r * Math.Cos(i * step);
                y = r * Math.Sin(i * step);

                input.AddPoint(x, y, 2);
                input.AddSegment(i, (i + 1) % numPoints, 2);
            }

            numPoints = input.Count;

            int numPointsB = GetParamValueInt(0, param0);

            // Box sides are 100 units long
            step = 100.0 / numPointsB;

            // Left box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(-50, -50 + i * step, 1);
            }

            // Top box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(-50 + i * step, 50, 1);
            }

            // Right box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(50, 50 - i * step, 1);
            }

            // Bottom box boundary points
            for (int i = 0; i < numPointsB; i++)
            {
                input.AddPoint(50 - i * step, -50, 1);
            }

            // Add box segments
            for (int i = numPoints; i < input.Count - 1; i++)
            {
                input.AddSegment(i, i + 1, 1);
            }

            // Add last segments which closes the box
            input.AddSegment(input.Count - 1, numPoints, 1);

            // Add hole
            input.AddHole(0, 0);

            return(input);
        }