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); } }
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); }