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
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
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
00094 renderer->setIsParent(false);
00095 renderer->setIndentation(0);
00096 if (iCol == kColorColumn)
00097 {
00098
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
00154
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();
00189 for (int i = 0; i!=nD; ++i)
00190 checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
00191
00192 pstack.pop_back();
00193 }
00194
00195
00196
00197 void FWGeometryTableManager::updateFilter()
00198 {
00199 std::string filterExp = m_browser->getFilter();
00200 m_filterOff = filterExp.empty();
00201
00202
00203 if (m_filterOff || m_entries.empty()) return;
00204
00205
00206
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
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
00237
00238
00239 m_entries.clear();
00240 m_row_to_index.clear();
00241 m_volumes.clear();
00242 m_levelOffset = 0;
00243
00244
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
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
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
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
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
00339 break;
00340 }
00341 }
00342
00343 if (toAdd)
00344 {
00345 vi.push_back(n);
00346 if (m_filterOff)
00347 {
00348
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
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