Voreen - Volume Rendering Engine Voreen - Volume Rendering Engine
Voreen - Volume Rendering Engine Westfälische Wilhelms-Universität Münster
  • About
  • Gallery
  • Download
  • Documentation
  • Publications
  • Community

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List

include/voreen/core/datastructures/volume/bricking/brickingmanager.h

00001 /**********************************************************************
00002  *                                                                    *
00003  * Voreen - The Volume Rendering Engine                               *
00004  *                                                                    *
00005  * Copyright (C) 2005-2010 The Voreen Team. <http://www.voreen.org>   *
00006  *                                                                    *
00007  * This file is part of the Voreen software package. Voreen is free   *
00008  * software: you can redistribute it and/or modify it under the terms *
00009  * of the GNU General Public License version 2 as published by the    *
00010  * Free Software Foundation.                                          *
00011  *                                                                    *
00012  * Voreen is distributed in the hope that it will be useful,          *
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the       *
00015  * GNU General Public License for more details.                       *
00016  *                                                                    *
00017  * You should have received a copy of the GNU General Public License  *
00018  * in the file "LICENSE.txt" along with this program.                 *
00019  * If not, see <http://www.gnu.org/licenses/>.                        *
00020  *                                                                    *
00021  * The authors reserve all rights not expressly granted herein. For   *
00022  * non-commercial academic use see the license exception specified in *
00023  * the file "LICENSE-academic.txt". To get information about          *
00024  * commercial licensing please contact the authors.                   *
00025  *                                                                    *
00026  **********************************************************************/
00027 
00028 #ifndef VRN_BRICKINGMANAGER_H
00029 #define VRN_BRICKINGMANAGER_H
00030 
00031 
00032 #include "voreen/core/io/brickedvolumereader.h"
00033 #include "voreen/core/io/ioprogress.h"
00034 
00035 #include "voreen/core/datastructures/volume/volumeatomic.h"
00036 #include "voreen/core/datastructures/volume/volumehandle.h"
00037 
00038 #include "voreen/core/datastructures/volume/bricking/boxbrickingregion.h"
00039 #include "voreen/core/datastructures/volume/bricking/brickedvolume.h"
00040 #include "voreen/core/datastructures/volume/bricking/brickedvolumegl.h"
00041 #include "voreen/core/datastructures/volume/bricking/brickinginformation.h"
00042 #include "voreen/core/datastructures/volume/bricking/brickingregionmanager.h"
00043 #include "voreen/core/datastructures/volume/bricking/balancedbrickresolutioncalculator.h"
00044 #include "voreen/core/datastructures/volume/bricking/cameralodselector.h"
00045 #include "voreen/core/datastructures/volume/bricking/errorlodselector.h"
00046 #include "voreen/core/datastructures/volume/bricking/largevolumemanager.h"
00047 #include "voreen/core/datastructures/volume/bricking/maximumbrickresolutioncalculator.h"
00048 #include "voreen/core/datastructures/volume/bricking/packingbrickassigner.h"
00049 #include "voreen/core/datastructures/volume/bricking/rammanager.h"
00050 #include "voreen/core/datastructures/volume/bricking/volumebrickcreator.h"
00051 
00052 #include "voreen/core/utils/voreenpainter.h"
00053 
00054 #include <math.h>
00055 #include <time.h>
00056 
00057 #include "tgt/camera.h"
00058 #include "tgt/gpucapabilities.h"
00059 
00060 namespace voreen {
00061 
00067     template<class T>
00068     class BrickingManager : public LargeVolumeManager {
00069     public:
00070 
00082         BrickingManager(VolumeHandle* volumeHandle, BrickedVolumeReader* brickedVolumeReader,
00083                         BrickingInformation brickingInformation,IOProgress* progress = 0);
00084 
00088         ~BrickingManager();
00089 
00094         void changeBrickResolutionCalculator(std::string mode);
00095 
00106         void changeBrickLodSelector(std::string selector);
00107 
00115         void setUpdateBricks(bool b);
00116 
00117         virtual void setCamera(tgt::Camera* camera) {
00118             brickingInformation_.camera = camera;
00119         }
00120 
00121         void setVolumeHandle(VolumeHandle* volumeHandle) {
00122             volumeHandle_ = volumeHandle;
00123         }
00124 
00125     protected:
00126 
00133         void createBrickedVolume();
00134 
00141         tgt::ivec3 calculateOptimalTextureDims();
00142 
00148         void createIndexVolume(tgt::ivec3 dimensions);
00149 
00154         void updateIndexVolume(VolumeBrick<T>* volBrick, PackingBrick<T>* packBrick);
00155 
00162         void createPackingBricks(tgt::ivec3 numbricks, VolumeAtomic<T>* packedVolume);
00163 
00168         void fillPackingBricks();
00169 
00174         void writeVolumeDataToPackedVolume();
00175 
00180         void updatePackedVolume();
00181 
00186         void updatePackedVolumeTexture();
00187 
00192         void getBrickingInformation();
00193 
00199         void updateBricking();
00200 
00205         void addBoxBrickingRegion(int prio, tgt::vec3 clipLLF, tgt::vec3 clipURB);
00206 
00212         std::list<Brick*> packingBricks_;
00213 
00218         std::vector<PackingBrick<T>*> bricksWithData_;
00219 
00224         BrickLodSelector* brickLodSelector_;
00225 
00230         BrickResolutionCalculator* brickResolutionCalculator_;
00231 
00235         BrickedVolumeReader* brickedVolumeReader_;
00236 
00242         VolumeBrickCreator<T>* volumeBrickCreator_;
00243 
00250         PackingBrickAssigner<T>* packingBrickAssigner_;
00251 
00257         RamManager<T>* ramManager_;
00258 
00265         BrickingInformation brickingInformation_;
00266 
00273         bool coarsenessOn_;
00274 
00279         bool updateBricks_;
00280 
00285         VolumeHandle* volumeHandle_;
00286 
00291         VolumeAtomic<T>* packedVolume_;
00292 
00297         Volume4xUInt16* indexVolume_;
00298 
00306         VolumeAtomic<uint8_t>* eepVolume_;
00307 
00314         BrickedVolume* brickedVolume_;
00315 
00319         IOProgress* ioProgress_;
00320 
00321         static const std::string loggerCat_;
00322 
00323     private:
00324 
00325 
00326     }; //class
00327 
00328 
00329     template<class T>
00330     const std::string BrickingManager<T>::loggerCat_("voreen.core.volume.bricking.BrickingManager");
00331 
00332     template<class T>
00333     BrickingManager<T>::BrickingManager(VolumeHandle* volumeHandle, BrickedVolumeReader* brickedVolumeReader,
00334                                         BrickingInformation brickingInformation, IOProgress* ioProgress)
00335 
00336         : LargeVolumeManager(volumeHandle, brickedVolumeReader),
00337           brickedVolumeReader_(brickedVolumeReader),
00338           brickingInformation_(brickingInformation),
00339           volumeHandle_(volumeHandle),
00340           ioProgress_(ioProgress)
00341     {
00342 
00343         packedVolume_ = 0;
00344         indexVolume_ = 0;
00345         eepVolume_ = 0;
00346         brickLodSelector_ = 0;
00347         brickResolutionCalculator_ = 0;
00348         volumeBrickCreator_ = 0;
00349         packingBrickAssigner_ = 0;
00350         updateBricks_ = false;
00351         coarsenessOn_ = false;
00352 
00353         //Fill the brickingInformation_ struct with information necessary for bricking.
00354         getBrickingInformation();
00355 
00356         //Now create the bricked volume.
00357         createBrickedVolume();
00358     }
00359 
00360     template<class T>
00361     void BrickingManager<T>::getBrickingInformation() {
00362 
00363         //This ugly code line calculates how many different resolution levels there are, for example,
00364         //if the bricksize is 32, there are a 6 different resolution levels (32 16 8 4 2 1).
00365         brickingInformation_.totalNumberOfResolutions = static_cast<int> ( ( log(
00366             (float)brickingInformation_.brickSize) / log(2.0) ) + 1);
00367 
00368         brickingInformation_.numVoxelsInBrick = brickingInformation_.brickSize *
00369             brickingInformation_.brickSize * brickingInformation_.brickSize;
00370 
00371         brickingInformation_.totalNumberOfBricksNeeded = brickingInformation_.numBricks.x *
00372                                                         brickingInformation_.numBricks.y *
00373                                                         brickingInformation_.numBricks.z;
00374 
00375         brickingInformation_.originalVolumeVoxelSizeInByte = sizeof(T);
00376 
00377         uint64_t temp = (uint64_t)brickingInformation_.originalVolumeVoxelSizeInByte *
00378                         brickingInformation_.originalVolumeNumVoxels;
00379 
00380         temp = temp / ( (uint64_t)1024 * (uint64_t)1024);
00381 
00382         brickingInformation_.originalVolumeSizeMB = static_cast<int>(temp);
00383 
00384         LINFO("original volume size: " << brickingInformation_.originalVolumeDimensions << " ("
00385               << brickingInformation_.originalVolumeSizeMB << " MB)");
00386 
00387         tgt::ivec3 bricksize = tgt::ivec3(brickingInformation_.brickSize);
00388 
00389         for (int i=0; i<brickingInformation_.totalNumberOfResolutions; i++) {
00390             brickingInformation_.lodToDimensionsMap.insert(std::pair<int,tgt::ivec3>(i, bricksize));
00391             bricksize=bricksize / 2;
00392         }
00393 
00394         brickingInformation_.camera=0;
00395         brickingInformation_.regionManager = 0;
00396 
00397         if (maxGpuMemory_ == 0) {
00398             brickingInformation_.gpuAvailableMemory = estimateMaxGpuMemory();
00399             LINFO("GPU memory available for bricking (estimated): "
00400                   << brickingInformation_.gpuAvailableMemory << " MB");
00401         } else {
00402             brickingInformation_.gpuAvailableMemory = maxGpuMemory_;
00403             LINFO("GPU memory available for bricking (user-specified): "
00404                   << brickingInformation_.gpuAvailableMemory << " MB");
00405         }
00406 
00407         LINFO("brick size: " << brickingInformation_.brickSize);
00408     }
00409 
00410     template<class T>
00411     BrickingManager<T>::~BrickingManager() {
00412 
00413         if (brickingInformation_.regionManager != 0) {
00414             delete brickingInformation_.regionManager;
00415             brickingInformation_.regionManager = 0;
00416         }
00417 
00418         std::vector<Brick*> bricks = brickingInformation_.volumeBricks;
00419         for (size_t i=0; i < bricks.size(); i++) {
00420             delete bricks.at(i);
00421         }
00422         bricks.clear();
00423 
00424         std::list<Brick*> packBricks = brickingInformation_.packingBricks;
00425         while (packBricks.size() > 0) {
00426             Brick* currentBrick = packBricks.front();
00427             packBricks.pop_front();
00428             delete currentBrick;
00429         }
00430 
00431         bricks = brickingInformation_.packingBricksWithData;
00432         for (size_t i=0; i < bricks.size(); i++) {
00433             delete bricks.at(i);
00434         }
00435         bricks.clear();
00436 
00437         delete brickResolutionCalculator_;
00438         delete volumeBrickCreator_;
00439         delete packingBrickAssigner_;
00440         delete brickLodSelector_;
00441         delete ramManager_;
00442         delete brickedVolumeReader_;
00443 
00444         //TODO: Delete volumehandle too?
00445     }
00446 
00447 
00448     template<class T>
00449     tgt::ivec3 BrickingManager<T>::calculateOptimalTextureDims() {
00450 
00451         uint64_t gpuMemorySizeInByte = brickingInformation_.gpuAvailableMemory * 1024 * 1024;
00452 
00453         uint64_t originalVolumeVoxelSizeInByte =
00454             (uint64_t)brickingInformation_.originalVolumeVoxelSizeInByte *
00455             brickingInformation_.originalVolumeNumVoxels;
00456 
00457         if (originalVolumeVoxelSizeInByte < (uint64_t)gpuMemorySizeInByte) {
00458             LINFO("original volume is smaller than memory available for bricking");
00459             gpuMemorySizeInByte = originalVolumeVoxelSizeInByte;
00460         }
00461         LINFO("using " << gpuMemorySizeInByte / (1024*1024) << " MB for bricking");
00462 
00463         int voxelSize = brickingInformation_.originalVolumeBytesAllocated;
00464         int brickSize = brickingInformation_.brickSize;
00465         int maxDim = GpuCaps.getMax3DTextureSize();
00466 
00467         if ((uint64_t)maxDim*maxDim*maxDim*brickingInformation_.originalVolumeVoxelSizeInByte < gpuMemorySizeInByte) {
00468             gpuMemorySizeInByte = (uint64_t)maxDim*maxDim*maxDim*brickingInformation_.originalVolumeVoxelSizeInByte;
00469             LINFO("maximum texture dimension " << maxDim << " reduces usable memory to "
00470                   << gpuMemorySizeInByte / (1024*1024) << " MB");
00471         }
00472 
00473         int xDim,yDim,zDim;
00474         xDim = yDim = zDim = brickSize;
00475 
00476         uint64_t memoryUsed = xDim*yDim*zDim * voxelSize;
00477 
00478         //Increase the texture's x-dimension if possible, otherwise try y, then z.
00479         while (memoryUsed < gpuMemorySizeInByte) {
00480             if (xDim + brickSize <= maxDim) {
00481                 xDim = xDim+brickSize;
00482             } else if (yDim + brickSize <= maxDim) {
00483                 yDim = yDim + brickSize;
00484             } else if (zDim + brickSize <= maxDim) {
00485                 zDim = zDim + brickSize;
00486             } else {
00487                 std::stringstream s;
00488                 s << "Max 3d texture sizes doesn't allow creation of a texture holding " << gpuMemorySizeInByte << " bytes.";
00489                 LINFO(s.str() );
00490                 break;
00491             }
00492 
00493             memoryUsed = xDim * yDim * zDim * voxelSize;
00494         }
00495 
00496         //Increasing the y or z-dimension in the while loop above potentially doubled the
00497         //texture size, so we have to reduce the y or x-dimension to cope for that.
00498         int tempXDim, tempYDim, tempZDim;
00499         while (memoryUsed >= gpuMemorySizeInByte) {
00500             tempXDim=xDim;
00501             tempYDim=yDim;
00502             tempZDim=zDim;
00503             bool miniumReached=true;
00504 
00505             if (xDim > brickSize) {
00506                 tempXDim = xDim - brickSize;
00507                 miniumReached=false;
00508             } else if (yDim > brickSize) {
00509                 tempYDim = yDim - brickSize;
00510                 miniumReached=false;
00511             } else if (zDim > brickSize) {
00512                 tempZDim = zDim - brickSize;
00513                 miniumReached=false;
00514             }
00515             if (miniumReached) {
00516                 break;
00517             }
00518 
00519             memoryUsed=tempXDim * tempYDim * tempZDim * voxelSize;
00520 
00521             if (memoryUsed >= gpuMemorySizeInByte) {
00522                 xDim = tempXDim;
00523                 yDim = tempYDim;
00524                 zDim = tempZDim;
00525             }
00526         }
00527 
00528         return tgt::ivec3(xDim,yDim,zDim);
00529     }
00530 
00531     template<class T>
00532     void BrickingManager<T>::createPackingBricks(tgt::ivec3 optimalDimensions,
00533         VolumeAtomic<T>* packedVolume) {
00534 
00535         int bricksize = brickingInformation_.brickSize;
00536         PackingBrick<T>* newBrick;
00537 
00538         for (int xpos=0; xpos < optimalDimensions.x; xpos = xpos+bricksize ) {
00539             for (int ypos=0; ypos < optimalDimensions.y; ypos = ypos+bricksize ) {
00540                 for (int zpos=0; zpos < optimalDimensions.z; zpos = zpos+bricksize ) {
00541 
00542                     newBrick = new PackingBrick<T>(tgt::ivec3(xpos, ypos, zpos), tgt::ivec3(bricksize),
00543                                                 brickingInformation_.packingBricks);
00544 
00545                     newBrick->setTargetVolume(packedVolume);
00546 
00547                     brickingInformation_.packingBricks.push_back(newBrick);
00548                 }
00549             }
00550         }
00551     }
00552 
00553     template<class T>
00554     void BrickingManager<T>::fillPackingBricks() {
00555 
00556         std::vector<Brick*> volumeBricks = brickingInformation_.volumeBricks;
00557         VolumeBrick<T>* currentBrick;
00558 
00559         for (size_t i=0; i< volumeBricks.size(); i++) {
00560             currentBrick = dynamic_cast<VolumeBrick<T>*>(volumeBricks.at(i));
00561             packingBrickAssigner_->assignVolumeBrickToPackingBrick(currentBrick);
00562         }
00563     }
00564 
00565     template<class T>
00566     void BrickingManager<T>::writeVolumeDataToPackedVolume() {
00567 
00568         PackingBrick<T>* currentBrick;
00569 
00570         for (size_t i=0;i < brickingInformation_.packingBricksWithData.size(); i++) {
00571             currentBrick = dynamic_cast<PackingBrick<T>* >(brickingInformation_.packingBricksWithData.at(i));
00572             currentBrick->setTargetVolume(packedVolume_);
00573             currentBrick->write();
00574         }
00575     }
00576 
00577     template<class T>
00578     void BrickingManager<T>::createIndexVolume(tgt::ivec3 dimensions) {
00579         if (indexVolume_ != 0) {
00580             delete indexVolume_;
00581         }
00582         indexVolume_ = new Volume4xUInt16(dimensions);
00583     }
00584 
00585     template<class T>
00586     void BrickingManager<T>::updateIndexVolume(VolumeBrick<T>* volBrick, PackingBrick<T>* packBrick) {
00587 
00588         int scaleFactor = static_cast<int>( pow(2.f, (int)volBrick->getCurrentLevelOfDetail() ));
00589 
00590         tgt::ivec3 indexVolumePosition = volBrick->getPosition() / brickingInformation_.brickSize;
00591         tgt::ivec4 indexVolumeValue = tgt::ivec4(packBrick->getPosition(),scaleFactor);
00592         indexVolume_->voxel(indexVolumePosition ) = indexVolumeValue;
00593     }
00594 
00595     template<class T>
00596     void BrickingManager<T>::updatePackedVolume() {
00597         //change the resolution of the determined blocks and upload them to the 3D texture
00598         updatePackedVolumeTexture();
00599 
00600         //regenerate the index 3D texture (we could also do a lot of updates, just like with
00601         //the packed 3D texture, but the index texture is always quite small, this should never
00602         //take long)
00603         BrickedVolumeGL* brickedVolumeGL = dynamic_cast<BrickedVolumeGL*>(volumeHandle_->getVolumeGL());
00604 
00605         if (brickedVolumeGL) {
00606             VolumeGL* indexVolume = brickedVolumeGL->getIndexVolumeGL();
00607 
00608             if (indexVolume) {
00609                 delete indexVolume;
00610                 indexVolume=new VolumeGL(indexVolume_);
00611                 brickedVolumeGL->setIndexVolumeGL(indexVolume);
00612             }
00613         }
00614 
00615     }
00616 
00617     template<class T>
00618     void BrickingManager<T>::updatePackedVolumeTexture() {
00619         //Get the texture we need to update
00620         BrickedVolumeGL* brickedVolumeGL = dynamic_cast<BrickedVolumeGL*>(volumeHandle_->getVolumeGL());
00621         if (!brickedVolumeGL) {
00622             return;
00623         }
00624 
00625         const VolumeTexture* packedTexture = brickedVolumeGL->getPackedVolumeGL()->getTexture();
00626 
00627         //a map holding all VolumeBricks that need a new LOD
00628         std::map<int, std::vector<Brick* > > brickMap;
00629         //an iterator for that map
00630         std::map<int, std::vector<Brick* > >::iterator brickMapIterator;
00631         //a map holding all PackingBricks holding space for a volume of the old LOD that are now free
00632         std::map<int, std::vector<Brick* > > packBrickMap;
00633         //an iterator for that map
00634         std::map<int, std::vector<Brick* > >::iterator packBrickMapIterator;
00635 
00636         int oldLod, newLod;
00637 
00638         for (size_t i=0; i<brickingInformation_.volumeBricks.size(); i++) {
00639 
00640             VolumeBrick<T>* currentBrick = dynamic_cast<VolumeBrick<T>* >(
00641                 brickingInformation_.volumeBricks.at(i));
00642 
00643             if (currentBrick->getLevelOfDetailChanged() ) {
00644                 //If the brick's LOD needs to be changed, get its old and new LOD
00645                 oldLod = currentBrick->getOldLevelOfDetail();
00646                 newLod = currentBrick->getCurrentLevelOfDetail();
00647 
00648                 //Get the VolumeBrick's old PackingBrick and put it into the PackingBrick map, because that
00649                 //PackingBrick is now free and can be used again.
00650                 packBrickMapIterator = packBrickMap.find(oldLod);
00651                 if (packBrickMapIterator != packBrickMap.end() ) {
00652                     packBrickMap[oldLod].push_back(currentBrick->getPackingBrick() );
00653                 } else {
00654                     std::vector<Brick* > newPackVector;
00655                     newPackVector.push_back(currentBrick->getPackingBrick() );
00656                     packBrickMap.insert( std::pair<int,std::vector<Brick* > >(oldLod,newPackVector) );
00657                 }
00658 
00659                 //Put the VolumeBrick into the VolumeBrick map which holds all VolumeBricks that need
00660                 //a new PackingBrick of a different size assigned.
00661                 brickMapIterator = brickMap.find(newLod);
00662                 if (brickMapIterator != brickMap.end() ) {
00663                     brickMap[newLod].push_back(currentBrick);
00664                 } else {
00665                     std::vector<Brick* > newVector;
00666                     newVector.push_back(currentBrick);
00667                     brickMap.insert( std::pair<int,std::vector<Brick* > >(newLod,newVector) );
00668                 }
00669 
00670             }
00671         }
00672 
00673         //Bind the texture to be updated
00674         packedTexture->bind();
00675 
00676         //Go through the map of all VolumeBricks needing a new PackingBrick and assign them
00677         //the PackingBricks of the PackingBrick map (because all those bricks are free)
00678         brickMapIterator = brickMap.begin();
00679 
00680         while (brickMapIterator != brickMap.end() ) {
00681             int newLod = brickMapIterator->first;
00682             //Get all the VolumeBricks needing a new PackingBrick, and all the PackingBricks
00683             //that can be used for that.
00684             std::vector<Brick* > changedVolumeBricks = brickMap[newLod];
00685             std::vector<Brick* > freePackBricks = packBrickMap[newLod];
00686 
00687             if (changedVolumeBricks.size() > 0 && freePackBricks.size() > 0) {
00688             //now assign those packingbricks to the volumebricks
00689                 for (size_t i=0; i< changedVolumeBricks.size() ; i++) {
00690                     VolumeBrick<T>* volBrick = dynamic_cast<VolumeBrick<T>* > (changedVolumeBricks.at(i));
00691                     PackingBrick<T>* packBrick = dynamic_cast<PackingBrick<T>* > (freePackBricks.at(i));
00692 
00693                     //Assign the VolumeBrick's correct volume (that means of the correct LOD) to the
00694                     //PackingBrick, and tell the VolumeBrick that it has a new PackingBrick.
00695                     tgt::ivec3 dims = brickingInformation_.lodToDimensionsMap[newLod];
00696                      packBrick->setSourceVolume( (T*)volBrick->getLodVolume(newLod), dims );
00697                     volBrick->setPackingBrick(packBrick);
00698 
00699                     //Update the index texture because the VolumeBrick now has a new place in the packed
00700                     //volume.
00701                     updateIndexVolume(volBrick,packBrick);
00702 
00703                     //At last update the packed texture with the PackingBrick's new content.
00704                     packBrick->updateTexture(packedTexture);
00705                 }
00706             }
00707 
00708             brickMapIterator++;
00709         }
00710     }
00711 
00712     template<class T>
00713     void BrickingManager<T>::changeBrickResolutionCalculator(std::string mode) {
00714 
00715         if (mode == "maximum") {
00716             delete brickResolutionCalculator_;
00717             delete brickLodSelector_;
00718             brickResolutionCalculator_ = new MaximumBrickResolutionCalculator(brickingInformation_);
00719             brickLodSelector_ = new CameraLodSelector(brickingInformation_);
00720         } else if (mode == "balanced") {
00721             delete brickResolutionCalculator_;
00722             delete brickLodSelector_;
00723             brickResolutionCalculator_ = new BalancedBrickResolutionCalculator(brickingInformation_);
00724             brickLodSelector_ = new CameraLodSelector(brickingInformation_);
00725         }
00726         updateBricking();
00727     }
00728 
00729     template<class T>
00730     void BrickingManager<T>::changeBrickLodSelector(std::string selector) {
00731         if (selector == "Camera-based") {
00732             delete brickLodSelector_;
00733             brickLodSelector_ = new CameraLodSelector(brickingInformation_);
00734         } else if (selector == "Error-based") {
00735             delete brickLodSelector_;
00736             brickLodSelector_ = new ErrorLodSelector(brickingInformation_);
00737             setUpdateBricks(false);
00738         }
00739         updateBricking();
00740     }
00741 
00742     template<class T>
00743     void BrickingManager<T>::setUpdateBricks(bool b) {
00744         updateBricks_=b;
00745     }
00746 
00747     template<class T>
00748     void BrickingManager<T>::createBrickedVolume() {
00749 
00750         brickingInformation_.packedVolumeDimensions = calculateOptimalTextureDims();
00751 
00752         brickResolutionCalculator_ = new MaximumBrickResolutionCalculator(brickingInformation_);
00753 
00754         brickResolutionCalculator_->calculateBrickResolutions();
00755 
00756         //The type of the eep volume doesn't matter as no memory will be allocated anyway.
00757         eepVolume_ = new VolumeAtomic<uint8_t>(brickingInformation_.originalVolumeDimensions,
00758                                                     brickingInformation_.originalVolumeSpacing,
00759                                                     brickingInformation_.originalVolumeBitsStored ,false);
00760 
00761         eepVolume_->meta().setBrickSize(brickingInformation_.brickSize);
00762 
00763 
00764         tgt::ivec3 dims = brickingInformation_.packedVolumeDimensions;
00765         LINFO("size for packed volume: " << dims << " ("
00766               << (((long)dims.x*(long)dims.y*(long)dims.z) / (1024*1024))
00767               * brickingInformation_.originalVolumeVoxelSizeInByte<< " MB)");
00768 
00769 
00770         packedVolume_ = new VolumeAtomic<T>(brickingInformation_.packedVolumeDimensions,
00771                                             brickingInformation_.originalVolumeSpacing,
00772                                             brickingInformation_.originalVolumeBitsStored);
00773 
00774         createIndexVolume(brickingInformation_.numBricks);
00775 
00776         createPackingBricks(brickingInformation_.packedVolumeDimensions,packedVolume_);
00777 
00778         ramManager_ = new RamManager<T>(brickingInformation_, brickedVolumeReader_, maxMemory_);
00779 
00780         packingBrickAssigner_ = new PackingBrickAssigner<T>(brickingInformation_,indexVolume_);
00781 
00782         volumeBrickCreator_= new VolumeBrickCreator<T> (brickingInformation_.numBricks,
00783             brickingInformation_.brickSize ,brickingInformation_.originalVolumeDimensions,
00784             brickingInformation_.originalVolumeSpacing, brickingInformation_.originalVolumeLLF,
00785             brickingInformation_.originalVolumeURB, ramManager_);
00786 
00787         if (ioProgress_)
00788             ioProgress_->setTotalSteps(static_cast<int>(brickingInformation_.totalNumberOfBricksNeeded*1.5));
00789         int bricksCreated = 0;
00790 
00791         VolumeBrick<T>* newBrick = volumeBrickCreator_->createNextBrick();
00792         bricksCreated++;
00793         if (ioProgress_)
00794             ioProgress_->setProgress(bricksCreated);
00795 
00796         while (newBrick != 0) {
00797             bricksCreated++;
00798             if (ioProgress_) {
00799                 ioProgress_->setProgress(bricksCreated);
00800             }
00801             if (newBrick->getAllVoxelsEqual() == true) {
00802                 //If all voxels are equal in the VolumeBrick, assign it a PackingBrick immediately.
00803                 //The LOD of this brick will never ever change anyway, so we don't have to keep
00804                 //track of the brick.
00805                 newBrick->setCurrentLevelOfDetail(brickingInformation_.totalNumberOfResolutions -1);
00806                 packingBrickAssigner_->assignVolumeBrickToPackingBrick(newBrick, true, packedVolume_);
00807             } else {
00808                 //The brick contains meaningful data, put it into the vector.
00809                 brickingInformation_.volumeBricks.push_back(newBrick);
00810             }
00811             newBrick = volumeBrickCreator_->createNextBrick();
00812         }
00813 
00814         //Until now, only VolumeBricks with only voxels of the same value have been assigned a PackingBrick.
00815         //And those bricks will never change their resolution, so they can permanently keep their place
00816         //in the packed volume. By creating a backup of the remaining PackingBricks one can rearrange
00817         //the other bricks inside the packed volume freely without interfering with the positions of the
00818         //bricks containing only voxels of the same value. Only PackingBricks not yet assigned end up
00819         //in the backup.
00820         packingBrickAssigner_->createPackingBrickBackups();
00821 
00822         brickingInformation_.regionManager = new BrickingRegionManager(brickingInformation_);
00823 
00824         brickLodSelector_ = new ErrorLodSelector(brickingInformation_);
00825         brickLodSelector_->selectLods();
00826         if (ioProgress_)
00827         ioProgress_->setProgress(static_cast<int>(brickingInformation_.totalNumberOfBricksNeeded*1.5));
00828 
00829         fillPackingBricks();
00830 
00831         writeVolumeDataToPackedVolume();
00832 
00833         // Immediately free all bricks after the packed volume has been written. This is done
00834         // to prevent storing three copies in RAM (one in RamManager, one in packed volume, one
00835         // by OpenGL), this way they are only stored twice.
00836         ramManager_->freeAll();
00837 
00838         brickedVolume_ = new BrickedVolume(indexVolume_,packedVolume_,eepVolume_);
00839         volumeHandle_->setVolume(brickedVolume_);
00840     }
00841 
00842     template<class T>
00843     void BrickingManager<T>::updateBricking() {
00844         brickResolutionCalculator_->calculateBrickResolutions();
00845 
00846         brickLodSelector_->selectLods();
00847 
00848         packingBrickAssigner_->deletePackingBricks();
00849 
00850         packingBrickAssigner_->createPackingBricksFromBackup();
00851 
00852         fillPackingBricks();
00853 
00854         BrickedVolumeGL* brickedVolumeGL = dynamic_cast<BrickedVolumeGL*>(volumeHandle_->getVolumeGL());
00855         if (!brickedVolumeGL) {
00856             return;
00857         }
00858 
00859         const VolumeTexture* packedTexture = brickedVolumeGL->getPackedVolumeGL()->getTexture();
00860 
00861         packedTexture->bind();
00862 
00863         PackingBrick<T>* currentBrick;
00864         for (size_t i=0; i<brickingInformation_.packingBricksWithData.size(); i++) {
00865             currentBrick = dynamic_cast<PackingBrick<T>*>(brickingInformation_.packingBricksWithData.at(i));
00866             currentBrick->updateTexture(packedTexture);
00867         }
00868 
00869         VolumeGL* indexVolumeGL = brickedVolumeGL->getIndexVolumeGL();
00870         delete indexVolumeGL;
00871         indexVolumeGL=new VolumeGL(indexVolume_);
00872         brickedVolumeGL->setIndexVolumeGL(indexVolumeGL);
00873     }
00874 
00875     template<class T>
00876     void BrickingManager<T>::addBoxBrickingRegion(int prio, tgt::vec3 clipLLF, tgt::vec3 clipURB) {
00877 
00878         BoxBrickingRegion* boxRegion = new BoxBrickingRegion(brickingInformation_);
00879         boxRegion->setBox(clipLLF,clipURB);
00880         boxRegion->calculateBricksInRegion();
00881         boxRegion->setPriority(prio);
00882         brickingInformation_.regionManager->addRegion(boxRegion);
00883     }
00884 
00885 } //namespace voreen
00886 
00887 #endif
  • Getting Started
  • Video Tutorials
  • Build Instructions
  • Adding a Module
  • Programming Tutorials
  • API Documentation
  • FAQ
edit