CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Fireworks/Core/src/FWEveView.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWEveView
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  Alja Mrak-Tadel
00010 //         Created:  Thu Mar 16 14:11:32 CET 2010
00011 // $Id: FWEveView.cc,v 1.56 2013/04/24 04:08:45 amraktad Exp $
00012 //
00013 
00014 
00015 
00016 #include <RVersion.h>
00017 #include <boost/bind.hpp>
00018 #include <stdexcept>
00019 
00020 
00021 // user include files
00022 
00023 #define private public  //!!! TODO add get/sets for camera zoom and FOV
00024 #include "TGLOrthoCamera.h"
00025 #include "TGLPerspectiveCamera.h"
00026 #undef private
00027 #include "TGLCameraGuide.h"
00028 
00029 #include "TGLEmbeddedViewer.h"
00030 #include "TEveViewer.h"
00031 #include "TGLScenePad.h"
00032 #include "TEveManager.h"
00033 #include "TEveElement.h"
00034 #include "TEveWindow.h"
00035 #include "TEveScene.h"
00036 #define protected public  //!!! TODO add get/sets for TEveCalo2D for CellIDs
00037 #include "TEveCalo.h"
00038 #undef protected
00039 #include "TGLOverlay.h"
00040 
00041 #include "Fireworks/Core/interface/FWEveView.h"
00042 #include "Fireworks/Core/interface/FWViewType.h"
00043 #include "Fireworks/Core/interface/CmsShowViewPopup.h"
00044 #include "Fireworks/Core/interface/FWEventAnnotation.h"
00045 #include "Fireworks/Core/interface/CmsAnnotation.h"
00046 #include "Fireworks/Core/interface/FWGLEventHandler.h"
00047 #include "Fireworks/Core/interface/FWViewContextMenuHandlerGL.h"
00048 #include "Fireworks/Core/interface/FWConfiguration.h"
00049 #include "Fireworks/Core/interface/FWColorManager.h"
00050 #include "Fireworks/Core/interface/fwLog.h"
00051 #include "Fireworks/Core/interface/Context.h"
00052 #include "Fireworks/Core/interface/FWViewContext.h"
00053 #include "Fireworks/Core/interface/FWViewEnergyScale.h"
00054 #include "Fireworks/Core/interface/CmsShowCommon.h"
00055 #include "Fireworks/Core/interface/FWViewEnergyScaleEditor.h"
00056 
00057 namespace fireworks
00058 {
00059 class Context;
00060 }
00061 
00062 /* This class is temporary workaround for missing in TGLAnnotation functionality */
00063 class ScaleAnnotation : public TGLAnnotation
00064 {
00065 public:
00066    ScaleAnnotation(TGLViewerBase* parent, const char* text, Float_t posx, Float_t posy):
00067       TGLAnnotation(parent, text, posx, posy) {}
00068    virtual ~ScaleAnnotation() {}
00069 
00070    void setText(const char* txt)
00071    {
00072       fText = txt;
00073    }
00074 };
00075 
00076 //
00077 // constructors and destructor
00078 //
00079 
00080 FWEveView::FWEveView(TEveWindowSlot* iParent, FWViewType::EType type, unsigned int version) :
00081    FWViewBase(type, version),
00082    m_viewer(0),
00083    m_eventScene(0),
00084    m_ownedProducts(0),
00085    m_geoScene(0),
00086    m_overlayEventInfo(0),
00087    m_overlayLogo(0),
00088    m_energyMaxValAnnotation(0),
00089    m_cameraGuide(0),
00090    m_context(0),
00091    // style
00092 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
00093    m_imageScale(this, "Image Scale", 1.0, 1.0, 6.0),
00094 #endif
00095    m_eventInfoLevel(this, "Overlay Event Info", 0l, 0l, 2l),
00096    m_drawCMSLogo(this,"Show Logo",false),
00097    m_pointSmooth(this, "Smooth points", false),
00098    m_pointSize(this, "Point size", 1.0, 1.0, 10.0),
00099    m_lineSmooth(this, "Smooth lines", false),
00100    m_lineWidth(this,"Line width",1.0,1.0,10.0),
00101    m_lineOutlineScale(this, "Outline width scale", 1.0, 0.01, 10.0),
00102    m_lineWireframeScale(this, "Wireframe width scale", 1.0, 0.01, 10.0),
00103    m_showCameraGuide(this,"Show Camera Guide",false),
00104    m_useGlobalEnergyScale(this, "UseGlobalEnergyScale", true),
00105    m_viewContext( new FWViewContext()),
00106    m_localEnergyScale( new FWViewEnergyScale(FWViewType::idToName(type), version)),
00107    m_viewEnergyScaleEditor(0)
00108 {
00109    m_viewer = new TEveViewer(typeName().c_str());
00110 
00111    TGLEmbeddedViewer* embeddedViewer;
00112 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,25,4)
00113    embeddedViewer =  m_viewer->SpawnGLEmbeddedViewer(0);
00114 #else
00115    embeddedViewer =  m_viewer->SpawnGLEmbeddedViewer();
00116 #endif
00117    iParent->ReplaceWindow(m_viewer);
00118    gEve->GetViewers()->AddElement(m_viewer);
00119 
00120    m_eventScene =  gEve->SpawnNewScene(Form("EventScene %s", typeName().c_str()));
00121    m_ownedProducts = new TEveElementList("ViewSpecificProducts");
00122    m_eventScene->AddElement(m_ownedProducts);
00123 
00124    m_viewer->AddScene(m_eventScene);
00125 
00126    // spawn geo scene
00127    m_geoScene = gEve->SpawnNewScene(Form("GeoScene %s", typeName().c_str()));
00128    m_geoScene->GetGLScene()->SetSelectable(kFALSE);
00129    m_viewer->AddScene(m_geoScene);
00130 
00131    FWGLEventHandler* eh = new FWGLEventHandler((TGWindow*)embeddedViewer->GetGLWidget(), (TObject*)embeddedViewer);
00132    embeddedViewer->SetEventHandler(eh);
00133    eh->setViewer(this);
00134    eh->openSelectedModelContextMenu_.connect(openSelectedModelContextMenu_);
00135    eh->SetDoInternalSelection(kFALSE);
00136    FWViewContextMenuHandlerGL* ctxHand = new FWViewContextMenuHandlerGL(this);
00137    // ctxHand->setPickCameraCenter(true);
00138    m_viewContextMenu.reset(ctxHand);
00139    
00140    m_energyMaxValAnnotation = new ScaleAnnotation(viewerGL(), "empty", 0.1, 0.9);
00141    m_energyMaxValAnnotation->SetRole(TGLOverlayElement::kViewer);
00142    m_energyMaxValAnnotation->SetState(TGLOverlayElement::kInvisible);
00143    m_energyMaxValAnnotation->SetUseColorSet(false);
00144    m_energyMaxValAnnotation->SetTextSize(0.05);
00145    m_energyMaxValAnnotation->SetTextColor(kMagenta);
00146 
00147    // style params
00148 
00149    m_overlayEventInfo = new FWEventAnnotation(embeddedViewer);
00150    m_overlayEventInfo->setLevel(0);
00151 
00152    m_eventInfoLevel.addEntry(0, "Nothing");
00153    m_eventInfoLevel.addEntry(1, "Run / event");
00154    m_eventInfoLevel.addEntry(2, "Run / event / lumi");
00155    m_eventInfoLevel.addEntry(3, "Full");
00156    m_eventInfoLevel.changed_.connect(boost::bind(&FWEventAnnotation::setLevel,m_overlayEventInfo, _1));
00157    
00158    m_overlayLogo = new CmsAnnotation(embeddedViewer, 0.02, 0.98);
00159    m_overlayLogo->setVisible(false);
00160    m_drawCMSLogo.changed_.connect(boost::bind(&CmsAnnotation::setVisible,m_overlayLogo, _1));
00161 
00162    m_cameraGuide = new TGLCameraGuide(0.9, 0.1, 0.08);
00163    m_cameraGuide->SetState(TGLOverlayElement::kInvisible);
00164    embeddedViewer->AddOverlayElement(m_cameraGuide);
00165    m_showCameraGuide.changed_.connect(boost::bind(&FWEveView::cameraGuideChanged,this));
00166 
00167    m_pointSmooth.changed_.connect(boost::bind(&FWEveView::pointLineScalesChanged,this));
00168    m_pointSize.changed_.connect(boost::bind(&FWEveView::pointLineScalesChanged,this));
00169    m_lineSmooth.changed_.connect(boost::bind(&FWEveView::pointLineScalesChanged,this));
00170    m_lineWidth.changed_.connect(boost::bind(&FWEveView::pointLineScalesChanged,this));
00171    m_lineOutlineScale.changed_.connect(boost::bind(&FWEveView::pointLineScalesChanged,this));
00172    m_lineWireframeScale.changed_.connect(boost::bind(&FWEveView::pointLineScalesChanged,this));
00173 
00174 
00175    // create scale for view  .. 
00176    m_viewContext->setEnergyScale(m_localEnergyScale.get());
00177    m_useGlobalEnergyScale.changed_.connect(boost::bind(&FWEveView::useGlobalEnergyScaleChanged, this));
00178    m_localEnergyScale->parameterChanged_.connect(boost::bind(&FWEveView::setupEnergyScale, this));
00179 }
00180 
00181 FWEveView::~FWEveView()
00182 {
00183    m_geoScene->RemoveElements();
00184    m_eventScene->RemoveElements();
00185    m_viewer->DestroyWindowAndSlot();
00186 }
00187 
00188 //______________________________________________________________________________
00189 // const member functions
00190 
00191 
00192 FWViewContextMenuHandlerBase* 
00193 FWEveView::contextMenuHandler() const {
00194    return dynamic_cast<FWViewContextMenuHandlerBase*> (m_viewContextMenu.get());
00195 }
00196 
00197 TGLViewer* 
00198 FWEveView::viewerGL() const
00199 {
00200    return  m_viewer->GetGLViewer();
00201 }
00202 
00203 void
00204 FWEveView::saveImageTo(const std::string& iName) const
00205 {
00206    bool succeeded = false;
00207 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
00208    succeeded = viewerGL()->SavePictureScale(iName, m_imageScale.value());
00209 #else
00210    succeeded = viewerGL()->SavePicture(iName.c_str());
00211 #endif
00212 
00213    if(!succeeded) {
00214       throw std::runtime_error("Unable to save picture");
00215    }
00216    fwLog(fwlog::kInfo) <<  "Saved image " << iName << std::endl;
00217 }
00218 
00219 //-------------------------------------------------------------------------------
00220 void
00221 FWEveView::pointLineScalesChanged()
00222 {
00223    viewerGL()->SetSmoothPoints(m_pointSmooth.value());
00224    viewerGL()->SetPointScale  (m_pointSize.value());
00225    viewerGL()->SetSmoothLines (m_lineSmooth.value());
00226    viewerGL()->SetLineScale   (m_lineWidth.value());
00227    viewerGL()->SetOLLineW     (m_lineOutlineScale.value());
00228    viewerGL()->SetWFLineW     (m_lineWireframeScale.value());
00229    viewerGL()->Changed();
00230    gEve->Redraw3D();
00231 }
00232 
00233 void
00234 FWEveView::cameraGuideChanged()
00235 {
00236    m_cameraGuide->SetBinaryState(m_showCameraGuide.value());
00237    viewerGL()->Changed();
00238    gEve->Redraw3D();
00239 }
00240 
00241 void
00242 FWEveView::eventBegin()
00243 {
00244 }
00245 
00246 void
00247 FWEveView::eventEnd()
00248 {
00249    m_overlayEventInfo->setEvent();
00250    setupEnergyScale();
00251 }
00252 
00253 void
00254 FWEveView::setBackgroundColor(Color_t iColor)
00255 {
00256    FWColorManager::setColorSetViewer(viewerGL(), iColor);
00257 }
00258 
00259 void
00260 FWEveView::resetCamera()
00261 {
00262    viewerGL()->ResetCurrentCamera();
00263 }
00264 
00265 //______________________________________________________________________________
00266 void 
00267 FWEveView::setContext(const fireworks::Context& x)
00268 {
00269    m_context = &x ;
00270 
00271    // in constructor view context has local scale
00272    if (m_useGlobalEnergyScale.value()) 
00273       m_viewContext->setEnergyScale(context().commonPrefs()->getEnergyScale());
00274 }
00275 
00276 bool
00277 FWEveView::isEnergyScaleGlobal() const
00278 {
00279    return m_useGlobalEnergyScale.value();
00280 }
00281 
00282 void
00283 FWEveView::useGlobalEnergyScaleChanged()
00284 {
00285    m_viewContext->setEnergyScale(m_useGlobalEnergyScale.value() ? context().commonPrefs()->getEnergyScale() : m_localEnergyScale.get());
00286    if (m_viewEnergyScaleEditor) m_viewEnergyScaleEditor->setEnabled(!m_useGlobalEnergyScale.value());
00287    setupEnergyScale();
00288 }
00289 
00290 void
00291 FWEveView::voteCaloMaxVal()
00292 {
00293    TEveCaloViz* calo = getEveCalo();
00294    if (calo)
00295       context().voteMaxEtAndEnergy(calo->GetData()->GetMaxVal(1), calo->GetData()->GetMaxVal(0));
00296 }
00297 
00298 void
00299 FWEveView::setupEnergyScale()
00300 {
00301    // Called at end of event OR if scale parameters changed.
00302 
00303    FWViewEnergyScale*  energyScale = viewContext()->getEnergyScale();
00304    // printf("setupEnergyScale %s >> scale name %s\n", typeName().c_str(), energyScale->name().c_str());
00305    voteCaloMaxVal();
00306    
00307    // set cache for energy to lenght conversion
00308    float maxVal = context().getMaxEnergyInEvent(energyScale->getPlotEt());
00309    energyScale->updateScaleFactors(maxVal);
00310    // printf("max event val %f \n", maxVal);
00311    // printf("scales lego %f \n",  energyScale->getScaleFactorLego());
00312 
00313    // configure TEveCaloViz
00314    TEveCaloViz* calo = getEveCalo();
00315    if (calo)
00316    {
00317       calo->SetPlotEt(energyScale->getPlotEt());
00318       if (FWViewType::isLego(typeId()))
00319       {
00320          float f = energyScale->getScaleFactorLego();
00321          calo->SetMaxValAbs(TMath::Pi()/f);
00322       }
00323       else
00324       {
00325          float f = energyScale->getScaleFactor3D();
00326          calo->SetMaxValAbs(100/f);
00327       }
00328       calo->ElementChanged();
00329    }
00330 
00331    // emit signal to proxy builders 
00332    viewContext()->scaleChanged();
00333    gEve->Redraw3D();
00334 }
00335 
00336 //-------------------------------------------------------------------------------
00337 void
00338 FWEveView::addTo(FWConfiguration& iTo) const
00339 {
00340    // take care of parameters
00341    FWConfigurableParameterizable::addTo(iTo);
00342    
00343    { 
00344       assert ( m_overlayEventInfo );
00345       m_overlayEventInfo->addTo(iTo);
00346    }
00347    { 
00348       assert ( m_overlayLogo );
00349       m_overlayLogo->addTo(iTo);
00350    }
00351 
00352    m_viewContext->getEnergyScale()->addTo(iTo);
00353 }
00354 
00355 void
00356 FWEveView::setFrom(const FWConfiguration& iFrom)
00357 {
00358    // Make sure you change the version ranges here
00359    // whenever you update the logic.
00360    // The rationale should be:
00361    // (version range supported by the next block) && (version range in the configuration file)
00362    //
00363    // This is not "forward" compatible, but I don't think
00364    // we care.
00365    if (version() >= 2 && iFrom.version() >= 1)
00366    {
00367       for(const_iterator it =begin(), itEnd = end();
00368           it != itEnd;
00369           ++it) {
00370          (*it)->setFrom(iFrom);      
00371       }  
00372    }
00373    if (iFrom.version() > 1)
00374    {
00375       assert( m_overlayEventInfo);
00376       m_overlayEventInfo->setFrom(iFrom);
00377    }
00378    {
00379       assert( m_overlayLogo);
00380       m_overlayLogo->setFrom(iFrom);
00381    }
00382    
00383    if (iFrom.version() > 4)
00384    {
00385       m_localEnergyScale->setFrom(iFrom);
00386    }
00387 
00388 
00389    // selection clors
00390    UChar_t* ca = 0;
00391    ca = gEve->GetDefaultGLViewer()->RefLightColorSet().Selection(1).Arr();
00392    viewerGL()->RefLightColorSet().Selection(1).SetColor(ca[0], ca[1], ca[2]);
00393    ca = gEve->GetDefaultGLViewer()->RefLightColorSet().Selection(3).Arr();
00394    viewerGL()->RefLightColorSet().Selection(3).SetColor(ca[0], ca[1], ca[2]);
00395    ca = gEve->GetDefaultGLViewer()->RefDarkColorSet().Selection(1).Arr();
00396    viewerGL()->RefDarkColorSet().Selection(1).SetColor(ca[0], ca[1], ca[2]);
00397    ca = gEve->GetDefaultGLViewer()->RefDarkColorSet().Selection(3).Arr();
00398    viewerGL()->RefDarkColorSet().Selection(3).SetColor(ca[0], ca[1], ca[2]);
00399 }
00400 
00401 //______________________________________________________________________________
00402 
00403 
00404 void
00405 FWEveView::addToOrthoCamera(TGLOrthoCamera* camera, FWConfiguration& iTo) const
00406 {
00407    // zoom
00408    std::ostringstream s;
00409    s<<(camera->fZoom);
00410    std::string name("cameraZoom");
00411    iTo.addKeyValue(name+typeName(),FWConfiguration(s.str()));
00412    
00413    // transformation matrix
00414    std::string matrixName("cameraMatrix");
00415    for ( unsigned int i = 0; i < 16; ++i ) {
00416       std::ostringstream osIndex;
00417       osIndex << i;
00418       std::ostringstream osValue;
00419       osValue << camera->GetCamTrans()[i];
00420       iTo.addKeyValue(matrixName+osIndex.str()+typeName(),FWConfiguration(osValue.str()));
00421    }   
00422 }
00423 
00424 void
00425 FWEveView::setFromOrthoCamera(TGLOrthoCamera* camera,  const FWConfiguration& iFrom)
00426 {
00427    try {
00428       // zoom
00429       std::string zoomName("cameraZoom"); zoomName += typeName();
00430       if (iFrom.valueForKey(zoomName) == 0 )
00431       {
00432          throw std::runtime_error("can't restore parameter cameraZoom");
00433       }
00434       std::istringstream s(iFrom.valueForKey(zoomName)->value());
00435       s>>(camera->fZoom);
00436       
00437       // transformation matrix
00438       std::string matrixName("cameraMatrix");
00439       for ( unsigned int i = 0; i < 16; ++i ) {
00440          std::ostringstream os;
00441          os << i;
00442          const FWConfiguration* value = iFrom.valueForKey( matrixName + os.str() + typeName() );
00443          if ( value ==  0 )
00444          {
00445             throw std::runtime_error ("can't restore parameter cameraMatrix.");
00446          }
00447          std::istringstream s(value->value());
00448          s>> (camera->RefCamTrans()[i]);
00449       }
00450    }
00451    catch (const std::runtime_error& iException)
00452    {
00453       fwLog(fwlog::kInfo) << "Caught exception while restoring camera parameters in view " << typeName() << "\n.";
00454       viewerGL()->ResetCamerasAfterNextUpdate();      
00455 
00456    }
00457    camera->IncTimeStamp();
00458 }
00459  
00460 void
00461 FWEveView::addToPerspectiveCamera(TGLPerspectiveCamera* cam, const std::string& name, FWConfiguration& iTo) const
00462 {   
00463    // transformation matrix
00464    std::string matrixName("cameraMatrix");
00465    for ( unsigned int i = 0; i < 16; ++i ){
00466       std::ostringstream osIndex;
00467       osIndex << i;
00468       std::ostringstream osValue;
00469       osValue << (cam->GetCamTrans())[i];
00470       iTo.addKeyValue(matrixName+osIndex.str()+name,FWConfiguration(osValue.str()));
00471    }
00472    
00473    // transformation matrix base
00474    matrixName = "cameraMatrixBase";
00475    for ( unsigned int i = 0; i < 16; ++i ){
00476       std::ostringstream osIndex;
00477       osIndex << i;
00478       std::ostringstream osValue;
00479       osValue << (cam->GetCamBase())[i];
00480       iTo.addKeyValue(matrixName+osIndex.str()+name,FWConfiguration(osValue.str()));
00481    }
00482    {
00483       std::ostringstream osValue;
00484       osValue << cam->fFOV;
00485       iTo.addKeyValue(name+" FOV",FWConfiguration(osValue.str()));
00486    }
00487 }
00488 
00489 void
00490 FWEveView::setFromPerspectiveCamera(TGLPerspectiveCamera* cam, const std::string& name, const FWConfiguration& iFrom)
00491 {
00492    try {
00493       std::string matrixName("cameraMatrix");
00494       for ( unsigned int i = 0; i < 16; ++i ){
00495          std::ostringstream os;
00496          os << i;
00497          const FWConfiguration* value = iFrom.valueForKey( matrixName + os.str() + name );
00498          if ( value ==  0 )
00499          {
00500             throw std::runtime_error ("can't restore parameter cameraMatrix.");
00501          }
00502          std::istringstream s(value->value());
00503          s>>((cam->RefCamTrans())[i]);
00504       }
00505       
00506       // transformation matrix base
00507       matrixName = "cameraMatrixBase";
00508       for ( unsigned int i = 0; i < 16; ++i ){
00509          std::ostringstream os;
00510          os << i;
00511          const FWConfiguration* value = iFrom.valueForKey( matrixName + os.str() + name );
00512          if ( value ==  0 )
00513          {
00514             throw std::runtime_error ("can't restore parameter cameraMatrixBase.");
00515          }
00516      
00517          std::istringstream s(value->value());
00518          s>>((cam->RefCamBase())[i]);
00519       }
00520       
00521       {
00522          const FWConfiguration* value = iFrom.valueForKey( name + " FOV" );
00523          if ( value ==  0 )
00524          {
00525             throw std::runtime_error ("can't restore parameter cameraMatrixBase.");
00526          }
00527          std::istringstream s(value->value());
00528          s>>cam->fFOV;
00529       }
00530       
00531       cam->IncTimeStamp();
00532    }
00533    catch (const std::runtime_error& iException)
00534    {
00535       fwLog(fwlog::kInfo) << "Caught exception while restoring camera parameters in view " << typeName() << "\n.";
00536       viewerGL()->ResetCamerasAfterNextUpdate();  
00537       fwLog(fwlog::kDebug) << "Reset camera fo view "  << typeName() << "\n.";
00538    }
00539 }
00540 
00541 
00542 void 
00543 FWEveView::populateController(ViewerParameterGUI& gui) const
00544 {
00545    gui.requestTab("Style").
00546       addParam(&m_eventInfoLevel).
00547       addParam(&m_drawCMSLogo).
00548       addParam(&m_showCameraGuide).
00549       separator().
00550 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,0)
00551       addParam(&m_imageScale).
00552 #endif
00553       addParam(&m_pointSize).
00554       addParam(&m_pointSmooth).
00555       addParam(&m_lineSmooth).
00556       addParam(&m_lineWidth).
00557       addParam(&m_lineOutlineScale).
00558       addParam(&m_lineWireframeScale);
00559 
00560 
00561    gui.requestTab("Scales").
00562       addParam(&m_useGlobalEnergyScale);
00563 
00564    m_viewEnergyScaleEditor = new FWViewEnergyScaleEditor(m_localEnergyScale.get(), gui.getTabContainer(), !FWViewType::isLego(typeId()));
00565    m_viewEnergyScaleEditor->setEnabled(!m_useGlobalEnergyScale.value());
00566    gui.addFrameToContainer(m_viewEnergyScaleEditor);
00567 }