00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00057
00058 m_renderer.showEditor(unsortedRow == m_editTransparencyIdx && iCol == kTranspColumn);
00059
00060
00061
00062 const NodeInfo& data = m_entries[unsortedRow];
00063 TGeoNode& gn = *data.m_node;
00064 bool isSelected = data.testBit(kHighlighted) || data.testBit(kSelected);
00065
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
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
00100 renderer->setIsParent(false);
00101 renderer->setIndentation(0);
00102 if (iCol == kColorColumn)
00103 {
00104
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
00165
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();
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
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
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
00268
00269
00270 m_entries.clear();
00271 m_row_to_index.clear();
00272 m_volumes.clear();
00273 m_levelOffset = 0;
00274
00275
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
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
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
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
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
00370 break;
00371 }
00372 }
00373
00374 if (toAdd)
00375 {
00376 vi.push_back(n);
00377 if (m_filterOff)
00378 {
00379
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
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
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
00611 }