File indexing completed on 2024-04-06 12:11:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
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
0052
0053 m_renderer.showEditor(unsortedRow == m_editTransparencyIdx && iCol == kTranspColumn);
0054
0055
0056
0057 const NodeInfo& data = m_entries[unsortedRow];
0058 TGeoNode& gn = *data.m_node;
0059 bool isSelected = data.testBit(kHighlighted) || data.testBit(kSelected);
0060
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
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
0087 renderer->setIsParent(false);
0088 renderer->setIndentation(0);
0089 if (iCol == kColorColumn) {
0090
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
0140
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();
0169 for (int i = 0; i < nD; ++i)
0170 checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
0171
0172 pstack.pop_back();
0173 }
0174
0175
0176
0177
0178 namespace {
0179 int matchTPME(const char* w, TPMERegexp& regexp) {
0180 TString s(w);
0181 return regexp.Match(s);
0182 }
0183 }
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
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
0234
0235
0236 m_entries.clear();
0237 m_row_to_index.clear();
0238 m_volumes.clear();
0239 m_levelOffset = 0;
0240
0241
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
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
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
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
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
0328 break;
0329 }
0330 }
0331
0332 if (toAdd) {
0333 vi.push_back(n);
0334 if (m_filterOff) {
0335
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
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
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
0539 }