shape_doc 0.1
|
00001 #include <shape/ssi_qsegment.hpp> 00002 //#include <shape/ssi/chrono.h> 00003 00004 #define ParametricSurface shape::surface_parametric<double> 00005 00006 namespace mmx { 00007 namespace shape_ssi { 00008 00009 std::ostream & operator<<( std::ostream& o, const lrnode& l ) 00010 { 00011 o << l.lmin << " " << l.lmax << " " << l.rmin << " " << l.rmax << std::endl; 00012 return o; 00013 }; 00014 00015 lrnode * lrnode::alloc( unsigned size ) 00016 { 00017 unsigned i, acc; 00018 i = size, acc =0; 00019 do { acc += i, i = i / 2 + i % 2; } while ( i > 1 ); 00020 return new lrnode[acc+1]; 00021 }; 00022 00023 lrnode * lrnode::make( lrnode * data, unsigned size ) 00024 { 00025 #define Mmin(a,b) std::min(a,b) 00026 #define Mmax(a,b) std::max(a,b) 00027 00028 unsigned bsize = size; 00029 bool right = true; 00030 lrnode * built = data; 00031 lrnode * curr = data + size; 00032 unsigned i,j; 00033 do 00034 { 00035 if ( right ) 00036 { 00037 for ( i = 0, j = 0; i < bsize-(bsize%2); i += 2, j++ ) 00038 { 00039 curr[j].umin = built[i].umin; 00040 curr[j].umax = built[i+1].umax; 00041 curr[j].lmin = Mmin(built[i].lmin, 00042 built[i+1].lmin); 00043 curr[j].lmax = Mmax(built[i].lmax, 00044 built[i+1].lmax); 00045 curr[j].rmin = Mmin(built[i].rmin, 00046 built[i+1].rmin); 00047 curr[j].rmax = Mmax(built[i].rmax, 00048 built[i+1].rmax); 00049 curr[j].ls = built + i; 00050 curr[j].rs = built + i + 1; 00051 }; 00052 00053 if ( bsize%2 ) { curr[j++] = built[bsize-1]; }; 00054 built = curr; 00055 curr += j; 00056 } 00057 else 00058 { 00059 unsigned next_size = bsize/2 + bsize % 2; 00060 built += bsize-1; 00061 curr += next_size-1; 00062 for ( i = 0, j = 0; i < bsize-(bsize%2); i += 2, j++ ) 00063 { 00064 curr[-j].umin = built[-i-1].umin; 00065 curr[-j].umax = built[-i].umax; 00066 curr[-j].lmin = Mmin(built[-i].lmin, 00067 built[-i-1].lmin); 00068 curr[-j].lmax = Mmax(built[-i].lmax, 00069 built[-i-1].lmax); 00070 curr[-j].rmin = Mmin(built[-i].rmin, 00071 built[-i-1].rmin); 00072 curr[-j].rmax = Mmax(built[-i].rmax, 00073 built[-i-1].rmax); 00074 curr[-j].ls = built - i - 1; 00075 curr[-j].rs = built - i; 00076 }; 00077 00078 if ( bsize%2 ) { curr[-j] = built[-bsize+1]; }; 00079 built = curr - next_size+1; 00080 curr++; 00081 }; 00082 right = !right; 00083 bsize = bsize/2 + bsize%2; 00084 } 00085 while( bsize > 1 ); 00086 return --curr; 00087 }; 00088 00089 00090 void shiftm( vector3 * v, unsigned sz, const aabb3 & box ) 00091 { 00092 // double m,M; 00093 for ( vector3 * src = v; src != v+sz; src ++ ) 00094 for ( int i = 0; i < 3; (*src)[i] -= box[i].m, i ++ ); 00095 }; 00096 00097 00098 void scale( vector3 * p, double s ){ 00099 for ( int i = 0; i < 4; i ++ ) 00100 for ( int d = 0; d < 3; d ++ ) 00101 p[i][d] *= s; 00102 }; 00103 00104 void qsegment::scale_conflict( vector3 * a, vector3 * b, qtree qa, qtree qb ) 00105 { 00106 00107 aabb3 h; 00108 hull(h,qa->box,qb->box); 00109 double s = 1.0/lmax(h); 00110 qa->fill(a,this); 00111 qb->fill(b,this); 00112 shiftm(a,4,h); 00113 shiftm(b,4,h); 00114 scale(a,s); 00115 scale(b,s); 00116 }; 00117 00118 void print( std::ostream& o, qtree q ) 00119 { 00120 o << *q << std::endl; 00121 if ( q->r) print( o, q->r ); 00122 if ( q->l ) print( o, q->l ); 00123 }; 00124 qnode * qsegment::make( rid_t id, coord_t vmin, coord_t vmax, lrnode * lr ) 00125 { 00126 qnode * curr, * l, * r; 00127 curr = l = r = 0; 00128 00129 if ( vmax <= lr->lmin || vmin >= lr->rmax ) return 0; 00130 if ( vmin < lr->lmax || vmax > lr->rmin ) 00131 { 00132 if ( lr->umax-lr->umin > vmax-vmin) 00133 { 00134 l = make( id, vmin, vmax, lr->ls ); 00135 r = make( id, vmin, vmax, lr->rs ); 00136 } 00137 else 00138 { 00139 unsigned m = (vmin + vmax)/2; 00140 l = make( id, vmin, m, lr ); 00141 r = make( id, m, vmax, lr ); 00142 }; 00143 00144 if ( l && r ) 00145 { 00146 curr = new qnode(); 00147 curr->umin = lr->umin; 00148 curr->umax = lr->umax; 00149 curr->vmin = vmin; 00150 curr->vmax = vmax; 00151 hull(curr->box,l->box,r->box); 00152 curr->l = l; 00153 curr->r = r; 00154 l->father = curr; 00155 r->father = curr; 00156 return curr; 00157 }; 00158 00159 if ( l ) { return l; }; 00160 if ( r ) { return r; }; 00161 } 00162 else 00163 { 00164 curr = new qnode(); 00165 curr->l = 0; 00166 curr->r = 0; 00167 curr->umin = lr->umin; 00168 curr->umax = lr->umax; 00169 curr->vmin = vmin; 00170 curr->vmax = vmax; 00171 curr->mbox(this); 00172 00173 return curr; 00174 }; 00175 return curr; 00176 }; 00177 00178 qsegment::qsegment( const ParametricSurface * s, unsigned w, unsigned h ) : lsegment( s, w, h ) 00179 { 00180 // _qt = time(); 00181 lrnode * lr_chunk = lrnode::alloc(h); 00182 for ( unsigned i = 0; i < this->regions.size(); i++ ) 00183 { 00184 lr_chunk -= this->regions[i].umin(); 00185 for ( coord_t u = this->regions[i].umin(); u < this->regions[i].umax(); u++ ) 00186 { 00187 lr_chunk[u].umin = u; 00188 lr_chunk[u].umax = u+1; 00189 lr_chunk[u].lmax = (lr_chunk[u].lmin = this->regions[i].min(u)); 00190 lr_chunk[u].rmax = (lr_chunk[u].rmin = this->regions[i].max(u)); 00191 lr_chunk[u].ls = lr_chunk[u].rs = 0; 00192 }; 00193 00194 lr_chunk += this->regions[i].umin(); 00195 00196 lrnode * lrt = lrnode::make(lr_chunk, 00197 this->regions[i].umax()-this->regions[i].umin()); 00198 qtree tmp = make( i, lrt->lmin, lrt->rmax, lrt ); 00199 tmp->father = 0; 00200 trees.push_back( tmp ); 00201 00202 }; 00203 delete[] lr_chunk; 00204 // std::cout << "q = " << (time()-_qt) << std::endl; 00205 }; 00206 00207 qsegment::~qsegment() 00208 { 00209 for ( unsigned i = 0; i < size(); delete trees[i], i++ ); 00210 }; 00211 00212 } 00213 00214 } //namespace mmx 00215 00216 # undef ParametricSurface