00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <iostream>
00016 #include <boost/bind.hpp>
00017
00018
00019 #include "TEveElement.h"
00020 #include "TEveCompound.h"
00021 #include "TEveManager.h"
00022 #include "TEveProjectionManager.h"
00023 #include "TEveSelection.h"
00024
00025 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
00026 #include "Fireworks/Core/interface/FWEventItem.h"
00027 #include "Fireworks/Core/interface/FWModelId.h"
00028 #include "Fireworks/Core/interface/FWInteractionList.h"
00029 #include "Fireworks/Core/interface/FWViewContext.h"
00030 #include "Fireworks/Core/interface/fwLog.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 FWProxyBuilderBase::Product::Product(FWViewType::EType t, const FWViewContext* c) : m_viewType(t), m_viewContext(c), m_elements(0)
00046 {
00047 m_elements = new TEveElementList("ProxyProduct");
00048 m_elements->IncDenyDestroy();
00049 }
00050
00051
00052 FWProxyBuilderBase::Product::~Product()
00053 {
00054
00055 TEveProjectable* pable = dynamic_cast<TEveProjectable*>(m_elements);
00056
00057 for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
00058 {
00059 TEveElement* projected = (*i)->GetProjectedAsElement();
00060 (*projected->BeginParents())->RemoveElement(projected);
00061 }
00062
00063
00064 while (m_elements->HasParents())
00065 {
00066 TEveElement* parent = *m_elements->BeginParents();
00067 parent->RemoveElement(m_elements);
00068 }
00069
00070 m_elements->Annihilate();
00071 }
00072
00073
00074
00075 FWProxyBuilderBase::FWProxyBuilderBase():
00076 m_interactionList(0),
00077 m_item(0),
00078 m_modelsChanged(false),
00079 m_haveWindow(false),
00080 m_mustBuild(true),
00081 m_layer(0)
00082 {
00083 }
00084
00085 FWProxyBuilderBase::~FWProxyBuilderBase()
00086 {
00087 m_products.clear();
00088 }
00089
00090
00091
00092
00093
00094 void
00095 FWProxyBuilderBase::setItem(const FWEventItem* iItem)
00096 {
00097 m_item = iItem;
00098 }
00099
00100 void
00101 FWProxyBuilderBase::setHaveWindow(bool iFlag)
00102 {
00103 bool oldValue = m_haveWindow;
00104 m_haveWindow=iFlag;
00105
00106 if(iFlag && !oldValue) {
00107
00108 if(m_mustBuild) {
00109 build();
00110 }
00111 }
00112 }
00113
00114 void
00115 FWProxyBuilderBase::itemBeingDestroyed(const FWEventItem* iItem)
00116 {
00117 m_item=0;
00118
00119 cleanLocal();
00120
00121 for (Product_it i = m_products.begin(); i!= m_products.end(); i++)
00122 {
00123
00124 (*i)->m_scaleConnection.disconnect();
00125 delete (*i);
00126 }
00127
00128 m_products.clear();
00129 }
00130
00131 void
00132 FWProxyBuilderBase::build()
00133 {
00134 if (m_item)
00135 {
00136 try
00137 {
00138 size_t itemSize = m_item->size();
00139
00140 clean();
00141 for (Product_it i = m_products.begin(); i != m_products.end(); ++i)
00142 {
00143
00144 TEveElementList* elms = (*i)->m_elements;
00145 size_t oldSize = elms->NumChildren();
00146
00147 if (haveSingleProduct())
00148 {
00149 build(m_item, elms, (*i)->m_viewContext);
00150 }
00151 else
00152 {
00153 buildViewType(m_item, elms, (*i)->m_viewType, (*i)->m_viewContext);
00154 }
00155
00156
00157
00158
00159 TEveProjectable* pable = dynamic_cast<TEveProjectable*>(elms);
00160 if (pable->HasProjecteds())
00161 {
00162 for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
00163 {
00164 TEveProjectionManager *pmgr = (*i)->GetManager();
00165 Float_t oldDepth = pmgr->GetCurrentDepth();
00166 pmgr->SetCurrentDepth(item()->layer());
00167 size_t cnt = 0;
00168
00169 TEveElement* projectedAsElement = (*i)->GetProjectedAsElement();
00170 TEveElement::List_i parentIt = projectedAsElement->BeginChildren();
00171 for (TEveElement::List_i prodIt = elms->BeginChildren(); prodIt != elms->EndChildren(); ++prodIt, ++cnt)
00172 {
00173 if (cnt < oldSize)
00174 {
00175
00176 pmgr->SubImportChildren(*prodIt, *parentIt);
00177 ++parentIt;
00178 }
00179 else if (cnt < itemSize)
00180 {
00181
00182 pmgr->SubImportElements(*prodIt, projectedAsElement);
00183 }
00184 else
00185 {
00186 break;
00187 }
00188 }
00189 pmgr->SetCurrentDepth(oldDepth);
00190 }
00191 }
00192
00193
00194 if (m_interactionList && itemSize > oldSize)
00195 {
00196 TEveElement::List_i elIt = elms->BeginChildren();
00197 for (size_t cnt = 0; cnt < itemSize; ++cnt, ++elIt)
00198 {
00199 if (cnt >= oldSize )
00200 m_interactionList->added(*elIt, cnt);
00201 }
00202 }
00203 }
00204 }
00205 catch (const std::runtime_error& iException)
00206 {
00207 fwLog(fwlog::kError) << "Caught exception in build function for item " << m_item->name() << ":\n"
00208 << iException.what() << std::endl;
00209 exit(1);
00210 }
00211 }
00212 m_mustBuild = false;
00213 }
00214
00215
00216 void
00217 FWProxyBuilderBase::modelChanges(const FWModelIds& iIds, Product* p)
00218 {
00219 TEveElementList* elms = p->m_elements;
00220 assert(m_item && static_cast<int>(m_item->size()) <= elms->NumChildren() && "can not use default modelChanges implementation");
00221
00222 TEveElement::List_i itElement = elms->BeginChildren();
00223 int index = 0;
00224 for (FWModelIds::const_iterator it = iIds.begin(), itEnd = iIds.end();
00225 it != itEnd;
00226 ++it,++itElement,++index)
00227 {
00228 assert(itElement != elms->EndChildren());
00229 while (index < it->index())
00230 {
00231 ++itElement;
00232 ++index;
00233 assert(itElement != elms->EndChildren());
00234 }
00235 if (visibilityModelChanges(*it, *itElement, p->m_viewType, p->m_viewContext))
00236 {
00237 elms->ProjectChild(*itElement);
00238 }
00239 else
00240 {
00241 localModelChanges(*it, *itElement, p->m_viewType, p->m_viewContext);
00242 }
00243 }
00244 }
00245
00246 void
00247 FWProxyBuilderBase::modelChanges(const FWModelIds& iIds)
00248 {
00249 if(m_haveWindow) {
00250 for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00251 {
00252 modelChanges(iIds, *i);
00253 }
00254 m_modelsChanged=false;
00255 } else {
00256 m_modelsChanged=true;
00257 }
00258 }
00259
00260
00261 void
00262 FWProxyBuilderBase::itemChanged(const FWEventItem* iItem)
00263 {
00264 if (iItem->layer() != m_layer)
00265 setProjectionLayer(iItem->layer());
00266
00267 if(m_haveWindow) {
00268 build();
00269 } else {
00270 m_mustBuild=true;
00271 }
00272 m_modelsChanged=false;
00273 }
00274
00275
00276 bool
00277 FWProxyBuilderBase::canHandle(const FWEventItem& item)
00278 {
00279 if (m_item)
00280 return (item.purpose() == m_item->purpose());
00281
00282 return false;
00283 }
00284
00285
00286
00287 TEveElementList*
00288 FWProxyBuilderBase::createProduct(const FWViewType::EType viewType, const FWViewContext* viewContext)
00289 {
00290 if ( havePerViewProduct(viewType) == false && m_products.empty() == false)
00291 {
00292 if (haveSingleProduct())
00293 {
00294 return m_products.back()->m_elements;
00295 }
00296 else
00297 {
00298 for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00299 {
00300 if (viewType == (*i)->m_viewType)
00301 return (*i)->m_elements;
00302 }
00303 }
00304 }
00305
00306
00307
00308 Product* product = new Product(viewType, viewContext);
00309 m_products.push_back(product);
00310 if (viewContext)
00311 {
00312 product->m_scaleConnection = viewContext->scaleChanged_.connect(boost::bind(&FWProxyBuilderBase::scaleChanged, this, _1));
00313 }
00314
00315 if (item())
00316 {
00317
00318 product->m_elements->SetElementName(item()->name().c_str());
00319 }
00320 return product->m_elements;
00321 }
00322
00323
00324
00325 void
00326 FWProxyBuilderBase::removePerViewProduct(FWViewType::EType type, const FWViewContext* vc)
00327 {
00328 for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00329 {
00330 if (havePerViewProduct(type) && (*i)->m_viewContext == vc)
00331 {
00332 if ((*i)->m_elements)
00333 (*i)->m_elements->DestroyElements();
00334
00335 if ( (*i)->m_viewContext)
00336 (*i)->m_scaleConnection.disconnect();
00337
00338 delete (*i);
00339 m_products.erase(i);
00340 break;
00341 }
00342 }
00343 }
00344
00345
00346
00347 void
00348 FWProxyBuilderBase::setInteractionList(FWInteractionList* l, const std::string& )
00349 {
00350
00351
00352 m_interactionList = l;
00353 }
00354
00355
00356 bool
00357 FWProxyBuilderBase::visibilityModelChanges(const FWModelId&, TEveElement*, FWViewType::EType, const FWViewContext*)
00358 {
00359 return false;
00360 }
00361
00362 void
00363 FWProxyBuilderBase::localModelChanges(const FWModelId&, TEveElement*, FWViewType::EType, const FWViewContext*)
00364 {
00365
00366
00367 }
00368
00369
00370 void
00371 FWProxyBuilderBase::scaleChanged(const FWViewContext* vc)
00372 {
00373 for (Product_it i = m_products.begin(); i!= m_products.end(); ++i)
00374 {
00375 if ( havePerViewProduct((*i)->m_viewType) && (*i)->m_viewContext == vc)
00376 {
00377 scaleProduct((*i)->m_elements, (*i)->m_viewType, (*i)->m_viewContext);
00378 }
00379 }
00380 gEve->Redraw3D();
00381 }
00382
00383 void
00384 FWProxyBuilderBase::clean()
00385 {
00386
00387 for (Product_it i = m_products.begin(); i != m_products.end(); ++i)
00388 {
00389 if ((*i)->m_elements)
00390 (*i)->m_elements->DestroyElements();
00391 }
00392
00393 cleanLocal();
00394 }
00395
00396 void
00397 FWProxyBuilderBase::cleanLocal()
00398 {
00399
00400 }
00401
00402
00403 void
00404 FWProxyBuilderBase::build(const FWEventItem*, TEveElementList*, const FWViewContext*)
00405 {
00406 assert("virtual build(const FWEventItem*, TEveElementList*, const FWViewContext*) not implemented by inherited class");
00407 }
00408
00409 void
00410 FWProxyBuilderBase::buildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*)
00411 {
00412 assert("virtual buildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*) not implemented by inherited class");
00413 }
00414
00415 void
00416 FWProxyBuilderBase::setProjectionLayer(float layer)
00417 {
00418 m_layer = layer;
00419 for (Product_it pIt = m_products.begin(); pIt != m_products.end(); ++pIt)
00420 {
00421 TEveProjectable* pable = static_cast<TEveProjectable*>((*pIt)->m_elements);
00422 for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
00423 (*i)->SetDepth(m_layer);
00424 }
00425 }
00426
00427
00428
00429 void
00430 FWProxyBuilderBase::setupAddElement(TEveElement* el, TEveElement* parent, bool color) const
00431 {
00432 setupElement(el, color);
00433 parent->AddElement(el);
00434 }
00435
00439 void
00440 FWProxyBuilderBase::setupElement(TEveElement* el, bool color) const
00441 {
00442 el->CSCTakeAnyParentAsMaster();
00443 el->SetPickable(true);
00444
00445 if (color)
00446 {
00447 el->CSCApplyMainColorToMatchingChildren();
00448 el->CSCApplyMainTransparencyToMatchingChildren();
00449 el->SetMainColor(m_item->defaultDisplayProperties().color());
00450 assert((m_item->defaultDisplayProperties().transparency() >= 0)
00451 && (m_item->defaultDisplayProperties().transparency() <= 100));
00452 el->SetMainTransparency(m_item->defaultDisplayProperties().transparency());
00453 }
00454 }
00455
00456
00457
00458 TEveCompound*
00459 FWProxyBuilderBase::createCompound(bool set_color, bool propagate_color_to_all_children) const
00460 {
00461 TEveCompound* c = new TEveCompound();
00462 c->CSCTakeAnyParentAsMaster();
00463 c->CSCImplySelectAllChildren();
00464 c->SetPickable(true);
00465 if (set_color)
00466 {
00467 c->SetMainColor(m_item->defaultDisplayProperties().color());
00468 c->SetMainTransparency(m_item->defaultDisplayProperties().transparency());
00469 }
00470 if (propagate_color_to_all_children)
00471 {
00472 c->CSCApplyMainColorToAllChildren();
00473 c->CSCApplyMainTransparencyToAllChildren();
00474 }
00475 else
00476 {
00477 c->CSCApplyMainColorToMatchingChildren();
00478 c->CSCApplyMainTransparencyToMatchingChildren();
00479 }
00480 return c;
00481 }
00482
00483 void
00484 FWProxyBuilderBase::increaseComponentTransparency(unsigned int index, TEveElement* holder,
00485 const std::string& name, Char_t transpOffset)
00486 {
00487
00488
00489 const FWDisplayProperties& dp = item()->modelInfo(index).displayProperties();
00490 Char_t transp = TMath::Min(100, transpOffset + (100 - transpOffset) * dp.transparency() / 100);
00491 TEveElement::List_t matches;
00492 holder->FindChildren(matches, name.c_str());
00493 for (TEveElement::List_i m = matches.begin(); m != matches.end(); ++m)
00494 {
00495 (*m)->SetMainTransparency(transp);
00496 }
00497 }
00498
00499
00500
00501
00502
00503 const fireworks::Context&
00504 FWProxyBuilderBase::context() const
00505 {
00506 return m_item->context();
00507 }
00508
00509 int
00510 FWProxyBuilderBase::layer() const
00511 {
00512 return m_item->layer();
00513 }
00514
00515
00516
00517
00518
00519 std::string FWProxyBuilderBase::typeOfBuilder()
00520 {
00521 return std::string();
00522 }
00523
00524 bool FWProxyBuilderBase::representsSubPart()
00525 {
00526 return false;
00527 }