void Terrain::ForceMerge(Node* T, Node* End) { if(T != TriangleTree.root) { if(TriangleTree.isInternal(T->LeftChild)) { ForceMerge(T->LeftChild, End); } else if(TriangleTree.isInternal(T->RightChild)) { ForceMerge(T->RightChild, End); } else if(TriangleTree.isExternal(T)) { ForceMerge(T->Parent, End); } else if( TriangleTree.isExternal(T->LeftChild) && TriangleTree.isExternal(T->RightChild) ) // Left and Right children of T are external { MergeNode(T); if(T != End) { ForceMerge(T->Parent, End); } } } }
void Terrain::ROAM(Node* T) { // T has been split and T must not be the root node if(T->LeftChild != NULL || T->RightChild != NULL) { // Should it be merged if( ( T->Priority <= 1000 && T->Distance >= 700)) { ForceMerge(T, T); } else { ROAM(T->LeftChild); ROAM(T->RightChild); } } else { // Should it be split if( (T->Priority > 1000) ) { if( (T->LeftChild == NULL) && (T->RightChild == NULL) && (T != TriangleTree.root) ) { ForceSplit(T); } ROAM(T->LeftChild); ROAM(T->RightChild); } else if( (T->Priority > 5 && T->Distance < 700) ) { if( (T->LeftChild == NULL) && (T->RightChild == NULL) && (T != TriangleTree.root) ) { ForceSplit(T); } ROAM(T->LeftChild); ROAM(T->RightChild); } } }
bool CListContour::CompactStrips() { CLineStrip* pStrip; CLineStrip* pStripBase; size_t i; CLineStripList::iterator pos,pos2; CLineStripList newList; bool again, changed; const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy); const size_t size = m_vStripLists.size(); assert__( size == GetNPlanes() ); for ( i = 0; i < size; i++ ) { if ( i == size / 2 ) mProgress( 1 ); again=true; while(again) { // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE again=false; // building compacted list assert__(newList.empty()); for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end(); pos++) { pStrip=(*pos); for (pos2=newList.begin(); pos2!=newList.end(); pos2++) { pStripBase=(*pos2); changed=MergeStrips(pStripBase,pStrip); if (changed) again=true; if (pStrip->empty()) break; } if (pStrip->empty()) delete pStrip; else newList.insert(newList.begin(),pStrip); } // deleting old list m_vStripLists[i].clear(); // Copying all for (pos2=newList.begin(); pos2 != newList.end(); pos2++) { pStrip=(*pos2); CLineStrip::iterator pos1 = pStrip->begin(),pos3; while (pos1!=pStrip->end()) { pos3 = pos1; pos3++; if ( pos3 != pStrip->end() && (*pos1) == (*pos3)) //femm, from if ( (*pos1) == (*pos3)) pStrip->erase(pos3); else pos1++; } //if (!(pStrip->front()==pStrip->back() && pStrip->size()==2)) if (pStrip->size()!=1) m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip ); else delete pStrip; } // emptying temp list newList.clear(); } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES) if (m_vStripLists[i].empty()) continue; /////////////////////////////////////////////////////////////////////// // compact more long_t Nstrip,j,index,count; Nstrip = m_vStripLists[i].size(); std::vector<bool> closed(Nstrip); double x,y; // First let's find the open and closed lists in m_vStripLists for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++) { pStrip = (*pos2); // is it open ? if (pStrip->front() != pStrip->back()) { index = pStrip->front(); x = GetXi(index); y = GetYi(index); index = pStrip->back(); x -= GetXi(index); y -= GetYi(index); // is it "almost closed" ? if ( x*x+y*y < weldDist) closed[j] = true; else { closed[j] = false; // updating not closed counter... count ++; } } else closed[j] = true; } // is there any open strip ? if (count > 1) { // Merge the open strips into NewList pos = m_vStripLists[i].begin(); for(j=0; j<Nstrip; j++) { if (closed[j] == false ) { pStrip = (*pos); newList.insert(newList.begin(),pStrip); pos = m_vStripLists[i].erase(pos); } else pos ++; } // are they open strips to process ? while(newList.size()>1) { pStripBase = newList.front(); // merge the rest to pStripBase again = true; while (again) { again = false; pos = newList.begin(); for(pos++; pos!=newList.end();) { pStrip = (*pos); changed = ForceMerge(pStripBase,pStrip); if (changed) { again = true; delete pStrip; pos = newList.erase(pos); } else pos ++; } } // while(again) index = pStripBase->front(); x = GetXi(index); y = GetYi(index); index = pStripBase->back(); x -= GetXi(index); y -= GetYi(index); // if pStripBase is closed or not if (x*x+y*y < weldDist) { m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); newList.pop_front(); } else { if (OnBoundary(pStripBase)) { LOG_TRACE("# open strip ends on boundary, continue.\n"); m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); newList.pop_front(); } else { LOG_TRACE("unpaired open strip at 1!"); //newList.pop_front();//femmfemmfemmefemm //continue; //femmfemmfemmefemm return false; } } } // while(newList.size()>1); if (newList.size() ==1) { pStripBase = newList.front(); if (OnBoundary(pStripBase)) { LOG_TRACE("# open strip ends on boundary, continue.\n"); m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); newList.pop_front(); } else { LOG_TRACE("unpaired open strip at 2!"); DumpPlane(i); return false; } } newList.clear(); } else if (count == 1) { pos = m_vStripLists[i].begin(); for(j=0; j<Nstrip; j++) { if (closed[j] == false ) { pStripBase = (*pos); break; } pos ++; } if (OnBoundary(pStripBase)) { LOG_TRACE("# open strip ends on boundary, continue.\n"); } else { LOG_TRACE("unpaired open strip at 3!"); DumpPlane(i); return false; } } ////////////////////////////////////////////////////////////////////////////////////////////////// } return true; }
void Terrain::MergeNode(Node* T) { if(T->LeftNeighbour != NULL) { if(T->LeftNeighbour->LeftChild != NULL || T->LeftNeighbour->RightChild != NULL) { // Merge LeftNeighbour ForceMerge(T->LeftNeighbour, T->LeftNeighbour); } if(T->LeftNeighbour->BaseNeighbour == T->LeftChild) { T->LeftNeighbour->BaseNeighbour = T; T->LeftNeighbour->Parent->RightNeighbour = T; } else { T->LeftNeighbour->RightNeighbour = T; } } if(T->RightNeighbour != NULL) { if(T->RightNeighbour->LeftChild != NULL || T->RightNeighbour->RightChild != NULL) { // Merge RightNeighbour ForceMerge(T->RightNeighbour, T->RightNeighbour); } if(T->RightNeighbour->BaseNeighbour == T->RightChild) { T->RightNeighbour->BaseNeighbour = T; T->RightNeighbour->Parent->LeftNeighbour = T; } else { T->RightNeighbour->LeftNeighbour = T; } } // Remove Children Node* Left = T->LeftChild; Left->Parent = NULL; Left->LeftNeighbour = NULL; Left->RightNeighbour = NULL; Left->BaseNeighbour = NULL; Node* Right = T->RightChild; Right->Parent = NULL; Right->LeftNeighbour = NULL; Right->RightNeighbour = NULL; Right->BaseNeighbour = NULL; T->LeftChild = NULL; T->RightChild = NULL; if(T->BaseNeighbour != NULL) { if(T->BaseNeighbour->LeftChild != NULL && T->BaseNeighbour->RightChild != NULL) { ForceMerge(T->BaseNeighbour, T->BaseNeighbour); } } delete Left; delete Right; Left = NULL; Right = NULL; }