Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:39

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWGeometryTableManager
0005 //
0006 // Implementation:
0007 //     [Notes on implementation]
0008 //
0009 // Original Author:
0010 //         Created:  Wed Jan  4 20:31:25 CET 2012
0011 //
0012 
0013 // system include files
0014 
0015 // user include files
0016 #include "Fireworks/Core/src/FWGeometryTableManager.h"
0017 #include "Fireworks/Core/interface/FWGeometryTableViewBase.h"
0018 #include "Fireworks/Core/interface/FWGeometryTableViewManager.h"
0019 #include "Fireworks/Core/src/FWGeometryTableView.h"
0020 
0021 #include "TEveUtil.h"
0022 #include "TEveVector.h"
0023 #include "TGeoShape.h"
0024 #include "TGeoMatrix.h"
0025 #include "TGeoBBox.h"
0026 #include "TPRegexp.h"
0027 
0028 FWGeometryTableManager::FWGeometryTableManager(FWGeometryTableView* v)
0029     : FWGeometryTableManagerBase(), m_browser(v), m_filterOff(true) {}
0030 
0031 FWGeometryTableManager::~FWGeometryTableManager() {}
0032 
0033 const char* FWGeometryTableManager::cellName(const NodeInfo& data) const {
0034   if (m_browser->getVolumeMode())
0035     return Form("%s [%d]", data.m_node->GetVolume()->GetName(), data.m_node->GetNdaughters());
0036   else
0037     return Form("%s [%d]", data.m_node->GetName(), data.m_node->GetNdaughters());
0038 }
0039 
0040 //------------------------------------------------------------------------------
0041 
0042 FWTableCellRendererBase* FWGeometryTableManager::cellRenderer(int iSortedRowNumber, int iCol) const {
0043   FWTextTreeCellRenderer* renderer = &m_renderer;
0044   if (m_row_to_index.empty())
0045     return renderer;
0046 
0047   int unsortedRow = m_row_to_index[iSortedRowNumber];
0048   if (unsortedRow < 0)
0049     printf("!!!!!!!!!!!!!!!! error %d %d \n", unsortedRow, iSortedRowNumber);
0050 
0051   // editor state
0052   //
0053   m_renderer.showEditor(unsortedRow == m_editTransparencyIdx && iCol == kTranspColumn);
0054 
0055   // selection state
0056   //
0057   const NodeInfo& data = m_entries[unsortedRow];
0058   TGeoNode& gn = *data.m_node;
0059   bool isSelected = data.testBit(kHighlighted) || data.testBit(kSelected);
0060   // printf("cell render %s \n", data.name());
0061   if (data.testBit(kSelected)) {
0062     m_highlightContext->SetBackground(0xc86464);
0063   } else if (data.testBit(kHighlighted)) {
0064     m_highlightContext->SetBackground(0x6464c8);
0065   } else if (iCol == kMaterialColumn && data.testBit(kMatches)) {
0066     m_highlightContext->SetBackground(0xdddddd);
0067   }
0068 
0069   // set column content
0070   //
0071   if (iCol == kNameColumn) {
0072     renderer->setData(cellName(data), isSelected);
0073 
0074     renderer->setIsParent(nodeIsParent(data));
0075 
0076     renderer->setIsOpen(data.testBit(FWGeometryTableManagerBase::kExpanded));
0077 
0078     int level = data.m_level - m_levelOffset;
0079     if (nodeIsParent(data))
0080       renderer->setIndentation(20 * level);
0081     else
0082       renderer->setIndentation(20 * level + FWTextTreeCellRenderer::iconWidth());
0083 
0084     return renderer;
0085   } else {
0086     // printf("title %s \n",data.m_node->GetTitle());
0087     renderer->setIsParent(false);
0088     renderer->setIndentation(0);
0089     if (iCol == kColorColumn) {
0090       // m_colorBoxRenderer.setData(data.m_node->GetVolume()->GetLineColor(), isSelected);
0091       m_colorBoxRenderer.setData(data.m_color, isSelected);
0092       return &m_colorBoxRenderer;
0093     } else if (iCol == kTranspColumn) {
0094       renderer->setData(Form("%d", 100 - data.m_transparency), isSelected);
0095       return renderer;
0096     } else if (iCol == kVisSelfColumn) {
0097       renderer->setData(getVisibility(data) ? "On" : "-", isSelected);
0098       return renderer;
0099     } else if (iCol == kVisChildColumn) {
0100       renderer->setData(getVisibilityChld(data) ? "On" : "-", isSelected);
0101       return renderer;
0102     } else if (iCol == kMaterialColumn) {
0103       renderer->setData(gn.GetVolume()->GetMaterial()->GetName(), isSelected);
0104       return renderer;
0105     } else {
0106       renderer->setData("ERROR", false);
0107       return renderer;
0108     }
0109   }
0110 }
0111 
0112 //------------------------------------------------------------------------------
0113 
0114 void FWGeometryTableManager::importChildren(int parent_idx) {
0115   NodeInfo& parent = m_entries[parent_idx];
0116   TGeoNode* parentGeoNode = parent.m_node;
0117   int parentLevel = parent.m_level;
0118 
0119   int nV = parentGeoNode->GetNdaughters();
0120   int dOff = 0;
0121   for (int n = 0; n != nV; ++n) {
0122     NodeInfo& data = m_entries[parent_idx + n + 1 + dOff];
0123     data.m_node = parentGeoNode->GetDaughter(n);
0124     data.m_level = parentLevel + 1;
0125     data.m_parent = parent_idx;
0126     data.m_color = data.m_node->GetVolume()->GetLineColor();
0127     data.m_transparency = data.m_node->GetVolume()->GetTransparency();
0128     if (data.m_level <= m_browser->getAutoExpand())
0129       data.setBit(kExpanded);
0130 
0131     importChildren(parent_idx + n + 1 + dOff);
0132     getNNodesTotal(parentGeoNode->GetDaughter(n), dOff);
0133   }
0134 }
0135 
0136 //==============================================================================
0137 
0138 void FWGeometryTableManager::checkHierarchy() {
0139   // Used for debug: in a NodeInfo entry look TGeoNode children from parent index and check
0140   // if child is found.
0141 
0142   for (size_t i = 0, e = m_entries.size(); i != e; ++i) {
0143     if (m_entries[i].m_level > 0) {
0144       TGeoNode* pn = m_entries[m_entries[i].m_parent].m_node;
0145       bool ok = false;
0146       for (int d = 0; d < pn->GetNdaughters(); ++d) {
0147         if (m_entries[i].m_node == pn->GetDaughter(d)) {
0148           ok = true;
0149           break;
0150         }
0151       }
0152       if (!ok)
0153         printf("!!!!!! node %s has false parent %s \n", m_entries[i].name(), pn->GetName());
0154     }
0155   }
0156 }
0157 
0158 void FWGeometryTableManager::checkChildMatches(TGeoVolume* vol, std::vector<TGeoVolume*>& pstack) {
0159   if (m_volumes[vol].m_matches) {
0160     for (std::vector<TGeoVolume*>::iterator i = pstack.begin(); i != pstack.end(); ++i) {
0161       Match& pm = m_volumes[*i];
0162       pm.m_childMatches = true;
0163     }
0164   }
0165 
0166   pstack.push_back(vol);
0167 
0168   int nD = vol->GetNdaughters();  //TMath::Min(m_browser->getMaxDaughters(), vol->GetNdaughters());
0169   for (int i = 0; i < nD; ++i)
0170     checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
0171 
0172   pstack.pop_back();
0173 }
0174 
0175 //------------------------------------------------------------------------------
0176 // Callbacks
0177 //------------------------------------------------------------------------------
0178 namespace {
0179   int matchTPME(const char* w, TPMERegexp& regexp) {
0180     TString s(w);
0181     return regexp.Match(s);
0182   }
0183 }  // namespace
0184 
0185 void FWGeometryTableManager::updateFilter(int iType) {
0186   std::string filterExp = m_browser->getFilter();
0187   m_filterOff = filterExp.empty();
0188   printf("update filter %s  OFF %d volumes size %d\n", filterExp.c_str(), m_filterOff, (int)m_volumes.size());
0189 
0190   if (m_filterOff || m_entries.empty())
0191     return;
0192 
0193   // update volume-match entries
0194   int numMatched = 0;
0195 
0196   TPMERegexp regexp(TString(filterExp.c_str()), "o");
0197   for (Volumes_i i = m_volumes.begin(); i != m_volumes.end(); ++i) {
0198     int res = 0;
0199 
0200     if (iType == FWGeometryTableView::kFilterMaterialName) {
0201       res = matchTPME(i->first->GetMaterial()->GetName(), regexp);
0202     } else if (iType == FWGeometryTableView::kFilterMaterialTitle) {
0203       res = matchTPME(i->first->GetMaterial()->GetTitle(), regexp);
0204     } else if (iType == FWGeometryTableView::kFilterShapeName) {
0205       res = matchTPME(i->first->GetShape()->GetName(), regexp);
0206     } else if (iType == FWGeometryTableView::kFilterShapeClassName) {
0207       res = matchTPME(i->first->GetShape()->ClassName(), regexp);
0208     }
0209 
0210     i->second.m_matches = (res > 0);
0211     i->second.m_childMatches = false;
0212     if (res)
0213       numMatched++;
0214   }
0215 
0216   printf("update filter [%d] volumes matched\n", numMatched);
0217   std::vector<TGeoVolume*> pstack;
0218   checkChildMatches(m_entries[0].m_node->GetVolume(), pstack);
0219 
0220   for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni) {
0221     ni->resetBit(kFilterCached);
0222     assertNodeFilterCache(*ni);
0223   }
0224 }
0225 
0226 //==============================================================================
0227 
0228 void FWGeometryTableManager::loadGeometry(TGeoNode* iGeoTopNode, TObjArray* iVolumes) {
0229 #ifdef PERFTOOL_GEO_TABLE
0230   ProfilerStart("loadGeo");
0231 #endif
0232 
0233   // Prepare data for cell render.
0234 
0235   // clear entries
0236   m_entries.clear();
0237   m_row_to_index.clear();
0238   m_volumes.clear();
0239   m_levelOffset = 0;
0240 
0241   // set volume table for filters
0242   Volumes_t pipi(iVolumes->GetSize());
0243   m_volumes.swap(pipi);
0244   TIter next(iVolumes);
0245   TGeoVolume* v;
0246   while ((v = (TGeoVolume*)next()) != nullptr)
0247     m_volumes.insert(std::make_pair(v, Match()));
0248 
0249   if (!m_filterOff)
0250     updateFilter(m_browser->getFilterType());
0251 
0252   // add top node to init
0253 
0254   int nTotal = 0;
0255   NodeInfo topNodeInfo;
0256   topNodeInfo.m_node = iGeoTopNode;
0257   topNodeInfo.m_level = 0;
0258   topNodeInfo.m_parent = -1;
0259   topNodeInfo.m_color = iGeoTopNode->GetVolume()->GetLineColor();
0260   topNodeInfo.m_transparency = iGeoTopNode->GetVolume()->GetTransparency();
0261   topNodeInfo.setBitVal(kExpanded, m_browser->getAutoExpand());
0262   topNodeInfo.setBitVal(kVisNodeSelf, m_browser->drawTopNode());
0263 
0264   getNNodesTotal(topNodeInfo.m_node, nTotal);
0265   m_entries.resize(nTotal + 1);
0266   m_entries[0] = topNodeInfo;
0267 
0268   importChildren(0);
0269 
0270   // checkHierarchy();
0271 
0272 #ifdef PERFTOOL_GEO_TABLE
0273   ProfilerStop();
0274 #endif
0275 }
0276 
0277 //------------------------------------------------------------------------------
0278 
0279 void FWGeometryTableManager::printMaterials() { std::cerr << "not implemented \n"; }
0280 
0281 //------------------------------------------------------------------------------
0282 
0283 void FWGeometryTableManager::recalculateVisibility() {
0284   m_row_to_index.clear();
0285 
0286   int i = TMath::Max(0, m_browser->getTopNodeIdx());
0287   m_row_to_index.push_back(i);
0288 
0289   NodeInfo& data = m_entries[i];
0290 
0291   if (!m_filterOff)
0292     assertNodeFilterCache(data);
0293 
0294   if ((m_filterOff && data.testBit(kExpanded) == false) ||
0295       (m_filterOff == false && data.testBit(kChildMatches) == false))
0296     return;
0297 
0298   if (m_browser->getVolumeMode())
0299     recalculateVisibilityVolumeRec(i);
0300   else
0301     recalculateVisibilityNodeRec(i);
0302 
0303   //  printf (" child [%d] FWGeometryTableManagerBase::recalculateVisibility table size %d \n", (int)m_row_to_index.size());
0304 }
0305 
0306 //------------------------------------------------------------------------------
0307 
0308 void FWGeometryTableManager::recalculateVisibilityVolumeRec(int pIdx) {
0309   TGeoNode* parentNode = m_entries[pIdx].m_node;
0310   int nD = parentNode->GetNdaughters();
0311   int dOff = 0;
0312 
0313   // printf("----------- parent %s\n", parentNode->GetName() );
0314 
0315   std::vector<int> vi;
0316   vi.reserve(nD);
0317 
0318   for (int n = 0; n != nD; ++n) {
0319     int idx = pIdx + 1 + n + dOff;
0320     NodeInfo& data = m_entries[idx];
0321 
0322     bool toAdd = true;
0323     for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u) {
0324       TGeoVolume* neighbourVolume = parentNode->GetDaughter(*u)->GetVolume();
0325       if (neighbourVolume == data.m_node->GetVolume()) {
0326         toAdd = false;
0327         // printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
0328         break;
0329       }
0330     }
0331 
0332     if (toAdd) {
0333       vi.push_back(n);
0334       if (m_filterOff) {
0335         //    std::cout << data.nameIndent() << std::endl;
0336         m_row_to_index.push_back(idx);
0337         if (data.testBit(kExpanded))
0338           recalculateVisibilityVolumeRec(idx);
0339       } else {
0340         assertNodeFilterCache(data);
0341         if (data.testBitAny(kMatches | kChildMatches))
0342           m_row_to_index.push_back(idx);
0343         if (data.testBit(kChildMatches) && data.testBit(kExpanded))
0344           recalculateVisibilityVolumeRec(idx);
0345       }
0346     }
0347     FWGeometryTableManagerBase::getNNodesTotal(parentNode->GetDaughter(n), dOff);
0348   }
0349 }
0350 
0351 //------------------------------------------------------------------------------
0352 
0353 void FWGeometryTableManager::recalculateVisibilityNodeRec(int pIdx) {
0354   TGeoNode* parentNode = m_entries[pIdx].m_node;
0355   int nD = parentNode->GetNdaughters();
0356   int dOff = 0;
0357   for (int n = 0; n != nD; ++n) {
0358     int idx = pIdx + 1 + n + dOff;
0359     NodeInfo& data = m_entries[idx];
0360 
0361     if (m_filterOff) {
0362       m_row_to_index.push_back(idx);
0363       if (data.testBit(kExpanded))
0364         recalculateVisibilityNodeRec(idx);
0365     } else {
0366       assertNodeFilterCache(data);
0367       if (data.testBitAny(kMatches | kChildMatches))
0368         m_row_to_index.push_back(idx);
0369       if (data.testBit(kChildMatches) && data.testBit(kExpanded))
0370         recalculateVisibilityNodeRec(idx);
0371     }
0372 
0373     FWGeometryTableManagerBase::getNNodesTotal(parentNode->GetDaughter(n), dOff);
0374   }
0375 }
0376 
0377 //------------------------------------------------------------------------------
0378 
0379 void FWGeometryTableManager::assertNodeFilterCache(NodeInfo& data) {
0380   if (!data.testBit(kFilterCached)) {
0381     bool matches = m_volumes[data.m_node->GetVolume()].m_matches;
0382     // if (matches) printf("%s matches filter \n", data.name());
0383     data.setBitVal(kMatches, matches);
0384     setVisibility(data, matches);
0385 
0386     bool childMatches = m_volumes[data.m_node->GetVolume()].m_childMatches;
0387     data.setBitVal(kChildMatches, childMatches);
0388     data.setBitVal(kExpanded, childMatches);
0389     setVisibilityChld(data, childMatches);
0390 
0391     data.setBit(kFilterCached);
0392     //  printf("%s matches [%d] childMatches [%d] ................ %d %d \n", data.name(), data.testBit(kMatches), data.testBit(kChildMatches), matches , childMatches);
0393   }
0394 }
0395 
0396 //------------------------------------------------------------------------------
0397 
0398 void FWGeometryTableManager::setVisibility(NodeInfo& data, bool x) {
0399   if (m_browser->getVolumeMode()) {
0400     if (data.m_node->GetVolume()->IsVisible() != x) {
0401       FWGeometryTableViewManager::getGeoMangeur();
0402       data.m_node->GetVolume()->SetVisibility(x);
0403     }
0404   } else {
0405     data.setBitVal(kVisNodeSelf, x);
0406   }
0407 }
0408 
0409 //------------------------------------------------------------------------------
0410 
0411 void FWGeometryTableManager::setVisibilityChld(NodeInfo& data, bool x) {
0412   if (m_browser->getVolumeMode()) {
0413     if (data.m_node->GetVolume()->IsVisibleDaughters() != x) {
0414       TEveGeoManagerHolder gmgr(FWGeometryTableViewManager::getGeoMangeur());
0415       data.m_node->GetVolume()->VisibleDaughters(x);
0416     }
0417   } else {
0418     data.setBitVal(kVisNodeChld, x);
0419   }
0420 }
0421 //______________________________________________________________________________
0422 
0423 void FWGeometryTableManager::setDaughtersSelfVisibility(int selectedIdx, bool v) {
0424   TGeoNode* parentNode = m_entries[selectedIdx].m_node;
0425   int nD = parentNode->GetNdaughters();
0426   int dOff = 0;
0427   for (int n = 0; n != nD; ++n) {
0428     int idx = selectedIdx + 1 + n + dOff;
0429     NodeInfo& data = m_entries[idx];
0430 
0431     setVisibility(data, v);
0432     setVisibilityChld(data, v);
0433 
0434     FWGeometryTableManager::getNNodesTotal(parentNode->GetDaughter(n), dOff);
0435   }
0436 }
0437 
0438 //------------------------------------------------------------------------------
0439 
0440 bool FWGeometryTableManager::getVisibility(const NodeInfo& data) const {
0441   if (m_browser->getVolumeMode())
0442     return data.m_node->GetVolume()->IsVisible();
0443 
0444   return data.testBit(kVisNodeSelf);
0445 }
0446 
0447 bool FWGeometryTableManager::getVisibilityChld(const NodeInfo& data) const {
0448   if (m_browser->getVolumeMode())
0449     return data.m_node->GetVolume()->IsVisibleDaughters();
0450 
0451   return data.testBit(kVisNodeChld);
0452 }
0453 
0454 //------------------------------------------------------------------------------
0455 
0456 bool FWGeometryTableManager::nodeIsParent(const NodeInfo& data) const {
0457   return (data.m_node->GetNdaughters() != 0) && (m_filterOff || data.testBit(kChildMatches));
0458 }
0459 
0460 //------------------------------------------------------------------------------
0461 
0462 void FWGeometryTableManager::checkRegionOfInterest(double* center, double radius, long algo) {
0463   double sqr_r = radius * radius;
0464 
0465   for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni)
0466     ni->resetBit(kVisNodeChld);
0467 
0468   int cnt = 0;
0469   TEveGeoManagerHolder mangeur(FWGeometryTableViewManager::getGeoMangeur());
0470   printf("FWGeometryTableManagerBase::checkRegionOfInterest BEGIN r=%d center= (%.1f, %.1f, %.1f)\n ",
0471          (int)radius,
0472          center[0],
0473          center[1],
0474          center[2]);
0475   TGeoIterator git(m_entries[0].m_node->GetVolume());
0476   Entries_i eit(m_entries.begin());
0477   while (git()) {
0478     const TGeoMatrix* gm = git.GetCurrentMatrix();
0479     const TGeoBBox* bb = static_cast<TGeoBBox*>(eit->m_node->GetVolume()->GetShape());
0480     const Double_t* bo = bb->GetOrigin();
0481     const Double_t bd[] = {bb->GetDX(), bb->GetDY(), bb->GetDZ()};
0482     const Double_t* cc = center;
0483 
0484     bool visible = false;
0485 
0486     switch (algo) {
0487       case FWGeometryTableView::kBBoxCenter: {
0488         const Double_t* t = gm->GetTranslation();
0489         TEveVectorD d(cc[0] - (t[0] + bo[0]), cc[1] - (t[1] + bo[1]), cc[2] - (t[2] + bo[2]));
0490         Double_t sqr_d = d.Mag2();
0491         ;
0492         visible = (sqr_d <= sqr_r);
0493         break;
0494       }
0495       case FWGeometryTableView::kBBoxSurface: {
0496         assert(gm->IsScale() == false);
0497 
0498         const Double_t* t = gm->GetTranslation();
0499         const Double_t* r = gm->GetRotationMatrix();
0500         TEveVectorD d(cc[0] - (t[0] + bo[0]), cc[1] - (t[1] + bo[1]), cc[2] - (t[2] + bo[2]));
0501         Double_t sqr_d = 0;
0502         for (Int_t i = 0; i < 3; ++i) {
0503           Double_t dp = d[0] * r[i] + d[1] * r[i + 3] + d[2] * r[i + 6];
0504           if (dp < -bd[i]) {
0505             Double_t delta = dp + bd[i];
0506             sqr_d += delta * delta;
0507           } else if (dp > bd[i]) {
0508             Double_t delta = dp - bd[i];
0509             sqr_d += delta * delta;
0510           }
0511         }
0512         visible = (sqr_d <= sqr_r);
0513       }
0514     }
0515 
0516     if (visible) {
0517       eit->setBit(kVisNodeSelf);
0518       int pidx = eit->m_parent;
0519       while (pidx >= 0) {
0520         m_entries[pidx].setBit(kVisNodeChld);
0521         pidx = m_entries[pidx].m_parent;
0522         ++cnt;
0523       }
0524     } else {
0525       eit->resetBit(kVisNodeSelf);
0526     }
0527     eit++;
0528   }
0529 
0530   printf("FWGeometryTableManager::checkRegionOfInterest END [%d]\n ", cnt);
0531 }
0532 
0533 void FWGeometryTableManager::resetRegionOfInterest() {
0534   for (Entries_i ni = m_entries.begin(); ni != m_entries.end(); ++ni) {
0535     ni->setBit(kVisNodeSelf);
0536     ni->setBit(kVisNodeChld);
0537   }
0538   // ni->setMatchRegion(true);
0539 }