示例#1
0
        public void TestDissolve()
        {
            // Outer space triangle.
            var dummy = new Triangle()
            {
                id = -1
            };

            var triangles = CreateExampleMesh();

            Otri s = default;
            Otri t = default;

            Otri tmp = default;

            // The bottom left triangle with edge 1 -> 3.
            s.tri    = triangles[0];
            s.orient = 1;

            // The center triangle with edge 3 -> 1.
            t.tri    = triangles[1];
            t.orient = 2;

            // Make sure we're on the correct edges.
            Assert.AreEqual(1, s.Org().ID);
            Assert.AreEqual(3, s.Dest().ID);
            Assert.AreEqual(3, t.Org().ID);
            Assert.AreEqual(1, t.Dest().ID);

            // Check that neighbors are properly set.
            s.Sym(ref tmp);
            Assert.AreEqual(1, tmp.tri.ID);
            t.Sym(ref tmp);
            Assert.AreEqual(0, tmp.tri.ID);

            // Now dissolve the bond from one side.
            s.Dissolve(dummy);

            // Check neighbors.
            s.Sym(ref tmp);
            Assert.AreEqual(-1, tmp.tri.ID);
            t.Sym(ref tmp);
            Assert.AreEqual(0, tmp.tri.ID);

            // And dissolve the bond from the other side.
            t.Dissolve(dummy);

            // Check neighbors.
            s.Sym(ref tmp);
            Assert.AreEqual(-1, tmp.tri.ID);
            t.Sym(ref tmp);
            Assert.AreEqual(-1, tmp.tri.ID);
        }
示例#2
0
        /// <summary>
        /// Removes ghost triangles.
        /// </summary>
        /// <param name="startghost"></param>
        /// <returns>Number of vertices on the hull.</returns>
        int RemoveGhosts(ref Otri startghost)
        {
            Otri   searchedge   = default(Otri);
            Otri   dissolveedge = default(Otri);
            Otri   deadtriangle = default(Otri);
            Vertex markorg;
            int    hullsize;



            bool noPoly = !mesh.behavior.Poly;

            var dummytri = mesh.dummytri;

            // Find an edge on the convex hull to start point location from.
            startghost.Lprev(ref searchedge);
            searchedge.Sym();
            dummytri.neighbors[0] = searchedge;
            // Remove the bounding box and count the convex hull edges.
            startghost.Copy(ref dissolveedge);
            hullsize = 0;
            do
            {
                hullsize++;
                dissolveedge.Lnext(ref deadtriangle);
                dissolveedge.Lprev();
                dissolveedge.Sym();

                // If no PSLG is involved, set the boundary markers of all the vertices
                // on the convex hull.  If a PSLG is used, this step is done later.
                if (noPoly)
                {
                    // Watch out for the case where all the input vertices are collinear.
                    if (dissolveedge.tri.id != Mesh.DUMMY)
                    {
                        markorg = dissolveedge.Org();
                        if (markorg.label == 0)
                        {
                            markorg.label = 1;
                        }
                    }
                }
                // Remove a bounding triangle from a convex hull triangle.
                dissolveedge.Dissolve(dummytri);
                // Find the next bounding triangle.
                deadtriangle.Sym(ref dissolveedge);

                // Delete the bounding triangle.
                mesh.TriangleDealloc(deadtriangle.tri);
            } while (!dissolveedge.Equals(startghost));

            return(hullsize);
        }
示例#3
0
        public int CheckSeg4Encroach(ref Osub testsubseg)
        {
            double num;
            Vertex vertex;
            Otri   otri    = new Otri();
            Osub   osub    = new Osub();
            int    num1    = 0;
            int    num2    = 0;
            Vertex vertex1 = testsubseg.Org();
            Vertex vertex2 = testsubseg.Dest();

            testsubseg.TriPivot(ref otri);
            if (otri.triangle != Mesh.dummytri)
            {
                num2++;
                vertex = otri.Apex();
                num    = (vertex1.x - vertex.x) * (vertex2.x - vertex.x) + (vertex1.y - vertex.y) * (vertex2.y - vertex.y);
                if (num < 0 && (this.behavior.ConformingDelaunay || num * num >= (2 * this.behavior.goodAngle - 1) * (2 * this.behavior.goodAngle - 1) * ((vertex1.x - vertex.x) * (vertex1.x - vertex.x) + (vertex1.y - vertex.y) * (vertex1.y - vertex.y)) * ((vertex2.x - vertex.x) * (vertex2.x - vertex.x) + (vertex2.y - vertex.y) * (vertex2.y - vertex.y))))
                {
                    num1 = 1;
                }
            }
            testsubseg.Sym(ref osub);
            osub.TriPivot(ref otri);
            if (otri.triangle != Mesh.dummytri)
            {
                num2++;
                vertex = otri.Apex();
                num    = (vertex1.x - vertex.x) * (vertex2.x - vertex.x) + (vertex1.y - vertex.y) * (vertex2.y - vertex.y);
                if (num < 0 && (this.behavior.ConformingDelaunay || num * num >= (2 * this.behavior.goodAngle - 1) * (2 * this.behavior.goodAngle - 1) * ((vertex1.x - vertex.x) * (vertex1.x - vertex.x) + (vertex1.y - vertex.y) * (vertex1.y - vertex.y)) * ((vertex2.x - vertex.x) * (vertex2.x - vertex.x) + (vertex2.y - vertex.y) * (vertex2.y - vertex.y))))
                {
                    num1 = num1 + 2;
                }
            }
            if (num1 > 0 && (this.behavior.NoBisect == 0 || this.behavior.NoBisect == 1 && num2 == 2))
            {
                BadSubseg badSubseg = new BadSubseg();
                if (num1 != 1)
                {
                    badSubseg.encsubseg  = osub;
                    badSubseg.subsegorg  = vertex2;
                    badSubseg.subsegdest = vertex1;
                }
                else
                {
                    badSubseg.encsubseg  = testsubseg;
                    badSubseg.subsegorg  = vertex1;
                    badSubseg.subsegdest = vertex2;
                }
                this.badsubsegs.Enqueue(badSubseg);
            }
            return(num1);
        }
示例#4
0
        public static void WriteEdges(Mesh mesh, string filename)
        {
            Otri     otri     = new Otri();
            Otri     otri1    = new Otri();
            Osub     osub     = new Osub();
            Behavior behavior = mesh.behavior;

            using (StreamWriter streamWriter = new StreamWriter(new FileStream(filename, FileMode.Create)))
            {
                streamWriter.WriteLine("{0} {1}", mesh.edges, (behavior.UseBoundaryMarkers ? "1" : "0"));
                long num = (long)0;
                foreach (Triangle value in mesh.triangles.Values)
                {
                    otri.triangle = value;
                    otri.orient   = 0;
                    while (otri.orient < 3)
                    {
                        otri.Sym(ref otri1);
                        if (otri.triangle.id < otri1.triangle.id || otri1.triangle == Mesh.dummytri)
                        {
                            Vertex vertex  = otri.Org();
                            Vertex vertex1 = otri.Dest();
                            if (!behavior.UseBoundaryMarkers)
                            {
                                streamWriter.WriteLine("{0} {1} {2}", num, vertex.id, vertex1.id);
                            }
                            else if (!behavior.useSegments)
                            {
                                StreamWriter streamWriter1 = streamWriter;
                                object[]     objArray      = new object[] { num, vertex.id, vertex1.id, null };
                                objArray[3] = (otri1.triangle == Mesh.dummytri ? "1" : "0");
                                streamWriter1.WriteLine("{0} {1} {2} {3}", objArray);
                            }
                            else
                            {
                                otri.SegPivot(ref osub);
                                if (osub.seg != Mesh.dummysub)
                                {
                                    streamWriter.WriteLine("{0} {1} {2} {3}", new object[] { num, vertex.id, vertex1.id, osub.seg.boundary });
                                }
                                else
                                {
                                    streamWriter.WriteLine("{0} {1} {2} {3}", new object[] { num, vertex.id, vertex1.id, 0 });
                                }
                            }
                            num = num + (long)1;
                        }
                        otri.orient = otri.orient + 1;
                    }
                }
            }
        }
        private void BuildCache(Vertex vertex, bool vertices)
        {
            cache.Clear();

            Otri init = vertex.tri;
            Otri next = default(Otri);
            Otri prev = default(Otri);

            init.Copy(ref next);

            // Move counter-clockwise around the vertex.
            while (next.tri.id != TriangleNetMesh.DUMMY)
            {
                cache.Add(next);

                next.Copy(ref prev);
                next.Onext();

                if (next.Equals(init))
                {
                    break;
                }
            }

            if (next.tri.id == TriangleNetMesh.DUMMY)
            {
                // We reached the boundary. To get all adjacent triangles, start
                // again at init triangle and now move clockwise.
                init.Copy(ref next);

                if (vertices)
                {
                    // Don't forget to add the vertex lying on the boundary.
                    prev.Lnext();
                    cache.Add(prev);
                }

                next.Oprev();

                while (next.tri.id != TriangleNetMesh.DUMMY)
                {
                    cache.Insert(0, next);

                    next.Oprev();

                    if (next.Equals(init))
                    {
                        break;
                    }
                }
            }
        }
示例#6
0
        public void Enqueue(ref Otri enqtri, double minedge, Vertex enqapex, Vertex enqorg, Vertex enqdest)
        {
            BadTriangle badTriangle = new BadTriangle()
            {
                poortri    = enqtri,
                key        = minedge,
                triangapex = enqapex,
                triangorg  = enqorg,
                triangdest = enqdest
            };

            this.Enqueue(badTriangle);
        }
        public void Update(Otri otri)
        {
            if (otri.Triangle == null || otri.Triangle.ID < 0)
            {
                renderer.SelectTriangle(null, null, null);
            }
            else
            {
                renderer.SelectTriangle(otri.Triangle, otri.Org(), otri.Dest());
            }

            this.Render();
        }
示例#8
0
        /// <summary> Add a bad triangle to the end of a queue. </summary>
        /// <param name="enqtri"></param>
        /// <param name="minedge"></param>
        /// <param name="apex"></param>
        /// <param name="org"></param>
        /// <param name="dest"></param>
        public void Enqueue(ref Otri enqtri, double minedge, Vertex apex, Vertex org, Vertex dest)
        {
            // Allocate space for the bad triangle.
            BadTriangle newbad = TrianglePool.AllocBadTri();

            newbad.poortri = enqtri;
            newbad.key     = minedge;
            newbad.apex    = apex;
            newbad.org     = org;
            newbad.dest    = dest;

            Enqueue(newbad);
        }
示例#9
0
        private SweepLine.SplayNode FrontLocate(SweepLine.SplayNode splayroot, Otri bottommost, Vertex searchvertex, ref Otri searchtri, ref bool farright)
        {
            bool i;

            bottommost.Copy(ref searchtri);
            splayroot = this.Splay(splayroot, searchvertex, ref searchtri);
            for (i = false; !i && this.RightOfHyperbola(ref searchtri, searchvertex); i = searchtri.Equal(bottommost))
            {
                searchtri.OnextSelf();
            }
            farright = i;
            return(splayroot);
        }
示例#10
0
        private void TallyFaces()
        {
            Otri otri = new Otri()
            {
                orient = 0
            };

            foreach (Triangle value in this.mesh.triangles.Values)
            {
                otri.triangle = value;
                this.TestTriangle(ref otri);
            }
        }
示例#11
0
        /// <summary>
        /// Add a bad triangle to the end of a queue.
        /// </summary>
        /// <param name="enqtri"></param>
        /// <param name="minedge"></param>
        /// <param name="enqapex"></param>
        /// <param name="enqorg"></param>
        /// <param name="enqdest"></param>
        public void Enqueue(ref Otri enqtri, double minedge, Vertex enqapex, Vertex enqorg, Vertex enqdest)
        {
            // Allocate space for the bad triangle.
            BadTriangle newbad = new BadTriangle();

            newbad.poortri    = enqtri;
            newbad.key        = minedge;
            newbad.triangapex = enqapex;
            newbad.triangorg  = enqorg;
            newbad.triangdest = enqdest;

            Enqueue(newbad);
        }
示例#12
0
        public int Triangulate(Mesh m)
        {
            Otri otri  = new Otri();
            Otri otri1 = new Otri();

            this.mesh      = m;
            this.sortarray = new Vertex[m.invertices];
            int num = 0;

            foreach (Vertex value in m.vertices.Values)
            {
                int num1 = num;
                num = num1 + 1;
                this.sortarray[num1] = value;
            }
            this.VertexSort(0, m.invertices - 1);
            num = 0;
            for (int i = 1; i < m.invertices; i++)
            {
                if (this.sortarray[num].x != this.sortarray[i].x || this.sortarray[num].y != this.sortarray[i].y)
                {
                    num++;
                    this.sortarray[num] = this.sortarray[i];
                }
                else
                {
                    if (Behavior.Verbose)
                    {
                        SimpleLog.Instance.Warning(string.Format("A duplicate vertex appeared and was ignored (ID {0}).", this.sortarray[i].hash), "DivConquer.DivconqDelaunay()");
                    }
                    this.sortarray[i].type = VertexType.UndeadVertex;
                    Mesh mesh = m;
                    mesh.undeads = mesh.undeads + 1;
                }
            }
            num++;
            if (this.useDwyer)
            {
                int num2 = num >> 1;
                if (num - num2 >= 2)
                {
                    if (num2 >= 2)
                    {
                        this.AlternateAxes(0, num2 - 1, 1);
                    }
                    this.AlternateAxes(num2, num - 1, 1);
                }
            }
            this.DivconqRecurse(0, num - 1, 0, ref otri, ref otri1);
            return(this.RemoveGhosts(ref otri));
        }
示例#13
0
        /// <summary>
        /// Form a Delaunay triangulation by the divide-and-conquer method.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Sorts the vertices, calls a recursive procedure to triangulate them, and
        /// removes the bounding box, setting boundary markers as appropriate.
        /// </remarks>
        public Mesh Triangulate(List <Vertex> points)
        {
            this.mesh = TrianglePool.AllocMesh();
            this.mesh.TransferNodes(points);

            Otri hullleft = default(Otri), hullright = default(Otri);
            int  divider;
            int  i, j, n = points.Count;

            sortarray = points;
            VertexSort(0, n - 1);
            // Discard duplicate vertices, which can really mess up the algorithm.
            i = 0;
            for (j = 1; j < n; j++)
            {
                if ((sortarray[i].X == sortarray[j].X) && (sortarray[i].Y == sortarray[j].Y))
                {
                    sortarray[j].type = VertexType.UndeadVertex;
                    mesh.undeads++;
                }
                else
                {
                    i++;
                    sortarray[i] = sortarray[j];
                }
            }
            i++;
            if (UseDwyer)
            {
                // Re-sort the array of vertices to accommodate alternating cuts.
                divider = i >> 1;
                if (i - divider >= 2)
                {
                    if (divider >= 2)
                    {
                        AlternateAxes(0, divider - 1, 1);
                    }
                    AlternateAxes(divider, i - 1, 1);
                }
            }

            // Form the Delaunay triangulation.
            DivconqRecurse(0, i - 1, 0, ref hullleft, ref hullright);

            //DebugWriter.Session.Write(mesh);
            //DebugWriter.Session.Finish();

            this.mesh.hullsize = RemoveGhosts(ref hullleft);

            return(this.mesh);
        }
示例#14
0
        private void ComputeCircumCenters()
        {
            Otri   otri = new Otri();
            double num  = 0;
            double num1 = 0;

            foreach (Triangle value in this.mesh.triangles.Values)
            {
                otri.triangle = value;
                Point point = Primitives.FindCircumcenter(otri.Org(), otri.Dest(), otri.Apex(), ref num, ref num1);
                point.id = value.id;
                this.points[value.id] = point;
            }
        }
示例#15
0
        /// <summary>
        /// Test every triangle in the mesh for quality measures.
        /// </summary>
        private void TallyFaces()
        {
            Otri triangleloop = default(Otri);

            triangleloop.orient = 0;

            foreach (var tri in mesh.triangles.Values)
            {
                triangleloop.triangle = tri;

                // If the triangle is bad, enqueue it.
                TestTriangle(ref triangleloop);
            }
        }
示例#16
0
        public void TestApex()
        {
            Otri t = default;

            t.tri = Helper.CreateTriangle(0, vertices[1], vertices[4], vertices[3]);

            t.orient = 0;
            Assert.AreEqual(3, t.Apex().ID);

            t.orient = 1;
            Assert.AreEqual(1, t.Apex().ID);

            t.orient = 2;
            Assert.AreEqual(4, t.Apex().ID);
        }
示例#17
0
        private void InfectHull()
        {
            Otri otri  = new Otri();
            Otri otri1 = new Otri();
            Otri otri2 = new Otri();
            Osub osub  = new Osub();

            otri.triangle = Mesh.dummytri;
            otri.orient   = 0;
            otri.SymSelf();
            otri.Copy(ref otri2);
            do
            {
                if (!otri.IsInfected())
                {
                    otri.SegPivot(ref osub);
                    if (osub.seg == Mesh.dummysub)
                    {
                        if (!otri.IsInfected())
                        {
                            otri.Infect();
                            this.viri.Add(otri.triangle);
                        }
                    }
                    else if (osub.seg.boundary == 0)
                    {
                        osub.seg.boundary = 1;
                        Vertex vertex  = otri.Org();
                        Vertex vertex1 = otri.Dest();
                        if (vertex.mark == 0)
                        {
                            vertex.mark = 1;
                        }
                        if (vertex1.mark == 0)
                        {
                            vertex1.mark = 1;
                        }
                    }
                }
                otri.LnextSelf();
                otri.Oprev(ref otri1);
                while (otri1.triangle != Mesh.dummytri)
                {
                    otri1.Copy(ref otri);
                    otri.Oprev(ref otri1);
                }
            }while (!otri.Equal(otri2));
        }
示例#18
0
        private SweepLine.SplayNode CircleTopInsert(SweepLine.SplayNode splayroot, Otri newkey, Vertex pa, Vertex pb, Vertex pc, double topy)
        {
            Point  point = new Point();
            Otri   otri  = new Otri();
            double num   = Primitives.CounterClockwise(pa, pb, pc);
            double num1  = pa.x - pc.x;
            double num2  = pa.y - pc.y;
            double num3  = pb.x - pc.x;
            double num4  = pb.y - pc.y;
            double num5  = num1 * num1 + num2 * num2;
            double num6  = num3 * num3 + num4 * num4;

            point.x = pc.x - (num2 * num6 - num4 * num5) / (2 * num);
            point.y = topy;
            return(this.SplayInsert(this.Splay(splayroot, point, ref otri), newkey, point));
        }
示例#19
0
            private void dotri(SCENE scene, Otri tri, vec2[] pts, vec2 phantom, int i, float w, vec4 col)
            {
                float rot  = angle(phantom, pts[2]) + PI;
                vec2  pos  = pts[2];
                vec2  size = v2(distance(phantom, pts[2]), distance(phantom, pts[i]));
                float d    = angle(pts[i], phantom) - angle(pts[2], phantom);

                if (d > PI || (d < 0 && d > -PI))
                {
                    pos  = pts[i];
                    rot -= PI2;
                    size = v2(size.y, size.x);
                }
                tri.update(scene.time, col, rot, v4(pos.x, pos.y, 1f, w), size);
                tri.draw(scene.g);
            }
示例#20
0
        /// <summary>
        /// Apply given action to each triangle of selected region.
        /// </summary>
        /// <param name="action"></param>
        /// <param name="protector"></param>
        void ProcessRegion(Action <Triangle> action, Func <SubSegment, bool> protector)
        {
            Otri testtri        = default(Otri);
            Otri neighbor       = default(Otri);
            Osub neighborsubseg = default(Osub);

            // Loop through all the infected triangles, spreading the attribute
            // and/or area constraint to their neighbors, then to their neighbors'
            // neighbors.
            for (int i = 0; i < region.Count; i++)
            {
                // WARNING: Don't use foreach, viri list gets modified.

                testtri.tri = region[i];

                // Apply function.
                action(testtri.tri);

                // Check each of the triangle's three neighbors.
                for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
                {
                    // Find the neighbor.
                    testtri.Sym(ref neighbor);
                    // Check for a subsegment between the triangle and its neighbor.
                    testtri.Pivot(ref neighborsubseg);
                    // Make sure the neighbor exists, is not already infected, and
                    // isn't protected by a subsegment.
                    if ((neighbor.tri.id != TriangleNetMesh.DUMMY) && !neighbor.IsInfected() &&
                        protector(neighborsubseg.seg))
                    {
                        // Infect the neighbor.
                        neighbor.Infect();
                        // Ensure that the neighbor's neighbors will be infected.
                        region.Add(neighbor.tri);
                    }
                }
            }

            // Uninfect all triangles.
            foreach (var virus in region)
            {
                virus.infected = false;
            }

            // Empty the virus pool.
            region.Clear();
        }
示例#21
0
        /// <summary>
        /// Reconstruct a triangulation from its raw data representation.
        /// </summary>
        public static Mesh ToMesh(Polygon polygon, ITriangle[] triangles)
        {
            Otri tri    = default(Otri);
            Osub subseg = default(Osub);
            int  i      = 0;

            int elements = triangles == null ? 0 : triangles.Length;
            int segments = polygon.Segments.Count;

            // TODO: Configuration should be a function argument.
            var mesh = new Mesh(new Configuration());

            mesh.TransferNodes(polygon.Points);

            mesh.regions.AddRange(polygon.Regions);
            mesh.behavior.useRegions = polygon.Regions.Count > 0;

            if (polygon.Segments.Count > 0)
            {
                mesh.behavior.Poly = true;
                mesh.holes.AddRange(polygon.Holes);
            }

            // Create the triangles.
            for (i = 0; i < elements; i++)
            {
                mesh.MakeTriangle(ref tri);
            }

            if (mesh.behavior.Poly)
            {
                mesh.insegments = segments;

                // Create the subsegments.
                for (i = 0; i < segments; i++)
                {
                    mesh.MakeSegment(ref subseg);
                }
            }

            var vertexarray = SetNeighbors(mesh, triangles);

            SetSegments(mesh, polygon, vertexarray);

            return(mesh);
        }
        private void ComputeCircumCenters()
        {
            Otri  tri = default(Otri);
            float xi = 0, eta = 0;
            Point pt;

            // Compue triangle circumcenters
            foreach (var item in _TriangleNetMesh.triangles)
            {
                tri.tri = item;

                pt    = predicates.FindCircumcenter(tri.Org(), tri.Dest(), tri.Apex(), ref xi, ref eta);
                pt.id = item.id;

                points[item.id] = pt;
            }
        }
示例#23
0
        SplayNode FrontLocate(SplayNode splayroot, Otri bottommost, Vertex searchvertex,
                              ref Otri searchtri, ref bool farright)
        {
            bool farrightflag;

            bottommost.Copy(ref searchtri);
            splayroot = Splay(splayroot, searchvertex, ref searchtri);

            farrightflag = false;
            while (!farrightflag && RightOfHyperbola(ref searchtri, searchvertex))
            {
                searchtri.Onext();
                farrightflag = searchtri.Equals(bottommost);
            }
            farright = farrightflag;
            return(splayroot);
        }
示例#24
0
        void Check4DeadEvent(ref Otri checktri, SweepEvent[] eventheap, ref int heapsize)
        {
            SweepEvent       deadevent;
            SweepEventVertex eventvertex;
            int eventnum = -1;

            eventvertex = checktri.Org() as SweepEventVertex;
            if (eventvertex != null)
            {
                deadevent = eventvertex.evt;
                eventnum  = deadevent.heapposition;

                HeapDelete(eventheap, heapsize, eventnum);
                heapsize--;
                checktri.SetOrg(null);
            }
        }
示例#25
0
        private void ComputeCircumCenters()
        {
            Otri   tri = default(Otri);
            double xi = 0, eta = 0;
            Point  pt;

            // Compue triangle circumcenters
            foreach (var item in mesh.triangles.Values)
            {
                tri.triangle = item;

                pt    = Primitives.FindCircumcenter(tri.Org(), tri.Dest(), tri.Apex(), ref xi, ref eta);
                pt.id = item.id;

                points[item.id] = pt;
            }
        }
示例#26
0
        public bool CheckDelaunay()
        {
            Otri otri    = new Otri();
            Otri otri1   = new Otri();
            Osub osub    = new Osub();
            bool noExact = Behavior.NoExact;

            Behavior.NoExact = false;
            int num = 0;

            foreach (Triangle value in this.mesh.triangles.Values)
            {
                otri.triangle = value;
                otri.orient   = 0;
                while (otri.orient < 3)
                {
                    Vertex vertex  = otri.Org();
                    Vertex vertex1 = otri.Dest();
                    Vertex vertex2 = otri.Apex();
                    otri.Sym(ref otri1);
                    Vertex vertex3 = otri1.Apex();
                    bool   flag    = (otri1.triangle == Mesh.dummytri || Otri.IsDead(otri1.triangle) || otri.triangle.id >= otri1.triangle.id || !(vertex != this.mesh.infvertex1) || !(vertex != this.mesh.infvertex2) || !(vertex != this.mesh.infvertex3) || !(vertex1 != this.mesh.infvertex1) || !(vertex1 != this.mesh.infvertex2) || !(vertex1 != this.mesh.infvertex3) || !(vertex2 != this.mesh.infvertex1) || !(vertex2 != this.mesh.infvertex2) || !(vertex2 != this.mesh.infvertex3) || !(vertex3 != this.mesh.infvertex1) || !(vertex3 != this.mesh.infvertex2) ? false : vertex3 != this.mesh.infvertex3);
                    if (this.mesh.checksegments & flag)
                    {
                        otri.SegPivot(ref osub);
                        if (osub.seg != Mesh.dummysub)
                        {
                            flag = false;
                        }
                    }
                    if (flag && Primitives.NonRegular(vertex, vertex1, vertex2, vertex3) > 0)
                    {
                        this.logger.Warning(string.Format("Non-regular pair of triangles found (IDs {0}/{1}).", otri.triangle.id, otri1.triangle.id), "Quality.CheckDelaunay()");
                        num++;
                    }
                    otri.orient = otri.orient + 1;
                }
            }
            if (num == 0)
            {
                this.logger.Info("Mesh is Delaunay.");
            }
            Behavior.NoExact = noExact;
            return(num == 0);
        }
示例#27
0
        private void ComputeCircumCenters()
        {
            Otri   otri = new Otri();
            double num  = 0;
            double num1 = 0;

            foreach (Triangle value in this.mesh.triangles.Values)
            {
                otri.triangle = value;
                Point point = Primitives.FindCircumcenter(otri.Org(), otri.Dest(), otri.Apex(), ref num, ref num1);
                point.id = value.id;
                this.points[value.id] = point;
                this.bounds.Update(point.x, point.y);
            }
            double num2 = Math.Max(this.bounds.Width, this.bounds.Height);

            this.bounds.Scale(num2, num2);
        }
示例#28
0
        /// <summary>
        /// Enumerate all edges of the given mesh.
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="skipSegments"></param>
        /// <returns></returns>
        /// <remarks>
        /// In contrast to <see cref="EnumerateEdges(IMesh)"/> this method will return
        /// objects that include the vertex information (and not only the indices).
        /// </remarks>
        public static IEnumerable <ISegment> EnumerateEdges(IMesh mesh, bool skipSegments = true)
        {
            Otri tri      = default;
            Otri neighbor = default;
            Osub sub      = default;

            Vertex p1, p2;

            bool segments = !skipSegments;

            foreach (var t in mesh.Triangles)
            {
                tri.tri    = t;
                tri.orient = 0;

                for (int i = 0; i < 3; i++)
                {
                    tri.Sym(ref neighbor);

                    int nid = neighbor.tri.id;

                    if ((tri.tri.id < nid) || (nid == Mesh.DUMMY))
                    {
                        p1 = tri.Org();
                        p2 = tri.Dest();

                        tri.Pivot(ref sub);

                        if (sub.seg.hash == Mesh.DUMMY)
                        {
                            yield return(new Segment(p1, p2));
                        }
                        else if (segments)
                        {
                            // Segments might be processed separately, so only
                            // include them if requested.
                            yield return(sub.seg);
                        }
                    }

                    tri.orient++;
                }
            }
        }
示例#29
0
        /// <summary>
        /// Write the triangles to an .ele file.
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="filename"></param>
        public void WriteElements(Mesh mesh, string filename)
        {
            Otri   tri = default(Otri);
            Vertex p1, p2, p3;
            bool   regions = mesh.behavior.useRegions;

            int j = 0;

            tri.orient = 0;

            using (
#if NETFX_CORE
                var writer = new WinRTLegacy.IO.StreamWriter(filename)
#else
                var writer = new StreamWriter(filename)
#endif
                )
            {
                // Number of triangles, vertices per triangle, attributes per triangle.
                writer.WriteLine("{0} 3 {1}", mesh.triangles.Count, regions ? 1 : 0);

                foreach (var item in mesh.triangles)
                {
                    tri.tri = item;

                    p1 = tri.Org();
                    p2 = tri.Dest();
                    p3 = tri.Apex();

                    // Triangle number, indices for three vertices.
                    writer.Write("{0} {1} {2} {3}", j, p1.id, p2.id, p3.id);

                    if (regions)
                    {
                        writer.Write(" {0}", tri.tri.label);
                    }

                    writer.WriteLine();

                    // Number elements
                    item.id = j++;
                }
            }
        }
示例#30
0
            public Ztestcube3(int start, int stop)
            {
                this.start = start;
                this.stop  = stop;
                framedelta = 100;

                points = new vec3[] {
                    v3(-10f, -10f, 90f),
                    v3(-10f, -10f, 110f),
                    v3(-10f, 10f, 90f),
                    v3(-10f, 10f, 110f),
                    v3(10f, -10f, 90f),
                    v3(10f, -10f, 110f),
                    v3(10f, 10f, 90f),
                    v3(10f, 10f, 110f),
                };

                _points = new vec3[points.Length];

                cube = new Cube(
                    Color.Cyan,
                    Color.Lime,
                    Color.Red,
                    Color.Blue,
                    Color.Yellow,
                    Color.Orange,
                    _points,
                    PA,
                    PD,
                    PC,
                    PB,
                    PF,
                    PE,
                    PH,
                    PG
                    );

                tris = new Otri[24];
                for (int i = 0; i < tris.Length; i++)
                {
                    tris[i] = new Otri();
                }
            }