CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWProxyBuilderBase
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  Chris Jones, Matevz Tadel, Alja Mrak-Tadel
00010 //         Created:  Thu Mar 18 14:12:00 CET 2010
00011 // $Id: FWProxyBuilderBase.cc,v 1.32 2010/10/29 10:42:02 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include <boost/bind.hpp>
00017 
00018 // user include files
00019 #include "TEveElement.h"
00020 #include "TEveCompound.h"
00021 #include "TEveManager.h"
00022 #include "TEveProjectionManager.h"
00023 #include "TEveSelection.h"
00024 
00025 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
00026 #include "Fireworks/Core/interface/FWEventItem.h"
00027 #include "Fireworks/Core/interface/FWModelId.h"
00028 #include "Fireworks/Core/interface/FWInteractionList.h"
00029 #include "Fireworks/Core/interface/FWViewContext.h"
00030 #include "Fireworks/Core/interface/fwLog.h"
00031 
00032 //
00033 // constants, enums and typedefs
00034 //
00035 
00036 //
00037 // static data member definitions
00038 //
00039 
00040 //
00041 // constructors and destructor
00042 //
00043 
00044 
00045 FWProxyBuilderBase::Product::Product(FWViewType::EType t, const FWViewContext* c) : m_viewType(t), m_viewContext(c), m_elements(0)
00046 {
00047    m_elements = new TEveElementList("ProxyProduct");
00048    m_elements->IncDenyDestroy();
00049 }
00050 
00051 
00052 FWProxyBuilderBase::Product::~Product()
00053 {
00054    // remove product from projected scene (RhoPhi or RhoZ)
00055    TEveProjectable* pable = dynamic_cast<TEveProjectable*>(m_elements);
00056    // don't have to check cast, because TEveElementList is TEveProjectable
00057    for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
00058    {
00059       TEveElement* projected  = (*i)->GetProjectedAsElement();
00060       (*projected->BeginParents())->RemoveElement(projected);
00061    }
00062 
00063    // remove from 3D scenes
00064    while (m_elements->HasParents())
00065    {
00066       TEveElement* parent = *m_elements->BeginParents();
00067       parent->RemoveElement(m_elements);
00068    }
00069 
00070    m_elements->Annihilate();
00071 }
00072 
00073 //______________________________________________________________________________
00074 
00075 FWProxyBuilderBase::FWProxyBuilderBase():
00076    m_interactionList(0),
00077    m_item(0),
00078    m_modelsChanged(false),
00079    m_haveWindow(false),
00080    m_mustBuild(true),
00081    m_layer(0)
00082 {
00083 }
00084 
00085 FWProxyBuilderBase::~FWProxyBuilderBase()
00086 {
00087    m_products.clear();
00088 }
00089 
00090 //
00091 // member functions
00092 //
00093 
00094 void
00095 FWProxyBuilderBase::setItem(const FWEventItem* iItem)
00096 { 
00097    m_item = iItem;
00098 }
00099 
00100 void
00101 FWProxyBuilderBase::setHaveWindow(bool iFlag)
00102 {
00103    bool oldValue = m_haveWindow;
00104    m_haveWindow=iFlag;
00105 
00106    if(iFlag && !oldValue) {
00107       //this is our first view so may need to rerun our building
00108       if(m_mustBuild) {
00109          build();
00110       }
00111    }
00112 }
00113 
00114 void
00115 FWProxyBuilderBase::itemBeingDestroyed(const FWEventItem* iItem)
00116 {
00117    m_item=0;
00118 
00119    cleanLocal();
00120 
00121    for (Product_it i = m_products.begin(); i!= m_products.end(); i++)
00122    {
00123 
00124       (*i)->m_scaleConnection.disconnect();
00125       delete (*i);
00126    }
00127 
00128    m_products.clear();
00129 }
00130 
00131 void 
00132 FWProxyBuilderBase::build()
00133 {
00134    if (m_item)
00135    {
00136       try 
00137       {
00138          size_t itemSize = m_item->size(); //cashed
00139 
00140          clean();
00141          for (Product_it i = m_products.begin(); i != m_products.end(); ++i)
00142          {
00143             // printf("build() %s \n", m_item->name().c_str());
00144             TEveElementList* elms = (*i)->m_elements;
00145             size_t oldSize = elms->NumChildren();
00146 
00147             if (haveSingleProduct())
00148             {
00149                build(m_item, elms, (*i)->m_viewContext);
00150             }
00151             else
00152             {
00153                buildViewType(m_item, elms, (*i)->m_viewType, (*i)->m_viewContext);
00154             }
00155 
00156             // Project all children of current product.
00157             // If product is not registered into any projection-manager,
00158             // this does nothing.          
00159             TEveProjectable* pable = dynamic_cast<TEveProjectable*>(elms);
00160             if (pable->HasProjecteds())
00161             {
00162                for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
00163                {
00164                   TEveProjectionManager *pmgr = (*i)->GetManager();
00165                   Float_t oldDepth = pmgr->GetCurrentDepth();
00166                   pmgr->SetCurrentDepth(item()->layer());
00167                   size_t cnt = 0;
00168 
00169                   TEveElement* projectedAsElement = (*i)->GetProjectedAsElement();
00170                   TEveElement::List_i parentIt = projectedAsElement->BeginChildren();
00171                   for (TEveElement::List_i prodIt = elms->BeginChildren(); prodIt != elms->EndChildren(); ++prodIt, ++cnt)
00172                   {
00173                      if (cnt < oldSize)
00174                      {  
00175                         // reused projected holder
00176                         pmgr->SubImportChildren(*prodIt, *parentIt);
00177                         ++parentIt;
00178                      }
00179                      else if (cnt < itemSize) 
00180                      {
00181                         // new product holder
00182                         pmgr->SubImportElements(*prodIt, projectedAsElement);
00183                      }
00184                      else
00185                      {
00186                         break;
00187                      }
00188                   }
00189                   pmgr->SetCurrentDepth(oldDepth);
00190                }
00191             }
00192          
00193 
00194             if (m_interactionList && itemSize > oldSize)
00195             {
00196                TEveElement::List_i elIt = elms->BeginChildren();
00197                for (size_t cnt = 0; cnt < itemSize; ++cnt, ++elIt)
00198                {
00199                   if (cnt >= oldSize )
00200                      m_interactionList->added(*elIt, cnt);
00201                }
00202             }
00203          }
00204       }
00205       catch (const std::runtime_error& iException)
00206       { 
00207          fwLog(fwlog::kError) << "Caught exception in build function for item " << m_item->name() << ":\n"
00208                               << iException.what() << std::endl;
00209          exit(1);
00210       }
00211    }
00212    m_mustBuild = false;
00213 }
00214 
00215 //______________________________________________________________________________
00216 void
00217 FWProxyBuilderBase::modelChanges(const FWModelIds& iIds, Product* p)
00218 {
00219    TEveElementList* elms = p->m_elements;
00220    assert(m_item && static_cast<int>(m_item->size()) <= elms->NumChildren() && "can not use default modelChanges implementation");
00221 
00222    TEveElement::List_i itElement = elms->BeginChildren();
00223    int index = 0;
00224    for (FWModelIds::const_iterator it = iIds.begin(), itEnd = iIds.end();
00225         it != itEnd;
00226         ++it,++itElement,++index)
00227    {
00228       assert(itElement != elms->EndChildren());
00229       while (index < it->index())
00230       {
00231          ++itElement;
00232          ++index;
00233          assert(itElement != elms->EndChildren());
00234       }
00235       if (visibilityModelChanges(*it, *itElement, p->m_viewType, p->m_viewContext))
00236       {
00237          elms->ProjectChild(*itElement);
00238       }
00239       else
00240       {
00241         localModelChanges(*it, *itElement, p->m_viewType, p->m_viewContext);
00242       }
00243    }
00244 }
00245 
00246 void
00247 FWProxyBuilderBase::modelChanges(const FWModelIds& iIds)
00248 {
00249   if(m_haveWindow) {
00250     for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00251     {
00252        modelChanges(iIds, *i);
00253     }
00254     m_modelsChanged=false;
00255   } else {
00256     m_modelsChanged=true;
00257   }
00258 }
00259 
00260 //______________________________________________________________________________
00261 void
00262 FWProxyBuilderBase::itemChanged(const FWEventItem* iItem)
00263 { 
00264    if (iItem->layer() != m_layer)
00265       setProjectionLayer(iItem->layer());
00266 
00267    if(m_haveWindow) {
00268       build();
00269    } else {
00270       m_mustBuild=true;
00271    }
00272    m_modelsChanged=false;
00273 }
00274 
00275 //______________________________________________________________________________
00276 bool
00277 FWProxyBuilderBase::canHandle(const FWEventItem& item)
00278 {
00279   if (m_item)
00280     return (item.purpose() == m_item->purpose());
00281 
00282   return false;
00283 }
00284 
00285 //______________________________________________________________________________
00286 
00287 TEveElementList*
00288 FWProxyBuilderBase::createProduct(const FWViewType::EType viewType, const FWViewContext* viewContext)
00289 {
00290    if ( havePerViewProduct(viewType) == false && m_products.empty() == false)
00291    {
00292       if (haveSingleProduct())
00293       {
00294          return m_products.back()->m_elements;
00295       }
00296       else
00297       {
00298          for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00299          {
00300             if (viewType == (*i)->m_viewType)  
00301                return (*i)->m_elements;
00302          }
00303       }
00304    }
00305 
00306    // printf("new product %s for item %s \n", FWViewType::idToName(viewType).c_str(), item()->name().c_str()); fflush(stdout);
00307  
00308    Product* product = new Product(viewType, viewContext);
00309    m_products.push_back(product);
00310    if (viewContext)
00311    {
00312       product->m_scaleConnection = viewContext->scaleChanged_.connect(boost::bind(&FWProxyBuilderBase::scaleChanged, this, _1));
00313    }
00314 
00315    if (item()) 
00316    {
00317       // debug info in eve browser       
00318       product->m_elements->SetElementName(item()->name().c_str());
00319    }
00320    return product->m_elements;
00321 }
00322 
00323 //______________________________________________________________________________
00324 
00325 void
00326 FWProxyBuilderBase::removePerViewProduct(FWViewType::EType type, const FWViewContext* vc)
00327 {
00328    for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00329    {  
00330       if (havePerViewProduct(type) &&  (*i)->m_viewContext == vc)
00331       { 
00332          if ((*i)->m_elements)
00333             (*i)->m_elements->DestroyElements();
00334 
00335          if ( (*i)->m_viewContext)
00336             (*i)->m_scaleConnection.disconnect();
00337 
00338          delete (*i);
00339          m_products.erase(i);
00340          break;
00341       }
00342    }
00343 }
00344 
00345 //------------------------------------------------------------------------------
00346 
00347 void
00348 FWProxyBuilderBase::setInteractionList(FWInteractionList* l, const std::string& /*purpose*/ )
00349 {
00350    // Called if willHandleInteraction() returns false. Purpose ignored by default.
00351 
00352    m_interactionList = l;
00353 }
00354 
00355 
00356 bool
00357 FWProxyBuilderBase::visibilityModelChanges(const FWModelId&, TEveElement*, FWViewType::EType, const FWViewContext*)
00358 {
00359    return false;
00360 }
00361 
00362 void
00363 FWProxyBuilderBase::localModelChanges(const FWModelId&, TEveElement*, FWViewType::EType, const FWViewContext*)
00364 {
00365    // Nothing to be done in base class.
00366    // Visibility, main color and main transparency are handled through FWInteractionList.
00367 }
00368 
00369 
00370 void
00371 FWProxyBuilderBase::scaleChanged(const FWViewContext* vc)
00372 {
00373    for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00374    {  
00375       if ( havePerViewProduct((*i)->m_viewType) && (*i)->m_viewContext == vc)
00376       {
00377          scaleProduct((*i)->m_elements, (*i)->m_viewType, (*i)->m_viewContext);
00378       }
00379    }
00380    gEve->Redraw3D();
00381 }
00382 
00383 void
00384 FWProxyBuilderBase::clean()
00385 {
00386    // Cleans local common element list.
00387    for (Product_it i = m_products.begin(); i != m_products.end(); ++i)
00388    {
00389       if ((*i)->m_elements)
00390          (*i)->m_elements->DestroyElements();
00391    }
00392 
00393    cleanLocal();
00394 }
00395 
00396 void
00397 FWProxyBuilderBase::cleanLocal()
00398 {
00399    // Cleans local common element list.
00400 }
00401 
00402 
00403 void
00404 FWProxyBuilderBase::build(const FWEventItem*, TEveElementList*, const FWViewContext*)
00405 {
00406    assert("virtual build(const FWEventItem*, TEveElementList*, const FWViewContext*) not implemented by inherited class");
00407 }
00408 
00409 void 
00410 FWProxyBuilderBase::buildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*)
00411 {
00412    assert("virtual buildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*) not implemented by inherited class");
00413 }
00414 
00415 void
00416 FWProxyBuilderBase::setProjectionLayer(float layer)
00417 {
00418    m_layer = layer;
00419    for (Product_it pIt = m_products.begin(); pIt != m_products.end(); ++pIt)
00420    {
00421       TEveProjectable* pable = static_cast<TEveProjectable*>((*pIt)->m_elements);
00422       for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
00423          (*i)->SetDepth(m_layer);
00424    }
00425 }
00426 
00427 //------------------------------------------------------------------------------
00428 
00429 void
00430 FWProxyBuilderBase::setupAddElement(TEveElement* el, TEveElement* parent, bool color) const
00431 {
00432    setupElement(el, color);
00433    parent->AddElement(el);
00434 }
00435 
00439 void
00440 FWProxyBuilderBase::setupElement(TEveElement* el, bool color) const
00441 {
00442    el->CSCTakeAnyParentAsMaster();
00443    el->SetPickable(true);
00444 
00445    if (color)
00446    {
00447       el->CSCApplyMainColorToMatchingChildren();
00448       el->CSCApplyMainTransparencyToMatchingChildren();
00449       el->SetMainColor(m_item->defaultDisplayProperties().color());
00450       assert((m_item->defaultDisplayProperties().transparency() >= 0)
00451              && (m_item->defaultDisplayProperties().transparency() <= 100));
00452       el->SetMainTransparency(m_item->defaultDisplayProperties().transparency());
00453    }
00454 }
00455 
00456 //------------------------------------------------------------------------------
00457 
00458 TEveCompound*
00459 FWProxyBuilderBase::createCompound(bool set_color, bool propagate_color_to_all_children) const
00460 {
00461    TEveCompound* c = new TEveCompound();
00462    c->CSCTakeAnyParentAsMaster();
00463    c->CSCImplySelectAllChildren();
00464    c->SetPickable(true);
00465    if (set_color)
00466    {
00467       c->SetMainColor(m_item->defaultDisplayProperties().color());
00468       c->SetMainTransparency(m_item->defaultDisplayProperties().transparency());
00469    }
00470    if (propagate_color_to_all_children)
00471    {
00472       c->CSCApplyMainColorToAllChildren();
00473       c->CSCApplyMainTransparencyToAllChildren();
00474    }
00475    else
00476    {
00477       c->CSCApplyMainColorToMatchingChildren();
00478       c->CSCApplyMainTransparencyToMatchingChildren();
00479    }
00480    return c;
00481 }
00482 
00483 void
00484 FWProxyBuilderBase::increaseComponentTransparency(unsigned int index, TEveElement* holder,
00485                                                     const std::string& name, Char_t transpOffset)
00486 {
00487    // Helper function to increse transparency of certain components.
00488 
00489    const FWDisplayProperties& dp = item()->modelInfo(index).displayProperties();
00490    Char_t transp = TMath::Min(100, transpOffset + (100 - transpOffset) * dp.transparency() / 100);
00491    TEveElement::List_t matches;
00492    holder->FindChildren(matches, name.c_str());
00493    for (TEveElement::List_i m = matches.begin(); m != matches.end(); ++m)
00494    {
00495       (*m)->SetMainTransparency(transp);
00496    }
00497 }
00498 
00499 //
00500 // const member functions
00501 //
00502 
00503 const fireworks::Context&
00504 FWProxyBuilderBase::context() const
00505 {
00506    return m_item->context();
00507 }
00508 
00509 int
00510 FWProxyBuilderBase::layer() const
00511 {
00512    return m_item->layer();
00513 }
00514 
00515 //
00516 // static member functions
00517 //
00518 
00519 std::string FWProxyBuilderBase::typeOfBuilder()
00520 {
00521    return std::string();
00522 }
00523 
00524 bool FWProxyBuilderBase::representsSubPart()
00525 {
00526    return false;
00527 }