00001
00002
00003 #ifndef _included_BBox_h
00004 #define _included_BBox_h
00005
00013 #include "lparx_copyright.h"
00014 #include "Coords.h"
00015
00016 #include <iosfwd>
00017 #include <cstdlib>
00018
00019 #ifndef LOWERBOUND
00020 #define LOWERBOUND (-1000000000)
00021 #endif
00022 #ifndef UPPERBOUND
00023 #define UPPERBOUND ( 1000000000)
00024 #endif
00025
00026 #define BBoxNULL ((BBox *) 0)
00027
00034 class BBox
00035 {
00036 friend std::istream& operator >> (std::istream&, BBox &);
00037 friend std::ostream& operator << (std::ostream&, BBox const &);
00038 friend std::ifstream& operator >> (std::ifstream&, BBox&);
00039 friend std::ofstream& operator << (std::ofstream&, const BBox&);
00040 friend std::stringstream& operator >> (std::stringstream&, BBox&);
00041 friend std::stringstream& operator << (std::stringstream&, const BBox&);
00042
00043 Coords lb, ub;
00044 Coords step;
00045
00046 public:
00047 int rank;
00048 static class BBox _empty_bbox;
00049
00050 public:
00051 inline BBox(void)
00052 : lb(0,UPPERBOUND), ub(0,LOWERBOUND), rank(-1) {}
00053 inline BBox(const int r, const int s)
00054 : lb(r,UPPERBOUND), ub(r,LOWERBOUND), step(r,s), rank(r) {}
00055 inline BBox(const int r, Coords const &s)
00056 : lb(r,UPPERBOUND), ub(r,LOWERBOUND), step(s), rank(r) {}
00057 inline BBox(Coords const &l, Coords const &u, const int s)
00058 : lb(l), ub(u), step(l.rank,s), rank(l.rank) {}
00059 inline BBox(const int r, const int *l, const int *u, const int s)
00060 : lb(r,l), ub(r,u), step(r,s), rank(r) {}
00061 inline BBox(Coords const &l, Coords const &u, Coords const &s)
00062 : lb(l), ub(u), step(s), rank(l.rank) {}
00063 inline BBox(const int r, const int *l, const int *u, const int *s)
00064 : lb(r,l), ub(r,u), step(r,s), rank(r) {}
00065 inline BBox(BBox const &other)
00066 : lb(other.lb), ub(other.ub), step(other.step), rank(other.rank) {}
00067
00068
00069 inline BBox(const int r, const int i,
00070 const int ii, const int s)
00071 : lb(r,i), ub(r,ii), step(r,s), rank(r) {}
00072 inline BBox(const int r, const int i, const int j,
00073 const int ii, const int jj, const int s)
00074 : lb(r,i,j), ub(r,ii,jj), step(r,s), rank(r) {}
00075 inline BBox(const int r, const int i, const int j, const int k,
00076 const int ii, const int jj, const int kk, const int s)
00077 : lb(r,i,j,k), ub(r,ii,jj,kk), step(r,s), rank(r) {}
00078 inline BBox(const int r, const int i, const int j,
00079 const int ii, const int jj,
00080 const int s, const int ss)
00081 : lb(r,i,j), ub(r,ii,jj), step(r,s,ss), rank(r) {}
00082 inline BBox(const int r, const int i, const int j, const int k,
00083 const int ii, const int jj, const int kk,
00084 const int s, const int ss, const int sss)
00085 : lb(r,i,j,k), ub(r,ii,jj,kk), step(r,s,ss,sss), rank(r) {}
00086
00087 inline BBox& operator = (const BBox& other)
00088 {
00089 step = other.step; rank = other.rank;
00090 lb = other.lb; ub = other.ub;
00091 return(*this);
00092 }
00093
00094 inline ~BBox() {}
00095
00096
00097 inline void setempty()
00098 { lb.setval(UPPERBOUND); ub.setval(LOWERBOUND); }
00099
00100 inline void setlower(Coords const &l) { lb = l; }
00101 inline void setlower(const int *l)
00102 { register int i; for (i=0;i<rank; i++) lb(i) = l[i]; }
00103
00104 inline void setupper(Coords const &u) { ub = u; }
00105 inline void setupper(const int *u)
00106 { register int i; for (i=0;i<rank; i++) ub(i) = u[i]; }
00107
00108 inline void setbbox(const int *l, const int *u)
00109 { setlower(l); setupper(u); }
00110 inline void setbbox(Coords const &l, Coords const &u)
00111 { lb = l; ub = u; }
00112 inline void setbbox(BBox const &other)
00113 { step = other.step; rank = other.rank; lb = other.lb; ub = other.ub; }
00114
00115
00116 inline Coords const &lower() const { return(lb); }
00117 inline Coords const &upper() const { return(ub); }
00118 inline int lower(const int i) const { return(lb(i)); }
00119 inline int upper(const int i) const { return(ub(i)); }
00120
00121 inline Coords &lower() { return(lb); }
00122 inline Coords &upper() { return(ub); }
00123 inline int &lower(const int i) { return(lb(i)); }
00124 inline int &upper(const int i) { return(ub(i)); }
00125
00126 inline Coords const &stepsize(void) const { return (step); }
00127 inline Coords &stepsize(void) { return (step); }
00128 inline int stepsize(const int i) const { return (step(i)); }
00129 inline int &stepsize(const int i) { return (step(i)); }
00130
00131 inline void setstepsize(const int i, const int s) { step(i) = s; }
00132 inline void setstepsize(Coords const &s) { step = s; }
00133 inline void setstepsize(const int s) { step.setval(s); }
00134
00135 inline int extents(const int i) const
00136 { return((ub(i)-lb(i)+step(i))/step(i)); }
00137 inline Coords extents() const
00138 { return((ub-lb+step)/step); }
00139
00140 inline int empty() const
00141 { return ( (rank < 0) ||
00142 ((rank > 0) && (ub(0) < lb(0))) ||
00143 ((rank > 1) && (ub(1) < lb(1))) ||
00144 ((rank > 2) && (ub(2) < lb(2)))
00145 ) ; }
00146
00147 inline int bottom(void) const
00148 {
00149 register int b = (rank > 0) ? lb(0)/step(0) : 0;
00150 register int e = (rank > 1) ? (ub(0)-lb(0)+step(0))/step(0) : 1;
00151 b += (rank > 1) ? e*lb(1)/step(1) : 0;
00152 e *= (rank > 2) ? (ub(1)-lb(1)+step(1))/step(1) : 1;
00153 b += (rank > 2) ? e*lb(2)/step(2) : 0;
00154 return (-b);
00155 }
00156
00157 inline int size() const
00158 {
00159 if (empty()) return 0;
00160 register int s = (rank > 0) ? (ub(0)-lb(0)+step(0))/step(0) : 0;
00161 s *= (rank > 1) ? ((ub(1)-lb(1)+step(1))/step(1)) : 1;
00162 s *= (rank > 2) ? ((ub(2)-lb(2)+step(2))/step(2)) : 1;
00163 return s;
00164 }
00165
00166
00167 inline int compatible(BBox const &rhs, const int d) const
00168 { return( lb(d) == rhs.lb(d) && ub(d) == rhs.ub(d) ); }
00169
00170
00171
00172 inline int mergable(BBox const &rhs, const int d, const int olap) const
00173 {
00174 return (
00175 (rank == 1) ? (std::abs(lb(d) - rhs.ub(d)) == (1-olap)*step(d)) ||
00176 (std::abs(ub(d) - rhs.lb(d)) == (1-olap)*step(d)) :
00177 (rank == 2) ? compatible(rhs,(d+1)%2) &&
00178 ((std::abs(lb(d) - rhs.ub(d)) == (1-olap)*step(d)) ||
00179 (std::abs(ub(d) - rhs.lb(d)) == (1-olap)*step(d))) :
00180 (rank == 3) ? compatible(rhs,(d+1)%3) &&
00181 compatible(rhs,(d+2)%3) &&
00182 ((std::abs(lb(d) - rhs.ub(d)) == (1-olap)*step(d)) ||
00183 (std::abs(ub(d) - rhs.lb(d)) == (1-olap)*step(d))): 0
00184 );
00185 }
00186
00187
00188 inline int mergable(BBox const &rhs, const short* olap) const
00189 {
00190 int flag = 0;
00191 flag = (rank == 3) ? flag || mergable(rhs, 2, olap[2]) : flag;
00192 flag = (rank >= 2) ? flag || mergable(rhs, 1, olap[1]) : flag;
00193 flag = (rank >= 1) ? flag || mergable(rhs, 0, olap[0]) : flag;
00194 return flag;
00195 }
00196
00197
00198 inline BBox &operator += (Coords const &rhs)
00199 {
00200 if (empty()) { lb = rhs; ub = rhs; return(*this); }
00201 lb.min(rhs); ub.max(rhs); return(*this);
00202 }
00203 inline BBox operator + (Coords const &rhs) const
00204 { BBox bbox(*this); bbox += rhs; return(bbox); }
00205
00206 inline BBox &operator += (BBox const &rhs)
00207 {
00208 if (empty()) return(*this = rhs);
00209 if (rhs.empty()) return(*this);
00210 lb.min(rhs.lb); ub.max(rhs.ub); return(*this);
00211 }
00212 inline BBox operator + (BBox const &rhs) const
00213 { BBox bbox(*this); bbox += rhs; return(bbox); }
00214
00215
00216 inline BBox &operator *= (BBox const &rhs)
00217 { lb.max(rhs.lb); ub.min(rhs.ub); return(*this); }
00218 inline BBox operator * (BBox const &rhs) const
00219 { BBox both(*this); both.lb.max(rhs.lb); both.ub.min(rhs.ub);
00220 return(both); }
00221 inline int intersects(BBox const &rhs) const
00222 { BBox both(*this); both.lb.max(rhs.lb); both.ub.min(rhs.ub);
00223 return(!both.empty()); }
00224
00225
00226 inline int operator == (BBox const &rhs) const
00227 { return(((ub == rhs.ub) && (lb == rhs.lb)) ||
00228 (empty() && rhs.empty())); }
00229 inline int operator != (BBox const &rhs) const
00230 { return(!(*this == rhs)); }
00231
00232
00233
00234 inline int inside(const int i) const
00235 { return ( (i >= lb(0)) && (i <= ub(0)) ); }
00236
00237 inline int inside(const int i, const int j) const
00238 { return ( ((i >= lb(0)) && (i <= ub(0)))
00239 && ((j >= lb(1)) && (j <= ub(1)))); }
00240
00241 inline int inside(const int i, const int j, const int k) const
00242 { return ( ((i >= lb(0)) && (i <= ub(0)))
00243 && ((j >= lb(1)) && (j <= ub(1)))
00244 && ((k >= lb(2)) && (k <= ub(2)))); }
00245
00246 inline int inside(const int *c) const
00247 { return ( !((rank <= 0) ||
00248 ((rank > 0) && (c[0] < lb(0) || c[0] > ub(0))) ||
00249 ((rank > 1) && (c[1] < lb(1) || c[1] > ub(1))) ||
00250 ((rank > 2) && (c[2] < lb(2) || c[2] > ub(2)))
00251 )) ; }
00252
00253 inline int inside(Coords const &c) const
00254 { return (BBox::inside(c())); }
00255
00256
00257
00258 inline int interior(const int i) const
00259 { return ( (i > lb(0)) && (i < ub(0)) ); }
00260
00261 inline int interior(const int i, const int j) const
00262 { return ( ((i > lb(0)) && (i < ub(0)))
00263 && ((j > lb(1)) && (j < ub(1)))); }
00264
00265 inline int interior(const int i, const int j, const int k) const
00266 { return ( ((i > lb(0)) && (i < ub(0)))
00267 && ((j > lb(1)) && (j < ub(1)))
00268 && ((k > lb(2)) && (k < ub(2)))); }
00269
00270 inline int interior(const int *c) const
00271 { return ( !((rank <= 0) ||
00272 ((rank > 0) && (c[0] <= lb(0) || c[0] >= ub(0))) ||
00273 ((rank > 1) && (c[1] <= lb(1) || c[1] >= ub(1))) ||
00274 ((rank > 2) && (c[2] <= lb(2) || c[2] >= ub(2)))
00275 )) ; }
00276 inline int interior(Coords const &c) const
00277 { return (BBox::interior(c())); }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 inline int operator > (BBox const &rhs) const
00290 { return( inside(rhs.upper()) && inside(rhs.lower()) ); }
00291 inline int operator >= (BBox const &rhs) const
00292 { return( (*this == rhs) ||
00293 (inside(rhs.upper()) && inside(rhs.lower())) ); }
00294
00295 inline int operator < (BBox const &rhs) const
00296 { return( rhs.inside(ub) && rhs.inside(lb) ); }
00297 inline int operator <= (BBox const &rhs) const
00298 { return( (rhs == *this) ||
00299 (rhs.inside(ub) && rhs.inside(lb)) ); }
00300
00301
00302 inline void accrete(const int i)
00303 { if (!empty()) { lb -= step*i; ub += step*i; } }
00304 inline void grow(const int i)
00305 { if (!empty()) { lb -= step*i; ub += step*i; } }
00306
00307 inline void accrete(Coords const &c)
00308 { if (!empty()) { lb -= c*step; ub += c*step; } }
00309 inline void grow(Coords const &c)
00310 { if (!empty()) { lb -= c*step; ub += c*step; } }
00311
00312 inline void growbydim(const short* c)
00313 {
00314 if (empty()) return;
00315 if (rank > 0) { lb(0) -= (step(0)*c[0]); ub(0) += (step(0)*c[1]); }
00316 if (rank > 1) { lb(1) -= (step(1)*c[2]); ub(1) += (step(1)*c[3]); }
00317 if (rank > 2) { lb(2) -= (step(2)*c[4]); ub(2) += (step(2)*c[5]); }
00318 }
00319
00320 inline void shrinkbydim(const short* c)
00321 {
00322 if (empty()) return;
00323 if (rank > 0) { lb(0) += (step(0)*c[0]); ub(0) -= (step(0)*c[1]); }
00324 if (rank > 1) { lb(1) += (step(1)*c[2]); ub(1) -= (step(1)*c[3]); }
00325 if (rank > 2) { lb(2) += (step(2)*c[4]); ub(2) -= (step(2)*c[5]); }
00326 }
00327
00328 inline void growupper(const int i)
00329 { if (!empty()) { ub += step*i; } }
00330 inline void growlower(const int i)
00331 { if (!empty()) { lb += step*i; } }
00332
00333 inline void growupper(Coords const &c)
00334 { if (!empty()) { ub += step*c; } }
00335 inline void growlower(Coords const &c)
00336 { if (!empty()) { lb += step*c; } }
00337
00338 inline void growupper(const int d, const int i)
00339 { if (!empty()) { ub(d) += i*step(d); } }
00340 inline void growlower(const int d, const int i)
00341 { if (!empty()) { lb(d) += i*step(d); } }
00342
00343 inline void growupperbydim(const short* c)
00344 {
00345 if (empty()) return;
00346 if (rank > 0) { ub(0) += (step(0)*c[0]); }
00347 if (rank > 1) { ub(1) += (step(1)*c[1]); }
00348 if (rank > 2) { ub(2) += (step(2)*c[2]); }
00349 }
00350 inline void growlowerbydim(const short* c)
00351 {
00352 if (empty()) return;
00353 if (rank > 0) { lb(0) += (step(0)*c[0]); }
00354 if (rank > 1) { lb(1) += (step(1)*c[1]); }
00355 if (rank > 2) { lb(2) += (step(2)*c[2]); }
00356 }
00357
00358 inline void shrinkupperbydim(const short* c)
00359 {
00360 if (empty()) return;
00361 if (rank > 0) { ub(0) -= (step(0)*c[0]); }
00362 if (rank > 1) { ub(1) -= (step(1)*c[1]); }
00363 if (rank > 2) { ub(2) -= (step(2)*c[2]); }
00364 }
00365 inline void shrinklowerbydim(const short* c)
00366 {
00367 if (empty()) return;
00368 if (rank > 0) { lb(0) -= (step(0)*c[0]); }
00369 if (rank > 1) { lb(1) -= (step(1)*c[1]); }
00370 if (rank > 2) { lb(2) -= (step(2)*c[2]); }
00371 }
00372
00373 inline void shift(const int c)
00374 { if (!empty()) { lb+=step*c ; ub+=step*c; } }
00375 inline void shift(Coords const &c)
00376 { if (!empty()) { lb+=step*c ; ub+=step*c; } }
00377 inline void shift(const int d, const int c)
00378 { if (!empty()) { lb(d)+=step(d)*c ; ub(d)+=step(d)*c; } }
00379
00380
00381 inline void coarsen(const int by) {
00382 step *= by;
00383 if (!empty()) {
00384 if (rank > 0) {
00385 if (lb(0)<0) lb(0) -= step(0)-1;
00386 if (ub(0)<0) ub(0) -= step(0)-1;
00387 }
00388 if (rank > 1) {
00389 if (lb(1)<0) lb(1) -= step(1)-1;
00390 if (ub(1)<0) ub(1) -= step(1)-1;
00391 }
00392 if (rank > 2) {
00393 if (lb(2)<0) lb(2) -= step(2)-1;
00394 if (ub(2)<0) ub(2) -= step(2)-1;
00395 }
00396 }
00397 lb = (lb/step)*step; ub = (ub/step)*step;
00398 }
00399 inline void coarsen(Coords const &by) {
00400 step *= by;
00401 if (!empty()) {
00402 if (rank>0 && by.rank>0) {
00403 if (lb(0)<0) lb(0) -= step(0)-1;
00404 if (ub(0)<0) ub(0) -= step(0)-1;
00405 }
00406 if (rank>1 && by.rank>1) {
00407 if (lb(1)<0) lb(1) -= step(1)-1;
00408 if (ub(1)<0) ub(1) -= step(1)-1;
00409 }
00410 if (rank>2 && by.rank>2) {
00411 if (lb(2)<0) lb(2) -= step(2)-1;
00412 if (ub(2)<0) ub(2) -= step(2)-1;
00413 }
00414 }
00415 lb = (lb/step)*step; ub = (ub/step)*step;
00416 }
00417 inline void coarsen(const int d, const int by) {
00418 if (!empty()) {
00419 step(d) *= by;
00420 if (lb(d)<0) lb(d) -= step(d)-1;
00421 if (ub(d)<0) ub(d) -= step(d)-1;
00422 lb(d) = (lb(d)/step(d))*step(d);
00423 ub(d) = (ub(d)/step(d))*step(d);
00424 }
00425 }
00426
00427
00428 inline void refine(const int by) { growupper(1); step /= by; growupper(-1); }
00429 inline void refine(Coords const &by) { growupper(1); step /= by; growupper(-1); }
00430
00431
00432 inline void refine(const int by, const int olap)
00433 { growupper(1); step /= by; growupper(-1); ub += (step*olap); }
00434 inline void refine(const int by, const short* olap)
00435 { growupper(1); step /= by; growupper(-1); growupperbydim(olap); }
00436 inline void refine(const int d, const int by, const int olap)
00437 { growupper(d,1); step(d) /= by; growupper(d,-1); ub(d) += (step(d)*olap); }
00438 };
00439
00440 std::istream& operator >> (std::istream& s, BBox & bb);
00441 std::ostream& operator << (std::ostream& s, const BBox &bb);
00442 std::ifstream& operator >> (std::ifstream& s, BBox& bb);
00443 std::ofstream& operator << (std::ofstream& s, const BBox& bb);
00444 std::stringstream& operator >> (std::stringstream& s, BBox& bb);
00445 std::stringstream& operator << (std::stringstream& s, const BBox& bb);
00446
00447
00448 inline Coords &upper(BBox &bb)
00449 { return (bb.upper()); }
00450 inline int upper(BBox &bb, const int i)
00451 { return (bb.upper(i)); }
00452
00453 inline Coords &lower(BBox &bb)
00454 { return (bb.lower()); }
00455 inline int lower(BBox &bb, const int i)
00456 { return (bb.lower(i)); }
00457
00458 inline Coords &stepsize(BBox &bb)
00459 { return (bb.stepsize()); }
00460 inline int stepsize(BBox &bb, const int i)
00461 { return (bb.stepsize(i)); }
00462
00463 inline Coords extents(BBox &bb)
00464 { return (bb.extents()); }
00465 inline int extents(BBox &bb, const int i)
00466 { return (bb.extents(i)); }
00467
00468 inline int size(BBox &bb)
00469 { return (bb.size()); }
00470 inline int inside(BBox &bb, Coords const &c)
00471 { return (bb.inside(c)); }
00472
00473
00474 inline BBox accrete(BBox const &bbox, Coords const &c)
00475 { const Coords& u = bbox.upper(); const Coords& l = bbox.lower();
00476 const Coords& s = bbox.stepsize();
00477 return ( (bbox.empty()) ? bbox : BBox(l-c*s, u+c*s, s) ); }
00478 inline BBox grow(BBox const &bbox, Coords const &c)
00479 { const Coords& u = bbox.upper(); const Coords& l = bbox.lower();
00480 const Coords& s = bbox.stepsize();
00481 return ( (bbox.empty()) ? bbox : BBox(l-c*s, u+c*s, s) ); }
00482
00483 inline BBox accrete(BBox const &bbox, const int c)
00484 { const Coords& u = bbox.upper(); const Coords& l = bbox.lower();
00485 const Coords& s = bbox.stepsize();
00486 return ( (bbox.empty()) ? bbox : BBox(l-s*c, u+s*c, s) ); }
00487 inline BBox grow(BBox const &bbox, const int c)
00488 { const Coords& u = bbox.upper(); const Coords& l = bbox.lower();
00489 const Coords& s = bbox.stepsize();
00490 return ( (bbox.empty()) ? bbox : BBox(l-s*c, u+s*c, s) ); }
00491
00492 BBox* accrete(BBox const *const bbox, const int n, const int c);
00493 BBox* grow(BBox const *const bbox, const int n, const int c);
00494
00495 BBox* accrete(BBox const *const bbox, const int n, Coords const &c);
00496 BBox* grow(BBox const *const bbox, const int n, Coords const &c);
00497
00498 inline BBox growupper(BBox const &bbox, const int c)
00499 { const Coords& u = bbox.upper(); const Coords& l = bbox.lower();
00500 const Coords& s = bbox.stepsize();
00501 return ( (bbox.empty()) ? bbox : BBox(l, u+s*c, s) ); }
00502 inline BBox growlower(BBox const &bbox, const int c)
00503 { const Coords& u = bbox.upper(); const Coords& l = bbox.lower();
00504 const Coords& s = bbox.stepsize();
00505 return ( (bbox.empty()) ? bbox : BBox(l+s*c, u, s) ); }
00506
00507 inline BBox growupper(BBox const &bbox, const int d, const int c)
00508 {
00509 if (bbox.empty()) return(bbox);
00510 const Coords& l = bbox.lower(); const Coords& s = bbox.stepsize();
00511 Coords u = bbox.upper(); u(d) += c*s(d);
00512 return(BBox(l, u, s));
00513 }
00514 inline BBox growlower(BBox const &bbox, const int d, const int c)
00515 {
00516 if (bbox.empty()) return(bbox);
00517 const Coords& u = bbox.upper(); const Coords& s = bbox.stepsize();
00518 Coords l = bbox.lower(); l(d) += c*s(d);
00519 return(BBox(l, u, s));
00520 }
00521
00522 inline BBox growbydim(BBox const &bbox, const short* c)
00523 {
00524 BBox bb(bbox);
00525 if (bb.empty()) return(bb);
00526 if (bb.rank > 0)
00527 {bb.lower(0) -= (bb.stepsize(0)*c[0]);bb.upper(0) += (bb.stepsize(0)*c[1]);}
00528 if (bb.rank > 1)
00529 {bb.lower(1) -= (bb.stepsize(1)*c[2]);bb.upper(1) += (bb.stepsize(1)*c[3]);}
00530 if (bb.rank > 2)
00531 {bb.lower(2) -= (bb.stepsize(2)*c[4]);bb.upper(2) += (bb.stepsize(2)*c[5]);}
00532 return bb;
00533 }
00534 inline BBox growupperbydim(BBox const &bbox, const short* c)
00535 {
00536 BBox bb(bbox);
00537 if (bb.empty()) return(bb);
00538 if (bb.rank > 0)
00539 {bb.upper(0) += (bb.stepsize(0)*c[0]);}
00540 if (bb.rank > 1)
00541 {bb.upper(1) += (bb.stepsize(1)*c[1]);}
00542 if (bb.rank > 2)
00543 {bb.upper(2) += (bb.stepsize(2)*c[2]);}
00544 return bb;
00545 }
00546 inline BBox growlowerbydim(BBox const &bbox, const short* c)
00547 {
00548 BBox bb(bbox);
00549 if (bb.empty()) return(bb);
00550 if (bb.rank > 0)
00551 {bb.lower(0) += (bb.stepsize(0)*c[0]);}
00552 if (bb.rank > 1)
00553 {bb.lower(1) += (bb.stepsize(1)*c[1]);}
00554 if (bb.rank > 2)
00555 {bb.lower(2) += (bb.stepsize(2)*c[2]);}
00556 return bb;
00557 }
00558
00559 inline BBox shrinkbydim(BBox const &bbox, const short* c)
00560 {
00561 BBox bb(bbox);
00562 if (bb.empty()) return(bb);
00563 if (bb.rank > 0)
00564 {bb.lower(0) += (bb.stepsize(0)*c[0]);bb.upper(0) -= (bb.stepsize(0)*c[1]);}
00565 if (bb.rank > 1)
00566 {bb.lower(1) += (bb.stepsize(1)*c[2]);bb.upper(1) -= (bb.stepsize(1)*c[3]);}
00567 if (bb.rank > 2)
00568 {bb.lower(2) += (bb.stepsize(2)*c[4]);bb.upper(2) -= (bb.stepsize(2)*c[5]);}
00569 return bb;
00570 }
00571 inline BBox shrinkupperbydim(BBox const &bbox, const short* c)
00572 {
00573 BBox bb(bbox);
00574 if (bb.empty()) return(bb);
00575 if (bb.rank > 0)
00576 {bb.upper(0) -= (bb.stepsize(0)*c[0]);}
00577 if (bb.rank > 1)
00578 {bb.upper(1) -= (bb.stepsize(1)*c[1]);}
00579 if (bb.rank > 2)
00580 {bb.upper(2) -= (bb.stepsize(2)*c[2]);}
00581 return bb;
00582 }
00583 inline BBox shrinklowerbydim(BBox const &bbox, const short* c)
00584 {
00585 BBox bb(bbox);
00586 if (bb.empty()) return(bb);
00587 if (bb.rank > 0)
00588 {bb.lower(0) -= (bb.stepsize(0)*c[0]);}
00589 if (bb.rank > 1)
00590 {bb.lower(1) -= (bb.stepsize(1)*c[1]);}
00591 if (bb.rank > 2)
00592 {bb.lower(2) -= (bb.stepsize(2)*c[2]);}
00593 return bb;
00594 }
00595
00596
00597 inline BBox shiftabs(BBox const &bb, const int c)
00598 { return(BBox(bb.lower()+c, bb.upper()+c, bb.stepsize())); }
00599 inline BBox shiftabs(BBox const &bb, Coords const &c)
00600 { return(BBox(bb.lower()+c, bb.upper()+c, bb.stepsize())); }
00601
00602 inline BBox shift(BBox const &bb, const int c)
00603 { return(BBox(bb.lower()+bb.stepsize()*c,
00604 bb.upper()+bb.stepsize()*c,bb.stepsize())); }
00605 inline BBox shift(BBox const &bb, Coords const &c)
00606 { return(BBox(bb.lower()+c*bb.stepsize(),
00607 bb.upper()+c*bb.stepsize(),bb.stepsize())); }
00608
00609 inline BBox shiftabs(BBox const &bbox, const int d, const int c)
00610 {
00611 if (bbox.empty()) return(bbox);
00612 Coords u = bbox.upper(); u(d) += c;
00613 Coords l = bbox.lower(); l(d) += c;
00614 return(BBox(l, u, bbox.stepsize()));
00615 }
00616 inline BBox shift(BBox const &bbox, const int d, const int c)
00617 {
00618 if (bbox.empty()) return(bbox);
00619 Coords u = bbox.upper(); u(d) += c*bbox.stepsize(d);
00620 Coords l = bbox.lower(); l(d) += c*bbox.stepsize(d);
00621 return(BBox(l, u, bbox.stepsize()));
00622 }
00623
00624
00625 inline BBox coarsen(BBox const &bbox, const int by) {
00626 BBox bb(bbox);
00627 bb.coarsen(by);
00628 return (bbox.empty() ? bbox : bb);
00629 }
00630 inline BBox coarsen(BBox const &bbox, Coords const by) {
00631 BBox bb(bbox);
00632 bb.coarsen(by);
00633 return (bbox.empty() ? bbox : bb);
00634 }
00635 inline BBox coarsen(BBox const &bbox, const int d, const int by) {
00636 BBox bb(bbox);
00637 bb.coarsen(d,by);
00638 return (bbox.empty() ? bbox : bb);
00639 }
00640
00641
00642 inline BBox refine(const BBox& bbox, const int by) {
00643 BBox bb(bbox);
00644 bb.refine(by);
00645 return (bbox.empty() ? bbox : bb);
00646 }
00647 inline BBox refine(const BBox& bbox, const Coords& by) {
00648 BBox bb(bbox);
00649 bb.refine(by);
00650 return (bbox.empty() ? bbox : bb);
00651 }
00652
00653
00654 inline BBox refine(const BBox& bbox, const int by, const int olap) {
00655 BBox bb(bbox);
00656 bb.refine(by,olap);
00657 return (bbox.empty() ? bbox : bb);
00658 }
00659 inline BBox refine(const BBox& bbox, const int by, const short* olap) {
00660 BBox bb(bbox);
00661 bb.refine(by,olap);
00662 return (bbox.empty() ? bbox : bb);
00663 }
00664 inline BBox refine(const BBox& bbox, const int d, const int by, const int olap) {
00665 BBox bb(bbox);
00666 bb.refine(d,by,olap);
00667 return (bbox.empty() ? bbox : bb);
00668 }
00669
00670 #include "CoordsIterator.h"
00671
00672 #endif