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; } } } }
//----------------------------------------------------------------------- // //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; } } } }
// //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();*/ }
//----------------------------------------------------------------------- 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); }