bool ConvexHull3<Real>::Update (int i) { // Locate a triangle visible to the input point (if possible). Triangle* visible = 0; Triangle* tri; typename std::set<Triangle*>::iterator iter = mHull.begin(); typename std::set<Triangle*>::iterator end = mHull.end(); for (/**/; iter != end; ++iter) { tri = *iter; if (tri->GetSign(i, mQuery) > 0) { visible = tri; break; } } if (!visible) { // The point is inside the current hull; nothing to do. return true; } // Locate and remove the visible triangles. std::stack<Triangle*> visibleSet; std::map<int,TerminatorData> terminator; visibleSet.push(visible); visible->OnStack = true; int j, v0, v1; while (!visibleSet.empty()) { tri = visibleSet.top(); visibleSet.pop(); tri->OnStack = false; for (j = 0; j < 3; ++j) { Triangle* adj = tri->Adj[j]; if (adj) { // Detach triangle and adjacent triangle from each other. int nullIndex = tri->DetachFrom(j, adj); if (adj->GetSign(i, mQuery) > 0) { if (!adj->OnStack) { // Adjacent triangle is visible. visibleSet.push(adj); adj->OnStack = true; } } else { // Adjacent triangle is invisible. v0 = tri->V[j]; v1 = tri->V[(j+1)%3]; terminator[v0] = TerminatorData(v0, v1, nullIndex, adj); } } } mHull.erase(tri); delete0(tri); } // Insert the new edges formed by the input point and the terminator // between visible and invisible triangles. int size = (int)terminator.size(); assertion(size >= 3, "Terminator must be at least a triangle\n"); typename std::map<int,TerminatorData>::iterator edge = terminator.begin(); v0 = edge->second.V[0]; v1 = edge->second.V[1]; tri = new0 Triangle(i, v0, v1); mHull.insert(tri); // Save information for linking first/last inserted new triangles. int saveV0 = edge->second.V[0]; Triangle* saveTri = tri; // Establish adjacency links across terminator edge. tri->Adj[1] = edge->second.T; edge->second.T->Adj[edge->second.NullIndex] = tri; for (j = 1; j < size; ++j) { edge = terminator.find(v1); assertion(edge != terminator.end(), "Unexpected condition\n"); v0 = v1; v1 = edge->second.V[1]; Triangle* next = new0 Triangle(i, v0, v1); mHull.insert(next); // Establish adjacency links across terminator edge. next->Adj[1] = edge->second.T; edge->second.T->Adj[edge->second.NullIndex] = next; // Establish adjacency links with previously inserted triangle. next->Adj[0] = tri; tri->Adj[2] = next; tri = next; } assertion(v1 == saveV0, "Expecting initial vertex\n"); WM5_UNUSED(saveV0); // Establish adjacency links between first/last triangles. saveTri->Adj[0] = tri; tri->Adj[2] = saveTri; return true; }
bool ConvexHull3<Real>::Update (int i) { // Locate a triangle visible to the input point (if possible). Triangle* pkVisible = 0; Triangle* pkTri; typename std::set<Triangle*>::iterator pkIter; for (pkIter = m_kHull.begin(); pkIter != m_kHull.end(); pkIter++) { pkTri = *pkIter; if (pkTri->GetSign(i,m_pkQuery) > 0) { pkVisible = pkTri; break; } } if (!pkVisible) { // The point is inside the current hull; nothing to do. return true; } // Locate and remove the visible triangles. std::stack<Triangle*> kVisible; std::map<int,TerminatorData> kTerminator; kVisible.push(pkVisible); pkVisible->OnStack = true; int j, iV0, iV1; while (!kVisible.empty()) { pkTri = kVisible.top(); kVisible.pop(); pkTri->OnStack = false; for (j = 0; j < 3; j++) { Triangle* pkAdj = pkTri->A[j]; if (pkAdj) { // Detach triangle and adjacent triangle from each other. int iNullIndex = pkTri->DetachFrom(j,pkAdj); if (pkAdj->GetSign(i,m_pkQuery) > 0) { if (!pkAdj->OnStack) { // Adjacent triangle is visible. kVisible.push(pkAdj); pkAdj->OnStack = true; } } else { // Adjacent triangle is invisible. iV0 = pkTri->V[j]; iV1 = pkTri->V[(j+1)%3]; kTerminator[iV0] = TerminatorData(iV0,iV1,iNullIndex, pkAdj); } } } m_kHull.erase(pkTri); WM4_DELETE pkTri; } // Insert the new edges formed by the input point and the terminator // between visible and invisible triangles. int iSize = (int)kTerminator.size(); assert(iSize >= 3); typename std::map<int,TerminatorData>::iterator pkEdge = kTerminator.begin(); iV0 = pkEdge->second.V[0]; iV1 = pkEdge->second.V[1]; pkTri = WM4_NEW Triangle(i,iV0,iV1); m_kHull.insert(pkTri); // save information for linking first/last inserted new triangles int iSaveV0 = pkEdge->second.V[0]; Triangle* pkSaveTri = pkTri; // establish adjacency links across terminator edge pkTri->A[1] = pkEdge->second.Tri; pkEdge->second.Tri->A[pkEdge->second.NullIndex] = pkTri; for (j = 1; j < iSize; j++) { pkEdge = kTerminator.find(iV1); assert(pkEdge != kTerminator.end()); iV0 = iV1; iV1 = pkEdge->second.V[1]; Triangle* pkNext = WM4_NEW Triangle(i,iV0,iV1); m_kHull.insert(pkNext); // establish adjacency links across terminator edge pkNext->A[1] = pkEdge->second.Tri; pkEdge->second.Tri->A[pkEdge->second.NullIndex] = pkNext; // establish adjacency links with previously inserted triangle pkNext->A[0] = pkTri; pkTri->A[2] = pkNext; pkTri = pkNext; } assert(iV1 == iSaveV0); (void)iSaveV0; // avoid warning in Release build // establish adjacency links between first/last triangles pkSaveTri->A[0] = pkTri; pkTri->A[2] = pkSaveTri; return true; }
bool ConvexHull3::Update (int i) { // Locate a TriFace visible to the input point (if possible). TriFace* visible = 0; TriFace* tri; std::set<TriFace*>::iterator iter = mHull.begin(); std::set<TriFace*>::iterator end = mHull.end(); for (/**/; iter != end; ++iter) { tri = *iter; if (tri->GetSign(i, mPnts, epsilon) > 0) { visible = tri; break; } } if (!visible) { // The point is inside the current hull; nothing to do. return true; } // Locate and remove the visible TriFaces. std::stack<TriFace*> visibleSet; std::map<int,TerminatorData> terminator; visibleSet.push(visible); visible->OnStack = true; int j, v0, v1; while (!visibleSet.empty()) { tri = visibleSet.top(); visibleSet.pop(); tri->OnStack = false; for (j = 0; j < 3; ++j) { TriFace* adj = tri->Adj[j]; if (adj) { // Detach TriFace and adjacent TriFace from each other. int nullIndex = tri->DetachFrom(j, adj); if(tri->Time != -1) { mPnts.clear(); return true; } if (adj->GetSign(i, mPnts, epsilon) > 0) { if (!adj->OnStack) { // Adjacent TriFace is visible. visibleSet.push(adj); adj->OnStack = true; } } else { // Adjacent TriFace is invisible. v0 = tri->V[j]; v1 = tri->V[(j+1)%3]; terminator[v0] = TerminatorData(v0, v1, nullIndex, adj); } } } mHull.erase(tri); delete tri; tri = NULL; } // Insert the new edges formed by the input point and the terminator // between visible and invisible TriFaces. int size = (int)terminator.size(); std::map<int,TerminatorData>::iterator edge = terminator.begin(); if(edge == terminator.end()) { mPnts.clear(); return true; } v0 = edge->second.V[0]; v1 = edge->second.V[1]; tri = new TriFace(i, v0, v1); mHull.insert(tri); // Save information for linking first/last inserted new TriFaces. int saveV0 = edge->second.V[0]; TriFace* saveTri = tri; // Establish adjacency links across terminator edge. tri->Adj[1] = edge->second.T; edge->second.T->Adj[edge->second.NullIndex] = tri; for (j = 1; j < size; ++j) { edge = terminator.find(v1); if(edge == terminator.end()) { mPnts.clear(); return true; } v0 = v1; v1 = edge->second.V[1]; TriFace* next = new TriFace(i, v0, v1); mHull.insert(next); // Establish adjacency links across terminator edge. next->Adj[1] = edge->second.T; edge->second.T->Adj[edge->second.NullIndex] = next; // Establish adjacency links with previously inserted TriFace. next->Adj[0] = tri; tri->Adj[2] = next; tri = next; } // Establish adjacency links between first/last TriFaces. saveTri->Adj[0] = tri; tri->Adj[2] = saveTri; return true; }