Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

vpslice.cpp

Go to the documentation of this file.
00001 
00002 //
00003 //  PROJECT.....: vpat - Creating Virtual Patients
00004 //  RESPONSIBLE.: Carla Freitas e Luciana Nedel
00005 //
00006 //  FILE........: vpslice.cpp
00007 //  DESCRIPTION.: Contain the VPSlice class implementation.
00008 //
00009 //  AUTHOR......: Isabel Harb Manssour
00010 //  DATE........: October/04/2000
00011 //  DESCRIPTION.: Constructors definition and methods implementation.
00012 //
00013 //  AUTHOR......: Isabel Harb Manssour
00014 //  DATE........: June/04/2001
00015 //  DESCRIPTION.: Methods and parameters changes.
00016 //
00017 //  AUTHOR......: Isabel Harb Manssour
00018 //  DATE........: October/25/2001
00019 //  DESCRIPTION.: Update for inner structure visualization.
00020 //
00022 
00023 
00024 #include <vpslice.h>
00025 #include <vpimage.h>
00026 #include <vpvolume.h>
00027 #include <vpplane.h>
00028 #include <cmath>
00029 #include <list>
00030 using namespace std;
00031 
00032 
00034 // Description: Class "VPSlice" constructor without parameter. 
00035 // Parameters.: -
00036 // Return.....: -
00037 
00038 VPSlice::VPSlice () {
00039     lineSBand = NULL;
00040     lineTBand = NULL;
00041     numTotalPoints = 0;
00042 }
00043 
00044 
00046 // Description: Class "VPSlice" destructor. 
00047 // Parameters.: -
00048 // Return.....: -
00049 
00050 VPSlice::~VPSlice () {
00051     if (lineSBand != NULL) {
00052         delete [] lineSBand;
00053         delete [] lineTBand;
00054     }
00055 }
00056 
00057 
00059 // Description: Method "vpTopSliceRender" implement the algorithm 
00060 //              to visualize one volume slice from the top.
00061 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00062 //              int sliceNumber, unsigned int image[][256] (pointer 
00063 //              to the image);
00064 // Return.....: -
00065 
00066 void VPSlice::vpTopSliceRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int **image) {
00067  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00068      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00069      imageXdelta=0, imageYdelta=0, whiteLine=0, whiteColumn=0;
00070  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0;
00071 
00072  VPPoint2D winTopRightValue;
00073  VPVector3D projectionDirection, vectorH, vectorV, deltaX, deltaY, up;
00074  VPPoint3D p1, minPlaneProjection; 
00075 
00076  // Set pointer to the volume object
00077  VPGraphicObj *volume = v;
00078 
00079  // Set a pointer to the right camera
00080  VPCamera *camera = c;
00081 
00082  VPPoint3D location = camera->vpGetLocation();
00083  VPPoint3D target = camera->vpGetTarget();
00084                 
00085  // Set projection direction by the vector
00086  projectionDirection.vpSetVector3D(target - location);
00087  projectionDirection.vpNormalize();
00088 
00089  // winTopRightValue has the projection plane size (x,y)
00090  winTopRightValue = camera->vpGetWinTopRight();
00091 
00092  // Set "h" and "v" vectors 
00093  up = camera->vpGetUp();
00094  vectorH = up.vpCrossProduct(projectionDirection);
00095  vectorV = vectorH.vpCrossProduct(projectionDirection);
00096 
00097  // Set scan window corner (where the scan begin)
00098  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00099  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00100 
00101  // Set variables to determine the end of the view scan
00102  finalLineValue = camera->vpGetViewHeight();
00103  finalColumnValue = camera->vpGetViewWidth();
00104 
00105  // To verify the ratio between the window and the view
00106  // greater window dimension / view dimension (where viewx=viewy)
00107  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00108     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00109     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00110     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00111  }
00112  else {
00113     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00114     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00115     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00116  }
00117 
00118  // Window/Viewport ratio
00119  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
00120  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00121 
00122  // Line, column and sample step 
00123  deltaX = vectorH * ratioX;
00124  deltaY = vectorV * ratioY;
00125  deltaZ = projectionDirection.vpModule();
00126 
00127   // Scan view line for the ray tracing 
00128   for (line=0; line<finalLineValue; line++) { 
00129 
00130      // Plane point computation
00131      p1 = minPlaneProjection;
00132      p1 = p1 + deltaY * line; 
00133 
00134      // Scan view column
00135      for (column=0; column<finalColumnValue; column++) {
00136 
00137         i = (int) (p1.vpGetX()); //(column);
00138         j = sliceNumber;         //(line);
00139         k = (int) (p1.vpGetZ()); //(depth);
00140 
00141         p1.vpSetY(sliceNumber);
00142         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
00143 
00144         image[line+imageYdelta][column+imageXdelta] = (unsigned int) voxelColor;
00145 
00146         // Next plane point computation
00147         p1 = p1 + deltaX; 
00148 
00149     } // for (column)
00150 
00151  } // for (line)
00152 
00153 }
00154 
00155 
00157 // Description: Method "vpSideSliceRender" implement the algorithm 
00158 //              to visualize one volume slice from the side.
00159 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00160 //              int sliceNumber, unsigned int image[][256] (pointer 
00161 //              to the image);
00162 // Return.....: -
00163 
00164 void VPSlice::vpSideSliceRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int **image) {
00165  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00166      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00167      imageXdelta=0, imageYdelta=0, virtualYDimension=0;
00168  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, yCorrection=0;
00169 
00170  VPPoint2D winTopRightValue;
00171  VPVector3D projectionDirection, vectorH, vectorV, deltaX, deltaY, up;
00172  VPPoint3D p1, minPlaneProjection; 
00173 
00174  // Set pointer to the volume object
00175  VPGraphicObj *volume = v;
00176 
00177  // Set a pointer to the right camera
00178  VPCamera *camera = c;
00179 
00180  VPPoint3D location = camera->vpGetLocation();
00181  VPPoint3D target = camera->vpGetTarget();
00182                 
00183  // Set projection direction by the vector
00184  projectionDirection.vpSetVector3D(target - location);
00185  projectionDirection.vpNormalize();
00186 
00187  // winTopRightValue has the projection plane size (x,y)
00188  winTopRightValue = camera->vpGetWinTopRight();
00189 
00190  // Set "h" and "v" vectors 
00191  up = camera->vpGetUp();
00192  vectorH = up.vpCrossProduct(projectionDirection);
00193  vectorV = vectorH.vpCrossProduct(projectionDirection);
00194 
00195  // Set scan window corner (where the scan begin)
00196  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00197  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00198 
00199  // Set variables to determine the end of the view scan
00200  finalLineValue = camera->vpGetViewHeight();
00201  finalColumnValue = camera->vpGetViewWidth();
00202 
00203  // To verify the ratio between the window and the view
00204  // greater window dimension / view dimension (where viewx=viewy)
00205  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00206     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00207     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00208     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00209  }
00210  else {
00211     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00212     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00213     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00214  }
00215 
00216  // To verify the smallest dimension and set the virtualVolumeDimension
00217  if ( ((VPImage *)volume)->vpGetXDimension() < ((VPVolume *)volume)->vpGetZDimension() )
00218     virtualYDimension = ((VPVolume *)volume)->vpGetZDimension();
00219  else 
00220     virtualYDimension = ((VPImage *)volume)->vpGetXDimension(); 
00221  yCorrection = ((float) ((VPImage *)volume)->vpGetYDimension()) / ((float) virtualYDimension);
00222 
00223  // Window/Viewport ratio
00224  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
00225  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00226 
00227  // Line, column and sample step 
00228  deltaX = vectorH * ratioX;
00229  deltaY = vectorV * ratioY;
00230  deltaZ = projectionDirection.vpModule();
00231 
00232   // Scan view line for the ray tracing 
00233   for (line=0; line<finalLineValue; line++) { 
00234 
00235      // Plane point computation
00236      p1 = minPlaneProjection;
00237      p1 = p1 + deltaY * line; 
00238      p1.y = p1.y*yCorrection;
00239 
00240      // Scan view column
00241      for (column=0; column<finalColumnValue; column++) {
00242 
00243         i = sliceNumber;        //(column);
00244         j = (int) (p1.vpGetY());//(line);
00245         k = (int) (p1.vpGetZ());//(depth);
00246 
00247         p1.vpSetX(sliceNumber);
00248         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
00249 
00250         image[line+imageYdelta][column+imageXdelta] = (unsigned int) voxelColor;
00251 
00252         // Next plane point computation
00253         p1 = p1 + deltaX; 
00254 
00255     } // for (column)
00256 
00257  } // for (line)
00258 
00259 }
00260 
00261 
00263 // Description: Method "vpFrontSliceRender" implement the algorithm 
00264 //              to visualize one volume slice from the front.
00265 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00266 //              int sliceNumber, unsigned int image[][256] (pointer 
00267 //              to the image);
00268 // Return.....: -
00269 
00270 void VPSlice::vpFrontSliceRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int **image) {
00271  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00272      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00273      imageXdelta=0, imageYdelta=0, virtualYDimension=0;
00274  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, yCorrection=0;
00275 
00276  VPPoint2D winTopRightValue;
00277  VPVector3D projectionDirection, vectorH, vectorV, deltaX, deltaY, up;
00278  VPPoint3D p1, minPlaneProjection; 
00279 
00280  // Set pointer to the volume object
00281  VPGraphicObj *volume = v;
00282 
00283  // Set a pointer to the right camera
00284  VPCamera *camera = c;
00285 
00286  VPPoint3D location = camera->vpGetLocation();
00287  VPPoint3D target = camera->vpGetTarget();
00288 
00289  // Set projection direction by the vector
00290  projectionDirection.vpSetVector3D(target - location);
00291  projectionDirection.vpNormalize();
00292 
00293  // winTopRightValue has the projection plane size (x,y)
00294  winTopRightValue = camera->vpGetWinTopRight();
00295 
00296  // Set "h" and "v" vectors 
00297  up = camera->vpGetUp();
00298  vectorH = projectionDirection.vpCrossProduct(up);
00299  vectorV = projectionDirection.vpCrossProduct(vectorH);
00300 
00301  // Set scan window corner (where the scan begin)
00302  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00303  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00304 
00305  // Set variables to determine the end of the view scan
00306  finalLineValue = camera->vpGetViewHeight();
00307  finalColumnValue = camera->vpGetViewWidth();
00308 
00309  // To verify the ratio between the window and the view
00310  // greater window dimension / view dimension (where viewx=viewy)
00311   if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00312     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00313     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00314     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00315  }
00316  else {
00317     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00318     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00319     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00320  }
00321 
00322  // To verify the smallest dimension and set the virtualVolumeDimension
00323  if ( ((VPImage *)volume)->vpGetXDimension() < ((VPVolume *)volume)->vpGetZDimension() )
00324     virtualYDimension = ((VPVolume *)volume)->vpGetZDimension();
00325  else 
00326     virtualYDimension = ((VPImage *)volume)->vpGetXDimension(); 
00327  yCorrection = ((float) ((VPImage *)volume)->vpGetYDimension()) / ((float) virtualYDimension);
00328 
00329  // Window/Viewport ratio
00330  ratioX = winTopRightValue.vpGetX()/finalColumnValue;
00331  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00332 
00333  // Line, column and sample step 
00334  deltaX = vectorH * ratioX;
00335  deltaY = vectorV * ratioY;
00336  deltaZ = projectionDirection.vpModule();
00337 
00338   // Scan view line for the ray tracing 
00339   for (line=0; line<finalLineValue; line++) { 
00340 
00341      // Plane point computation
00342      p1 = minPlaneProjection;
00343      p1 = p1 + deltaY * line; 
00344      p1.y = p1.y*yCorrection;
00345 
00346      // Scan view column
00347      for (column=0; column<finalColumnValue; column++) {
00348 
00349         i = (int) (p1.vpGetX());//(column);
00350         j = (int) (p1.vpGetY());//(line);
00351         k = sliceNumber;        //(depth);
00352 
00353         p1.vpSetZ(sliceNumber);
00354         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
00355 
00356         image[line+imageYdelta][column+imageXdelta] = (unsigned int) voxelColor;
00357 
00358         // Next plane point computation
00359         p1 = p1 + deltaX; 
00360 
00361     } // for (column)
00362 
00363  } // for (line)
00364 
00365 }
00366 
00367 
00369 // Description: Method "vpLineTopSliceRender" implement the algorithm 
00370 //              to visualize one volume slice from the top. Lines
00371 //              indicating the position of the other two orthogonal
00372 //              planes are draw in the image.
00373 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00374 //              int sliceNumber, unsigned int image[][256] (pointer 
00375 //              to the image);
00376 // Return.....: -
00377 
00378 void VPSlice::vpLineTopSliceRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int **image) {
00379  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00380      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00381      imageXdelta=0, imageYdelta=0, whiteLine=0, whiteColumn=0;
00382  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0;
00383 
00384  VPPoint2D winTopRightValue;
00385  VPVector3D projectionDirection, vectorH, vectorV, deltaX, deltaY, up;
00386  VPPoint3D p1, minPlaneProjection; 
00387 
00388  // Set pointer to the volume object
00389  VPGraphicObj *volume = v;
00390 
00391  // Set a pointer to the right camera
00392  VPCamera *camera = c;
00393 
00394  VPPoint3D location = camera->vpGetLocation();
00395  VPPoint3D target = camera->vpGetTarget();
00396                 
00397  // Set projection direction by the vector
00398  projectionDirection.vpSetVector3D(target - location);
00399  projectionDirection.vpNormalize();
00400 
00401  // winTopRightValue has the projection plane size (x,y)
00402  winTopRightValue = camera->vpGetWinTopRight();
00403 
00404  // Set "h" and "v" vectors 
00405  up = camera->vpGetUp();
00406  vectorH = up.vpCrossProduct(projectionDirection);
00407  vectorV = vectorH.vpCrossProduct(projectionDirection);
00408 
00409  // Set scan window corner (where the scan begin)
00410  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00411  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00412 
00413  // Set variables to determine the end of the view scan
00414  finalLineValue = camera->vpGetViewHeight();
00415  finalColumnValue = camera->vpGetViewWidth();
00416 
00417  // To verify the ratio between the window and the view
00418  // greater window dimension / view dimension (where viewx=viewy)
00419  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00420     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00421     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00422     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00423  }
00424  else {
00425     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00426     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00427     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00428  }
00429 
00430  // Window/Viewport ratio
00431  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
00432  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00433 
00434  // Line, column and sample step 
00435  deltaX = vectorH * ratioX;
00436  deltaY = vectorV * ratioY;
00437  deltaZ = projectionDirection.vpModule();
00438 
00439  // Other orthogonal planes visualization values
00440  // (goal: put a line in the right position)
00441  int side = ((VPVolume *)volume)->vpGetSideSlice();
00442  int front = ((VPVolume *)volume)->vpGetFrontSlice();
00443  bool sideFlag = true, frontFlag = true;
00444 
00445   // Scan view line for the ray tracing 
00446   for (line=0; line<finalLineValue; line++) { 
00447 
00448      // Plane point computation
00449      p1 = minPlaneProjection;
00450      p1 = p1 + deltaY * line; 
00451 
00452      // Scan view column
00453      for (column=0; column<finalColumnValue; column++) {
00454 
00455         i = (int) (p1.vpGetX()); //(column);
00456         j = sliceNumber;         //(line);
00457         k = (int) (p1.vpGetZ()); //(depth);
00458 
00459         p1.vpSetY(sliceNumber);
00460         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
00461 
00462         if ( ((k<=front+1)&&(k>=front-1)) && frontFlag ) {
00463             frontFlag = false;
00464             front = line+imageYdelta;
00465         }
00466         else if ( ((i<=side+1)&&(i>=side-1)) && sideFlag ) {
00467             sideFlag = false;
00468             side = column+imageXdelta;
00469         }
00470         else
00471             image[line+imageYdelta][column+imageXdelta] = (unsigned int) voxelColor;
00472 
00473         // Next plane point computation
00474         p1 = p1 + deltaX; 
00475 
00476     } // for (column)
00477 
00478  } // for (line)
00479 
00480 
00481   // To draw the line of the other orthogonal planes visualization
00482   finalLineValue = camera->vpGetViewHeight();
00483   for (line=0; line<finalLineValue; line++)
00484     image[line][side] = (unsigned int) 255;
00485 
00486   finalColumnValue = camera->vpGetViewWidth();
00487   for (column=0; column<finalColumnValue; column++)
00488     image[front][column] = (unsigned int) 255;
00489 
00490 }
00491 
00492 
00494 // Description: Method "vpLineSideSliceRender" implement the algorithm 
00495 //              to visualize one volume slice from the side. Lines
00496 //              indicating the position of the other two orthogonal
00497 //              planes are draw in the image.
00498 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00499 //              int sliceNumber, unsigned int image[][256] (pointer 
00500 //              to the image);
00501 // Return.....: -
00502 
00503 void VPSlice::vpLineSideSliceRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int **image) {
00504  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00505      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00506      imageXdelta=0, imageYdelta=0, virtualYDimension=0;
00507  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, yCorrection=0;
00508 
00509  VPPoint2D winTopRightValue;
00510  VPVector3D projectionDirection, vectorH, vectorV, deltaX, deltaY, up;
00511  VPPoint3D p1, minPlaneProjection; 
00512 
00513  // Set pointer to the volume object
00514  VPGraphicObj *volume = v;
00515 
00516  // Set a pointer to the right camera
00517  VPCamera *camera = c;
00518 
00519  VPPoint3D location = camera->vpGetLocation();
00520  VPPoint3D target = camera->vpGetTarget();
00521                 
00522  // Set projection direction by the vector
00523  projectionDirection.vpSetVector3D(target - location);
00524  projectionDirection.vpNormalize();
00525 
00526  // winTopRightValue has the projection plane size (x,y)
00527  winTopRightValue = camera->vpGetWinTopRight();
00528 
00529  // Set "h" and "v" vectors 
00530  up = camera->vpGetUp();
00531  vectorH = up.vpCrossProduct(projectionDirection);
00532  vectorV = vectorH.vpCrossProduct(projectionDirection);
00533 
00534  // Set scan window corner (where the scan begin)
00535  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00536  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00537 
00538  // Set variables to determine the end of the view scan
00539  finalLineValue = camera->vpGetViewHeight();
00540  finalColumnValue = camera->vpGetViewWidth();
00541 
00542  // To verify the ratio between the window and the view
00543  // greater window dimension / view dimension (where viewx=viewy)
00544  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00545     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00546     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00547     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00548  }
00549  else {
00550     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00551     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00552     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00553  }
00554 
00555  // To verify the smallest dimension and set the virtualVolumeDimension
00556  if ( ((VPImage *)volume)->vpGetXDimension() < ((VPVolume *)volume)->vpGetZDimension() )
00557     virtualYDimension = ((VPVolume *)volume)->vpGetZDimension();
00558  else 
00559     virtualYDimension = ((VPImage *)volume)->vpGetXDimension(); 
00560  yCorrection = ((float) ((VPImage *)volume)->vpGetYDimension()) / ((float) virtualYDimension);
00561 
00562  // Window/Viewport ratio
00563  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
00564  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00565 
00566  // Line, column and sample step 
00567  deltaX = vectorH * ratioX;
00568  deltaY = vectorV * ratioY;
00569  deltaZ = projectionDirection.vpModule();
00570 
00571  // Other orthogonal planes visualization values
00572  // (goal: put a line in the right position)
00573  int top = ((VPVolume *)volume)->vpGetTopSlice();
00574  int front = ((VPVolume *)volume)->vpGetFrontSlice();
00575  bool topFlag = true, frontFlag = true;
00576 
00577   // Scan view line for the ray tracing 
00578   for (line=0; line<finalLineValue; line++) { 
00579 
00580      // Plane point computation
00581      p1 = minPlaneProjection;
00582      p1 = p1 + deltaY * line; 
00583      p1.y = p1.y*yCorrection;
00584 
00585      // Scan view column
00586      for (column=0; column<finalColumnValue; column++) {
00587 
00588         i = sliceNumber;        //(column);
00589         j = (int) (p1.vpGetY());//(line);
00590         k = (int) (p1.vpGetZ());//(depth);
00591 
00592         p1.vpSetX(sliceNumber);
00593         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
00594 
00595         if ( ((j<=top+1)&&(j>=top-1)) && topFlag ) {
00596             topFlag = false;
00597             top = line+imageYdelta;
00598         }
00599         else if ( ((k<=front+1)&&(k>=front-1)) && frontFlag ) {
00600             frontFlag = false;
00601             front = column+imageXdelta;
00602         }
00603         else
00604             image[line+imageYdelta][column+imageXdelta] = (unsigned int) voxelColor;
00605 
00606         // Next plane point computation
00607         p1 = p1 + deltaX; 
00608 
00609     } // for (column)
00610 
00611  } // for (line)
00612 
00613 
00614   // To draw the line of the other orthogonal planes visualization
00615   finalLineValue = camera->vpGetViewHeight();
00616   for (line=0; line<finalLineValue; line++)
00617     image[line][front] = (unsigned int) 255;
00618 
00619   finalColumnValue = camera->vpGetViewWidth();
00620   for (column=0; column<finalColumnValue; column++)
00621     image[top][column] = (unsigned int) 255;
00622 
00623 }
00624 
00625 
00627 // Description: Method "vpLineFrontSliceRender" implement the algorithm 
00628 //              to visualize one volume slice from the front. Lines
00629 //              indicating the position of the other two orthogonal
00630 //              planes are draw in the image.
00631 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00632 //              int sliceNumber, unsigned int image[][256] (pointer 
00633 //              to the image);
00634 // Return.....: -
00635 
00636 void VPSlice::vpLineFrontSliceRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int **image) {
00637  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00638      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00639      imageXdelta=0, imageYdelta=0, virtualYDimension=0;
00640  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, yCorrection=0;
00641 
00642  VPPoint2D winTopRightValue;
00643  VPVector3D projectionDirection, vectorH, vectorV, deltaX, deltaY, up;
00644  VPPoint3D p1, minPlaneProjection; 
00645 
00646  // Set pointer to the volume object
00647  VPGraphicObj *volume = v;
00648 
00649  // Set a pointer to the right camera
00650  VPCamera *camera = c;
00651 
00652  VPPoint3D location = camera->vpGetLocation();
00653  VPPoint3D target = camera->vpGetTarget();
00654 
00655  // Set projection direction by the vector
00656  projectionDirection.vpSetVector3D(target - location);
00657  projectionDirection.vpNormalize();
00658 
00659  // winTopRightValue has the projection plane size (x,y)
00660  winTopRightValue = camera->vpGetWinTopRight();
00661 
00662  // Set "h" and "v" vectors 
00663  up = camera->vpGetUp();
00664  vectorH = projectionDirection.vpCrossProduct(up);
00665  vectorV = projectionDirection.vpCrossProduct(vectorH);
00666 
00667  // Set scan window corner (where the scan begin)
00668  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00669  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00670 
00671  // Set variables to determine the end of the view scan
00672  finalLineValue = camera->vpGetViewHeight();
00673  finalColumnValue = camera->vpGetViewWidth();
00674 
00675  // To verify the ratio between the window and the view
00676  // greater window dimension / view dimension (where viewx=viewy)
00677   if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00678     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00679     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00680     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00681  }
00682  else {
00683     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00684     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00685     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00686  }
00687 
00688  // To verify the smallest dimension and set the virtualVolumeDimension
00689  if ( ((VPImage *)volume)->vpGetXDimension() < ((VPVolume *)volume)->vpGetZDimension() )
00690     virtualYDimension = ((VPVolume *)volume)->vpGetZDimension();
00691  else 
00692     virtualYDimension = ((VPImage *)volume)->vpGetXDimension(); 
00693  yCorrection = ((float) ((VPImage *)volume)->vpGetYDimension()) / ((float) virtualYDimension);
00694 
00695  // Window/Viewport ratio
00696  ratioX = winTopRightValue.vpGetX()/finalColumnValue;
00697  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00698 
00699  // Line, column and sample step 
00700  deltaX = vectorH * ratioX;
00701  deltaY = vectorV * ratioY;
00702  deltaZ = projectionDirection.vpModule();
00703 
00704  // Other orthogonal planes visualization values
00705  // (goal: put a line in the right position)
00706  int top = ((VPVolume *)volume)->vpGetTopSlice();
00707  int side = ((VPVolume *)volume)->vpGetSideSlice();
00708  bool topFlag = true, sideFlag = true;
00709 
00710   // Scan view line for the ray tracing 
00711   for (line=0; line<finalLineValue; line++) { 
00712 
00713      // Plane point computation
00714      p1 = minPlaneProjection;
00715      p1 = p1 + deltaY * line; 
00716      p1.y = p1.y*yCorrection;
00717 
00718      // Scan view column
00719      for (column=0; column<finalColumnValue; column++) {
00720 
00721         i = (int) (p1.vpGetX());//(column);
00722         j = (int) (p1.vpGetY());//(line);
00723         k = sliceNumber;        //(depth);
00724 
00725         p1.vpSetZ(sliceNumber);
00726         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
00727 
00728         if ( ((j<=top+1)&&(j>=top-1)) && topFlag ) {
00729             topFlag = false;
00730             top = line+imageYdelta;
00731         }
00732         else if ( ((i<=side+1)&&(i>=side-1)) && sideFlag ) {
00733             sideFlag = false;
00734             side = column+imageXdelta;
00735         }
00736         else
00737             image[line+imageYdelta][column+imageXdelta] = (unsigned int) voxelColor;
00738 
00739         // Next plane point computation
00740         p1 = p1 + deltaX; 
00741 
00742     } // for (column)
00743 
00744  } // for (line)
00745 
00746 
00747   // To draw the line of the other orthogonal planes visualization
00748   finalLineValue = camera->vpGetViewHeight();
00749   for (line=0; line<finalLineValue; line++)
00750     image[line][side] = (unsigned int) 255;
00751 
00752   finalColumnValue = camera->vpGetViewWidth();
00753   for (column=0; column<finalColumnValue; column++)
00754     image[top][column] = (unsigned int) 255;
00755 
00756 }
00757 
00758 
00760 // Description: Method "vpTopInnerStructRender" implement the 
00761 //              algorithm to visualize one volume slice from the 
00762 //              top. Point indicating the position of the end of 
00763 //              S-Band and end of T-Band (used for setting the 
00764 //              inner structures parameters visualization) are draw 
00765 //              in the image.
00766 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
00767 //              int sliceNumber, unsigned int image[][256] (pointer 
00768 //              to the image with colors);
00769 // Return.....: -
00770 
00771 void VPSlice::vpTopInnerStructRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int ***image) {
00772  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
00773      finalLineValue=0, initialColumnValue=0, finalColumnValue=0,
00774      imageXdelta=0, imageYdelta=0, whiteLine=0, whiteColumn=0, cont=0;
00775  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, auxFloat=0;
00776 
00777  VPPoint2D winTopRightValue;
00778  VPVector3D projectionDirection, scanDirection, lineScan, vectorH, vectorV, 
00779             deltaX, deltaY, up(0,1,0), auxUp;
00780  VPPoint3D p1, minPlaneProjection, auxTarget, auxPoint, nextPoint, nextLinePoint; 
00781  
00782  VPGraphicObj *volume = v;  // Set pointer to the volume object
00783 
00784  VPPoint3D volumeCameraLocation = ((VPVolume *)volume)->vpGetCameraLocationForInnerStructure();
00785  
00786  VPCamera *camera = c;  // Set a pointer to the right camera
00787 
00788  VPPoint3D location = camera->vpGetLocation();
00789  VPPoint3D target = camera->vpGetTarget();
00790                 
00791  // Set projection direction by the vector
00792  projectionDirection.vpSetVector3D(target - location);
00793  projectionDirection.vpNormalize();
00794 
00795  // Set scan window direction and line scan (for SBand and TBand lines processing)
00796  auxTarget = target;
00797  scanDirection.vpSetVector3D(auxTarget - volumeCameraLocation);
00798  scanDirection.vpNormalize();
00799  lineScan = scanDirection.vpCrossProduct(up);
00800  scanDirection.y = lineScan.y = 0;
00801 
00802  // winTopRightValue has the projection plane size (x,y)
00803  winTopRightValue = camera->vpGetWinTopRight();
00804 
00805  auxUp = camera->vpGetUp();
00806  vectorH = auxUp.vpCrossProduct(projectionDirection);  // Set "h" vector
00807  vectorV = vectorH.vpCrossProduct(projectionDirection);  // Set "v" vector
00808 
00809  // Set scan window corner (where the scan begin)
00810  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
00811  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
00812 
00813  // Set variables to determine the end of the view scan
00814  finalLineValue = camera->vpGetViewHeight();
00815  finalColumnValue = camera->vpGetViewWidth();
00816 
00817  // To verify the ratio between the window and the view
00818  // greater window dimension / view dimension (where viewx=viewy)
00819  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
00820     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
00821     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
00822     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
00823  }
00824  else {
00825     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
00826     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
00827     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
00828  }
00829 
00830  // Window/Viewport ratio
00831  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
00832  ratioY = winTopRightValue.vpGetY()/finalLineValue;
00833 
00834  // Line, column and sample step 
00835  deltaX = vectorH * ratioX;
00836  deltaY = vectorV * ratioY;
00837  deltaZ = projectionDirection.vpModule();
00838 
00839  
00841  // Inner structures visualization parameters
00842  // Goal: exhibition of two points (end of S-Band and T-Band), 
00843  //       a line that join them, and a line that identify
00844  //       the ROI (where data will be sampled)
00845 
00846  // Necessary variables to set the S-Band and T-Band position in the image
00847  VPPoint3D SBand, TBand, center = ((VPVolume *)volume)->vpGetCenterFocalPoint();  
00848  bool findPoint;
00849  int aux=0, arrayDimension, edgeComparison,
00850      xDimension = ((VPVolume *)volume)->vpGetXDimension(),
00851      zDimension = ((VPVolume *)volume)->vpGetZDimension();
00852  int edge=0, SBandSteps=0, TBandSteps=0;
00853 
00854  // To set arrayDimension (slice diagonal)
00855   arrayDimension = (int) ( sqrt( (xDimension*xDimension) + (zDimension*zDimension) ) / 2.0 + 1.0 );
00856 
00857  // round value
00858  SBand.x = (int) (center.x+0.5);
00859  SBand.y = (int) (center.y+0.5);
00860  SBand.z = ((VPVolume *)volume)->vpGetRayCastingSBand();
00861  TBand.x = (int) (center.x+0.5);
00862  TBand.y = (int) (center.y+0.5);
00863  TBand.z = ((VPVolume *)volume)->vpGetRayCastingTBand();
00864 
00865  // Process the steps between the edge and SBand and between
00866  // SBand and TBand (using the "middle slice")
00867  edge = 0;
00868  while (((VPVolume *)volume)->vpGetValue(SBand.x,SBand.y,edge) <= 40) 
00869      edge++;
00870  SBandSteps = SBand.z - edge;
00871  TBandSteps = TBand.z - SBand.z;        
00872 
00874  // First: find the lineSBand and lineTBand points
00875  numTotalPoints=0;
00876  if (lineSBand != NULL) {
00877     delete [] lineSBand;
00878     delete [] lineTBand;
00879  }
00880  lineSBand = new VPPoint2D [sizeof(VPPoint2D) * arrayDimension];
00881  lineTBand = new VPPoint2D [sizeof(VPPoint2D) * arrayDimension];
00882 
00883  // Find object edge at "SBand column" 
00884  edge = 0;
00885  edgeComparison = 0.8 * zDimension; // 80%
00886  while ( (((VPVolume *)volume)->vpGetValue(SBand.x,sliceNumber,edge) <= 40) && (edge<=edgeComparison) )
00887     edge++;
00888  if ( edge < edgeComparison )
00889     edgeComparison = 1;
00890  else
00891     edgeComparison = 0;
00892  
00893  // For the case of a very dark slice (top or bottom slice)
00894  if ( edgeComparison )
00895  { 
00896      // New SBand and TBand in accordance with scan direction
00897      nextPoint = volumeCameraLocation;
00898      nextPoint.y = sliceNumber;
00899      vpFindPointInsideAxialSlice(nextPoint, scanDirection, xDimension, zDimension);
00900      while ( ((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) <= 40 )
00901         nextPoint = nextPoint + scanDirection;
00902      
00903      SBand = nextPoint;
00904 
00905      for (i=0; i<SBandSteps; i++)
00906          SBand = SBand + scanDirection;
00907         
00908      TBand = SBand;
00909 
00910      for (i=0; i<TBandSteps; i++)
00911          TBand = TBand + scanDirection;
00912         
00913      // round value
00914      SBand.x = (int) (SBand.x+0.5);
00915      SBand.y = (int) (SBand.y+0.5);
00916      SBand.z = (int) (SBand.z+0.5);
00917      TBand.x = (int) (TBand.x+0.5);
00918      TBand.y = (int) (TBand.y+0.5);
00919      TBand.z = (int) (TBand.z+0.5);
00920 
00921      // lineScan to find the positions at scanDirection
00922      // (from the center to left, and from the center to right)
00923      lineSBand[numTotalPoints].x = endOfSBand.x = SBand.x;
00924      lineSBand[numTotalPoints].y = endOfSBand.y = SBand.z;
00925      lineTBand[numTotalPoints].x = endOfTBand.x = TBand.x;          
00926      lineTBand[numTotalPoints].y = endOfTBand.y = TBand.z;
00927      findPoint = true;
00928      numTotalPoints++;
00929 
00930      nextLinePoint = volumeCameraLocation;
00931      nextLinePoint.y = sliceNumber;
00932 
00933      // First, process "right" points
00934      while (findPoint) {
00935         nextLinePoint = nextLinePoint + lineScan + lineScan; // next point after SBand in line scan
00936         nextPoint = nextLinePoint;
00937         vpFindPointInsideAxialSlice(nextPoint, scanDirection, xDimension, zDimension);
00938         edge = 0;
00939         edgeComparison = 0.8 * zDimension; // 80%
00940         while ( (((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) <= 40) && (edge<=edgeComparison) ) 
00941         {
00942             nextPoint = nextPoint + scanDirection;
00943             edge++;
00944             if ( (nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )
00945                 break;
00946         }
00947         if ((nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension))
00948                 edgeComparison = 0;
00949         else    if ( edge <= edgeComparison )
00950                     edgeComparison = 1;
00951                 else 
00952                     edgeComparison = 0;
00953 
00954         if ( edgeComparison ) { // if the column "hit the volume"
00955             // nextPoint is 3D, but y is the selected slice 
00956             // lineSBand is 2D; since y is always the same, x=nextPoint.x and y=nextPoint.z (the point in the "slice plane")
00957             lineSBand[numTotalPoints].x = nextPoint.x + (SBandSteps * scanDirection.x);
00958             lineSBand[numTotalPoints].y = nextPoint.z + (SBandSteps * scanDirection.z); 
00959             lineTBand[numTotalPoints].x = lineSBand[numTotalPoints].x + (TBandSteps * scanDirection.x);
00960             lineTBand[numTotalPoints].y = lineSBand[numTotalPoints].y + (TBandSteps * scanDirection.z); 
00961             
00962             numTotalPoints++;
00963         }
00964         else { // the column doesn't "hit the volume"
00965             findPoint = false;  
00966             aux = numTotalPoints;
00967         }
00968      } // while
00969      findPoint = true;
00970      nextLinePoint = volumeCameraLocation;
00971      nextLinePoint.y = sliceNumber;
00972      nextLinePoint = nextLinePoint - lineScan - lineScan; // "next point" before SBand in line scan
00973      nextPoint = nextLinePoint;
00974      vpFindPointInsideAxialSlice(nextPoint, scanDirection, xDimension, zDimension);
00975 
00976      // Second, process "left" points
00977      while (findPoint) {
00978         edge = 0;
00979         edgeComparison = 0.8 * zDimension; // 80%
00980 
00981         while ( (((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) <= 40) && (edge<=edgeComparison) ) 
00982         {
00983             nextPoint = nextPoint + scanDirection;
00984             edge++;
00985             if ( (nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )
00986                 break;
00987         }
00988         if ((nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension))
00989                 edgeComparison = 0;
00990         else    if ( edge <= edgeComparison )
00991                     edgeComparison = 1;
00992                 else 
00993                     edgeComparison = 0;
00994 
00995         if ( edgeComparison ) { // the column "hit the volume"
00996 
00997             lineSBand[numTotalPoints].x = nextPoint.x + (SBandSteps * scanDirection.x);
00998             lineSBand[numTotalPoints].y = nextPoint.z + (SBandSteps * scanDirection.z); 
00999             lineTBand[numTotalPoints].x = lineSBand[numTotalPoints].x + (TBandSteps * scanDirection.x);
01000             lineTBand[numTotalPoints].y = lineSBand[numTotalPoints].y + (TBandSteps * scanDirection.z); 
01001             nextLinePoint = nextLinePoint - lineScan - lineScan; // "next point" before SBand in line scan
01002             nextPoint = nextLinePoint;
01003             vpFindPointInsideAxialSlice(nextPoint, scanDirection, xDimension, zDimension);
01004             numTotalPoints++;
01005         }
01006         else // the column doesn't "hit the volume"
01007             findPoint = false;  
01008      }
01009  }
01010 
01011  vpOrder(arrayDimension, numTotalPoints, aux);
01012 
01014  // Scan view line for the ray casting 
01015 
01016  for (line=0; line<finalLineValue; line++) { 
01017 
01018      // Plane point computation
01019      p1 = minPlaneProjection;
01020      p1 = p1 + deltaY * line; 
01021 
01022      // Scan view column
01023      for (column=0; column<finalColumnValue; column++) {
01024 
01025         i = (int) (p1.x); //(column);
01026         j = sliceNumber;  //(line);
01027         k = (int) (p1.z); //(depth);
01028 
01029         p1.vpSetY(sliceNumber);
01030         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
01031 
01032         //i = (int) (p1.x+0.5);
01033 
01034         image[line+imageYdelta][column+imageXdelta][red] = (unsigned short int) voxelColor;
01035         image[line+imageYdelta][column+imageXdelta][green] = (unsigned short int) voxelColor;
01036         image[line+imageYdelta][column+imageXdelta][blue] = (unsigned short int) voxelColor;
01037 
01038         // Next plane point computation
01039         p1 = p1 + deltaX; 
01040 
01041     } // for (column)
01042 
01043  } // for (line)
01044 
01045  // Mapping endOfSBand and endOfTBand from the window to the viewport
01046  auxFloat = endOfSBand.x;
01047  endOfSBand.x = (finalLineValue*(endOfSBand.y-zDimension)) / zDimension + finalLineValue;
01048  endOfSBand.y = ( (finalColumnValue*auxFloat) / xDimension );
01049  endOfSBand.x += imageYdelta;
01050  endOfSBand.y += imageXdelta;
01051  auxFloat = endOfTBand.x;
01052  endOfTBand.x = (finalLineValue*(endOfTBand.y-zDimension)) / zDimension + finalLineValue;
01053  endOfTBand.y = ( (finalColumnValue*auxFloat) / xDimension );
01054  endOfTBand.x += imageYdelta;
01055  endOfTBand.y += imageXdelta;
01056 
01057  // Mapping lineTBand and lineSBand points from the window to the viewport
01058  for (cont=0; cont<numTotalPoints; cont++) {
01059     auxFloat = lineTBand[cont].x;
01060     lineTBand[cont].x = (finalLineValue*(lineTBand[cont].y-zDimension)) / zDimension + finalLineValue;
01061     lineTBand[cont].y = ( (finalColumnValue*auxFloat) / xDimension );
01062     lineTBand[cont].x += imageYdelta;
01063     lineTBand[cont].y += imageXdelta;
01064 
01065     auxFloat = lineSBand[cont].x;
01066     lineSBand[cont].x = (finalLineValue*(lineSBand[cont].y-zDimension)) / zDimension + finalLineValue;
01067     lineSBand[cont].y = ( (finalColumnValue*auxFloat) / xDimension );
01068     lineSBand[cont].x += imageYdelta;
01069     lineSBand[cont].y += imageXdelta;
01070  }
01071 
01072 }
01073 
01074 
01076 // Description: Method "vpSideInnerStructRender" implement the 
01077 //              algorithm to visualize one volume slice from the 
01078 //              side. Point indicating the position of the end of 
01079 //              S-Band and end of T-Band (used for setting the 
01080 //              inner structures parameters visualization) are draw 
01081 //              in the image.
01082 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
01083 //              int sliceNumber, unsigned int image[][256] (pointer 
01084 //              to the image with colors);
01085 // Return.....: -
01086 
01087 void VPSlice::vpSideInnerStructRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int ***image) {
01088  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
01089      finalLineValue=0, initialColumnValue=0, finalColumnValue=0, virtualYDimension=0,
01090      imageXdelta=0, imageYdelta=0, whiteLine=0, whiteColumn=0, cont=0;
01091  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, auxFloat=0, yCorrection=0;
01092 
01093  VPPoint2D winTopRightValue;
01094  VPVector3D projectionDirection, scanDirection, lineScan, vectorH, vectorV, 
01095             deltaX, deltaY, xAxis(1,0,0), up;
01096  VPPoint3D p1, minPlaneProjection, auxTarget, auxPoint, nextPoint, nextLinePoint; 
01097  
01098  VPGraphicObj *volume = v;  // Set pointer to the volume object
01099 
01100  VPPoint3D volumeCameraLocation = ((VPVolume *)volume)->vpGetCameraLocationForInnerStructure();
01101  
01102  VPCamera *camera = c;  // Set a pointer to the right camera
01103 
01104  VPPoint3D location = camera->vpGetLocation();
01105  VPPoint3D target = camera->vpGetTarget();
01106                 
01107  // Set projection direction by the vector
01108  projectionDirection.vpSetVector3D(target - location);
01109  projectionDirection.vpNormalize();
01110 
01111  // Set scan window direction and line scan (for SBand and TBand lines processing)
01112  auxTarget = target;
01113  scanDirection.vpSetVector3D(auxTarget - volumeCameraLocation);
01114  scanDirection.vpNormalize();
01115  lineScan = scanDirection.vpCrossProduct(xAxis);
01116  scanDirection.x = lineScan.x = 0;
01117 
01118  // winTopRightValue has the projection plane size (x,y)
01119  winTopRightValue = camera->vpGetWinTopRight();
01120 
01121  up = camera->vpGetUp();
01122  vectorH = up.vpCrossProduct(projectionDirection);
01123  vectorV = vectorH.vpCrossProduct(projectionDirection);
01124 
01125  // Set scan window corner (where the scan begin)
01126  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
01127  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
01128 
01129  // Set variables to determine the end of the view scan
01130  finalLineValue = camera->vpGetViewHeight();
01131  finalColumnValue = camera->vpGetViewWidth();
01132 
01133  // To verify the ratio between the window and the view
01134  // greater window dimension / view dimension (where viewx=viewy)
01135  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
01136     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
01137     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
01138     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
01139  }
01140  else {
01141     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
01142     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
01143     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
01144  }
01145 
01146  // To verify the smallest dimension and set the virtualVolumeDimension
01147  if ( ((VPImage *)volume)->vpGetXDimension() < ((VPVolume *)volume)->vpGetZDimension() )
01148     virtualYDimension = ((VPVolume *)volume)->vpGetZDimension();
01149  else 
01150     virtualYDimension = ((VPImage *)volume)->vpGetXDimension(); 
01151  yCorrection = ((float) ((VPImage *)volume)->vpGetYDimension()) / ((float) virtualYDimension);
01152 
01153  // Window/Viewport ratio
01154  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
01155  ratioY = winTopRightValue.vpGetY()/finalLineValue;
01156 
01157  // Line, column and sample step 
01158  deltaX = vectorH * ratioX;
01159  deltaY = vectorV * ratioY;
01160  deltaZ = projectionDirection.vpModule();
01161  
01163  // Inner structures visualization parameters
01164  // Goal: exhibition of two points (end of S-Band and T-Band), 
01165  //       a line that join them, and a line that identify
01166  //       the ROI (where data will be sampled)
01167 
01168  // Necessary variables to set the S-Band and T-Band position in the image
01169  VPPoint3D SBand, TBand, center = ((VPVolume *)volume)->vpGetCenterFocalPoint();  
01170  bool findPoint;
01171  int aux=0, arrayDimension, edgeComparison, matrixValue,
01172      yDimension = ((VPVolume *)volume)->vpGetYDimension(),
01173      zDimension = ((VPVolume *)volume)->vpGetZDimension();
01174  int edge=0, SBandSteps=0, TBandSteps=0;
01175 
01176  // To set arrayDimension (slice diagonal)
01177   arrayDimension = (int) ( sqrt( (yDimension*yDimension) + (zDimension*zDimension) ) / 2.0 + 1.0 );
01178 
01179    // round value
01180  SBand.x = (int) (center.x+0.5);
01181  SBand.y = (int) (center.y+0.5);
01182  SBand.z = ((VPVolume *)volume)->vpGetRayCastingSBand();
01183  TBand.x = (int) (center.x+0.5);
01184  TBand.y = (int) (center.y+0.5);
01185  TBand.z = ((VPVolume *)volume)->vpGetRayCastingTBand();
01186 
01187  // Process the steps between the edge and SBand and between
01188  // SBand and TBand (using the "middle slice")
01189  edge = 0;
01190  while (((VPVolume *)volume)->vpGetValue(SBand.x,SBand.y,edge) <= 40) 
01191      edge++;
01192  SBandSteps = SBand.z - edge;
01193  TBandSteps = TBand.z - SBand.z;
01194 
01196  // First: find the lineSBand and lineTBand points
01197  numTotalPoints=0;
01198  if (lineSBand != NULL) {
01199     delete [] lineSBand;
01200     delete [] lineTBand;
01201  }
01202  lineSBand = new VPPoint2D [sizeof(VPPoint2D) * arrayDimension];
01203  lineTBand = new VPPoint2D [sizeof(VPPoint2D) * arrayDimension];
01204 
01205  // Find object edge at "SBand column"
01206  edge = 0;
01207  edgeComparison = 0.8 * zDimension; // 80%
01208  while ( (((VPVolume *)volume)->vpGetValue(sliceNumber,SBand.y,edge) <= 40) && (edge<=edgeComparison) )
01209     edge++;
01210  if ( edge < edgeComparison )
01211     edgeComparison = 1;
01212  else
01213     edgeComparison = 0;
01214  
01215  // For the case of a very dark slice (top or bottom slice)
01216  if ( edgeComparison )
01217  { 
01218      // New SBand and TBand in accordance with scan direction
01219      nextPoint = volumeCameraLocation;
01220      nextPoint.x = sliceNumber;
01221      vpFindPntInsideSagittalSlice(nextPoint, scanDirection, virtualYDimension, zDimension); // @@ YDimension
01222      while ( ((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y*yCorrection,nextPoint.z) <= 40 ) // @@ Tirar *yCorrection
01223         nextPoint = nextPoint + scanDirection;
01224      
01225      SBand = nextPoint;
01226 
01227      for (i=0; i<SBandSteps; i++)
01228          SBand = SBand + scanDirection;
01229         
01230      TBand = SBand;
01231 
01232      for (i=0; i<TBandSteps; i++)
01233          TBand = TBand + scanDirection;
01234         
01235      // round value
01236      SBand.x = (int) (SBand.x+0.5);
01237      SBand.y = (int) (SBand.y+0.5);
01238      SBand.z = (int) (SBand.z+0.5);
01239      TBand.x = (int) (TBand.x+0.5);
01240      TBand.y = (int) (TBand.y+0.5);
01241      TBand.z = (int) (TBand.z+0.5);
01242 
01243      // lineScan to find the positions at scanDirection
01244      // (from the center to left, and from the center to right)
01245      lineSBand[numTotalPoints].x = endOfSBand.x = SBand.z;
01246      lineSBand[numTotalPoints].y = endOfSBand.y = SBand.y*yCorrection; // @@ tirar *yCorrection
01247      lineTBand[numTotalPoints].x = endOfTBand.x = TBand.z;          
01248      lineTBand[numTotalPoints].y = endOfTBand.y = TBand.y*yCorrection; // @@ tirar *yCorrection
01249      findPoint = true;
01250      numTotalPoints++;
01251 
01252      nextLinePoint = volumeCameraLocation;
01253      nextLinePoint.x = sliceNumber;
01254 
01255      // First, process "right" points
01256      while (findPoint) {
01257         nextLinePoint = nextLinePoint + lineScan + lineScan; // next point after SBand in line scan
01258         nextPoint = nextLinePoint;
01259         edge = 0;
01260         edgeComparison = 0.8 * zDimension; // 80%
01261         while ( (nextPoint.y<0) || (nextPoint.y>=virtualYDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )
01262         {
01263             nextPoint = nextPoint + scanDirection;
01264             edge++; // to verify if the point is out of the volume (edge must be <= edgeComparison)
01265             if (edge > edgeComparison)
01266                 break;
01267         }
01268         if (edge <= edgeComparison)
01269         {
01270             edge = 0;
01271             matrixValue = ((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y*yCorrection,nextPoint.z);
01272         }
01273         else
01274             matrixValue = 0;
01275         while ( (matrixValue <= 40) && (edge<=edgeComparison) )  // @@ Tirar *yCorrection
01276         {
01277             nextPoint = nextPoint + scanDirection;
01278             edge++;
01279             if ( (nextPoint.y<0) || (nextPoint.y>=virtualYDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) ) // @@ yDimension 
01280                 break;
01281             matrixValue = ((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y*yCorrection,nextPoint.z);
01282         }
01283         if ((nextPoint.y<0) || (nextPoint.y>=virtualYDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension)) // @@ yDimension 
01284                 edgeComparison = 0;
01285         else    if ( edge <= edgeComparison )
01286                     edgeComparison = 1;
01287                 else 
01288                     edgeComparison = 0;
01289 
01290         if ( edgeComparison ) { // if the column "hit the volume"
01291             // nextPoint is 3D, but x is the selected slice 
01292             // lineSBand is 2D; since x is always the same, x=nextPoint.z and y=nextPoint.y (the point in the "slice plane")
01293             lineSBand[numTotalPoints].x = nextPoint.z + (SBandSteps * scanDirection.z);
01294             lineSBand[numTotalPoints].y = nextPoint.y*yCorrection + (SBandSteps * scanDirection.y); // @@ Tirar *yCorrection
01295             lineTBand[numTotalPoints].x = lineSBand[numTotalPoints].x + (TBandSteps * scanDirection.z);
01296             lineTBand[numTotalPoints].y = lineSBand[numTotalPoints].y + (TBandSteps * scanDirection.y); 
01297             
01298             numTotalPoints++;
01299         }
01300         else { // the column doesn't "hit the volume"
01301             findPoint = false;  
01302             aux = numTotalPoints;
01303         }
01304      } // while
01305      findPoint = true;
01306      nextLinePoint = volumeCameraLocation;
01307      nextLinePoint.x = sliceNumber;
01308      nextLinePoint = nextLinePoint - lineScan - lineScan; // "next point" before SBand in line scan
01309      nextPoint = nextLinePoint;
01310      vpFindPntInsideSagittalSlice(nextPoint, scanDirection, virtualYDimension, zDimension); 
01311 
01312      // Second, process "left" points
01313      while (findPoint) {
01314         edge = 0;
01315         edgeComparison = 0.8 * zDimension; // 80%
01316 
01317         while ( (((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y*yCorrection,nextPoint.z) <= 40) && (edge<=edgeComparison) ) 
01318         {
01319             nextPoint = nextPoint + scanDirection;
01320             edge++;
01321             if ( (nextPoint.y<0) || (nextPoint.y>=virtualYDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )
01322                 break;
01323         }
01324         if ((nextPoint.y<0) || (nextPoint.y>=virtualYDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension))
01325                 edgeComparison = 0;
01326         else    if ( edge <= edgeComparison )
01327                     edgeComparison = 1;
01328                 else 
01329                     edgeComparison = 0;
01330 
01331         if ( edgeComparison ) { // the column "hit the volume"
01332             lineSBand[numTotalPoints].x = nextPoint.z + (SBandSteps * scanDirection.z);
01333             lineSBand[numTotalPoints].y = nextPoint.y*yCorrection + (SBandSteps * scanDirection.y); 
01334             lineTBand[numTotalPoints].x = lineSBand[numTotalPoints].x + (TBandSteps * scanDirection.z);
01335             lineTBand[numTotalPoints].y = lineSBand[numTotalPoints].y + (TBandSteps * scanDirection.y); 
01336             nextLinePoint = nextLinePoint - lineScan - lineScan; // "next point" before SBand in line scan
01337             nextPoint = nextLinePoint;
01338             numTotalPoints++;
01339 
01340             // Guarantee that the next point is inside the volume...
01341             edge = 0;
01342             edgeComparison = 0.8 * zDimension; // 80%
01343             while ( (nextPoint.y<0) || (nextPoint.y>=virtualYDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )   {
01344                 nextPoint = nextPoint + scanDirection;
01345                 edge++; 
01346                 if (edge > edgeComparison)// to verify if the point is out of the volume (edge must be <= edgeComparison)
01347                     break;
01348             }
01349             if (edge > edgeComparison)
01350                 findPoint = false;
01351         }
01352         else // the column doesn't "hit the volume"
01353             findPoint = false;  
01354      }
01355  }
01356 
01357  vpOrder(arrayDimension, numTotalPoints, aux);
01358 
01360  // Scan view line for the ray casting 
01361 
01362  for (line=0; line<finalLineValue; line++) { 
01363 
01364      // Plane point computation
01365      p1 = minPlaneProjection;
01366      p1 = p1 + deltaY * line; 
01367      p1.y = p1.y*yCorrection;
01368 
01369      // Scan view column
01370      for (column=0; column<finalColumnValue; column++) {
01371 
01372         i = sliceNumber;        //(column);
01373         j = (int) (p1.vpGetY());//(line);
01374         k = (int) (p1.vpGetZ());//(depth);
01375 
01376         p1.vpSetX(sliceNumber);
01377         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
01378 
01379         image[line+imageYdelta][column+imageXdelta][red] = (unsigned short int) voxelColor;
01380         image[line+imageYdelta][column+imageXdelta][green] = (unsigned short int) voxelColor;
01381         image[line+imageYdelta][column+imageXdelta][blue] = (unsigned short int) voxelColor;
01382 
01383         // Next plane point computation
01384         p1 = p1 + deltaX; 
01385 
01386     } // for (column)
01387 
01388  } // for (line)
01389 
01390  // Mapping endOfSBand and endOfTBand from the window to the viewport
01391  auxFloat = endOfSBand.x;
01392  endOfSBand.x = ( (-finalLineValue)*endOfSBand.y ) / yDimension + finalLineValue;
01393  endOfSBand.y = ( (finalColumnValue*(auxFloat-zDimension)) / -zDimension );
01394  endOfSBand.x += imageYdelta;
01395  endOfSBand.y += imageXdelta;
01396  auxFloat = endOfTBand.x;
01397  endOfTBand.x = ( (-finalLineValue)*endOfTBand.y ) / yDimension + finalLineValue;
01398  endOfTBand.y = ( (finalColumnValue*(auxFloat-zDimension)) / -zDimension );
01399  endOfTBand.x += imageYdelta;
01400  endOfTBand.y += imageXdelta;
01401 
01402 
01403 
01404  // Mapping lineTBand and lineSBand points from the window to the viewport
01405  for (cont=0; cont<numTotalPoints; cont++) {
01406     auxFloat = lineTBand[cont].x;
01407     lineTBand[cont].x = ( (-finalLineValue)*lineTBand[cont].y ) / yDimension + finalLineValue;
01408     lineTBand[cont].y = ( (finalColumnValue*(auxFloat-zDimension)) / -zDimension );
01409     lineTBand[cont].x += imageYdelta;
01410     lineTBand[cont].y += imageXdelta;
01411 
01412     auxFloat = lineSBand[cont].x;
01413     lineSBand[cont].x = ( (-finalLineValue)*lineSBand[cont].y ) / yDimension + finalLineValue;
01414     lineSBand[cont].y = ( (finalColumnValue*(auxFloat-zDimension)) / -zDimension );
01415     lineSBand[cont].x += imageYdelta;
01416     lineSBand[cont].y += imageXdelta;
01417  }
01418 
01419 }
01420 
01421 
01423 // Description: Method "vpFrontInnerStructRender" implement the 
01424 //              algorithm to visualize one volume slice from the 
01425 //              front. Point indicating the position of the end of 
01426 //              S-Band and end of T-Band (used for setting the 
01427 //              inner structures parameters visualization) are draw 
01428 //              in the image.
01429 // Parameters.: VPCamera *c (active camera), VPGraphicObj *v, 
01430 //              int sliceNumber, unsigned int image[][256] (pointer 
01431 //              to the image with colors);
01432 // Return.....: -
01433 
01434 void VPSlice::vpFrontInnerStructRender(VPCamera *c, VPGraphicObj *v, int sliceNumber, unsigned int ***image) {
01435  int line=0, column=0, i=0, j=0, k=0, initialLineValue=0, 
01436      finalLineValue=0, initialColumnValue=0, finalColumnValue=0, virtualYDimension=0,
01437      imageXdelta=0, imageYdelta=0, whiteLine=0, whiteColumn=0, cont=0;
01438  float voxelColor=0, ratioX=0, ratioY=0, deltaZ=0, auxRatio=0, auxFloat=0, yCorrection=0;
01439 
01440  VPPoint2D winTopRightValue;
01441  VPVector3D projectionDirection, scanDirection, lineScan, vectorH, vectorV, 
01442             deltaX, deltaY, zAxis(0,0,1), up;
01443  VPPoint3D p1, minPlaneProjection, auxTarget, auxPoint, nextPoint, nextLinePoint; 
01444  
01445  VPGraphicObj *volume = v;  // Set pointer to the volume object
01446 
01447  VPPoint3D volumeCameraLocation = ((VPVolume *)volume)->vpGetCameraLocationForInnerStructure();
01448  
01449  VPCamera *camera = c;  // Set a pointer to the right camera
01450 
01451  VPPoint3D location = camera->vpGetLocation();
01452  VPPoint3D target = camera->vpGetTarget();
01453                 
01454  // Set projection direction by the vector
01455  projectionDirection.vpSetVector3D(target - location);
01456  projectionDirection.vpNormalize();
01457 
01458  // Set scan window direction and line scan (for SBand and TBand lines processing)
01459  auxTarget = target;
01460  scanDirection.vpSetVector3D(auxTarget - volumeCameraLocation);
01461  scanDirection.vpNormalize();
01462  lineScan = scanDirection.vpCrossProduct(zAxis);
01463  scanDirection.z = lineScan.z = 0;
01464 
01465  // winTopRightValue has the projection plane size (x,y)
01466  winTopRightValue = camera->vpGetWinTopRight();
01467 
01468  up = camera->vpGetUp();
01469  vectorH = up.vpCrossProduct(projectionDirection);
01470  vectorV = vectorH.vpCrossProduct(projectionDirection);
01471 
01472  // Set scan window corner (where the scan begin)
01473  minPlaneProjection = (location - vectorH*(winTopRightValue.vpGetX()/2));
01474  minPlaneProjection = (minPlaneProjection - vectorV*(winTopRightValue.vpGetY()/2));
01475 
01476  // Set variables to determine the end of the view scan
01477  finalLineValue = camera->vpGetViewHeight();
01478  finalColumnValue = camera->vpGetViewWidth();
01479 
01480  // To verify the ratio between the window and the view
01481  // greater window dimension / view dimension (where viewx=viewy)
01482  if (winTopRightValue.vpGetX() > winTopRightValue.vpGetY()) {
01483     auxRatio = winTopRightValue.vpGetX() / finalColumnValue;
01484     finalLineValue = winTopRightValue.vpGetY() / auxRatio;
01485     imageYdelta = (camera->vpGetViewHeight() - finalLineValue) / 2;
01486  }
01487  else {
01488     auxRatio = winTopRightValue.vpGetY() / finalLineValue;
01489     finalColumnValue = winTopRightValue.vpGetX() / auxRatio;
01490     imageXdelta = (camera->vpGetViewWidth() - finalColumnValue) / 2;
01491  }
01492 
01493  // To verify the smallest dimension and set the virtualVolumeDimension
01494  if ( ((VPImage *)volume)->vpGetXDimension() < ((VPVolume *)volume)->vpGetZDimension() )
01495     virtualYDimension = ((VPVolume *)volume)->vpGetZDimension();
01496  else 
01497     virtualYDimension = ((VPImage *)volume)->vpGetXDimension(); 
01498  yCorrection = ((float) ((VPImage *)volume)->vpGetYDimension()) / ((float) virtualYDimension);
01499 
01500  // Window/Viewport ratio
01501  ratioX =  winTopRightValue.vpGetX()/finalColumnValue;
01502  ratioY = winTopRightValue.vpGetY()/finalLineValue;
01503 
01504  // Line, column and sample step 
01505  deltaX = vectorH * ratioX;
01506  deltaY = vectorV * ratioY;
01507  deltaZ = projectionDirection.vpModule();
01508  
01510  // Inner structures visualization parameters
01511  // Goal: exhibition of two points (end of S-Band and T-Band), 
01512  //       a line that join them, and a line that identify
01513  //       the ROI (where data will be sampled)
01514 
01515  // Necessary variables to set the S-Band and T-Band position in the image
01516  VPPoint3D SBand, TBand, center = ((VPVolume *)volume)->vpGetCenterFocalPoint();  
01517  bool findPoint;
01518  int aux=0, arrayDimension, edgeComparison,
01519      xDimension = ((VPVolume *)volume)->vpGetXDimension(),
01520      yDimension = ((VPVolume *)volume)->vpGetYDimension();
01521  int edge=0, SBandSteps=0, TBandSteps=0;
01522 
01523  // To set arrayDimension (slice diagonal)
01524   arrayDimension = (int) ( sqrt( (xDimension*xDimension) + (yDimension*yDimension) ) / 2.0 + 1.0 );
01525 
01526  // round value
01527  SBand.x = (int) (center.x+0.5);
01528  SBand.y = (int) (center.y+0.5);
01529  SBand.z = ((VPVolume *)volume)->vpGetRayCastingSBand();
01530  TBand.x = (int) (center.x+0.5);
01531  TBand.y = (int) (center.y+0.5);
01532  TBand.z = ((VPVolume *)volume)->vpGetRayCastingTBand();
01533 
01534  // Process the steps between the edge and SBand and between
01535  // SBand and TBand (using the "middle slice")
01536  edge = 0;
01537  while (((VPVolume *)volume)->vpGetValue(SBand.x,SBand.y,edge) <= 40) 
01538      edge++;
01539  SBandSteps = SBand.z - edge;
01540  TBandSteps = TBand.z - SBand.z;
01541 
01543  // First: find the lineSBand and lineTBand points
01544  numTotalPoints=0;
01545  if (lineSBand != NULL) {
01546     delete [] lineSBand;
01547     delete [] lineTBand;
01548  }
01549  lineSBand = new VPPoint2D [sizeof(VPPoint2D) * arrayDimension];
01550  lineTBand = new VPPoint2D [sizeof(VPPoint2D) * arrayDimension];
01551 
01552  // Find object edge at "SBand column"
01553  edge = 0;
01554  edgeComparison = 0.8 * yDimension; // 80%
01555  while ( (((VPVolume *)volume)->vpGetValue(SBand.x,edge,sliceNumber) <= 40) && (edge<=edgeComparison) )
01556     edge++;
01557  if ( edge < edgeComparison )
01558     edgeComparison = 1;
01559  else
01560     edgeComparison = 0;
01561  
01562  // For the case of a very dark slice (top or bottom slice)
01563  if ( edgeComparison )
01564  { 
01565      // New SBand and TBand in accordance with scan direction
01566      nextPoint = volumeCameraLocation;
01567      nextPoint.z = sliceNumber;
01568      vpFindPntInsideFrontalSlice(nextPoint, scanDirection, xDimension, yDimension);
01569      if ( ((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) >= 10 )
01570      { // if the point is already inside the volume, it's necessary to find "the limit"
01571          while ( (nextPoint.x>1) && (nextPoint.x<xDimension-1) && (nextPoint.y>1) && (nextPoint.y<yDimension-1) )
01572             nextPoint = nextPoint - scanDirection;
01573      }
01574      while ( ((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) <= 40 )
01575         nextPoint = nextPoint + scanDirection;
01576      
01577      SBand = nextPoint;
01578 
01579      for (i=0; i<SBandSteps; i++)
01580          SBand = SBand + scanDirection;
01581         
01582      TBand = SBand;
01583 
01584      for (i=0; i<TBandSteps; i++)
01585          TBand = TBand + scanDirection;
01586         
01587      // round value
01588      SBand.x = (int) (SBand.x+0.5);
01589      SBand.y = (int) (SBand.y+0.5);
01590      SBand.z = (int) (SBand.z+0.5);
01591      TBand.x = (int) (TBand.x+0.5);
01592      TBand.y = (int) (TBand.y+0.5);
01593      TBand.z = (int) (TBand.z+0.5);
01594 
01595      // lineScan to find the positions at scanDirection
01596      // (from the center to left, and from the center to right)
01597      lineSBand[numTotalPoints].x = endOfSBand.x = SBand.x;
01598      lineSBand[numTotalPoints].y = endOfSBand.y = SBand.y;
01599      lineTBand[numTotalPoints].x = endOfTBand.x = TBand.x;          
01600      lineTBand[numTotalPoints].y = endOfTBand.y = TBand.y;
01601      findPoint = true;
01602      numTotalPoints++;
01603 
01604      nextLinePoint = volumeCameraLocation;
01605      nextLinePoint.z = sliceNumber;
01606 
01607      // First, process "right" points
01608      while (findPoint) {
01609         nextLinePoint = nextLinePoint + lineScan + lineScan; // next point after SBand in line scan
01610         nextPoint = nextLinePoint;
01611         vpFindPntInsideFrontalSlice(nextPoint, scanDirection, xDimension, yDimension);
01612         
01613         // if the point is already inside the volume, it's necessary to find "the limit"
01614         while ( (nextPoint.x>1) && (nextPoint.x<xDimension-1) && (nextPoint.y>1) && (nextPoint.y<yDimension-1) )
01615             nextPoint = nextPoint - scanDirection;
01616 
01617         edge = 0;
01618         edgeComparison = 0.8 * yDimension; // 80%
01619         while ( (((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) <= 40) && (edge<=edgeComparison) ) 
01620         {
01621             nextPoint = nextPoint + scanDirection;
01622             edge++;
01623             if ( (nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.y<0) || (nextPoint.y>=yDimension) )
01624                 break;
01625         }
01626         if ((nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.y<0) || (nextPoint.y>=yDimension))
01627                 edgeComparison = 0;
01628         else    if ( edge <= edgeComparison )
01629                     edgeComparison = 1;
01630                 else 
01631                     edgeComparison = 0;
01632 
01633         if ( edgeComparison ) { // if the column "hit the volume"
01634             // nextPoint is 3D, but z is the selected slice 
01635             // lineSBand is 2D; since z is always the same, x=nextPoint.x and y=nextPoint.y (the point in the "slice plane")
01636             lineSBand[numTotalPoints].x = nextPoint.x + (SBandSteps * scanDirection.x);
01637             lineSBand[numTotalPoints].y = nextPoint.y + (SBandSteps * scanDirection.y); 
01638             lineTBand[numTotalPoints].x = lineSBand[numTotalPoints].x + (TBandSteps * scanDirection.x);
01639             lineTBand[numTotalPoints].y = lineSBand[numTotalPoints].y + (TBandSteps * scanDirection.y); 
01640             
01641             numTotalPoints++;
01642         }
01643         else { // the column doesn't "hit the volume"
01644             findPoint = false;  
01645             aux = numTotalPoints;
01646         }
01647      } // while
01648      findPoint = true;
01649      nextLinePoint = volumeCameraLocation;
01650      nextLinePoint.z = sliceNumber;
01651      nextLinePoint = nextLinePoint - lineScan - lineScan; // "next point" before SBand in line scan
01652      nextPoint = nextLinePoint;
01653      vpFindPntInsideFrontalSlice(nextPoint, scanDirection, xDimension, yDimension);
01654 
01655      // Second, process "left" points
01656      while (findPoint) {
01657         edge = 0;
01658         edgeComparison = 0.8 * yDimension; // 80%
01659 
01660         // if the point is already inside the volume, it's necessary to find "the limit"
01661         while ( (nextPoint.x>1) && (nextPoint.x<xDimension-1) && (nextPoint.y>1) && (nextPoint.y<yDimension-1) )
01662             nextPoint = nextPoint - scanDirection;
01663         
01664         while ( (((VPVolume *)volume)->vpGetValue(nextPoint.x,nextPoint.y,nextPoint.z) <= 40) && (edge<=edgeComparison) ) 
01665         {
01666             nextPoint = nextPoint + scanDirection;
01667             edge++;
01668             if ( (nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.y<0) || (nextPoint.y>=yDimension) )
01669                 break;
01670         }
01671         if ((nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.y<0) || (nextPoint.y>=yDimension))
01672                 edgeComparison = 0;
01673         else    if ( edge <= edgeComparison )
01674                     edgeComparison = 1;
01675                 else 
01676                     edgeComparison = 0;
01677 
01678         if ( edgeComparison ) { // the column "hit the volume"
01679 
01680             lineSBand[numTotalPoints].x = nextPoint.x + (SBandSteps * scanDirection.x);
01681             lineSBand[numTotalPoints].y = nextPoint.y + (SBandSteps * scanDirection.y); 
01682             lineTBand[numTotalPoints].x = lineSBand[numTotalPoints].x + (TBandSteps * scanDirection.x);
01683             lineTBand[numTotalPoints].y = lineSBand[numTotalPoints].y + (TBandSteps * scanDirection.y); 
01684             nextLinePoint = nextLinePoint - lineScan - lineScan; // "next point" before SBand in line scan
01685             nextPoint = nextLinePoint;
01686             vpFindPntInsideFrontalSlice(nextPoint, scanDirection, xDimension, yDimension);
01687 
01688             // if the point is already inside the volume, it's necessary to find "the limit"
01689             while ( (nextPoint.x>1) && (nextPoint.x<xDimension-1) && (nextPoint.y>1) && (nextPoint.y<yDimension-1) )
01690                 nextPoint = nextPoint - scanDirection;
01691             
01692             numTotalPoints++;
01693         }
01694         else // the column doesn't "hit the volume"
01695             findPoint = false;  
01696      }
01697  }
01698 
01699  vpOrder(arrayDimension, numTotalPoints, aux);
01700 
01702  // Scan view line for the ray casting 
01703 
01704  for (line=0; line<finalLineValue; line++) { 
01705 
01706      // Plane point computation
01707      p1 = minPlaneProjection;
01708      p1 = p1 + deltaY * line; 
01709      p1.y = p1.y*yCorrection;
01710 
01711      // Scan view column
01712      for (column=0; column<finalColumnValue; column++) {
01713 
01714         i = (int) (p1.vpGetX()); //(column);
01715         j = (int) (p1.vpGetY()); //(line);
01716         k = sliceNumber; //(depth);
01717 
01718         p1.vpSetZ(sliceNumber);
01719         voxelColor = vpTrilinearInterpolation(i,j,k,volume,p1);
01720 
01721         image[line+imageYdelta][column+imageXdelta][red] = (unsigned short int) voxelColor;
01722         image[line+imageYdelta][column+imageXdelta][green] = (unsigned short int) voxelColor;
01723         image[line+imageYdelta][column+imageXdelta][blue] = (unsigned short int) voxelColor;
01724 
01725         // Next plane point computation
01726         p1 = p1 + deltaX; 
01727 
01728     } // for (column)
01729 
01730  } // for (line)
01731 
01732  // Mapping endOfSBand and endOfTBand from the window to the viewport
01733  auxFloat = endOfSBand.x;
01734  endOfSBand.x = (finalLineValue*(endOfSBand.y-yDimension)) / yDimension + finalLineValue;
01735  endOfSBand.y = ( (finalColumnValue*(auxFloat-xDimension)) / -xDimension );
01736  endOfSBand.x += imageYdelta;
01737  endOfSBand.y += imageXdelta;
01738  auxFloat = endOfTBand.x;
01739  endOfTBand.x = (finalLineValue*(endOfTBand.y-yDimension)) / yDimension + finalLineValue;
01740  endOfTBand.y = ( (finalColumnValue*(auxFloat-xDimension)) / -xDimension );
01741  endOfTBand.x += imageYdelta;
01742  endOfTBand.y += imageXdelta;
01743 
01744  // Mapping lineTBand and lineSBand points from the window to the viewport
01745  for (cont=0; cont<numTotalPoints; cont++) {
01746     auxFloat = lineTBand[cont].x;
01747     lineTBand[cont].x = (finalLineValue*(lineTBand[cont].y-yDimension)) / yDimension + finalLineValue;
01748     lineTBand[cont].y = ( (finalColumnValue*(auxFloat-xDimension)) / -xDimension );
01749     lineTBand[cont].x += imageYdelta;
01750     lineTBand[cont].y += imageXdelta;
01751 
01752     auxFloat = lineSBand[cont].x;
01753     lineSBand[cont].x = (finalLineValue*(lineSBand[cont].y-yDimension)) / yDimension + finalLineValue;
01754     lineSBand[cont].y = ( (finalColumnValue*(auxFloat-xDimension)) / -xDimension );
01755     lineSBand[cont].x += imageYdelta;
01756     lineSBand[cont].y += imageXdelta;
01757  }
01758 
01759 }
01760 
01761 
01763 // Description: Method "vpFindPointInsideAxialSlice" guarante that 
01764 //              the point is inside a axial slice in the volume.
01765 // Parameters.: VPPoint3D nextPoint (point inside the volume)
01766 //              VPVector3D scanDirection (direction to find the point)
01767 //              int xDimension (x volume dimension)
01768 //              int zDimension (z volume dimension)
01769 // Return.....: -
01770 
01771 void VPSlice::vpFindPointInsideAxialSlice(VPPoint3D &nextPoint, VPVector3D scanDirection, int xDimension, int zDimension) {
01772     while ( (nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )
01773             nextPoint = nextPoint + scanDirection;
01774 }
01775 
01776 
01778 // Description: Method "vpFindPntInsideSagittalSlice" guarante that 
01779 //              the point is inside a sagittal slice in the volume.
01780 // Parameters.: VPPoint3D nextPoint (point inside the volume)
01781 //              VPVector3D scanDirection (direction to find the point)
01782 //              int yDimension (y volume dimension)
01783 //              int zDimension (z volume dimension)
01784 // Return.....: -
01785 
01786 void VPSlice::vpFindPntInsideSagittalSlice(VPPoint3D &nextPoint, VPVector3D scanDirection, int yDimension, int zDimension) {
01787     while ( (nextPoint.y<0) || (nextPoint.y>=yDimension) || (nextPoint.z<0) || (nextPoint.z>=zDimension) )
01788             nextPoint = nextPoint + scanDirection;
01789 }
01790 
01791 
01793 // Description: Method "vpFindPntInsideFrontalSlice" guarante that 
01794 //              the point is inside a frontal slice in the volume.
01795 // Parameters.: VPPoint3D nextPoint (point inside the volume)
01796 //              VPVector3D scanDirection (direction to find the point)
01797 //              int xDimension (x volume dimension)
01798 //              int yDimension (y volume dimension)
01799 // Return.....: -
01800 
01801 void VPSlice::vpFindPntInsideFrontalSlice(VPPoint3D &nextPoint, VPVector3D scanDirection, int xDimension, int yDimension) {
01802     while ( (nextPoint.x<0) || (nextPoint.x>=xDimension) || (nextPoint.y<0) || (nextPoint.y>=yDimension) )
01803             nextPoint = nextPoint + scanDirection;
01804 }
01805 
01806 
01808 // Description: Method "vpOrder" "put in order" the points of the
01809 //              lineSBand and lineTBand arrays.
01810 // Parameters.: int arraySize, to alloc a temporary array (same 
01811 //                             size as lineTBand and lineSBand)
01812 //              int numTotalPoints (arrays total points) 
01813 //              int aux (middle point, separate left and right
01814 //                       points from SBand and TBand) 
01815 // Return.....: -
01816 
01817 void VPSlice::vpOrder(int arraySize, int numTotalPoints, int aux)
01818 {
01819  VPPoint2D *auxLine, *auxPointer; 
01820  int i, j;
01821 
01822  auxLine = new VPPoint2D [sizeof(VPPoint2D) * arraySize];
01823 
01824  for (i=numTotalPoints-1, j=0; i>=aux; i--, j++) {
01825     auxLine[j].x = lineSBand[i].x;
01826     auxLine[j].y = lineSBand[i].y;
01827  }
01828  auxLine[j].x = lineSBand[0].x;
01829  auxLine[j].y = lineSBand[0].y;
01830  j++;
01831  for (i=1; i<aux; i++, j++) {
01832     auxLine[j].x = lineSBand[i].x;
01833     auxLine[j].y = lineSBand[i].y;
01834  }
01835 
01836  auxPointer = lineSBand;
01837  lineSBand = auxLine;
01838  auxLine = auxPointer;
01839 
01840  for (i=numTotalPoints-1, j=0; i>=aux; i--, j++) {
01841     auxLine[j].x = lineTBand[i].x;
01842     auxLine[j].y = lineTBand[i].y;
01843  }
01844  auxLine[j].x = lineTBand[0].x;
01845  auxLine[j].y = lineTBand[0].y;
01846  j++;
01847  for (i=1; i<aux; i++, j++) {
01848     auxLine[j].x = lineTBand[i].x;
01849     auxLine[j].y = lineTBand[i].y;
01850  }
01851 
01852  auxPointer = lineTBand;
01853  lineTBand = auxLine;
01854 
01855  delete [] auxPointer;
01856 }
01857     
01858 
01860 // Description: Method "vpTrilinearInterpolation" process the voxel 
01861 //              color (gray) using trilinear interpolation.
01862 // Parameters.: int i, int j, int k, VPGraphicObj *volume,
01863 //              float increment (i,j,k=volume matrix index; 
01864 //              depth=ray position; volume=object volume that has all 
01865 //              information about the volume; increment=increment step
01866 //              in the ray) 
01867 // Return.....: float color (voxel color)
01868 
01869 float VPSlice::vpTrilinearInterpolation(int i, int j, int k,  
01870                                              VPGraphicObj *volume, VPPoint3D p) {
01871 
01872  int C1, C2, C3, C4, C5, C6, C7, C8, ii, jj, kk;
01873  float i1, i2, i3, i4, i5, i6, i7,  // valores interpolados
01874        dx, dy, dz;                  // distância (delta)
01875 
01876  // First, voxels color initialization
01877  ii = ((i+1) < ((VPImage *)volume)->vpGetXDimension()) ? i+1 : i;
01878  jj = ((j+1) < ((VPImage *)volume)->vpGetYDimension()) ? j+1 : j;
01879  kk = ((k+1) < ((VPVolume *)volume)->vpGetZDimension()) ? k+1 : k;
01880  C1 = ((VPVolume *)volume)->vpGetValue(i,j,k);
01881  C2 = ((VPVolume *)volume)->vpGetValue(ii,j,k);
01882  C3 = ((VPVolume *)volume)->vpGetValue(ii,jj,k);
01883  C4 = ((VPVolume *)volume)->vpGetValue(i,jj,k);
01884  C5 = ((VPVolume *)volume)->vpGetValue(i,j,kk);
01885  C6 = ((VPVolume *)volume)->vpGetValue(ii,j,kk);
01886  C7 = ((VPVolume *)volume)->vpGetValue(ii,jj,kk);
01887  C8 = ((VPVolume *)volume)->vpGetValue(i,jj,kk);
01888  
01889   // If all voxels have the same color, it is not necessary to interpolate  
01890  if ((C1==C2) && (C2==C3) && (C3==C4) && (C4==C5) && (C5==C6) && (C6==C7) && (C7==C8))
01891     return( (float)(C1) );
01892 
01893  // Trilinear interpolation (seven linear interpolations)
01894  //                 
01895  //       5-----------------6       
01896  //      /|                /|       
01897  //     i1-------i5-------i2|       
01898  //    /  |      |       /  |       
01899  //   1-----------------2   |       
01900  //   |   |      |      |   |       
01901  //   |   |      i7     |   |       
01902  //   |   |      |      |   |       
01903  //   |   8------|i3----|---7       
01904  //   |  /       |/     |  /        
01905  //   | /        i6     | /     
01906  //   |/        /       |/      
01907  //   4--------i4-------3       
01908  //                 
01909 
01910  // Distance from the voxel 1
01911  dx = p.vpGetX()-i;
01912  dy = p.vpGetY()-j;
01913  dz = p.vpGetZ()-k;
01914 
01915  // Interpolation values
01916  i1 = ( (C5-C1) * dz + C1);
01917  i2 = ( (C6-C2) * dz + C2);
01918  i3 = ( (C7-C8) * dx + C8);
01919  i4 = ( (C3-C4) * dx + C4);
01920  i5 = ( (i2-i1) * dx + i1);
01921  i6 = ( (i3-i4) * dz + i4);
01922  i7 = ( (i6-i5) * dy + i5);
01923 
01924  return(i7);
01925 }
01926 
01927 
01929 // Description: Method "vpGetViewSBandPoint" returns the value of 
01930 //              endOfSBand attribute.
01931 // Parameters.: -
01932 // Return.....: VPPoint2D endOfSBand (attribute value)
01933 
01934 VPPoint2D VPSlice::vpGetViewSBandPoint() {
01935     return endOfSBand; // endOfSBand;
01936 }
01937 
01938 
01940 // Description: Method "vpGetViewTBandPoint" returns the value of 
01941 //              endOfTBand attribute.
01942 // Parameters.: -
01943 // Return.....: VPPoint2D endOfTBand (attribute value)
01944 
01945 VPPoint2D VPSlice::vpGetViewTBandPoint() {
01946     return endOfTBand; // endOfTBand;
01947 }
01948 
01949 
01951 // Description: Method "vpGetLineSBand" returns the value of 
01952 //              lineSBand attribute and how many points it has.
01953 // Parameters.: VPPoint2D *l, int &n
01954 // Return.....: -
01955 
01956 void VPSlice::vpGetLineSBand(VPPoint2D **l, int &n) {
01957     *l = lineSBand;
01958     n = numTotalPoints;
01959 }
01960 
01961 
01963 // Description: Method "vpGetLineTBand" returns the value of 
01964 //              lineTBand attribute and how many points it has.
01965 // Parameters.: VPPoint2D *l, int n
01966 // Return.....: -
01967 
01968 void VPSlice::vpGetLineTBand(VPPoint2D **l, int &n) {
01969     *l = lineTBand;
01970     n = numTotalPoints;
01971 }
01972 
01973 

Generated on Tue Sep 6 10:00:06 2005 for VPAT by  doxygen 1.4.4