Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }