diff --git a/Code/VisuRefac/otbChangeExtractRegionActionHandler.h b/Code/VisuRefac/otbChangeExtractRegionActionHandler.h index eb3ed7adc88dc1705a7a9a79c48462d7db025493..b9fbef72a9a2e664d69219f8a19eff4d92b3e51a 100644 --- a/Code/VisuRefac/otbChangeExtractRegionActionHandler.h +++ b/Code/VisuRefac/otbChangeExtractRegionActionHandler.h @@ -70,11 +70,20 @@ public: { otbMsgDevMacro(<<"ChangeExtractRegionActionHandler::HandleWidgetEvent(): handling ("<<widgetId<<", "<<event<<")"); // Get the clicked index + typename ViewType::ImageWidgetType::PointType screenPoint, imagePoint; + screenPoint[0] = Fl::event_x(); + screenPoint[1] = Fl::event_y(); + + // Transform to image point + imagePoint = m_View->GetScrollWidget()->GetScreenToImageTransform()->TransformPoint(screenPoint); + + // Transform to index typename ViewType::IndexType index; - index[0] = Fl::event_x(); - index[1] = Fl::event_y(); + index[0]=static_cast<int>(imagePoint[0]); + index[1]=static_cast<int>(imagePoint[1]); + // Change scaled extract region center - m_Model->SetExtractRegionCenter(m_View->GetScrollWidget()->ScreenIndexToImageIndex(index)); + m_Model->SetExtractRegionCenter(index); // Update model m_Model->Update(); return true; diff --git a/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h b/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h index 1a43c0f9cfed36a530f9b01f206335d0d7a61a4f..ca019e0e39e528c9f5b0c9cbc5200e35e01baeee 100644 --- a/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h +++ b/Code/VisuRefac/otbChangeScaledExtractRegionActionHandler.h @@ -70,11 +70,20 @@ public: { otbMsgDevMacro(<<"ChangeScaledExtractRegionActionHandler::HandleWidgetEvent(): handling ("<<widgetId<<", "<<event<<")"); // Get the clicked index + typename ViewType::ImageWidgetType::PointType screenPoint, imagePoint; + screenPoint[0] = Fl::event_x(); + screenPoint[1] = Fl::event_y(); + + // Transform to image point + imagePoint = m_View->GetFullWidget()->GetScreenToImageTransform()->TransformPoint(screenPoint); + + // Transform to index typename ViewType::IndexType index; - index[0] = Fl::event_x(); - index[1] = Fl::event_y(); + index[0]=static_cast<int>(imagePoint[0]); + index[1]=static_cast<int>(imagePoint[1]); + // Change scaled extract region center - m_Model->SetScaledExtractRegionCenter(m_View->GetFullWidget()->ScreenIndexToRegionIndex(index)); + m_Model->SetScaledExtractRegionCenter(index); // Update model m_Model->Update(); return true; diff --git a/Code/VisuRefac/otbImageWidget.h b/Code/VisuRefac/otbImageWidget.h index 676c54f0b31e4509ea72b66faee7290635761bd1..f596ae41ff6971037dfdf248ddeba7ebfb9fc1bb 100644 --- a/Code/VisuRefac/otbImageWidget.h +++ b/Code/VisuRefac/otbImageWidget.h @@ -24,6 +24,7 @@ #include "otbImage.h" #include "itkRGBPixel.h" #include "itkFixedArray.h" +#include "otbGlComponent.h" namespace otb @@ -60,9 +61,15 @@ public: /** Region size & index typedef */ typedef typename RegionType::SizeType SizeType; typedef typename RegionType::IndexType IndexType; - - /** Color typedef (used to draw the rectangle, 4th channel is alpha) */ - typedef typename Superclass::ColorType ColorType; + + /** GlComponent typedef */ + typedef GlComponent GlComponentType; + typedef typename GlComponentType::Pointer GlComponentPointerType; + typedef typename GlComponentType::ColorType ColorType; + typedef typename GlComponentType::AffineTransformType AffineTransformType; + typedef typename AffineTransformType::Pointer AffineTransformPointerType; + typedef typename GlComponentType::VectorType VectorType; + typedef typename GlComponentType::PointType PointType; /** Reads the OpenGl buffer from an image pointer * \param image The image pointer, @@ -95,19 +102,9 @@ public: itkSetMacro(SubsamplingRate,unsigned int); itkGetMacro(SubsamplingRate,unsigned int); - /** Convert a screen index to a buffered region index */ - IndexType ScreenIndexToRegionIndex(const IndexType& index ); - - /** Convert a buffered region index to a screen index */ - IndexType RegionIndexToScreenIndex(const IndexType& index); - - /** Convert a screen index to an image index (taking into account - * subsampling rate) */ - IndexType ScreenIndexToImageIndex(const IndexType& index ); - - /** Convert an image index to a screen index (taking into account - * subsamplinh rate) */ - IndexType ImageIndexToScreenIndex(const IndexType& index); + /** Get the image to screen transform */ + itkGetObjectMacro(ImageToScreenTransform,AffineTransformType); + itkGetObjectMacro(ScreenToImageTransform,AffineTransformType); protected: /** Constructor */ @@ -120,9 +117,13 @@ protected: /** Actually render the buffer to the screen. This method is * used by FLTK routines and should not be called on its own. */ + + /** Update the image to screen transform */ + void UpdateImageToScreenTransform(); + virtual void draw(void); - - /** Compute the linear buffer index according to the 2D region and + + /** Compute the linear buffer index according to the 2D region and * its 2D index.This method is used when OTB_GL_USE_ACCEL is ON. * \param index 2D index * \param region 2D region @@ -161,16 +162,16 @@ private: bool m_DisplayRectangle; ColorType m_RectangleColor; - /** Image extent coordinates in the display axis system */ - double m_ImageExtentWidth; - double m_ImageExtentHeight; - double m_ImageExtentX; - double m_ImageExtentY; + /** The display extent */ + RegionType m_Extent; /** If the image is subsampled with respect to the original image, * this indicates the subsampling rate */ unsigned int m_SubsamplingRate; + /** Space to screen transform */ + AffineTransformPointerType m_ImageToScreenTransform; + AffineTransformPointerType m_ScreenToImageTransform; }; // end class } // end namespace otb diff --git a/Code/VisuRefac/otbImageWidget.txx b/Code/VisuRefac/otbImageWidget.txx index bbe04276f97e6aa2b8b1fac0c04ad437cd27d6b6..86a431d98249cdc2c6b93801fe2aa2a1d91ce8cb 100644 --- a/Code/VisuRefac/otbImageWidget.txx +++ b/Code/VisuRefac/otbImageWidget.txx @@ -26,13 +26,17 @@ namespace otb template <class TInputImage> ImageWidget<TInputImage> ::ImageWidget() : m_IsotropicZoom(1.0), m_OpenGlBuffer(NULL), m_OpenGlBufferedRegion(), - m_Rectangle(),m_DisplayRectangle(false),m_RectangleColor(), m_ImageExtentWidth(0), - m_ImageExtentHeight(0), m_ImageExtentX(), m_ImageExtentY(), m_SubsamplingRate(1) + m_Rectangle(),m_DisplayRectangle(false),m_RectangleColor(), m_Extent(), + m_SubsamplingRate(1), m_ImageToScreenTransform(),m_ScreenToImageTransform() { // Default color for rectangle m_RectangleColor.Fill(0.); m_RectangleColor[0]=1.0; m_RectangleColor[3]=1.0; + + // Initialize space to screen transform and inverse + m_ImageToScreenTransform = AffineTransformType::New(); + m_ScreenToImageTransform = AffineTransformType::New(); } template <class TInputImage> @@ -120,6 +124,41 @@ ImageWidget<TInputImage> m_OpenGlBufferedRegion = region; } +template <class TInputImage> +void +ImageWidget<TInputImage> +::UpdateImageToScreenTransform() +{ + assert(m_IsotropicZoom>0 && "Isotropic zoom should be non null positive."); + + typename RegionType::IndexType index; + typename RegionType::SizeType size; + // Update image extent + size[0]= static_cast<unsigned int>(m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[0])); + size[1]= static_cast<unsigned int>(m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[1])); + index[0] = (this->w()-size[0])/2; + index[1] = (this->h()-size[1])/2; + m_Extent.SetIndex(index); + m_Extent.SetSize(size); + + // Image to screen matrix + typename AffineTransformType::MatrixType s2iMatrix; + s2iMatrix.Fill(0); + const double s2iSpacing =(m_SubsamplingRate)/m_IsotropicZoom; + s2iMatrix(0,0)=s2iSpacing; + s2iMatrix(1,1)=s2iSpacing; + m_ScreenToImageTransform->SetMatrix(s2iMatrix); + + // Image to screen translation + typename AffineTransformType::OutputVectorType translation; + translation[0]= m_SubsamplingRate * (m_OpenGlBufferedRegion.GetIndex()[0]-m_Extent.GetIndex()[0]/m_IsotropicZoom); + translation[1]= m_SubsamplingRate * (m_OpenGlBufferedRegion.GetIndex()[0]-m_Extent.GetIndex()[0]/m_IsotropicZoom); + m_ScreenToImageTransform->SetTranslation(translation); + + // Compute the inverse transform + m_ScreenToImageTransform->GetInverse(m_ImageToScreenTransform); +} + template <class TInputImage> void ImageWidget<TInputImage> @@ -135,16 +174,14 @@ ImageWidget<TInputImage> return; } - // Image extent - m_ImageExtentWidth = m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[0]); - m_ImageExtentHeight = m_IsotropicZoom*static_cast<double>(m_OpenGlBufferedRegion.GetSize()[1]); - m_ImageExtentX = (static_cast<double>(this->w())-m_ImageExtentWidth)/2; - m_ImageExtentY = (static_cast<double>(this->h())-m_ImageExtentHeight)/2; + // Update the space to screen transform + this->UpdateImageToScreenTransform(); + if(!this->GetUseGlAcceleration()) { // Set the pixel Zoom - glRasterPos2f(m_ImageExtentX,m_ImageExtentY); + glRasterPos2f(m_Extent.GetIndex()[0],m_Extent.GetIndex()[1]); glPixelZoom(m_IsotropicZoom,m_IsotropicZoom); // display the image @@ -167,90 +204,41 @@ ImageWidget<TInputImage> glBindTexture (GL_TEXTURE_2D, texture); glBegin (GL_QUADS); glTexCoord2f (0.0, 1.0); - glVertex3f (m_ImageExtentX,m_ImageExtentY, 0.0); + glVertex3f (m_Extent.GetIndex()[0],m_Extent.GetIndex()[1], 0.0); glTexCoord2f (1.0, 1.0); - glVertex3f (m_ImageExtentX+m_ImageExtentWidth, m_ImageExtentY, 0.0); + glVertex3f (m_Extent.GetIndex()[0]+m_Extent.GetSize()[0], m_Extent.GetIndex()[1], 0.0); glTexCoord2f (1.0, 0.0); - glVertex3f (m_ImageExtentX+m_ImageExtentWidth,m_ImageExtentY+m_ImageExtentHeight, 0.0); + glVertex3f (m_Extent.GetIndex()[0]+m_Extent.GetSize()[0],m_Extent.GetIndex()[1]+m_Extent.GetSize()[1], 0.0); glTexCoord2f (0.0, 0.0); - glVertex3f (m_ImageExtentX,m_ImageExtentY+m_ImageExtentHeight, 0.0); + glVertex3f (m_Extent.GetIndex()[0],m_Extent.GetIndex()[1]+m_Extent.GetSize()[1], 0.0); glEnd (); glDisable(GL_TEXTURE_2D); } - // Draw the rectangle if necessary - if(m_DisplayRectangle) - { - typename RegionType::IndexType index; - typename RegionType::SizeType size; - - index = m_Rectangle.GetIndex(); - // UL left in image space is LR in opengl space, so we need to get - // the real upper left - index[1]+=m_Rectangle.GetSize()[1]; - index = ImageIndexToScreenIndex(index); +// // Draw the rectangle if necessary +// if(m_DisplayRectangle) +// { +// typename RegionType::IndexType index; +// typename RegionType::SizeType size; + +// index = m_Rectangle.GetIndex(); +// // UL left in image space is LR in opengl space, so we need to get +// // the real upper left +// index[1]+=m_Rectangle.GetSize()[1]; +// index = ImageIndexToScreenIndex(index); - size[0]= static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[0]/m_SubsamplingRate)*m_IsotropicZoom); - size[1] = static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[1]/m_SubsamplingRate)*m_IsotropicZoom); +// size[0]= static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[0]/m_SubsamplingRate)*m_IsotropicZoom); +// size[1] = static_cast<unsigned int>(static_cast<double>(m_Rectangle.GetSize()[1]/m_SubsamplingRate)*m_IsotropicZoom); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(m_RectangleColor[0],m_RectangleColor[1],m_RectangleColor[2],m_RectangleColor[3]); - glBegin(GL_LINE_LOOP); - gl_rect(index[0],index[1],size[0],size[1]); - glEnd(); - glDisable(GL_BLEND); - } -} - -template <class TInputImage> -typename ImageWidget<TInputImage> -::IndexType -ImageWidget<TInputImage> -::ScreenIndexToRegionIndex(const IndexType & index) -{ - IndexType resp; - resp[0] = static_cast<int>(m_OpenGlBufferedRegion.GetIndex()[0]+static_cast<double>(index[0]-m_ImageExtentX)/m_IsotropicZoom); - resp[1] = static_cast<int>(m_OpenGlBufferedRegion.GetIndex()[1]+static_cast<double>(index[1]-m_ImageExtentY)/m_IsotropicZoom); - return resp; -} - -template <class TInputImage> -typename ImageWidget<TInputImage> -::IndexType -ImageWidget<TInputImage> -::ScreenIndexToImageIndex(const IndexType & index) -{ - IndexType resp = ScreenIndexToRegionIndex(index); - resp[0]*=m_SubsamplingRate; - resp[1]*=m_SubsamplingRate; - return resp; +// glEnable(GL_BLEND); +// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// glColor4f(m_RectangleColor[0],m_RectangleColor[1],m_RectangleColor[2],m_RectangleColor[3]); +// glBegin(GL_LINE_LOOP); +// gl_rect(index[0],index[1],size[0],size[1]); +// glEnd(); +// glDisable(GL_BLEND); +// } } - -template <class TInputImage> -typename ImageWidget<TInputImage> -::IndexType -ImageWidget<TInputImage> -::RegionIndexToScreenIndex(const IndexType & index) -{ - IndexType resp; - resp[0]=static_cast<int>(m_ImageExtentX+(index[0]-m_OpenGlBufferedRegion.GetIndex()[0])*m_IsotropicZoom); - resp[1]=static_cast<int>(m_ImageExtentY+m_ImageExtentHeight-(index[1]-m_OpenGlBufferedRegion.GetIndex()[1])*m_IsotropicZoom); - return resp; -} - -template <class TInputImage> -typename ImageWidget<TInputImage> -::IndexType -ImageWidget<TInputImage> -::ImageIndexToScreenIndex(const IndexType & index) -{ - IndexType resp; - resp[0]=static_cast<int>(m_ImageExtentX+(index[0]/m_SubsamplingRate-m_OpenGlBufferedRegion.GetIndex()[0])*m_IsotropicZoom); - resp[1]=static_cast<int>(m_ImageExtentY+m_ImageExtentHeight-(index[1]/m_SubsamplingRate-m_OpenGlBufferedRegion.GetIndex()[1])*m_IsotropicZoom); - return resp; -} - } #endif diff --git a/Code/VisuRefac/otbPixelDescriptionActionHandler.h b/Code/VisuRefac/otbPixelDescriptionActionHandler.h index 527b153b4400ef969600ef39d847522fd4e20075..05110e4aa45487e4b97858829c744ea1723cb31f 100644 --- a/Code/VisuRefac/otbPixelDescriptionActionHandler.h +++ b/Code/VisuRefac/otbPixelDescriptionActionHandler.h @@ -96,14 +96,22 @@ public: } case FL_MOVE: { - // Get the hovered index - IndexType index; - index[0]=Fl::event_x(); - index[1]=Fl::event_y(); - // Convert to image index - index = sourceWidget->ScreenIndexToImageIndex(index); + // Get the clicked index + typename ViewType::ImageWidgetType::PointType screenPoint, imagePoint; + screenPoint[0] = Fl::event_x(); + screenPoint[1] = Fl::event_y(); + + // Transform to image point + imagePoint = sourceWidget->GetScreenToImageTransform()->TransformPoint(screenPoint); + + // Transform to index + typename ViewType::IndexType index; + index[0]=static_cast<int>(imagePoint[0]); + index[1]=static_cast<int>(imagePoint[1]); + // Communicate new index to model m_Model->UpdatePixelDescription(index); + return true; break; }