shape_doc 0.1
|
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