Ejemplo n.º 1
0
        internal bool InsertIntoMesh(AM_Mesh2d pmesh)
        {
            AM_Vertex pvertex = null;

            for (int i = 0; i < m_ArrayCoord.Count; i++)
            {
                Point3d pt = m_ArrayCoord[i];
                if (pmesh.InsertPoint(new Point2d(pt), pt.Z, out pvertex))
                {
                    pvertex.Flag = 0x01;
                    m_ArrayVertex.Add(pvertex);
                }
                else
                {
                    /*
                     * Debug.Assert(false);
                     * throw 2;
                     */
                    pvertex.Flag = 0x01;
                    m_ArrayVertex.Add(pvertex);

                    // Il vertice esiste già: viene eliminato dalla sequenza
                    //m_ArrayCoord.RemoveAt(i);
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
        internal double SpaceFunction(Point2d p, AM_Mesh2d pSpaceFunction)
        {
            if (pSpaceFunction != null)
            {
                double z = 0;
                if (pSpaceFunction.GetCoordZ(p, ref z))
                {
                    return(z);
                }
            }

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

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

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

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

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

            return(f);
        }
Ejemplo n.º 3
0
        bool RefineMesh(bool bRefine, AM_Mesh2d pSpcFtSurface)
        {
            {
                m_Mesh2D.FirstClassific();

                bool bUseSpace = true;

                if (bRefine)
                {
                    if (pSpcFtSurface == null || !bUseSpace)
                    {
                        m_Mesh2D.RefineMesh();
                    }
                    else
                    {
                        m_Mesh2D.RefineMesh(pSpcFtSurface);
                    }
                }

                //pMesh2D.RelaxMesh();
                m_Mesh2D.SmoothMesh();
                m_Mesh2D.CheckWEdge();

                m_Mesh2D.ResetZ();
            }

            return(true);
        }
Ejemplo n.º 4
0
        internal bool RefineMesh(AM_Mesh2d pSpcFtSurface = null)
        {
            m_pSpaceFunction = pSpcFtSurface;
            while (m_ArrayActFace.Count != 0)
            {
                RefineMeshStep();
            }

            return(true);
        }
Ejemplo n.º 5
0
        internal bool InsertVertex(AM_Mesh2d mesh, Point3d pt, int numGenVertex = 0)
        {
            while (numGenVertex < m_GenVertexArray.Count)
            {
                int v1 = m_GenVertexArray[numGenVertex];
                int v2 = m_GenVertexArray[(numGenVertex + 1) % m_GenVertexArray.Count];

                if (v2 < v1)
                {
                    v2 += m_GenVertexArray.Count;
                }

                Point2d p  = new Point2d(pt);
                Point2d p1 = new Point2d(m_ArrayCoord[v1]);
                Point2d p2 = new Point2d(m_ArrayCoord[v2]);

                Vector2d vec1 = (p2 - p1);
                Vector2d vec2 = (p - p1);

                vec1.Unitize();
                vec2.Unitize();

                if (AM_Util.IsEqual(vec2.Length, 0))
                {
                    double t = (p - p1).Length;
                    for (int i = v1 + 1; i <= v2; i++)
                    {
                        Point2d pv = new Point2d(m_ArrayCoord[i % m_ArrayCoord.Count]);
                        if ((pv - p1).Length > t)
                        {
                            AM_Vertex pVertex = null;
                            if (mesh.InsertPoint(p, pt.Z, out pVertex))
                            {
                                InsertVertex(i, pVertex);
                                return(true);
                            }
                            else
                            {
                                return(false);
                            }
                        }
                    }
                }

                numGenVertex++;
            }

            return(false);
        }
Ejemplo n.º 6
0
        internal bool SpacingTest(Point2d p, AM_Mesh2d pSpaceFunction)
        {
            double f    = SpaceFunction(p, pSpaceFunction);
            double dist = 0;

            for (int i = 0; i < 3; i++)
            {
                Vector2d v = Vertex(i).Coord - p;
                dist = v.Length;
                if (dist < (AM_Mesh2d.SpaceCoef * f))
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 7
0
        internal void SetTriangleParameter(AM_Mesh2d pSpaceFunction)
        {
            ComputeCircumCircle();

            Point2d GravityCenter = 1 / 3d * (Vertex(0).Coord
                                              + Vertex(1).Coord
                                              + Vertex(2).Coord);
            double r = TeoricRadius(GravityCenter, pSpaceFunction);

            if ((r / m_CircumRadius) > AM_Mesh2d.Delta)
            {
                m_FaceType = EFaceType.FT_ACCEPTED;
            }
            else
            {
                m_FaceType = EFaceType.FT_NONE;
            }
        }
Ejemplo n.º 8
0
        bool BuildBoundary()
        {
            m_Mesh2D = new AM_Mesh2d();

            BoundingBox maxRect = new BoundingBox();

            if (!BuildMeshBoundary(ref maxRect))
            {
                return(false);
            }

            // Inserisce i contorni
            m_Mesh2D.Init(maxRect);

            int numBoundary = m_ArrayMeshBoundary.Count;

            for (int i = 0; i < numBoundary; i++)
            {
                m_ArrayMeshBoundary[i].InsertIntoMesh(m_Mesh2D);
            }

            //// Inserisce i vertici isolati
            for (int i = 0; i < m_ArrayInnerVertex.Count; i++)
            {
                var       vertex  = m_ArrayInnerVertex[i];
                AM_Vertex pvertex = null;

                Point2d pt = vertex.Location;

                if (m_Mesh2D.InsertPoint(new Point2d(pt), vertex.Space, out pvertex))
                {
                    pvertex.Flag      = 0x01;
                    vertex.MeshVertex = pvertex;
                }
            }

            return(true);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
        // --- Test ---
        internal double TeoricRadius(Point2d p, AM_Mesh2d pSpaceFunction)
        {
            double f = SpaceFunction(p, pSpaceFunction);

            return(AM_Mesh2d.RadCoef * f);
        }