public void Write(Mesh mesh, string filename) { if (mesh.Vertices.Count > 0) { format.Write(mesh, filename); } }
/// <summary> /// Export the mesh to EPS format. /// </summary> /// <param name="mesh">The current mesh.</param> /// <param name="filename">The EPS filename.</param> /// <param name="width">The desired width of the image (currently ignored).</param> public void Export(Mesh mesh, string filename, int width) { // Check file name if (String.IsNullOrWhiteSpace(filename)) { filename = String.Format("mesh-{0}.eps", DateTime.Now.ToString("yyyy-M-d-hh-mm-ss")); } if (!filename.EndsWith(".eps")) { filename = Path.ChangeExtension(filename, ".eps"); } UpdateMetrics(mesh.Bounds); using (StreamWriter eps = new StreamWriter(filename)) { WriteHeader(filename, eps); DrawClip(eps); DrawTriangles(eps, mesh, false); DrawSegments(eps, mesh); DrawPoints(eps, mesh, false); WriteTrailer(eps); } }
public void BuildMeshFromGeometry() { triMesh = new TriangleNet.Mesh(); triMesh.behavior.Quality = true; triMesh.behavior.MinAngle = 1f; triMesh.Triangulate(Geometry); // var statistic = new Statistic(); // statistic.Update(triMesh, 1); // Refine by setting a custom maximum area constraint. //triMesh.Refine(statistic.LargestArea / 4); //triMesh.Smooth(); triMesh.Renumber(); UniMesh.vertices = TriangleConverter.ConverteVertices(triMesh.Vertices); UniMesh.RecalculateNormals(); UniMesh.triangles = TriangleConverter.ConverteTriangles(triMesh.Triangles); UniMesh.uv = TriangleConverter.ConverteUVs(triMesh); Debug.Log(string.Format("width {0:0.00}, height {1:0.00}; min {2:0.00}, {3:0.00}; max {4:0.00}, {5:0.00}", triMesh.Bounds.Width, triMesh.Bounds.Height, triMesh.Bounds.Xmin, triMesh.Bounds.Ymin, triMesh.Bounds.Xmax, triMesh.Bounds.Ymax)); }
public void HandleMeshImport(IPolygon geometry, Mesh mesh) { // Previous mesh stats lbNumVert2.Text = "-"; lbNumTri2.Text = "-"; lbNumSeg2.Text = "-"; }
public TriangleLocator(Mesh mesh, IPredicates predicates) { this.mesh = mesh; this.predicates = predicates; sampler = new TriangleSampler(mesh); }
public void HandleMeshUpdate(Mesh mesh) { // Previous mesh stats lbNumVert2.Text = lbNumVert.Text; lbNumTri2.Text = lbNumTri.Text; lbNumSeg2.Text = lbNumSeg.Text; }
public void SetMesh(TriangleNet.Mesh mesh) { int n = mesh.Vertices.Count; int i = 0; // Linear numbering of mesh mesh.Renumber(); // Copy points this.Vertices = new Vector3[n]; foreach (var pt in mesh.Vertices) { this.Vertices[i] = new Vector3((float)pt.X, (float)pt.Y, 0); i++; } // Copy Triangles var triangles = new List <int>(3 * mesh.Triangles.Count); foreach (var tri in mesh.Triangles) { triangles.Add(tri.P0); triangles.Add(tri.P1); triangles.Add(tri.P2); /*if (this.NumberOfRegions > 0) * { * this.TrianglePartition[i++] = tri.Region; * }*/ } this.Triangles = triangles.ToArray(); }
// generate mesh private TriangleNet.Mesh DxfMesh(Polygon poly) { // routine to generate a mesh from the contnet of poly // Set quality and constraint options. var options = new ConstraintOptions() { ConformingDelaunay = true }; var quality = new QualityOptions() { MinimumAngle = 15.0, MaximumArea = mds.minimumMeshArea }; // create the mesh mesh = (TriangleNet.Mesh)poly.Triangulate(options, quality); // make sure there are at least 1000 elements in the mesh while (mesh.Triangles.Count < 1000) { mds.minimumMeshArea = mds.minimumMeshArea / 2; quality.MaximumArea = mds.minimumMeshArea; mesh = (TriangleNet.Mesh)poly.Triangulate(options, quality); } // smooth the mesh var smoother = new SimpleSmoother(); smoother.Smooth(mesh); return(mesh); }
public void HandleMeshChange(Mesh mesh) { // New mesh stats lbNumVert.Text = mesh.Vertices.Count.ToString(); lbNumSeg.Text = mesh.Segments.Count.ToString(); lbNumTri.Text = mesh.Triangles.Count.ToString(); // Update statistics tab angleHistogram1.SetData(statistic.MinAngleHistogram, statistic.MaxAngleHistogram); lbAreaMin.Text = Util.DoubleToString(statistic.SmallestArea); lbAreaMax.Text = Util.DoubleToString(statistic.LargestArea); lbEdgeMin.Text = Util.DoubleToString(statistic.ShortestEdge); lbEdgeMax.Text = Util.DoubleToString(statistic.LongestEdge); lbAngleMin.Text = Util.AngleToString(statistic.SmallestAngle); lbAngleMax.Text = Util.AngleToString(statistic.LargestAngle); // Update quality if (quality == null) { quality = new QualityMeasure(); } quality.Update(mesh); lbQualAlphaMin.Text = Util.DoubleToString(quality.AlphaMinimum); lbQualAlphaAve.Text = Util.DoubleToString(quality.AlphaAverage); lbQualAspectMin.Text = Util.DoubleToString(quality.Q_Minimum); lbQualAspectAve.Text = Util.DoubleToString(quality.Q_Average); }
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 NewLocation(Mesh mesh, IPredicates predicates) { this.mesh = mesh; this.predicates = predicates; this.behavior = mesh.behavior; }
public override void Start() { base.Start(); _mesh = new TriangleNet.Mesh(); Query = (geo) => geo["geometry"]["type"].str == "Polygon"; Order = 2; MergeMeshes = true; _useTriangulationNet = true; var bfs = ScriptableObject.CreateInstance("BagBuildingFactorySettings") as BagBuildingFactorySettings; bfs.DefaultBuilding = createBuildingSettings(BagFunctionType.Unknown, 3, 6, "Default"); bfs.SettingsBuildings = new List <BagBuildingSettings> { createBuildingSettings(BagFunctionType.Health, 16, 16, "Hospital"), createBuildingSettings(BagFunctionType.Education, 10, 10, "University"), createBuildingSettings(BagFunctionType.Residential, 7, 7, "Residential"), createBuildingSettings(BagFunctionType.Office, 4, 8, "Industrial"), createBuildingSettings(BagFunctionType.Industrial, 4, 8, "Industrial"), createBuildingSettings(BagFunctionType.Shop, 4, 10, "Commercial"), createBuildingSettings(BagFunctionType.Meeting, 4, 10, "Commercial"), createBuildingSettings(BagFunctionType.Lodgings, 4, 10, "Commercial"), createBuildingSettings(BagFunctionType.Other, 4, 10, "Default"), createBuildingSettings(BagFunctionType.Sport, 12, 12, "Industrial") }; FactorySettings = bfs; }
/// <summary> /// Get a random sample set of triangle keys. /// </summary> /// <returns>Array of triangle keys.</returns> public int[] GetSamples(Mesh mesh) { // TODO: Using currKeys to check key availability? List<int> randSamples = new List<int>(samples); int range = triangleCount / samples; int key; for (int i = 0; i < samples; i++) { // Yeah, rand should be equally distributed, but just to make // sure, use a range variable... key = rand.Next(i * range, (i + 1) * range - 1); if (!mesh.triangles.Keys.Contains(keys[key])) { // Keys collection isn't up to date anymore! this.Update(mesh, true); i--; } else { randSamples.Add(keys[key]); } } return randSamples.ToArray(); }
public void Initiate() { heights = new List <float>(); polygon = new Polygon(); if (randomPoints == true) { for (int i = 0; i < pointDensity; i++) { var x = Random.Range(.0f, sizeX); var y = Random.Range(.0f, sizeY); polygon.Add(new Vertex(x, y)); } } else { poissonPoints = PoissonDiscSampling.GeneratePoints(minDistancePerPoint, new Vector2(sizeX, sizeY), rejectionSamples); for (int i = 0; i < poissonPoints.Count; i++) { polygon.Add(new Vertex(poissonPoints[i].x, poissonPoints[i].y)); } } ConstraintOptions constraints = new ConstraintOptions(); constraints.ConformingDelaunay = true; mesh = polygon.Triangulate(constraints) as TriangleNet.Mesh; ShapeTerrain(); GenerateMesh(); }
/// <summary> /// Export the mesh to EPS format. /// </summary> /// <param name="mesh">The current mesh.</param> /// <param name="filename">The EPS filename.</param> /// <param name="width">The desired width of the image (currently ignored).</param> public void Export(Mesh mesh, string filename, int width) { // Check file name if (String.IsNullOrWhiteSpace(filename)) { filename = String.Format("mesh-{0}.eps", DateTime.Now.ToString("yyyy-M-d-hh-mm-ss")); } if (!filename.EndsWith(".eps")) { filename = Path.ChangeExtension(filename, ".eps"); } UpdateMetrics(mesh.Bounds); using (var eps = new EpsDocument(filename, ps)) { int n = mesh.Vertices.Count; // Size of the points. eps.DefaultPointSize = (n < 100) ? 3 : ((n < 500) ? 2 : 1); eps.WriteHeader(); // Draw a gray border around the page. eps.SetColor(ColorBorder); eps.DrawRectangle(GetRectangle(ps)); // Define a clipping polygon. eps.SetClip(GetRectangle(clip)); // Draw edges. eps.AddComment("Draw edges."); eps.SetStroke(0.4f, ColorLines); foreach (var e in EdgeIterator.EnumerateEdges(mesh)) { eps.DrawLine(Transform(e.GetVertex(0)), Transform(e.GetVertex(1))); } // Draw Segments. eps.AddComment("Draw Segments."); eps.SetStroke(0.8f, ColorSegments); foreach (var s in mesh.Segments) { eps.DrawLine(Transform(s.GetVertex(0)), Transform(s.GetVertex(1))); } // Draw points. eps.AddComment("Draw points."); eps.SetColor(ColorPoints); foreach (var node in mesh.Vertices) { eps.DrawPoint(Transform(node)); } } }
public Triangle_2D() { TriangleMesh = new TriangleNet.Mesh(); Geometry = new InputGeometry(); InnerHole = new List <List <Point> >(); InnerPolygon = new List <List <Point> >(); OuterPolygon = new List <List <Point> >(); }
private static ICollection <Triangle> Triangulate(InputGeometry input) { TriangleNet.Mesh mesh = new TriangleNet.Mesh(); mesh.Behavior.ConformingDelaunay = true; mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine; mesh.Behavior.Convex = false; mesh.Triangulate(input); return(mesh.Triangles); }
private void DrawTriangles(StreamWriter svg, Mesh mesh, bool label) { svg.Write("\t<path d=\""); StringBuilder labels = new StringBuilder(); Vertex v1, v2, v3; double x1, y1, x2, y2, x3, y3, xa, ya; int i = 1; foreach (var tri in mesh.Triangles) { v1 = tri.GetVertex(0); v2 = tri.GetVertex(1); v3 = tri.GetVertex(2); x1 = scale * v1.X; y1 = scale * v1.Y; x2 = scale * v2.X; y2 = scale * v2.Y; x3 = scale * v3.X; y3 = scale * v3.Y; svg.Write("M {0:0.#},{1:0.#} L {2:0.#},{3:0.#} {4:0.#},{5:0.#} Z ", x1, y1, x2, y2, x3, y3); if (i % LINEBREAK_COUNT == 0) { svg.WriteLine(); svg.Write("\t"); } i++; if (label) { xa = (x1 + x2 + x3) / 3.0; ya = (y1 + y2 + y3) / 3.0; labels.AppendFormat("<text x=\"{0:0.#}\" y=\"{1:0.#}\">{2}</text>", xa, ya, tri.ID); labels.AppendLine(); } } svg.WriteLine("\" style=\"stroke:#c2c2c2; fill:none; stroke-linejoin:bevel;\"/>"); // Label the triangles. if (label) { svg.WriteLine("\t<g font-family=\"Verdana\" font-size=\"11\" fill=\"black\">"); svg.Write(labels.ToString()); svg.WriteLine("\t<g/>"); } }
private void FormTopology_Load(object sender, EventArgs e) { mesh = (Mesh)GenericMesher.StructuredMesh(new Rectangle(0.0, 0.0, 4.0, 4.0), 4, 4); renderControl.Initialize(mesh); topoControlView.PrimitiveCommandInvoked += PrimitiveCommandHandler; current = default(Otri); }
private void ExportEps(Mesh mesh, string filename, int width, bool compress) { var eps = new EpsImage(); eps.Export(mesh, filename, width); if (compress) { CompressFile(filename, true); } }
private void ExportSvg(Mesh mesh, string filename, int width, bool compress) { var svg = new SvgImage(); svg.Export(mesh, filename, width); if (compress) { CompressFile(filename, true); } }
private static Mesh buildMesh(Dictionary<Point, Color> pointIndex) { InputGeometry g = new InputGeometry(); foreach (var value in pointIndex) { g.AddPoint(value.Key.X, value.Key.Y); } Mesh m = new Mesh(); m.Triangulate(g); return m; }
public Quality(Mesh mesh) { logger = SimpleLog.Instance; badsubsegs = new Queue<BadSubseg>(); queue = new BadTriQueue(); this.mesh = mesh; this.behavior = mesh.behavior; newLocation = new NewLocation(mesh); }
private void DrawPoints(StreamWriter svg, Mesh mesh, bool label) { int n = mesh.Vertices.Count; int circle_size = 1; if (n < 100) { circle_size = 4; } else if (n < 500) { circle_size = 3; } else if (n < 1000) { circle_size = 2; } svg.WriteLine(" <g style=\"fill: #006400\">"); double x, y; StringBuilder labels = new StringBuilder(); foreach (var node in mesh.Vertices) { x = scale * node.X; y = scale * node.Y; svg.WriteLine(" <circle cx=\"{0}\" cy=\"{1}\" r=\"{2}\" />", x.ToString("0.0", Util.Nfi), y.ToString("0.0", Util.Nfi), circle_size); if (label) { labels.AppendFormat("<text x=\"{0}\" y=\"{1}\">{2}</text>", x.ToString("0.0", Util.Nfi), y.ToString("0.0", Util.Nfi), node.ID); labels.AppendLine(); } } svg.WriteLine(" </g>"); // Label the nodes. if (label) { svg.WriteLine(" <g font-family=\"Verdana\" font-size=\"11\" fill=\"black\">"); svg.Write(labels.ToString()); svg.WriteLine(" <g/>"); } }
/// <summary> /// Export the mesh to SVG format. /// </summary> /// <param name="mesh">The current mesh.</param> /// <param name="filename">The SVG filename.</param> /// <param name="width">The desired width of the image.</param> public void Export(Mesh mesh, string filename, int width) { // Check file name if (String.IsNullOrWhiteSpace(filename)) { filename = String.Format("mesh-{0}.svg", DateTime.Now.ToString("yyyy-M-d-hh-mm-ss")); } if (!filename.EndsWith(".svg")) { filename = Path.ChangeExtension(filename, ".svg"); } if (width < 200) { width = 200; } var bounds = mesh.Bounds; float margin = 0.05f * (float)bounds.Width; scale = width / ((float)bounds.Width + 2 * margin); int x_offset = -(int)((bounds.Left - margin) * scale); int y_offset = (int)((bounds.Top + margin) * scale); int height = (int)((bounds.Height + 2 * margin) * scale); using (var svg = new FormattingStreamWriter(filename)) { svg.WriteLine("<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\""); svg.WriteLine("\twidth=\"{0}px\" height=\"{1}px\"", width, height); svg.WriteLine("\tviewBox=\"0 0 {0} {1}\">", width, height); svg.WriteLine("<g transform=\"translate({0}, {1}) scale(1,-1)\">", x_offset, y_offset); DrawTriangles(svg, mesh, false); //DrawEdges(svg, mesh); DrawSegments(svg, mesh); DrawPoints(svg, mesh, false); svg.WriteLine("</g>"); svg.WriteLine("</svg>"); } }
/// <summary> /// Export the mesh to PNG format. /// </summary> /// <param name="mesh">The current mesh.</param> /// <param name="filename">The PNG filename.</param> /// <param name="type">Image type (0 = png, 1 = eps, 2 = svg).</param> /// <param name="width">The desired width of the image.</param> /// <param name="compress">Use GZip compression (only eps or svg).</param> public void Export(Mesh mesh, string filename, int type, int width, bool compress) { if (type == 1) { ExportEps(mesh, filename, width, compress); } else if (type == 2) { ExportSvg(mesh, filename, width, compress); } else { ImageRenderer.Save(mesh, filename, width); } }
/// <summary> /// Initializes a new instance of the <see cref="MeshRenderer" /> class. /// </summary> public TopologyRenderer(Mesh mesh) { this.mesh = mesh; points = new PointF[mesh.Vertices.Count]; int k = 0; foreach (var v in mesh.Vertices) { points[k++] = new PointF((float)v.X, (float)v.Y); } font = new Font("Arial", 7.5f); fontTri = new Font("Arial", 12f, FontStyle.Bold); }
private void CreateMesh(InputGeometry corners, MeshData meshdata) { var mesh = new TriangleNet.Mesh(); mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine; mesh.Behavior.Quality = true; mesh.Triangulate(corners); var vertsStartCount = meshdata.Vertices.Count; meshdata.Vertices.AddRange(corners.Points.Select(x => new Vector3((float)x.X, 0, (float)x.Y)).ToList()); foreach (var tri in mesh.Triangles) { meshdata.Indices.Add(vertsStartCount + tri.P1); meshdata.Indices.Add(vertsStartCount + tri.P0); meshdata.Indices.Add(vertsStartCount + tri.P2); } }
/// <summary> /// Initialize the graphics buffer (should be called in the forms load event). /// </summary> public void Initialize(Mesh mesh) { renderer = new TopologyRenderer(mesh); zoom = new Projection(this.ClientRectangle); //zoom.ClipMargin = 10.0f; var b = mesh.Bounds; zoom.Initialize(new BoundingBox((float)b.Left, (float)b.Right, (float)b.Bottom, (float)b.Top)); InitializeBuffer(); initialized = true; this.Render(); }
public static Vector2[] ConverteUVs(TriangleNet.Mesh mesh) { double w = mesh.Bounds.Width; double h = mesh.Bounds.Height; double min_x = mesh.Bounds.Xmin; double min_y = mesh.Bounds.Ymin; int n = mesh.Vertices.Count; Vector2[] result = new Vector2[n]; int i = 0; foreach (var pt in mesh.Vertices.Select(p => new Vector2((float)(p.X / w - min_x), (float)(p.Y / h - min_y)))) { result[i] = pt; i++; } return(result); }
void CreateMap(TriangleNet.Mesh m, float maxz, float yOffset) { Dictionary <int, TriangleNet.Geometry.Vertex> id2vert = new Dictionary <int, TriangleNet.Geometry.Vertex>(); List <TriangleNet.Geometry.Vertex> vertices = new List <TriangleNet.Geometry.Vertex>(); List <ISegment> segments = new List <ISegment>(); foreach (TriangleNet.Geometry.Vertex v in m.Vertices) { id2vert[v.id] = v; vertices.Add(v); } foreach (Edge e in m.Edges) { TriangleNet.Geometry.Vertex v1 = id2vert[e.P0]; TriangleNet.Geometry.Vertex v2 = id2vert[e.P1]; segments.Add(new Segment(v1, v2)); } CreateMap(vertices, segments, maxz, yOffset); }
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); }
/// <summary> /// Update sampling parameters if mesh changed. /// </summary> /// <param name="mesh">Current mesh.</param> public void Update(Mesh mesh, bool forceUpdate) { int count = mesh.triangles.Count; // TODO: Is checking the triangle count a good way to monitor mesh changes? if (triangleCount != count || forceUpdate) { triangleCount = count; // The number of random samples taken is proportional to the cube root of // the number of triangles in the mesh. The next bit of code assumes // that the number of triangles increases monotonically (or at least // doesn't decrease enough to matter). while (samplefactor * samples * samples * samples < count) { samples++; } // TODO: Is there a way not calling ToArray()? keys = mesh.triangles.Keys.ToArray(); } }
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); }
private void HandleNewInput() { // Reset mesh mesh = null; // Reset state settings.RefineMode = false; settings.ExceptionThrown = false; // Reset buttons btnMesh.Enabled = true; btnMesh.Text = "Triangulate"; btnSmooth.Enabled = false; // Update Statistic view statisticView.HandleNewInput(input); // Clear voronoi menuViewVoronoi.Checked = false; // Disable menu items menuFileSave.Enabled = false; menuFileExport.Enabled = false; menuViewVoronoi.Enabled = false; menuToolsCheck.Enabled = false; menuToolsRcm.Enabled = false; // Render input renderData.SetInputGeometry(input); renderManager.SetData(renderData); // Update window caption this.Text = "Triangle.NET - Mesh Explorer - " + settings.CurrentFile; }
/// <summary> /// Copy mesh data. /// </summary> public void SetMesh(Mesh mesh) { // Clear unused buffers this.Segments = null; this.VoronoiPoints = null; this.VoronoiEdges = null; int n = mesh.Vertices.Count; int i = 0; this.NumberOfInputPoints = mesh.NumberOfInputPoints; // Linear numbering of mesh mesh.Renumber(); // Copy points this.Points = new float[2 * n]; foreach (var pt in mesh.Vertices) { this.Points[2 * i] = (float)pt.X; this.Points[2 * i + 1] = (float)pt.Y; i++; } // Copy segments n = mesh.Segments.Count; if (n > 0 && mesh.IsPolygon) { var segments = new List<uint>(2 * n); foreach (var seg in mesh.Segments) { segments.Add((uint)seg.P0); segments.Add((uint)seg.P1); } this.Segments = segments.ToArray(); } // Copy edges var edges = new List<uint>(2 * mesh.NumberOfEdges); EdgeEnumerator e = new EdgeEnumerator(mesh); while (e.MoveNext()) { edges.Add((uint)e.Current.P0); edges.Add((uint)e.Current.P1); } this.MeshEdges = edges.ToArray(); if (this.NumberOfRegions > 0) { this.TrianglePartition = new int[mesh.Triangles.Count]; } i = 0; // Copy Triangles var triangles = new List<uint>(3 * mesh.Triangles.Count); foreach (var tri in mesh.Triangles) { triangles.Add((uint)tri.P0); triangles.Add((uint)tri.P1); triangles.Add((uint)tri.P2); if (this.NumberOfRegions > 0) { this.TrianglePartition[i++] = tri.Region; } } this.Triangles = triangles.ToArray(); this.Bounds = new BoundingBox( (float)mesh.Bounds.Xmin, (float)mesh.Bounds.Xmax, (float)mesh.Bounds.Ymin, (float)mesh.Bounds.Ymax); }
public Carver(Mesh mesh) { this.mesh = mesh; this.viri = new List<Triangle>(); }
private void RecalculateVertices() { if (points.Count < 2) { return; } vertexPositionColorArray = null; var lineColor = Color.Red; #region clipper List<IntPoint> clipperPath = new List<IntPoint>(points.Count); foreach (var point in points) { clipperPath.Add(new IntPoint(point.X * ClipperScale, point.Y * ClipperScale)); } List<List<IntPoint>> clipperSolution = new List<List<IntPoint>>(); ClipperOffset clipperOffset = new ClipperOffset(); clipperOffset.AddPath(clipperPath, JoinType.jtRound, EndType.etOpenRound); clipperOffset.Execute(ref clipperSolution, lineThickness / 2.0f * ClipperScale); #endregion #region triangle.net InputGeometry InputGeometry = new InputGeometry(); Mesh TriangleMesh = new Mesh(); for (int iii = 0; iii < clipperSolution.Count; iii++) { var trianglePath = clipperSolution[iii].Select(p => new TrianglePoint(p.X / (float)ClipperScale, p.Y / (float)ClipperScale)).ToList(); if (iii == 0) { InputGeometry.AddRing(trianglePath); } else { InputGeometry.AddRingAsHole(trianglePath); } } #endregion if (InputGeometry.Count > 0) { TriangleMesh.Triangulate(InputGeometry); vertexPositionColorArray = TriangleMesh.GetTriangleList().Select(v => new VertexPositionColor(new Vector3((float)v.X, (float)v.Y, 0.0f), lineColor)).ToArray(); vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, vertexPositionColorArray.Length, BufferUsage.WriteOnly); vertexBuffer.SetData<VertexPositionColor>(vertexPositionColorArray); } }
/// <summary> /// Test the mesh for topological consistency. /// </summary> public static bool IsConsistent(Mesh mesh) { Otri tri = default(Otri); Otri oppotri = default(Otri), oppooppotri = default(Otri); Vertex org, dest, apex; Vertex oppoorg, oppodest; var logger = Log.Instance; // Temporarily turn on exact arithmetic if it's off. bool saveexact = Behavior.NoExact; Behavior.NoExact = false; int horrors = 0; // Run through the list of triangles, checking each one. foreach (var t in mesh.triangles) { tri.tri = t; // Check all three edges of the triangle. for (tri.orient = 0; tri.orient < 3; tri.orient++) { org = tri.Org(); dest = tri.Dest(); if (tri.orient == 0) { // Only test for inversion once. // Test if the triangle is flat or inverted. apex = tri.Apex(); if (predicates.CounterClockwise(org, dest, apex) <= 0.0) { if (Log.Verbose) { logger.Warning(String.Format("Triangle is flat or inverted (ID {0}).", t.id), "MeshValidator.IsConsistent()"); } horrors++; } } // Find the neighboring triangle on this edge. tri.Sym(ref oppotri); if (oppotri.tri.id != Mesh.DUMMY) { // Check that the triangle's neighbor knows it's a neighbor. oppotri.Sym(ref oppooppotri); if ((tri.tri != oppooppotri.tri) || (tri.orient != oppooppotri.orient)) { if (tri.tri == oppooppotri.tri && Log.Verbose) { logger.Warning("Asymmetric triangle-triangle bond: (Right triangle, wrong orientation)", "MeshValidator.IsConsistent()"); } horrors++; } // Check that both triangles agree on the identities // of their shared vertices. oppoorg = oppotri.Org(); oppodest = oppotri.Dest(); if ((org != oppodest) || (dest != oppoorg)) { if (Log.Verbose) { logger.Warning("Mismatched edge coordinates between two triangles.", "MeshValidator.IsConsistent()"); } horrors++; } } } } // Check for unconnected vertices mesh.MakeVertexMap(); foreach (var v in mesh.vertices.Values) { if (v.tri.tri == null && Log.Verbose) { logger.Warning("Vertex (ID " + v.id + ") not connected to mesh (duplicate input vertex?)", "MeshValidator.IsConsistent()"); } } // Restore the status of exact arithmetic. Behavior.NoExact = saveexact; return (horrors == 0); }
/// <summary> /// Ensure that the mesh is (constrained) Delaunay. /// </summary> private static bool IsDelaunay(Mesh mesh, bool constrained) { Otri loop = default(Otri); Otri oppotri = default(Otri); Osub opposubseg = default(Osub); Vertex org, dest, apex; Vertex oppoapex; bool shouldbedelaunay; var logger = Log.Instance; // Temporarily turn on exact arithmetic if it's off. bool saveexact = Behavior.NoExact; Behavior.NoExact = false; int horrors = 0; var inf1 = mesh.infvertex1; var inf2 = mesh.infvertex2; var inf3 = mesh.infvertex3; // Run through the list of triangles, checking each one. foreach (var tri in mesh.triangles) { loop.tri = tri; // Check all three edges of the triangle. for (loop.orient = 0; loop.orient < 3; loop.orient++) { org = loop.Org(); dest = loop.Dest(); apex = loop.Apex(); loop.Sym(ref oppotri); oppoapex = oppotri.Apex(); // Only test that the edge is locally Delaunay if there is an // adjoining triangle whose pointer is larger (to ensure that // each pair isn't tested twice). shouldbedelaunay = (loop.tri.id < oppotri.tri.id) && !Otri.IsDead(oppotri.tri) && (oppotri.tri.id != Mesh.DUMMY) && (org != inf1) && (org != inf2) && (org != inf3) && (dest != inf1) && (dest != inf2) && (dest != inf3) && (apex != inf1) && (apex != inf2) && (apex != inf3) && (oppoapex != inf1) && (oppoapex != inf2) && (oppoapex != inf3); if (constrained && mesh.checksegments && shouldbedelaunay) { // If a subsegment separates the triangles, then the edge is // constrained, so no local Delaunay test should be done. loop.Pivot(ref opposubseg); if (opposubseg.seg.hash != Mesh.DUMMY) { shouldbedelaunay = false; } } if (shouldbedelaunay) { if (predicates.NonRegular(org, dest, apex, oppoapex) > 0.0) { if (Log.Verbose) { logger.Warning(String.Format("Non-regular pair of triangles found (IDs {0}/{1}).", loop.tri.id, oppotri.tri.id), "MeshValidator.IsDelaunay()"); } horrors++; } } } } // Restore the status of exact arithmetic. Behavior.NoExact = saveexact; return (horrors == 0); }
public void MakeMesh(Vector3[] _vertices) { Polygon polygon = new Polygon(); elevations.Clear(); for (int i = 0; i < _vertices.Length; i++) { polygon.Add(new Vertex(_vertices[i].x, _vertices[i].z)); elevations.Add(_vertices[i].y); } Debug.Log("Length of polygon vertex-count: " + polygon.Count + "\n Length of elevations:" + elevations.Count); int trianglesInChunk = 400; TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true, Convex = false, SegmentSplitting = 1 }; mesh = (TriangleNet.Mesh)polygon.Triangulate(options); /* * foreach (Vertex vert in mesh.Vertices) * { * elevations.Add(7); * } */ Debug.Log("Mesh.vertices at breakpoint: " + mesh.Vertices.Count); // Instantiate an enumerator to go over the Triangle.Net triangles - they don't // provide any array-like interface for indexing IEnumerator <Triangle> triangleEnumerator = mesh.Triangles.GetEnumerator(); // Create more than one chunk, if necessary for (int chunkStart = 0; chunkStart < mesh.Triangles.Count; chunkStart += trianglesInChunk) { // Vertices in the unity mesh List <Vector3> vertices = new List <Vector3>(); // Per-vertex normals List <Vector3> normals = new List <Vector3>(); // Per-vertex UVs - unused here, but Unity still wants them List <Vector2> uvs = new List <Vector2>(); // Triangles - each triangle is made of three indices in the vertices array List <int> triangles = new List <int>(); // Iterate over all the triangles until we hit the maximum chunk size int chunkEnd = chunkStart + trianglesInChunk; for (int i = chunkStart; i < chunkEnd; i++) { if (!triangleEnumerator.MoveNext()) { // If we hit the last triangle before we hit the end of the chunk, stop break; } // Get the current triangle Triangle triangle = triangleEnumerator.Current; // For the triangles to be right-side up, they need // to be wound in the opposite direction Vector3 v0 = GetPoint3D(triangle.vertices[2].id); Vector3 v1 = GetPoint3D(triangle.vertices[1].id); Vector3 v2 = GetPoint3D(triangle.vertices[0].id); // This triangle is made of the next three vertices to be added triangles.Add(vertices.Count); triangles.Add(vertices.Count + 1); triangles.Add(vertices.Count + 2); triangles.Add(vertices.Count); triangles.Add(vertices.Count + 2); triangles.Add(vertices.Count + 1); // Add the vertices vertices.Add(v0); vertices.Add(v1); vertices.Add(v2); // Compute the normal - flat shaded, so the vertices all have the same normal Vector3 normal = Vector3.Cross(v1 - v0, v2 - v0); normals.Add(normal); normals.Add(normal); normals.Add(normal); // If you want to texture your terrain, UVs are important, // but I just use a flat color so put in dummy coords uvs.Add(new Vector2(0.0f, 0.0f)); uvs.Add(new Vector2(0.0f, 0.0f)); uvs.Add(new Vector2(0.0f, 0.0f)); } // Create the actual Unity mesh object UnityEngine.Mesh chunkMesh = new UnityEngine.Mesh(); chunkMesh.vertices = vertices.ToArray(); chunkMesh.uv = uvs.ToArray(); chunkMesh.triangles = triangles.ToArray(); chunkMesh.normals = normals.ToArray(); // Instantiate the GameObject which will display this chunk Transform chunk = Instantiate <Transform>(chunkPrefab, transform.position, transform.rotation); chunk.GetComponent <MeshFilter>().mesh = chunkMesh; //chunk.GetComponent<MeshCollider>().sharedMesh = chunkMesh; chunk.transform.parent = transform; } }
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()); } }
void GenMap() { /* * <settings> */ int starsAm = 10000; // What percentage of space is taken up by stars. int starDensity = 20; // Minimal corridor length relative to maximal star size. float minCorridorLengthCoeff = 3.0f; // What percentage of space is taken up by corridors. int corridorDensity = 60; float maxz = 3.0f; /* * </settings> */ float max_star_size = Mathf.Max(pos_star_sizes); Debug.Log("Max star size: " + max_star_size); float min_corridor_length = max_star_size * minCorridorLengthCoeff; float min_corridor_length_squared = Mathf.Pow(min_corridor_length, 2); int starsx = Mathf.RoundToInt(Mathf.Sqrt(starsAm)); int starsy = starsx; float width = (starsx * max_star_size) + ((starsx - 1) * min_corridor_length); float height = (starsy * max_star_size) + ((starsy - 1) * min_corridor_length); background.transform.localScale = new Vector3(width * 0.11f, 1.0f, height * 0.11f); background.GetComponent <MeshRenderer>().material.SetTextureScale("_MainTex", new Vector2(width / 70.0f, height / 70.0f)); Debug.Log("Dimensions: " + width + ", " + height); float minx = width * -0.5f; float miny = height * -0.5f; float maxx = width * 0.5f; float maxy = height * 0.5f; float max_offset_x = (width / starsx) - ((min_corridor_length - max_star_size) * 0.5f); float max_offset_y = (height / starsy) - ((min_corridor_length - max_star_size) * 0.5f); Debug.Log("Offsets: " + max_offset_x + ", " + max_offset_y); Rectangle bounds = new Rectangle(minx, miny, width, height); TriangleNet.Mesh mesh = (TriangleNet.Mesh)GenericMesher.StructuredMesh(bounds, starsx - 1, starsy - 1); List <TriangleNet.Geometry.Vertex> stars = new List <TriangleNet.Geometry.Vertex>(); List <TriangleNet.Geometry.Vertex> shuffled_verts = new List <TriangleNet.Geometry.Vertex>(mesh.Vertices); shuffled_verts.Shuffle(); int stars_amount = 0; foreach (TriangleNet.Geometry.Vertex v in shuffled_verts) { if (stars_amount > 3 && Random.Range(0, 101) > starDensity) { continue; } stars.Add(v); stars_amount++; } GenericMesher gm = new GenericMesher(new SweepLine()); mesh = (TriangleNet.Mesh)gm.Triangulate(stars); StandardVoronoi sv = new StandardVoronoi(mesh); Polygon final = new Polygon(sv.Vertices.Count); Dictionary <int, TriangleNet.Geometry.Vertex> good_stars = new Dictionary <int, TriangleNet.Geometry.Vertex>(); Dictionary <int, int> bad2goodstar = new Dictionary <int, int>(); List <int> outBoundStars = new List <int>(); foreach (TriangleNet.Topology.DCEL.Vertex v in sv.Vertices) { if (v.x < minx || v.x > maxx || v.y < miny || v.y > maxy) { outBoundStars.Add(v.id); continue; } bool invalid = false; foreach (TriangleNet.Geometry.Vertex other in good_stars.Values) { Vector2 v1 = new Vector2((float)v.x, (float)v.y); Vector2 v2 = new Vector2((float)other.x, (float)other.y); if ((v2 - v1).sqrMagnitude < min_corridor_length_squared) { invalid = true; bad2goodstar[v.id] = other.id; } } if (invalid) { continue; } TriangleNet.Geometry.Vertex new_v = new TriangleNet.Geometry.Vertex(v.x, v.y); new_v.id = v.id; good_stars[v.id] = new_v; final.Add(new_v); } List <Segment> good_segments = new List <Segment>(); foreach (Edge e in sv.Edges) { if (outBoundStars.Contains(e.P0) || outBoundStars.Contains(e.P1)) { continue; } int P0_id; int P1_id; if (bad2goodstar.ContainsKey(e.P0)) { P0_id = bad2goodstar[e.P0]; } else { P0_id = e.P0; } if (bad2goodstar.ContainsKey(e.P1)) { P1_id = bad2goodstar[e.P1]; } else { P1_id = e.P1; } if (P0_id == P1_id) { continue; } good_segments.Add(new Segment(good_stars[P0_id], good_stars[P1_id])); } Dictionary <int, List <int> > connected_stars = new Dictionary <int, List <int> >(); foreach (Segment s in good_segments) { if (!connected_stars.ContainsKey(s.P0)) { connected_stars[s.P0] = new List <int>(); } connected_stars[s.P0].Add(s.P1); if (!connected_stars.ContainsKey(s.P1)) { connected_stars[s.P1] = new List <int>(); } connected_stars[s.P1].Add(s.P0); } Debug.Log("Currently edges: " + good_segments.Count); List <Segment> temp_segments = new List <Segment>(good_segments); temp_segments.Shuffle(); foreach (Segment s in temp_segments) { if (Random.Range(0, 101) > corridorDensity && RemovalConnectionsCheck(connected_stars, s.P0, s.P1)) { connected_stars[s.P0].Remove(s.P1); connected_stars[s.P1].Remove(s.P0); good_segments.Remove(s); } } foreach (Segment s in good_segments) { final.Add(s); } Debug.Log("Stars after everything: " + final.Points.Count); Debug.Log("Corridors after everything: " + good_segments.Count); CreateMap(final, maxz, 0.0f); }
// Dictionary<string, double> Results = new Dictionary<string, double>(); public void ReadDXF(string dxfFileName, ref Section section) { mds = new MesherDataSet(); string filename = dxfFileName; List <Polygon> polygons = getArea(filename); double d = 0.0; double[] aluFrame1dim = singledepth(polygons.ElementAt(0)); double[] aluFrame2dim = singledepth(polygons.ElementAt(1)); if (aluFrame1dim[2] > aluFrame2dim[2]) { d = aluFrame1dim[2] - aluFrame2dim[3]; } else { d = aluFrame2dim[2] - aluFrame1dim[3]; } section.d = d / 10; double Zoo = 0.0; double Zou = 0.0; double Zuo = 0.0; double Zuu = 0.0; for (int i = 0; i < polygons.Count; i++) { poly = polygons.ElementAt(i); mesh = DxfMesh(poly); // compute mesh basic property MesherBasicProperty(); double[] Z = singledepth(poly); if (i == 0) { Zoo = Z.ElementAt(0); Zou = Z.ElementAt(1); section.Zoo = Zoo / 10; section.Zou = Zou / 10; section.Ao = mds.totalMeshArea / 100; section.Io = mds.meshIxxC / 10000; section.Ioyy = mds.meshIyyC / 10000; // by Wei section.Wo = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 2.7 / 1000; // weight in N/cm } else if (i == 1) { Zuo = Z.ElementAt(0); Zuu = Z.ElementAt(1); section.Zuo = Zuo / 10; section.Zuu = Zuu / 10; section.Au = mds.totalMeshArea / 100; section.Iu = mds.meshIxxC / 10000; section.Iuyy = mds.meshIyyC / 10000; // by Wei section.Wu = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 2.7 / 1000; // weight in N/cm } else if (i == 2) { section.Wl = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 1.2 * 1.27 / 1000; } else if (i == 3) { section.Wr = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 1.2 * 1.27 / 1000; } } section.Weight = section.Wo + section.Wu + section.Wl + section.Wr; }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="contour"></param> void AddMunicipalDivision(string name, List <DVector2> contour) { if (municipalDivisions.ContainsKey(name)) { return; } var mesh = new TriangleNet.Mesh(); mesh.Behavior.Quality = true; mesh.Behavior.MinAngle = 25; mesh.Behavior.Convex = false; var ig = new InputGeometry(); ig.AddPoint(contour[0].X, contour[0].Y); for (int v = 1; v < contour.Count; v++) { ig.AddPoint(contour[v].X, contour[v].Y); ig.AddSegment(v - 1, v); } ig.AddSegment(contour.Count - 1, 0); mesh.Triangulate(ig); int n = mesh.Vertices.Count; mesh.Renumber(); // Vertices var moVerts = new GeoVert[n]; int i = 0; foreach (var pt in mesh.Vertices) { moVerts[i] = new GeoVert { Lon = pt.X * Math.PI / 180.0, Lat = pt.Y * Math.PI / 180.0, Position = Vector3.Zero, Tex = Vector4.Zero, Color = Color.White }; i++; } // Triangles var triangles = new int[3 * mesh.Triangles.Count]; i = 0; foreach (var tri in mesh.Triangles) { triangles[i * 3 + 0] = tri.P0; triangles[i * 3 + 1] = tri.P1; triangles[i * 3 + 2] = tri.P2; i++; } // Contour vertices var contourVerts = new GeoVert[contour.Count * 2]; contourVerts[1] = new GeoVert { Lon = contour[0].X * Math.PI / 180.0, Lat = contour[0].Y * Math.PI / 180.0, Position = Vector3.Zero, Tex = Vector4.Zero, Color = Color.Red }; for (int j = 1; j < contour.Count; j++) { contourVerts[2 * j + 1] = new GeoVert { Lon = contour[j].X * Math.PI / 180.0, Lat = contour[j].Y * Math.PI / 180.0, Position = Vector3.Zero, Tex = Vector4.Zero, Color = Color.Red }; contourVerts[2 * j] = contourVerts[2 * (j - 1) + 1]; } contourVerts[0] = contourVerts[contourVerts.Length - 1]; // Create buffers var vb = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), moVerts.Length); var inds = new IndexBuffer(Game.GraphicsDevice, triangles.Length); var cont = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), contourVerts.Length); vb.SetData(moVerts, 0, moVerts.Length); inds.SetData(triangles, 0, triangles.Length); cont.SetData(contourVerts, 0, contourVerts.Length); municipalDivisions.Add(name, new MD { Contour = cont, Indeces = inds, Vertices = vb, Value = r.NextFloat(0.0f, 1.0f) }); }
// Dictionary<string, double> Results = new Dictionary<string, double>(); public void ReadDXF(string dxfFileName, ref Section section) { mds = new MesherDataSet(); string filename = dxfFileName; List <Polygon> polygons = getArea(filename); double d = dxfPolydepth(filename); section.d = d / 10; double Zoo = 0.0; double Zou = 0.0; double Zuo = 0.0; double Zuu = 0.0; for (int i = 0; i < polygons.Count; i++) { poly = polygons.ElementAt(i); mesh = DxfMesh(poly); // compute mesh basic property MesherBasicProperty(); double[] Z = singledepth(poly); if (i == 0) { Zoo = Z.ElementAt(0); Zou = Z.ElementAt(1); section.Zoo = Zoo / 10; section.Zou = Zou / 10; section.Ao = mds.totalMeshArea / 100; section.Io = mds.meshIxxC / 10000; section.Ioyy = mds.meshIyyC / 10000; // by Wei section.Wo = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 2.7 / 1000; // weight in N/cm } else if (i == 1) { Zuo = Z.ElementAt(0); Zuu = Z.ElementAt(1); section.Zuo = Zuo / 10; section.Zuu = Zuu / 10; section.Au = mds.totalMeshArea / 100; section.Iu = mds.meshIxxC / 10000; section.Iuyy = mds.meshIyyC / 10000; // by Wei section.Wu = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 2.7 / 1000; // weight in N/cm } else if (i == 2) { section.Wl = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 1.2 * 1.27 / 1000; } else if (i == 3) { section.Wr = 9.80665 / 100 * mds.totalMeshArea / 100 * 100 * 1.2 * 1.27 / 1000; } } section.Weight = section.Wo + section.Wu + section.Wl + section.Wr; //double a = d - Zoo - Zuu; //Results.Add("a", a / 10); //double ao = (Results["Au"] * a) / (Results["Au"] + Results["Ao"]); //double au = a - ao; //Results.Add("ao", ao / 10); //Results.Add("au", au / 10); }
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 void generateTerrain() { this.holes.Add(new Vector2(2, 2)); this.top = HexMathHelper.hexToWorldCoords(new Vector2(minX - 2, maxY + 2), this.getHexSize()).y; this.left = HexMathHelper.hexToWorldCoords(new Vector2(leftMostHexCoordinates.x - 2, leftMostHexCoordinates.y), this.getHexSize()).x; this.bottom = HexMathHelper.hexToWorldCoords(new Vector2(maxX + 2, minY - 2), this.getHexSize()).y; this.right = HexMathHelper.hexToWorldCoords(new Vector2(rightMostHexCoordinates.x + 2, rightMostHexCoordinates.y), this.getHexSize()).x; float mapHeight = top - bottom; float mapWidth = right - left; this.mapCenter = new Vector2(right - mapWidth / 2, top - mapHeight / 2); this.surfaceCurving = generateSurfaceCurving(top, left, bottom, right); Polygon polygon = new Polygon(); //polygon.Add(new Vertex(left, top)); //polygon.Add(new Vertex(right, top)); //polygon.Add(new Vertex(right, bottom)); //polygon.Add(new Vertex(left, bottom)); for (float y = bottom; y <= top;) { for (float x = left; x < right;) { x += polygonDensity * (1 + Random.Range(-0.4f, 0.4f)); if (x > right) { x = right; } float yDispersion = y == bottom || y == top ? 0 : polygonDensity *Random.Range(-0.3f, 0.3f); if (!this.holes.Exists(hole => hole == HexMathHelper.worldToHexCoords(new Vector2(x, y + yDispersion), this.getHexSize()))) { polygon.Add(new Vertex(x, y + yDispersion)); } } if (y == top) { break; } y += polygonDensity * (1 + Random.Range(-0.3f, 0.3f)); if (y > top) { y = top; } } foreach (Vector2 hole in holes) { Vector2 hexCenter = HexMathHelper.hexToWorldCoords(hole, this.getHexSize()); Vector2 topCorner = hexCenter + this.hexCornerVectors[0]; Vector2 rightTopCorner = hexCenter + this.hexCornerVectors[1]; Vector2 rightBottomCorner = hexCenter + this.hexCornerVectors[2]; Vector2 bottomCorner = hexCenter + this.hexCornerVectors[3]; Vector2 leftBottomCorner = hexCenter + this.hexCornerVectors[4]; Vector2 leftTopCorner = hexCenter + this.hexCornerVectors[5]; polygon.Add(new Vertex(topCorner.x, topCorner.y)); polygon.Add(new Vertex(rightTopCorner.x, rightTopCorner.y)); polygon.Add(new Vertex(rightBottomCorner.x, rightBottomCorner.y)); polygon.Add(new Vertex(bottomCorner.x, bottomCorner.y)); polygon.Add(new Vertex(leftBottomCorner.x, leftBottomCorner.y)); polygon.Add(new Vertex(leftTopCorner.x, leftTopCorner.y)); } Debug.Log(polygon.Count); TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true }; testMesh = (TriangleNet.Mesh)polygon.Triangulate(options); }
public override void Start() { base.Start(); _mesh = new TriangleNet.Mesh(); Query = (geo) => geo["geometry"]["type"].str == "Polygon"; }
private bool Open(string filename) { if (FileProcessor.ContainsMeshData(filename)) { if (DarkMessageBox.Show("Import mesh", Settings.ImportString, "Do you want to import the mesh?", MessageBoxButtons.YesNo) == DialogResult.OK) { input = null; mesh = FileProcessor.Import(filename); if (mesh != null) { statisticView.UpdateStatistic(mesh); // Update settings settings.CurrentFile = Path.GetFileName(filename); HandleMeshImport(); btnSmooth.Enabled = true; // TODO: Remove } // else Message return true; } } input = FileProcessor.Read(filename); if (input != null) { // Update settings settings.CurrentFile = Path.GetFileName(filename); HandleNewInput(); } // else Message return true; }
private void Reload() { if (input != null) { mesh = null; settings.RefineMode = false; settings.ExceptionThrown = false; HandleNewInput(); } }
private void Triangulate() { if (input == null) return; //Stopwatch sw = new Stopwatch(); mesh = new Mesh(); if (meshControlView.ParamConformDelChecked) { mesh.Behavior.ConformingDelaunay = true; } if (meshControlView.ParamSweeplineChecked) { mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine; } if (meshControlView.ParamQualityChecked) { mesh.Behavior.Quality = true; mesh.Behavior.MinAngle = meshControlView.ParamMinAngleValue; double maxAngle = meshControlView.ParamMaxAngleValue; if (maxAngle < 180) { mesh.Behavior.MaxAngle = maxAngle; } // Ignore area constraints on initial triangulation. //double area = slMaxArea.Value * 0.01; //if (area > 0 && area < 1) //{ // var size = input.Bounds; // double min = Math.Min(size.Width, size.Height); // mesh.Behavior.MaxArea, area * min); //} } if (meshControlView.ParamConvexChecked) { mesh.Behavior.Convex = true; } try { //sw.Start(); mesh.Triangulate(input); //sw.Stop(); statisticView.UpdateStatistic(mesh); HandleMeshUpdate(); if (meshControlView.ParamQualityChecked) { settings.RefineMode = true; } } catch (Exception ex) { LockOnException(); DarkMessageBox.Show("Exception - Triangulate", ex.Message, MessageBoxButtons.OK); } UpdateLog(); }
void InitBuildingsOSM() { var osm = Game.GetService <LayerService>().OpenStreetMapSource; List <GeoVert> lines = new List <GeoVert>(); List <GeoVert> simple = new List <GeoVert>(); var nodes = osm.allNodes; int k = 0; foreach (var way in osm.allWays) { if (!way.Value.isBuilding) { continue; } var centerMerc = way.Value.BBox.Center(); float width = (way.Value.BBox.Maximum - way.Value.BBox.Minimum).X * 10000.0f; float length = (way.Value.BBox.Maximum - way.Value.BBox.Minimum).Y * 10000.0f; double lon, lat; GeoHelper.TileToWorldPos(centerMerc.X, centerMerc.Y, 0, out lon, out lat); simple.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(lon), Lat = DMathUtil.DegreesToRadians(lat), Color = Color.White, Position = Vector3.Zero, Tex = new Vector4(width, length, 0, 0) }); List <DVector2> buildingVertices = new List <DVector2>(); for (int i = 0; i < way.Value.nodeRef.Length - 1; i++) { var nInds = way.Value.nodeRef; lines.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(nodes[nInds[i]].Longitude), Lat = DMathUtil.DegreesToRadians(nodes[nInds[i]].Latitude), Position = new Vector3(1.0f, 0.0f, 0.0f), Color = Color.Yellow, Tex = Vector4.Zero }); lines.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(nodes[nInds[i + 1]].Longitude), Lat = DMathUtil.DegreesToRadians(nodes[nInds[i + 1]].Latitude), Position = new Vector3(1.0f, 0.0f, 0.0f), Color = Color.Yellow, Tex = Vector4.Zero }); buildingVertices.Add(new DVector2(nodes[nInds[i]].Longitude, nodes[nInds[i]].Latitude)); } buildingVertices.Add(new DVector2(nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Longitude, nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Latitude)); ///////////////////////////////////////// var mesh = new Mesh(); mesh.Behavior.Quality = false; mesh.Behavior.MinAngle = 25; mesh.Behavior.Convex = false; var ig = new InputGeometry(); ig.AddPoint(buildingVertices[0].X, buildingVertices[0].Y); for (int v = 1; v < buildingVertices.Count; v++) { ig.AddPoint(buildingVertices[v].X, buildingVertices[v].Y); ig.AddSegment(v - 1, v); } ig.AddSegment(buildingVertices.Count - 1, 0); mesh.Triangulate(ig); int n = mesh.Vertices.Count; mesh.Renumber(); buildings = new GeoVert[mesh.Triangles.Count * 3]; int ind = 0; foreach (var triangle in mesh.Triangles) { buildings[ind++] = new GeoVert { Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).X), Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).Y), Position = new Vector3(0.1f, 0.0f, 0.0f), Color = Color.Green, Tex = Vector4.Zero }; buildings[ind++] = new GeoVert { Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).X), Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).Y), Position = new Vector3(0.1f, 0.0f, 0.0f), Color = Color.Green, Tex = Vector4.Zero }; buildings[ind++] = new GeoVert { Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).X), Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).Y), Position = new Vector3(0.1f, 0.0f, 0.0f), Color = Color.Green, Tex = Vector4.Zero }; } ///////////////////////////////////////// k++; if (k >= 1) { break; } } simpleBuildings = simple.ToArray(); contourBuildings = lines.ToArray(); contourBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), contourBuildings.Length); contourBuildingsVB.SetData(contourBuildings, 0, contourBuildings.Length); simpleBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), simpleBuildings.Length); simpleBuildingsVB.SetData(simpleBuildings, 0, simpleBuildings.Length); buildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), buildings.Length); buildingsVB.SetData(buildings, 0, buildings.Length); }