public void buildFromSegmentSoup(std_vector<Segment3D> segList, ref std_vector<Path> @out) { //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap; //Vec3MultiMap segs; std_multimap<Vector3,Vector3>segs=new std_multimap<Vector3,Vector3>(new Vector3Comparator()); // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it) foreach(var it in segList) { //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB)); //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA)); segs.insert(it.mA,it.mB); segs.insert(it.mB,it.mA); } while (!segs.empty()) { Vector3 headFirst = segs.get(0).first;//segs.begin()->first; Vector3 headSecond = segs.get(0).second[0];//segs.begin()->second; Path p=new Path(); p.addPoint(headFirst).addPoint(headSecond); //Vec3MultiMap::iterator firstSeg = segs.begin(); int firstSeg_pos=segs.begin(); Vector3 firstSeg=segs.get(0).first; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>> correspondants2 = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;) for(int i=correspondants2.first.second.Count-1;i>=0;i--) { // Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt=correspondants2.first.second[i]; //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8) if((removeIt-firstSeg).SquaredLength<1e-8) segs.erase(removeIt); } segs.erase(firstSeg); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //Vec3MultiMap::iterator next = segs.find(headSecond); int next_pos = segs.find(headSecond); //if (next != segs.end()) if(next_pos!=-1) { std_pair<Vector3,List<Vector3>>next=segs.get((uint)next_pos); foundSomething = true; headSecond = next.second[0]; p.addPoint(headSecond); //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0;i-- ) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - next->first).squaredLength() < 1e-8) if ((removeIt - next.first).SquaredLength < 1e-8) segs.erase(removeIt); } //segs.erase(next); segs.erase(next.first); } //Vec3MultiMap::iterator previous = segs.find(headFirst); int previous_pos=segs.find(headFirst); //if (previous != segs.end()) if(previous_pos!=-1) { std_pair<Vector3, List<Vector3>> previous = segs.get((uint)previous_pos); foundSomething = true; //p.insertPoint(0, previous.second); p.insertPoint(0, previous.second[0]);//??? headFirst = previous.second[0]; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headFirst); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for(int i=correspondants.first.second.Count-1;i>=0;i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt=correspondants.first.second[i]; //if ((removeIt->second - previous->first).squaredLength() < 1e-8) if((removeIt-previous.first).SquaredLength<1e-8) segs.erase(removeIt); } //segs.erase(previous); segs.erase(previous.first); } } if ((p.getPoint(0)-p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6) { p.getPointsReference().pop_back(); p.close(); } @out.push_back(p); } }
//----------------------------------------------------------------------- // //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; } } } }
public void buildFromSegmentSoup(std_vector <Segment3D> segList, ref std_vector <Path> @out) { //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap; //Vec3MultiMap segs; std_multimap <Vector3, Vector3> segs = new std_multimap <Vector3, Vector3>(new Vector3Comparator()); // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it) foreach (var it in segList) { //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB)); //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA)); segs.insert(it.mA, it.mB); segs.insert(it.mB, it.mA); } while (!segs.empty()) { Vector3 headFirst = segs.get(0).first; //segs.begin()->first; Vector3 headSecond = segs.get(0).second[0]; //segs.begin()->second; Path p = new Path(); p.addPoint(headFirst).addPoint(headSecond); //Vec3MultiMap::iterator firstSeg = segs.begin(); int firstSeg_pos = segs.begin(); Vector3 firstSeg = segs.get(0).first; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants2 = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;) for (int i = correspondants2.first.second.Count - 1; i >= 0; i--) { // Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants2.first.second[i]; //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8) if ((removeIt - firstSeg).SquaredLength < 1e-8) { segs.erase(removeIt); } } segs.erase(firstSeg); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //Vec3MultiMap::iterator next = segs.find(headSecond); int next_pos = segs.find(headSecond); //if (next != segs.end()) if (next_pos != -1) { std_pair <Vector3, List <Vector3> > next = segs.get((uint)next_pos); foundSomething = true; headSecond = next.second[0]; p.addPoint(headSecond); //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0; i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - next->first).squaredLength() < 1e-8) if ((removeIt - next.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(next); segs.erase(next.first); } //Vec3MultiMap::iterator previous = segs.find(headFirst); int previous_pos = segs.find(headFirst); //if (previous != segs.end()) if (previous_pos != -1) { std_pair <Vector3, List <Vector3> > previous = segs.get((uint)previous_pos); foundSomething = true; //p.insertPoint(0, previous.second); p.insertPoint(0, previous.second[0]);//??? headFirst = previous.second[0]; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headFirst); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0; i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - previous->first).squaredLength() < 1e-8) if ((removeIt - previous.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(previous); segs.erase(previous.first); } } if ((p.getPoint(0) - p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6) { p.getPointsReference().pop_back(); p.close(); } @out.push_back(p); } }
//----------------------------------------------------------------------- public void buildFromSegmentSoup(std_vector <Segment2D> segList) { //std.multimap<Vector2, Vector2, Vector2Comparator> segs = new std.multimap<Vector2, Vector2, Vector2Comparator>(); std_multimap <Vector2, Vector2> segs = new std_multimap <Vector2, Vector2>(); // for (List<Segment2D>.Enumerator it = segList.GetEnumerator(); it.MoveNext(); ++it) foreach (var it in segList) { //segs.insert(std.pair<Vector2, Vector2 > (it.mA, it.mB)); //segs.insert(std.pair<Vector2, Vector2 > (it.mB, it.mA)); segs.insert(it.mA, it.mB); segs.insert(it.mB, it.mA); } while (!segs.empty()) { Vector2 headFirst = segs.get(0).first; //segs.begin().first; Vector2 headSecond = segs.get(0).second[0]; //segs.begin().second; Shape s = new Shape(); s.addPoint(headFirst).addPoint(headSecond); //std_multimap<Vector2, Vector2, Vector2Comparator>.Enumerator firstSeg = segs.begin(); int firstSeg_pos = segs.begin(); std_pair <Vector2, List <Vector2> > firstSeg = segs.get(0); // std.pair<std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator, std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator> correspondants2 = segs.equal_range(headSecond); std_pair <std_pair <Vector2, List <Vector2> >, std_pair <Vector2, List <Vector2> > > correspondants2 = segs.equal_range(headSecond); //for (std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator it = correspondants2.first; it != correspondants2.second;) //{ // std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator removeIt = ++it; // if ((removeIt.second - firstSeg.first).squaredLength() < 1e-8) // segs.erase(removeIt); //} for (int i = 1; i < correspondants2.first.second.Count; i++) { Vector2 removeIt = correspondants2.first.second[i]; if ((removeIt - firstSeg.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } segs.erase(firstSeg.first); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator next = segs.find(headSecond); int next_pos = segs.find(headSecond); // if (next != segs.end()) if (next_pos != -1) { std_pair <Vector2, List <Vector2> > next = segs.get((uint)next_pos); foundSomething = true; //headSecond = next.second; headSecond = next.second[0]; s.addPoint(headSecond); //std.pair<std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator, std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator> correspondants = segs.equal_range(headSecond); std_pair <std_pair <Vector2, List <Vector2> >, std_pair <Vector2, List <Vector2> > > correspondants = segs.equal_range(headSecond); //for (std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator it = correspondants.first; it != correspondants.second;) //{ // std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator removeIt = ++it; // if ((removeIt.second - next.first).squaredLength() < 1e-8) // segs.erase(removeIt); //} for (int j = 1; j < correspondants.first.second.Count; j++) { Vector2 removeIt = correspondants2.first.second[j]; if ((removeIt - next.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(next); segs.erase(next.first); } //std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator previous = segs.find(headFirst); int previous_pos = segs.find(headFirst); //if (previous != segs.end()) { if (previous_pos != -1) { foundSomething = true; std_pair <Vector2, List <Vector2> > previous = segs.get((uint)previous_pos); // s.insertPoint(0, previous.second); s.insertPoint(0, previous.second[0]); //headFirst = previous.second; headFirst = previous.second[0]; //std.pair<std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator, std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator> correspondants = segs.equal_range(headFirst); std_pair <std_pair <Vector2, List <Vector2> >, std_pair <Vector2, List <Vector2> > > correspondants = segs.equal_range(headFirst); //for (std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator it = correspondants.first; it != correspondants.second; ) { for (int j = 1; j < correspondants.first.second.Count; j++) { //std.multimap<Vector2, Vector2, Vector2Comparator>.Enumerator removeIt = ++it; //if ((removeIt.second - previous.first).squaredLength() < 1e-8) // segs.erase(removeIt); Vector2 removeIt = correspondants.first.second[j]; if ((removeIt - previous.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(previous); segs.erase(previous.first); } } if ((s.getPoint(0) - s.getPoint(s.getSegCount() + 1)).SquaredLength < 1e-6) { s.getPointsReference().pop_back(); s.close(); } addShape(s); } }