shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/ssi_dsearch.hpp
Go to the documentation of this file.
00001 #ifndef SYNAPS_SHAPE_GAIA_DSEARCH_H
00002 #define SYANSP_SHAPE_GAIA_DSEARCH_H
00003 #include <shape/ssi_def.hpp>
00004 #include <shape/ssi_qsegment.hpp>
00005 #include <list>
00006 #include <queue>
00007 #include <shape/ssi_ordered_pair.hpp>
00008 
00009 #define ParametricSurface shape::surface_parametric<double>
00010 
00011 namespace mmx {
00012 namespace shape_ssi {
00013   
00014   typedef std::list< point2 >  list2_t; 
00015   typedef std::list< point3 >  list3_t;
00016   typedef  list2_t::iterator p2ref_t;
00017   
00018   struct dcurve
00019   {      
00020     unsigned size;
00021     dcurve  *   owner; 
00022     list2_t     left,right;
00023     list3_t     inter;
00024     dcurve( const point2& l, const point2& r, const point3& i ) ;
00025     dcurve( const point2& l0, const point2& l1, const point2& r0, const point2& r1, const point3& i0, const point3& i1 );
00026   };
00027 
00028   template<class DPoint>
00029     struct dim_cmp   
00030     { 
00031       unsigned dim; 
00032       dim_cmp(unsigned d = 0): dim(d) {}; 
00033       dim_cmp next() const { return dim_cmp((dim+1)%4); };
00034       bool operator()(  DPoint*const& a, DPoint *const& b ) const { return (*a)[dim] < (*b)[dim]; };
00035       bool operator()( const DPoint& a, const DPoint&  b ) const { return    a[dim] < b[dim];    };
00036     };
00037 
00038   template<class DP>
00039     inline double distance( DP * pa, DP * pb )
00040     {
00041       double acc = 0.0;
00042       for ( unsigned i = 0; i < 4; i++ )
00043         acc += ((*pa)[i]-(*pb)[i])*((*pa)[i]-(*pb)[i]);
00044       return acc;
00045     };
00046 
00047   struct sdpoint_t
00048   {
00049     typedef double value_type;
00050     dcurve  *  curve;
00051     p2ref_t idl;
00052     p2ref_t idr;
00053   
00054     inline const double& operator[]( unsigned i ) const
00055     {
00056       if ( i < 2 ) return (*idl)[i];
00057       return (*idr)[i-2];
00058     };
00059   
00060     inline double& operator[]( unsigned i ) 
00061     {
00062       if ( i < 2 ) return (*idl)[i];
00063       return (*idr)[i-2];
00064     };
00065   };
00066 
00067   struct pdpoint_t
00068   {
00069     typedef double value_type;
00070     dcurve * curve;
00071     p2ref_t ref;
00072     pdpoint_t * a;
00073 
00074     inline value_type& operator[]( unsigned i ) 
00075     { 
00076       if ( i < 2 ) return (*ref)[i];
00077       return (*(a->ref))[i-2];
00078     };
00079     inline const value_type& operator[]( unsigned i ) const 
00080     { 
00081       if ( i < 2 ) return (*ref)[i];
00082       return (*(a->ref))[i-2];
00083     };
00084   };
00085 
00086   void append( dcurve *  a, dcurve   * b ) ;
00087   void prepend( dcurve * a, dcurve * b ) ;
00088   void reverse( dcurve * c ) ;
00089 
00090 
00091   struct sdknode
00092   {
00093     sdpoint_t   * data; 
00094     sdknode * l, * r; 
00095     sdknode( sdpoint_t * d, sdknode * _l, sdknode * _r ) : data(d), l(_l), r(_r){}; 
00096     ~sdknode() { if ( l ) delete l; if ( r ) delete r; };
00097   };
00098 
00099   struct pdknode
00100   {
00101     pdpoint_t   * data; 
00102     pdknode * l, * r; 
00103     pdknode( pdpoint_t * d, pdknode * _l, pdknode * _r ) : data(d), l(_l), r(_r){}; 
00104     ~pdknode() { if ( l ) delete l; if ( r ) delete r; };
00105   };
00106 
00107 
00108 
00109   inline  bool   empty( dcurve * c ) { return c->owner != c; };
00110 
00111   inline  pdpoint_t * sibble( pdpoint_t * p )  { return p->a; };
00112   void extremums( sdpoint_t* dst, dcurve* src );
00113   void extremums( pdpoint_t * dst, dcurve * c );
00114   dcurve * curve( pdpoint_t * p );
00115   dcurve *  curve( sdpoint_t * p );
00116 
00117 
00118   inline  bool isfirst ( sdpoint_t* p ) { return curve(p)->left.begin() == p->idl;     };
00119   inline  bool islast  ( sdpoint_t* p ) { return (--(curve(p)->left.end())) == p->idl; };
00120 
00121   inline bool isfirst ( pdpoint_t* p ) { return curve(p)->left.begin() == p->ref || curve(p)->right.begin() == p->ref; };
00122   inline bool islast ( pdpoint_t* p ) { return (--(curve(p)->left.end())) == p->ref ||(--(curve(p)->right.end())) == p->ref;};
00123 
00124   inline bool isextrem( pdpoint_t* p  ) { return  isfirst(p) || islast(p); };
00125   inline bool isextrem( sdpoint_t*  p ) { return  isfirst(p) || islast(p); };
00126 
00127   void link( sdpoint_t* a, sdpoint_t* b);
00128   void link( pdpoint_t* a, pdpoint_t* b);
00129   inline void swap( dcurve * c ) { c->left.swap( c->right ); };
00130 
00131   inline bool isright( pdpoint_t* p )
00132     { return p->ref == curve(p)->right.begin() || p->ref == --(curve(p)->right.end());};
00133 
00134 
00135   template<class DPoint>
00136     inline void _link(  DPoint* a, DPoint* b ) 
00137     {
00138       if ( islast(a)   ) 
00139         {
00140           if( islast(b) )
00141             reverse(curve(b));
00142           // last a + first b
00143           append(curve(a),curve(b));
00144         }
00145       else
00146         {
00147           if ( isfirst(b) )
00148             reverse(curve(b));
00149           // last b + first a
00150           prepend(curve(a),curve(b));
00151         };
00152     };
00153 
00154 
00155   sdknode * make( sdpoint_t * first, sdpoint_t * last, const dim_cmp<sdpoint_t>& f ) ;
00156   pdknode * make( pdpoint_t ** first, pdpoint_t ** last, const dim_cmp<pdpoint_t>& f ) ;
00157 
00158 
00159   template<class DPoint>
00160     struct assoc_t
00161     {
00162       std::pair<DPoint*,DPoint*>         pp;
00163       double                              d;
00164       // comparing association on pointers
00165       struct pair_cmp
00166       { bool operator()( const assoc_t& a1, const assoc_t& a2 ) const { return a1.pp < a2.pp;  }; };
00167       // comparing association on distances
00168       struct dist_cmp
00169       { bool operator()( const assoc_t& a1, const assoc_t& a2 ) const { return a1.d > a2.d;    }; };
00170       assoc_t(){};
00171       assoc_t( DPoint * a, DPoint * b, double _d ):
00172         pp(a,b), d(_d){};
00173     };
00174 
00175   typedef std::priority_queue< assoc_t<pdpoint_t>, 
00176     std::vector< assoc_t<pdpoint_t> >, 
00177     assoc_t< pdpoint_t>::dist_cmp > pheap_t;    
00178   typedef std::priority_queue< assoc_t<sdpoint_t>, 
00179     std::vector< assoc_t<sdpoint_t> >, 
00180     assoc_t< sdpoint_t>::dist_cmp > sheap_t;
00181 
00182   typedef std::set< assoc_t< pdpoint_t > ,  assoc_t<pdpoint_t>::pair_cmp > pset_t;
00183 
00184   typedef assoc_t<sdpoint_t> sdassc_t;
00185   typedef assoc_t<pdpoint_t> pdassc_t;
00186 
00187   void solve_sheap( sheap_t& h );
00188   void solve_pheap( pheap_t& h );
00189 
00190   typedef std::pair<pdpoint_t*,pdpoint_t*> ppair_t;
00191   typedef std::list< ppair_t > links_t;
00192   typedef std::map< dcurve*, links_t > curves_links_t;
00193   typedef ordered_pair<dcurve*> cpair_t;
00194 
00195   template <class A, class B>
00196     inline void container_add( A& h, const B& a ) { h.push(a); };
00197   inline void container_add( pset_t& s, const pdassc_t& a ) { s.insert(a); };
00198   inline cpair_t curves( const pdassc_t& ass ) { return cpair_t(curve(ass.pp.first),curve(ass.pp.second)); };
00199   inline pdassc_t sibbles( const pdassc_t& ass )
00200     {
00201       pdpoint_t * a = sibble(ass.pp.first);
00202       pdpoint_t * b = sibble(ass.pp.second);
00203       if ( a < b )
00204         return pdassc_t(a,b,0);
00205       else 
00206         return pdassc_t(b,a,0);
00207     };
00208 
00209   void satisfy_links(  curves_links_t::iterator it );
00210   void solve_pset( curves_links_t& links, pset_t& s );
00211   std::list<dcurve*> * reduce2( std::vector< dcurve * > * conflicts );
00212   typedef  pset_t::iterator pset_iterator;
00213 
00214   struct dsearch : qsegment
00215   {
00216     bool m_cnf;
00217   
00218   
00219     //------------------------------------------------------------------------------
00220     std::vector< dcurve * >  * curr_config;           // represent the current region/region conflict resultings segments
00221     std::list  < dcurve * >  ** _branches;            // represent the reduced set of curves for each region/region conflict
00222   
00223     void cnfpush( qtree f, qtree s );
00224     void push( qtree f, qtree s );
00225     inline  std::list  < dcurve * >  *& branches( unsigned i, unsigned j ) 
00226     { return _branches[i*this->regions.size()+j]; };
00227     // add a pair of segment to the segment soup
00228     void push (  const point2& l0,  const point2& l1, 
00229                  const point2& r0,  const point2& r1,
00230                  const point3& i0,  const point3& i1 )
00231     { 
00232       curr_config->push_back( new dcurve( l0,l1,r0, r1, i0, i1 ) ); 
00233     };
00234   
00235     // use of the qsegment_t bounding box hierarchy to retrieve unit quad that intersects
00236 #define push_s push
00237 #define push_f push
00238     // search specialisation s is known to be a leaf
00239     void search_f(  qtree f, qtree const s );
00240     // same thing here f is a leaf
00241     void search_s(   qtree const f, qtree s );
00242     // search generic case: both f and s are root node
00243     void search(qtree f, qtree s );
00244     
00245     // launch the search for region i vs region j
00246     void search( rid_t i, rid_t j );
00247   
00248     // try to reduce the number of double curves
00249     std::list<dcurve*> * reduce( std::vector< dcurve * > * conflicts );
00250     inline void find_branches( rid_t id0, rid_t id1 )
00251     {
00252       branches( id0, id1 ) = reduce( curr_config );
00253       delete curr_config;
00254     };
00255   
00256     // stats structure
00257     struct 
00258     {
00259       double search_time;
00260       double recons_time;
00261     } stats;
00262   
00263     std::list< dcurve * >  *result;
00264   
00265     point2 ** lefts;
00266     point2 ** rights;
00267   
00268     unsigned * sizes;
00269     unsigned nbcurves;
00270     unsigned nbpoints;
00271     unsigned conflict_count;
00272   
00273     void GnuPlotOutput( char * name );
00274   
00275     std::vector< point3 > cnfdata3;
00276     std::vector< point2 > cnfdata2;
00277   
00278   
00279     double _st;
00280     dsearch( const ParametricSurface * s , unsigned w, unsigned h, bool cnf = false  );
00281     ~dsearch();
00282   };
00283 }
00284 
00285 } //namespace mmx
00286 # undef ParametricSurface
00287 # endif