00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "VolField.h"
00021 #include <mathGutz.h>
00022 #include <util/simPow.h>
00023
00024 using namespace gutz;
00025 using namespace glift;
00026 using namespace std;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 VolField::VolField()
00038 : SimBase(),
00039 NrroSPVec(),
00040 _on(false),
00041 _up(false),
00042 _bricked(false),
00043 _texquality(BEST),
00044 _texUnit(-1)
00045 {}
00046
00047 VolField::VolField(Nrro *n)
00048 : SimBase(),
00049 NrroSPVec(1,NrroSP(n)),
00050 _on(true),
00051 _up(true),
00052 _bricked(false),
00053 _texquality(BEST),
00054 _texUnit(-1)
00055 {}
00056
00057 VolField::VolField(NrroSP n)
00058 : SimBase(),
00059 NrroSPVec(1,n),
00060 _on(true),
00061 _up(true),
00062 _bricked(false),
00063 _texquality(BEST),
00064 _texUnit(-1)
00065 {}
00066
00067 void VolField::setNrro(NrroSP nrro, unsigned int n)
00068 {
00069 for(int i=int(size())-1; i<int(n); ++i)
00070 {
00071 NrroSPVec::push_back(NrroSP());
00072 derr("setNrro(), inserting NULL nrro objects");
00073 }
00074 NrroSPVec::operator[](n) = nrro;
00075 }
00076
00077
00078
00079
00080 void VolField::update()
00081 {
00082
00083 if(!getUpdate()) return;
00084
00085
00086 if(isBricked())
00087 {
00088 nukeBricks();
00089 }
00090 clearTex();
00091
00092
00093 setUpdate(false);
00094 }
00095
00096
00097
00098
00099 SingleTexSP VolField::genTexture(unsigned int n)
00100 {
00101 for(unsigned int i=g_max(int(_tex.size())-1,0); i<n; ++i)
00102 {
00103 _tex.push_back(SingleTexSP());
00104 derr("genTexture(),inserting null textures");
00105 }
00106
00107 if(n == _tex.size())
00108 _tex.push_back(SingleTexSP());
00109
00110 if(!_tex[n])
00111 {
00112 NrroSP nrro = NrroSPVec::operator[](n);
00113 if(!nrro.isNull())
00114 {
00115 _tex[n] = loadNrroTexture(nrro, _texquality);
00116 }
00117 else
00118 {
00119 derr("genTex(), nrro not valid, returning null texture");
00120 }
00121 }
00122 if(!_tex[n])
00123 {
00124 derr("genTex(), ERROR:: invalid texture returned!");
00125 }
00126 return _tex[n];
00127 }
00128
00129
00130
00131
00132 glift::SingleTexSP VolField::genBrickTexture(unsigned int n)
00133 {
00134 if(isBricked())
00135 return genTexture(n+1);
00136 return genTexture(n);
00137 }
00138
00139
00140
00141
00142
00143 bool VolField::checkDims(SmartPtr<VolField> f)
00144 {
00145
00146 for(unsigned int i=0; i<size(); ++i)
00147 {
00148 NrroSP n1 = getNrro(i);
00149 NrroSP n2 = f->getNrro(i);
00150
00151 if(n2.isNull() || n1.isNull())
00152 {
00153 derr("checkDims(), NULL nrro comparision");
00154 }
00155
00156 if(n1->dim() != n1->dim())
00157 {
00158 return false;
00159 }
00160
00161 for(int d=0; d<n1->dim(0); ++d)
00162 {
00163 if(n1->dim(d) != n2->dim(d))
00164 return false;
00165 }
00166 }
00167 return true;
00168 }
00169
00170
00171
00172
00173 NrroSP VolField::getBrick(unsigned int i)
00174 {
00175 if(isBricked() && i<size())
00176 {
00177 return getNrro(i+1);
00178 }
00179
00180
00181 return getNrro(0);
00182 }
00183
00184
00185
00186
00187 unsigned int VolField::numBricks()
00188 {
00189 if(isBricked() && size() > 1)
00190 {
00191 return size()-1;
00192 }
00193 else
00194 {
00195 return 1;
00196 }
00197 }
00198
00199
00200
00201
00202 void VolField::nukeBricks()
00203 {
00204
00205 if(!isBricked()) return;
00206
00207
00208
00209 for(unsigned int i=0; i<size()-1; ++i)
00210 {
00211 NrroSPVec::pop_back();
00212 }
00213
00214
00215 setBricked(false);
00216 }
00217
00218
00219
00220
00221 NrroSP VolField::genBrick(vec3i pos, vec3i size, NrroSP nin)
00222 {
00223
00224 int min[4] = {-1,
00225 pos.x,
00226 pos.y,
00227 pos.z};
00228 int max[4] = {-1,
00229 g_min(nin->dim(1)-1,pos.x+size.x-1),
00230 g_min(nin->dim(2)-1,pos.y+size.y-1),
00231 g_min(nin->dim(3)-1,pos.z+size.z-1)};
00232
00233
00234 NrroSP nnew = nin->crop(min,max);
00235
00236 if(!nnew.isNull())
00237 {
00238
00239 if((pos.x+size.x > nin->dim(1)) ||
00240 (pos.y+size.y > nin->dim(2)) ||
00241 (pos.z+size.z > nin->dim(3)))
00242 {
00243
00244 int pmin[4] = {0,0,0,0};
00245 int pmax[4] = {nnew->dim(0)-1, size.x-1, size.y-1, size.z-1};
00246 nnew = nnew->pad(pmin,pmax,Nrro::BLEED);
00247 }
00248 }
00249 return nnew;
00250 }
00251
00252
00253
00254
00255 void VolField::brick(gutz::vec3i bdim)
00256 {
00257 if(getUpdate()) update();
00258 if(isBricked()) return;
00259
00260 NrroSP n = getNrro(0);
00261
00262
00263
00264 vec3i vsize(n->dim(1), n->dim(2), n->dim(3));
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 unsigned int nxb = vsize.x/bdim.x;
00275 if(vsize.x%bdim.x) nxb += 1;
00276
00277 unsigned int nyb = vsize.y/bdim.y;
00278 if(vsize.y%bdim.y) nyb += 1;
00279
00280 unsigned int nzb = vsize.z/bdim.z;
00281 if(vsize.z%bdim.z) nzb += 1;
00282
00283 vec3i pos(0,0,0);
00284
00285 for(unsigned int z=0; z<nzb; ++z, pos.z+=bdim.z-1)
00286 {
00287 pos.y = 0;
00288
00289 for(unsigned int y=0; y<nyb; ++y, pos.y+=bdim.y-1)
00290 {
00291 pos.x = 0;
00292
00293 for(unsigned int x=0; x<nxb; ++x, pos.x+=bdim.x-1)
00294 {
00295 NrroSP nnew;
00296 if(pos + bdim > vsize)
00297 {
00298 nnew = genBrick(pos, getNextPow2(vsize - pos), n);
00299 }
00300 else
00301 {
00302 nnew = genBrick(pos, bdim, n);
00303 }
00304 NrroSPVec::push_back(nnew);
00305
00306 }
00307 }
00308 }
00309 setBricked(true);
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 void VolFieldVec::update()
00326 {
00327
00328 for(unsigned int i=0; i<size(); ++i)
00329 {
00330 if(!getField(i).isNull())
00331 {
00332 getField(i)->update();
00333 }
00334 }
00335 }
00336
00337 bool VolFieldVec::needUpdate()
00338 {
00339
00340 bool ret = false;
00341 for(unsigned int i=0; i<size(); ++i)
00342 {
00343 if(!getField(i).isNull())
00344 {
00345 if(getField(i)->getUpdate()) ret = true;
00346 }
00347 }
00348 return ret;
00349 }
00350
00351
00352
00353
00354 void VolFieldVec::addNrro(NrroSP n)
00355 {
00356 n->forceMultiChannel();
00357 push_back(VolFieldSP(new VolField(n)));
00358 }
00359
00360
00361
00362
00363
00364 VolFieldSP VolFieldVec::getField(unsigned int i)
00365 {
00366 if(i<size())
00367 return operator[](i);
00368
00369 derr("getFields(), WARNING:: accessing a null field");
00370 return VolFieldSP(0);
00371 }
00372
00373
00374
00375
00376
00377 void VolFieldVec::setField(unsigned int idx, VolField *f)
00378 {
00379
00380 for(unsigned int i=size()-1; i<idx; ++i)
00381 {
00382 operator[](i) = VolFieldSP();
00383 }
00384 operator[](idx) = VolFieldSP(f);
00385 }
00386
00387
00388
00389
00390 void VolFieldVec::delField(unsigned int i)
00391 {
00392
00393
00394 if(i<size())
00395 operator[](i) = VolFieldSP();
00396 }
00397
00398
00399
00400
00401 bool VolFieldVec::checkFields()
00402 {
00403 bool bret = true;
00404
00405
00406 for(unsigned int i=0; i<size(); ++i)
00407 {
00408 VolFieldSP f = getField(i);
00409 if(!f.isNull())
00410 if(f->isActive())
00411 if(!checkField(i))
00412 bret = false;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421 for(unsigned int i=0; i<size(); ++i)
00422 {
00423
00424 if(getField(i)->isActive())
00425 {
00426 for(unsigned int k=i+1; k<size(); ++k)
00427 {
00428 if(getField(k)->isActive())
00429 {
00430 if(!getField(i)->checkDims(getField(k)))
00431 {
00432 bret = false;
00433
00434 derr("checkFields(), dims not matching");
00435 }
00436 }
00437 }
00438 }
00439 }
00440
00441 return bret;
00442 }
00443
00444
00445
00446
00447
00448
00449 bool VolFieldVec::checkField(unsigned int i)
00450 {
00451 VolFieldSP f = getField(i);
00452 if(f.isNull())
00453 {
00454
00455 derr("checkField(), null field");
00456 return false;
00457 }
00458
00459 NrroSP n = f->getNrro();
00460 if(n.isNull())
00461 {
00462
00463 derr("checkField(), null nrro");
00464 return false;
00465 }
00466
00467
00468 if((Nrro::VOLUME != n->getKind()) && (Nrro::IMAGE != n->getKind()))
00469 {
00470 f->setActive(false);
00471 derr("checkField(), Nrro::KIND not supported");
00472 n->printKind();
00473 return false;
00474 }
00475
00476
00477
00478 if(((3==n->dim()) && (n->getKind() == Nrro::VOLUME)) ||
00479 ((2==n->dim()) && (n->getKind() == Nrro::IMAGE)))
00480 {
00481 derr("checkField(), forcing multi-channel");
00482 n->forceMultiChannel();
00483 f->setUpdate(true);
00484 }
00485
00486
00487
00488
00489 if(n->dim() > 4)
00490 {
00491 derr("checkField(), don't know how to handle volume with greater than 4 dims");
00492 f->setActive(false);
00493 return false;
00494 }
00495
00496
00497
00498
00499
00500 if((n->dim(0) > 4) && (n->getKind() == Nrro::VOLUME))
00501 {
00502 NrroSP n = f->getNrro();
00503 derr("checkField(), large number of fields, needs split");
00504 int lastField = 0;
00505
00506 while(n->dim(0) - lastField > 4)
00507 {
00508 int min[4] = {lastField, -1, -1, -1};
00509 int max[4] = {lastField+4, -1, -1, -1};
00510 max[0] = g_min(max[0], int(n->dim(0)-1));
00511 NrroSP nnew = n->crop(min, max);
00512 if(!nnew->isValid()) return false;
00513 VolFieldSP nvf(new VolField(nnew));
00514 nvf->setActive(f->isActive());
00515 push_back(nvf);
00516 lastField = max[0] + 1;
00517 }
00518
00519
00520 f->setActive(false);
00521 f->clearTex();
00522 f->nukeBricks();
00523 }
00524 return true;
00525 }
00526
00527
00528
00529
00530 void VolFieldVec::brickData(gutz::vec3i bdims)
00531 {
00532
00533
00534 for(unsigned int i=0; i<size(); ++i)
00535 {
00536 if((getField(i)->isActive()) &&
00537 ( (!getField(i)->isBricked()) ||
00538 (getField(i)->getUpdate()) ) )
00539 {
00540 getField(i)->clearTex();
00541 getField(i)->nukeBricks();
00542 getField(i)->brick(bdims);
00543 }
00544 }
00545
00546 }