/// <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();
            }
        }
Esempio n. 3
0
        /// <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();
            }
        }
Esempio n. 4
0
 /// <inheritdoc />
 public IMesh Triangulate(IPolygon polygon, QualityOptions quality)
 {
     return(Triangulate(polygon, null, quality));
 }
Esempio n. 5
0
 /// <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);
 }
Esempio n. 6
0
 /// <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);
 }
Esempio n. 8
0
        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();
        }
Esempio n. 9
0
        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();
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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");
        }