mt.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *   
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 /****************************************************************************
00024   History
00025 
00026 $Log: not supported by cvs2svn $
00027 
00028 ****************************************************************************/
00029 
00030 #ifndef VCG_MT_H
00031 #define VCG_MT_H
00032 
00033 #include <vector>
00034 #include <queue> 
00035 #include <map>
00036 
00037 #include <vcg/space/sphere3.h>
00038 #include <vcg/space/point3.h>
00039 #include <wrap/gui/frustum.h>
00040 
00041 namespace vcg {  
00042 
00053 template <class C> class MT {
00054 public:
00055   typedef C Cell;
00056 
00057 private:
00058 
00059   class Frag:public std::vector<Cell *> {};
00060 
00061   struct Node {  
00062     std::vector<Node *> in;
00063     std::vector<Node *> out;
00064     std::vector<Frag> frags;    
00065     float error;
00066     bool visited;        
00067   };
00068 
00069   std::vector<Node> nodes;
00070 
00071 public:
00072 
00078   class Update {
00079   public:  
00080     std::vector<Cell *> erased; 
00081     std::vector<Cell *> created;    
00082   };
00083   
00085   void Load(std::vector<Update> &updates) {    
00086     //The last update erases everything.
00087     assert(updates[0].erased.size() == 0);
00088 
00089     //maps cell -> node containing it
00090     std::map<Cell *, unsigned int> cell_node;   
00091     nodes.resize(updates.size());
00092 
00093     //building fragments and nodes.
00094     unsigned int current_node = 0;
00095     std::vector<Update>::iterator u;
00096     for(u = updates.begin(); u != updates.end(); u++) {      
00097     
00098       Node &node = nodes[current_node];
00099       node.error = 0;
00100         
00101       //created cells belong to this node, we look also for max error.      
00102       for(unsigned int i = 0; i < (*u).created.size(); i++) {
00103         Cell *cell = (*u).created[i];
00104         if(cell->Error() > node.error)
00105           node.error = cell->Error();
00106           
00107         cell_node[cell] = current_node;        
00108       }
00109         
00110       //Every erased cell already belonged to a node.
00111       //we record for each node its cells.
00112       std::map<unsigned int, std::vector<Cell *> > node_erased;      
00113         
00114       for(unsigned int i = 0; i < (*u).erased.size(); i++) {
00115         Cell *cell = (*u).erased[i];
00116         assert(cell_node.count(cell));
00117         node_erased[cell_node[cell]].push_back(cell);               
00118       }      
00119 
00120       //for every node with erased cells we build a frag and put the corresponding cells in it.      
00121       std::map<unsigned int, std::vector<Cell *> >::iterator e;
00122       for(e = node_erased.begin(); e != node_erased.end(); e++) {
00123         //Build a new Frag.
00124         Frag fr;
00125         float max_err = -1;
00126 
00127         //Fill it with erased cells.
00128         std::vector<Cell *> &cells = (*e).second;
00129         std::vector<Cell *>::iterator k;
00130         for(k = cells.begin(); k != cells.end(); k++) {
00131           Cell *cell = (*k);
00132           fr.push_back(cell);
00133           if(cell->Error() > max_err)
00134             max_err = cell->Error();            
00135         }
00136         
00137         //Add the new Frag to the node.
00138         unsigned int floor_node = (*e).first;
00139         Node &oldnode = nodes[floor_node];
00140         oldnode.frags.push_back(fr);
00141         if(node.error < max_err)
00142           node.error = max_err;
00143       
00144         //Update in and out of the nodes.
00145         node.in.push_back(&oldnode);
00146         oldnode.out.push_back(&node);
00147       }
00148       current_node++;
00149     }
00150   }
00151   void Clear() {
00152     nodes.clear();
00153   }
00154     
00156   template <class CONT> void Extract(CONT &selected, float error) {
00157     std::vector<Node>::iterator n;
00158     for(n = nodes.begin(); n != nodes.end(); n++)
00159       (*n).visited = false;
00160 
00161     std::queue<Node *> qnodo;
00162           qnodo.push(&nodes[0]);
00163     nodes[0].visited = true;
00164 
00165           for( ; !qnodo.empty(); qnodo.pop()) {
00166       Node &node = *qnodo.front();
00167                                                                     
00168       std::vector<Frag>::iterator fragment;
00169       std::vector<Node *>::iterator on;
00170                   for(on = node.out.begin(), fragment = node.frags.begin(); on != node.out.end(); ++on, ++fragment) {
00171         if((*on)->visited) continue;
00172                                 
00173         if(error < (*on)->error) { //need to expand this node.
00174                                   qnodo.push(*on);
00175           (*on)->visited = 1;
00176                           } else {
00177           vector<Cell *>::iterator cell;
00178           for(cell=(*fragment).begin(); cell != (*fragment).end(); ++cell) 
00179             selected.push_back(*cell);                   
00180                           }
00181                   }
00182     }  
00183   }    
00184 
00185   //custom extraction
00186   template <class CONT, class POLICY> void Extract(CONT &selected, POLICY &policy) {
00187     std::vector<Node>::iterator n;
00188     for(n = nodes.begin(); n != nodes.end(); n++)
00189       (*n).visited = false;
00190 
00191     std::queue<Node *> qnodo;
00192           qnodo.push(&nodes[0]);
00193     nodes[0].visited = true;
00194 
00195     for( ; !qnodo.empty(); qnodo.pop()) {
00196       Node &node = *qnodo.front();   
00197 
00198       std::vector<Frag>::iterator i;
00199       std::vector<Node *>::iterator on;
00200       for(i = node.frags.begin(), on = node.out.begin(); i != node.frags.end(); i++, on++) {
00201         if((*on)->visited) continue;
00202         Frag &frag = (*i);
00203         std::vector<Cell *>::iterator cell;
00204         for(cell = frag.begin(); cell != frag.end(); cell++) {              
00205           if(policy.Expand(*cell))          
00206             visit(*on, qnodo);          
00207         }
00208       }
00209     }
00210     Extract(selected);
00211   }
00212 
00213   //extract using a user class which must provides:
00214     //bool refineCell(Cell *cell, Frustum &frustum);
00215     //void addCell(Cell *cell);
00216     //void removeCell(Cell *cell);
00217   //template <class CONT> void extract(std::vector<Cell *> &selected, Frustum &frustum, T &error);      
00218 
00220   template <class CONT> void Extract(CONT &selected) {
00221     selected.clear();
00222     std::vector<Node>::iterator i;
00223     for(i = nodes.begin(); i != nodes.end(); i++) {
00224       Node &node = *i;
00225       if(!node.visited)       
00226         continue;                  
00227     
00228       std::vector<Node *>::iterator n;
00229       std::vector<Frag>::iterator f;        
00230       for(n = node.out.begin(), f = node.frags.begin(); n != node.out.end(); n++, f++) {
00231         if(!(*n)->visited || (*n)->error == 0) {
00232           vector<Cell *>::iterator c;
00233           Frag &frag = (*f);
00234           for(c = frag.begin(); c != frag.end(); c++)            
00235              selected.insert(selected.end(), *c);        
00236         }      
00237       } 
00238     }
00239   }
00240 
00242   void Visit(Node *node, std::queue<Node *> &qnode) {    
00243     std::vector<Node *>::iterator n;
00244     for(n = node->in.begin(); n != node->in.end(); n++) 
00245       if(!(*n)->visited) 
00246         visit(*n, qnode);  
00247 
00248     node->visited = true;
00249     qnode.push(node);
00250   }
00251 
00252     
00253 };
00254 
00255 template <class C> class FrustumPolicy {
00256 public:
00257   typedef C Cell;
00258 
00259   Frustumf frustum;
00261   float error;
00262 
00263   bool Expand(Cell *cell) {
00264     if(cell->Error() == 0) return false;
00265     float dist = Distance(*cell, frustum.ViewPoint());
00266     /*Point3f line = frustum.viewPoint() - cell->sphere.center;
00267     float dist = line.Norm() - cell->sphere.radius;  */
00268     if(dist < 0) return true;
00269     dist = pow(dist, 1.2);
00270     float res =  cell->Error() / (frustum.Resolution()*dist);
00271     return res;
00272   }
00273 };
00274 
00276 template <class C> class DiracPolicy {
00277 public:
00278   typedef C Cell;
00279   
00280   Point3f focus;
00282   float error;
00283 
00284   DiracPolicy(Point3f &f = Point3f(0, 0, 0), float e = 0): focus(f), error(e) {}
00285 
00286   bool Expand(Cell *cell) {
00287     if(cell->Error() == 0) return false;
00288     float dist = Distance(*cell, focus);
00289     if(dist > 0) return true;
00290     return false;
00291   }
00292 };
00293 
00294 }//namespace vcg
00295 
00296 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:33:22