File indexing completed on 2024-04-06 12:11:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <iostream>
0015 #include <functional>
0016
0017
0018 #include "TEveElement.h"
0019 #include "TEveCompound.h"
0020 #include "TEveManager.h"
0021 #include "TEveProjectionManager.h"
0022 #include "TEveSelection.h"
0023
0024 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
0025 #include "Fireworks/Core/interface/FWEventItem.h"
0026 #include "Fireworks/Core/interface/FWModelId.h"
0027 #include "Fireworks/Core/interface/FWInteractionList.h"
0028 #include "Fireworks/Core/interface/FWViewContext.h"
0029 #include "Fireworks/Core/interface/fwLog.h"
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 FWProxyBuilderBase::Product::Product(FWViewType::EType t, const FWViewContext* c)
0044 : m_viewType(t), m_viewContext(c), m_elements(nullptr) {
0045 m_elements = new TEveElementList("ProxyProduct");
0046 m_elements->IncDenyDestroy();
0047 }
0048
0049 FWProxyBuilderBase::Product::~Product() {
0050
0051 TEveProjectable* pable = dynamic_cast<TEveProjectable*>(m_elements);
0052
0053 for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i) {
0054 TEveElement* projected = (*i)->GetProjectedAsElement();
0055 (*projected->BeginParents())->RemoveElement(projected);
0056 }
0057
0058
0059 while (m_elements->HasParents()) {
0060 TEveElement* parent = *m_elements->BeginParents();
0061 parent->RemoveElement(m_elements);
0062 }
0063
0064 m_elements->Annihilate();
0065 }
0066
0067
0068
0069 FWProxyBuilderBase::FWProxyBuilderBase()
0070 : m_interactionList(nullptr),
0071 m_item(nullptr),
0072 m_modelsChanged(false),
0073 m_haveWindow(false),
0074 m_mustBuild(true),
0075 m_layer(0) {}
0076
0077 FWProxyBuilderBase::~FWProxyBuilderBase() { m_products.clear(); }
0078
0079
0080
0081
0082
0083 void FWProxyBuilderBase::setItem(const FWEventItem* iItem) { m_item = iItem; }
0084
0085 void FWProxyBuilderBase::setHaveWindow(bool iFlag) {
0086 bool oldValue = m_haveWindow;
0087 m_haveWindow = iFlag;
0088
0089 if (iFlag && !oldValue) {
0090
0091 if (m_mustBuild) {
0092 build();
0093 }
0094 }
0095 }
0096
0097 void FWProxyBuilderBase::itemBeingDestroyed(const FWEventItem* iItem) {
0098 m_item = nullptr;
0099
0100 cleanLocal();
0101
0102 for (Product_it i = m_products.begin(); i != m_products.end(); i++) {
0103 (*i)->m_scaleConnection.disconnect();
0104 delete (*i);
0105 }
0106
0107 m_products.clear();
0108 }
0109
0110 void FWProxyBuilderBase::build() {
0111 if (m_item) {
0112 try {
0113 size_t itemSize = m_item->size();
0114
0115 clean();
0116 for (Product_it i = m_products.begin(); i != m_products.end(); ++i) {
0117
0118 TEveElementList* elms = (*i)->m_elements;
0119 size_t oldSize = elms->NumChildren();
0120
0121 if (haveSingleProduct()) {
0122 build(m_item, elms, (*i)->m_viewContext);
0123 } else {
0124 buildViewType(m_item, elms, (*i)->m_viewType, (*i)->m_viewContext);
0125 }
0126
0127
0128
0129
0130 TEveProjectable* pable = dynamic_cast<TEveProjectable*>(elms);
0131 if (pable->HasProjecteds()) {
0132
0133 for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i) {
0134 TEveProjectionManager* pmgr = (*i)->GetManager();
0135 Float_t oldDepth = pmgr->GetCurrentDepth();
0136 pmgr->SetCurrentDepth(item()->layer());
0137 size_t cnt = 0;
0138
0139 TEveElement* projectedAsElement = (*i)->GetProjectedAsElement();
0140 TEveElement::List_i parentIt = projectedAsElement->BeginChildren();
0141 for (TEveElement::List_i prodIt = elms->BeginChildren(); prodIt != elms->EndChildren(); ++prodIt, ++cnt) {
0142
0143 if (cnt < oldSize) {
0144 if ((*parentIt)->NumChildren()) {
0145
0146 for (TEveElement::List_i pci = (*parentIt)->BeginChildren(); pci != (*parentIt)->EndChildren(); pci++)
0147 pmgr->ProjectChildrenRecurse(*parentIt);
0148 } else {
0149
0150 pmgr->SubImportChildren(*prodIt, *parentIt);
0151 }
0152
0153 ++parentIt;
0154 } else if (cnt < itemSize) {
0155
0156 pmgr->SubImportElements(*prodIt, projectedAsElement);
0157 } else {
0158 break;
0159 }
0160 }
0161 pmgr->SetCurrentDepth(oldDepth);
0162 }
0163 }
0164
0165 if (m_interactionList && itemSize > oldSize) {
0166 TEveElement::List_i elIt = elms->BeginChildren();
0167 for (size_t cnt = 0; cnt < itemSize; ++cnt, ++elIt) {
0168 if (cnt >= oldSize)
0169 m_interactionList->added(*elIt, cnt);
0170 }
0171 }
0172 }
0173 } catch (const std::runtime_error& iException) {
0174 fwLog(fwlog::kError) << "Caught exception in build function for item " << m_item->name() << ":\n"
0175 << iException.what() << std::endl;
0176 exit(1);
0177 }
0178 }
0179 m_mustBuild = false;
0180 }
0181
0182
0183 void FWProxyBuilderBase::modelChanges(const FWModelIds& iIds, Product* p) {
0184 TEveElementList* elms = p->m_elements;
0185 assert(m_item && static_cast<int>(m_item->size()) <= elms->NumChildren() &&
0186 "can not use default modelChanges implementation");
0187
0188 TEveElement::List_i itElement = elms->BeginChildren();
0189 int index = 0;
0190 for (FWModelIds::const_iterator it = iIds.begin(), itEnd = iIds.end(); it != itEnd; ++it, ++itElement, ++index) {
0191 assert(itElement != elms->EndChildren());
0192 while (index < it->index()) {
0193 ++itElement;
0194 ++index;
0195 assert(itElement != elms->EndChildren());
0196 }
0197 if (visibilityModelChanges(*it, *itElement, p->m_viewType, p->m_viewContext)) {
0198 elms->ProjectChild(*itElement);
0199 } else {
0200 localModelChanges(*it, *itElement, p->m_viewType, p->m_viewContext);
0201 }
0202 }
0203 }
0204
0205 void FWProxyBuilderBase::modelChanges(const FWModelIds& iIds) {
0206 if (m_haveWindow) {
0207 for (Product_it i = m_products.begin(); i != m_products.end(); ++i) {
0208 modelChanges(iIds, *i);
0209 }
0210 m_modelsChanged = false;
0211 } else {
0212 m_modelsChanged = true;
0213 }
0214 }
0215
0216
0217 void FWProxyBuilderBase::itemChanged(const FWEventItem* iItem) {
0218 if (iItem->layer() != m_layer)
0219 setProjectionLayer(iItem->layer());
0220
0221 if (m_haveWindow) {
0222 build();
0223 } else {
0224 m_mustBuild = true;
0225 }
0226 m_modelsChanged = false;
0227 }
0228
0229
0230 bool FWProxyBuilderBase::canHandle(const FWEventItem& item) {
0231 if (m_item)
0232 return (item.purpose() == m_item->purpose());
0233
0234 return false;
0235 }
0236
0237
0238
0239 TEveElementList* FWProxyBuilderBase::createProduct(const FWViewType::EType viewType, const FWViewContext* viewContext) {
0240 if (havePerViewProduct(viewType) == false && m_products.empty() == false) {
0241 if (haveSingleProduct()) {
0242 return m_products.back()->m_elements;
0243 } else {
0244 for (Product_it i = m_products.begin(); i != m_products.end(); ++i) {
0245 if (viewType == (*i)->m_viewType)
0246 return (*i)->m_elements;
0247 }
0248 }
0249 }
0250
0251
0252
0253 Product* product = new Product(viewType, viewContext);
0254 m_products.push_back(product);
0255 if (viewContext) {
0256 product->m_scaleConnection =
0257 viewContext->scaleChanged_.connect(std::bind(&FWProxyBuilderBase::scaleChanged, this, std::placeholders::_1));
0258 }
0259
0260 if (item()) {
0261
0262 product->m_elements->SetElementName(item()->name().c_str());
0263 }
0264 return product->m_elements;
0265 }
0266
0267
0268
0269 void FWProxyBuilderBase::removePerViewProduct(FWViewType::EType type, const FWViewContext* vc) {
0270 for (Product_it i = m_products.begin(); i != m_products.end(); ++i) {
0271 if (havePerViewProduct(type) && (*i)->m_viewContext == vc) {
0272 if ((*i)->m_elements)
0273 (*i)->m_elements->DestroyElements();
0274
0275 if ((*i)->m_viewContext)
0276 (*i)->m_scaleConnection.disconnect();
0277
0278 delete (*i);
0279 m_products.erase(i);
0280 break;
0281 }
0282 }
0283 }
0284
0285
0286
0287 void FWProxyBuilderBase::setInteractionList(FWInteractionList* l, const std::string& ) {
0288
0289
0290 m_interactionList = l;
0291 }
0292
0293 bool FWProxyBuilderBase::visibilityModelChanges(const FWModelId&,
0294 TEveElement*,
0295 FWViewType::EType,
0296 const FWViewContext*) {
0297 return false;
0298 }
0299
0300 void FWProxyBuilderBase::localModelChanges(const FWModelId&, TEveElement*, FWViewType::EType, const FWViewContext*) {
0301
0302
0303 }
0304
0305 void FWProxyBuilderBase::scaleChanged(const FWViewContext* vc) {
0306 for (Product_it i = m_products.begin(); i != m_products.end(); ++i) {
0307 if (havePerViewProduct((*i)->m_viewType) && (*i)->m_viewContext == vc) {
0308 scaleProduct((*i)->m_elements, (*i)->m_viewType, (*i)->m_viewContext);
0309 }
0310 }
0311 gEve->Redraw3D();
0312 }
0313
0314 void FWProxyBuilderBase::clean() {
0315
0316 for (Product_it i = m_products.begin(); i != m_products.end(); ++i) {
0317 if ((*i)->m_elements)
0318 (*i)->m_elements->DestroyElements();
0319 }
0320
0321 cleanLocal();
0322 }
0323
0324 void FWProxyBuilderBase::cleanLocal() {
0325
0326 }
0327
0328 void FWProxyBuilderBase::build(const FWEventItem*, TEveElementList*, const FWViewContext*) {
0329 assert(
0330 "virtual build(const FWEventItem*, TEveElementList*, const FWViewContext*) not implemented by inherited class");
0331 }
0332
0333 void FWProxyBuilderBase::buildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*) {
0334 assert(
0335 "virtual buildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*) not "
0336 "implemented by inherited class");
0337 }
0338
0339 void FWProxyBuilderBase::setProjectionLayer(float layer) {
0340 m_layer = layer;
0341 for (Product_it pIt = m_products.begin(); pIt != m_products.end(); ++pIt) {
0342 TEveProjectable* pable = static_cast<TEveProjectable*>((*pIt)->m_elements);
0343 for (TEveProjectable::ProjList_i i = pable->BeginProjecteds(); i != pable->EndProjecteds(); ++i)
0344 (*i)->SetDepth(m_layer);
0345 }
0346 }
0347
0348
0349
0350 void FWProxyBuilderBase::setupAddElement(TEveElement* el, TEveElement* parent, bool color) const {
0351 setupElement(el, color);
0352 parent->AddElement(el);
0353 }
0354
0355
0356
0357
0358 void FWProxyBuilderBase::setupElement(TEveElement* el, bool color) const {
0359 el->CSCTakeAnyParentAsMaster();
0360 el->SetPickable(true);
0361
0362 if (color) {
0363 el->CSCApplyMainColorToMatchingChildren();
0364 el->CSCApplyMainTransparencyToMatchingChildren();
0365 el->SetMainColor(m_item->defaultDisplayProperties().color());
0366 assert((m_item->defaultDisplayProperties().transparency() >= 0) &&
0367 (m_item->defaultDisplayProperties().transparency() <= 100));
0368 el->SetMainTransparency(m_item->defaultDisplayProperties().transparency());
0369 }
0370 }
0371
0372
0373
0374 TEveCompound* FWProxyBuilderBase::createCompound(bool set_color, bool propagate_color_to_all_children) const {
0375 TEveCompound* c = new TEveCompound();
0376 c->CSCTakeAnyParentAsMaster();
0377 c->CSCImplySelectAllChildren();
0378 c->SetPickable(true);
0379 if (set_color) {
0380 c->SetMainColor(m_item->defaultDisplayProperties().color());
0381 c->SetMainTransparency(m_item->defaultDisplayProperties().transparency());
0382 }
0383 if (propagate_color_to_all_children) {
0384 c->CSCApplyMainColorToAllChildren();
0385 c->CSCApplyMainTransparencyToAllChildren();
0386 } else {
0387 c->CSCApplyMainColorToMatchingChildren();
0388 c->CSCApplyMainTransparencyToMatchingChildren();
0389 }
0390 return c;
0391 }
0392
0393 void FWProxyBuilderBase::increaseComponentTransparency(unsigned int index,
0394 TEveElement* holder,
0395 const std::string& name,
0396 Char_t transpOffset) {
0397
0398
0399 Char_t transparency = item()->modelInfo(index).displayProperties().transparency();
0400 Char_t transp = TMath::Min(100, transpOffset + (100 - transpOffset) * transparency / 100);
0401 TEveElement::List_t matches;
0402 holder->FindChildren(matches, name.c_str());
0403 for (TEveElement::List_i m = matches.begin(); m != matches.end(); ++m) {
0404 (*m)->SetMainTransparency(transp);
0405 }
0406 }
0407
0408
0409
0410
0411
0412 const fireworks::Context& FWProxyBuilderBase::context() const { return m_item->context(); }
0413
0414 int FWProxyBuilderBase::layer() const { return m_item->layer(); }
0415
0416
0417
0418
0419
0420 std::string FWProxyBuilderBase::typeOfBuilder() { return std::string(); }
0421
0422 bool FWProxyBuilderBase::representsSubPart() { return false; }