CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Fireworks/Core/src/FWGeometryTableManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWGeometryTableManager
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  
00010 //         Created:  Wed Jan  4 20:31:25 CET 2012
00011 // $Id: FWGeometryTableManager.cc,v 1.45 2012/02/22 23:03:47 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 
00016 // user include files
00017 #include "Fireworks/Core/src/FWGeometryTableManager.h"
00018 #include "Fireworks/Core/interface/FWGeometryTableViewBase.h"
00019 #include "Fireworks/Core/interface/FWGeometryTableViewManager.h"
00020 #include "Fireworks/Core/src/FWGeometryTableView.h"
00021 
00022 #include "TEveUtil.h"
00023 
00024 FWGeometryTableManager::FWGeometryTableManager(FWGeometryTableView* v):
00025    FWGeometryTableManagerBase(),
00026    m_browser(v),
00027    m_filterOff(true)
00028 {
00029 }
00030 
00031 
00032 FWGeometryTableManager::~FWGeometryTableManager()
00033 {
00034 }
00035 
00036 const char* FWGeometryTableManager::cellName(const NodeInfo& data) const
00037 {
00038    if (m_browser->getVolumeMode())
00039       return Form("%s [%d]", data.m_node->GetVolume()->GetName(), data.m_node->GetNdaughters());
00040    else    
00041       return Form("%s [%d]", data.m_node->GetName(), data.m_node->GetNdaughters()); 
00042 }
00043 
00044 //______________________________________________________________________________
00045 
00046 FWTableCellRendererBase* FWGeometryTableManager::cellRenderer(int iSortedRowNumber, int iCol) const
00047 {
00048    FWTextTreeCellRenderer* renderer = &m_renderer;
00049    if (m_row_to_index.empty()) return renderer;
00050 
00051 
00052    int unsortedRow =  m_row_to_index[iSortedRowNumber];
00053    if (unsortedRow < 0) printf("!!!!!!!!!!!!!!!! error %d %d \n",unsortedRow,  iSortedRowNumber);
00054 
00055 
00056    const NodeInfo& data = m_entries[unsortedRow];
00057    TGeoNode& gn = *data.m_node;
00058    bool isSelected = data.testBit(kHighlighted) ||  data.testBit(kSelected);
00059    // printf("cell render %s \n", data.name());
00060    if (data.testBit(kSelected))
00061    {
00062       m_highlightContext->SetBackground(0xc86464);
00063    }
00064    else if (data.testBit(kHighlighted) )
00065    {
00066       m_highlightContext->SetBackground(0x6464c8);
00067    }
00068    else if (iCol == kMaterialColumn && data.testBit(kMatches) )
00069    {
00070          m_highlightContext->SetBackground(0xdddddd);
00071    }
00072 
00073 
00074    if (iCol == kNameColumn)
00075    {
00076       renderer->setData(cellName(data), isSelected); 
00077 
00078 
00079       renderer->setIsParent(nodeIsParent(data));
00080 
00081       renderer->setIsOpen( data.testBit(FWGeometryTableManagerBase::kExpanded));
00082 
00083       int level = data.m_level - m_levelOffset;
00084       if (nodeIsParent(data))
00085          renderer->setIndentation(20*level);
00086       else
00087          renderer->setIndentation(20*level + FWTextTreeCellRenderer::iconWidth());
00088 
00089       return renderer;
00090    }
00091    else
00092    {
00093       // printf("title %s \n",data.m_node->GetTitle() );
00094       renderer->setIsParent(false);
00095       renderer->setIndentation(0);
00096       if (iCol == kColorColumn)
00097       {
00098          // m_colorBoxRenderer.setData(data.m_node->GetVolume()->GetLineColor(), isSelected);
00099          m_colorBoxRenderer.setData(data.m_color, isSelected);
00100          return  &m_colorBoxRenderer;
00101       }
00102       else if (iCol == kVisSelfColumn )
00103       {
00104          renderer->setData(getVisibility(data)  ? "On" : "-",  isSelected );
00105          return renderer;
00106       }
00107       else if (iCol == kVisChildColumn )
00108       {
00109          renderer->setData( getVisibilityChld(data) ? "On" : "-",  isSelected);
00110          return renderer;
00111       }
00112       else if (iCol == kMaterialColumn )
00113       { 
00114          renderer->setData( gn.GetVolume()->GetMaterial()->GetName(),  isSelected);
00115          return renderer;
00116       }
00117       else
00118       {  renderer->setData("ERROR", false);
00119          return renderer;
00120       }
00121 
00122    }
00123 }
00124 //____________________________________________________________________________
00125 
00126 void FWGeometryTableManager::importChildren(int parent_idx)
00127 {
00128    NodeInfo& parent        = m_entries[parent_idx];
00129    TGeoNode* parentGeoNode = parent.m_node; 
00130    int       parentLevel   = parent.m_level; 
00131    
00132    int nV = parentGeoNode->GetNdaughters();
00133    int dOff = 0; 
00134    for (int n = 0; n != nV; ++n)
00135    {         
00136       NodeInfo& data = m_entries[parent_idx + n + 1 + dOff];    
00137       data.m_node =   parentGeoNode->GetDaughter(n);
00138       data.m_level =  parentLevel + 1;
00139       data.m_parent = parent_idx;
00140       data.m_color =  data.m_node->GetVolume()->GetLineColor();
00141       if (data.m_level <=  m_browser->getAutoExpand()) data.setBit(kExpanded);
00142       
00143  
00144       importChildren(parent_idx + n + 1 + dOff);         
00145       getNNodesTotal(parentGeoNode->GetDaughter(n), dOff);            
00146    }  
00147 }
00148 
00149 //==============================================================================
00150 
00151 void FWGeometryTableManager::checkHierarchy()
00152 {
00153    // Used for debug: in a NodeInfo entry look TGeoNode children from parent index and check
00154    // if child is found.
00155    
00156    for ( size_t i = 0,  e = m_entries.size(); i != e; ++i )
00157    {
00158       if ( m_entries[i].m_level > 0)
00159       {
00160          TGeoNode* pn = m_entries[m_entries[i].m_parent].m_node;
00161          bool ok = false;
00162          for (int d = 0; d < pn->GetNdaughters(); ++d )
00163          {
00164             if (m_entries[i].m_node ==  pn->GetDaughter(d))
00165             {
00166                ok = true;
00167                break;
00168             }
00169          }
00170          if (!ok) printf("!!!!!! node %s has false parent %s \n", m_entries[i].name(), pn->GetName());
00171       }   
00172    }
00173 }
00174 
00175 void FWGeometryTableManager::checkChildMatches(TGeoVolume* vol,  std::vector<TGeoVolume*>& pstack)
00176 {
00177    if (m_volumes[vol].m_matches)
00178    {
00179       for (std::vector<TGeoVolume*>::iterator i = pstack.begin(); i!= pstack.end(); ++i)
00180       {
00181          Match& pm =  m_volumes[*i];
00182          pm.m_childMatches = true; 
00183       }
00184    }
00185 
00186    pstack.push_back(vol);
00187 
00188    int nD =  vol->GetNdaughters();//TMath::Min(m_browser->getMaxDaughters(), vol->GetNdaughters());
00189    for (int i = 0; i!=nD; ++i)
00190       checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
00191    
00192    pstack.pop_back();
00193 }
00194 
00195 // callbacks ______________________________________________________________________________
00196 
00197 void FWGeometryTableManager::updateFilter()
00198 {
00199    std::string filterExp =  m_browser->getFilter();
00200    m_filterOff =  filterExp.empty();
00201    //   printf("update filter %s  OFF %d volumes size %d\n",filterExp.c_str(),  m_filterOff , (int)m_volumes.size());
00202 
00203    if (m_filterOff || m_entries.empty()) return;
00204    
00205    // update volume-match entries
00206    //   m_numVolumesMatched = 0;
00207    for (Volumes_i i = m_volumes.begin(); i!= m_volumes.end(); ++i) 
00208    {
00209       if (strcasestr(i->first->GetMaterial()->GetName(), filterExp.c_str()) > 0) {
00210          i->second.m_matches = true;
00211          //    m_numVolumesMatched++;
00212       }
00213       else {
00214          i->second.m_matches = false;
00215       }
00216       i->second.m_childMatches = false;
00217    }  
00218 
00219    std::vector<TGeoVolume*> pstack;
00220    checkChildMatches(m_entries[TMath::Max(0,m_browser->getTopNodeIdx())].m_node->GetVolume(), pstack);
00221  
00222 
00223    for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni)
00224       ni->resetBit(kFilterCached);
00225 
00226 }
00227 
00228 //==============================================================================
00229 
00230 void FWGeometryTableManager::loadGeometry( TGeoNode* iGeoTopNode, TObjArray* iVolumes)
00231 {
00232 #ifdef PERFTOOL_GEO_TABLE  
00233    ProfilerStart("loadGeo");
00234 #endif
00235    
00236    // Prepare data for cell render.
00237    
00238    // clear entries
00239    m_entries.clear();
00240    m_row_to_index.clear();
00241    m_volumes.clear();
00242    m_levelOffset = 0;
00243 
00244    // set volume table for filters
00245    boost::unordered_map<TGeoVolume*, Match>  pipi(iVolumes->GetSize());
00246    m_volumes.swap(pipi);
00247    TIter next( iVolumes);
00248    TGeoVolume* v;
00249    while ((v = (TGeoVolume*) next()) != 0)
00250       m_volumes.insert(std::make_pair(v, Match()));
00251 
00252    if (!m_filterOff)
00253       updateFilter();  
00254 
00255    // add top node to init
00256  
00257    int nTotal = 0;
00258    NodeInfo topNodeInfo;
00259    topNodeInfo.m_node   = iGeoTopNode;
00260    topNodeInfo.m_level  = 0;
00261    topNodeInfo.m_parent = -1;
00262    topNodeInfo.setBitVal(kExpanded, m_browser->getAutoExpand());
00263    topNodeInfo.setBitVal(kVisNodeSelf, m_browser->drawTopNode());
00264 
00265    getNNodesTotal(topNodeInfo.m_node , nTotal);
00266    m_entries.resize(nTotal+1);
00267    m_entries[0] = topNodeInfo;
00268 
00269    importChildren(0);
00270 
00271    // checkHierarchy();
00272    
00273 #ifdef PERFTOOL_GEO_TABLE  
00274    ProfilerStop();
00275 #endif
00276 }
00277 
00278 
00279 
00280 //______________________________________________________________________________
00281 void FWGeometryTableManager::printMaterials()
00282 {
00283    std::cerr << "not implemented \n";
00284 }
00285 //______________________________________________________________________________
00286       
00287 void FWGeometryTableManager::recalculateVisibility()
00288 {
00289    m_row_to_index.clear();
00290 
00291 
00292    int i = TMath::Max(0, m_browser->getTopNodeIdx());
00293    m_row_to_index.push_back(i);
00294 
00295    NodeInfo& data = m_entries[i];
00296 
00297    if (!m_filterOff)
00298       assertNodeFilterCache(data);
00299 
00300    if ((m_filterOff && data.testBit(kExpanded) == false) ||
00301        (m_filterOff == false && data.testBit(kChildMatches) == false) )
00302       return;
00303 
00304    if (m_browser->getVolumeMode())
00305       recalculateVisibilityVolumeRec(i);
00306    else
00307       recalculateVisibilityNodeRec(i);
00308 
00309    //  printf (" child [%d] FWGeometryTableManagerBase::recalculateVisibility table size %d \n", (int)m_row_to_index.size());
00310 }
00311 
00312 //______________________________________________________________________________
00313 
00314 void FWGeometryTableManager::recalculateVisibilityVolumeRec(int pIdx)
00315 {
00316    TGeoNode* parentNode = m_entries[pIdx].m_node;
00317    int nD = parentNode->GetNdaughters();
00318    int dOff=0;
00319 
00320    // printf("----------- parent %s\n", parentNode->GetName() );
00321 
00322    std::vector<int> vi; 
00323    vi.reserve(nD);
00324 
00325 
00326    for (int n = 0; n != nD; ++n)
00327    {
00328       int idx = pIdx + 1 + n + dOff;
00329       NodeInfo& data = m_entries[idx];
00330 
00331       bool toAdd = true;
00332       for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u )
00333       {
00334          TGeoVolume* neighbourVolume =  parentNode->GetDaughter(*u)->GetVolume();
00335          if (neighbourVolume == data.m_node->GetVolume())
00336          {
00337             toAdd = false;
00338             // printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
00339             break;
00340          }
00341       }
00342 
00343       if (toAdd)
00344       {
00345          vi.push_back(n);
00346          if (m_filterOff)
00347          {
00348             //    std::cout << data.nameIndent() << std::endl;
00349             m_row_to_index.push_back(idx);
00350             if (data.testBit(kExpanded)) recalculateVisibilityVolumeRec(idx);
00351          }
00352          else
00353          {
00354             assertNodeFilterCache(data);
00355             if (data.testBitAny(kMatches | kChildMatches)) m_row_to_index.push_back(idx); 
00356             if (data.testBit(kChildMatches) && data.testBit(kExpanded)) recalculateVisibilityVolumeRec(idx);
00357          }
00358       }
00359       FWGeometryTableManagerBase::getNNodesTotal(parentNode->GetDaughter(n), dOff);
00360    }
00361 }
00362 
00363 //______________________________________________________________________________
00364 
00365 void FWGeometryTableManager::recalculateVisibilityNodeRec( int pIdx)
00366 {
00367    TGeoNode* parentNode = m_entries[pIdx].m_node;
00368    int nD = parentNode->GetNdaughters();
00369    int dOff=0;
00370    for (int n = 0; n != nD; ++n)
00371    {
00372       int idx = pIdx + 1 + n + dOff;
00373       NodeInfo& data = m_entries[idx];
00374 
00375       if (m_filterOff)
00376       {
00377          m_row_to_index.push_back(idx);
00378          if (data.testBit(kExpanded)) recalculateVisibilityNodeRec(idx);
00379       }
00380       else
00381       {
00382          assertNodeFilterCache(data);
00383          if (data.testBitAny(kMatches | kChildMatches)) m_row_to_index.push_back(idx); 
00384          if (data.testBit(kChildMatches) && data.testBit(kExpanded) ) recalculateVisibilityNodeRec(idx);
00385       }
00386 
00387       FWGeometryTableManagerBase::getNNodesTotal(parentNode->GetDaughter(n), dOff);
00388    }
00389 } 
00390 
00391 //______________________________________________________________________________
00392 void FWGeometryTableManager::assertNodeFilterCache(NodeInfo& data)
00393 {
00394    if (!data.testBit(kFilterCached))
00395    {
00396       bool matches = m_volumes[data.m_node->GetVolume()].m_matches;
00397       data.setBitVal(kMatches, matches);
00398       setVisibility(data, matches);
00399 
00400       bool childMatches = m_volumes[data.m_node->GetVolume()].m_childMatches;
00401       data.setBitVal(kChildMatches, childMatches);
00402       data.setBitVal(kExpanded, childMatches);
00403       setVisibilityChld(data, childMatches);
00404 
00405       data.setBit(kFilterCached);
00406       //  printf("%s matches [%d] childMatches [%d] ................ %d %d \n", data.name(), data.testBit(kMatches), data.testBit(kChildMatches), matches , childMatches);
00407    }
00408 }
00409 
00410 //______________________________________________________________________________
00411 void FWGeometryTableManager::setVisibility(NodeInfo& data, bool x)
00412 {
00413    if (m_browser->getVolumeMode())
00414    {
00415       if (data.m_node->GetVolume()->IsVisible() != x)
00416       {
00417          FWGeometryTableViewManager::getGeoMangeur();
00418          data.m_node->GetVolume()->SetVisibility(x);
00419       }
00420    }
00421    else
00422    {
00423       data.setBitVal(kVisNodeSelf, x);
00424    }
00425 }
00426 
00427 //______________________________________________________________________________
00428 
00429 void FWGeometryTableManager::setVisibilityChld(NodeInfo& data, bool x)
00430 {
00431    if (m_browser->getVolumeMode())
00432    {
00433       if (data.m_node->GetVolume()->IsVisibleDaughters() != x)
00434       {
00435          TEveGeoManagerHolder gmgr( FWGeometryTableViewManager::getGeoMangeur());
00436          data.m_node->GetVolume()->VisibleDaughters(x);
00437       }
00438    }
00439    else
00440       data.setBitVal(kVisNodeChld, x);
00441 }
00442 //______________________________________________________________________________
00443 
00444 void FWGeometryTableManager::setDaughtersSelfVisibility(int selectedIdx, bool v)
00445 {
00446    int dOff = 0;
00447    TGeoNode* parentNode = m_entries[selectedIdx].m_node;
00448    int nD = parentNode->GetNdaughters();
00449    for (int n = 0; n != nD; ++n)
00450    {
00451       int idx = selectedIdx + 1 + n + dOff;
00452       NodeInfo& data = m_entries[idx];
00453 
00454       setVisibility(data, v);
00455       setVisibilityChld(data, v);
00456 
00457       FWGeometryTableManager::getNNodesTotal(parentNode->GetDaughter(n), dOff);
00458    }
00459 }
00460 
00461 //______________________________________________________________________________
00462 
00463 bool  FWGeometryTableManager::getVisibility(const NodeInfo& data) const
00464 {
00465    if (m_browser->getVolumeMode())
00466       return data.m_node->GetVolume()->IsVisible();
00467 
00468    return  data.testBit(kVisNodeSelf);   
00469 }
00470 
00471 bool  FWGeometryTableManager::getVisibilityChld(const NodeInfo& data) const
00472 {
00473    if (m_browser->getVolumeMode())
00474       return data.m_node->GetVolume()->IsVisibleDaughters();
00475 
00476    return  data.testBit(kVisNodeChld);   
00477 }
00478 
00479 //______________________________________________________________________________
00480 
00481 bool  FWGeometryTableManager::nodeIsParent(const NodeInfo& data) const
00482 {
00483    return   (data.m_node->GetNdaughters() != 0) && (m_filterOff || data.testBit(kChildMatches) );
00484 }
00485