CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/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.54 2012/05/22 18:56:07 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 #include "TEveVector.h"
00024 #include "TGeoShape.h"
00025 #include "TGeoMatrix.h"
00026 #include "TGeoBBox.h"
00027 
00028 
00029 FWGeometryTableManager::FWGeometryTableManager(FWGeometryTableView* v):
00030    FWGeometryTableManagerBase(),
00031    m_browser(v),
00032    m_filterOff(true)
00033 {}
00034 
00035 FWGeometryTableManager::~FWGeometryTableManager()
00036 {}
00037 
00038 const char* FWGeometryTableManager::cellName(const NodeInfo& data) const
00039 {
00040    if (m_browser->getVolumeMode())
00041       return Form("%s [%d]", data.m_node->GetVolume()->GetName(), data.m_node->GetNdaughters());
00042    else
00043       return Form("%s [%d]", data.m_node->GetName(), data.m_node->GetNdaughters());
00044 }
00045 
00046 //------------------------------------------------------------------------------
00047 
00048 FWTableCellRendererBase* FWGeometryTableManager::cellRenderer(int iSortedRowNumber, int iCol) const
00049 {
00050    FWTextTreeCellRenderer* renderer = &m_renderer;
00051    if (m_row_to_index.empty()) return renderer;
00052 
00053    int unsortedRow =  m_row_to_index[iSortedRowNumber];
00054    if (unsortedRow < 0) printf("!!!!!!!!!!!!!!!! error %d %d \n",unsortedRow,  iSortedRowNumber);
00055 
00056    // editor state
00057    //
00058    m_renderer.showEditor(unsortedRow == m_editTransparencyIdx && iCol == kTranspColumn);
00059 
00060    // selection state
00061    //
00062    const NodeInfo& data = m_entries[unsortedRow];
00063    TGeoNode& gn = *data.m_node;
00064    bool isSelected = data.testBit(kHighlighted) ||  data.testBit(kSelected);
00065    // printf("cell render %s \n", data.name());
00066    if (data.testBit(kSelected))
00067    {
00068       m_highlightContext->SetBackground(0xc86464);
00069    }
00070    else if (data.testBit(kHighlighted) )
00071    {
00072       m_highlightContext->SetBackground(0x6464c8);
00073    }
00074    else if (iCol == kMaterialColumn && data.testBit(kMatches) )
00075    {
00076       m_highlightContext->SetBackground(0xdddddd);
00077    }
00078 
00079    // set column content
00080    //
00081    if (iCol == kNameColumn)
00082    {
00083       renderer->setData(cellName(data), isSelected);
00084 
00085       renderer->setIsParent(nodeIsParent(data));
00086 
00087       renderer->setIsOpen( data.testBit(FWGeometryTableManagerBase::kExpanded));
00088 
00089       int level = data.m_level - m_levelOffset;
00090       if (nodeIsParent(data))
00091          renderer->setIndentation(20*level);
00092       else
00093          renderer->setIndentation(20*level + FWTextTreeCellRenderer::iconWidth());
00094 
00095       return renderer;
00096    }
00097    else
00098    {
00099       // printf("title %s \n",data.m_node->GetTitle());
00100       renderer->setIsParent(false);
00101       renderer->setIndentation(0);
00102       if (iCol == kColorColumn)
00103       {
00104          // m_colorBoxRenderer.setData(data.m_node->GetVolume()->GetLineColor(), isSelected);
00105          m_colorBoxRenderer.setData(data.m_color, isSelected);
00106          return  &m_colorBoxRenderer;
00107       }
00108       else if (iCol == kTranspColumn)
00109       {
00110          renderer->setData(Form("%d", 100 -data.m_transparency), isSelected);
00111          return renderer;
00112       }
00113       else if (iCol == kVisSelfColumn)
00114       {
00115          renderer->setData(getVisibility(data)  ? "On" : "-", isSelected);
00116          return renderer;
00117       }
00118       else if (iCol == kVisChildColumn)
00119       {
00120          renderer->setData( getVisibilityChld(data) ? "On" : "-", isSelected);
00121          return renderer;
00122       }
00123       else if (iCol == kMaterialColumn)
00124       {
00125          renderer->setData( gn.GetVolume()->GetMaterial()->GetName(), isSelected);
00126          return renderer;
00127       }
00128       else
00129       {  renderer->setData("ERROR", false);
00130          return renderer;
00131       }
00132    }
00133 }
00134 
00135 //------------------------------------------------------------------------------
00136 
00137 void FWGeometryTableManager::importChildren(int parent_idx)
00138 {
00139    NodeInfo& parent        = m_entries[parent_idx];
00140    TGeoNode* parentGeoNode = parent.m_node;
00141    int       parentLevel   = parent.m_level;
00142 
00143    int nV   = parentGeoNode->GetNdaughters();
00144    int dOff = 0;
00145    for (int n = 0; n != nV; ++n)
00146    {
00147       NodeInfo& data = m_entries[parent_idx + n + 1 + dOff];
00148       data.m_node    = parentGeoNode->GetDaughter(n);
00149       data.m_level   = parentLevel + 1;
00150       data.m_parent  = parent_idx;
00151       data.m_color   = data.m_node->GetVolume()->GetLineColor();
00152       data.m_transparency = data.m_node->GetVolume()->GetTransparency();
00153       if (data.m_level <= m_browser->getAutoExpand()) data.setBit(kExpanded);
00154 
00155       importChildren(parent_idx + n + 1 + dOff);
00156       getNNodesTotal(parentGeoNode->GetDaughter(n), dOff);
00157    }
00158 }
00159 
00160 //==============================================================================
00161 
00162 void FWGeometryTableManager::checkHierarchy()
00163 {
00164    // Used for debug: in a NodeInfo entry look TGeoNode children from parent index and check
00165    // if child is found.
00166 
00167    for (size_t i = 0,  e = m_entries.size(); i != e; ++i)
00168    {
00169       if (m_entries[i].m_level > 0)
00170       {
00171          TGeoNode* pn = m_entries[m_entries[i].m_parent].m_node;
00172          bool ok = false;
00173          for (int d = 0; d < pn->GetNdaughters(); ++d)
00174          {
00175             if (m_entries[i].m_node == pn->GetDaughter(d))
00176             {
00177                ok = true;
00178                break;
00179             }
00180          }
00181          if (! ok) printf("!!!!!! node %s has false parent %s \n", m_entries[i].name(), pn->GetName());
00182       }
00183    }
00184 }
00185 
00186 void FWGeometryTableManager::checkChildMatches(TGeoVolume* vol, std::vector<TGeoVolume*>& pstack)
00187 {
00188    if (m_volumes[vol].m_matches)
00189    {
00190       for (std::vector<TGeoVolume*>::iterator i = pstack.begin(); i != pstack.end(); ++i)
00191       {
00192          Match& pm =  m_volumes[*i];
00193          pm.m_childMatches = true;
00194       }
00195    }
00196 
00197    pstack.push_back(vol);
00198 
00199    int nD = vol->GetNdaughters(); //TMath::Min(m_browser->getMaxDaughters(), vol->GetNdaughters());
00200    for (int i = 0; i < nD; ++i)
00201       checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
00202 
00203    pstack.pop_back();
00204 }
00205 
00206 
00207 //------------------------------------------------------------------------------
00208 // Callbacks
00209 //------------------------------------------------------------------------------
00210 
00211 void FWGeometryTableManager::updateFilter(int iType)
00212 {
00213    std::string filterExp =  m_browser->getFilter();
00214    m_filterOff =  filterExp.empty();
00215    printf("update filter %s  OFF %d volumes size %d\n",filterExp.c_str(),  m_filterOff , (int)m_volumes.size());
00216 
00217    if (m_filterOff || m_entries.empty()) return;
00218 
00219    // update volume-match entries
00220    int numMatched = 0;
00221    for (Volumes_i i = m_volumes.begin(); i != m_volumes.end(); ++i)
00222    {
00223       const char* res = 0;
00224       
00225       if (iType == FWGeometryTableView::kFilterMaterialName)
00226       {
00227          res = strcasestr( i->first->GetMaterial()->GetName() , filterExp.c_str());
00228       }
00229       else if (iType == FWGeometryTableView::kFilterMaterialTitle)
00230       {
00231          res = strcasestr( i->first->GetMaterial()->GetTitle() , filterExp.c_str());
00232       }
00233       else if (iType == FWGeometryTableView::kFilterShapeName) 
00234       {
00235          res = strcasestr( i->first->GetShape()->GetName() , filterExp.c_str());
00236       }      
00237       else if (iType == FWGeometryTableView::kFilterShapeClassName) 
00238       {
00239          res = strcasestr( i->first->GetShape()->ClassName() , filterExp.c_str());
00240       }
00241       
00242       i->second.m_matches = (res != 0);
00243       i->second.m_childMatches = false;
00244       if (res != 0) numMatched++;
00245    }
00246 
00247    printf("update filter [%d] volumes matched\n", numMatched);
00248    std::vector<TGeoVolume*> pstack;
00249    checkChildMatches(m_entries[0].m_node->GetVolume(), pstack);
00250 
00251    for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni)
00252    {
00253       ni->resetBit(kFilterCached);
00254      assertNodeFilterCache(*ni);
00255    }
00256    
00257 }
00258 
00259 //==============================================================================
00260 
00261 void FWGeometryTableManager::loadGeometry(TGeoNode* iGeoTopNode, TObjArray* iVolumes)
00262 {
00263 #ifdef PERFTOOL_GEO_TABLE
00264    ProfilerStart("loadGeo");
00265 #endif
00266 
00267    // Prepare data for cell render.
00268 
00269    // clear entries
00270    m_entries.clear();
00271    m_row_to_index.clear();
00272    m_volumes.clear();
00273    m_levelOffset = 0;
00274 
00275    // set volume table for filters
00276    boost::unordered_map<TGeoVolume*, Match>  pipi(iVolumes->GetSize());
00277    m_volumes.swap(pipi);
00278    TIter next( iVolumes);
00279    TGeoVolume* v;
00280    while ((v = (TGeoVolume*) next()) != 0)
00281       m_volumes.insert(std::make_pair(v, Match()));
00282 
00283    if (!m_filterOff)
00284       updateFilter(m_browser->getFilterType());
00285 
00286    // add top node to init
00287 
00288    int nTotal = 0;
00289    NodeInfo topNodeInfo;
00290    topNodeInfo.m_node   = iGeoTopNode;
00291    topNodeInfo.m_level  = 0;
00292    topNodeInfo.m_parent = -1;
00293    topNodeInfo.m_color =  iGeoTopNode->GetVolume()->GetLineColor();
00294    topNodeInfo.m_transparency = iGeoTopNode->GetVolume()->GetTransparency();
00295    topNodeInfo.setBitVal(kExpanded, m_browser->getAutoExpand());
00296    topNodeInfo.setBitVal(kVisNodeSelf, m_browser->drawTopNode());
00297 
00298    getNNodesTotal(topNodeInfo.m_node , nTotal);
00299    m_entries.resize(nTotal+1);
00300    m_entries[0] = topNodeInfo;
00301 
00302    importChildren(0);
00303 
00304    // checkHierarchy();
00305 
00306 #ifdef PERFTOOL_GEO_TABLE
00307    ProfilerStop();
00308 #endif
00309 }
00310 
00311 //------------------------------------------------------------------------------
00312 
00313 void FWGeometryTableManager::printMaterials()
00314 {
00315    std::cerr << "not implemented \n";
00316 }
00317 
00318 //------------------------------------------------------------------------------
00319 
00320 void FWGeometryTableManager::recalculateVisibility()
00321 {
00322    m_row_to_index.clear();
00323 
00324    int i = TMath::Max(0, m_browser->getTopNodeIdx());
00325    m_row_to_index.push_back(i);
00326 
00327    NodeInfo& data = m_entries[i];
00328 
00329    if (!m_filterOff)
00330       assertNodeFilterCache(data);
00331 
00332    if ((m_filterOff && data.testBit(kExpanded) == false) ||
00333        (m_filterOff == false && data.testBit(kChildMatches) == false))
00334       return;
00335 
00336    if (m_browser->getVolumeMode())
00337       recalculateVisibilityVolumeRec(i);
00338    else
00339       recalculateVisibilityNodeRec(i);
00340 
00341    //  printf (" child [%d] FWGeometryTableManagerBase::recalculateVisibility table size %d \n", (int)m_row_to_index.size());
00342 }
00343 
00344 //------------------------------------------------------------------------------
00345 
00346 void FWGeometryTableManager::recalculateVisibilityVolumeRec(int pIdx)
00347 {
00348    TGeoNode* parentNode = m_entries[pIdx].m_node;
00349    int nD = parentNode->GetNdaughters();
00350    int dOff=0;
00351 
00352    // printf("----------- parent %s\n", parentNode->GetName() );
00353 
00354    std::vector<int> vi;
00355    vi.reserve(nD);
00356 
00357    for (int n = 0; n != nD; ++n)
00358    {
00359       int idx = pIdx + 1 + n + dOff;
00360       NodeInfo& data = m_entries[idx];
00361 
00362       bool toAdd = true;
00363       for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u )
00364       {
00365          TGeoVolume* neighbourVolume =  parentNode->GetDaughter(*u)->GetVolume();
00366          if (neighbourVolume == data.m_node->GetVolume())
00367          {
00368             toAdd = false;
00369             // printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
00370             break;
00371          }
00372       }
00373 
00374       if (toAdd)
00375       {
00376          vi.push_back(n);
00377          if (m_filterOff)
00378          {
00379             //    std::cout << data.nameIndent() << std::endl;
00380             m_row_to_index.push_back(idx);
00381             if (data.testBit(kExpanded)) recalculateVisibilityVolumeRec(idx);
00382          }
00383          else
00384          {
00385             assertNodeFilterCache(data);
00386             if (data.testBitAny(kMatches | kChildMatches)) m_row_to_index.push_back(idx);
00387             if (data.testBit(kChildMatches) && data.testBit(kExpanded)) recalculateVisibilityVolumeRec(idx);
00388          }
00389       }
00390       FWGeometryTableManagerBase::getNNodesTotal(parentNode->GetDaughter(n), dOff);
00391    }
00392 }
00393 
00394 //------------------------------------------------------------------------------
00395 
00396 void FWGeometryTableManager::recalculateVisibilityNodeRec( int pIdx)
00397 {
00398    TGeoNode* parentNode = m_entries[pIdx].m_node;
00399    int nD   = parentNode->GetNdaughters();
00400    int dOff = 0;
00401    for (int n = 0; n != nD; ++n)
00402    {
00403       int idx = pIdx + 1 + n + dOff;
00404       NodeInfo& data = m_entries[idx];
00405 
00406       if (m_filterOff)
00407       {
00408          m_row_to_index.push_back(idx);
00409          if (data.testBit(kExpanded)) recalculateVisibilityNodeRec(idx);
00410       }
00411       else
00412       {
00413          assertNodeFilterCache(data);
00414          if (data.testBitAny(kMatches | kChildMatches)) m_row_to_index.push_back(idx);
00415          if (data.testBit(kChildMatches) && data.testBit(kExpanded) ) recalculateVisibilityNodeRec(idx);
00416       }
00417 
00418       FWGeometryTableManagerBase::getNNodesTotal(parentNode->GetDaughter(n), dOff);
00419    }
00420 }
00421 
00422 //------------------------------------------------------------------------------
00423 
00424 void FWGeometryTableManager::assertNodeFilterCache(NodeInfo& data)
00425 {
00426    if (! data.testBit(kFilterCached))
00427    {
00428       bool matches = m_volumes[data.m_node->GetVolume()].m_matches;
00429      // if (matches) printf("%s matches filter \n", data.name());
00430       data.setBitVal(kMatches, matches);
00431       setVisibility(data, matches);
00432 
00433       bool childMatches = m_volumes[data.m_node->GetVolume()].m_childMatches;
00434       data.setBitVal(kChildMatches, childMatches);
00435       data.setBitVal(kExpanded, childMatches);
00436       setVisibilityChld(data, childMatches);
00437 
00438       data.setBit(kFilterCached);
00439       //  printf("%s matches [%d] childMatches [%d] ................ %d %d \n", data.name(), data.testBit(kMatches), data.testBit(kChildMatches), matches , childMatches);
00440    }
00441 }
00442 
00443 //------------------------------------------------------------------------------
00444 
00445 void FWGeometryTableManager::setVisibility(NodeInfo& data, bool x)
00446 {
00447    if (m_browser->getVolumeMode())
00448    {
00449       if (data.m_node->GetVolume()->IsVisible() != x)
00450       {
00451          FWGeometryTableViewManager::getGeoMangeur();
00452          data.m_node->GetVolume()->SetVisibility(x);
00453       }
00454    }
00455    else
00456    {
00457       data.setBitVal(kVisNodeSelf, x);
00458    }
00459 }
00460 
00461 //------------------------------------------------------------------------------
00462 
00463 void FWGeometryTableManager::setVisibilityChld(NodeInfo& data, bool x)
00464 {
00465    if (m_browser->getVolumeMode())
00466    {
00467       if (data.m_node->GetVolume()->IsVisibleDaughters() != x)
00468       {
00469          TEveGeoManagerHolder gmgr( FWGeometryTableViewManager::getGeoMangeur());
00470          data.m_node->GetVolume()->VisibleDaughters(x);
00471       }
00472    }
00473    else
00474    {
00475       data.setBitVal(kVisNodeChld, x);
00476    }
00477 }
00478 //______________________________________________________________________________
00479 
00480 void FWGeometryTableManager::setDaughtersSelfVisibility(int selectedIdx, bool v)
00481 {
00482    TGeoNode  *parentNode = m_entries[selectedIdx].m_node;
00483    int nD   = parentNode->GetNdaughters();
00484    int dOff = 0;
00485    for (int n = 0; n != nD; ++n)
00486    {
00487       int idx = selectedIdx + 1 + n + dOff;
00488       NodeInfo& data = m_entries[idx];
00489 
00490       setVisibility(data, v);
00491       setVisibilityChld(data, v);
00492 
00493       FWGeometryTableManager::getNNodesTotal(parentNode->GetDaughter(n), dOff);
00494    }
00495 }
00496 
00497 //------------------------------------------------------------------------------
00498 
00499 bool FWGeometryTableManager::getVisibility(const NodeInfo& data) const
00500 {
00501    if (m_browser->getVolumeMode())
00502       return data.m_node->GetVolume()->IsVisible();
00503 
00504    return data.testBit(kVisNodeSelf);
00505 }
00506 
00507 bool FWGeometryTableManager::getVisibilityChld(const NodeInfo& data) const
00508 {
00509    if (m_browser->getVolumeMode())
00510       return data.m_node->GetVolume()->IsVisibleDaughters();
00511 
00512    return data.testBit(kVisNodeChld);
00513 }
00514 
00515 //------------------------------------------------------------------------------
00516 
00517 bool FWGeometryTableManager::nodeIsParent(const NodeInfo& data) const
00518 {
00519    return (data.m_node->GetNdaughters() != 0) && (m_filterOff || data.testBit(kChildMatches));
00520 }
00521 
00522 //------------------------------------------------------------------------------
00523 
00524 void FWGeometryTableManager::checkRegionOfInterest(double* center, double radius, long algo)
00525 {
00526    double sqr_r = radius * radius;
00527 
00528    for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni)
00529       ni->resetBit(kVisNodeChld);
00530 
00531    int cnt = 0;
00532    TEveGeoManagerHolder mangeur( FWGeometryTableViewManager::getGeoMangeur());
00533    printf("FWGeometryTableManagerBase::checkRegionOfInterest BEGIN r=%d center= (%.1f, %.1f, %.1f)\n ", (int)radius, center[0], center[1], center[2]);
00534    TGeoIterator git(m_entries[0].m_node->GetVolume());
00535    Entries_i    eit(m_entries.begin());
00536    while (git())
00537    {
00538       const TGeoMatrix *gm   = git.GetCurrentMatrix();
00539       const TGeoBBox   *bb   = static_cast<TGeoBBox*>(eit->m_node->GetVolume()->GetShape());
00540       const Double_t   *bo   = bb->GetOrigin();
00541       const Double_t    bd[] = { bb->GetDX(), bb->GetDY(), bb->GetDZ() };
00542       const Double_t   *cc   = center;
00543 
00544       bool visible = false;
00545 
00546       switch (algo)
00547       {
00548          case FWGeometryTableView::kBBoxCenter:
00549          {
00550             const Double_t *t = gm->GetTranslation();
00551             TEveVectorD d(cc[0] - (t[0] + bo[0]), cc[1] - (t[1] + bo[1]), cc[2] - (t[2] + bo[2]));
00552             Double_t sqr_d = d.Mag2();;
00553             visible = (sqr_d <= sqr_r);
00554             break;
00555          }
00556          case FWGeometryTableView::kBBoxSurface:
00557          {
00558             assert (gm->IsScale() == false);
00559 
00560             const Double_t *t = gm->GetTranslation();
00561             const Double_t *r = gm->GetRotationMatrix();
00562             TEveVectorD d(cc[0] - (t[0] + bo[0]), cc[1] - (t[1] + bo[1]), cc[2] - (t[2] + bo[2]));
00563             Double_t sqr_d = 0;
00564             for (Int_t i = 0; i < 3; ++i)
00565             {
00566                Double_t dp = d[0]*r[i] + d[1]*r[i+3] + d[2]*r[i+6];
00567                if (dp < -bd[i])
00568                {
00569                   Double_t delta = dp + bd[i];
00570                   sqr_d += delta * delta;
00571                }
00572                else if (dp > bd[i])
00573                {
00574                   Double_t delta = dp - bd[i];
00575                   sqr_d += delta * delta;               
00576                }
00577             }
00578             visible = (sqr_d <= sqr_r);
00579          }
00580       }
00581 
00582       if (visible)
00583       {
00584          eit->setBit(kVisNodeSelf);
00585          int pidx = eit->m_parent;
00586          while (pidx >= 0)
00587          {
00588             m_entries[pidx].setBit(kVisNodeChld);
00589             pidx = m_entries[pidx].m_parent;
00590             ++cnt;
00591          }
00592       }
00593       else
00594       {
00595          eit->resetBit(kVisNodeSelf);
00596       }
00597       eit++;
00598    }
00599 
00600    printf("FWGeometryTableManager::checkRegionOfInterest END [%d]\n ", cnt);
00601 }
00602 
00603 void FWGeometryTableManager::resetRegionOfInterest()
00604 {
00605    for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni)
00606    {
00607       ni->setBit(kVisNodeSelf);
00608       ni->setBit(kVisNodeChld);
00609    }
00610    // ni->setMatchRegion(true);
00611 }