/// <inheritdoc /> public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality) { var mesh = (Mesh)triangulator.Triangulate(polygon.Points, config); var cmesher = new ConstraintMesher(mesh, config); var qmesher = new QualityMesher(mesh, config); mesh.SetQualityMesher(qmesher); // Insert segments. cmesher.Apply(polygon, options); // Refine mesh. qmesher.Apply(quality); return mesh; }
/// <summary> /// Apply quality constraints to a mesh. /// </summary> /// <param name="quality">The quality constraints.</param> /// <param name="delaunay">A value indicating, if the refined mesh should be Conforming Delaunay.</param> public void Apply(QualityOptions quality, bool delaunay = false) { // Copy quality options if (quality != null) { behavior.Quality = true; behavior.MinAngle = quality.MinimumAngle; behavior.MaxAngle = quality.MaximumAngle; behavior.MaxArea = quality.MaximumArea; behavior.UserTest = quality.UserTest; behavior.VarArea = quality.VariableArea; behavior.ConformingDelaunay = behavior.ConformingDelaunay || delaunay; mesh.steinerleft = quality.SteinerPoints == 0 ? -1 : quality.SteinerPoints; } // TODO: remove if (!behavior.Poly) { // Be careful not to allocate space for element area constraints that // will never be assigned any value (other than the default -1.0). behavior.VarArea = false; } // Ensure that no vertex can be mistaken for a triangular bounding // box vertex in insertvertex(). mesh.infvertex1 = null; mesh.infvertex2 = null; mesh.infvertex3 = null; if (behavior.useSegments) { mesh.checksegments = true; } if (behavior.Quality && mesh.triangles.Count > 0) { // Enforce angle and area constraints. EnforceQuality(); } }
/// <summary> /// Apply quality constraints to a mesh. /// </summary> /// <param name="quality">The quality constraints.</param> /// <param name="delaunay">A value indicating, if the refined mesh should be Conforming Delaunay.</param> public void Apply(QualityOptions quality, bool delaunay = false) { // Copy quality options if (quality != null) { behavior.Quality = true; behavior.MinAngle = quality.MinimumAngle; behavior.MaxAngle = quality.MaximumAngle; behavior.MaxArea = quality.MaximumArea; behavior.UserTest = quality.UserTest; behavior.VarArea = quality.VariableArea; behavior.ConformingDelaunay = behavior.ConformingDelaunay || delaunay; _TriangleNetMesh.steinerleft = quality.SteinerPoints == 0 ? -1 : quality.SteinerPoints; } // TODO: remove if (!behavior.Poly) { // Be careful not to allocate space for element area constraints that // will never be assigned any value (other than the default -1.0). behavior.VarArea = false; } // Ensure that no vertex can be mistaken for a triangular bounding // box vertex in insertvertex(). _TriangleNetMesh.infvertex1 = null; _TriangleNetMesh.infvertex2 = null; _TriangleNetMesh.infvertex3 = null; if (behavior.useSegments) { _TriangleNetMesh.checksegments = true; } if (behavior.Quality && _TriangleNetMesh.triangles.Count > 0) { // Enforce angle and area constraints. EnforceQuality(); } }
/// <inheritdoc /> public IMesh Triangulate(IPolygon polygon, QualityOptions quality) { return(Triangulate(polygon, null, quality)); }
/// <summary> /// Triangulates a polygon, applying quality and constraint options. /// </summary> /// <param name="options">Constraint options.</param> /// <param name="quality">Quality options.</param> /// <param name="triangulator">The triangulation algorithm.</param> public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality, ITriangulator triangulator) { return (new GenericMesher(triangulator)).Triangulate(polygon, options, quality); }
/// <summary> /// Triangulates a polygon, applying quality options. /// </summary> /// <param name="quality">Quality options.</param> public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality) { return (new GenericMesher()).Triangulate(polygon, null, quality); }
/// <inheritdoc /> public IMesh Triangulate(IPolygon polygon, QualityOptions quality) { return Triangulate(polygon, null, quality); }
private void Refine() { if (mesh == null) return; double area = meshControlView.ParamMaxAreaValue; var quality = new QualityOptions(); if (area > 0 && area < 1) { quality.MaximumArea = area * statisticView.Statistic.LargestArea; } quality.MinimumAngle = meshControlView.ParamMinAngleValue; double maxAngle = meshControlView.ParamMaxAngleValue; if (maxAngle < 180) { quality.MaximumAngle = maxAngle; } try { mesh.Refine(quality, meshControlView.ParamConformDelChecked); statisticView.UpdateStatistic(mesh); HandleMeshUpdate(); } catch (Exception ex) { LockOnException(); DarkMessageBox.Show("Exception - Refine", ex.Message, MessageBoxButtons.OK); } UpdateLog(); }
private void Triangulate() { if (input == null) return; var options = new ConstraintOptions(); var quality = new QualityOptions(); if (meshControlView.ParamConformDelChecked) { options.ConformingDelaunay = true; } if (meshControlView.ParamQualityChecked) { quality.MinimumAngle = meshControlView.ParamMinAngleValue; double maxAngle = meshControlView.ParamMaxAngleValue; if (maxAngle < 180) { quality.MaximumAngle = 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.SetOption(Options.MaxArea, area * min); //} } if (meshControlView.ParamConvexChecked) { options.Convex = true; } try { if (meshControlView.ParamSweeplineChecked) { mesh = (Mesh)input.Triangulate(options, quality, new SweepLine()); } else { mesh = (Mesh)input.Triangulate(options, quality); } statisticView.UpdateStatistic(mesh); HandleMeshUpdate(); if (meshControlView.ParamQualityChecked) { settings.RefineMode = true; } } catch (Exception ex) { LockOnException(); DarkMessageBox.Show("Exception - Triangulate", ex.Message, MessageBoxButtons.OK); } UpdateLog(); }
public void Refine(QualityOptions quality, bool delaunay = false) { invertices = vertices.Count; if (behavior.Poly) { insegments = behavior.useSegments ? subsegs.Count : hullsize; } Reset(); if (qualityMesher == null) { qualityMesher = new QualityMesher(this, new Configuration()); } // Enforce angle and area constraints. qualityMesher.Apply(quality, delaunay); }
public void Refine(QualityOptions quality) { invertices = vertices.Count; if (behavior.Poly) { insegments = behavior.useSegments ? subsegs.Count : hullsize; } Reset(); // Enforce angle and area constraints. qualityMesher.Apply(quality); }
private void Triangulate_Click(object sender, RoutedEventArgs e) { var qualityOptions = new TriangleNet.Meshing.QualityOptions(); qualityOptions.MaximumArea = double.Parse(hTextBox.Text); qualityOptions.MinimumAngle = double.Parse(LTextBox.Text); var objct = new TriangleNet.Geometry.Polygon(); foreach (var item in mycoordinates) { objct.Add(item); } for (int i = 0; i < mycoordinates.Count - 1; i++) { objct.Add(new Segment(mycoordinates[i], mycoordinates[i + 1])); } objct.Add(new Segment(mycoordinates.LastOrDefault(), mycoordinates.FirstOrDefault())); //var test = new TriangleNet.Meshing.Algorithm.SweepLine(); var constraintOption = new TriangleNet.Meshing.ConstraintOptions(); meshResult = objct.Triangulate(constraintOption, qualityOptions, new TriangleNet.Meshing.Algorithm.Incremental()); //Triangulation //meshResult = objct.Triangulate(qualityOptions); meshResult.Renumber(); //triangleResult = new List<TriangleNet.Topology.Triangle>(meshResult.Triangles); //Triangles trianglesResult = GetTrianglesFromMeshTriangles(meshResult.Triangles); resultsTriangles.ItemsSource = trianglesResult; //Vertices verticesResult = new List <Vertex>(meshResult.Vertices); myvertixesResult = meshResult.Vertices.Select(v => new MyVertex { Id = v.ID, X = v.X, Y = v.Y }).ToList(); results.ItemsSource = myvertixesResult; //Заповнення граничних сегментів for (int i = 0; i < boundaries.Count; i++) { boundaries[i].SetSegments(meshResult.Segments, boundaries.Count); } //Перетворення орієнтації всіх сегментів проти годинникової стрілки for (int i = 0; i < boundaries.Count; i++) { if (i != boundaries.Count - 1) { boundaries[i].SetSegmentsOrientationToCounterclockwise(i, i + 1); } else { boundaries[i].SetSegmentsOrientationToCounterclockwise(i, 0); } } // FillGridWithBoundaries(resultsBoundaries, boundaries); DrawData(meshResult); //Етап 2: Створення матриць Me, Ke, Qe, Re, Pe //Підготовка //Зчитування параметрів double a11 = double.Parse(a11TextBox.Text); double a22 = double.Parse(a22TextBox.Text); double d = double.Parse(dTextBox.Text); double f = double.Parse(fTextBox.Text); //Створення масиву точок var CT = GetPointsArray(myvertixesResult); //Створення масиву трикутників var NT = GetTrianglesArray(trianglesResult); //Створення масиву граничних сегментів var NTGR = GetBoundarySegments(boundaries); //Створення масиву значень ф-кції f у точках var fe = GetFe(CT, f); //Етап 3 (ініціалізація A,B) //Кількість вузлів int nodeNumber = CT.Length; var A = new double[nodeNumber][]; for (int i = 0; i < nodeNumber; i++) { A[i] = new double[nodeNumber]; } var b = new double[nodeNumber]; //Створення Me, Ke, Qe (та їх розсилання) double[] function_value = new double[3]; for (int k = 0; k < trianglesResult.Count; k++) { //трикутник містить координати вузлів скінченного елемента var triangle = NT[k]; //Підготовка double[] i = CT[triangle[0]], j = CT[triangle[1]], m = CT[triangle[2]]; double Se = GetArea(i, j, m); double ai = GetA(j, m), bi = GetB(j, m), ci = GetC(j, m), aj = GetA(m, i), bj = GetB(m, i), cj = GetC(m, i), am = GetA(i, j), bm = GetB(i, j), cm = GetC(i, j); double[] a = new double[] { ai, aj, am }, B = new double[] { bi, bj, bm }, c = new double[] { ci, cj, cm }; function_value[0] = fe[triangle[0]]; function_value[1] = fe[triangle[1]]; function_value[2] = fe[triangle[2]]; //Ke var ke = new KE(k, Se, a11, a22, B, c); ke.print(); //Me var me = new ME(k, Se, d); me.print(); //Qe var qe = new QE(k, Se, fe); qe.print(); //Етап 3 for (int q = 0; q < 3; q++) { //triangle[q] це номер вузла елемента for (int w = 0; w < 3; w++) { A[triangle[q]][triangle[w]] += ke.Ke[q][w] + me.Me[q][w]; } b[triangle[q]] += qe.Qe[q][0]; } } //Створення Re, Pe (та їх розсилання) for (int k = 0; k < boundaries.Count; k++) { for (int l = 0; l < NTGR[k].Length; l++) { //сегмент містить координати вузлів граничного сегмента var segment = NTGR[k][l]; //Підготовка double[] i = CT[NTGR[k][l][0]], j = CT[NTGR[k][l][1]]; double Length = GetLength(i, j); //Re var re = new RE(k + l, boundaries[k].G, boundaries[k].B, Length, k + "|" + l + "|" + NTGR[k][l][0] + "-" + NTGR[k][l][1]); re.print(); //Pe var pe = new PE(k + l, boundaries[k].G, boundaries[k].B, boundaries[k].Uc, Length, k + "|" + l + "|" + NTGR[k][l][0] + "-" + NTGR[k][l][1]); pe.print(); //Етап 3 for (int q = 0; q < 2; q++) { //segment[q] це номер вузла сегмента for (int w = 0; w < 2; w++) { A[segment[q]][segment[w]] += re.Re[q][w]; } b[segment[q]] += pe.Pe[q][0]; } } } //Запис у файл A,b print(A, b); //Етап 3-2 var u = GausseMethod(nodeNumber, A, b); printNonFormatted(CT, u, "results.txt"); }