X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vv%2FvvSlicer.cxx;h=ed53d2c83b138c600eeabf680da7edd775854cbc;hb=1bd2bf8d3ee24d10708d27d1347eab8467318c94;hp=4f66ee0d9648805bfc03d2d18e78a302ea1f2caa;hpb=9ac2232043d7a08735edf00572ccb6565919fd3d;p=clitk.git diff --git a/vv/vvSlicer.cxx b/vv/vvSlicer.cxx index 4f66ee0..ed53d2c 100644 --- a/vv/vvSlicer.cxx +++ b/vv/vvSlicer.cxx @@ -71,6 +71,7 @@ #include #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10) # include +# include #endif vtkCxxRevisionMacro(vvSlicer, "DummyRevision"); @@ -144,6 +145,7 @@ vvSlicer::vvSlicer() this->InstallPipeline(); mLinkOverlayWindowLevel = true; + mImageVisibility = true; #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10) this->GetImageActor()->GetMapper()->BorderOn(); @@ -153,6 +155,7 @@ vvSlicer::vvSlicer() mConcatenatedTransform = vtkSmartPointer::New(); mConcatenatedFusionTransform = vtkSmartPointer::New(); mConcatenatedOverlayTransform = vtkSmartPointer::New(); + mFirstSetSliceOrientation = true; } //------------------------------------------------------------------------------ @@ -367,6 +370,7 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay) { if (overlay->GetVTKImages().size()) { mOverlay = overlay; + mOverlayVisibility = true; if (!mOverlayReslice) { mOverlayReslice = vtkSmartPointer::New(); @@ -420,6 +424,7 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion, int fusionSequenceCode) mFusionSequenceCode = fusionSequenceCode; if (fusion->GetVTKImages().size()) { mFusion = fusion; + mFusionVisibility = true; if (!mFusionReslice) { mFusionReslice = vtkSmartPointer::New(); @@ -471,21 +476,16 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion, int fusionSequenceCode) 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") || (actor_type == "fusionSequence") ){ - vis = this->mFusionActor->GetVisibility(); - } + if (actor_type == "image") + vis = mImageVisibility; + else if (actor_type == "vector") + vis = mVFVisibility; + else if (actor_type == "overlay") + vis = mOverlayVisibility; + else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ) + vis = mFusionVisibility; else if (actor_type == "contour") vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility(); - return vis; } //------------------------------------------------------------------------------ @@ -493,18 +493,14 @@ bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_ind //------------------------------------------------------------------------------ void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis) { - if (actor_type == "image") { - this->ImageActor->SetVisibility(vis); - } - else if (actor_type == "vector") { - this->mVFActor->SetVisibility(vis); - } - else if (actor_type == "overlay") { - this->mOverlayActor->SetVisibility(vis); - } - else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ){ - this->mFusionActor->SetVisibility(vis); - } + if (actor_type == "image") + mImageVisibility = vis; + else if (actor_type == "vector") + mVFVisibility = vis; + else if (actor_type == "overlay") + mOverlayVisibility = vis; + else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ) + mFusionVisibility = vis; else if (actor_type == "contour") this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis); UpdateDisplayExtent(); @@ -516,6 +512,7 @@ void vvSlicer::SetVF(vvImage::Pointer vf) { if (vf->GetVTKImages().size()) { mVF = vf; + mVFVisibility = true; if (!mAAFilter) { mAAFilter= vtkSmartPointer::New(); @@ -857,15 +854,17 @@ void vvSlicer::SetSliceOrientation(int orientation) // DDV(cursorPos, 3); // SetCurrentPosition(cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]); - if (this->Renderer && this->GetInput()) { + if (mFirstSetSliceOrientation) { + int *range = this->GetSliceRange(); + if (range) + this->Slice = static_cast((range[0] + range[1]) * 0.5); + mFirstSetSliceOrientation = false; + } + else if (this->Renderer && this->GetInput()) { double s = mCursor[orientation]; double sCursor = (s - this->GetInput()->GetOrigin()[orientation])/this->GetInput()->GetSpacing()[orientation]; this->Slice = static_cast(sCursor); } - -// int *range = this->GetSliceRange(); -// if (range) -// this->Slice = static_cast((range[0] + range[1]) * 0.5); this->UpdateOrientation(); this->UpdateDisplayExtent(); @@ -905,8 +904,13 @@ void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice) // Step 1: from world coordinates to image coordinates origin[this->SliceOrientation] -= mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation]; origin[this->SliceOrientation] /= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation]; - // Step 2: round to superior grid positionInc - origin[this->SliceOrientation] = itk::Math::Ceil(origin[this->SliceOrientation]); + + // Step 2: round to nearest grid positionInc. This has been validated as the only + // way to have something consistent with the thickness of a 2D slice visible on the + // other slices. The thickness is accounted for so if the 2D slice is to thin and + // between two slices, one will never be able to see this 2D slice (bug #1883). + origin[this->SliceOrientation] = itk::Math::Round(origin[this->SliceOrientation]); + // Step 3: back to world coordinates origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation]; origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation]; @@ -957,25 +961,44 @@ void vvSlicer::UpdateDisplayExtent() w_ext[ this->SliceOrientation*2+1 ] = this->Slice; // Image actor + this->ImageActor->SetVisibility(mImageVisibility); this->ImageActor->SetDisplayExtent(w_ext); - +#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10) + // Fix for bug #1882 + dynamic_cast(this->ImageActor->GetMapper())->SetOrientation(this->GetOrientation()); +#endif + // Overlay image actor - if (mOverlay && mOverlayActor->GetVisibility()) { + if (mOverlay && mOverlayVisibility) { AdjustResliceToSliceOrientation(mOverlayReslice); int overExtent[6]; this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent); - ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent()); + bool out = ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent()); + mOverlayActor->SetVisibility(!out); mOverlayActor->SetDisplayExtent( overExtent ); +#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10) + // Fix for bug #1882 + dynamic_cast(mOverlayActor->GetMapper())->SetOrientation(this->GetOrientation()); +#endif } + else if(mOverlay) + mOverlayActor->SetVisibility(false); // Fusion image actor - if (mFusion && mFusionActor->GetVisibility()) { + if (mFusion && mFusionVisibility) { AdjustResliceToSliceOrientation(mFusionReslice); int fusExtent[6]; this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent); - ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent()); - mFusionActor->SetDisplayExtent(fusExtent); + bool out = ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent()); + mFusionActor->SetVisibility(!out); + mFusionActor->SetDisplayExtent( fusExtent ); +#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10) + // Fix for bug #1882 + dynamic_cast(mFusionActor->GetMapper())->SetOrientation(this->GetOrientation()); +#endif } + else if(mFusion) + mFusionActor->SetVisibility(false); // Vector field actor double* camera = Renderer->GetActiveCamera()->GetPosition(); @@ -995,11 +1018,12 @@ void vvSlicer::UpdateDisplayExtent() if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2]) offset = -1; - if (mVF && mVFActor->GetVisibility()) { + if (mVF && mVFVisibility) { int vfExtent[6]; mVF->GetVTKImages()[0]->UpdateInformation(); this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetVTKImages()[0], vfExtent); - ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent()); + bool out = ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent()); + mVFActor->SetVisibility(!out); mVOIFilter->SetVOI(vfExtent); int orientation[3] = {1,1,1}; orientation[this->SliceOrientation] = 0; @@ -1009,7 +1033,9 @@ void vvSlicer::UpdateDisplayExtent() position[this->SliceOrientation] += offset; mVFActor->SetPosition(position); } - + else if(mVF) + mVFActor->SetVisibility(false); + // Landmarks actor if (mLandActor) { if (mClipBox) { @@ -1060,26 +1086,23 @@ void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const // From world coordinates to floating point target voxel coordinates dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2]; - // Round to nearest - //targetExtent[i] = itk::Math::Round(dExtents[i]); - targetExtent[i] = itk::Math::Floor(dExtents[i]); + // Round to current slice or larger extent + if(i/2==this->GetOrientation()) + targetExtent[i] = itk::Math::Round(dExtents[i]); + else if(i%2==1) + targetExtent[i] = itk::Math::Ceil(dExtents[i]); + else + targetExtent[i] = itk::Math::Floor(dExtents[i]); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6]) +bool vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6]) { bool out = false; int maxBound = 6; - //2D overlay on 3D image specific case - if (refExtent[4] == refExtent[5]) { - maxBound = 4; - extent[4] = refExtent[4]; - extent[5] = refExtent[5]; - } - for (int i = 0; i < maxBound; i = i+2) { //if we are totally outside the image if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) { @@ -1087,16 +1110,17 @@ void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6]) break; } //crop to the limit of the image - extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i]; - extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1]; - extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i]; - extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1]; + extent[i] = std::max(extent[i], refExtent[i]); + extent[i] = std::min(extent[i], refExtent[i+1]);; + extent[i+1] = std::max(extent[i+1], refExtent[i]); + extent[i+1] = std::min(extent[i+1], refExtent[i+1]);; } if (out) for (int i = 0; i < maxBound; i = i+2) { extent[i] = refExtent[i]; extent[i+1] = refExtent[i]; } + return out; } //---------------------------------------------------------------------------- @@ -1432,12 +1456,12 @@ void vvSlicer::Render() double yCursor = (y - this->GetInput()->GetOrigin()[1])/this->GetInput()->GetSpacing()[1]; double zCursor = (z - this->GetInput()->GetOrigin()[2])/this->GetInput()->GetSpacing()[2]; - if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0] && - xCursor < this->GetImageActor()->GetDisplayExtent()[1]+1 && - yCursor >= this->GetImageActor()->GetDisplayExtent()[2] && - yCursor < this->GetImageActor()->GetDisplayExtent()[3]+1 && - zCursor >= this->GetImageActor()->GetDisplayExtent()[4] && - zCursor < this->GetImageActor()->GetDisplayExtent()[5]+1 ) { + if (xCursor >= this->GetImageActor()->GetDisplayExtent()[0]-0.5 && + xCursor < this->GetImageActor()->GetDisplayExtent()[1]+0.5 && + yCursor >= this->GetImageActor()->GetDisplayExtent()[2]-0.5 && + yCursor < this->GetImageActor()->GetDisplayExtent()[3]+0.5 && + zCursor >= this->GetImageActor()->GetDisplayExtent()[4]-0.5 && + zCursor < this->GetImageActor()->GetDisplayExtent()[5]+0.5 ) { vtkRenderer * renderer = this->Renderer; renderer->WorldToView(x,y,z);