X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vv%2FvvSlicer.cxx;h=92cb2686d25cdb543f188a7112c101220c9712d2;hb=acdc20ec4afc95db1db29bf8d885a3b72c9c7ee0;hp=371cd2d62be1dd5ced9900355c9fbcc71d266fa6;hpb=9983384fdd6b9ac0a9cc8de007884826157c9d00;p=clitk.git diff --git a/vv/vvSlicer.cxx b/vv/vvSlicer.cxx index 371cd2d..92cb268 100644 --- a/vv/vvSlicer.cxx +++ b/vv/vvSlicer.cxx @@ -69,12 +69,15 @@ vtkCxxRevisionMacro(vvSlicer, "DummyRevision"); vtkStandardNewMacro(vvSlicer); - +static void copyExtent(int* in, int* to){ + for(int i=0; i<6; ++i) to[i]=in[i]; +} //------------------------------------------------------------------------------ vvSlicer::vvSlicer() { this->UnInstallPipeline(); mImage = NULL; + mReducedExtent = new int[6]; mCurrentTSlice = 0; mUseReducedExtent = false; @@ -95,22 +98,6 @@ vvSlicer::vvSlicer() mVFColor[1] = 1; mVFColor[2] = 0; - std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n"; - text += "F5 = horizontal flip; F6 = vertical flip\n\n"; - text += "0,1,2,3,4,5 : preset windowing\n"; - text += "6,7,8,9 : preset colormap\n"; - text += "z : local windowing\n"; - text += "r : reset view\n"; - text += "l : reload image\n"; - text += "f : fly to mouse position\n"; - text += "g : go to cross hair position\n\n"; - text += "Up,down : change slice\n"; - text += "Left,right : change tenporal slice\n\n"; - text += "Scrollbar (or w/x) : zoom in/out\n"; - text += "left button : synchronize all views\n"; - text += "middle button : grab image\n"; - text += "right button : change windowing\n"; - crossCursor = vtkSmartPointer::New(); crossCursor->AllOff(); crossCursor->AxesOn(); @@ -148,6 +135,8 @@ vvSlicer::vvSlicer() this->WindowLevel = vvImageMapToWLColors::New(); this->InstallPipeline(); + + mLinkOverlayWindowLevel = true; } //------------------------------------------------------------------------------ @@ -169,7 +158,7 @@ vvBlendImageActor* vvSlicer::GetOverlayActor() //------------------------------------------------------------------------------ -vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper() +vtkImageMapToColors* vvSlicer::GetFusionMapper() { return mFusionMapper.GetPointer(); } @@ -211,7 +200,7 @@ void vvSlicer::EnableReducedExtent(bool b) //------------------------------------------------------------------------------ void vvSlicer::SetReducedExtent(int * ext) { - mReducedExtent = ext; + copyExtent(ext, mReducedExtent); } //------------------------------------------------------------------------------ @@ -289,6 +278,7 @@ vvSlicer::~vvSlicer() for (std::vector::iterator i=mSurfaceCutActors.begin(); i!=mSurfaceCutActors.end(); i++) delete (*i); + delete [] mReducedExtent; } //------------------------------------------------------------------------------ @@ -327,7 +317,7 @@ void vvSlicer::SetImage(vvImage::Pointer image) // Prevent crash when reload -> change slice if outside extent if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) { - Slice = (extent[SliceOrientation*2+1]-extent[SliceOrientation*2])/2.0; + Slice = (extent[SliceOrientation*2+1]+extent[SliceOrientation*2])/2.0; } // Make sure that the required part image has been computed @@ -368,7 +358,7 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay) mOverlayActor = vtkSmartPointer::New(); mOverlayActor->SetInput(mOverlayMapper->GetOutput()); mOverlayActor->SetPickable(0); - mOverlayActor->SetVisibility(false); + mOverlayActor->SetVisibility(true); mOverlayActor->SetOpacity(0.5); } @@ -381,7 +371,8 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay) this->GetRenderer()->AddActor(mOverlayActor); //Synchronize orientation and slice - this->SetSliceOrientation(this->SliceOrientation); + AdjustResliceToSliceOrientation(mOverlayReslice); + this->UpdateDisplayExtent(); this->SetTSlice(mCurrentTSlice); } } @@ -404,45 +395,78 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion) mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData()); if (!mFusionMapper) - mFusionMapper = vtkSmartPointer::New(); + mFusionMapper = vtkSmartPointer::New(); + + vtkSmartPointer lut = vtkLookupTable::New(); + lut->SetRange(0, 1); + lut->SetValueRange(0, 1); + lut->SetSaturationRange(0, 0); + lut->Build(); + mFusionMapper->SetLookupTable(lut); mFusionMapper->SetInput(mFusionReslice->GetOutput()); if (!mFusionActor) { mFusionActor = vtkSmartPointer::New(); mFusionActor->SetInput(mFusionMapper->GetOutput()); mFusionActor->SetPickable(0); - mFusionActor->SetVisibility(false); + mFusionActor->SetVisibility(true); mFusionActor->SetOpacity(0.7); this->GetRenderer()->AddActor(mFusionActor); } //Synchronize orientation and slice - this->SetSliceOrientation(this->SliceOrientation); + AdjustResliceToSliceOrientation(mFusionReslice); + this->UpdateDisplayExtent(); this->SetTSlice(mCurrentTSlice); } } //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index) +{ + bool vis = false; + if (actor_type == "image") { + vis = this->ImageActor->GetVisibility(); + } + else if (actor_type == "vector") { + vis = this->mVFActor->GetVisibility(); + } + else if (actor_type == "overlay") { + vis = this->mOverlayActor->GetVisibility(); + } + else if (actor_type == "fusion") { + vis = this->mFusionActor->GetVisibility(); + } + else if (actor_type == "contour") + vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility(); + + return vis; +} +//------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis) { - if (actor_type == "vector") { + if (actor_type == "image") { + this->ImageActor->SetVisibility(vis); + } + else if (actor_type == "vector") { this->mVFActor->SetVisibility(vis); } - if (actor_type == "overlay") { + else if (actor_type == "overlay") { this->mOverlayActor->SetVisibility(vis); } - if (actor_type == "fusion") { + else if (actor_type == "fusion") { this->mFusionActor->SetVisibility(vis); } - if (actor_type == "contour") + else if (actor_type == "contour") this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis); UpdateDisplayExtent(); } //------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ void vvSlicer::SetVF(vvImage::Pointer vf) { @@ -731,12 +755,14 @@ void vvSlicer::SetSliceOrientation(int orientation) // of the displayed image in the slicing direction. void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice) { - // Reset autocrop - double origin[3] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX}; - double spacing[3] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX}; - reslice->SetOutputOrigin(origin); - reslice->SetOutputSpacing(spacing); + // Reset autocrop and update output information + reslice->SetOutputOriginToDefault(); + reslice->SetOutputSpacingToDefault(); reslice->GetOutput()->UpdateInformation(); + + // Ge new origin / spacing + double origin[3]; + double spacing[3]; reslice->GetOutput()->GetOrigin(origin); reslice->GetOutput()->GetSpacing(spacing); @@ -757,12 +783,12 @@ void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice) reslice->SetOutputOrigin(origin); reslice->SetOutputSpacing(spacing); reslice->UpdateInformation(); + reslice->GetOutput()->UpdateInformation(); } //------------------------------------------------------------------------------ //---------------------------------------------------------------------------- -int * vvSlicer::GetExtent() -{ +int * vvSlicer::GetExtent(){ int *w_ext; if (mUseReducedExtent) { w_ext = mReducedExtent; @@ -779,6 +805,7 @@ int vvSlicer::GetOrientation() } //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- void vvSlicer::UpdateDisplayExtent() { @@ -790,13 +817,7 @@ void vvSlicer::UpdateDisplayExtent() // Local copy of extent int w_ext[6]; - for(unsigned int i=0; i<6; i++){ - if (mUseReducedExtent) - w_ext[i] = mReducedExtent[i]; - else - w_ext[i] = input->GetWholeExtent()[i]; - } - + copyExtent(GetExtent(), w_ext); // Set slice value w_ext[ this->SliceOrientation*2 ] = this->Slice; w_ext[ this->SliceOrientation*2+1 ] = this->Slice; @@ -804,34 +825,42 @@ void vvSlicer::UpdateDisplayExtent() // Image actor this->ImageActor->SetDisplayExtent(w_ext); - // Position vector - double position[3] = {0.,0.,0.}; - double positionInc = (Renderer->GetActiveCamera()->GetPosition()[this->SliceOrientation] > this->Slice)?10:-10; - position[this->SliceOrientation] += positionInc; - // Overlay image actor if (mOverlay && mOverlayActor->GetVisibility()) { + AdjustResliceToSliceOrientation(mOverlayReslice); int overExtent[6]; - mOverlayReslice->GetOutput()->UpdateInformation(); this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent); ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent()); mOverlayActor->SetDisplayExtent( overExtent ); - mOverlayActor->SetPosition(position); } - position[this->SliceOrientation] += positionInc; // Fusion image actor if (mFusion && mFusionActor->GetVisibility()) { + AdjustResliceToSliceOrientation(mFusionReslice); int fusExtent[6]; - mFusionReslice->GetOutput()->UpdateInformation(); this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent); ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent()); mFusionActor->SetDisplayExtent(fusExtent); - mFusionActor->SetPosition(position); } - position[this->SliceOrientation] += positionInc; // Vector field actor + double* camera = Renderer->GetActiveCamera()->GetPosition(); + double* image_bounds = ImageActor->GetBounds(); + double position[3] = {0, 0, 0}; + position[this->SliceOrientation] = image_bounds[this->SliceOrientation*2]; + + //print_vector("camera", camera); + //print_vector("image_bounds", image_bounds); + //print_vector("position", position); + + // find where to place the VF actor. to deal with + // z-buffer issues, the VF is placed right in front of the image, + // subject to a small offset. the position actually depends on the + // the location of the camera relative to the image. + double offset = 1; + if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2]) + offset = -1; + if (mVF && mVFActor->GetVisibility()) { int vfExtent[6]; mVF->GetVTKImages()[0]->UpdateInformation(); @@ -842,21 +871,24 @@ void vvSlicer::UpdateDisplayExtent() orientation[this->SliceOrientation] = 0; mGlyphFilter->SetOrientation(orientation[0], orientation[1], orientation[2]); mVFMapper->Update(); + + position[this->SliceOrientation] += offset; mVFActor->SetPosition(position); } - position[this->SliceOrientation] += positionInc; - + // Landmarks actor if (mLandActor) { if (mClipBox) { double bounds [6]; for(unsigned int i=0; i<6; i++) bounds[i] = ImageActor->GetBounds()[i]; - bounds[ this->SliceOrientation*2 ] = ImageActor->GetBounds()[ this->SliceOrientation*2 ]-fabs(0.5/this->GetInput()->GetSpacing()[this->SliceOrientation]); - bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(0.5/this->GetInput()->GetSpacing()[this->SliceOrientation]); + bounds[ this->SliceOrientation*2 ] = ImageActor->GetBounds()[ this->SliceOrientation*2 ]-fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]); + bounds[ this->SliceOrientation*2+1 ] = ImageActor->GetBounds()[ this->SliceOrientation*2+1 ]+fabs(this->GetInput()->GetSpacing()[this->SliceOrientation]); mClipBox->SetBounds(bounds); UpdateLandmarks(); } + + position[this->SliceOrientation] = offset; mLandActor->SetPosition(position); } @@ -880,6 +912,7 @@ void vvSlicer::UpdateDisplayExtent() } } } + } //---------------------------------------------------------------------------- @@ -1017,12 +1050,7 @@ void vvSlicer::ResetCamera() //---------------------------------------------------------------------------- void vvSlicer::SetDisplayMode(bool i) { - this->GetImageActor()->SetVisibility(i); - this->GetAnnotation()->SetVisibility(i); this->GetRenderer()->SetDraw(i); - if (mLandActor) - mLandActor->SetVisibility(i); - pdmA->SetVisibility(i); if (i) UpdateDisplayExtent(); } @@ -1035,7 +1063,11 @@ void vvSlicer::FlipHorizontalView() vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL; if (cam) { double *position = cam->GetPosition(); - switch (this->SliceOrientation) { + double factor[3] = {1, 1, 1}; + factor[this->SliceOrientation] = -1; + cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]); + +/* switch (this->SliceOrientation) { case vtkImageViewer2::SLICE_ORIENTATION_XY: cam->SetPosition(position[0],position[1],-position[2]); break; @@ -1047,7 +1079,8 @@ void vvSlicer::FlipHorizontalView() case vtkImageViewer2::SLICE_ORIENTATION_YZ: cam->SetPosition(-position[0],position[1],position[2]); break; - } + }*/ + this->Renderer->ResetCameraClippingRange(); this->UpdateDisplayExtent(); } @@ -1075,30 +1108,63 @@ void vvSlicer::SetColorWindow(double window) vtkLookupTable* LUT = static_cast(this->GetWindowLevel()->GetLookupTable()); if ( LUT ) { double level = this->GetWindowLevel()->GetLevel(); - LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4); + LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2); LUT->Build(); } this->vtkImageViewer2::SetColorWindow(window); } //---------------------------------------------------------------------------- - //---------------------------------------------------------------------------- void vvSlicer::SetColorLevel(double level) { vtkLookupTable* LUT = static_cast(this->GetWindowLevel()->GetLookupTable()); if ( LUT ) { double window = this->GetWindowLevel()->GetWindow(); - LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4); + LUT->SetTableRange(level-fabs(window)/2,level+fabs(window)/2); LUT->Build(); } this->vtkImageViewer2::SetColorLevel(level); } //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +double vvSlicer::GetOverlayColorWindow() +{ + if(mOverlayMapper) + return mOverlayMapper->GetWindow(); + else + return 0.; +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +double vvSlicer::GetOverlayColorLevel() +{ + if(mOverlayMapper) + return mOverlayMapper->GetLevel(); + else + return 0.; +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicer::SetOverlayColorWindow(double window) +{ + mOverlayMapper->SetWindow(window); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +void vvSlicer::SetOverlayColorLevel(double level) +{ + mOverlayMapper->SetLevel(level); +} +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- // Returns the min an the max value in a 41x41 region around the mouse pointer -void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max) +void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image) { //Get mouse pointer position in view coordinates double fLocalExtents[6]; @@ -1120,8 +1186,8 @@ void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max) //Convert to image pixel coordinates (rounded) int iLocalExtents[6]; for(int i=0; i<3; i++) { - fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i]; - fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i]; + fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - image->GetOrigin()[i])/image->GetSpacing()[i]; + fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - image->GetOrigin()[i])/image->GetSpacing()[i]; iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]); iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]); @@ -1131,7 +1197,7 @@ void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max) } vtkSmartPointer voiFilter = vtkSmartPointer::New(); - voiFilter->SetInput(this->GetInput()); + voiFilter->SetInput(image); voiFilter->SetVOI(iLocalExtents); voiFilter->Update(); if (!voiFilter->GetOutput()->GetNumberOfPoints()) { @@ -1201,7 +1267,9 @@ void vvSlicer::Render() int ix, iy, iz; double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz); - worldPos << "data value : " << value << std::endl; + if(ImageActor->GetVisibility()) + worldPos << "data value : " << value << std::endl; + worldPos << "mm : " << lrint(mCurrent[0]) << ' ' << lrint(mCurrent[1]) << ' ' << lrint(mCurrent[2]) << ' ' @@ -1244,8 +1312,10 @@ void vvSlicer::Render() if (mOverlay && mOverlayActor->GetVisibility()) { - mOverlayMapper->SetWindow(this->GetColorWindow()); - mOverlayMapper->SetLevel(this->GetColorLevel()); + if(mLinkOverlayWindowLevel) { + mOverlayMapper->SetWindow(this->GetColorWindow()); + mOverlayMapper->SetLevel(this->GetColorLevel()); + } mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent()); mOverlayMapper->GetOutput()->Update(); mOverlayMapper->Update(); @@ -1261,13 +1331,11 @@ void vvSlicer::Render() //---------------------------------------------------------------------------- void vvSlicer::UpdateCursorPosition() { - if (this->GetImageActor()->GetVisibility()) { - pdmA->SetVisibility(true); - mCursor[0] = mCurrent[0]; - mCursor[1] = mCurrent[1]; - mCursor[2] = mCurrent[2]; - mCursor[3] = mCurrentTSlice; - } + pdmA->SetVisibility(true); + mCursor[0] = mCurrent[0]; + mCursor[1] = mCurrent[1]; + mCursor[2] = mCurrent[2]; + mCursor[3] = mCurrentTSlice; } //---------------------------------------------------------------------------- @@ -1322,9 +1390,12 @@ void vvSlicer::SetContourSlice() { if (mSurfaceCutActors.size() > 0) for (std::vector::iterator i=mSurfaceCutActors.begin(); - i!=mSurfaceCutActors.end(); i++) + i!=mSurfaceCutActors.end(); i++) { + + (*i)->SetSlicingOrientation(this->SliceOrientation); (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+ this->GetImage()->GetOrigin()[this->SliceOrientation]); + } } //----------------------------------------------------------------------------