Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveDataProxyBuilderBase.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel, 2018
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
15 #include <ROOT/REveViewContext.hxx>
16 #include <ROOT/REveCompound.hxx>
17 
18 #include <cassert>
19 
20 
21 using namespace ROOT::Experimental;
22 namespace REX = ROOT::Experimental;
23 
24 
25 REveDataProxyBuilderBase::Product::Product(std::string iViewType, const REveViewContext* c) : m_viewType(iViewType), m_viewContext(c), m_elements(0)
26 {
27  m_elements = new REveCompound("ProxyProduct", "", false);
28  m_elements->IncDenyDestroy();
29 }
30 
31 //______________________________________________________________________________
32 
33 
34 REveDataProxyBuilderBase::REveDataProxyBuilderBase(const std::string &type):
35  m_type(type),
36  m_collection(nullptr),
37  // m_interactionList(0),
38  m_haveWindow(false)
39 {
40 }
41 
42 REveDataProxyBuilderBase::Product::~Product()
43 {
44  // remove product from projected scene (RhoPhi or RhoZ)
45  for (auto i : m_elements->RefProjecteds())
46  {
47  REveElement *projected = i->GetProjectedAsElement();
48  projected->GetMother()->RemoveElement(projected);
49  }
50 
51  // XXXX This might break now ... m_elements will auto drestruct, no?
52  // We don't set incdenydestroy or additional something, do we?
53 
54  // remove from 3D scenes
55  if (m_elements->HasMother())
56  {
57  m_elements->GetMother()->RemoveElement(m_elements);
58  }
59 
60  m_elements->Annihilate();
61 }
62 
63 //------------------------------------------------------------------------------
64 
65 void REveDataProxyBuilderBase::SetCollection(REveDataCollection* c)
66 {
67  m_collection = c;
68 }
69 
70 //------------------------------------------------------------------------------
71 
72 /*
73 void
74 REveDataProxyBuilderBase::SetInteractionList(REveDataInteractionList* l, const std::string& purpose )
75 {
76  // Called if willHandleInteraction() returns false. Purpose ignored by default.
77 
78  m_interactionList = l;
79 }
80 */
81 
82 //------------------------------------------------------------------------------
83 
84 void REveDataProxyBuilderBase::Build()
85 {
86  if (m_collection)
87  {
88  // printf("Base %p %s %s\n", m_collection, m_collection->GetCName(), m_type.c_str());
89  try
90  {
91  auto itemSize = m_collection->GetNItems(); //cashed
92 
93  Clean();
94  for (auto &pp: m_products)
95  {
96  // printf("build() %s \n", m_collection->GetCName());
97  REveElement* elms = pp->m_elements;
98  auto oldSize = elms->NumChildren();
99 
100  if (HaveSingleProduct())
101  {
102  Build(m_collection, elms, pp->m_viewContext);
103  }
104  else
105  {
106  BuildViewType(m_collection, elms, pp->m_viewType, pp->m_viewContext);
107  }
108 
109  // Project all children of current product.
110  // If product is not registered into any projection-manager,
111  // this does nothing.
112  REveProjectable* pable = dynamic_cast<REveProjectable*>(elms);
113  if (pable->HasProjecteds())
114  {
115  // loop projected holders
116  for (auto &prj: pable->RefProjecteds())
117  {
118  REveProjectionManager *pmgr = prj->GetManager();
119  Float_t oldDepth = pmgr->GetCurrentDepth();
120  pmgr->SetCurrentDepth(m_layer);
121  Int_t cnt = 0;
122 
123  REveElement *projectedAsElement = prj->GetProjectedAsElement();
124  auto parentIt = projectedAsElement->RefChildren().begin();
125  for (auto &prod: elms->RefChildren())
126  {
127  // reused projected holder
128  if (cnt < oldSize)
129  {
130  /*
131  // AMT no use case for this at the moment
132  if ((*parentIt)->NumChildren()) {
133  // update projected (mislleading name)
134  for ( REveElement::List_i pci = (*parentIt)->BeginChildren(); pci != (*parentIt)->EndChildren(); pci++)
135  pmgr->ProjectChildrenRecurse(*pci);
136  }
137  */
138  // import projectable
139  pmgr->SubImportChildren(prod, *parentIt);
140 
141  ++parentIt;
142  }
143  else if (cnt < itemSize)
144  {
145  // new product holder
146  pmgr->SubImportElements(prod, projectedAsElement);
147  }
148  else
149  {
150  break;
151  }
152  ++cnt;
153  }
154  pmgr->SetCurrentDepth(oldDepth);
155  }
156  }
157 
158  /*
159  if (m_interactionList && itemSize > oldSize)
160  {
161  auto elIt = elms->RefChildren().begin();
162  for (size_t cnt = 0; cnt < itemSize; ++cnt, ++elIt)
163  {
164  if (cnt >= oldSize )
165  m_interactionList->Added(*elIt, cnt);
166  }
167  }
168  */
169  }
170  }
171  catch (const std::runtime_error& iException)
172  {
173  std::cout << "Caught exception in build function for item " << m_collection->GetCName() << ":\n"
174  << iException.what() << std::endl;
175  exit(1);
176  }
177  }
178 }
179 
180 //------------------------------------------------------------------------------
181 
182 void
183 REveDataProxyBuilderBase::Build(const REveDataCollection*, REveElement*, const REveViewContext*)
184 {
185  assert("virtual Build(const REveEventItem*, REveElement*, const REveViewContext*) not implemented by inherited class");
186 }
187 
188 
189 void
190 REveDataProxyBuilderBase::BuildViewType(const REveDataCollection*, REveElement*, std::string, const REveViewContext*)
191 {
192  assert("virtual BuildViewType(const FWEventItem*, TEveElementList*, FWViewType::EType, const FWViewContext*) not implemented by inherited class");
193 }
194 
195 //------------------------------------------------------------------------------
196 
197 REveElement*
198 REveDataProxyBuilderBase::CreateProduct( std::string viewType, const REveViewContext* viewContext)
199 {
200  if ( m_products.empty() == false)
201  {
202  if (HaveSingleProduct()) {
203  return m_products.back()->m_elements;
204  }
205  else {
206 
207  for (auto &prod: m_products)
208  {
209  if (viewType == prod->m_viewType)
210  return prod->m_elements;
211  }
212  }
213  }
214 
215  auto product = new Product(viewType, viewContext);
216  m_products.push_back(product);
217 
218  if (m_collection)
219  {
220  // debug info in eve browser
221  product->m_elements->SetName(Form("product %s", m_collection->GetCName()));
222  }
223  return product->m_elements;
224 }
225 
226 //------------------------------------------------------------------------------
227 
228 namespace
229 {
230  void applyColorAttrToChildren(REveElement* p) {
231  for (auto &it: p->RefChildren())
232  {
233  REveElement* c = it;
234  if (c->GetMainColor() != p->GetMainColor())
235  {
236  c->SetMainColor(p->GetMainColor());
237  // printf("apply color %d to %s\n", p->GetMainColor(), c->GetCName());
238  }
239  applyColorAttrToChildren(c);
240  }
241  }
242 }
243 
244 void
245 REveDataProxyBuilderBase::ModelChanges(const REveDataCollection::Ids_t& iIds, Product* p)
246 {
247  printf("REveDataProxyBuilderBase::ModelChanges %s \n", m_collection->GetCName());
248  REveElement* elms = p->m_elements;
249  assert(m_collection && static_cast<int>(m_collection->GetNItems()) <= elms->NumChildren() && "can not use default modelChanges implementation");
250 
251  for (auto itemIdx: iIds)
252  {
253  REveDataItem *item = m_collection->GetDataItem(itemIdx);
254 
255  // printf("Edit compound for item index %d \n", itemIdx);
256  // imitate FWInteractionList::modelChanges
257  auto itElement = elms->RefChildren().begin();
258  std::advance(itElement, itemIdx);
259  REveElement* comp = *itElement;
260  bool visible = (!item->GetFiltered()) && item->GetRnrSelf();
261  comp->SetRnrSelf(visible);
262  comp->SetRnrChildren(visible);
263 
264  if (item->GetMainColor() != comp->GetMainColor()) comp->SetMainColor(item->GetMainColor());
265  applyColorAttrToChildren(comp);
266 
267  if (VisibilityModelChanges(itemIdx, comp, p->m_viewContext))
268  {
269  elms->ProjectChild(comp);
270  printf("---REveDataProxyBuilderBase project child\n");
271  }
272  else
273  {
274  LocalModelChanges(itemIdx, comp, p->m_viewContext);
275  }
276  }
277 }
278 
279 void
280 REveDataProxyBuilderBase::LocalModelChanges(int, REveElement*, const REveViewContext*)
281 {
282  // Nothing to be done in base class.
283  // Visibility, main color and main transparency are handled automatically throught compound.
284 }
285 
286 //------------------------------------------------------------------------------
287 
288 void
289 REveDataProxyBuilderBase::ModelChanges(const REveDataCollection::Ids_t& iIds)
290 {
291  if(m_haveWindow) {
292  for (auto &prod: m_products)
293  {
294  ModelChanges(iIds, prod);
295  }
296  m_modelsChanged = false;
297  } else {
298  m_modelsChanged = true;
299  }
300 }
301 
302 //______________________________________________________________________________
303 void
304 REveDataProxyBuilderBase::CollectionChanged(const REveDataCollection* /*iItem*/)
305 {
306  if(m_haveWindow) {
307  Build();
308  }
309 }
310 
311 //------------------------------------------------------------------------------
312 
313 void
314 REveDataProxyBuilderBase::SetupAddElement(REveElement* el, REveElement* parent, bool color) const
315 {
316  SetupElement(el, color);
317  // AMT -- this temprary to get right tooltip
318  el->SetName(parent->GetName());
319  parent->AddElement(el);
320 }
321 
322 /** This method is invoked to setup the per element properties of the various
323  objects being drawn.
324  */
325 void
326 REveDataProxyBuilderBase::SetupElement(REveElement* el, bool color) const
327 {
328  el->CSCTakeMotherAsMaster();
329  el->SetPickable(true);
330 
331  if (color)
332  {
333  el->CSCApplyMainColorToMatchingChildren();
334  el->CSCApplyMainTransparencyToMatchingChildren();
335  el->SetMainColor(m_collection->GetMainColor());
336  el->SetMainTransparency(m_collection->GetMainTransparency());
337  }
338 }
339 
340 
341 
342 REveCompound*
343 REveDataProxyBuilderBase::CreateCompound(bool set_color, bool propagate_color_to_all_children) const
344 {
345  REveCompound *c = new REveCompound();
346  c->CSCImplySelectAllChildren();
347  c->SetPickable(true);
348  if (set_color)
349  {
350  c->SetMainColor(m_collection->GetMainColor());
351  c->SetMainTransparency(m_collection->GetMainTransparency());
352  }
353  if (propagate_color_to_all_children)
354  {
355  c->CSCApplyMainColorToAllChildren();
356  c->CSCApplyMainTransparencyToAllChildren();
357  }
358  else
359  {
360  c->CSCApplyMainColorToMatchingChildren();
361  c->CSCApplyMainTransparencyToMatchingChildren();
362  }
363  return c;
364 }
365 
366 //------------------------------------------------------------------------------
367 
368 void REveDataProxyBuilderBase::Clean()
369 {
370  // Cleans local common element list.
371  for (auto &prod: m_products)
372  {
373  if (prod->m_elements)
374  prod->m_elements->DestroyElements();
375  }
376 
377  CleanLocal();
378 }
379 
380 void REveDataProxyBuilderBase::CleanLocal()
381 {
382  // Cleans local common element list.
383 }
384 
385 void REveDataProxyBuilderBase::CollectionBeingDestroyed(const REveDataCollection* /*iItem*/)
386 {
387  m_collection = nullptr;
388 
389  CleanLocal();
390 
391  for (auto &prod: m_products)
392  {
393 
394  // (*i)->m_scaleConnection.disconnect();
395  delete prod;
396  }
397 
398  m_products.clear();
399 }
400 
401 bool REveDataProxyBuilderBase::VisibilityModelChanges(int, REveElement *, const REveViewContext *)
402 {
403  return false;
404 }
405 
406 void REveDataProxyBuilderBase::SetHaveAWindow(bool iHaveAWindow)
407 {
408  m_haveWindow = iHaveAWindow;
409 }