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