コード例 #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
ファイル: StarInBox.cs プロジェクト: wuxiaod1987/WCAE
        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
ファイル: WaterSurface.cs プロジェクト: muguangyuze/RCAFF
    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();
    }
コード例 #4
0
    /// <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);
    }
コード例 #5
0
        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);
        }
コード例 #6
0
		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
ファイル: EarthFactory.cs プロジェクト: yening520/MapzenGo
        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
ファイル: LanduseFactory.cs プロジェクト: dotlive/uAdventure
        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
ファイル: LanduseFactory.cs プロジェクト: dotlive/uAdventure
        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
ファイル: RectanglePolygon.cs プロジェクト: zon/triangle
        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);
            }
        }
コード例 #20
0
        public static void Triangulate(List <Vector2> vertices, List <IndexedEdge> edges, List <Hole> holes,
                                       ref List <int> indices)
        {
            indices.Clear();

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

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

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

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

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

                triangleMesh.Triangulate(inputGeometry);

                foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles)
                {
                    if (triangle.P0 >= 0 && triangle.P0 < vertices.Count &&
                        triangle.P0 >= 0 && triangle.P1 < vertices.Count &&
                        triangle.P0 >= 0 && triangle.P2 < vertices.Count)
                    {
                        indices.Add(triangle.P0);
                        indices.Add(triangle.P2);
                        indices.Add(triangle.P1);
                    }
                }
            }
        }
コード例 #21
0
ファイル: JsonFile.cs プロジェクト: robu3/triangle.net
        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
ファイル: BuildingFactory.cs プロジェクト: style0912/MapzenGo
        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);
        }