00001 #include <OSGConfig.h>
00002
00003 #include <OSGBrick.h>
00004
00005 #include <OSGSlicer.h>
00006 #include <OSGDVRClipper.h>
00007 #include <OSGDVRVolume.h>
00008 #include <OSGDVRClipObjects.h>
00009 #include <OSGDVRVolumeTexture.h>
00010
00011
00012 #define FACE_FRONT (1)
00013 #define FACE_BACK (2)
00014 #define FACE_RIGHT (4)
00015 #define FACE_LEFT (8)
00016 #define FACE_BOTTOM (16)
00017 #define FACE_TOP (32)
00018
00019
00020 OSG_BEGIN_NAMESPACE
00021
00022 BrickSet::~BrickSet()
00023 {
00024 delete [] m_pBricks;
00025 }
00026
00027 void BrickSet::buildBricks3D(DVRVolume *volume,
00028 Vec3f brickSize,
00029 Int32 overlap,
00030 Orientation ori)
00031 {
00032 FDEBUG(("BrickSet::buildBricks3D %d %d %d\n",
00033 brickSize[0],
00034 brickSize[1],
00035 brickSize[2]));
00036
00037 SINFO << "BrickSet::buildBricks3D (size)"
00038 << brickSize[0] << ", "
00039 << brickSize[1] << ","
00040 << brickSize[2] << std::endl;
00041
00042 m_nOrientation = ori;
00043
00044 DVRVolumeTexturePtr vT = DVRVOLUME_PARAMETER(volume, DVRVolumeTexture);
00045
00046 if(vT == NullFC)
00047 {
00048 SWARNING << "BrickSet::buildTextures3D - No Volume" << std::endl;
00049 return;
00050 }
00051
00052 if((brickSize[0] <= overlap) ||
00053 (brickSize[1] <= overlap) ||
00054 (brickSize[2] <= overlap) )
00055 {
00056 SFATAL << "BrickSet::buildBricks3D - brickSize too small: "
00057 << brickSize[0] << ","
00058 << brickSize[1] << ","
00059 << brickSize[2] << "for overlap "
00060 << overlap << std::endl;
00061
00062 return;
00063 }
00064
00065 Vec3f vox = vT->getSliceThickness();
00066 Vec3f res = vT->getResolution();
00067 Int32 resX = (Int32) res[0];
00068 Int32 resY = (Int32) res[1];
00069 Int32 resZ = (Int32) res[2];
00070
00071 Int32 nNumBricksX = Int32((resX - overlap) / (brickSize[0] - overlap));
00072 Int32 nNumBricksY = Int32((resY - overlap) / (brickSize[1] - overlap));
00073 Int32 nNumBricksZ = Int32((resZ - overlap) / (brickSize[2] - overlap));
00074
00075 SINFO << "BrickSet::buildBricks3D (num)"
00076 << nNumBricksX << ", "
00077 << nNumBricksY << ","
00078 << nNumBricksZ << std::endl;
00079
00080 m_nNumBricks = nNumBricksX * nNumBricksY * nNumBricksZ;
00081
00082 m_pBricks = new Brick[m_nNumBricks];
00083
00084 Int32 nBrickSizeX = Int32(brickSize[0]);
00085 Int32 nBrickSizeY = Int32(brickSize[1]);
00086 Int32 nBrickSizeZ = Int32(brickSize[2]);
00087
00088 Int32 nXMin = 0;
00089 Int32 nYMin = 0;
00090 Int32 nZMin = 0;
00091
00092 Real32 xmin = (overlap - 1 + 0.5f - resX / 2) * vox[0];
00093 Real32 ymin = (overlap - 1 + 0.5f - resY / 2) * vox[1];
00094 Real32 zmin = (overlap - 1 + 0.5f - resZ / 2) * vox[2];
00095
00096 Real32 xmax = 0, ymax = 0, zmax = 0;
00097
00098 Int32 index = 0;
00099
00100 for(Int32 z = 0; z < nNumBricksZ; z++)
00101 {
00102 nYMin = 0;
00103 ymin = (overlap - 1 + 0.5f - resY / 2) * vox[1];
00104
00105 for(Int32 y = 0; y < nNumBricksY; y++)
00106 {
00107 nXMin = 0;
00108 xmin = (overlap - 1 + 0.5f - resX / 2) * vox[0];
00109
00110 for(Int32 x = 0; x < nNumBricksX; x++)
00111 {
00112 xmax = xmin + (nBrickSizeX - (2 * (overlap - 1) + 1)) * vox[0];
00113 ymax = ymin + (nBrickSizeY - (2 * (overlap - 1) + 1)) * vox[1];
00114 zmax = zmin + (nBrickSizeZ - (2 * (overlap - 1) + 1)) * vox[2];
00115
00116 m_pBricks[index].init(nXMin, nYMin, nZMin,
00117 nBrickSizeX, nBrickSizeY, nBrickSizeZ,
00118 xmin, ymin, zmin,
00119 xmax, ymax, zmax,
00120 overlap,
00121 ori );
00122
00123 index++;
00124
00125 nXMin += nBrickSizeX - (2 * overlap - 1);
00126 xmin = xmax;
00127 }
00128
00129 nYMin += nBrickSizeY - (2 * overlap - 1);
00130 ymin = ymax;
00131 }
00132
00133 nZMin += nBrickSizeZ - (2 * overlap - 1);
00134 zmin = zmax;
00135 }
00136 }
00137
00138
00139 void BrickSet::buildBricks2D(DVRVolume *volume, Orientation ori)
00140 {
00141 m_nOrientation = ori;
00142
00143 DVRVolumeTexturePtr vT = DVRVOLUME_PARAMETER(volume, DVRVolumeTexture);
00144
00145 if(vT == NullFC)
00146 return;
00147
00148 Vec3f vox = vT->getSliceThickness();
00149 Vec3f res = vT->getResolution();
00150
00151 Int32 resX = 0, resY= 0, resZ= 0;
00152 Real32 xmin = 0, ymin = 0, zmin = 0;
00153 Real32 xmax = 0, ymax = 0, zmax = 0;
00154 Real32 xinc = 0, yinc = 0, zinc = 0;
00155
00156 switch(ori)
00157 {
00158 case XY:
00159 {
00160
00161 resX = (Int32) res[0];
00162 resY = (Int32) res[1];
00163 resZ = 1;
00164
00165 xinc = 0;
00166 yinc = 0;
00167 zinc = 1;
00168
00169
00170 xmin = (-(res[0] - 1) / 2) * vox[0];
00171 ymin = (-(res[1] - 1) / 2) * vox[1];
00172 zmin = (-(res[2] ) / 2) * vox[2];
00173
00174 xmax = -xmin;
00175 ymax = -ymin;
00176 zmax = zmin + zinc * vox[2];
00177
00178 m_nNumBricks = (int) res[2];
00179 m_pBricks = new Brick[m_nNumBricks];
00180
00181 break;
00182 }
00183
00184 case XZ:
00185 {
00186
00187 resX = (Int32) res[0];
00188 resY = 1;
00189 resZ = (Int32) res[2];
00190
00191 xinc = 0;
00192 yinc = 1;
00193 zinc = 0;
00194
00195
00196 xmin = (-(res[0] - 1) / 2) * vox[0];
00197 ymin = (-(res[1] ) / 2) * vox[1];
00198 zmin = (-(res[2] - 1) / 2) * vox[2];
00199
00200 xmax = -xmin;
00201 ymax = ymin + yinc * vox[1];
00202 zmax = -zmin;
00203
00204 m_nNumBricks = (int) res[1];
00205 m_pBricks = new Brick[m_nNumBricks];
00206
00207 break;
00208 }
00209
00210 case YZ:
00211 {
00212
00213 resX = 1;
00214 resY = (Int32) res[1];
00215 resZ = (Int32) res[2];
00216
00217 xinc = 1;
00218 yinc = 0;
00219 zinc = 0;
00220
00221
00222 xmin = (-(res[0] ) / 2) * vox[0];
00223 ymin = (-(res[1] - 1) / 2) * vox[1];
00224 zmin = (-(res[2] - 1) / 2) * vox[2];
00225
00226 xmax = xmin + xinc * vox[0];
00227 ymax = -ymin;
00228 zmax = -zmin;
00229
00230 m_nNumBricks = (int) res[0];
00231 m_pBricks = new Brick[m_nNumBricks];
00232
00233 break;
00234 }
00235
00236 case UNDEF:
00237 {
00238 SFATAL << "BrickSet::buildBricks2D called with unspecified "
00239 << "orientation"
00240 << std::endl;
00241 break;
00242 }
00243 }
00244
00245 for(Int32 index = 0; index < m_nNumBricks; index++)
00246 {
00247 m_pBricks[index].init(resX == 1 ? index : 0,
00248 resY == 1 ? index : 0,
00249 resZ == 1 ? index : 0,
00250 resX, resY, resZ,
00251 xmin, ymin, zmin,
00252 xmax, ymax, zmax,
00253 1,
00254 ori);
00255
00256 xmin += xinc * vox[0];
00257 xmax += xinc * vox[0];
00258
00259 ymin += yinc * vox[1];
00260 ymax += yinc * vox[1];
00261
00262 zmin += zinc * vox[2];
00263 zmax += zinc * vox[2];
00264 }
00265 }
00266
00267
00269 TextureChunkPtr BrickSet::makeTexture(UInt32 internalFormat,
00270 UInt32 externalFormat,
00271 ImagePtr img)
00272 {
00273 TextureChunkPtr chunk = TextureChunk::create();
00274
00275 beginEditCP(chunk);
00276 {
00277 chunk->setImage (img );
00278 chunk->setInternalFormat(internalFormat);
00279 chunk->setExternalFormat(externalFormat);
00280
00281 FDEBUG(("TextureManager - makeTexture: intern %d - extern %d\n",
00282 internalFormat, externalFormat));
00283
00287 #if defined GL_ARB_texture_border_clamp
00288 chunk->setWrapS(GL_CLAMP_TO_BORDER);
00289 chunk->setWrapT(GL_CLAMP_TO_BORDER);
00290 chunk->setWrapR(GL_CLAMP_TO_BORDER);
00291 #else
00292
00293
00294
00295
00296 chunk->setWrapS(GL_CLAMP);
00297 chunk->setWrapT(GL_CLAMP);
00298 chunk->setWrapR(GL_CLAMP);
00299 #endif
00300
00301 chunk->setMinFilter(GL_LINEAR);
00302 chunk->setMagFilter(GL_LINEAR);
00303
00304
00305 chunk->setEnvMode(GL_MODULATE);
00306 }
00307 endEditCP(chunk);
00308
00309 return chunk;
00310 }
00311
00312
00314 void BrickSet::buildBrickTextures(ChunkMaterialPtr &material,
00315 TextureSet &textures,
00316 TextureManager::TextureMode mode )
00317 {
00318
00319 UInt32 numTextures = textures.size();
00320
00321 if(mode == TextureManager::TM_2D_Multi)
00322 numTextures *= 2;
00323
00324 beginEditCP(material);
00325 {
00326
00327 for(Int32 index = 0; index < m_nNumBricks; index++)
00328 {
00329 Int32 &resX = m_pBricks[index].voxSize[0];
00330 Int32 &resY = m_pBricks[index].voxSize[1];
00331 Int32 &resZ = m_pBricks[index].voxSize[2];
00332
00333 Int32 &nXMin = m_pBricks[index].minVox[0];
00334 Int32 &nYMin = m_pBricks[index].minVox[1];
00335 Int32 &nZMin = m_pBricks[index].minVox[2];
00336
00337 int texCounter = 0;
00338
00339 m_pBricks[index].texture = new TextureChunkPtr[numTextures];
00340 m_pBricks[index].texStage = new UInt32[numTextures];
00341 m_pBricks[index].numTextures = numTextures;
00342
00343
00344 for(UInt32 tch = 0; tch < textures.size(); tch++)
00345 {
00346 ImagePtr img = Image::create();
00347
00348 switch (mode)
00349 {
00350 case TextureManager::TM_2D_Multi:
00351 {
00352
00353 textures[tch]->_image->slice(resX == 2 ? nXMin : -1,
00354 resY == 2 ? nYMin : -1,
00355 resZ == 2 ? nZMin : -1,
00356 img);
00357 if (index == 0)
00358 {
00359 m_pBricks[index].texture[texCounter] =
00360 makeTexture(textures[tch]->_internalFormat,
00361 textures[tch]->_externalFormat,
00362 img );
00363 }
00364 else
00365 {
00366
00367
00368
00369 m_pBricks[index].texture[texCounter] =
00370 m_pBricks[index-1].texture[texCounter+1];
00371 }
00372
00373 m_pBricks[index].texStage[texCounter] =
00374 textures[tch]->_textureStage0;
00375
00376 material->addChunk(
00377 m_pBricks[index].texture[texCounter]);
00378
00379 texCounter++;
00380
00381
00382 img = Image::create();
00383
00384 textures[tch]->_image->slice(
00385 resX == 2 ? nXMin + 1 : -1,
00386 resY == 2 ? nYMin + 1 : -1,
00387 resZ == 2 ? nZMin + 1 : -1,
00388 img );
00389
00390 m_pBricks[index].texture[texCounter] =
00391 makeTexture(textures[tch]->_internalFormat,
00392 textures[tch]->_externalFormat,
00393 img );
00394
00395 m_pBricks[index].texStage[texCounter] =
00396 textures[tch]->_textureStage1;
00397
00398 material->addChunk(
00399 m_pBricks[index].texture[texCounter]);
00400
00401 texCounter++;
00402
00403 break;
00404 }
00405
00406 case TextureManager::TM_2D:
00407 {
00408 textures[tch]->_image->slice(resX == 1 ? nXMin : -1,
00409 resY == 1 ? nYMin : -1,
00410 resZ == 1 ? nZMin : -1,
00411 img);
00412
00413 m_pBricks[index].texture[texCounter] =
00414 makeTexture(textures[tch]->_internalFormat,
00415 textures[tch]->_externalFormat,
00416 img );
00417
00418 m_pBricks[index].texStage[texCounter] =
00419 textures[tch]->_textureStage0;
00420
00421 material->addChunk(
00422 m_pBricks[index].texture[texCounter]);
00423
00424 texCounter++;
00425
00426 break;
00427 }
00428
00429 case TextureManager::TM_3D:
00430 default:
00431 {
00432 textures[tch]->_image->subImage(nXMin, nYMin, nZMin,
00433 resX, resY, resZ,
00434 img );
00435
00436 m_pBricks[index].texture[texCounter] =
00437 makeTexture(textures[tch]->_internalFormat,
00438 textures[tch]->_externalFormat,
00439 img );
00440
00441 m_pBricks[index].texStage[texCounter] =
00442 textures[texCounter]->_textureStage0;
00443
00444 material->addChunk(
00445 m_pBricks[index].texture[texCounter]);
00446
00447 texCounter++;
00448
00449 break;
00450 }
00451 }
00452
00453 }
00454
00455 }
00456 }
00457 endEditCP(material);
00458 }
00459
00460
00462 void BrickSet::reloadBrickTextures(DrawActionBase *action, UInt32 texStage)
00463 {
00464 for(Int32 i = 0; i < m_nNumBricks; i++)
00465 {
00466 for(Int32 j = 0; j < m_pBricks[i].numTextures; j++)
00467 {
00468 if(m_pBricks[i].texStage[j] == texStage)
00469 {
00470 action->getWindow()->refreshGLObject(
00471 m_pBricks[i].texture[j]->getGLId());
00472 }
00473 }
00474 }
00475 }
00476
00477
00479 void BrickSet::clearBrickTextures(ChunkMaterialPtr & material)
00480 {
00481 for(Int32 i = 0; i < m_nNumBricks; i++)
00482 {
00483 for(Int32 j = 0; j < m_pBricks[i].numTextures; j++)
00484 {
00485 material->subChunk(m_pBricks[i].texture[j]);
00486 }
00487 }
00488 }
00489
00490
00492 Brick *BrickSet::sortBricks3D(const Matrix & modelMat, const Vec3f & eyePoint)
00493 {
00494
00495 Brick *BrickList = m_pBricks;
00496
00497 Int32 nBrick;
00498 Real32 distance;
00499 Brick *previous, *current, *incoming;
00500
00501 Vec3f transformedCenter;
00502
00503 m_pBricks[0].prev = NULL;
00504 m_pBricks[0].next = NULL;
00505
00506 modelMat.multMatrixPnt(m_pBricks[0].center,transformedCenter);
00507
00508 m_pBricks[0].distance = (eyePoint - transformedCenter).length();
00509
00510
00511 for(nBrick = 1; nBrick < m_nNumBricks; nBrick++)
00512 {
00513 incoming = &(m_pBricks[nBrick]);
00514
00515 modelMat.multMatrixPnt(incoming->center,transformedCenter);
00516
00517 distance = (eyePoint - transformedCenter).length();
00518
00519 incoming->distance = distance;
00520 incoming->next = NULL;
00521 incoming->prev = NULL;
00522
00523 current = BrickList;
00524 previous = NULL;
00525
00526 while((current != NULL) && (current->distance > distance))
00527 {
00528 previous = current;
00529 current = current->next;
00530 }
00531
00532
00533 if (current == NULL)
00534 {
00535
00536 previous->next = incoming;
00537 incoming->prev = previous;
00538
00539 }
00540 else
00541 {
00542 incoming->next = current;
00543 incoming->prev = current->prev;
00544 current->prev = incoming;
00545
00546 if (incoming->prev == NULL)
00547 {
00548 BrickList = incoming;
00549 }
00550 else
00551 {
00552 incoming->prev->next = incoming;
00553 }
00554 }
00555 }
00556
00557 return BrickList;
00558 }
00559
00560
00562 Brick *BrickSet::sortBricks2D(bool backToFront)
00563 {
00564 Brick *brickList = m_pBricks;
00565
00566 if(brickList)
00567 {
00568 if(backToFront)
00569 {
00570 for(int i = m_nNumBricks - 1; i >= 0; i--)
00571 {
00572 m_pBricks[i].prev = &(m_pBricks[i + 1]);
00573 m_pBricks[i].next = &(m_pBricks[i - 1]);
00574 }
00575
00576 m_pBricks[0].next = NULL;
00577 m_pBricks[m_nNumBricks - 1].prev = NULL;
00578
00579 brickList = &(m_pBricks[m_nNumBricks - 1]);
00580 }
00581 else
00582 {
00583 for (int i = 0; i < m_nNumBricks; i++)
00584 {
00585 m_pBricks[i].prev = &(m_pBricks[i - 1]);
00586 m_pBricks[i].next = &(m_pBricks[i + 1]);
00587 }
00588
00589 m_pBricks[0].prev = NULL;
00590 m_pBricks[m_nNumBricks - 1].next = NULL;
00591
00592 brickList = &(m_pBricks[0]);
00593 }
00594 }
00595
00596 return brickList;
00597 }
00598
00599
00601 void Brick::init(Int32 minVoxX, Int32 minVoxY, Int32 minVoxZ,
00602 Int32 resX, Int32 resY, Int32 resZ,
00603 Real32 xmin, Real32 ymin, Real32 zmin,
00604 Real32 xmax, Real32 ymax, Real32 zmax,
00605 Int32 overlap,
00606 BrickSet::Orientation ori )
00607 {
00608
00609 FINFO(("Brick::init - upper left (%d, %d, %d)\n",
00610 minVoxX, minVoxY, minVoxZ));
00611
00612 FINFO(("Brick::init (%d, %d, %d): %f %f %f -> %f %f %f \n",
00613 resX, resY, resZ, xmin, ymin, zmin, xmax, ymax, zmax));
00614
00615 Real32 xrange = xmax - xmin;
00616 Real32 yrange = ymax - ymin;
00617 Real32 zrange = zmax - zmin;
00618
00619 minVox[0] = minVoxX;
00620 minVox[1] = minVoxY;
00621 minVox[2] = minVoxZ;
00622
00623 voxSize[0] = resX;
00624 voxSize[1] = resY;
00625 voxSize[2] = resZ;
00626
00627 m_lowerLeft = Vec3f(xmin, ymin, zmin);
00628 m_upperRight = Vec3f(xmax, ymax, zmax);
00629
00630 m_ori = ori;
00631
00632 Real32 texCoorMin[3], texCoorMax[3];
00633
00634 texCoorMin[0] = (2 * Real32(overlap) - 1) / 2.0f / Real32(resX);
00635 texCoorMin[1] = (2 * Real32(overlap) - 1) / 2.0f / Real32(resY);
00636 texCoorMin[2] = (2 * Real32(overlap) - 1) / 2.0f / Real32(resZ);
00637
00638 texCoorMax[0] = 1 - texCoorMin[0];
00639 texCoorMax[1] = 1 - texCoorMin[1];
00640 texCoorMax[2] = 1 - texCoorMin[2];
00641
00642 texScale = Vec3f((texCoorMax[0] - texCoorMin[0]) / xrange,
00643 (texCoorMax[1] - texCoorMin[1]) / yrange,
00644 (texCoorMax[2] - texCoorMin[2]) / zrange);
00645
00646 texTranslate = Vec3f(texCoorMin[0] - texScale[0] * xmin,
00647 texCoorMin[1] - texScale[1] * ymin,
00648 texCoorMin[2] - texScale[2] * zmin);
00649
00650 FINFO (("Brick::init - overlap: %d \n",
00651 overlap));
00652
00653 FINFO (("Brick::init - texScale: %f %f %f \n",
00654 texScale[0], texScale[1], texScale[2]));
00655
00656 FINFO (("Brick::init - texTranslate: %f %f %f \n",
00657 texTranslate[0], texTranslate[1], texTranslate[2]));
00658
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 vertex[0] = Vec3f( xmin, ymin, zmin);
00686 vertex[1] = Vec3f( xmax, ymin, zmin);
00687 vertex[2] = Vec3f( xmax, ymax, zmin);
00688 vertex[3] = Vec3f( xmin, ymax, zmin);
00689
00690 vertex[4] = Vec3f( xmax, ymax, zmax);
00691 vertex[5] = Vec3f( xmin, ymax, zmax);
00692 vertex[6] = Vec3f( xmin, ymin, zmax);
00693 vertex[7] = Vec3f( xmax, ymin, zmax);
00694
00695 center = Vec3f(0.0, 0.0, 0.0);
00696
00697 for(Int32 j = 0; j < 8; j++)
00698 {
00699 center += vertex[j];
00700 }
00701
00702 center /= 8.0;
00703 radius = (vertex[0] - center).length();
00704
00705
00706
00707 const int eindex[12][2] =
00708 {
00709 {0, 1},
00710 {2, 3},
00711 {6, 7},
00712 {4, 5},
00713 {1, 2},
00714 {0, 3},
00715 {5, 6},
00716 {4, 7},
00717 {1, 7},
00718 {2, 4},
00719 {3, 5},
00720 {0, 6}
00721 };
00722
00723 for(Int32 i = 0; i < 12; i++)
00724 {
00725 edges[i] = Line(Pnt3f(vertex[eindex[i][0]]),
00726 Pnt3f(vertex[eindex[i][1]]));
00727 }
00728
00729 #if 0
00730 TOUT("Init Brick");
00731 TOUT("Brick (" << x << ", " << y << ", " << z << ")");
00732 TOUT(VARDUMP(nXMin) << ", " << VARDUMP(nXMax));
00733 TOUT(VARDUMP(nYMin) << ", " << VARDUMP(nYMax));
00734 TOUT(VARDUMP(nZMin) << ", " << VARDUMP(nZMax));
00735 TOUT(VARDUMP(nDataSize));
00736 #endif
00737 }
00738
00739
00741 void Brick::activateTexture(DrawActionBase *action)
00742 {
00743 for(Int32 i = 0; i < numTextures; i++)
00744 {
00745 FDEBUG(("Brick::activateTexture - Brick: %d - Texture %d "
00746 "- Stage: %d - ID: %d\n",
00747 this, i, texStage[i], texture[i]->getGLId()));
00748
00749 texture[i]->activate(action, texStage[i]);
00750 }
00751 }
00752
00753
00755 void Brick::changeFromTexture(DrawActionBase *action, Brick *old)
00756 {
00757 FDEBUG(("Brick::changeFromTexture\n"));
00758
00759 if(old == NULL)
00760 activateTexture(action);
00761
00762 for(Int32 i = 0; i < numTextures; i++)
00763 {
00764 texture[i]->changeFrom(action, &(*(old->texture[i])), texStage[i]);
00765 }
00766 }
00767
00768
00770 void Brick::deactivateTexture(DrawActionBase *action)
00771 {
00772 for(Int32 i = 0; i < numTextures; i++)
00773 {
00774 texture[i]->deactivate(action, texStage[i]);
00775 }
00776
00777 }
00778
00779
00781 void Brick::renderSlices(DVRVolume *volume,
00782 DrawActionBase *action,
00783 DVRShaderPtr shader,
00784 DVRClipper *clipper,
00785 TextureManager::TextureMode textureMode)
00786 {
00787 switch (textureMode)
00788 {
00789 case TextureManager::TM_2D:
00790 {
00791 GLboolean val;
00792 glGetBooleanv(GL_TEXTURE_3D, &val);
00793
00794 if(val != 0)
00795 {
00796 glDisable(GL_TEXTURE_3D);
00797 SWARNING << "Brick::renderSlices - 3DTextures enabled "
00798 << "-> DISABLING "
00799 << (int) val
00800 << std::endl;
00801 }
00802
00803 Vec3f sliceDir;
00804
00805 Slicer::getAASlicingDirection(action, &sliceDir);
00806
00807 render2DSlices(volume, action, shader, clipper, sliceDir);
00808
00809 break;
00810 }
00811 case TextureManager::TM_2D_Multi:
00812 {
00813 FDEBUG(("Brick::renderSlices - 2D MTex Slabs\n"));
00814
00815 Vec3f sliceDir;
00816
00817 Int32 dir = Slicer::getAASlicingDirection(action, &sliceDir);
00818
00819 render2DMultiSlices(volume, action, shader, clipper,
00820 Slicer::isBackToFront(dir),sliceDir);
00821 break;
00822 }
00823
00824 default:
00825 case TextureManager::TM_3D:
00826 {
00827 FDEBUG(("Brick::renderSlices -3D slices\n"));
00828
00829 Vec3f sliceDir;
00830
00831 Slicer::getSlicingDirection(action, &sliceDir);
00832
00833 render3DSlices(volume, action, shader, clipper, sliceDir);
00834
00835 break;
00836 }
00837 }
00838 }
00839
00840
00842 void Brick::renderBrick()
00843 {
00844 FDEBUG(("Brick::renderBrick"));
00845
00846 const int eindex[12][2] =
00847 {
00848 {0,1},
00849 {2,3},
00850 {6,7},
00851 {4,5},
00852 {1,2},
00853 {0,3},
00854 {5,6},
00855 {4,7},
00856 {1,7},
00857 {2,4},
00858 {3,5},
00859 {0,6}
00860 };
00861
00862 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
00863 glDisable (GL_TEXTURE_3D);
00864 glDisable (GL_TEXTURE_2D);
00865
00866 glColor4f (1.0, 0.0, 0.0, 1.0 );
00867
00868 glBegin(GL_LINES);
00869 {
00870 for(Int32 i = 0; i < 12; i++)
00871 {
00872 glVertex3fv(vertex[eindex[i][0]].getValues());
00873 glVertex3fv(vertex[eindex[i][1]].getValues());
00874 }
00875 }
00876 glEnd();
00877
00878 glPopAttrib();
00879 }
00880
00881
00883 void Brick::vertToTex(Real32 *vx, Real32 *vy, Real32 *vz,
00884 Real32 *tx, Real32 *ty, Real32 *tz)
00885 {
00886 *tx = *vx * texScale[0] + texTranslate[0];
00887 *ty = *vy * texScale[1] + texTranslate[1];
00888 *tz = *vz * texScale[2] + texTranslate[2];
00889 }
00890
00891
00893 void Brick::vertToTex(Vec3f &vert, Vec3f &tex)
00894 {
00895 tex[0] = vert[0] * texScale[0] + texTranslate[0];
00896 tex[1] = vert[1] * texScale[1] + texTranslate[1];
00897 tex[2] = vert[2] * texScale[2] + texTranslate[2];
00898 };
00899
00900
00902 void Brick::render3DSlices(DVRVolume *volume,
00903 DrawActionBase *action,
00904 DVRShaderPtr shader,
00905 DVRClipper *clipper,
00906 const Vec3f &sliceDir)
00907 {
00908 Int32 i, j;
00909
00910 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(volume, DVRVolumeTexture);
00911
00912 if(tex == NullFC)
00913 return;
00914
00915 Vec3f res = tex->getResolution();
00916 Vec3f vox = tex->getSliceThickness();
00917
00918 Real32 fSampleRate = volume->getSampling();
00919 Real32 fSliceDistance = vox.length() / 2.0f / fSampleRate;
00920 Real32 fTolerance = fSliceDistance / 100.0f;
00921 Real32 fAlphaCorrect = 1.f - osgpow(1.f - volume->getBaseAlpha(),
00922 1.0f / fSampleRate );
00923
00924 SINFO << "Sampling rate: "
00925 << fSampleRate
00926 << " Alpha-Correction "
00927 << fAlphaCorrect
00928 << std::endl;
00929
00930 Vec3f diag(res[0]*vox[0], res[1]*vox[1], res[2]*vox[2]);
00931
00932 Real32 fRadius = 0.5f * diag.length();
00933
00934 const int ecodes[12] =
00935 {
00936 (FACE_FRONT + FACE_BOTTOM),
00937 (FACE_FRONT + FACE_TOP ),
00938 (FACE_BACK + FACE_BOTTOM),
00939 (FACE_BACK + FACE_TOP ),
00940
00941 (FACE_FRONT + FACE_RIGHT ),
00942 (FACE_FRONT + FACE_LEFT ),
00943 (FACE_BACK + FACE_LEFT ),
00944 (FACE_BACK + FACE_RIGHT ),
00945
00946 (FACE_RIGHT + FACE_BOTTOM),
00947 (FACE_RIGHT + FACE_TOP ),
00948 (FACE_TOP + FACE_LEFT ),
00949 (FACE_BOTTOM + FACE_LEFT )
00950 };
00951
00952
00953 Vec3f vecViewDir = sliceDir;
00954
00955 Plane planeSlice(vecViewDir, -fRadius);
00956
00957 Int32 numSlices = 1 + (Int32) (2.0f * fRadius/ fSliceDistance);
00958
00959 Vec3f vecIntersections[12];
00960 Int32 nEdgeCodes[12];
00961
00962 bool bIntersectionUsed[12];
00963
00964 Vec3f vecIntersectionsSorted[12];
00965 Vec3f vecIntersection;
00966
00967 Int32 nSlice, numIntersections, nEdgeCode, numUsedIntersections;
00968
00969 Vec3f v, texscale, textrans;
00970
00971 texscale = texScale;
00972 textrans = texTranslate;
00973
00974
00975 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume,
00976 DVRClipObjects);
00977
00978 bool doClipping = false;
00979
00980 if(clipObjects != NullFC)
00981 {
00982 if(clipObjects->count() > 0 &&
00983 clipObjects->getClipMode() != DVRClipObjects::Off)
00984 {
00985 doClipping = true;
00986 clipper->reset(volume);
00987 }
00988 }
00989
00990 slice.setTextureTransform(texScale,texTranslate);
00991
00992 for(nSlice = 0; nSlice < numSlices; nSlice++)
00993 {
00994
00995
00996 numIntersections = 0;
00997
00998 for(i = 0; i < 12; i++)
00999 {
01000 if(planeSlice.intersect(edges[i],vecIntersection))
01001 {
01002
01003 if((vecIntersection-center).length() <= radius)
01004 {
01005 vecIntersections[numIntersections] = vecIntersection;
01006 nEdgeCodes[numIntersections] = ecodes[i];
01007 bIntersectionUsed[numIntersections] = false;
01008
01009 numIntersections++;
01010 }
01011 }
01012 }
01013
01014
01015
01016
01017 if (numIntersections > 2)
01018 {
01019 for(i = 0; i < numIntersections-1; i++)
01020 {
01021 for(j = i+1; j < numIntersections; j++)
01022 {
01023 if((vecIntersections[i]-vecIntersections[j]).length() <
01024 fTolerance)
01025 {
01026
01027 nEdgeCodes[i] |= nEdgeCodes[j];
01028
01029 if(j < numIntersections-1)
01030 {
01031 vecIntersections[j] =
01032 vecIntersections[numIntersections-1];
01033 nEdgeCodes[j] = nEdgeCodes[numIntersections-1];
01034
01035
01036
01037 j--;
01038 }
01039
01040 numIntersections--;
01041 }
01042 }
01043 }
01044 }
01045
01046 assert(numIntersections <= 6);
01047
01048 if(numIntersections > 2)
01049 {
01050
01051
01052 vecIntersectionsSorted[0] = vecIntersections[0];
01053 bIntersectionUsed[0] = true;
01054 numUsedIntersections = 1;
01055
01056 nEdgeCode = nEdgeCodes[0];
01057
01058
01059 UInt32 count = 0;
01060 while(numUsedIntersections != numIntersections && ++count <= numIntersections)
01061 {
01062 for(Int32 i = 1; i < numIntersections; i++)
01063 {
01064 if ((bIntersectionUsed[i] == false ) &&
01065 (nEdgeCodes[i] & nEdgeCode) )
01066 {
01067 vecIntersectionsSorted[numUsedIntersections] =
01068 vecIntersections[i];
01069
01070 nEdgeCode = nEdgeCodes[i];
01071 bIntersectionUsed[i] = true;
01072
01073 numUsedIntersections++;
01074 }
01075 }
01076 }
01077
01078 if(doClipping)
01079 {
01080
01081 Vec3f sliceNormal =
01082 (vecIntersectionsSorted[1] -
01083 vecIntersectionsSorted[0]).cross(
01084 vecIntersectionsSorted[2]-vecIntersectionsSorted[1]);
01085
01086 bool sliceCCW = sliceNormal.dot(sliceDir) > 0.0;
01087
01088 slice.resetSlice();
01089
01090 if(sliceCCW)
01091 {
01092 for(Int32 i = 0; i < numIntersections; i++)
01093 {
01094 slice.setVertex(vecIntersectionsSorted[i]);
01095 }
01096 }
01097 else
01098 {
01099 for(Int32 i = numIntersections-1; i >=0 ; i--)
01100 {
01101 slice.setVertex(vecIntersectionsSorted[i]);
01102 }
01103 }
01104
01105 slice.setNormal(sliceDir);
01106
01107
01108
01109
01110 clippedSlice.numPerVertexData = 0;
01111
01112
01113 clippedSlice.orientation = DVRRenderSlice::UNDEFINED;
01114
01115
01116 if(clipObjects->getDoContours())
01117 {
01118 deactivateTexture(action);
01119 clipper->clipSlice(volume,
01120 slice,
01121 sliceDir,
01122 fSliceDistance * nSlice,
01123 clippedSlice);
01124 activateTexture(action);
01125 }
01126 else if (shader->hasRenderCallback())
01127 {
01128
01129
01130 clippedSlice.directRender = false;
01131
01132 clipper->clipSlice(volume, slice,
01133 sliceDir,
01134 fSliceDistance * nSlice,
01135 clippedSlice);
01136
01137 shader->renderSlice(volume, action, &clippedSlice);
01138 }
01139 else if (volume->getDoTextures())
01140 {
01141
01142
01143 clippedSlice.directRender = true;
01144
01145 clipper->clipSlice(volume,
01146 slice,
01147 sliceDir,
01148 fSliceDistance * nSlice,
01149 clippedSlice);
01150 }
01151 else
01152 {
01153
01154
01155 glColor4f(1.0, 1.0, 1.0, 1.0);
01156
01157 clippedSlice.directRender = true;
01158
01159 clipper->clipSlice(volume,
01160 slice,
01161 sliceDir,
01162 fSliceDistance * nSlice,
01163 clippedSlice);
01164 }
01165 clippedSlice.clear();
01166 }
01167 else
01168 {
01169
01170
01171 if(shader->hasRenderCallback())
01172 {
01173
01174
01175
01176
01177 Real32 data[12 * 6];
01178 UInt32 index = 0;
01179
01180 for(Int32 i = 0; i < numIntersections; i++)
01181 {
01182 v = vecIntersectionsSorted[i];
01183
01184 data[index++] = v[0];
01185 data[index++] = v[1];
01186 data[index++] = v[2];
01187
01188 data[index++] = v[0] * texscale[0] + textrans[0];
01189 data[index++] = v[1] * texscale[1] + textrans[1];
01190 data[index++] = v[2] * texscale[2] + textrans[2];
01191 }
01192
01193 shader->renderSlice(volume,
01194 action,
01195 data,
01196 numIntersections,
01197 6);
01198 }
01199 else if (volume->getDoTextures())
01200 {
01201
01202
01203 glBegin(GL_TRIANGLE_FAN);
01204
01205 for(i = 0; i < numIntersections; i++)
01206 {
01207 v = vecIntersectionsSorted[i];
01208
01209 glColor4f(1.0, 1.0, 1.0, fAlphaCorrect);
01210
01211 glTexCoord3f((v[0] * texscale[0] + textrans[0]),
01212 (v[1] * texscale[1] + textrans[1]) ,
01213 (v[2] * texscale[2] + textrans[2]));
01214 glVertex3fv(v.getValues());
01215
01216 FDEBUG(
01217 ("Brick::render3DSlices V: %f %f %f T: %f %f %f\n",
01218 v[0], v[1], v[2],
01219 (v[0] * texscale[0] + textrans[0]),
01220 (v[1] * texscale[1] + textrans[1]),
01221 (v[2] * texscale[2] + textrans[2])));
01222 }
01223
01224 glEnd();
01225
01226 }
01227 else
01228 {
01229
01230
01231 glColor4f(1.0, 1.0, 1.0, 1.0);
01232
01233 glBegin(GL_LINE_LOOP);
01234 {
01235 for(i = 0; i < numIntersections; i++)
01236 {
01237 v = vecIntersectionsSorted[i];
01238
01239 glVertex3fv(v.getValues());
01240 }
01241 }
01242 glEnd();
01243 }
01244 }
01245 }
01246
01247
01248 planeSlice.offset(fSliceDistance);
01249 }
01250 }
01251
01252
01253 void Brick::render2DSliceXY(DVRVolume *volume,
01254 DrawActionBase *action,
01255 DVRShaderPtr shader,
01256 DVRClipper *clipper,
01257 const Vec3f &sliceDir,
01258 const Real32 &zCoord)
01259 {
01260 Real32 xmin = vertex[0][0];
01261 Real32 xmax = vertex[1][0];
01262
01263 Real32 ymin = vertex[0][1];
01264 Real32 ymax = vertex[2][1];
01265
01266
01267 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume,
01268 DVRClipObjects);
01269
01270
01271 bool doClipping = false;
01272 if(clipObjects != NullFC)
01273 {
01274 if(clipObjects->count() > 0 &&
01275 clipObjects->getClipMode() != DVRClipObjects::Off)
01276 {
01277 doClipping = true;
01278 }
01279 }
01280
01281 if(doClipping)
01282 {
01283 slice.resetSlice();
01284
01285 if(sliceDir[2] > 0.0)
01286 {
01287 slice.setVertex(Vec3f(xmin, ymin, zCoord));
01288 slice.setVertex(Vec3f(xmax, ymin, zCoord));
01289 slice.setVertex(Vec3f(xmax, ymax, zCoord));
01290 slice.setVertex(Vec3f(xmin, ymax, zCoord));
01291 }
01292 else
01293 {
01294 slice.setVertex(Vec3f(xmin, ymax, zCoord));
01295 slice.setVertex(Vec3f(xmax, ymax, zCoord));
01296 slice.setVertex(Vec3f(xmax, ymin, zCoord));
01297 slice.setVertex(Vec3f(xmin, ymin, zCoord));
01298 }
01299
01300 slice.setNormal(sliceDir);
01301
01302 Real32 dist = clipper->getReferencePlane().distance(
01303 Pnt3f(center[0], center[1], zCoord));
01304
01305 FDEBUG(("Brick - dist to refPlane: %f\n",dist))
01306 FDEBUG(("Brick - Brick center: %f\n",zCoord))
01307
01308
01309 if(clipObjects->getDoContours())
01310 {
01311 deactivateTexture(action);
01312
01313 clipper->clipSlice(volume,
01314 slice,
01315 sliceDir,
01316 dist,
01317 clippedSlice);
01318
01319 activateTexture(action);
01320 }
01321 else if (shader->hasRenderCallback())
01322 {
01323
01324
01325 clippedSlice.directRender = false;
01326
01327 clipper->clipSlice(volume,
01328 slice,
01329 sliceDir,
01330 dist,
01331 clippedSlice);
01332
01333 shader->renderSlice(volume, action, &clippedSlice);
01334 }
01335 else if(volume->getDoTextures())
01336 {
01337
01338
01339 clippedSlice.directRender = true;
01340
01341 clipper->clipSlice(volume, slice,
01342 sliceDir,dist,
01343 clippedSlice);
01344 }
01345 else
01346 {
01347
01348
01349 glColor4f(1.0, 1.0, 1.0, 1.0);
01350
01351 clippedSlice.directRender = true;
01352
01353 clipper->clipSlice(volume,
01354 slice,
01355 sliceDir,
01356 dist,
01357 clippedSlice);
01358 }
01359 clippedSlice.clear();
01360 }
01361 else
01362 {
01363
01364
01365 if((shader != NullFC) && shader->hasRenderCallback())
01366 {
01367
01368 }
01369 else if(volume->getDoTextures())
01370 {
01371 glBegin(GL_TRIANGLE_FAN);
01372 }
01373 else
01374 {
01375 glColor4f(1.0, 1.0, 1.0, 1.0);
01376 glBegin(GL_LINE_LOOP);
01377 }
01378
01379 if((shader != NullFC) && shader->hasRenderCallback())
01380 {
01381
01382
01383 Real32 multiTexIntFactor = zCoord - m_lowerLeft[2];
01384
01385 Real32 data[] =
01386 {
01387 xmin,
01388 ymin,
01389 zCoord,
01390 xmin * texScale[0] + texTranslate[0],
01391 ymin * texScale[1] + texTranslate[1],
01392 multiTexIntFactor,
01393
01394 xmax,
01395 ymin,
01396 zCoord,
01397 xmax * texScale[0] + texTranslate[0],
01398 ymin * texScale[1] + texTranslate[1], multiTexIntFactor,
01399
01400 xmax,
01401 ymax,
01402 zCoord,
01403 xmax * texScale[0] + texTranslate[0],
01404 ymax * texScale[1] + texTranslate[1],
01405 multiTexIntFactor,
01406
01407 xmin,
01408 ymax,
01409 zCoord,
01410 xmin * texScale[0] + texTranslate[0],
01411 ymax * texScale[1] + texTranslate[1],
01412 multiTexIntFactor
01413 };
01414
01415 shader->renderSlice(volume, action, data, 4, 6);
01416
01417 }
01418 else
01419 {
01420 glTexCoord2f(xmin * texScale[0] + texTranslate[0],
01421 ymin * texScale[1] + texTranslate[1]);
01422
01423 glVertex3f(xmin, ymin, zCoord);
01424
01425
01426 glTexCoord2f(xmax * texScale[0] + texTranslate[0],
01427 ymin * texScale[1] + texTranslate[1]);
01428
01429 glVertex3f(xmax, ymin, zCoord);
01430
01431
01432 glTexCoord2f(xmax * texScale[0] + texTranslate[0],
01433 ymax * texScale[1] + texTranslate[1]);
01434
01435 glVertex3f(xmax, ymax, zCoord);
01436
01437
01438 glTexCoord2f(xmin * texScale[0] + texTranslate[0],
01439 ymax * texScale[1] + texTranslate[1]);
01440
01441 glVertex3f(xmin, ymax, zCoord);
01442 }
01443
01444 if((shader != NullFC) && shader->hasRenderCallback())
01445 {
01446
01447 }
01448 else
01449 {
01450 glEnd();
01451 }
01452
01453 }
01454
01455 }
01456
01457 void Brick::render2DSliceXZ(DVRVolume *volume,
01458 DrawActionBase *action,
01459 DVRShaderPtr shader,
01460 DVRClipper *clipper,
01461 const Vec3f &sliceDir,
01462 const Real32 &yCoord)
01463 {
01464 Real32 xmin = vertex[0][0];
01465 Real32 xmax = vertex[1][0];
01466
01467 Real32 zmin = vertex[0][2];
01468 Real32 zmax = vertex[4][2];
01469
01470
01471 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume,
01472 DVRClipObjects);
01473
01474
01475 bool doClipping = false;
01476 if(clipObjects != NullFC)
01477 {
01478 if(clipObjects->count() > 0 &&
01479 clipObjects->getClipMode() != DVRClipObjects::Off)
01480 {
01481 doClipping = true;
01482 }
01483 }
01484
01485 if(doClipping)
01486 {
01487 slice.resetSlice();
01488
01489 if(sliceDir[1] < 0.0)
01490 {
01491 slice.setVertex(Vec3f(xmin, yCoord, zmin));
01492 slice.setVertex(Vec3f(xmax, yCoord, zmin));
01493 slice.setVertex(Vec3f(xmax, yCoord, zmax));
01494 slice.setVertex(Vec3f(xmin, yCoord, zmax));
01495 }
01496 else
01497 {
01498 slice.setVertex(Vec3f(xmin, yCoord, zmax));
01499 slice.setVertex(Vec3f(xmax, yCoord, zmax));
01500 slice.setVertex(Vec3f(xmax, yCoord, zmin));
01501 slice.setVertex(Vec3f(xmin, yCoord, zmin));
01502 }
01503
01504 slice.setNormal(sliceDir);
01505
01506 Real32 dist = clipper->getReferencePlane().distance(
01507 Pnt3f(center[0], yCoord, center[2]));
01508
01509 FDEBUG(("Brick - dist to refPlane: %f\n",dist))
01510 FDEBUG(("Brick - Brick center: %f\n",yCoord))
01511
01512
01513 if(clipObjects->getDoContours())
01514 {
01515 deactivateTexture(action);
01516
01517 clipper->clipSlice(volume,
01518 slice,
01519 sliceDir,
01520 dist,
01521 clippedSlice);
01522
01523 activateTexture(action);
01524 }
01525 else if(shader->hasRenderCallback())
01526 {
01527
01528
01529 clippedSlice.directRender = false;
01530
01531 clipper->clipSlice(volume,
01532 slice,
01533 sliceDir,
01534 dist,
01535 clippedSlice);
01536
01537 shader->renderSlice(volume, action, &clippedSlice);
01538 }
01539 else if(volume->getDoTextures())
01540 {
01541
01542
01543 clippedSlice.directRender = true;
01544
01545 clipper->clipSlice(volume,
01546 slice,
01547 sliceDir,
01548 dist,
01549 clippedSlice);
01550 }
01551 else
01552 {
01553
01554
01555 glColor4f(1.0, 1.0, 1.0, 1.0);
01556
01557 clippedSlice.directRender = true;
01558
01559 clipper->clipSlice(volume,
01560 slice,
01561 sliceDir,
01562 dist,
01563 clippedSlice);
01564 }
01565 clippedSlice.clear();
01566 }
01567 else
01568 {
01569
01570
01571 if((shader != NullFC) && shader->hasRenderCallback())
01572 {
01573
01574 }
01575 else if(volume->getDoTextures())
01576 {
01577 glBegin(GL_TRIANGLE_FAN);
01578 }
01579 else
01580 {
01581 glColor4f(1.0, 1.0, 1.0, 1.0);
01582
01583 glBegin(GL_LINE_LOOP);
01584 }
01585
01586 if((shader != NullFC) && shader->hasRenderCallback())
01587 {
01588
01589
01590 Real32 multiTexIntFactor = yCoord - m_lowerLeft[1];
01591
01592 Real32 data[] =
01593 {
01594 xmin,
01595 yCoord,
01596 zmin,
01597 xmin * texScale[0] + texTranslate[0],
01598 zmin * texScale[2] + texTranslate[2],
01599 multiTexIntFactor,
01600
01601 xmax,
01602 yCoord,
01603 zmin,
01604 xmax * texScale[0] + texTranslate[0],
01605 zmin * texScale[2] + texTranslate[2],
01606 multiTexIntFactor,
01607
01608 xmax,
01609 yCoord,
01610 zmax,
01611 xmax * texScale[0] + texTranslate[0],
01612 zmax * texScale[2] + texTranslate[2],
01613 multiTexIntFactor,
01614
01615 xmin,
01616 yCoord,
01617 zmax,
01618 xmin * texScale[0] + texTranslate[0],
01619 zmax * texScale[2] + texTranslate[2],
01620 multiTexIntFactor
01621 };
01622
01623 shader->renderSlice(volume, action, data, 4, 6);
01624 }
01625 else
01626 {
01627 FDEBUG(("XZ render2dslice (texcoor): %f %f\n",
01628 xmin * texScale[0] + texTranslate[0],
01629 zmin * texScale[2] + texTranslate[2]));
01630
01631 glTexCoord2f(xmin * texScale[0] + texTranslate[0],
01632 zmin * texScale[2] + texTranslate[2]);
01633
01634 glVertex3f(xmin, yCoord, zmin);
01635
01636
01637 glTexCoord2f(xmax * texScale[0] + texTranslate[0],
01638 zmin * texScale[2] + texTranslate[2]);
01639
01640 glVertex3f(xmax, yCoord, zmin);
01641
01642
01643 glTexCoord2f(xmax * texScale[0] + texTranslate[0],
01644 zmax * texScale[2] + texTranslate[2]);
01645
01646 glVertex3f(xmax, yCoord, zmax);
01647
01648
01649 glTexCoord2f(xmin * texScale[0] + texTranslate[0],
01650 zmax * texScale[2] + texTranslate[2]);
01651
01652 glVertex3f(xmin, yCoord, zmax);
01653 }
01654
01655 if((shader != NullFC) && shader->hasRenderCallback())
01656 {
01657
01658 }
01659 else
01660 {
01661 glEnd();
01662 }
01663 }
01664 }
01665
01666 void Brick::render2DSliceYZ(DVRVolume *volume,
01667 DrawActionBase *action,
01668 DVRShaderPtr shader,
01669 DVRClipper *clipper,
01670 const Vec3f &sliceDir,
01671 const Real32 &xCoord)
01672 {
01673 Real32 ymin = vertex[0][1];
01674 Real32 ymax = vertex[2][1];
01675
01676 Real32 zmin = vertex[0][2];
01677 Real32 zmax = vertex[4][2];
01678
01679
01680 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume,
01681 DVRClipObjects);
01682
01683
01684 bool doClipping = false;
01685
01686 if(clipObjects != NullFC)
01687 {
01688 if(clipObjects->count() > 0 &&
01689 clipObjects->getClipMode() != DVRClipObjects::Off)
01690 {
01691 doClipping = true;
01692 }
01693 }
01694
01695 if(doClipping)
01696 {
01697
01698 slice.resetSlice();
01699
01700 if(sliceDir[0] > 0.0)
01701 {
01702 slice.setVertex(Vec3f(xCoord, ymin, zmin));
01703 slice.setVertex(Vec3f(xCoord, ymax, zmin));
01704 slice.setVertex(Vec3f(xCoord, ymax, zmax));
01705 slice.setVertex(Vec3f(xCoord, ymin, zmax));
01706 }
01707 else
01708 {
01709 slice.setVertex(Vec3f(xCoord, ymin, zmax));
01710 slice.setVertex(Vec3f(xCoord, ymax, zmax));
01711 slice.setVertex(Vec3f(xCoord, ymax, zmin));
01712 slice.setVertex(Vec3f(xCoord, ymin, zmin));
01713 }
01714
01715 slice.setNormal(sliceDir);
01716
01717 Real32 dist = clipper->getReferencePlane().distance(
01718 Pnt3f(xCoord,center[1],center[2]));
01719
01720 FDEBUG(("Brick - dist to refPlane: %f\n",dist))
01721 FDEBUG(("Brick - Brick center: %f\n",xCoord))
01722
01723
01724 if(clipObjects->getDoContours())
01725 {
01726 deactivateTexture(action);
01727
01728 clipper->clipSlice(volume,
01729 slice,
01730 sliceDir,
01731 dist,
01732 clippedSlice);
01733
01734 activateTexture(action);
01735 }
01736 else if(shader->hasRenderCallback())
01737 {
01738
01739
01740 clippedSlice.directRender = false;
01741
01742 clipper->clipSlice(volume,
01743 slice,
01744 sliceDir,
01745 dist,
01746 clippedSlice);
01747
01748 shader->renderSlice(volume, action, &clippedSlice);
01749
01750 }
01751 else if (volume->getDoTextures())
01752 {
01753
01754
01755 clippedSlice.directRender = true;
01756
01757 clipper->clipSlice(volume,
01758 slice,
01759 sliceDir,
01760 dist,
01761 clippedSlice);
01762 }
01763 else
01764 {
01765
01766
01767 glColor4f(1.0, 1.0, 1.0, 1.0);
01768
01769 clippedSlice.directRender = true;
01770
01771 clipper->clipSlice(volume,
01772 slice,
01773 sliceDir,
01774 dist,
01775 clippedSlice);
01776 }
01777 clippedSlice.clear();
01778 }
01779 else
01780 {
01781
01782
01783 if((shader != NullFC) && shader->hasRenderCallback())
01784 {
01785
01786 }
01787 else if (volume->getDoTextures())
01788 {
01789 glBegin(GL_TRIANGLE_FAN);
01790 }
01791 else
01792 {
01793 glColor4f(1.0, 1.0, 1.0, 1.0);
01794
01795 glBegin(GL_LINE_LOOP);
01796 }
01797
01798 if((shader != NullFC) && shader->hasRenderCallback())
01799 {
01800
01801
01802 Real32 multiTexIntFactor = xCoord - m_lowerLeft[0];
01803
01804 Real32 data[] =
01805 {
01806 xCoord,
01807 ymin,
01808 zmin,
01809 ymin * texScale[1] + texTranslate[1],
01810 zmin * texScale[2] + texTranslate[2],
01811 multiTexIntFactor,
01812
01813 xCoord,
01814 ymax,
01815 zmin,
01816 ymax * texScale[1] + texTranslate[1],
01817 zmin * texScale[2] + texTranslate[2],
01818 multiTexIntFactor,
01819
01820 xCoord,
01821 ymax,
01822 zmax,
01823 ymax * texScale[1] + texTranslate[1],
01824 zmax * texScale[2] + texTranslate[2],
01825 multiTexIntFactor,
01826
01827 xCoord,
01828 ymin,
01829 zmax,
01830 ymin * texScale[1] + texTranslate[1],
01831 zmax * texScale[2] + texTranslate[2],
01832 multiTexIntFactor
01833 };
01834
01835 shader->renderSlice(volume, action, data, 4, 6);
01836 }
01837 else
01838 {
01839 glTexCoord2f(ymin * texScale[1] + texTranslate[1],
01840 zmin * texScale[2] + texTranslate[2]);
01841
01842 glVertex3f(xCoord, ymin, zmin);
01843
01844
01845 glTexCoord2f(ymax * texScale[1] + texTranslate[1],
01846 zmin * texScale[2] + texTranslate[2]);
01847
01848 glVertex3f(xCoord, ymax, zmin);
01849
01850
01851 glTexCoord2f(ymax * texScale[1] + texTranslate[1],
01852 zmax * texScale[2] + texTranslate[2]);
01853
01854 glVertex3f(xCoord, ymax, zmax);
01855
01856
01857 glTexCoord2f(ymin * texScale[1] + texTranslate[1],
01858 zmax * texScale[2] + texTranslate[2]);
01859
01860 glVertex3f(xCoord, ymin, zmax);
01861 }
01862
01863 if((shader != NullFC) && shader->hasRenderCallback())
01864 {
01865
01866 }
01867 else
01868 {
01869 glEnd();
01870 }
01871 }
01872 }
01873
01874
01875 void Brick::render2DSlices(DVRVolume *volume,
01876 DrawActionBase *action,
01877 DVRShaderPtr shader,
01878 DVRClipper *clipper,
01879 const Vec3f &sliceDir)
01880 {
01881
01882
01883
01884 clippedSlice.numPerVertexData = 0;
01885
01886 slice.setTextureTransform(texScale,texTranslate);
01887
01888 switch(m_ori)
01889 {
01890 case BrickSet::XY:
01891 clippedSlice.orientation = DVRRenderSlice::XY;
01892 render2DSliceXY(volume,
01893 action,
01894 shader,
01895 clipper,
01896 sliceDir,
01897 center[2]);
01898 break;
01899
01900 case BrickSet::XZ:
01901 clippedSlice.orientation = DVRRenderSlice::XZ;
01902 render2DSliceXZ(volume,
01903 action,
01904 shader,
01905 clipper,
01906 sliceDir,
01907 center[1]);
01908 break;
01909
01910 case BrickSet::YZ:
01911 clippedSlice.orientation = DVRRenderSlice::YZ;
01912 render2DSliceYZ(volume,
01913 action,
01914 shader,
01915 clipper,
01916 sliceDir,
01917 center[0]);
01918 break;
01919
01920 default:
01921 break;
01922 }
01923 }
01924
01925
01927 void Brick::render2DMultiSlices(DVRVolume *volume,
01928 DrawActionBase *action,
01929 DVRShaderPtr shader,
01930 DVRClipper *clipper,
01931 bool btf,
01932 const Vec3f &sliceDir)
01933 {
01934 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(volume, DVRVolumeTexture);
01935
01936 if(tex == NullFC)
01937 return;
01938
01939 Vec3f res = tex->getResolution();
01940 Vec3f vox = tex->getSliceThickness();
01941
01942 Real32 fSampleRate = volume->getSampling();
01943
01944 Int32 dim = 2 - m_ori;
01945
01946 Real32 numSlices = res[dim] * fSampleRate;
01947
01948
01949 Real32 anchor = (-res[dim] / 2.0f + 0.5f) * vox[dim];
01950 Real32 dist = vox[dim] / fSampleRate;
01951
01952 if(btf)
01953 {
01954 SINFO << "Brick::render2DMultiSlices - BTF" << std::endl;
01955
01956 anchor = -anchor;
01957 dist = -dist;
01958 }
01959
01960 FDEBUG(("Brick::render2DMultiSlices - ori: %d", m_ori));
01961 FDEBUG(("Brick::render2DMultiSlices - numSlices: %d", numSlices));
01962
01963
01964
01965
01966 clippedSlice.numPerVertexData = 0;
01967
01968 Vec3f multiTexScale = texScale;
01969 Vec3f multiTexTranslate = texTranslate;
01970
01971 switch(m_ori)
01972 {
01973 case BrickSet::XY:
01974
01975 clippedSlice.orientation = DVRRenderSlice::XY;
01976
01977
01978
01979 multiTexScale[2] = 0.0;
01980
01981 for(UInt32 nSlice = 0; nSlice < numSlices; nSlice++)
01982 {
01983 if((anchor >= m_lowerLeft[2]) && (anchor < m_upperRight[2]))
01984 {
01985 FDEBUG(("Slice %d: %f\n", nSlice, anchor));
01986
01987 multiTexTranslate[2] = anchor - m_lowerLeft[2];
01988
01989 slice.setTextureTransform(multiTexScale,multiTexTranslate);
01990
01991 render2DSliceXY(volume,
01992 action,
01993 shader,
01994 clipper,
01995 sliceDir,
01996 anchor);
01997 }
01998
01999
02000 anchor += dist;
02001 }
02002 break;
02003
02004 case BrickSet::XZ:
02005
02006 clippedSlice.orientation = DVRRenderSlice::XZ;
02007
02008 multiTexScale[1] = 0.0;
02009
02010 for(UInt32 nSlice = 0; nSlice < numSlices; nSlice++)
02011 {
02012 if((anchor >= m_lowerLeft[1]) && (anchor < m_upperRight[1]))
02013 {
02014 FDEBUG(("Slice %d: %f\n", nSlice, anchor));
02015
02016
02017
02018 multiTexTranslate[1] = anchor - m_lowerLeft[1];
02019
02020 slice.setTextureTransform(multiTexScale,multiTexTranslate);
02021
02022 render2DSliceXZ(volume,
02023 action,
02024 shader,
02025 clipper,
02026 sliceDir,
02027 anchor);
02028 }
02029
02030 anchor += dist;
02031 }
02032 break;
02033
02034 case BrickSet::YZ:
02035
02036 clippedSlice.orientation = DVRRenderSlice::YZ;
02037
02038 multiTexScale[0] = 0.0;
02039
02040 for(UInt32 nSlice = 0; nSlice < numSlices; nSlice++)
02041 {
02042 if((anchor >= m_lowerLeft[0]) && (anchor < m_upperRight[0]))
02043 {
02044 FDEBUG(("Slice %d: %f\n", nSlice, anchor));
02045
02046
02047
02048 multiTexTranslate[0] = anchor - m_lowerLeft[0];
02049
02050 slice.setTextureTransform(multiTexScale,multiTexTranslate);
02051
02052 render2DSliceYZ(volume,
02053 action,
02054 shader,
02055 clipper,
02056 sliceDir,
02057 anchor);
02058 }
02059
02060
02061 anchor += dist;
02062 }
02063 break;
02064
02065 default:
02066 break;
02067 }
02068 }
02069
02070 OSG_END_NAMESPACE
02071
02072