Exemplo n.º 1
0
        void _addConstraints(ref DelaunayTriangleBuffer tbuffer, PointList pl, std_vector <int> segmentListIndices)
        {
            std_vector <DelaunaySegment> segList = new std_vector <DelaunaySegment>();

            //Utils::log("a co");
            //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++)
            //	Utils::log(it->debugDescription());

            // First, list all the segments that are not already in one of the delaunay triangles
            //for (std::vector<int>::const_iterator it2 = segmentListIndices.begin(); it2 != segmentListIndices.end(); it2++)
            for (int i = 0; i < segmentListIndices.Count; i++)
            {
                //int i1 = *it2;
                int i1 = segmentListIndices[i];
                //it2++;
                i++;
                //int i2 = *it2;
                int i2 = segmentListIndices[i];

                bool isAlreadyIn = false;
                //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end(); ++it)
                foreach (var it in tbuffer)
                {
                    if (it.containsSegment(i1, i2))
                    {
                        isAlreadyIn = true;
                        break;
                    }
                }
                // only do something for segments not already in DT
                if (!isAlreadyIn)
                {
                    segList.push_back(new DelaunaySegment(i1, i2));
                }
            }

            // Re-Triangulate according to the new segments
            //for (std::vector<DelaunaySegment>::iterator itSeg=segList.begin(); itSeg!=segList.end(); itSeg++)
            for (int ii = segList.Count - 1; ii >= 0; ii--)
            {
                DelaunaySegment itSeg = segList[ii];
                //Utils::log("itseg " + StringConverter::toString(itSeg->i1) + "," + StringConverter::toString(itSeg->i2) + " " + StringConverter::toString(pl[itSeg->i1]) + "," + StringConverter::toString(pl[itSeg->i2]));
                // Remove all triangles intersecting the segment and keep a list of outside edges
                std_set <DelaunaySegment> segments = new std_set <DelaunaySegment>();
                Segment2D seg1 = new Segment2D(pl[itSeg.i1], pl[itSeg.i2]);
                //for (DelaunayTriangleBuffer::iterator itTri = tbuffer.begin(); itTri!=tbuffer.end(); )
                for (int jj = tbuffer.Count - 1; jj >= 0; jj--)
                {
                    Triangle itTri = tbuffer.getElement(jj).Value;
                    bool     isTriangleIntersected = false;
                    bool     isDegenerate          = false;
                    int      degenIndex;
                    for (int i = 0; i < 3; i++)
                    {
                        //Early out if 2 points are in fact the same
                        if (itTri.i[i] == itSeg.i1 || itTri.i[i] == itSeg.i2 || itTri.i[(i + 1) % 3] == itSeg.i1 || itTri.i[(i + 1) % 3] == itSeg.i2)
                        {
                            if (itTri.isDegenerate())
                            {
                                if (itTri.i[i] == itSeg.i1 || itTri.i[(i + 1) % 3] == itSeg.i1)
                                {
                                    degenIndex = itSeg.i1;
                                }
                                else if (itTri.i[i] == itSeg.i2 || itTri.i[(i + 1) % 3] == itSeg.i2)
                                {
                                    degenIndex = itSeg.i2;
                                }
                                isTriangleIntersected = true;
                                isDegenerate          = true;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        Segment2D seg2 = new Segment2D(itTri.p(i), itTri.p((i + 1) % 3));
                        if (seg1.intersects(seg2))
                        {
                            isTriangleIntersected = true;
                            break;
                        }
                    }
                    if (isTriangleIntersected)
                    {
                        //if (isDegenerate)
                        //Utils::log("degen " + itTri->debugDescription());
                        for (int k = 0; k < 3; k++)
                        {
                            DelaunaySegment d1 = new DelaunaySegment(itTri.i[k], itTri.i[(k + 1) % 3]);
                            if (segments.find(d1) != segments.end())
                            {
                                segments.erase(d1);
                            }
                            else if (segments.find(d1.inverse()) != segments.end())
                            {
                                segments.erase(d1.inverse());
                            }
                            else
                            {
                                segments.insert(d1);
                            }
                        }
                        //itTri=tbuffer.erase(itTri);
                        tbuffer.erase(jj);
                    }
                    //else
                    //	itTri++;
                }

                // Divide the list of points (coming from remaining segments) in 2 groups : "above" and "below"
                std_vector <int> pointsAbove = new std_vector <int>();
                std_vector <int> pointsBelow = new std_vector <int>();
                int  pt      = itSeg.i1;
                bool isAbove = true;
                while (segments.size() > 0)
                {
                    //find next point
                    //for (std::set<DelaunaySegment>::iterator it = segments.begin(); it!=segments.end(); ++it)
                    DelaunaySegment[] segments_all = segments.get_allocator();
                    for (int i = 0; i < segments_all.Length; ++i)
                    {
                        DelaunaySegment it = segments_all[i];//segments.find(i,true);
                        if (it.i1 == pt || it.i2 == pt)
                        {
                            //Utils::log("next " + StringConverter::toString(pt));

                            if (it.i1 == pt)
                            {
                                pt = it.i2;
                            }
                            else
                            {
                                pt = it.i1;
                            }
                            segments.erase(it);
                            if (pt == itSeg.i2)
                            {
                                isAbove = false;
                            }
                            else if (pt != itSeg.i1)
                            {
                                if (isAbove)
                                {
                                    pointsAbove.push_back(pt);
                                }
                                else
                                {
                                    pointsBelow.push_back(pt);
                                }
                            }
                            break;
                        }
                    }
                }

                // Recursively triangulate both polygons
                _recursiveTriangulatePolygon(itSeg, pointsAbove, tbuffer, pl);
                _recursiveTriangulatePolygon(itSeg.inverse(), pointsBelow, tbuffer, pl);
            }
            // Clean up segments outside of multishape
            if (mRemoveOutside)
            {
                if (mMultiShapeToTriangulate != null && mMultiShapeToTriangulate.isClosed())
                {
                    //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();)
                    for (int i = tbuffer.Count - 1; i >= 0; i--)
                    {
                        Triangle it            = tbuffer.getElement(i).Value;
                        bool     isTriangleOut = !mMultiShapeToTriangulate.isPointInside(it.getMidPoint());

                        if (isTriangleOut)
                        {
                            //it = tbuffer.erase(it);
                            tbuffer.erase(i);
                        }
                        //else
                        //	++it;
                    }
                }
                else if (mShapeToTriangulate != null && mShapeToTriangulate.isClosed())
                {
                    //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();)
                    for (int i = tbuffer.Count - 1; i >= 0; i--)
                    {
                        Triangle it            = tbuffer.getElement(i).Value;
                        bool     isTriangleOut = !mShapeToTriangulate.isPointInside(it.getMidPoint());

                        if (isTriangleOut)
                        {
                            //it = tbuffer.erase(it);
                            tbuffer.erase(i);
                        }
                        //else
                        //	++it;
                    }
                }
            }
        }
Exemplo n.º 2
0
        //-----------------------------------------------------------------------

        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            std_vector <TriangleBuffer.Vertex> vec1 = mMesh1.getVertices();
            std_vector <int> ind1 = mMesh1.getIndices();
            std_vector <TriangleBuffer.Vertex> vec2 = mMesh2.getVertices();
            std_vector <int> ind2 = mMesh2.getIndices();
            Segment3D        intersectionResult = new Segment3D();

            std_vector <Intersect> intersectionList = new std_vector <Intersect>();

            // Find all intersections between mMesh1 and mMesh2
            int idx1 = 0;

            //for (std::vector<int>::const_iterator it = ind1.begin(); it != ind1.end(); idx1++)
            for (int i = 0; i < ind1.Count; i += 3, idx1++)
            {
                int it = ind1[i];
                //Triangle3D t1(vec1[*it++].mPosition, vec1[*it++].mPosition, vec1[*it++].mPosition);
                Triangle3D t1   = new Triangle3D(vec1[it].mPosition, vec1[it + 1].mPosition, vec1[it + 2].mPosition);
                int        idx2 = 0;
                //for (std::vector<int>::const_iterator it2 = ind2.begin(); it2 != ind2.end(); idx2++)
                for (int j = 0; j < ind2.Count; j += 3, idx2++)
                {
                    int it2 = ind2[j];
                    //Triangle3D t2(vec2[*it2++].mPosition, vec2[*it2++].mPosition, vec2[*it2++].mPosition);
                    Triangle3D t2 = new Triangle3D(vec2[it2].mPosition, vec2[it2 + 1].mPosition, vec2[it2 + 2].mPosition);
                    if (t1.findIntersect(t2, ref intersectionResult))
                    {
                        Intersect intersect = new Intersect(intersectionResult, idx1, idx2);
                        intersectionList.push_back(intersect);
                    }
                }
            }
            // Remove all intersection segments too small to be relevant
            //for (std::vector<Intersect>::iterator it = intersectionList.begin(); it != intersectionList.end();)
            //    if ((it.mSeg.mB - it.mSeg.mA).squaredLength() < 1e-8)
            //        it = intersectionList.erase(it);
            //    else
            //        ++it;
            for (int i = intersectionList.Count - 1; i >= 0; i--)
            {
                Intersect it = intersectionList[i];
                if ((it.mSeg.mB - it.mSeg.mA).SquaredLength < 1e-8)
                {
                    intersectionList.erase((uint)i);
                }
            }


            // Retriangulate
            TriangleBuffer newMesh1 = new TriangleBuffer();
            TriangleBuffer newMesh2 = new TriangleBuffer();

            GlobalMembersProceduralBoolean._retriangulate(ref newMesh1, mMesh1, intersectionList, true);
            GlobalMembersProceduralBoolean._retriangulate(ref newMesh2, mMesh2, intersectionList, false);

            //buffer.append(newMesh1);
            //buffer.append(newMesh2);
            //return;

            // Trace contours
            std_vector <Path>      contours    = new std_vector <Path>();
            std_vector <Segment3D> segmentSoup = new std_vector <Segment3D>();

            //for (std::vector<Intersect>::iterator it = intersectionList.begin(); it != intersectionList.end(); ++it)
            foreach (var it in intersectionList)
            {
                segmentSoup.push_back(it.mSeg);
            }
            new Path().buildFromSegmentSoup(segmentSoup, ref contours);

            // Build a lookup from segment to triangle
            TriLookup triLookup1 = new std_multimap <Segment3D, int>(new Seg3Comparator()), triLookup2 = new std_multimap <Segment3D, int>(new Seg3Comparator());

            GlobalMembersProceduralBoolean._buildTriLookup(ref triLookup1, newMesh1);
            GlobalMembersProceduralBoolean._buildTriLookup(ref triLookup2, newMesh2);

            std_set <Segment3D> limits = new std_set <Segment3D>(new Seg3Comparator());

            //for (std::vector<Segment3D>::iterator it = segmentSoup.begin(); it != segmentSoup.end(); ++it)
            foreach (var it in segmentSoup)
            {
                limits.insert(it.orderedCopy());
            }
            // Build resulting mesh
            //for (std::vector<Path>::iterator it = contours.begin(); it != contours.end(); ++it)
            foreach (var it in contours)
            {
                // Find 2 seed triangles for each contour
                Segment3D firstSeg = new Segment3D(it.getPoint(0), it.getPoint(1));
                //std_pair<TriLookup::iterator, TriLookup::iterator> it2mesh1 = triLookup1.equal_range(firstSeg.orderedCopy());
                //std_pair<TriLookup::iterator, TriLookup::iterator> it2mesh2 = triLookup2.equal_range(firstSeg.orderedCopy());
                std_pair <std_pair <Segment3D, List <int> >, std_pair <Segment3D, List <int> > > it2mesh1 = triLookup1.equal_range(firstSeg.orderedCopy());
                std_pair <std_pair <Segment3D, List <int> >, std_pair <Segment3D, List <int> > > it2mesh2 = triLookup2.equal_range(firstSeg.orderedCopy());
                int mesh1seed1 = 0, mesh1seed2 = 0, mesh2seed1 = 0, mesh2seed2 = 0;

                //if (it2mesh1.first != triLookup1.end() && it2mesh2.first != triLookup2.end())
                if (it2mesh1.first != null && it2mesh2.first != null)
                {
                    // check which of seed1 and seed2 must be included (it can be 0, 1 or both)
                    //mesh1seed1 = it2mesh1.first.second;
                    //mesh1seed2 = (--it2mesh1.second).second;
                    //mesh2seed1 = it2mesh2.first.second;
                    //mesh2seed2 = (--it2mesh2.second).second;
                    mesh1seed1 = it2mesh1.first.second[0];
                    mesh1seed2 = it2mesh1.first.second[it2mesh1.first.second.Count - 1]; //(--it2mesh1.second).second[0];
                    mesh2seed1 = it2mesh2.first.second[0];
                    mesh2seed2 = it2mesh2.first.second[it2mesh2.first.second.Count - 1]; //(--it2mesh2.second).second[0];

                    if (mesh1seed1 == mesh1seed2)
                    {
                        mesh1seed2 = -1;
                    }
                    if (mesh2seed1 == mesh2seed2)
                    {
                        mesh2seed2 = -1;
                    }

                    Vector3 vMesh1 = new Vector3(0f, 0f, 0f), nMesh1 = new Vector3(0f, 0f, 0f), vMesh2 = new Vector3(0f, 0f, 0f), nMesh2 = new Vector3(0f, 0f, 0f);
                    for (int i = 0; i < 3; i++)
                    {
                        Vector3 pos = newMesh1.getVertices()[newMesh1.getIndices()[mesh1seed1 * 3 + i]].mPosition;
                        if ((pos - firstSeg.mA).SquaredLength > 1e-6 && (pos - firstSeg.mB).SquaredLength > 1e-6)
                        {
                            vMesh1 = pos;
                            nMesh1 = newMesh1.getVertices()[newMesh1.getIndices()[mesh1seed1 * 3 + i]].mNormal;
                            break;
                        }
                    }

                    for (int i = 0; i < 3; i++)
                    {
                        Vector3 pos = newMesh2.getVertices()[newMesh2.getIndices()[mesh2seed1 * 3 + i]].mPosition;
                        if ((pos - firstSeg.mA).SquaredLength > 1e-6 && (pos - firstSeg.mB).SquaredLength > 1e-6)
                        {
                            vMesh2 = pos;
                            nMesh2 = newMesh2.getVertices()[newMesh2.getIndices()[mesh2seed1 * 3 + i]].mNormal;
                            break;
                        }
                    }

                    bool M2S1InsideM1 = (nMesh1.DotProduct(vMesh2 - firstSeg.mA) < 0f);
                    bool M1S1InsideM2 = (nMesh2.DotProduct(vMesh1 - firstSeg.mA) < 0f);

                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh1seed1, ref triLookup1);
                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh2seed1, ref triLookup2);
                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh1seed2, ref triLookup1);
                    GlobalMembersProceduralBoolean._removeFromTriLookup(mesh2seed2, ref triLookup2);

                    // Recursively add all neighbours of these triangles
                    // Stop when a contour is touched
                    switch (mBooleanOperation)
                    {
                    case BooleanOperation.BT_UNION:
                        if (M1S1InsideM2)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false);
                        }
                        if (M2S1InsideM1)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, false);
                        }
                        break;

                    case BooleanOperation.BT_INTERSECTION:
                        if (M1S1InsideM2)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false);
                        }
                        if (M2S1InsideM1)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, false);
                        }
                        break;

                    case BooleanOperation.BT_DIFFERENCE:
                        if (M1S1InsideM2)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false);
                        }
                        if (M2S1InsideM1)
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, true);
                        }
                        else
                        {
                            GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, true);
                        }
                        break;
                    }
                }
            }
        }
Exemplo n.º 3
0
        //
        //ORIGINAL LINE: void delaunay(List<Ogre::Vector2>& pointList, LinkedList<Triangle>& tbuffer) const
        void delaunay(PointList pointList, ref DelaunayTriangleBuffer tbuffer)
        {
            // Compute super triangle or insert manual super triangle
            if (mManualSuperTriangle != null)
            {
                float maxTriangleSize = 0.0f;
                //for (PointList::iterator it = pointList.begin(); it!=pointList.end(); ++it)
                foreach (Vector2 it in pointList)
                {
                    maxTriangleSize = max(maxTriangleSize, Math.Abs(it.x));
                    maxTriangleSize = max(maxTriangleSize, Math.Abs(it.y));
                }
                pointList.push_back(new Vector2(-3f * maxTriangleSize, -3f * maxTriangleSize));
                pointList.push_back(new Vector2(3f * maxTriangleSize, -3f * maxTriangleSize));
                pointList.push_back(new Vector2(0.0f, 3 * maxTriangleSize));

                int      maxTriangleIndex = pointList.size() - 3;
                Triangle superTriangle    = new Triangle(pointList);
                superTriangle.i[0] = maxTriangleIndex;
                superTriangle.i[1] = maxTriangleIndex + 1;
                superTriangle.i[2] = maxTriangleIndex + 2;
                tbuffer.push_back(superTriangle);
            }

            // Point insertion loop
            for (int i = 0; i < pointList.size() - 3; i++)
            {
                //Utils::log("insert point " + StringConverter::toString(i));
                //std::list<std::list<Triangle>::iterator> borderlineTriangles;
                std_list <Triangle> borderlineTriangles = new std_list <Triangle>();
                // Insert 1 point, find all triangles for which the point is in circumcircle
                Vector2 p = pointList[i];
                //std::set<DelaunaySegment> segments;
                std_set <DelaunaySegment> segments = new std_set <DelaunaySegment>();
                IEnumerator <Triangle>    et       = tbuffer.GetEnumerator();
                //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();)
                List <Triangle> need_erase = new List <Triangle>();
                while (et.MoveNext())
                {
                    Triangle            it       = et.Current;
                    Triangle.InsideType isInside = it.isPointInsideCircumcircle(p);
                    if (isInside == Triangle.InsideType.IT_INSIDE)
                    {
                        if (!it.isDegenerate())
                        {
                            //Utils::log("tri insie" + it->debugDescription());
                            for (int k = 0; k < 3; k++)
                            {
                                DelaunaySegment d1 = new DelaunaySegment(it.i[k], it.i[(k + 1) % 3]);
                                if (segments.find(d1) != segments.end())
                                {
                                    segments.erase(d1);
                                }
                                else if (segments.find(d1.inverse()) != segments.end())
                                {
                                    segments.erase(d1.inverse());
                                }
                                else
                                {
                                    segments.insert(d1);
                                }
                            }
                        }
                        //it=tbuffer.erase(it);
                        need_erase.Add(it);
                    }
                    else if (isInside == Triangle.InsideType.IT_BORDERLINEOUTSIDE)
                    {
                        //Utils::log("tri borer " + it->debugDescription());
                        borderlineTriangles.push_back(it);
                        //++it;
                    }
                    else
                    {
                        //++it;
                    }
                }
                //do delete
                foreach (var v in need_erase)
                {
                    tbuffer.Remove(v);
                }

                // Robustification of the standard algorithm : if one triangle's circumcircle was borderline against the new point,
                // test whether that triangle is intersected by new segments or not (normal situation : it should not)
                // If intersected, the triangle is considered having the new point in its circumc
                std_set <DelaunaySegment> copySegment = segments;
                IEnumerator <Triangle>    be          = borderlineTriangles.GetEnumerator();
                //for (std::list<std::list<Triangle>::iterator>::iterator itpTri = borderlineTriangles.begin(); itpTri!=borderlineTriangles.end(); itpTri++ )
                while (be.MoveNext())
                {
                    Triangle itpTri = be.Current;
                    //DelaunayTriangleBuffer::iterator itTri = *itpTri;
                    Triangle itTri      = itpTri;
                    bool     triRemoved = false;
                    //for (std::set<DelaunaySegment>::iterator it = copySegment.begin(); it!=copySegment.end() && !triRemoved; ++it)
                    IEnumerator <DelaunaySegment> cse = copySegment.GetEnumerator();
                    while (cse.MoveNext() && !triRemoved)
                    {
                        DelaunaySegment it = cse.Current;
                        bool            isTriangleIntersected = false;
                        for (int k = 0; k < 2; k++)
                        {
                            int i1 = (k == 0) ? it.i1 : it.i2;
                            int i2 = i;
                            for (int l = 0; l < 3; l++)
                            {
                                //Early out if 2 points are in fact the same
                                if (itTri.i[l] == i1 || itTri.i[l] == i2 || itTri.i[(l + 1) % 3] == i1 || itTri.i[(l + 1) % 3] == i2)
                                {
                                    continue;
                                }
                                Segment2D seg2 = new Segment2D(itTri.p(l), itTri.p((l + 1) % 3));
                                Segment2D seg1 = new Segment2D(pointList[i1], pointList[i2]);
                                if (seg1.intersects(seg2))
                                {
                                    isTriangleIntersected = true;
                                    break;
                                }
                            }
                        }
                        if (isTriangleIntersected)
                        {
                            if (!itTri.isDegenerate())
                            {
                                //Utils::log("tri inside" + itTri->debugDescription());
                                for (int m = 0; m < 3; m++)
                                {
                                    DelaunaySegment d1 = new DelaunaySegment(itTri.i[m], itTri.i[(m + 1) % 3]);
                                    if (segments.find(d1) != segments.end())
                                    {
                                        segments.erase(d1);
                                    }
                                    else if (segments.find(d1.inverse()) != segments.end())
                                    {
                                        segments.erase(d1.inverse());
                                    }
                                    else
                                    {
                                        segments.insert(d1);
                                    }
                                }
                            }
                            //tbuffer.erase(itTri);
                            need_erase.Clear();
                            need_erase.Add(itTri);
                            triRemoved = true;
                        }
                    }
                }
                //do delete
                foreach (var v in need_erase)
                {
                    tbuffer.Remove(v);
                }
                // Find all the non-interior edges
                IEnumerator <DelaunaySegment> seg_ie = segments.GetEnumerator();
                //for (std::set<DelaunaySegment>::iterator it = segments.begin(); it!=segments.end(); ++it)
                while (seg_ie.MoveNext())
                {
                    DelaunaySegment it = seg_ie.Current;
                    //Triangle dt(&pointList);
                    Triangle dt = new Triangle(pointList);
                    dt.setVertices(it.i1, it.i2, i);
                    dt.makeDirectIfNeeded();
                    //Utils::log("Add tri " + dt.debugDescription());
                    tbuffer.push_back(dt);
                }
            }

            // NB : Don't remove super triangle here, because all outer triangles are already removed in the addconstraints method.
            //      Uncomment that code if delaunay triangulation ever has to be unconstrained...

            /*TouchSuperTriangle touchSuperTriangle(maxTriangleIndex, maxTriangleIndex+1,maxTriangleIndex+2);
             * tbuffer.remove_if(touchSuperTriangle);
             * pointList.pop_back();
             * pointList.pop_back();
             * pointList.pop_back();*/
        }
Exemplo n.º 4
0
        //-----------------------------------------------------------------------

        public static void _recursiveAddNeighbour(ref TriangleBuffer result, TriangleBuffer source, int triNumber, ref TriLookup lookup, std_set <Segment3D> limits, bool inverted)
        {
            if (triNumber == -1)
            {
                return;
            }
            Utils.log("tri " + (triNumber.ToString()));
            std_vector <int> ind = source.getIndices();
            std_vector <TriangleBuffer.Vertex> vec = source.getVertices();

            result.rebaseOffset();
            if (inverted)
            {
                result.triangle(0, 2, 1);
                TriangleBuffer.Vertex v = vec[ind[triNumber * 3]];
                v.mNormal = -v.mNormal;
                result.vertex(v);
                v         = vec[ind[triNumber * 3 + 1]];
                v.mNormal = -v.mNormal;
                result.vertex(v);
                v         = vec[ind[triNumber * 3 + 2]];
                v.mNormal = -v.mNormal;
                result.vertex(v);
            }
            else
            {
                result.triangle(0, 1, 2);
                result.vertex(vec[ind[triNumber * 3]]);
                result.vertex(vec[ind[triNumber * 3 + 1]]);
                result.vertex(vec[ind[triNumber * 3 + 2]]);
            }

            //Utils::log("vertex " + StringConverter::toString(vec[ind[triNumber*3]].mPosition));
            //Utils::log("vertex " + StringConverter::toString(vec[ind[triNumber*3+1]].mPosition));
            //Utils::log("vertex " + StringConverter::toString(vec[ind[triNumber*3+2]].mPosition));

            std_pair <Segment3D, List <int> > it = null;

            int nextTriangle1 = -1;
            int nextTriangle2 = -1;
            int nextTriangle3 = -1;
            int it_find       = lookup.find(new Segment3D(vec[ind[triNumber * 3]].mPosition, vec[ind[triNumber * 3 + 1]].mPosition).orderedCopy());

            ////if (it != lookup.end() && limits.find(it->first.orderedCopy()) != limits.end())
            ////	Utils::log("Cross limit1");
            //if (it != lookup.end() && limits.find(it->first.orderedCopy()) == limits.end()) {
            //    nextTriangle1 = it->second;
            //    _removeFromTriLookup(nextTriangle1, lookup);
            //}
            if (it_find != -1)
            {
                it = lookup.get((uint)it_find);
                if (limits.find(it.first.orderedCopy()) == -1)
                {
                    nextTriangle1 = it.second[0];
                    GlobalMembersProceduralBoolean._removeFromTriLookup(nextTriangle1, ref lookup);
                }
            }
            //	it = lookup.find(Segment3D(vec[ind[triNumber * 3 + 1]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());
            it_find = lookup.find(new Segment3D(vec[ind[triNumber * 3 + 1]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());

            ////if (it != lookup.end() && limits.find(it->first.orderedCopy()) != limits.end())
            ////Utils::log("Cross limit2");
            //if (it != lookup.end() && limits.find(it->first.orderedCopy()) == limits.end()) {
            //    nextTriangle2 = it->second;
            //    _removeFromTriLookup(nextTriangle2, lookup);
            //}
            if (it_find != -1)
            {
                it = lookup.get((uint)it_find);
                if (limits.find(it.first.orderedCopy()) == -1)
                {
                    nextTriangle2 = it.second[0];
                    GlobalMembersProceduralBoolean._removeFromTriLookup(nextTriangle2, ref lookup);
                }
            }
            //it = lookup.find(Segment3D(vec[ind[triNumber * 3]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());
            ////if (it != lookup.end() && limits.find(it->first.orderedCopy()) != limits.end())
            ////	Utils::log("Cross limit3");
            //if (it != lookup.end() && limits.find(it->first.orderedCopy()) == limits.end()) {
            //    nextTriangle3 = it->second;
            //    _removeFromTriLookup(nextTriangle3, lookup);
            //}
            it_find = lookup.find(new Segment3D(vec[ind[triNumber * 3]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());
            if (it_find != -1)
            {
                it = lookup.get((uint)it_find);
                if (limits.find(it.first.orderedCopy()) == -1)
                {
                    nextTriangle3 = it.second[0];
                    GlobalMembersProceduralBoolean._removeFromTriLookup(nextTriangle3, ref lookup);
                }
            }

            //Utils::log("add " + StringConverter::toString(nextTriangle1) + " ," + StringConverter::toString(nextTriangle2) + " ,"+StringConverter::toString(nextTriangle3) );

            _recursiveAddNeighbour(ref result, source, nextTriangle1, ref lookup, limits, inverted);
            _recursiveAddNeighbour(ref result, source, nextTriangle2, ref lookup, limits, inverted);
            _recursiveAddNeighbour(ref result, source, nextTriangle3, ref lookup, limits, inverted);
        }