public static TriangleNet.Mesh TriangulateMesh(List <PointF> path, float minAngle, float maxAngle, bool conformingDelaunay, bool quality, bool convex) { if (path == null) { return(null); } if (path.Count <= 2) { return(null); } List <FTriangle> outTris = new List <FTriangle>(); MeshRenderer.Core.RenderData renderData = new MeshRenderer.Core.RenderData(); MeshRenderer.Core.RenderManager renderManager = new MeshRenderer.Core.RenderManager(); TriangleNet.Geometry.InputGeometry input = new TriangleNet.Geometry.InputGeometry(path.Count); TriangleNet.Mesh mesh = new TriangleNet.Mesh(); input.AddPoint(path[0].X, path[0].Y); for (int i = 1; i < path.Count; i++) { input.AddPoint(path[i].X, path[i].Y); input.AddSegment(i - 1, i); } input.AddSegment(path.Count - 1, 0); renderData.SetInputGeometry(input); renderManager.CreateDefaultControl(); renderManager.SetData(renderData); mesh.Behavior.MinAngle = FMath.Clamp(0, 40, minAngle); mesh.Behavior.MaxAngle = FMath.Clamp(80, 180, maxAngle); mesh.Behavior.ConformingDelaunay = conformingDelaunay; mesh.Behavior.Quality = quality; mesh.Behavior.Convex = convex; mesh.Triangulate(input); return(mesh); }
private Mesh TriangulateMesh() { if (verts.Count > 2) { var tnMesh = new TriangleNet.Mesh(); var input = new TriangleNet.Geometry.InputGeometry(); var localVertices = verts.Select(v => spriteRenderer.transform.InverseTransformPoint(v.position)).ToArray(); for (int i = 0; i < verts.Count; i++) { verts[i].index = i; input.AddPoint(verts[i].position.x, verts[i].position.y); } foreach (var seg in segments) { if (!seg.IsDeleted()) { input.AddSegment(seg.first.index, seg.second.index); } } foreach (var hole in holes) { input.AddHole(hole.x, hole.y); } tnMesh.Triangulate(input); try { Mesh mesh = new Mesh(); mesh.vertices = localVertices; mesh.triangles = tnMesh.Triangles.ToUnityMeshTriangleIndices(); mesh.uv = genUV(mesh.vertices); mesh.RecalculateBounds(); mesh.RecalculateNormals(); return(mesh); } catch { Debug.LogError("Mesh topology was wrong. Make sure you dont have intersecting edges."); throw; } } else { return(null); } }
/// <summary> /// Creates a surface from the given points. /// </summary> /// <param name="points">Input points</param> /// <param name="surface">The type of surface being operated on</param> public void SurfaceFromPoints(Point3dCollection points, SurfaceType surface) { TriangleNet.Mesh mesh = new TriangleNet.Mesh(); TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(points.Count); foreach (Point3d point in points) { geometry.AddPoint(point.X, point.Y, 0, point.Z); } mesh.Triangulate(geometry); if (surface == SurfaceType.Original) { originalSurface = mesh; } else { proposedSurface = mesh; } }
public static void RunPopulationScenario() { WaterTableArgs args = new WaterTableArgs(); Bitmap bmp = new Bitmap(args.inputPath + "rivers.png"); IField2d <float> baseMap = new Utils.FieldFromBitmap(new Bitmap(args.inputPath + "base_heights.png")); baseMap = new ReResField(baseMap, (float)bmp.Width / baseMap.Width); var wtf = Utils.GenerateWaters(bmp, baseMap); Utils.OutputAsColoredMap(wtf, wtf.RiverSystems, bmp, args.outputPath + "colored_map.png"); IField2d <float> rainfall = new Utils.FieldFromBitmap(new Bitmap(args.inputPath + "rainfall.png")); rainfall = new ReResField(rainfall, (float)wtf.Width / rainfall.Width); IField2d <float> wateriness = Utils.GetWaterinessMap(wtf, rainfall); Utils.OutputField(new NormalizedComposition2d <float>(wateriness), bmp, args.outputPath + "wateriness.png"); var locations = Utils.GetSettlementLocations(wtf, wateriness); SparseField2d <float> settlementMap = new SparseField2d <float>(wtf.Width, wtf.Height, 0f); foreach (var loc in locations) { settlementMap.Add(loc, wateriness[loc.y, loc.x]); } Utils.OutputField(settlementMap, bmp, args.outputPath + "settlements.png"); TriangleNet.Geometry.InputGeometry pointSet = new TriangleNet.Geometry.InputGeometry(); foreach (var loc in locations) { pointSet.AddPoint(loc.x, loc.y); } TriangleNet.Mesh mesh = new TriangleNet.Mesh(); mesh.Triangulate(pointSet); //TriangleNet.Tools.AdjacencyMatrix mat = new TriangleNet.Tools.AdjacencyMatrix(mesh); Field2d <float> meshField = new Field2d <float>(settlementMap); foreach (var e in mesh.Edges) { var v0 = mesh.GetVertex(e.P0); var v1 = mesh.GetVertex(e.P1); float distance = (float)Math.Sqrt(Math.Pow(v0.X - v1.X, 2) + Math.Pow(v0.Y - v1.Y, 2)); for (float t = 0f; t <= 1f; t += 0.5f / distance) { int x = (int)Math.Round((1f - t) * v0.X + t * v1.X); int y = (int)Math.Round((1f - t) * v0.Y + t * v1.Y); meshField[y, x] = 0.5f; } meshField[(int)v0.Y, (int)v0.X] = 1f; meshField[(int)v1.Y, (int)v1.X] = 1f; } Utils.OutputField(meshField, bmp, args.outputPath + "mesh.png"); }
private void endBtn_Click(object sender, RoutedEventArgs e) { this._host.CommandReset.Click -= endBtn_Click; this._host.Menues.IsEnabled = true; this._host.UIMessage.Visibility = Visibility.Hidden; //this.JGraphMode = false; this._host.Cursor = Cursors.Arrow; this._host.FloorScene.MouseLeftButtonDown -= FloorScene_MouseLeftButtonDown; try { #region Create Graph HashSet <UV> pnts = new HashSet <UV>(); TriangleNet.Behavior behavior = new Behavior(); TriangleNet.Mesh t_mesh = new TriangleNet.Mesh(); TriangleNet.Geometry.InputGeometry geom = new TriangleNet.Geometry.InputGeometry(); foreach (Node node in JGNodes) { TriangleNet.Data.Vertex vertex = new TriangleNet.Data.Vertex(node.Coordinates.U, node.Coordinates.V, 0); geom.AddPoint(vertex); pnts.Add(node.Coordinates); } t_mesh.Triangulate(geom); var graph = new JGGraph(pnts); foreach (var item in t_mesh.Triangles) { UV a = null; var vrtx = t_mesh.GetVertex(item.P0); if (vrtx != null) { a = new UV(vrtx.X, vrtx.Y); } UV b = null; vrtx = t_mesh.GetVertex(item.P1); if (vrtx != null) { b = new UV(vrtx.X, vrtx.Y); } UV c = null; vrtx = t_mesh.GetVertex(item.P2); if (vrtx != null) { c = new UV(vrtx.X, vrtx.Y); } if (a != null && b != null) { graph.AddConnection(a, b); } if (a != null && c != null) { graph.AddConnection(a, c); } if (c != null && b != null) { graph.AddConnection(c, b); } } #endregion #region Remove Edges with isovists at the ends that do not overlap this.edges = graph.ToEdges(); Dictionary <int, Isovist> IsovistGuid = new Dictionary <int, Isovist>(); foreach (JGVertex item in graph.Vertices) { double x = double.NegativeInfinity; foreach (JGVertex vertex in item.Connections) { var y = item.Point.DistanceTo(vertex.Point); if (y > x) { x = y; } } var isovist = CellularIsovistCalculator.GetIsovist(item.Point, x, BarrierType.Visual, this._host.cellularFloor); IsovistGuid.Add(item.Point.GetHashCode(), isovist); } HashSet <JGEdge> visibleVertexes = new HashSet <JGEdge>(); foreach (JGEdge item in this.edges) { Isovist v1 = null; IsovistGuid.TryGetValue(item.P1.GetHashCode(), out v1); Isovist v2 = null; IsovistGuid.TryGetValue(item.P2.GetHashCode(), out v2); if (v1 != null && v2 != null) { if (v2.VisibleCells.Overlaps(v1.VisibleCells)) { visibleVertexes.Add(item); } } } #endregion #region setting the edges JGEdge.LineToEdgeGuide.Clear(); foreach (JGEdge edge in this.edges) { edge.Clear(); } this.edges = visibleVertexes.ToList <JGEdge>(); foreach (JGEdge item in this.edges) { item.Draw(); } #endregion //cleaning up the used data t_mesh = null; graph = null; geom.Clear(); geom = null; visibleVertexes = null; IsovistGuid = null; //enabling edit mode this.EditGraph.IsEnabled = true; this.DrawJG.IsEnabled = true; this.Hide_show_Menu.IsEnabled = true; this.CreateCovexGraph.Header = "Reset Convex Graph"; } catch (Exception error) { MessageBox.Show(error.Report()); } }