imedgine_image_viewer.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------
00012 //---------------------------------------------------
00013 
00014 #include "imedgine_image_viewer.h"
00015 #include "image_pixel_view.h"
00016 #include "../controller/controller.h"
00017 #include "polyline_ROI.h"
00018 
00019 #include <Inventor/actions/SoRayPickAction.h>
00020 #include <Inventor/SoPickedPoint.h>
00021 #include <Inventor/Qt/SoQtCursor.h>
00022 #include <Inventor/nodes/SoTexture2.h>
00023 #include <Inventor/nodes/SoBaseColor.h>
00024 
00025 #include <QPixmap>
00026 #include <QImage>
00027 #include <QDataStream>
00028 
00029 #include <sstream>
00030 #include <limits>
00031 
00032 #include <stdio.h>
00033 
00034 namespace imedgine 
00035 {
00036   ImedgineImageViewer::ImedgineImageViewer(
00037       ImagePixelView* image_view, QWidget* parent, const char* name /*=NULL*/)
00038   : ImedgineViewer(parent, name),
00039     image_view_(image_view),
00040     view_mode_(DEFAULT_MODE),
00041     region_of_interest_(0),      
00042     double_click_check_time_(0.0),
00043     mouse_movement_scaling_factor_(1.0) 
00044   {
00045     QWidget* widget = this->buildWidget(this->getParentWidget());
00046     this->setBaseWidget(widget);
00047     this->setDecoration(false);  
00048       
00049     popup_button_sep_ = new SoSeparator;  
00050     image_view_->getStaticSceneSeparator()->addChild(popup_button_sep_);  
00051     
00052     SoTransform* popup_button_transform_ = new SoTransform;
00053     popup_button_transform_->translation = SbVec3f(-0.94, 0.93, 0.3);
00054     popup_button_sep_->addChild(popup_button_transform_);      
00055     
00056     SoTexture2* popup_button_texture = new SoTexture2;
00057     popup_button_sep_->addChild(popup_button_texture);
00058     //QPixmap temp_pixmap(":/icons/axial.png");
00059     QPixmap temp_pixmap(":/icons/document-open.png");
00060     
00061     unsigned char* converted_image = temp_pixmap.toImage().bits();  
00062     
00063 /*    for (int index = 0; index <= temp_pixmap.toImage().numBytes(); index += 4)
00064     {
00065       unsigned char tmp;   
00066       
00067       tmp = converted_image[index];
00068       converted_image[index] = converted_image[index+3];
00069       converted_image[index+3] = tmp;       
00070     
00071       tmp = converted_image[index+1];
00072       converted_image[index+1] = converted_image[index+2];
00073       converted_image[index+2] = tmp;
00074     } */    
00075     
00076     std::cout << "Num bytes: " << temp_pixmap.toImage().numBytes() << std::endl;
00077     std::cout << "Num bytes per line: " << temp_pixmap.toImage().bytesPerLine() << std::endl;
00078     std::cout << "Height: " << temp_pixmap.toImage().size().height()  << std::endl;
00079     std::cout << "Width: " << temp_pixmap.toImage().size().width()  << std::endl; 
00080        
00081     popup_button_texture->image.setValue(
00082         SbVec2s(16,16), 
00083         4, converted_image);
00084       
00085     popup_button_ = new SoCube;  
00086     popup_button_->depth = 0;
00087     popup_button_->height = 0.1;  
00088     popup_button_->width = 0.1;  
00089     popup_button_sep_->addChild(popup_button_); 
00090     
00091     status_info_sep_ = new SoSeparator;
00092     image_view_->getStaticSceneSeparator()->addChild(status_info_sep_); 
00093     SoBaseColor* status_info_color = new SoBaseColor;
00094     status_info_color->rgb = SbVec3f(0, 1, 0); // fluorescent green  
00095     status_info_sep_->addChild(status_info_color);
00096      
00097     //create dataset status info 
00098     dataset_status_info_transform_ = new SoTransform;
00099     dataset_status_info_transform_->translation.setValue(-1.8, 0, 0);  
00100     status_info_sep_->addChild(dataset_status_info_transform_);  
00101     dataset_status_info_text_ = new SoText2;
00102     dataset_status_info_text_->justification = SoText2::LEFT;  
00103     status_info_sep_->addChild(dataset_status_info_text_);    
00104 
00105     region_of_interest_sep_ = new SoSeparator;
00106     image_view_->getDynamicSceneSeparator()->addChild(region_of_interest_sep_); 
00107        
00108     // calculate the mouse movement scaling factor depending on the minimum 
00109     // and maximum pixel value of the image
00110     mouse_movement_scaling_factor_ = (image_view_->getMaxPixelValue() -
00111             image_view_->getMinPixelValue()) / 1200.0;
00112   }
00113   
00114   //--------------------------------------------------  
00115   
00116   ImedgineImageViewer::~ImedgineImageViewer()
00117   {
00118 #ifdef DEBUG
00119     std::cout << "Deleting ImedgineImageViewer" << std::endl;
00120 #endif
00121   }
00122 
00123   //--------------------------------------------------   
00124   
00125   SbBool ImedgineImageViewer::processSoEvent(const SoEvent * const ev)
00126   { 
00127     const SoType type(ev->getTypeId());;
00128     
00129     //set DEFAULT cursor
00130     //FIXME: should not set for every event - but where else it is possible?  
00131     this->setComponentCursor(SoQtCursor::DEFAULT);   
00132     
00133     if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) 
00134     {   
00135       const SoLocation2Event * event = dynamic_cast<const SoLocation2Event *>(ev);  
00136       SbVec2s pos = ev->getPosition();   
00137       
00138       if (view_mode_ == ZOOM_IN_OUT_MODE)
00139       {  
00140         //set ZOOM cursor    
00141         this->setComponentCursor(SoQtCursor::getZoomCursor());         
00142         
00143         int diff = last_position_[Y_DIMENSION] - pos[Y_DIMENSION]; 
00144         
00145         SbViewVolume view_volume = this->getCamera()->getViewVolume();    
00146             
00147         //zoom in    
00148         if (diff < 0) 
00149         {     
00150           //restrict camera movement            
00151           if (view_volume.getHeight() < 0.3)
00152           {
00153             return(false);
00154           }          
00155           else if (diff == 0)
00156           {
00157             return(false);
00158           }                           
00159           else if (diff % 3 == 0)
00160           {     
00161             last_position_ = event->getPosition();       
00162             last_button_click_event_->setButton(SoMouseButtonEvent::BUTTON5);       
00163             return(ImedgineViewer::processSoEvent(last_button_click_event_.get()));
00164           }
00165         }
00166         //zoom out    
00167         else
00168         {   
00169           //restrict camera movement         
00170           if (view_volume.getHeight() > 5)
00171           {
00172             return(false);
00173           }              
00174           else if (diff == 0)
00175           {
00176             return(false);
00177           }                           
00178           else if (diff % 3 == 0)
00179           {     
00180             last_position_ = event->getPosition();         
00181             last_button_click_event_->setButton(SoMouseButtonEvent::BUTTON4);          
00182             return(ImedgineViewer::processSoEvent(last_button_click_event_.get()));
00183           }
00184         }      
00185       }
00186     }   
00187     
00188     if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) 
00189     {
00190       const SoMouseButtonEvent * const event = dynamic_cast<const SoMouseButtonEvent *>(ev);
00191       const int button = event->getButton();
00192   
00193       const SbVec2s size(this->getGLSize());
00194       const SbVec2s pos(ev->getPosition());      
00195       
00196       switch (button) 
00197       {
00198         case SoMouseButtonEvent::BUTTON1:
00199         {                                         
00200           if (SoMouseButtonEvent::isButtonPressEvent(event, 
00201               SoMouseButtonEvent::BUTTON1))
00202           {       
00204             
00205             //window/level movement        
00206             left_mouse_button_press_location_ = pos;        
00207             
00208             //Polyline ROI
00209             if (Controller::getInstance().getGuiInteractionMode() ==
00210                 REGION_OF_INTEREST_POLY_LINE_MODE)
00211             {       
00212               if (region_of_interest_ == 0)
00213               {
00214                 region_of_interest_ = new PolylineROI(region_of_interest_sep_);        
00215               }             
00216              
00217               try
00218               {           
00219                 static_cast<PolylineROI*>(region_of_interest_)->addPoint(convertCoordsFromWorldToSpace(pos));  
00220                 static_cast<PolylineROI*>(region_of_interest_)->drawROI();    
00221               }              
00222               catch (NullPointerException const&) 
00223               {
00224                 //TODO: what should happen if the user clicks outside the texture?
00225                 //at the moment this click is simply ignored                
00226               }  
00227                   
00228               return (false);       
00229             }        
00230            
00231             //Popup menu              
00232             SoRayPickAction rp(image_view_->getRenderArea()->getViewportRegion());
00233             rp.setPoint(pos);
00234             rp.apply(image_view_->getRenderArea()->getSceneGraph());                               
00235             
00236             //double click for new crosshair position assignment     
00237             if (double_click_check_time_ == 0.0)
00238             {           
00239               double_click_check_time_ = ev->getTime();
00240               return(false);      
00241             }
00242                
00243             double_click_check_time_ = ev->getTime() - double_click_check_time_;     
00244           
00245             if (double_click_check_time_ < 0.5)  // 0.5 secs
00246             {
00247               SbVec2s texture_coords;     
00248               if (!convertCoordsFromScreenToTexture(pos, texture_coords))
00249               {
00250                 return(false);
00251               }
00252           
00253               image_view_->setFocusPoint2D(
00254                   texture_coords[X_DIMENSION], 
00255                   texture_coords[Y_DIMENSION]);
00256             
00257               //reset      
00258               double_click_check_time_ = 0.0;      
00259             }
00260             else
00261             {
00262               double_click_check_time_ = ev->getTime();
00263             }               
00264           }
00265           
00266           if (SoMouseButtonEvent::isButtonReleaseEvent(event, 
00267               SoMouseButtonEvent::BUTTON1))
00268           {    
00276             
00277             //Window/level movement                  
00278             SbVec2s left_mouse_button_release_location = pos;
00279     
00280             int x_difference = left_mouse_button_release_location[X_DIMENSION] - 
00281                 left_mouse_button_press_location_[X_DIMENSION];
00282             int y_difference = left_mouse_button_release_location[Y_DIMENSION] - 
00283                 left_mouse_button_press_location_[Y_DIMENSION];
00284       
00285             //std::cout << "X Difference: " << x_difference << std::endl;
00286             //std::cout << "Y Difference: " << y_difference << std::endl;            
00287             
00288             double new_window = image_view_->getIntensityWindow();
00289             new_window += x_difference * mouse_movement_scaling_factor_;
00290             if (new_window < 0)
00291             {
00292               new_window = 1;
00293             }
00294          
00295             double new_level = image_view_->getIntensityLevel();
00296             new_level += y_difference * mouse_movement_scaling_factor_;
00297       
00298             image_view_->setIntensity(new_window, new_level);
00299             
00300             view_mode_ = DEFAULT_MODE;
00301           }                         
00302            
00303           return(false);
00304         }      
00305         //right mouse button    
00306         case SoMouseButtonEvent::BUTTON2:
00307         { 
00308           //Polyline ROI
00309           if (Controller::getInstance().getGuiInteractionMode() == REGION_OF_INTEREST_POLY_LINE_MODE)
00310           {
00311             //auto-close polyline ROI
00312             static_cast<PolylineROI*>(region_of_interest_)->autoCloseROI();
00313             static_cast<PolylineROI*>(region_of_interest_)->drawROI();        
00314             Controller::getInstance().setGuiInteractionMode(STANDARD_MODE);         
00315             return (false);      
00316           }                                   
00317           
00318           last_position_ = event->getPosition();                      
00319           last_button_click_event_.reset(new SoMouseButtonEvent(*event));
00320                
00321           if (SoMouseButtonEvent::isButtonPressEvent(event, 
00322               SoMouseButtonEvent::BUTTON2))
00323           {
00324             view_mode_ = ZOOM_IN_OUT_MODE;          
00325           }
00326           else
00327           {
00328             view_mode_ = DEFAULT_MODE;   
00329           }                     
00330                       
00331           return(false);     
00332         }
00333         case SoMouseButtonEvent::BUTTON3:
00334         {
00335           return(ImedgineViewer::processSoEvent(event));
00336         }
00337         case SoMouseButtonEvent::BUTTON4: // wheel up
00338         {  
00339           return(false);     
00340         }     
00341         case SoMouseButtonEvent::BUTTON5: // wheel down
00342         {   
00343           return(false);
00344         }
00345         default:
00346         {}     
00347       }
00348     }
00349     return(ImedgineViewer::processSoEvent(ev));    
00350   }   
00351 
00352   //--------------------------------------------------   
00353   
00354   bool ImedgineImageViewer::convertCoordsFromScreenToTexture(
00355       SbVec2s const& screen_coords, SbVec2s& texture_coords)
00356   {
00357     SoRayPickAction rp(image_view_->getRenderArea()->getViewportRegion());
00358     rp.setPoint(screen_coords);
00359     rp.apply(image_view_->getRenderArea()->getSceneGraph());  
00360     
00361     SoPickedPoint* picked_point = rp.getPickedPoint(); 
00362           
00363     if (picked_point == 0)
00364     {
00365       //TODO: throw exception here   
00366       return(false);
00367     }
00368     
00369     float texture_xy_relation_factor =
00370         static_cast<float>(image_view_->getSize()[Y_DIMENSION]) /  
00371         static_cast<float>(image_view_->getSize()[X_DIMENSION]);    
00372     
00373     texture_coords[X_DIMENSION] = static_cast<short int>(
00374         (image_view_->getSize()[X_DIMENSION] *
00375         (picked_point->getPoint()[X_DIMENSION] + 0.5)) / 1.0);
00376           
00377     texture_coords[Y_DIMENSION] = static_cast<short int>(
00378         (image_view_->getSize()[Y_DIMENSION] * 
00379         (picked_point->getPoint()[Y_DIMENSION] + (texture_xy_relation_factor / 2.0))) /
00380         texture_xy_relation_factor);
00381     
00382     return (true);  
00383   }   
00384   
00385   //--------------------------------------------------   
00386   
00387   void ImedgineImageViewer::convertCoordsFromTextureToWorld(
00388       SbVec2s const& texture_coords, SbVec2f& space_coords)
00389   {
00390     float texture_xy_relation_factor = 
00391         static_cast<float>(image_view_->getSize()[Y_DIMENSION]) /  
00392         static_cast<float>(image_view_->getSize()[X_DIMENSION]);  
00393     
00394     space_coords[X_DIMENSION] = 
00395         (static_cast<float>(texture_coords[X_DIMENSION]) * 1.0 / 
00396         static_cast<float>(image_view_->getSize()[X_DIMENSION])) - 0.5;
00397   
00398     space_coords[Y_DIMENSION] = 
00399         (static_cast<float>(texture_coords[Y_DIMENSION]) * texture_xy_relation_factor / 
00400         static_cast<float>(image_view_->getSize()[Y_DIMENSION])) - 
00401         (texture_xy_relation_factor / 2.0);   
00402   }
00403   
00404   //--------------------------------------------------   
00405   
00406   void ImedgineImageViewer::updateDatasetStatusInfo()
00407   {
00408     std::ostringstream dataset_info_tmp;
00409     dataset_info_tmp << image_view_->getDatasetKey();
00410     
00411     dataset_status_info_text_->string = dataset_info_tmp.str().c_str();    
00412   }
00413   
00414   //--------------------------------------------------   
00415   
00416   SbVec3f ImedgineImageViewer::convertCoordsFromWorldToSpace(SbVec2s screen_coords)
00417       throw(NullPointerException)   
00418   {    
00419 //     SbViewVolume view_volume = image_view_->getStaticCamera()->getViewVolume();
00420 //  
00421 //     SbVec2f normalized_screen_coords = SbVec2f(
00422 //         static_cast<float>(screen_coords[X_DIMENSION]), 
00423 //         static_cast<float>(screen_coords[Y_DIMENSION]));
00424 //     
00425 //     normalized_screen_coords.normalize();   
00426 //     
00427 //     // Find world space line along view direction through cursor
00428 //     SbLine line;
00429 //     view_volume.projectPointToLine(SbVec2f(
00430 //         normalized_screen_coords[X_DIMENSION], 
00431 //         normalized_screen_coords[Y_DIMENSION]), line);
00432 // 
00433 //     // Since you have an orthographic camera,
00434 //     // the x and y values of any point on this
00435 //     // line are the ones you want.
00436 //     SbVec3f space_coords;
00437 //     space_coords[X_DIMENSION] = line.getPosition()[X_DIMENSION];
00438 //     space_coords[Y_DIMENSION] = line.getPosition()[Y_DIMENSION];
00439 //     space_coords[Z_DIMENSION] = 0.1;  //TODO: value right?
00440 //     return space_coords;
00441     
00442     SoRayPickAction ray_pick(this->getViewportRegion());
00443     ray_pick.setPoint(screen_coords);
00444     ray_pick.apply(this->getSceneGraph()); 
00445 
00446     std::cout << "Picked point: " << ray_pick.getPickedPoint()->getPoint()[X_DIMENSION] 
00447         << "/" << ray_pick.getPickedPoint()->getPoint()[Y_DIMENSION] << std::endl;  
00448     
00449     if (ray_pick.getPickedPoint() == 0)  
00450     {
00451       throw(NullPointerException("ImedgineImageViewer::getWorldSpacePosition()"));   
00452     }
00453      
00454     return(ray_pick.getPickedPoint()->getPoint());        
00455   }    
00456       
00457 } // namespace imedgine

Generated on Sun Aug 13 18:19:41 2006 for iMEDgine by  doxygen 1.4.6