bool RecoverBoundary() { { int numBoundary = m_ArrayMeshBoundary.Count; List <Point3d> AddArray = new List <Point3d>(); bool bflag = true; while (bflag) { bflag = false; for (int i = 0; i < numBoundary; i++) { AM_Boundary pBoundary = m_ArrayMeshBoundary[i]; if (!pBoundary.FlagHole && i == numBoundary - 1) { break; } for (int j = 0; j < pBoundary.GetNumGenVertex(); j++) { bflag |= pBoundary.RecoverGenEdge(m_Mesh2D, j, AddArray); } } } } return(true); }
bool BuildMeshBoundary(ref BoundingBox maxRect) { maxRect = BoundingBox.Empty; for (int i = 0; i < m_Loops.Count; i++) { var pLoop = m_Loops[i]; AM_Boundary boundary = new AM_Boundary(); m_ArrayMeshBoundary.Add(boundary); boundary.SetLoopIndex(i); boundary.FlagHole = m_Loops[i].IsClosed; for (int j = 0; j < pLoop.NumSegments; j++) { var pVertex = pLoop.GetVertex(j); boundary.AddPoint(pVertex.Location, pVertex.Space, true); maxRect.Union(AM_Util.To3d(pVertex.Location)); var arrayPoints = pLoop.GetGeneratedPoints(j); for (int k = 0; k < arrayPoints.Count; k++) { // Nota: questa riga serve per gestire l'orientamento // TODO: valuatare se necessaria //int n = (pEdge.m_Index & 0x01) ? (arrayPoint.size() - k - 1) : k; int n = k; var meshPt = arrayPoints[k]; boundary.AddPoint(new Point2d(meshPt.X, meshPt.Y), meshPt.Z); maxRect.Union(new Point3d(meshPt.X, meshPt.Y, 0)); } } } return(true); }
// --- 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); }
internal bool SetBoundary(AM_Boundary boundary) { AM_Edge edge; int numVertex = boundary.GetNumVertex(); // Viene marcato il flag di contorno for (int i = 0; i < boundary.GetNumVertex(); i++) { edge = boundary.Vertex(i).Edge; Point2d nextCoord = new Point2d(boundary[(i + 1) % numVertex]); // si trova lo spigolo del contorno while (!edge.DestCoord().EpsilonEquals(nextCoord, AM_Util.FLT_EPSILON)) { edge = edge.Next; } edge.Flag |= 0x02; edge.Symm().Flag |= 0x02; } // Trova lo spigolo iniziale AM_Edge pprevEdge = boundary.Vertex(numVertex - 1).Edge; while (!pprevEdge.DestCoord().EpsilonEquals(new Point2d(boundary[0]), 1e-8)) { pprevEdge = pprevEdge.Next; } pprevEdge = pprevEdge.Symm(); // viene usato come sentinella // controllo su tutti gli spigoli del contorno for (int i = 1; i <= boundary.GetNumVertex(); i++) { edge = boundary.Vertex(i - 1).Edge; Point2d nextCoord = new Point2d(boundary[i % numVertex]); // si trova lo spigolo del contorno while (edge.DestCoord() != nextCoord) { edge = edge.Next; } if (edge.CwFace() != null) { // se c'è una faccia a dx dello spigolo // ci sono spigoli da eliminare AM_Edge plookEdge = edge.Prev; while (plookEdge != pprevEdge) { AM_Edge pdeleteEdge = plookEdge; plookEdge = plookEdge.Prev; if ((pdeleteEdge.Flag & 0x02) == 0) { // Non è uno spigolo di bordo DeleteEdge(pdeleteEdge); } } } pprevEdge = edge.Symm(); } return(true); }
bool RecoverBoundary(AM_Boundary boundary) { // se viene inserito un punto per aggiustare la conformità // il flag baddFlag diventa true bool baddFlag = false; AM_Edge pbase = null; AM_Edge pprev = pbase = boundary.Vertex(0).Edge; for (int i = 1; (boundary.FlagHole ? i <= boundary.GetNumVertex() : i < boundary.GetNumVertex()); i++) { // si controlla che tutti i vertici siano in sequenza while (true) { Point3d p1 = boundary[i - 1]; Point3d p2 = boundary[i % (boundary.GetNumVertex())]; if (pbase.DestCoord() == new Point2d(p2)) { // 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 baddFlag = true; // si segnala l'aggiunta di un vertice Point3d mid = 0.5 * (p1 + p2); // si inserisce un vertice nel mezzo dello spigolo AM_Vertex pvertex = null; InsertPoint(new Point2d(mid), mid.Z, out pvertex); if (pvertex == null) { Debug.Assert(false); //throw 6; } boundary.InsertVertex(i, pvertex); // si ricomincia il controllo pbase = boundary.Vertex(i - 1).Edge; pprev = pbase; } } } pbase = boundary.Vertex(i % (boundary.GetNumVertex())).Edge; pprev = pbase; } return(baddFlag); }