Octree::Octree( StdList<BaseTriangle*>& tris, int triPerNode ) { for(StdList<BaseTriangle*>::const_iterator f = tris.begin(); f != tris.end(); f++) { this->triangleData.push_back(*f); } init(triPerNode); }
void Stitcher::fillSmallHole(Mesh * M, int borderVertex) { int fIndex = M->numberOfFaces(); StdList<int> boundry = M->getBoundry(borderVertex, true); StdList<int>::iterator i = boundry.begin(); StdList<int>::iterator j = i; j++; StdList<int>::reverse_iterator k = boundry.rbegin(); StdList<int>::reverse_iterator l = k; l++; double len1, len2; while(*i != *k){ bool advanceA = false; len1 = (M->vec(*i) - M->vec(*j)).norm() + (M->vec(*k) - M->vec(*j)).norm(); len2 = (M->vec(*i) - M->vec(*l)).norm() + (M->vec(*k) - M->vec(*l)).norm(); if(len1 < len2) advanceA = true; double minAngleA = Vertex::minAngle(M->vec(*i), M->vec(*j), M->vec(*k)); double minAngleB = Vertex::minAngle(M->vec(*i), M->vec(*l), M->vec(*k)); if(advanceA) { if(minAngleA < theta && minAngleB > minAngleA) advanceA = false; } else { if(minAngleB < theta && minAngleA > minAngleB) advanceA = true; } // Avoid almost and self-intersects if(advanceA){ Plane p(M->vec(*i), M->vec(*j), M->vec(*k)); if(p.IsInTri(M->vec(*l), M->vec(*i), M->vec(*j), M->vec(*k))) advanceA = false; }else { Plane p(M->vec(*i), M->vec(*l), M->vec(*k)); if(p.IsInTri(M->vec(*j), M->vec(*i), M->vec(*l), M->vec(*k))) advanceA = true; } if(advanceA){ M->addFace(*j, *k, *i, fIndex++, true); i++; j++; } else { M->addFace(*l, *k, *i, fIndex++, true); k++; l++; } addedFaces.push_back(&(M->facesList()->back())); if (j == boundry.end() || l == boundry.rend() || *i == *l || *k == *j || *j == *l) break; } // Last triangle: Vector<int> lastTri = LIST_TO_VECTOR(M->getBoundry(*i, true)); if(lastTri.size() > 2) M->addFace(lastTri[0], lastTri[1], lastTri[2], fIndex++, true); }