Exemplo n.º 1
0
        bool SetBoundary()
        {
            {
                m_Mesh2D.DeleteInit();

                int numBoundary = m_ArrayMeshBoundary.Count;
                for (int i = 0; i < numBoundary; i++)
                {
                    if (m_ArrayMeshBoundary[i].FlagHole)
                    {
                        m_Mesh2D.SetBoundary(m_ArrayMeshBoundary[i]);
                    }
                }

                // Elimina eventuali spigoli isolati
                for (int i = 0; i < m_Mesh2D.ArrayWEdges.Count; i++)
                {
                    AM_Edge pedge = m_Mesh2D.ArrayWEdges[i].Edge();
                    if (pedge.CcwFace() == null && pedge.CwFace() == null)
                    {
                        m_Mesh2D.DeleteEdge(pedge);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 2
0
        AM_Edge Locate(Point2d x)
        {
            AM_Edge e          = m_StartingEdge;
            int     actualEdge = 0;
            int     numEdge    = m_ArrayWEdges.Count;

            while (actualEdge++ <= numEdge)
            {
                if (x == e.OrgCoord() || x == e.DestCoord())
                {
                    return(e);
                }
                else if (AM_Edge.RightOf(x, e))
                {
                    e = e.Symm();
                }
                else if (!AM_Edge.RightOf(x, e.Next))
                {
                    e = e.Next;
                }
                else if (!AM_Edge.RightOf(x, e.CcwEdge().Symm()))
                {
                    e = e.CcwEdge().Symm();
                }
                else
                {
                    return(e);
                }
            }
            return(null);
        }
Exemplo n.º 3
0
        bool OnEdge(Point2d p, AM_Edge edge)
        {
            double t1, t2, t3;
            double EPS = 1e-6;

            Point2d org = edge.OrgCoord();

            t1 = (p - org).Length;
            t2 = (p - edge.DestCoord()).Length;
            if (t1 < EPS || t2 < EPS)
            {
                return(true);
            }

            Vector2d vector = org - edge.DestCoord();

            t3 = vector.Length;
            if (t1 > t3 || t2 > t3)
            {
                return(false);
            }

            double a = vector.Y / t3;
            double b = -vector.X / t3;
            double c = -(a * org.X + b * org.Y);

            return(Math.Abs((a * p.X + b * p.Y + c)) < EPS);
        }
Exemplo n.º 4
0
        private void AddTransitionVertexes(AM_Vertex v, List <int> transitionVts)
        {
            if ((v.Flag & 0x02) == 0)
            {
                v.Flag |= 0x02;
                transitionVts.Add(v.Index);

                AM_Edge start_edge = v.Edge;
                AM_Edge edge       = start_edge.Next;

                while (edge != start_edge)
                {
                    if ((edge.Flag & 0x04) == 0)
                    {
                        edge.Flag |= 0x04;
                        var dest = edge.Destination();
                        if ((dest.Flag & 0x01) == 0)
                        {
                            AddTransitionVertexes(dest, transitionVts);
                        }
                    }
                    edge = edge.Next;
                }
            }
        }
Exemplo n.º 5
0
        bool CheckSwapEdge(AM_Edge pedge)
        {
            // Controlla l'ammissibilità dello swap.
            // Uno spigolo può essere scambiato all'interno di un quadrangolo
            // se quest'ultimo è convesso.

            Point2d p1 = pedge.CcwEdge().DestCoord();
            Point2d p2 = pedge.OrgCoord();
            Point2d p3 = pedge.DestCoord();
            Point2d p4 = pedge.Symm().CcwEdge().DestCoord();

            Vector2d v1 = p4 - p2;
            Vector2d v2 = p1 - p2;

            v1.Unitize();
            v2.Unitize();

            if ((v1.X * v2.Y - v2.X * v1.Y) < AM_Util.FLT_EPSILON)
            {
                return(false);
            }

            Vector2d v3 = p1 - p3;
            Vector2d v4 = p4 - p3;

            v3.Unitize();
            v4.Unitize();

            if ((v3.X * v4.Y - v4.X * v3.Y) < AM_Util.FLT_EPSILON)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 6
0
        internal AM_Coedge(AM_Vertex vtx_org, AM_Vertex vtx_dest)
        {
            m_Edges[0] = new AM_Edge(this, 0);
            m_Edges[1] = new AM_Edge(this, 1);

            m_Edges[0].Vertex = vtx_org;
            m_Edges[1].Vertex = vtx_dest;
        }
Exemplo n.º 7
0
        internal static void SwapEdge(AM_Edge pedge)
        {
            Debug.Assert(pedge.CcwFace().NumEdges == 3);
            Debug.Assert(pedge.CwFace().NumEdges == 3);

            AM_Edge pstart = pedge;

            do
            {
                Point2d p1 = pedge.CcwEdge().DestCoord();
                Point2d p2 = pedge.OrgCoord();
                Point2d p3 = pedge.DestCoord();
                Point2d p4 = pedge.Symm().CcwEdge().DestCoord();

                //int n1 = pedge.CcwEdge().Destination().Index;
                //int n2 = pedge.Origin().Index;
                //int n3 = pedge.Destination().Index;
                //int n4 = pedge.Symm().CcwEdge().Destination().Index;

                //int v1 = pedge.CcwEdge().Symm().m_nVertex;
                //int v2 = pedge.m_nVertex;
                //int v3 = pedge.Symm().m_nVertex;
                //int v4 = pedge.Symm().CcwEdge().Symm().m_nVertex;

                AM_Edge poldPrev = pedge.Prev;
                AM_Edge poldNext = pedge.Next;
                AM_Edge pnewNext = pedge.Prev.Symm();
                AM_Edge pnewPrev = pnewNext.Prev;
                AM_Face poldFace = pedge.Face;


                pedge.Origin().Edge = poldNext;
                pedge.Vertex = pnewNext.Vertex; // Ripristina l'origine...
                pedge.Origin().Edge = pedge;    // e aggiorna il suo puntatore

                // ripristina i collegamenti corretti
                poldPrev.Next = poldNext;
                poldNext.Prev = poldPrev;
                pnewPrev.Next = pedge;
                pnewNext.Prev = pedge;
                pedge.Next    = pnewNext;
                pedge.Prev    = pnewPrev;

                Debug.Assert(pedge.Origin() != pedge.Destination());

                // parte dallo spigolo che definisce la faccia sinistra
                // e che è precedente in senso antiorario
                pnewNext = poldNext.Symm();
                for (int i = 0; i < 3; i++)
                {
                    pnewNext.Face = poldFace;
                    poldFace[i]   = pnewNext;
                    pnewNext      = pnewNext.CcwEdge();
                }

                pedge = pedge.Symm();
            } while (pstart != pedge);
        }
Exemplo n.º 8
0
        void Init(Point3d a, Point3d b, Point3d c)
        {
            Debug.Assert(m_ArrayFaces.Count == 0);

            AM_Face face = new AM_Face();

            Point3d[] coord = { a, b, c };
            AddFace(face, coord);
            m_StartingEdge = face[0];
        }
Exemplo n.º 9
0
        bool DeleteVertex(AM_Vertex vertex, bool bdelete = false)
        {
            // Cancella un vertice dall'array globale dei vertici
            if (vertex == null || vertex.Index < 0)
            {
                Debug.Assert(false);
                return(false);
            }

            int nindex = vertex.Index;
            int nlast  = m_ArrayVertexes.Count - 1;

            // La cancellazione dall'array globale degli vertici avviene
            // spostando l'ultimo vertice dell'array al posto di quello da cancellare
            m_ArrayVertexes[nindex]       = m_ArrayVertexes[nlast];
            m_ArrayVertexes[nindex].Index = nindex;
            m_ArrayVertexes.RemoveAt(nlast);

            if (nlast != nindex)
            {
                // è necessario aggiornare opportunamente l'anello del vertice
                // aggiornando il dato membro m_nVertex;
                AM_Edge pstartEdge = m_ArrayVertexes[nindex].Edge;
                AM_Edge edge       = pstartEdge;

                if (pstartEdge == null)
                {
                    Debug.Assert(false);
                    return(true);
                }

                do
                {
                    edge.Vertex = m_ArrayVertexes[nindex];
                    edge        = edge.Next;
                } while (edge != pstartEdge);

                if (bdelete)
                {
                    //delete vertex;
                    vertex.Edge  = null;
                    vertex.Index = -1;
                }
                else
                {
                    vertex.Edge  = null;
                    vertex.Index = -1;
                }
            }

            return(true);
        }
Exemplo n.º 10
0
        internal AM_Edge FindEdge(AM_Vertex pVertex2)
        {
            AM_Edge pNext = m_Edge;

            do
            {
                if (pNext.Destination() == pVertex2)
                {
                    return(pNext);
                }
                pNext = pNext.Next;
            } while (pNext != m_Edge);
            return(null);
        }
Exemplo n.º 11
0
        void RelaxMesh()
        {
            // Esegue la procedura di "Mesh Relaxation"
            bool bPrev = m_bFlagClassific;

            m_bFlagClassific = false;
            for (int DiffDegree = 3; DiffDegree >= 2; DiffDegree--)
            {
                for (int i = 0; i < m_ArrayWEdges.Count; i++)
                {
                    AM_Edge edge = m_ArrayWEdges[i].Edge();
                    if (edge.CcwFace() != null && edge.CwFace() != null)
                    {
                        AM_Vertex [] Vertex = { edge.Origin(),
                                                edge.Destination(),
                                                edge.Next.Destination(),
                                                edge.Prev.Destination(), };
                        double []    degree = { 0, 0, 0, 0 };
                        for (int j = 0; j < degree.Length; j++)
                        {
                            degree[j] = Vertex[j].Degree();
                        }

                        double R = 0;
                        for (int j = 0; j < 4; j++)
                        {
                            R += (6 - degree[j]) * (6 - degree[j]);
                        }

                        // aggiorna il grado con l'ipotesi do swap
                        degree[0] -= 1;
                        degree[1] -= 1;
                        degree[2] += 1;
                        degree[3] += 1;

                        double R1 = 0;
                        for (int j = 0; j < 4; j++)
                        {
                            R1 += (6 - degree[j]) * (6 - degree[j]);
                        }

                        if (R - R1 >= DiffDegree)
                        {
                            Swap(edge);
                        }
                    }
                }
            }
            m_bFlagClassific = bPrev;
        }
Exemplo n.º 12
0
        internal double Degree(bool bSimple = false)
        {
            int degree = 0;

            if (m_Edge == null)
            {
                Debug.Assert(false);
                return(0);
            }

            // Il "grado" di un vertice è definito come il numero di vertici
            // ad esso conneesso.
            if (bSimple)
            {
                // Se bSimple = true si conta semplicemente il numero
                // di spigoli connessi

                AM_Edge pNext = m_Edge;
                do
                {
                    degree++;
                    pNext = pNext.Next;
                } while (pNext != m_Edge);
                return(degree);
            }

            double angle = 0;

            {
                AM_Edge pNext = m_Edge;
                do
                {
                    degree++;
                    if (pNext.CcwFace() != null)
                    {
                        Vector2d v0 = (pNext.DestCoord() - m_Coord);
                        Vector2d v1 = (pNext.Next.DestCoord() - m_Coord);
                        v0.Unitize();
                        v1.Unitize();

                        double cos_ang = Vector2d.Multiply(v0, v1);
                        angle += Math.Acos(cos_ang);
                    }
                    pNext = pNext.Next;
                } while (pNext != m_Edge);
            }

            return(degree * 2 * Math.PI / angle);
        }
Exemplo n.º 13
0
        bool RefineMeshStep()
        {
            AM_Face face = null;

            Point2d innerPoint;

            AM_Face triangleContaining = null;

            face = FindMaxActive();

            if (face == null)
            {
                return(false);
            }

            m_StartingEdge = face.GetStartingEdge();
            innerPoint     = face.InsertPoint(m_pSpaceFunction);

            //localizzo il triangolo che contiene il punto per fare il test di spaziatura.
            AM_Edge e = Locate(innerPoint);

            triangleContaining = e != null? (AM_Edge.RightOf(innerPoint, e) ? e.CwFace() : e.CcwFace())
                           : null;

            if (triangleContaining == null)
            {
                DeleteActiveFace(face);
            }
            else
            {
                //innerPoint.Z = triangleContaining.SpaceFunction(innerPoint, m_pSpaceFunction);
                double s = triangleContaining.SpaceFunction(innerPoint, m_pSpaceFunction);
                if (triangleContaining.SpacingTest(innerPoint, m_pSpaceFunction))
                {
                    AM_Vertex vertex;
                    if (!InsertPoint(innerPoint, s, out vertex))
                    {
                        DeleteActiveFace(face);
                    }
                }
                else
                {
                    DeleteActiveFace(face);
                }
            }

            return(true);
        }
Exemplo n.º 14
0
        internal AM_Edge GetGenEdge(int i)
        {
            int numVertex = GetNumGenVertex();

            if (i >= numVertex)
            {
                Debug.Assert(false);
                return(null);
            }

            AM_Vertex pV1 = m_ArrayVertex[i];
            AM_Vertex pV2 = m_ArrayVertex[(i + 1) % numVertex];

            AM_Edge pEdge = pV1.FindEdge(pV2);;

            return(pEdge);
        }
Exemplo n.º 15
0
        internal bool GetCoordZ(Point2d p, ref double Z)
        {
            // Localizza uno spigolo vicino
            AM_Edge edge = Locate(p);

            if (edge == null)
            {
                return(false);
            }

            AM_Face face = null;

            if (AM_Edge.LeftOf(p, edge))
            {
                face = edge.CcwFace();
            }
            else
            {
                face = edge.CwFace();
            }

            Z = 0;
            if (face == null)
            {
                return(false);
            }

            Point2d p0 = face.Vertex(0).Coord;
            Point2d p1 = face.Vertex(1).Coord;
            Point2d p2 = face.Vertex(2).Coord;

            double det = AM_Util.TriArea(p0, p1, p2);

            Debug.Assert(det != 00);
            double alfa = AM_Util.TriArea(p0, p, p2) / det;
            double beta = AM_Util.TriArea(p0, p1, p) / det;

            double f0 = face.Vertex(0).Z;
            double f1 = face.Vertex(1).Z;
            double f2 = face.Vertex(2).Z;

            Z = f0 + alfa * (f1 - f0) + beta * (f2 - f0);

            return(true);
        }
Exemplo n.º 16
0
        AM_Edge FindEdge(AM_Vertex org, AM_Vertex dest)
        {
            AM_Edge pstart = org.Edge;

            if (pstart != null)
            {
                AM_Edge pnext = pstart;
                do
                {
                    if (pnext.Destination() == dest)
                    {
                        return(pnext); // lo spigolo esiste già
                    }
                    pnext = pnext.Next;
                } while (pnext != pstart);
            }
            return(null);
        }
Exemplo n.º 17
0
        internal int NumDegree()
        {
            if (m_Edge == null)
            {
                return(0);
            }

            int degree = 0;

            AM_Edge pNext = m_Edge;

            do
            {
                degree++;
                pNext = pNext.Next;
            } while (pNext != m_Edge);
            return(degree);
        }
Exemplo n.º 18
0
        internal bool CheckWEdge()
        {
            for (int i = 0; i < m_ArrayWEdges.Count; i++)
            {
                AM_Edge edge = m_ArrayWEdges[i].Edge();
                Debug.Assert(edge.Origin() != edge.Destination());
            }

            for (int i = 0; i < m_ArrayFaces.Count; i++)
            {
                AM_Face edge = m_ArrayFaces[i];
                double  area = AM_Util.TriArea(edge[0].OrgCoord(),
                                               edge[1].OrgCoord(),
                                               edge[2].OrgCoord());
                Debug.Assert(area > 0);
            }

            return(true);
        }
Exemplo n.º 19
0
        bool BelongToBorder(AM_Vertex v)
        {
            AM_Edge start_edge = v.Edge;

            if (start_edge != null)
            {
                AM_Edge edge = start_edge.Next;
                while (edge != start_edge)
                {
                    if (edge.CcwFace() == null || edge.CwFace() == null)
                    {
                        return(true);
                    }
                    edge = edge.Next;
                }
            }

            return(false);
        }
Exemplo n.º 20
0
        AM_Edge AddEdge(AM_Vertex org, AM_Vertex dest)
        {
            AM_Coedge pwEdge = new AM_Coedge(org, dest);

            if (pwEdge == null)
            {
                Debug.Assert(false);
                //throw -1;
            }

            pwEdge.Index = m_ArrayWEdges.Count;
            m_ArrayWEdges.Add(pwEdge);

            AM_Edge edge = pwEdge.Edge();

            //edge.m_pArrayVertex = &m_ArrayVertexes;
            //edge.Symm().m_pArrayVertex = &m_ArrayVertexes;
            return(edge);
        }
Exemplo n.º 21
0
        void Swap(AM_Edge edge)
        {
            AM_Face face1 = (AM_Face)edge.CcwFace();
            AM_Face face2 = (AM_Face)edge.CwFace();

            if (face1 == null || face2 == null)
            {
                if (face1 != null && face1.FaceType == AM_Face.EFaceType.FT_ACTIVE)
                {
                    DeleteActiveFace(face1);
                }
                if (face2 != null && face2.FaceType == AM_Face.EFaceType.FT_ACTIVE)
                {
                    DeleteActiveFace(face2);
                }
                return;
            }

            Debug.Assert(edge.CwFace() != null);
            Debug.Assert(edge.CcwFace() != null);

            if (face1.FaceType == AM_Face.EFaceType.FT_ACTIVE)
            {
                DeleteActiveFace(face1);
            }

            if (face2.FaceType == AM_Face.EFaceType.FT_ACTIVE)
            {
                DeleteActiveFace(face2);
            }

            AM_Face.SwapEdge(edge);

            if (m_bFlagClassific)
            {
                face1.SetTriangleParameter(m_pSpaceFunction);
                face2.SetTriangleParameter(m_pSpaceFunction);
                Classific(face1);
                Classific(face2);
            }
        }
Exemplo n.º 22
0
        internal bool InnerTest(Point2d p)
        {
            Point2d x = p;

            // Per appartenere alla faccia devono essere tutte a sinistra dello spigolo
            for (int i = 0; i < 3; i++)
            {
                AM_Edge e = m_pEdges[i];
                if (x.EpsilonEquals(e.OrgCoord(), AM_Util.FLT_EPSILON))
                {
                    return(true);
                }

                if (AM_Edge.RightOf(x, e))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 23
0
        internal int NumConnectedFace()
        {
            if (m_Edge == null)
            {
                return(0);
            }

            int nFace = 0;

            AM_Edge pNext = m_Edge;

            do
            {
                if (pNext.CcwFace() != null)
                {
                    nFace++;
                }
                pNext = pNext.Next;
            } while (pNext != m_Edge);

            return(nFace);
        }
Exemplo n.º 24
0
        bool IsBoundaryVertex(AM_Vertex pvertex)
        {
            AM_Edge start = pvertex.Edge;

            if (start == null)
            {
                Debug.Assert(false);
                return(false); // Indefinito
            }

            AM_Edge edge = start;

            do
            {
                if (edge.CwFace() == null || edge.CcwFace() == null)
                {
                    return(true);
                }

                edge = edge.Next;
            } while (start != edge);

            return(false);
        }
Exemplo n.º 25
0
        internal bool RecoverGenEdge(AM_Mesh2d mesh, int num, List <Point3d> AddArray, bool bStraight = false)
        {
            // se viene inserito un punto per aggiustare la conformità
            // il flag baddFlag diventa true
            bool baddFlag = false;

            if (!m_bFlagHole && num >= m_GenVertexArray.Count)
            {
                return(true);
            }

            int v1 = m_GenVertexArray[num];
            int v2 = m_GenVertexArray[(num + 1) % m_GenVertexArray.Count];

            if (v2 < v1)
            {
                v2 += GetNumVertex();
            }

            AM_Edge pbase;
            AM_Edge pprev = pbase = Vertex(v1).Edge;

            for (int i = v1 + 1; i <= v2; i++)
            {
                AM_Vertex pV1 = Vertex((i - 1) % (GetNumVertex()));
                AM_Vertex pV2 = Vertex((i) % (GetNumVertex()));

                Point2d orgCoord = pV1.Coord;

                // si controlla che tutti i vertici siano in sequenza
                while (true)
                {
                    Point2d baseCoord = pbase.DestCoord();

                    Point2d prvCoord  = new Point2d(m_ArrayCoord[(i - 1) % (GetNumVertex())]);
                    Point2d destCoord = new Point2d(m_ArrayCoord[i % (GetNumVertex())]);

                    if (baseCoord == destCoord)
                    {
                        // il vertice è in sequenza: si continua con il successivo
                        break;
                    }
                    else
                    {
                        pbase = pbase.Next;

                        if (pbase == pprev)
                        {
                            // il ciclo dell'anello si è chiuso senza trovare il vertice
                            // successivo; è necessario inserire un vertice in mezzeria del
                            // lato mancante

                            if (!bStraight)
                            {
                                // 1. Algoritmo di ripristino del bordo con l'aggiunta del punto medio
                                baddFlag = true; // si segnala l'aggiunta di un vertice

                                Point3d p1    = m_ArrayCoord[i - 1];
                                Point3d p2    = (m_ArrayCoord[i % (GetNumVertex())]);
                                Point3d mid   = 0.5 * (p1 + p2);
                                Point3d insPt = new Point3d(mid.X, mid.Y, 0);

                                // si inserisce un vertice nel mezzo del
                                AM_Vertex pvertex;
                                mesh.InsertPoint(new Point2d(insPt), insPt.Z, out pvertex);

                                if (pvertex == null)
                                {
                                    Debug.Assert(false);
                                    //throw 6;
                                }


                                InsertVertex(i, pvertex);
                                v2++;
                                AddArray.Add(insPt);

                                // si ricomincia il controllo
                                pbase = Vertex(i - 1).Edge;
                                pprev = pbase;
                            }
                            else
                            {
                                // 2. Algoritmo di ripristino del bordo con swap di spigoli
                                AM_Edge pdest = Vertex(i).Edge;

                                Vector2d dir = destCoord - orgCoord;
                                dir.Unitize();

                                var m = AM_Util.AffineMatrix(orgCoord, dir);

                                while (pV1.FindEdge(pV2) == null)
                                {
                                    bool    bCoinc  = false;
                                    AM_Edge pSearch = pbase;

                                    // Si controllano situazioni di appartenenza al lato da ripristinare
                                    do
                                    {
                                        double cosang = Vector2d.Multiply(pSearch.GetVersor(), dir);

                                        if (AM_Util.IsEqual(cosang, 1, AM_Util.FLT_EPSILON))
                                        {
                                            // Lo spigolo appartiene già al lato da ripristinare
                                            InsertVertex(i, pSearch.Destination());
                                            v2++;

                                            Point2d dc = pSearch.DestCoord();
                                            AddArray.Add(new Point3d(dc.X, dc.Y, 0));

                                            // si ricomincia il controllo
                                            pbase = Vertex(i - 1).Edge;
                                            pprev = pbase;

                                            bCoinc = true;
                                            break;
                                        }
                                        pSearch = pSearch.Next;
                                    } while (pSearch != pbase);

                                    if (bCoinc)
                                    {
                                        break;
                                    }

                                    // Trova il lato di partenza
                                    pSearch = pbase;

                                    while (!AM_Util.IsInside(pSearch.GetVector(), pSearch.Next.GetVector(), dir))
                                    {
                                        pSearch = pSearch.Next;
                                        if (pSearch == pprev)
                                        {
                                            Debug.Assert(false);
                                            //mesh.ExportMesh("RecoverSt7.txt");
                                            return(false);
                                        }
                                    }

                                    AM_Edge        pStartEdge = pSearch.CcwEdge();
                                    List <AM_Edge> swapArray  = new List <AM_Edge>();

                                    while (pStartEdge.Destination() != pV2)
                                    {
                                        Point2d o = pStartEdge.OrgCoord();
                                        Point2d d = pStartEdge.DestCoord();
                                        swapArray.Add(pStartEdge);

                                        pStartEdge = pStartEdge.Prev;
                                        Point2d pt = AM_Util.ToLocal(m, pStartEdge.DestCoord());
                                        if (pt.Y < -AM_Util.FLT_EPSILON)
                                        {
                                            pStartEdge = pStartEdge.CcwEdge();

                                            Debug.Assert(AM_Util.ToLocal(m, pStartEdge.DestCoord()).Y > 0);
                                        }
                                    }

                                    for (int j = 0; j < swapArray.Count; j++)
                                    {
                                        AM_Edge pSwapEdge = swapArray[j];

                                        // Vengono ruotati gli spigoli all'interno
                                        if (AM_Util.CheckSwapEdge(pSwapEdge))
                                        {
                                            Debug.Assert(pSearch.CcwFace() != null && pSearch.Next.CwFace() != null);
                                            Debug.Assert(pSwapEdge.CcwFace() != null && pSwapEdge.CwFace() != null);

                                            AM_Face.SwapEdge(pSwapEdge);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                pbase = Vertex(i % (GetNumVertex())).Edge;
                pprev = pbase;
            }

            return(baddFlag);
        }
Exemplo n.º 26
0
        // --- Copia ---
        AM_Boundary CopyBoundary(AM_Mesh2d source, AM_Mesh2d dest,
                                 bool bSameGenVertex = true)
        {
            AM_Boundary pCopy = new AM_Boundary();

            pCopy.m_LoopIndex = m_LoopIndex;

            if (bSameGenVertex)
            {
                // Il numero dei vertici generati è lo stesso;
                // viene normalmente usato in caso di 'merge' tra due mesh adiacenti
                pCopy.m_ArrayCoord.Capacity = m_ArrayCoord.Count;
                for (int i = 0; i < m_ArrayCoord.Count; i++)
                {
                    pCopy.m_ArrayCoord[i] = m_ArrayCoord[i];
                }

                pCopy.m_GenVertexArray.Capacity = m_GenVertexArray.Count;
                for (int i = 0; i < m_GenVertexArray.Count; i++)
                {
                    pCopy.m_GenVertexArray[i] = m_GenVertexArray[i];
                }

                // Trova il primo vertice
                int destVertex = dest.ArrayVertexes.Count;
                int nVertex    = dest.AddVertex(new Point2d(m_ArrayCoord[0]), m_ArrayCoord[0].Z);
                Debug.Assert(nVertex < destVertex); // non vengono aggiunti vertici

                AM_Vertex pVertex = dest.ArrayVertexes[nVertex];
                pVertex.Flag |= 0x01;
                pCopy.m_ArrayVertex.Add(pVertex);

                for (int i = 1; i < m_ArrayCoord.Count; i++)
                {
                    Point2d ptDest    = new Point2d(m_ArrayCoord[i]);
                    AM_Edge pEdge     = pVertex.Edge;
                    AM_Edge pNextEdge = pEdge.Next;

                    while ((ptDest - pNextEdge.DestCoord()).Length > AM_Util.FLT_EPSILON)
                    {
                        if (pNextEdge == pEdge)
                        {
                            Debug.Assert(false);
                            nVertex = dest.AddVertex(ptDest, 0);
                            Debug.Assert(nVertex < destVertex);
                            pNextEdge = dest.ArrayVertexes[nVertex].Edge.Symm();
                            break;
                        }
                        pNextEdge = pNextEdge.Next;
                    }

                    pVertex       = pNextEdge.Destination();
                    pVertex.Flag |= 0x01;
                    pCopy.m_ArrayVertex.Add(pVertex);
                }

                Debug.Assert(pCopy.m_ArrayVertex.Count == m_ArrayVertex.Count);
            }
            else
            {
                // Il numero dei vertici generati è diverso;
                // viene normalmente usato in caso di ricostruzione di contorni
                pCopy.m_GenVertexArray.Capacity = m_GenVertexArray.Count;

                for (int i = 1; i < m_GenVertexArray.Count; i++)
                {
                    Point2d p0 = new Point2d(m_ArrayCoord[m_GenVertexArray[i - 1]]);
                    Point2d p1 = new Point2d(m_ArrayCoord[m_GenVertexArray[i]]);

                    AM_Vertex pV0 = dest.RangeSearch.Search(p0.X, p0.Y);
                    AM_Vertex pV1 = dest.RangeSearch.Search(p1.X, p1.Y);
                    Debug.Assert(pV0 != null && pV1 != null);

                    // La direzione è data dal vettore p0-p1
                    Vector2d vDir = (p1 - p0);
                    vDir.Unitize();

                    pCopy.m_GenVertexArray[i - 1] = pCopy.m_ArrayCoord.Count;

                    AM_Vertex pV = pV0;
                    while (pV != pV1)
                    {
                        pCopy.m_ArrayCoord.Add(new Point3d(pV.Coord.X, pV.Coord.Y, 0));
                        pCopy.m_ArrayVertex.Add(pV);

                        // Trova il vertice successivo
                        double minCos = -double.MaxValue;

                        AM_Edge pEdge    = pV.Edge;
                        AM_Edge pDirEdge = null;

                        do
                        {
                            double dirCos = pEdge.GetVersor() * vDir;
                            if (dirCos > minCos)
                            {
                                minCos   = dirCos;
                                pDirEdge = pEdge;
                            }

                            pEdge = pEdge.Next;
                        } while (pEdge != pV.Edge);

                        Debug.Assert(AM_Util.IsEqual(minCos, 1));
                        pV = pDirEdge.Destination();
                    }
                }
            }

            return(pCopy);
        }
Exemplo n.º 27
0
 internal static bool LeftOf(Point2d x, AM_Edge pedge)
 {
     return(AM_Util.CCW(x, pedge.OrgCoord(), pedge.DestCoord()));
 }
Exemplo n.º 28
0
        // Connessioni
        internal bool SetConnection()
        {
            // testa la compatibilità delle facce. Eventuali problemi
            // possono insorgere se vi è incoerenza tra le normali di
            // due facce adiacenti
            for (int i = 0; i < NumEdges; i++)
            {
                if (m_pEdges[i].Face != null)
                {
                    return(false);
                }
            }

            Debug.Assert(NumEdges <= 4);

            // Inizializza le connessioni preesistenti
            AM_Edge [] poldConn = new AM_Edge[8];
            for (int i = 0; i < 8; i++)
            {
                poldConn[i] = null;
            }

            for (int i = 0; i < NumEdges; i++)
            {
                AM_Edge pedge = m_pEdges[i];
                AM_Edge psymm = pedge.Symm();
                pedge.Face = this;

                if (pedge.Next != null)
                {
                    poldConn[i * 2] = pedge.Next;
                }
                pedge.Next = m_pEdges[(i + NumEdges - 1) % NumEdges].Symm();

                if (psymm.Prev != null)
                {
                    poldConn[i * 2 + 1] = psymm.Prev;
                }
                psymm.Prev = m_pEdges[(i + 1) % NumEdges];
            }

            if (!AdjustConnection(poldConn))
            {
                // la connessione è fallita: si ripristinano
                // le connessioni precedenti
                for (int i = 0; i < NumEdges; i++)
                {
                    AM_Edge pedge = m_pEdges[i];
                    AM_Edge psymm = pedge.Symm();
                    pedge.Face = null;

                    if (poldConn[i * 2] != null)
                    {
                        pedge.Next = poldConn[i * 2];
                    }
                    else
                    {
                        pedge.Next = null;
                    }

                    if (poldConn[i * 2 + 1] != null)
                    {
                        psymm.Prev = poldConn[i * 2 + 1];
                    }
                    else
                    {
                        psymm.Prev = null;
                    }
                }

                return(false);
            }
            return(true);
        }
Exemplo n.º 29
0
        bool AdjustConnection(AM_Edge[] poldConn)
        {
            for (int i = 0; i < NumEdges; i++)
            {
                AM_Edge pconnSx = poldConn[i * 2];
                AM_Edge pconnDx = poldConn[(i * 2 + (NumEdges * 2) - 1) % (NumEdges * 2)];


                if (pconnDx == null && pconnSx == null)
                {
                    if (Vertex(i).Edge != null)
                    {
                        // Inserisce i due spigoli della faccia nell'anello del vertice
                        // individuato da Vertex(i)

                        AM_Edge pedge = ((AM_Edge)(Vertex(i).Edge)).FindLastConnected();
                        Debug.Assert(pedge != null);
                        AM_Edge poldnextEdge = pedge.Next;

                        m_pEdges[i].Prev      = pedge;
                        pedge.Next            = m_pEdges[i];
                        poldnextEdge.Prev     = m_pEdges[i].Next;
                        m_pEdges[i].Next.Next = poldnextEdge;
                    }
                    else
                    {
                        // Lo spigolo è isolato: inizializza l'anello

                        m_pEdges[i].Prev      = m_pEdges[i].Next;
                        m_pEdges[i].Next.Next = m_pEdges[i];
                        Vertex(i).Edge        = m_pEdges[i];
                    }
                }
                else
                {
                    if (pconnSx == pconnDx)
                    {
                        continue;
                    }
                    // vi erano connessioni preesistenti: l'anello viene aggiornato
                    if (pconnSx != null) // anello in senso antiorario
                    {
                        AM_Edge padjust = pconnSx;
                        AM_Edge pstart  = pconnSx.Prev;

                        /*TRACE_EDGE(padjust);
                         * TRACE_EDGE(pstart);*/

                        int ncheck = 0; //contatore per evitare loop infinito
                        while (padjust != null)
                        {
                            if (ncheck++ > 300)
                            {
                                Debug.Assert(false);
                                return(false);
                            }

                            if (padjust.Prev.Next == padjust)
                            {
                                break;
                            }
                            AM_Edge pnewconn = padjust;
                            padjust.Prev = pstart.FindLastConnected();
                            pstart       = padjust.Prev;
                            padjust      = pstart.Next;
                            pstart.Next  = pnewconn;
                        }
                    }

                    if (pconnDx != null) // anello in senso orario
                    {
                        AM_Edge padjust = pconnDx;
                        AM_Edge pstart  = pconnDx.Next;

                        /*TRACE_EDGE(padjust);
                         * TRACE_EDGE(pstart);*/
                        int ncheck = 0; //contatore per evitare loop infinito

                        while (padjust != null)
                        {
                            if (ncheck++ > 300)
                            {
                                Debug.Assert(false);
                                return(false);
                            }

                            if (padjust.Next.Prev == padjust)
                            {
                                break;
                            }
                            AM_Edge pnewconn = padjust;
                            padjust.Next = pstart.FindLastConnected(false);
                            pstart       = padjust.Next;
                            padjust      = pstart.Prev;
                            pstart.Prev  = pnewconn;
                        }
                    }
                }
            }

            return(true);
        }
Exemplo n.º 30
0
        // --- Impostazioni ---
        internal Point2d InsertPoint(AM_Mesh2d pSpaceFunction)
        {
            AM_Edge pRif = null;

            for (int i = 0; i < 3; i++)
            {
                if (GetNearTriangle(i) == null)
                {
                    pRif = m_pEdges[i];
                    break;
                }

                if (GetNearTriangle(i).m_FaceType == EFaceType.FT_ACCEPTED)
                {
                    pRif = m_pEdges[i];
                }
            }

            if (pRif == null)
            {
                return(Vertex(0).Coord);
            }

            Point2d thirdPoint     = Point2d.Origin;
            Point2d midPoint       = 0.5 * (pRif.OrgCoord() + pRif.DestCoord());
            Point2d directionPoint = m_CircumCenter;

            for (int i = 0; i < 3; i++)
            {
                if (Vertex(i) != pRif.Origin() &&
                    Vertex(i) != pRif.Destination())
                {
                    thirdPoint = Vertex(i).Coord;
                    break;
                }
            }

            if (m_CircumCenter == midPoint) //triangolo rettangolo
            {
                directionPoint = thirdPoint;
            }

            double radius = TeoricRadius(midPoint, pSpaceFunction);
            double p      = (pRif.OrgCoord() - pRif.DestCoord()).Length / 2;
            double q      = (midPoint - m_CircumCenter).Length;

            if (radius < p)
            {
                radius = p;
            }
            if (q != 0)
            {
                double tmp = (p * p + q * q) / (2 * q);
                if (radius > tmp)
                {
                    radius = tmp;
                }
            }

            Vector2d versor;

            if (AM_Edge.LeftOf(directionPoint, pRif) && AM_Edge.RightOf(thirdPoint, pRif) ||
                AM_Edge.LeftOf(thirdPoint, pRif) && AM_Edge.RightOf(directionPoint, pRif))
            {
                versor = midPoint - directionPoint;
            }
            else
            {
                versor = directionPoint - midPoint;
            }
            versor.Unitize();

            double  d     = radius + Math.Sqrt(radius * radius - p * p);
            Point2d point = midPoint + d * versor;

            return(point);
        }