diff --git a/Code/Visu/otbImageAlternateViewer.h b/Code/Visu/otbImageAlternateViewer.h index 8bd373f14b8e83c61a427a0948d49622fb7694b1..480479aea8e31dad1c1af1f505c3d0a0149332b2 100644 --- a/Code/Visu/otbImageAlternateViewer.h +++ b/Code/Visu/otbImageAlternateViewer.h @@ -108,6 +108,10 @@ class ITK_EXPORT ImageAlternateViewer itkSetObjectMacro(Image,ImageType); itkGetObjectMacro(Image,ImageType); + + itkSetObjectMacro(SecondImage,ImageType); + itkGetObjectMacro(SecondImage,ImageType); + itkSetMacro(DisplayExtent,RegionType); itkGetMacro(DisplayExtent,RegionType); @@ -161,11 +165,19 @@ protected: RegionType GetAdditionalBufferRegion(unsigned int i); - unsigned char * CreateAdditionalBuffer(RegionType region); + unsigned char * CreateAdditionalBuffer(RegionType region,ImagePointerType image); virtual void MergeBuffersAndFreeMemory(std::vector<unsigned char *> bufferList, std::vector<RegionType> bufferRegionList); + + virtual void AdditionalRedraw(void); + + virtual void DecorationRedraw(void); + virtual void DrawRegionBoundary(RegionType& region); + + virtual long IndexInOldGrid(PointType point, PointType oldUpperLeft, SpacingType spacing, SizeType size); + RegionType ComputeRequestedRegion(RegionType ®ion); /**PrintSelf method */ virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; @@ -230,9 +242,24 @@ private: /** Prevent messing around with simultaneous update */ bool m_Updating; - + /** Region splitter */ SplitterPointerType m_Splitter; - + /** Swith the drag mode */ + bool m_Drag; + /** Count drag events */ + unsigned int m_DragEventCounter; + /** Remember the mouse pos in drag mode */ + IndexType m_OldMousePos; + + /** The second image */ + ImagePointerType m_SecondImage; + /** The subwindow region */ + RegionType m_SubWindowRegion; + /** subwindow mode switch */ + bool m_SubWindowMode; +/** subwindow mode switch */ + bool m_SubWindowMove; + }; }// End namespace otb #ifndef OTB_MANUAL_INSTANTIATION diff --git a/Code/Visu/otbImageAlternateViewer.txx b/Code/Visu/otbImageAlternateViewer.txx index 3db902d6a0099919981b10757943f5b4968386dc..9daddfafe794106c861ede65a27001f32bd2cd47 100644 --- a/Code/Visu/otbImageAlternateViewer.txx +++ b/Code/Visu/otbImageAlternateViewer.txx @@ -24,7 +24,7 @@ PURPOSE. See the above copyright notices for more information. #include "otbMath.h" #include "itkTimeProbe.h" #include "GL/glu.h" - +#include "itkMacro.h" namespace otb { @@ -55,8 +55,8 @@ namespace otb bsplineInterpolator->SetSplineOrder(3); - m_ZoomInInterpolator = WindowedSincInterpolatorType::New(); - // m_ZoomInInterpolator=DefaultInterpolatorType::New(); + // m_ZoomInInterpolator = WindowedSincInterpolatorType::New(); + m_ZoomInInterpolator=DefaultInterpolatorType::New(); // m_ZoomInInterpolator=bsplineInterpolator; m_ZoomOutInterpolator = DefaultInterpolatorType::New(); @@ -89,6 +89,14 @@ namespace otb m_ZoomState = 0; m_Splitter=SplitterType::New(); m_Updating = false; + m_Drag = false; + m_DragEventCounter = 0; + m_OldMousePos.Fill(0); + + m_SubWindowRegion.SetIndex(index); + m_SubWindowRegion.SetSize(nullSize); + m_SubWindowMode = false; + m_SubWindowMove = false; } /** * Destructor @@ -156,26 +164,35 @@ namespace otb { if(m_Updating) return; - m_Updating = true; // avoid odd sizes if(w%2==1) w+=1; if(h%2==1) h+=1; - IndexType index; - SizeType size; + IndexType index,subWindowIndex; + SizeType size,subWindowSize; m_OldDisplayExtent=m_DisplayExtent; index[0]=x; index[1]=y; size[0]=w; size[1]=h; + + subWindowIndex[0] = 3*static_cast<long>(size[0])/8; + subWindowIndex[1] = 3*static_cast<long>(size[1])/8; + subWindowSize[0] = size[0]/4; + subWindowSize[1] = size[1]/4; + + m_SubWindowRegion.SetIndex(subWindowIndex); + m_SubWindowRegion.SetSize(subWindowSize); + m_DisplayExtent.SetIndex(index); m_DisplayExtent.SetSize(size); + + //comment std::cout<<"New display extent: "<<m_DisplayExtent<<std::endl; this->Fl_Gl_Window::resize(x,y,w,h); this->redraw(); - m_Updating = false; } /** * Set view mode to RGB. @@ -224,28 +241,101 @@ namespace otb ImageAlternateViewer<TPixel> ::draw(void) { - IncrementalOpenGlBufferUpdate(); - ResetOpenGlContext(); - this->Draw(m_OpenGlBuffer,m_BufferedRegion); - + if(!m_Updating) + { + m_Updating = true; + IncrementalOpenGlBufferUpdate(); + ResetOpenGlContext(); + this->Draw(m_OpenGlBuffer,m_BufferedRegion); + //COMMENT std::cout<<"Buffered region: "<<m_BufferedRegion<<std::endl; + + if(!m_Drag) + { + AdditionalRedraw(); + } + m_Updating = false; + } + } + + + template <class TPixel> + void + ImageAlternateViewer<TPixel> + ::AdditionalRedraw(void) + { std::vector<unsigned char *> bufferList; std::vector<RegionType> bufferRegionList; - + if(m_BufferedRegion!=m_DisplayExtent) { for(unsigned int i = 0;i<8;++i) { RegionType additionalBufferRegion = GetAdditionalBufferRegion(i); - //comment std::cout<<"Additional region required: "<<additionalBufferRegion<<std::endl; - unsigned char * additionalBuffer = CreateAdditionalBuffer(additionalBufferRegion); + //COMMENT std::cout<<"Additional region required: "<<additionalBufferRegion<<std::endl; + unsigned char * additionalBuffer = CreateAdditionalBuffer(additionalBufferRegion,m_Image); this->Draw(additionalBuffer,additionalBufferRegion); bufferList.push_back(additionalBuffer); bufferRegionList.push_back(additionalBufferRegion); } + DecorationRedraw(); MergeBuffersAndFreeMemory(bufferList,bufferRegionList); } + if(m_SubWindowMode) + { + unsigned char * subWindowBuffer = CreateAdditionalBuffer(m_SubWindowRegion,m_SecondImage); + this->Draw(subWindowBuffer,m_SubWindowRegion); + delete [] subWindowBuffer; + } + DecorationRedraw(); + } + + + template <class TPixel> + void + ImageAlternateViewer<TPixel> + ::DecorationRedraw(void) + { + if(m_SubWindowMode) + { + this->DrawRegionBoundary(m_SubWindowRegion); + } + itk::OStringStream oss; + oss<<"Zoom: "<<m_OpenGlIsotropicZoom<<", scale: "<<m_SpacingZoomFactor; + gl_color(FL_RED); + gl_font(FL_SCREEN_BOLD,10); + gl_draw(oss.str().c_str(),static_cast<int>(m_DisplayExtent.GetIndex()[0])+10,static_cast<int>(m_DisplayExtent.GetIndex()[1])+10); + swap_buffers(); + glFlush(); + } + + template <class TPixel> + long + ImageAlternateViewer<TPixel> + ::IndexInOldGrid(PointType point, PointType oldUpperLeft, SpacingType spacing, SizeType size) + { + long resp; + double x = (point[0]-oldUpperLeft[0])/spacing[0]; + double y = (point[1]-oldUpperLeft[1])/spacing[1]; + + // std::cout<<"x: "<<x<<", y: "<<y<<std::endl; + + if ((vcl_floor(x)!=x)||(vcl_floor(y)!=y)) + { + resp=-1; + } + else if(x<0||x>size[0]||y<0||y>size[1]) + { + resp = -1; + } + else + { + resp = 4*(static_cast<long>(y)*size[0]+static_cast<long>(x)); + } + + return resp; } + template <class TPixel> void ImageAlternateViewer<TPixel> @@ -255,8 +345,19 @@ namespace otb focusOffset[0]=static_cast<long>(static_cast<double>(m_ViewedRegionCenter[0]-m_OldViewedRegionCenter[0])/m_SpacingZoomFactor); focusOffset[1]=static_cast<long>(static_cast<double>(m_ViewedRegionCenter[1]-m_OldViewedRegionCenter[1])/m_SpacingZoomFactor); + //COMMENT std::cout<<"Focus offset: "<<focusOffset<<std::endl; IndexType newBufferedRegionIndex; + + SizeType newBufferedRegionSize; + + newBufferedRegionSize[0]=static_cast<unsigned long>(static_cast<double>((m_BufferedRegion.GetSize()[0])*m_OldSpacingZoomFactor/m_SpacingZoomFactor)); + newBufferedRegionSize[1]=static_cast<unsigned long>(static_cast<double>((m_BufferedRegion.GetSize()[1])*m_OldSpacingZoomFactor/m_SpacingZoomFactor)); + + m_OldBufferedRegion = m_BufferedRegion; + + m_BufferedRegion.SetSize(newBufferedRegionSize); + newBufferedRegionIndex[0]=(static_cast<long>(m_DisplayExtent.GetSize()[0]) -static_cast<long>(m_BufferedRegion.GetSize()[0]))/2; newBufferedRegionIndex[1]=(static_cast<long>(m_DisplayExtent.GetSize()[1]) @@ -265,22 +366,195 @@ namespace otb newBufferedRegionIndex[1]-=focusOffset[1]; //std::cout<<"NewBufferedRegionIndex: "<<newBufferedRegionIndex<<std::endl; m_BufferedRegion.SetIndex(newBufferedRegionIndex); - m_OldViewedRegionCenter = m_ViewedRegionCenter; + // m_OldViewedRegionCenter = m_ViewedRegionCenter; + //std::cout<<"New buffered region: "<<m_BufferedRegion<<std::endl; + PointType center; + m_Image->TransformIndexToPhysicalPoint(m_ViewedRegionCenter,center); + //COMMENT std::cout<<"Center: "<<center<<std::endl; if(m_SpacingZoomFactor != m_OldSpacingZoomFactor) { - SizeType newSize; - newSize.Fill(0); - m_BufferedRegion.SetSize(newSize); - IndexType newIndex; - newIndex[0]= static_cast<long>(m_DisplayExtent.GetSize()[0])/2; - newIndex[1]= static_cast<long>(m_DisplayExtent.GetSize()[1])/2; - m_BufferedRegion.SetIndex(newIndex); + m_BufferedRegion.Crop(m_DisplayExtent); +// std::cout<<"New buffered region2 "<<m_BufferedRegion<<std::endl; + + + SpacingType spacing = m_Image->GetSpacing()*m_SpacingZoomFactor; + SpacingType oldSpacing = m_Image->GetSpacing()*m_OldSpacingZoomFactor; + + PointType origin; + origin[0]=center[0]-(static_cast<double>(this->m_DisplayExtent.GetSize()[0])/2-1)*spacing[0]; + origin[1]=center[1]-(static_cast<double>(this->m_DisplayExtent.GetSize()[1])/2-1)*spacing[1]; + + PointType oldOrigin; + oldOrigin[0]=center[0]-(static_cast<double>(this->m_DisplayExtent.GetSize()[0])/2-1)*oldSpacing[0]; + oldOrigin[1]=center[1]-(static_cast<double>(this->m_DisplayExtent.GetSize()[1])/2-1)*oldSpacing[1]; + + PointType oldBufferedUpperLeft; + oldBufferedUpperLeft[0]=oldOrigin[0]+static_cast<double>(m_OldBufferedRegion.GetIndex()[0])*oldSpacing[0]; + oldBufferedUpperLeft[1]=oldOrigin[1]+static_cast<double>(m_OldBufferedRegion.GetIndex()[1])*oldSpacing[1]; + + PointType bufferedUpperLeft; + bufferedUpperLeft[0]=origin[0]+static_cast<double>(m_BufferedRegion.GetIndex()[0])*spacing[0]; + bufferedUpperLeft[1]=origin[1]+static_cast<double>(m_BufferedRegion.GetIndex()[1])*spacing[1]; + + //std::cout<<"OldBufferedRegion: "<<m_OldBufferedRegion<<std::endl; +// std::cout<<"DisplayExtent: "<<m_DisplayExtent<<std::endl; +// std::cout<<"Center: "<<center<<std::endl; +// std::cout<<"Spacing: "<<spacing<<std::endl; +// std::cout<<"OldSpacing: "<<oldSpacing<<std::endl; +// std::cout<<"BufferedUpperLeft: "<<bufferedUpperLeft<<std::endl; +// std::cout<<"oldBufferedUpperLeft: "<<oldBufferedUpperLeft<<std::endl; + + + unsigned char * newBuffer = NULL; + unsigned int bufferLenght = 4*m_BufferedRegion.GetSize()[0]*m_BufferedRegion.GetSize()[1]; + + newBuffer = new unsigned char[bufferLenght]; + typename ImageListType::Pointer bandList; + unsigned int index = 0; + PixelType interpolatedValue = 0; + PointType interpolatedPos; + interpolatedPos.Fill(0); + unsigned int numberOfSplits=1; + + unsigned int optiCount = 0; + + if(m_SpacingZoomFactor>0) + { + numberOfSplits=max((static_cast<unsigned int>(m_SpacingZoomFactor))*(static_cast<unsigned int>(m_SpacingZoomFactor)),1U); + } + + unsigned int splitterNumberOfSplits = m_Splitter->GetNumberOfSplits(m_BufferedRegion,numberOfSplits); + + //std::cout<<"numberOfSplits: "<<numberOfSplits<<std::endl; + //std::cout<<"splitterNumberOfSplits: "<<splitterNumberOfSplits<<std::endl; + + for(unsigned int splitIndex = 0;splitIndex<splitterNumberOfSplits;++splitIndex) + { + RegionType splitRegion = m_Splitter->GetSplit(splitIndex,splitterNumberOfSplits,m_BufferedRegion); + //std::cout<<splitRegion<<std::endl; + m_RequestedRegion = ComputeRequestedRegion(splitRegion); + if(! m_RequestedRegion.Crop(m_Image->GetLargestPossibleRegion())) + { + SizeType nullSize; + nullSize.Fill(0); + IndexType nullIndex; + nullIndex.Fill(0); + m_RequestedRegion.SetSize(nullSize); + m_RequestedRegion.SetIndex(nullIndex); + } + //std::cout<<"Image Requested Region: "<<m_RequestedRegion<<std::endl; + + // if(!m_RequestedRegion.IsInside(bandList->GetNthElement(m_RedChannelIndex)->GetBufferedRegion())) + // { + //std::cout<<"Requested region: "<<m_RequestedRegion<<std::endl; + m_DecompositionFilter = VectorImageDecompositionFilterType::New(); + m_DecompositionFilter->SetInput(m_Image); + bandList = m_DecompositionFilter->GetOutput(); + bandList->UpdateOutputInformation(); + bandList->GetNthElement(m_RedChannelIndex)->SetRequestedRegion(m_RequestedRegion); + if(m_ViewModelIsRGB) + { + bandList->GetNthElement(m_GreenChannelIndex)->SetRequestedRegion(m_RequestedRegion); + bandList->GetNthElement(m_BlueChannelIndex)->SetRequestedRegion(m_RequestedRegion); + } + bandList->PropagateRequestedRegion(); + bandList->UpdateOutputData(); + + // } + + PointType upperLeft; + upperLeft[0]=origin[0]+static_cast<double>(splitRegion.GetIndex()[0])*spacing[0]; + upperLeft[1]=origin[1]+static_cast<double>(splitRegion.GetIndex()[1])*spacing[1]; + + + interpolatedPos[1]=upperLeft[1]; + for(unsigned int j = 0;j<splitRegion.GetSize()[1];++j) + { + interpolatedPos[0]=upperLeft[0]; + for(unsigned int i = 0;i<splitRegion.GetSize()[0];++i) + { + + long indexInOldBuffer = IndexInOldGrid(interpolatedPos,oldBufferedUpperLeft,oldSpacing,m_OldBufferedRegion.GetSize()); + // std::cout<<interpolatedPos<<" "<<indexInOldBuffer<<std::endl; + if(indexInOldBuffer>0) + { + newBuffer[index] = m_OpenGlBuffer[indexInOldBuffer]; + newBuffer[index+1] = m_OpenGlBuffer[indexInOldBuffer+1]; + newBuffer[index+2] = m_OpenGlBuffer[indexInOldBuffer+2]; + newBuffer[index+3] = m_OpenGlBuffer[indexInOldBuffer+3]; + index+=4; + optiCount++; + } + else + { + m_ZoomInInterpolator->SetInputImage(bandList->GetNthElement(m_RedChannelIndex)); + if( m_ZoomInInterpolator->IsInsideBuffer(interpolatedPos)) + { + interpolatedValue = static_cast<PixelType>(m_ZoomInInterpolator->Evaluate(interpolatedPos)); + } + else + { + interpolatedValue = 0; + } + newBuffer[index] = Normalize(interpolatedValue,m_RedChannelIndex); + if(m_ViewModelIsRGB) + { + m_ZoomInInterpolator->SetInputImage(bandList->GetNthElement(m_GreenChannelIndex)); + if( m_ZoomInInterpolator->IsInsideBuffer(interpolatedPos)) + { + interpolatedValue = static_cast<PixelType>( m_ZoomInInterpolator->Evaluate(interpolatedPos)); + } + else + { + interpolatedValue = 0; + } + newBuffer[index+1] = Normalize(interpolatedValue,m_GreenChannelIndex); + m_ZoomInInterpolator->SetInputImage(bandList->GetNthElement(m_BlueChannelIndex)); + if( m_ZoomInInterpolator->IsInsideBuffer(interpolatedPos)) + { + interpolatedValue = static_cast<PixelType>(m_ZoomInInterpolator->Evaluate(interpolatedPos)); + } + else + { + interpolatedValue = 0; + } + newBuffer[index+2] = Normalize(interpolatedValue,m_BlueChannelIndex); + newBuffer[index+3] = 255; + index+=4; + } + else + { + newBuffer[index+1] = Normalize(interpolatedValue,m_RedChannelIndex); + newBuffer[index+2] = Normalize(interpolatedValue,m_RedChannelIndex); + newBuffer[index+3] = 255; + index+=4; + } + } + interpolatedPos[0] +=spacing[0]; + } + interpolatedPos[1] +=spacing[1]; + } + } + if(m_OpenGlBuffer!=NULL) + { + delete [] m_OpenGlBuffer; + } + m_OpenGlBuffer = newBuffer; + m_OldSpacingZoomFactor = m_SpacingZoomFactor; + //std::cout<<"Optimisation called "<<optiCount<<" times over "<<m_BufferedRegion.GetNumberOfPixels()<<std::endl; } - //comment std::cout<<"New buffered region: "<<m_BufferedRegion<<std::endl; + +// std::cout<<"BufferedRegion: "<<m_BufferedRegion<<std::endl; +// std::cout<<"OldBufferedRegion: "<<m_OldBufferedRegion<<std::endl; +// std::cout<<"BufferedUpperLeft: "<<bufferedUpperLeft<<std::endl; +// std::cout<<"OldBufferedUpperLeft: "<<oldBufferedUpperLeft<<std::endl; +// std::cout<<"Spacing: "<<spacing<<std::endl; +// std::cout<<"OldSpacing: "<<oldSpacing<<std::endl; + } template <class TPixel> @@ -363,89 +637,6 @@ namespace otb index[1] = min(deLR[1],bufLR[1]); size[0] = max(deLR[0]-bufLR[0],0L); size[1] = max(deLR[1]-bufLR[1],0L); - - // case 0: - // index[0]=deIndex[0]; - // index[1]=deIndex[1]; - // size[0]=max(bufIndex[0]-deIndex[0],0L); - // size[1]=max(bufIndex[1]-deIndex[1],0L); - // break; - - // case 1: - // index[0]=max(bufIndex[0],0L); - // index[1]=deIndex[1]; - // // size[0]=max(0L,static_cast<long>(bufSize[0])-vcl_abs(bufIndex[0])); - // size[0]=max(0L,min(static_cast<long>(bufSize[0])-vcl_abs(bufIndex[0]),static_cast<long>(deSize[0])-index[0])); - // size[1]=max(bufIndex[1]-deIndex[1],0L); - // break; - - // case 2: - // index[0]=bufIndex[0]+bufSize[0]; - // index[1]=deIndex[1]; - // size[0]=max(deIndex[0]+static_cast<long>(deSize[0])-bufIndex[0]-static_cast<long>(bufSize[0]),0L); - // size[1]=max(bufIndex[1]-deIndex[1],0L); - // break; - - // case 3: - // index[0]=deIndex[0]; - // index[1]=max(bufIndex[1],0L); - // size[0]=max(bufIndex[0]-deIndex[0], 0L); - // // size[1]=max(0L,static_cast<long>(bufSize[1])-vcl_abs(bufIndex[1])); - // size[1]=max(0L,min(static_cast<long>(bufSize[1])-vcl_abs(bufIndex[1]),static_cast<long>(deSize[1])-index[1])); - - // break; - - // case 4: - // index[0]=bufIndex[0]+bufSize[0]; - // index[1]=max(bufIndex[1],0L); - // size[0]=max(deIndex[0]+static_cast<long>(deSize[0])-bufIndex[0]-static_cast<long>(bufSize[0]),0L); - // // size[1]=max(0L,static_cast<long>(bufSize[1])-vcl_abs(bufIndex[1])); - // size[1]=max(0L,min(static_cast<long>(bufSize[1])-vcl_abs(bufIndex[1]),static_cast<long>(deSize[1])-index[1])); - - // break; - - // case 5: - // index[0]=deIndex[0]; - // index[1]=bufIndex[1]+bufSize[1]; - // size[0]=max(bufIndex[0]-deIndex[0],0L); - // size[1]=max(deIndex[1]+static_cast<long>(deSize[1])-bufIndex[1]-static_cast<long>(bufSize[1]),0L); - // break; - - // case 6: - // index[0]=max(bufIndex[0],0L); - // index[1]=bufIndex[1]+bufSize[1]; - // // size[0]=max(0L,static_cast<long>(bufSize[0])-vcl_abs(bufIndex[0])); - // size[0]=max(0L,min(static_cast<long>(bufSize[0])-vcl_abs(bufIndex[0]),static_cast<long>(deSize[0])-index[0])); - // size[1]=max(deIndex[1]+static_cast<long>(deSize[1])-bufIndex[1]-static_cast<long>(bufSize[1]),0L); - // break; - - // case 7: - // index[0]=bufIndex[0]+bufSize[0]; - // index[1]=bufIndex[1]+bufSize[1]; - // size[0]=max(deIndex[0]+static_cast<long>(deSize[0])-bufIndex[0]-static_cast<long>(bufSize[0]),0L); - // size[1]=max(deIndex[1]+static_cast<long>(deSize[1])-bufIndex[1]-static_cast<long>(bufSize[1]),0L); - // break; - - // size[0]=deSize[0]; - // size[1]=(bufIndex[1] > deIndex[1] ? bufIndex[1]-deIndex[1] : 0); - // index[0]=deIndex[0]; - // index[1]=deIndex[1]; - // break; - // case 1: - - // break; - // case 2: - // size[0]=(deIndex[0]+deSize[0] > bufIndex[0]+bufSize[0] ? deIndex[0]+deSize[0]-bufIndex[0]-bufSize[0] : 0); - // size[1]=bufSize[1]; - // index[0]=bufIndex[0]+bufSize[0]; - // index[1]=max(bufIndex[1],0L); - // break; - // case 3: - // size[0]=deSize[0]; - // size[1]=(deIndex[1]+deSize[1] > bufIndex[1]+bufSize[1] ?deIndex[1]+deSize[1]-bufIndex[1]-bufSize[1] : 0); - // index[0]=deIndex[0]; - // index[1]=bufIndex[1]+bufSize[1]; - // break; } region.SetSize(size); region.SetIndex(index); @@ -490,6 +681,11 @@ namespace otb bufferedLowerRight[0]=bufferedUpperLeft[0]+static_cast<double>(m_BufferedRegion.GetSize()[0]-1)*spacing[0]; bufferedLowerRight[1]=bufferedUpperLeft[1]+static_cast<double>(m_BufferedRegion.GetSize()[1]-1)*spacing[1]; + //COMMENT std::cout<<"UpperLeft: "<<upperLeft<<std::endl; + //COMMENT std::cout<<"LowerRight: "<<lowerRight<<std::endl; + //COMMENT std::cout<<"BufferedUpperLeft: "<<bufferedUpperLeft<<std::endl; + //COMMENT std::cout<<"BufferedLowerRight: "<<bufferedLowerRight<<std::endl; + IndexType lowerRightIndex; IndexType requestedIndex; SizeType requestedSize; @@ -510,7 +706,7 @@ namespace otb template <class TPixel> unsigned char * ImageAlternateViewer<TPixel> - ::CreateAdditionalBuffer(RegionType region) + ::CreateAdditionalBuffer(RegionType region,ImagePointerType image) { itk::TimeProbe total,filter,interpolation; total.Start(); @@ -537,23 +733,22 @@ namespace otb interpolatedPos.Fill(0); unsigned int numberOfSplits=1; - if(m_ZoomState>0) + if(m_SpacingZoomFactor>0) { - numberOfSplits=(m_ZoomState+1)*(m_ZoomState+1); + numberOfSplits=max((static_cast<unsigned int>(m_SpacingZoomFactor))*(static_cast<unsigned int>(m_SpacingZoomFactor)),1U); } - unsigned int splitterNumberOfSplits = m_Splitter->GetNumberOfSplits(region,numberOfSplits); - // std::cout<<"ZoomState: "<<m_ZoomState<<std::endl; -// std::cout<<"Number of splits: "<<numberOfSplits<<std::endl; -// std::cout<<"Zoom out number of splits: "<<splitterNumberOfSplits<<std::endl; + // std::cout<<"ZoomState: "<<m_ZoomState<<std::endl; + // std::cout<<"Number of splits: "<<numberOfSplits<<std::endl; + // std::cout<<"Zoom out number of splits: "<<splitterNumberOfSplits<<std::endl; - SpacingType spacing = m_Image->GetSpacing()*m_SpacingZoomFactor; + SpacingType spacing = image->GetSpacing()*m_SpacingZoomFactor; PointType center; - m_Image->TransformIndexToPhysicalPoint(m_ViewedRegionCenter,center); - + image->TransformIndexToPhysicalPoint(m_ViewedRegionCenter,center); + //COMMENT std::cout<<"Center(ad): "<<center<<std::endl; PointType origin; origin[0]=center[0]-(static_cast<double>(this->m_DisplayExtent.GetSize()[0])/2-1)*spacing[0]; origin[1]=center[1]-(static_cast<double>(this->m_DisplayExtent.GetSize()[1])/2-1)*spacing[1]; @@ -565,29 +760,39 @@ namespace otb PointType upperLeft; upperLeft[0]=origin[0]+(static_cast<double>(splitRegion.GetIndex()[0]))*spacing[0]; upperLeft[1]=origin[1]+(static_cast<double>(splitRegion.GetIndex()[1]))*spacing[1]; - + //COMMENT std::cout<<"Loop upper left: "<<upperLeft<<std::endl; m_RequestedRegion = ComputeRequestedRegion(splitRegion); - m_RequestedRegion.Crop(m_Image->GetLargestPossibleRegion()); - + // std::cout<<"Additional requested region: "<<m_RequestedRegion<<std::endl; + // std::cout<<"Largest possible region: "<<image->GetLargestPossibleRegion()<<std::endl; + if(!m_RequestedRegion.Crop(image->GetLargestPossibleRegion())) + { + SizeType nullSize; + nullSize.Fill(0); + IndexType nullIndex; + nullIndex.Fill(0); + m_RequestedRegion.SetSize(nullSize); + m_RequestedRegion.SetIndex(nullIndex); + } + //std::cout<<"Additional cropped requested region: "<<m_RequestedRegion<<std::endl; -// if(!m_RequestedRegion.IsInside(bandList->GetNthElement(m_RedChannelIndex)->GetBufferedRegion())) -// { - m_DecompositionFilter = VectorImageDecompositionFilterType::New(); - m_DecompositionFilter->SetInput(m_Image); - bandList = m_DecompositionFilter->GetOutput(); - //std::cout<<"Requested region: "<<m_RequestedRegion<<std::endl; - bandList->UpdateOutputInformation(); - bandList->GetNthElement(m_RedChannelIndex)->SetRequestedRegion(m_RequestedRegion); - if(m_ViewModelIsRGB) - { - bandList->GetNthElement(m_GreenChannelIndex)->SetRequestedRegion(m_RequestedRegion); - bandList->GetNthElement(m_BlueChannelIndex)->SetRequestedRegion(m_RequestedRegion); - } - bandList->PropagateRequestedRegion(); - bandList->UpdateOutputData(); + // if(!m_RequestedRegion.IsInside(bandList->GetNthElement(m_RedChannelIndex)->GetBufferedRegion())) + // { + m_DecompositionFilter = VectorImageDecompositionFilterType::New(); + m_DecompositionFilter->SetInput(image); + bandList = m_DecompositionFilter->GetOutput(); + + bandList->UpdateOutputInformation(); + bandList->GetNthElement(m_RedChannelIndex)->SetRequestedRegion(m_RequestedRegion); + if(m_ViewModelIsRGB) + { + bandList->GetNthElement(m_GreenChannelIndex)->SetRequestedRegion(m_RequestedRegion); + bandList->GetNthElement(m_BlueChannelIndex)->SetRequestedRegion(m_RequestedRegion); + } + bandList->PropagateRequestedRegion(); + bandList->UpdateOutputData(); - filter.Stop(); -// } + filter.Stop(); + // } interpolation.Start(); interpolatedPos[1]=upperLeft[1]; @@ -664,26 +869,97 @@ namespace otb ImageAlternateViewer<TPixel> ::handle(int event) { - if(!m_Updating) - m_Updating=true; + if(m_Updating) + return 0; switch(event) { case FL_PUSH: { - int x = Fl::event_x(); - int y = Fl::event_y(); - SpacingType spacing = m_Image->GetSpacing()*m_SpacingZoomFactor; - PointType origin; - origin[0]=static_cast<double>(m_ViewedRegionCenter[0])-static_cast<double>(this->m_DisplayExtent.GetSize()[0]/2)*spacing[0]; - origin[1]=static_cast<double>(m_ViewedRegionCenter[1])-static_cast<double>(this->m_DisplayExtent.GetSize()[1]/2)*spacing[1]; - - PointType newCenter; - newCenter[0]=origin[0]+static_cast<double>(x)*spacing[0]; - newCenter[1]=origin[1]+static_cast<double>(y)*spacing[1]; + if(!m_Drag) + { + m_OldMousePos[0]= static_cast<long int>(static_cast<double>(m_DisplayExtent.GetSize()[0]/2) + +(static_cast<double>(Fl::event_x())-static_cast<double>(m_DisplayExtent.GetSize()[0]/2))/m_OpenGlIsotropicZoom); + m_OldMousePos[1]= static_cast<long int>(static_cast<double>(m_DisplayExtent.GetSize()[1]/2) + +(static_cast<double>(Fl::event_y())-static_cast<double>(m_DisplayExtent.GetSize()[1]/2))/m_OpenGlIsotropicZoom); + // m_OldMousePos[1]= Fl::event_y(); + m_Drag=true; + m_DragEventCounter=0; + + if(m_SubWindowRegion.IsInside(m_OldMousePos)) + { + m_SubWindowMove = true; + } + else + { + m_OldViewedRegionCenter = m_ViewedRegionCenter; + } + } + return 1; + } + + case FL_DRAG: + { + //std::cout<<"FL_DRAG"<<std::endl; + m_Drag=true; + + int x =static_cast<int>(static_cast<double>(m_DisplayExtent.GetSize()[0]/2) + +(Fl::event_x()-static_cast<double>(m_DisplayExtent.GetSize()[0]/2))/m_OpenGlIsotropicZoom); + int y = static_cast<long int>(static_cast<double>(m_DisplayExtent.GetSize()[1]/2) + +(Fl::event_y()-static_cast<double>(m_DisplayExtent.GetSize()[1]/2))/m_OpenGlIsotropicZoom); + if(Fl::event_button()==FL_MIDDLE_MOUSE) + { + if(!m_SubWindowMode) + m_SubWindowMode = true; + IndexType newIndex; + SizeType newSize; + + newIndex[0]=(x>m_OldMousePos[0] ? m_OldMousePos[0] : x); + newIndex[1]=(y>m_OldMousePos[1] ? m_OldMousePos[1] : y); + newSize[0]=vcl_abs(x-m_OldMousePos[0]); + newSize[1]=vcl_abs(y-m_OldMousePos[1]); + m_SubWindowRegion.SetIndex(newIndex); + m_SubWindowRegion.SetSize(newSize); + //COMMENT std::cout<<"new subWindowRegion: "<<m_SubWindowRegion<<std::endl; + this->redraw(); + m_DragEventCounter++; + } + else if(m_SubWindowMove) + { + IndexType index = m_SubWindowRegion.GetIndex(); + index[0]+=(x-m_OldMousePos[0]); + index[1]+=(y-m_OldMousePos[1]); + m_SubWindowRegion.SetIndex(index); + m_OldMousePos[0]=x; + m_OldMousePos[1]=y; + this->redraw(); + m_DragEventCounter++; + } + + else + { + SpacingType spacing = m_Image->GetSpacing()*m_SpacingZoomFactor; + PointType origin; + origin[0]=static_cast<double>(m_OldViewedRegionCenter[0])-static_cast<double>(this->m_DisplayExtent.GetSize()[0]/2)*spacing[0]; + origin[1]=static_cast<double>(m_OldViewedRegionCenter[1])-static_cast<double>(this->m_DisplayExtent.GetSize()[1]/2)*spacing[1]; + PointType newCenter; + newCenter[0]=origin[0]+static_cast<double>(m_OldMousePos[0]-x+static_cast<long>(this->m_DisplayExtent.GetSize()[0])/2)*spacing[0]; + newCenter[1]=origin[1]+static_cast<double>(m_OldMousePos[1]-y+static_cast<long>(this->m_DisplayExtent.GetSize()[1])/2)*spacing[1]; + //COMMENT std::cout<<"Drag focus offset: "<<m_OldMousePos[0]-x<<", "<<m_OldMousePos[1]-y<<std::endl; + m_Image->TransformPhysicalPointToIndex(newCenter,m_ViewedRegionCenter); + this->redraw(); + m_DragEventCounter++; + } + + DecorationRedraw(); + return 1; + } + + case FL_RELEASE: + { m_OldViewedRegionCenter = m_ViewedRegionCenter; - m_Image->TransformPhysicalPointToIndex(newCenter,m_ViewedRegionCenter); - this->redraw(); - m_Updating=false; + m_Drag=false; + AdditionalRedraw(); + m_SubWindowMove = false; return 1; } @@ -691,38 +967,46 @@ namespace otb { int dy = Fl::event_dy(); int oldState = m_ZoomState; - + m_OldSpacingZoomFactor = m_SpacingZoomFactor; m_OpenGlIsotropicZoom -=static_cast<double>(dy)/10; if(m_OpenGlIsotropicZoom>2) { - m_SpacingZoomFactor/=2; m_OpenGlIsotropicZoom = 1; } else if(m_OpenGlIsotropicZoom<1) { m_SpacingZoomFactor*=2; - m_OpenGlIsotropicZoom = 1.9; - + m_OpenGlIsotropicZoom = 1.9; } - - // std::cout<<"Zoom state: "<<m_ZoomState<<std::endl; -// std::cout<<"Old zoom state: "<<oldState<<std::endl; -// std::cout<<"Opengl zoom: "<<m_OpenGlIsotropicZoom<<std::endl; -// std::cout<<"Interpolator zoom factor: "<<m_SpacingZoomFactor<<std::endl; this->redraw(); - m_Updating=false; - return 1; + return 1; + } + case FL_FOCUS: + { + return 1; + } + case FL_UNFOCUS: + { + return 1; + } + case FL_KEYDOWN: + { + if(Fl::event_key()==116) // T kye + { + m_SubWindowMode = !m_SubWindowMode; + this->redraw(); + } + return 1; } } - m_Updating=false; return 0; } template <class TPixel> void ImageAlternateViewer<TPixel> - ::MergeBuffersAndFreeMemory(std::vector<unsigned char *> bufferList, std::vector<RegionType> bufferRegionList) + ::MergeBuffersAndFreeMemory(std::vector<unsigned char *> bufferList, std::vector<RegionType> bufferRegionList) { //std::cout<<"Entering merge method"<<std::endl; if(bufferList.size()!=8 || bufferRegionList.size()!=8) @@ -919,6 +1203,7 @@ namespace otb } // update buffered region + m_OldBufferedRegion = m_BufferedRegion; m_BufferedRegion=m_DisplayExtent; // delete previous buffer if (m_OpenGlBuffer!=NULL) @@ -955,6 +1240,8 @@ namespace otb double movey = static_cast<double>(m_DisplayExtent.GetSize()[1])-static_cast<double>(region.GetIndex()[1])-zoomOffsetY; glBitmap(0,0,0,0,movex,movey,NULL); glPixelZoom(m_OpenGlIsotropicZoom,-m_OpenGlIsotropicZoom); + + // display the image glDrawPixels(region.GetSize()[0], region.GetSize()[1], @@ -968,6 +1255,43 @@ namespace otb total.Stop(); } + + template <class TPixel> + void + ImageAlternateViewer<TPixel> + ::DrawRegionBoundary(RegionType& region) + { + double zoomOffsetX = 0; + double zoomOffsetY = 0; + + zoomOffsetX = (1-m_OpenGlIsotropicZoom)*(static_cast<double>(m_DisplayExtent.GetSize()[0]/2)-static_cast<double>(region.GetIndex()[0])); + zoomOffsetY = (1-m_OpenGlIsotropicZoom)*( static_cast<double>(m_DisplayExtent.GetSize()[1]/2)-static_cast<double>(region.GetIndex()[1])); + double minx,maxx,miny,maxy; + + minx = static_cast<double>(region.GetIndex()[0])/**m_OpenGlIsotropicZoom*/+zoomOffsetX; + maxx = minx + static_cast<double>(region.GetSize()[0])*m_OpenGlIsotropicZoom; + miny = static_cast<double>(m_DisplayExtent.GetSize()[1])-static_cast<double>(region.GetIndex()[1])/**m_OpenGlIsotropicZoom*/-zoomOffsetY; + maxy = miny-static_cast<double>(region.GetSize()[1])*m_OpenGlIsotropicZoom; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1,0,0,1); + glBegin(GL_LINE_LOOP); + glVertex2f(minx,miny); + glVertex2f(minx,maxy); + glVertex2f(maxx,maxy); + glVertex2f(maxx,miny); + glEnd(); + glDisable(GL_BLEND); + + } + + + + + + + // template <class TPixel> // void // ImageAlternateViewer<TPixel>