Logo ROOT   master
Reference Guide
REveManager.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
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 #include <ROOT/REveManager.hxx>
13 
14 #include <ROOT/REveUtil.hxx>
15 #include <ROOT/REveSelection.hxx>
16 #include <ROOT/REveViewer.hxx>
17 #include <ROOT/REveScene.hxx>
18 #include <ROOT/REveClient.hxx>
19 #include <ROOT/REveGeomViewer.hxx>
20 #include <ROOT/RWebWindow.hxx>
21 #include <ROOT/RLogger.hxx>
22 
23 #include "TGeoManager.h"
24 #include "TObjString.h"
25 #include "TROOT.h"
26 #include "TFile.h"
27 #include "TMap.h"
28 #include "TExMap.h"
29 #include "TMacro.h"
30 #include "TFolder.h"
31 #include "TSystem.h"
32 #include "TEnv.h"
33 #include "TColor.h"
34 #include "TPluginManager.h"
35 #include "TPRegexp.h"
36 #include "TClass.h"
37 #include "THttpServer.h"
38 
39 #include "Riostream.h"
40 
41 #include "json.hpp"
42 #include <sstream>
43 #include <iostream>
44 
45 using namespace ROOT::Experimental;
46 namespace REX = ROOT::Experimental;
47 
48 REveManager *REX::gEve = nullptr;
49 
50 
51 /** \class REveManager
52 \ingroup REve
53 Central application manager for Eve.
54 Manages elements, GUI, GL scenes and GL viewers.
55 
56 Following parameters can be specified in .rootrc file
57 
58 WebEve.GLViewer: Three # kind of GLViewer, either Three, JSRoot or RCore
59 WebEve.DisableShow: 1 # do not start new web browser when REveManager::Show is called
60 WebEve.HTimeout: 200 # timeout in ms for elements highlight
61 WebEve.DblClick: Off # mouse double click handling in GL viewer: Off or Reset
62 WebEve.TableRowHeight: 33 # size of each row in pixels in the Table view, can be used to make design more compact
63 */
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 
67 REveManager::REveManager() : // (Bool_t map_window, Option_t* opt) :
68  fExcHandler (nullptr),
69  fVizDB (nullptr),
70  fVizDBReplace(kTRUE),
71  fVizDBUpdate(kTRUE),
72  fGeometries (nullptr),
73  fGeometryAliases (nullptr),
74 
75  fMacroFolder (nullptr),
76 
77  fRedrawDisabled (0),
78  fResetCameras (kFALSE),
79  fDropLogicals (kFALSE),
80  fKeepEmptyCont (kFALSE),
81  fTimerActive (kFALSE),
82  fRedrawTimer ()
83 {
84  // Constructor.
85 
86  static const REveException eh("REveManager::REveManager ");
87 
88  if (REX::gEve)
89  throw eh + "There can be only one REve!";
90 
91  REX::gEve = this;
92 
94 
98 
99  fElementIdMap[0] = nullptr; // do not increase count for null element.
100 
101  fRedrawTimer.Connect("Timeout()", "ROOT::Experimental::REveManager", this, "DoRedraw3D()");
102  fMacroFolder = new TFolder("EVE", "Visualization macros");
103  gROOT->GetListOfBrowsables()->Add(fMacroFolder);
104 
105  fWorld = new REveScene("EveWorld", "Top-level Eve Scene");
108 
109  fSelectionList = new REveElement("Selection List");
110  fSelectionList->SetChildClass(TClass::GetClass<REveSelection>());
113  fSelection = new REveSelection("Global Selection", "", kRed, kViolet);
116  fHighlight = new REveSelection("Global Highlight", "", kGreen, kCyan);
120 
121  fViewers = new REveViewerList("Viewers");
124 
125  fScenes = new REveSceneList ("Scenes");
128 
129  fGlobalScene = new REveScene("Geometry scene");
132 
133  fEventScene = new REveScene("Event scene");
136 
137  {
138  REveViewer *v = SpawnNewViewer("Default Viewer");
139  v->AddScene(fGlobalScene);
140  v->AddScene(fEventScene);
141  }
142 
143  // !!! AMT increase threshold to enable color pick on client
145 
147  fWebWindow->SetDefaultPage("file:rootui5sys/eve7/index.html");
148 
149  const char *gl_viewer = gEnv->GetValue("WebEve.GLViewer", "Three");
150  const char *gl_dblclick = gEnv->GetValue("WebEve.DblClick", "Off");
151  Int_t htimeout = gEnv->GetValue("WebEve.HTimeout", 250);
152  Int_t table_row_height = gEnv->GetValue("WebEve.TableRowHeight", 0);
153  fWebWindow->SetUserArgs(Form("{ GLViewer: \"%s\", DblClick: \"%s\", HTimeout: %d, TableRowHeight: %d }", gl_viewer, gl_dblclick, htimeout, table_row_height));
154 
155  // this is call-back, invoked when message received via websocket
156  fWebWindow->SetCallBacks([this](unsigned connid) { WindowConnect(connid); },
157  [this](unsigned connid, const std::string &arg) { WindowData(connid, arg); },
158  [this](unsigned connid) { WindowDisconnect(connid); });
159  fWebWindow->SetGeometry(900, 700); // configure predefined window geometry
160  fWebWindow->SetConnLimit(100); // maximal number of connections
161  fWebWindow->SetMaxQueueLength(30); // number of allowed entries in the window queue
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// Destructor.
166 
168 {
169  // Stop timer and deny further redraw requests.
170  fRedrawTimer.Stop();
172 
177  // Not needed - no more top-items: fScenes->Destroy();
178  fScenes = nullptr;
179 
182  // Not needed - no more top-items: fViewers->Destroy();
183  fViewers = nullptr;
184 
185  // fWindowManager->DestroyWindows();
186  // fWindowManager->DecDenyDestroy();
187  // fWindowManager->Destroy();
188  // fWindowManager = 0;
189 
192 
193  gROOT->GetListOfBrowsables()->Remove(fMacroFolder);
194  delete fMacroFolder;
195 
196  delete fGeometryAliases;
197  delete fGeometries;
198  delete fVizDB;
199  delete fExcHandler;
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Create a new GL viewer.
204 
205 REveViewer* REveManager::SpawnNewViewer(const char* name, const char* title)
206 {
207  REveViewer* v = new REveViewer(name, title);
209  return v;
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Create a new scene.
214 
215 REveScene* REveManager::SpawnNewScene(const char* name, const char* title)
216 {
217  REveScene* s = new REveScene(name, title);
218  AddElement(s, fScenes);
219  return s;
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Find macro in fMacroFolder by name.
224 
225 TMacro* REveManager::GetMacro(const char* name) const
226 {
227  return dynamic_cast<TMacro*>(fMacroFolder->FindObject(name));
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Register a request for 3D redraw.
232 
234 {
237 }
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 /// Perform 3D redraw of scenes and viewers whose contents has
241 /// changed.
242 
244 {
245  static const REveException eh("REveManager::DoRedraw3D ");
246  nlohmann::json jobj = {};
247 
248  jobj["content"] = "BeginChanges";
249  fWebWindow->Send(0, jobj.dump());
250 
251  // Process changes in scenes.
254 
255  jobj["content"] = "EndChanges";
256  fWebWindow->Send(0, jobj.dump());
257 
260 
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// Perform 3D redraw of all scenes and viewers.
266 
267 void REveManager::FullRedraw3D(Bool_t /*resetCameras*/, Bool_t /*dropLogicals*/)
268 {
269  // XXXX fScenes ->RepaintAllScenes (dropLogicals);
270  // XXXX fViewers->RepaintAllViewers(resetCameras, dropLogicals);
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Clear all selection objects. Can make things easier for EVE when going to
275 /// the next event. Still, destruction os selected object should still work
276 /// correctly as long as it is executed within a change cycle.
277 
279 {
280  for (auto el : fSelectionList->fChildren)
281  {
282  dynamic_cast<REveSelection*>(el)->ClearSelection();
283  }
284 }
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// Add an element. If parent is not specified it is added into
288 /// current event (which is created if does not exist).
289 
291 {
292  if (parent == nullptr) {
293  // XXXX
294  }
295 
296  parent->AddElement(element);
297 }
298 
299 ////////////////////////////////////////////////////////////////////////////////
300 /// Add a global element, i.e. one that does not change on each
301 /// event, like geometry or projection manager.
302 /// If parent is not specified it is added to a global scene.
303 
305 {
306  if (!parent)
307  parent = fGlobalScene;
308 
309  parent->AddElement(element);
310 }
311 
312 ////////////////////////////////////////////////////////////////////////////////
313 /// Remove element from parent.
314 
316  REveElement* parent)
317 {
318  parent->RemoveElement(element);
319 }
320 
321 ////////////////////////////////////////////////////////////////////////////////
322 /// Lookup ElementId in element map and return corresponding REveElement*.
323 /// Returns nullptr if the id is not found
324 
326 {
327  static const REveException eh("REveManager::FindElementById ");
328 
329  auto it = fElementIdMap.find(id);
330  return (it != fElementIdMap.end()) ? it->second : nullptr;
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// Assign a unique ElementId to given element.
335 
337 {
338  static const REveException eh("REveManager::AssignElementId ");
339 
341  throw eh + "ElementId map is full.";
342 
343 next_free_id:
344  while (fElementIdMap.find(++fLastElementId) != fElementIdMap.end());
345  if (fLastElementId == 0) goto next_free_id;
346  // MT - alternatively, we could spawn a thread to find next thousand or so ids and
347  // put them in a vector of ranges. Or collect them when they are freed.
348  // Don't think this won't happen ... online event display can run for months
349  // and easily produce 100000 objects per minute -- about a month to use up all id space!
350 
351  element->fElementId = fLastElementId;
352  fElementIdMap.insert(std::make_pair(fLastElementId, element));
353  ++fNumElementIds;
354 }
355 
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Activate EVE browser (summary view) for specified element id
359 
361 {
362  nlohmann::json msg = {};
363  msg["content"] = "BrowseElement";
364  msg["id"] = id;
365 
366  fWebWindow->Send(0, msg.dump());
367 }
368 
369 
370 ////////////////////////////////////////////////////////////////////////////////
371 /// Called from REveElement prior to its destruction so the
372 /// framework components (like object editor) can unreference it.
373 
375 {
376  if (el->fImpliedSelected > 0)
377  {
378  for (auto slc : fSelectionList->fChildren)
379  {
380  REveSelection *sel = dynamic_cast<REveSelection*>(slc);
382  }
383 
384  if (el->fImpliedSelected != 0)
385  Error("REveManager::PreDeleteElement", "ImpliedSelected not zero (%d) after cleanup of selections.", el->fImpliedSelected);
386  }
387  // Primary selection deregistration is handled through Niece removal from Aunts.
388 
389  if (el->fElementId != 0)
390  {
391  auto it = fElementIdMap.find(el->fElementId);
392  if (it != fElementIdMap.end())
393  {
394  if (it->second == el)
395  {
396  fElementIdMap.erase(it);
397  --fNumElementIds;
398  }
399  else Error("PreDeleteElement", "element ptr in ElementIdMap does not match the argument element.");
400  }
401  else Error("PreDeleteElement", "element id %u was not registered in ElementIdMap.", el->fElementId);
402  }
403  else Error("PreDeleteElement", "element with 0 ElementId passed in.");
404 }
405 
406 ////////////////////////////////////////////////////////////////////////////////
407 /// Insert a new visualization-parameter database entry. Returns
408 /// true if the element is inserted successfully.
409 /// If entry with the same key already exists the behaviour depends on the
410 /// 'replace' flag:
411 /// - true - The old model is deleted and new one is inserted (default).
412 /// Clients of the old model are transferred to the new one and
413 /// if 'update' flag is true (default), the new model's parameters
414 /// are assigned to all clients.
415 /// - false - The old model is kept, false is returned.
416 ///
417 /// If insert is successful, the ownership of the model-element is
418 /// transferred to the manager.
419 
421  Bool_t replace, Bool_t update)
422 {
423  TPair* pair = (TPair*) fVizDB->FindObject(tag);
424  if (pair)
425  {
426  if (replace)
427  {
428  model->IncDenyDestroy();
429  model->SetRnrChildren(kFALSE);
430 
431  REveElement* old_model = dynamic_cast<REveElement*>(pair->Value());
432  if (old_model)
433  {
434  while (old_model->HasChildren())
435  {
436  REveElement *el = old_model->FirstChild();
437  el->SetVizModel(model);
438  if (update)
439  {
440  el->CopyVizParams(model);
442  }
443  }
444  old_model->DecDenyDestroy();
445  }
446  pair->SetValue(dynamic_cast<TObject*>(model));
447  return kTRUE;
448  }
449  else
450  {
451  return kFALSE;
452  }
453  }
454  else
455  {
456  model->IncDenyDestroy();
457  model->SetRnrChildren(kFALSE);
458  fVizDB->Add(new TObjString(tag), dynamic_cast<TObject*>(model));
459  return kTRUE;
460  }
461 }
462 
463 ////////////////////////////////////////////////////////////////////////////////
464 /// Insert a new visualization-parameter database entry with the default
465 /// parameters for replace and update, as specified by members
466 /// fVizDBReplace(default=kTRUE) and fVizDBUpdate(default=kTRUE).
467 /// See docs of the above function.
468 
470 {
471  return InsertVizDBEntry(tag, model, fVizDBReplace, fVizDBUpdate);
472 }
473 
474 ////////////////////////////////////////////////////////////////////////////////
475 /// Find a visualization-parameter database entry corresponding to tag.
476 /// If the entry is not found 0 is returned.
477 
479 {
480  return dynamic_cast<REveElement*>(fVizDB->GetValue(tag));
481 }
482 
483 ////////////////////////////////////////////////////////////////////////////////
484 /// Load visualization-parameter database from file filename. The
485 /// replace, update arguments replace the values of fVizDBReplace
486 /// and fVizDBUpdate members for the duration of the macro
487 /// execution.
488 
489 void REveManager::LoadVizDB(const TString& filename, Bool_t replace, Bool_t update)
490 {
491  Bool_t ex_replace = fVizDBReplace;
492  Bool_t ex_update = fVizDBUpdate;
493  fVizDBReplace = replace;
495 
496  LoadVizDB(filename);
497 
498  fVizDBReplace = ex_replace;
499  fVizDBUpdate = ex_update;
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 /// Load visualization-parameter database from file filename.
504 /// State of data-members fVizDBReplace and fVizDBUpdate determine
505 /// how the registered entries are handled.
506 
507 void REveManager::LoadVizDB(const TString& filename)
508 {
509  REveUtil::Macro(filename);
510  Redraw3D();
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Save visualization-parameter database to file filename.
515 
516 void REveManager::SaveVizDB(const TString& filename)
517 {
518  TPMERegexp re("(.+)\\.\\w+");
519  if (re.Match(filename) != 2) {
520  Error("SaveVizDB", "filename does not match required format '(.+)\\.\\w+'.");
521  return;
522  }
523 
524  TString exp_filename(filename);
525  gSystem->ExpandPathName(exp_filename);
526 
527  std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
528  out << "void " << re[1] << "()\n";
529  out << "{\n";
530  out << " REveManager::Create();\n";
531 
533 
534  Int_t var_id = 0;
535  TString var_name;
536  TIter next(fVizDB);
537  TObjString *key;
538  while ((key = (TObjString*)next()))
539  {
540  REveElement* mdl = dynamic_cast<REveElement*>(fVizDB->GetValue(key));
541  if (mdl)
542  {
543  var_name.Form("x%03d", var_id++);
544  mdl->SaveVizParams(out, key->String(), var_name);
545  }
546  else
547  {
548  Warning("SaveVizDB", "Saving failed for key '%s'.", key->String().Data());
549  }
550  }
551 
552  out << "}\n";
553  out.close();
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 /// Get geometry with given filename.
558 /// This is cached internally so the second time this function is
559 /// called with the same argument the same geo-manager is returned.
560 /// gGeoManager is set to the return value.
561 
563 {
564  static const REveException eh("REveManager::GetGeometry ");
565 
566  TString exp_filename = filename;
567  gSystem->ExpandPathName(exp_filename);
568  printf("REveManager::GetGeometry loading: '%s' -> '%s'.\n",
569  filename.Data(), exp_filename.Data());
570 
572  if (gGeoManager)
573  {
575  }
576  else
577  {
578  Bool_t locked = TGeoManager::IsLocked();
579  if (locked) {
580  Warning("REveManager::GetGeometry", "TGeoManager is locked ... unlocking it.");
582  }
583  if (TGeoManager::Import(filename) == 0) {
584  throw eh + "TGeoManager::Import() failed for '" + exp_filename + "'.";
585  }
586  if (locked) {
588  }
589 
591 
592  // Import colors exported by Gled, if they exist.
593  {
594  TFile f(exp_filename, "READ");
595  TObjArray* collist = (TObjArray*) f.Get("ColorList");
596  f.Close();
597  if (collist) {
599  TGeoVolume* vol;
600  while ((vol = (TGeoVolume*) next()) != nullptr)
601  {
602  Int_t oldID = vol->GetLineColor();
603  TColor* col = (TColor*)collist->At(oldID);
604  Float_t r, g, b;
605  col->GetRGB(r, g, b);
606  Int_t newID = TColor::GetColor(r,g,b);
607  vol->SetLineColor(newID);
608  }
609  }
610  }
611 
612  fGeometries->Add(new TObjString(filename), gGeoManager);
613  }
614  return gGeoManager;
615 }
616 
617 ////////////////////////////////////////////////////////////////////////////////
618 /// Get geometry with given alias.
619 /// The alias must be registered via RegisterGeometryAlias().
620 
622 {
623  static const REveException eh("REveManager::GetGeometry ");
624 
625  TObjString* full_name = (TObjString*) fGeometryAliases->GetValue(alias);
626  if (!full_name)
627  throw eh + "geometry alias '" + alias + "' not registered.";
628  return GetGeometry(full_name->String());
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Get the default geometry.
633 /// It should be registered via RegisterGeometryName("Default", <URL>).
634 
636 {
637  return GetGeometryByAlias("Default");
638 }
639 
640 ////////////////////////////////////////////////////////////////////////////////
641 /// Register 'name' as an alias for geometry file 'filename'.
642 /// The old aliases are silently overwritten.
643 /// After that the geometry can be retrieved also by calling:
644 /// REX::gEve->GetGeometryByName(name);
645 
646 void REveManager::RegisterGeometryAlias(const TString& alias, const TString& filename)
647 {
648  fGeometryAliases->Add(new TObjString(alias), new TObjString(filename));
649 }
650 
651 ////////////////////////////////////////////////////////////////////////////////
652 /// Work-around uber ugly hack used in SavePrimitive and co.
653 
655 {
656  TIter nextcl(gROOT->GetListOfClasses());
657  TClass *cls;
658  while((cls = (TClass *)nextcl()))
659  {
661  }
662 }
663 
664 ////////////////////////////////////////////////////////////////////////////////
665 /// Register new directory to THttpServer
666 // For example: AddLocation("mydir/", "/test/EveWebApp/ui5");
667 //
668 void REveManager::AddLocation(const std::string& locationName, const std::string& path)
669 {
670  fWebWindow->GetServer()->AddLocation(locationName.c_str(), path.c_str());
671 }
672 
673 ////////////////////////////////////////////////////////////////////////////////
674 /// Set content of default window HTML page
675 // Got example: SetDefaultHtmlPage("file:currentdir/test.html")
676 //
677 void REveManager::SetDefaultHtmlPage(const std::string& path)
678 {
679  fWebWindow->SetDefaultPage(path.c_str());
680 }
681 
682 
683 ////////////////////////////////////////////////////////////////////////////////
684 /// Set client version, used as prefix in scripts URL
685 /// When changed, web browser will reload all related JS files while full URL will be different
686 /// Default is empty value - no extra string in URL
687 /// Version should be string like "1.2" or "ver1.subv2" and not contain any special symbols
688 void REveManager::SetClientVersion(const std::string& version)
689 {
690  fWebWindow->SetClientVersion(version);
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// If global REveManager* REX::gEve is not set initialize it.
695 /// Returns REX::gEve.
696 
698 {
699  static const REveException eh("REveManager::Create ");
700 
701  if (!REX::gEve)
702  {
703  // XXXX Initialize some server stuff ???
704 
705  REX::gEve = new REveManager();
706  }
707  return REX::gEve;
708 }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Properly terminate global REveManager.
712 
714 {
715  if (!REX::gEve) return;
716 
717  delete REX::gEve;
718  REX::gEve = nullptr;
719 }
720 
721 /** \class REveManager::RExceptionHandler
722 \ingroup REve
723 Exception handler for Eve exceptions.
724 */
725 
726 
727 ////////////////////////////////////////////////////////////////////////////////
728 /// Handle exceptions deriving from REveException.
729 
732 {
733  REveException *ex = dynamic_cast<REveException *>(&exc);
734  if (ex) {
735  Info("Handle", "Exception %s", ex->what());
736  // REX::gEve->SetStatusLine(ex->Data());
737  gSystem->Beep();
738  return kSEHandled;
739  }
740  return kSEProceed;
741 }
742 
743 ////////////////////////////////////////////////////////////////////////////////
744 /// Process new connection from web window
745 
746 void REveManager::WindowConnect(unsigned connid)
747 {
748  fConnList.emplace_back(connid);
749  printf("connection established %u\n", connid);
750 
751  // This prepares core and render data buffers.
752  printf("\nEVEMNG ............. streaming the world scene.\n");
753 
754  fWorld->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
756 
757  printf(" sending json, len = %d\n", (int) fWorld->fOutputJson.size());
758  Send(connid, fWorld->fOutputJson);
759  printf(" for now assume world-scene has no render data, binary-size=%d\n", fWorld->fTotalBinarySize);
760  assert(fWorld->fTotalBinarySize == 0);
761 
762  for (auto &c: fScenes->RefChildren())
763  {
764  REveScene* scene = dynamic_cast<REveScene *>(c);
765 
766  scene->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
767  printf("\nEVEMNG ............. streaming scene %s [%s]\n",
768  scene->GetCTitle(), scene->GetCName());
769 
770  // This prepares core and render data buffers.
771  scene->StreamElements();
772 
773  printf(" sending json, len = %d\n", (int) scene->fOutputJson.size());
774  Send(connid, scene->fOutputJson);
775 
776  if (scene->fTotalBinarySize > 0)
777  {
778  printf(" sending binary, len = %d\n", scene->fTotalBinarySize);
779  SendBinary(connid, &scene->fOutputBinary[0], scene->fTotalBinarySize);
780  }
781  else
782  {
783  printf(" NOT sending binary, len = %d\n", scene->fTotalBinarySize);
784  }
785  }
786 }
787 
788 ////////////////////////////////////////////////////////////////////////////////
789 /// Process disconnect of web window
790 
791 void REveManager::WindowDisconnect(unsigned connid)
792 {
793  auto conn = fConnList.end();
794  for (auto i = fConnList.begin(); i != fConnList.end(); ++i)
795  {
796  if (i->fId == connid)
797  {
798  conn = i;
799  break;
800  }
801  }
802  // this should not happen, just check
803  if (conn == fConnList.end()) {
804  printf("error, connection not found!");
805  } else {
806  printf("connection closed %u\n", connid);
807  fConnList.erase(conn);
808  for (auto &c: fScenes->RefChildren())
809  {
810  REveScene* scene = dynamic_cast<REveScene *>(c);
811  scene->RemoveSubscriber(connid);
812  }
813  fWorld->RemoveSubscriber(connid);
814 
815  }
816 
817 }
818 
819 ////////////////////////////////////////////////////////////////////////////////
820 /// Process data from web window
821 
822 void REveManager::WindowData(unsigned connid, const std::string &arg)
823 {
824  static const REveException eh("REveManager::WindowData ");
825 
826  // find connection object
827  bool found = false;
828  for (auto &conn : fConnList) {
829  if (conn.fId == connid) {
830  found = true;
831  break;
832  }
833  }
834  // this should not happen, just check
835  if (!found) {
836  R__ERROR_HERE("webeve") << "Internal error - no connection with id " << connid << " found";
837  return;
838  }
839 
840  nlohmann::json cj = nlohmann::json::parse(arg);
841  if (gDebug > 0)
842  ::Info("REveManager::WindowData", "MIR test %s", cj.dump().c_str());
843  std::string mir = cj["mir"];
844  int id = cj["fElementId"];
845 
846  // MIR
847  std::stringstream cmd;
848 
849  if (id == 0) {
850  cmd << "((ROOT::Experimental::REveManager *)" << std::hex << std::showbase << (size_t) this << ")->" << mir << ";";
851  } else {
852  auto el = FindElementById(id);
853  if (!el) {
854  R__ERROR_HERE("webeve") << "Element with id " << id << " not found";
855  return;
856  }
857  std::string ctype = cj["class"];
858  cmd << "((" << ctype << "*)" << std::hex << std::showbase << (size_t)el << ")->" << mir << ";";
859  }
860 
862  fScenes->AcceptChanges(true);
863 
864  if (gDebug > 0)
865  ::Info("REveManager::WindowData", "MIR cmd %s", cmd.str().c_str());
866  gROOT->ProcessLine(cmd.str().c_str());
867 
868  fScenes->AcceptChanges(false);
870 
871  Redraw3D();
872 
873  /*
874  nlohmann::json resp;
875  resp["function"] = "replaceElement";
876  //el->SetCoreJson(resp);
877  for (auto &conn : fConnList)
878  fWebWindow->Send(conn.fId, resp.dump());
879  */
880 }
881 
882 void REveManager::Send(unsigned connid, const std::string &data)
883 {
884  fWebWindow->Send(connid, data);
885 }
886 
887 
888 void REveManager::SendBinary(unsigned connid, const void *data, std::size_t len)
889 {
890  fWebWindow->SendBinary(connid, data, len);
891 }
892 
893 //------------------------------------------------------------------------------
894 
896 {
897  // XXXXX - not called, what's with end accepting changes?
898 
900  fScenes->AcceptChanges(false);
901 
902  nlohmann::json jarr = nlohmann::json::array();
903 
904  nlohmann::json jhdr = {};
905  jhdr["content"] = "REveManager::DestroyElementsOf";
906 
907  nlohmann::json jels = nlohmann::json::array();
908 
909  for (auto &ep : els) {
910  jels.push_back(ep->GetElementId());
911 
912  ep->DestroyElements();
913  }
914 
915  jhdr["element_ids"] = jels;
916 
917  jarr.push_back(jhdr);
918 
919  std::string msg = jarr.dump();
920 
921  // XXXX Do we have broadcast?
922 
923  for (auto &conn : fConnList) {
924  fWebWindow->Send(conn.fId, msg);
925  }
926 }
927 
929 {
930  // XXXXX - not called, what's with begin accepting changes?
931 
932  for (auto &ep : els)
933  {
934  REveScene* scene = dynamic_cast<REveScene*>(ep);
935  assert (scene != nullptr);
936 
937  printf("\nEVEMNG ............. streaming scene %s [%s]\n",
938  scene->GetCTitle(), scene->GetCName());
939 
940  // This prepares core and render data buffers.
941  scene->StreamElements();
942 
943  for (auto &conn : fConnList) {
944  printf(" sending json, len = %d --> to conn_id = %d\n", (int)scene->fOutputJson.size(), conn.fId);
945  fWebWindow->Send(conn.fId, scene->fOutputJson);
946  printf(" sending binary, len = %d --> to conn_id = %d\n", scene->fTotalBinarySize, conn.fId);
947  fWebWindow->SendBinary(conn.fId, &scene->fOutputBinary[0], scene->fTotalBinarySize);
948  }
949  }
950 
951  // AMT: These calls may not be necessary
952  fScenes->AcceptChanges(true);
954 }
955 
956 //////////////////////////////////////////////////////////////////
957 /// Show eve manager in specified browser.
958 
959 /// If rootrc variable WebEve.DisableShow is set, HTTP server will be
960 /// started and access URL printed on stdout.
961 
963 {
964  if (gEnv->GetValue("WebEve.DisableShow", 0) != 0) {
965  std::string url = fWebWindow->GetUrl(true);
966  printf("EVE URL %s\n", url.c_str());
967  } else {
968  fWebWindow->Show(args);
969  }
970 }
971 
972 //////////////////////////////////////////////////////////////////
973 /// Show current geometry in web browser
974 
975 std::shared_ptr<REveGeomViewer> REveManager::ShowGeometry(const RWebDisplayArgs &args)
976 {
977  if (!gGeoManager) {
978  Error("ShowGeometry", "No geometry is loaded");
979  return nullptr;
980  }
981 
982  auto viewer = std::make_shared<REveGeomViewer>(gGeoManager);
983 
984  viewer->Show(args);
985 
986  return viewer;
987 }
A TFolder object is a collection of objects and folders.
Definition: TFolder.h:30
An array of TObjects.
Definition: TObjArray.h:37
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:861
void WindowData(unsigned connid, const std::string &arg)
Process data from web window.
The manager class for any TGeo geometry.
Definition: TGeoManager.h:42
static void SetColorThreshold(Float_t t)
This method specifies the color threshold used by GetColor to retrieve a color.
Definition: TColor.cxx:1831
REveViewer Reve representation of TGLViewer.
Definition: REveViewer.hxx:27
std::shared_ptr< ROOT::Experimental::RWebWindow > fWebWindow
Collectable string class.
Definition: TObjString.h:28
static void Macro(const char *mac)
Execute macro &#39;mac&#39;. Do not reload the macro.
Definition: REveUtil.cxx:98
void SetHighlightMode()
Set to &#39;highlight&#39; mode.
Definition: Rtypes.h:64
virtual Bool_t SetRnrChildren(Bool_t rnr)
Set render state of this element&#39;s children, i.e.
#define g(i)
Definition: RSha256.hxx:105
Holds different arguments for starting browser with RWebDisplayHandle::Display() method.
An identity transformation.
Definition: TGeoMatrix.h:383
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:42
virtual void CopyVizParams(const REveElement *el)
Copy visualization parameters from element el.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:48
virtual EStatus Handle(std::exception &exc)
Handle exceptions deriving from REveException.
const char * GetCTitle() const
void RemoveElement(REveElement *element, REveElement *parent)
Remove element from parent.
void AddLocation(const std::string &name, const std::string &path)
Register new directory to THttpServer.
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:53
#define gROOT
Definition: TROOT.h:415
Class supporting a collection of lines with C++ code.
Definition: TMacro.h:31
void PreDeleteElement(REveElement *element)
Called from REveElement prior to its destruction so the framework components (like object editor) can...
Basic string class.
Definition: TString.h:131
REveElement * FirstChild() const
Returns the first child element or 0 if the list is empty.
#define f(i)
Definition: RSha256.hxx:104
void VisibleDaughters(Bool_t vis=kTRUE)
set visibility for daughters
std::unordered_map< ElementId_t, REveElement * > fElementIdMap
void RegisterRedraw3D()
Register a request for 3D redraw.
Definition: Rtypes.h:64
void Redraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
const char * GetCName() const
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:51
void SetClientVersion(const std::string &version)
Set client version, used as prefix in scripts URL When changed, web browser will reload all related J...
void LoadVizDB(const TString &filename, Bool_t replace, Bool_t update)
Load visualization-parameter database from file filename.
std::shared_ptr< REveGeomViewer > ShowGeometry(const RWebDisplayArgs &args="")
Show current geometry in web browser.
void FullRedraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
Perform 3D redraw of all scenes and viewers.
virtual ~REveManager()
Destructor.
void BroadcastElementsOf(REveElement::List_t &els)
void SendBinary(unsigned connid, const void *data, std::size_t len)
static Bool_t IsLocked()
Check lock state.
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:211
void Info(const char *location, const char *msgfmt,...)
void RegisterGeometryAlias(const TString &alias, const TString &filename)
Register &#39;name&#39; as an alias for geometry file &#39;filename&#39;.
static constexpr double s
XFontStruct * id
Definition: TGX11.cxx:108
virtual void AddElement(REveElement *el)
Add el to the list of children.
void DestroyScenes()
Destroy all scenes and their contents.
Definition: REveScene.cxx:471
TObject * Value() const
Definition: TMap.h:121
void Error(const char *location, const char *msgfmt,...)
REveElement * FindElementById(ElementId_t id) const
Lookup ElementId in element map and return corresponding REveElement*.
REveScene * SpawnNewScene(const char *name, const char *title="")
Create a new scene.
TGeoManager * GetGeometryByAlias(const TString &alias)
Get geometry with given alias.
TMacro * GetMacro(const char *name) const
Find macro in fMacroFolder by name.
void SetValue(TObject *val)
Definition: TMap.h:122
virtual void PropagateVizParamsToProjecteds()
Propagate visualization parameters to dependent elements.
int RemoveImpliedSelectedReferencesTo(REveElement *el)
Remove pointers to el from implied selected sets.
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot...
Definition: TQObject.cxx:867
std::list< REveElement * > List_t
Definition: REveElement.hxx:87
virtual void SetOwnerKeyValue(Bool_t ownkeys=kTRUE, Bool_t ownvals=kTRUE)
Set ownership for keys and values.
Definition: TMap.cxx:351
TGeoManager * GetGeometry(const TString &filename)
Get geometry with given filename.
ROOT::R::TRInterface & r
Definition: Object.C:4
static void LockGeometry()
Lock current geometry so that no other geometry can be imported.
R__EXTERN TSystem * gSystem
Definition: TSystem.h:557
void Show(const RWebDisplayArgs &args="")
Show eve manager in specified browser.
static REveManager * Create()
If global REveManager* REX::gEve is not set initialize it.
R__EXTERN TEveManager * gEve
Definition: TEveManager.h:243
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
void AssignElementId(REveElement *element)
Assign a unique ElementId to given element.
char * Form(const char *fmt,...)
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb"...
Definition: TColor.cxx:1764
void AddSubscriber(std::unique_ptr< REveClient > &&sub)
Definition: REveScene.cxx:61
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
RExceptionHandler * fExcHandler
exception handler
Definition: REveManager.hxx:88
void DestroyElementsOf(REveElement::List_t &els)
void Warning(const char *location, const char *msgfmt,...)
TString & String()
Definition: TObjString.h:48
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:488
void AddElement(REveElement *el) override
Call base-class implementation.
Definition: REveViewer.cxx:133
unsigned int ElementId_t
Definition: REveTypes.hxx:25
const Bool_t kFALSE
Definition: RtypesCore.h:88
void AcceptChanges(bool)
Set accept changes flag on all scenes.
Definition: REveScene.cxx:485
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
REveElement * FindVizDBEntry(const TString &tag)
Find a visualization-parameter database entry corresponding to tag.
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:600
void WindowConnect(unsigned connid)
Process new connection from web window.
void IncDenyDestroy()
Increases the deny-destroy count of the element.
void DecDenyDestroy()
Decreases the deny-destroy count of the element.
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
void Send(unsigned connid, const std::string &data)
REveViewerList List of Viewers providing common operations on REveViewer collections.
Definition: REveViewer.hxx:52
void AddElement(REveElement *element, REveElement *parent=nullptr)
Add an element.
static std::shared_ptr< RWebWindow > Create()
Create new RWebWindow Using default RWebWindowsManager.
void Beep(Int_t freq=-1, Int_t duration=-1, Bool_t setDefault=kFALSE)
Beep for duration milliseconds with a tone of frequency freq.
Definition: TSystem.cxx:318
The color creation and management class.
Definition: TColor.h:19
std::vector< Conn > fConnList
void ClearAllSelections()
Clear all selection objects.
Definition: Rtypes.h:64
virtual TObject * FindObject(const char *name) const
Search object identified by name in the tree of folders inside this folder.
Definition: TFolder.cxx:310
std::vector< char > fOutputBinary
!
Definition: REveScene.hxx:78
REveViewer * SpawnNewViewer(const char *name, const char *title="")
Create a new GL viewer.
static void Terminate()
Properly terminate global REveManager.
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex &#39;this&#39; was created with.
Definition: TPRegexp.cxx:708
TObject * FindObject(const char *keyname) const
Check if a (key,value) pair exists with keyname as name of the key.
Definition: TMap.cxx:214
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
virtual void RemoveElement(REveElement *el)
Remove el from the list of children.
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:97
void RemoveSubscriber(unsigned int)
Definition: REveScene.cxx:72
void ClearROOTClassSaved()
Work-around uber ugly hack used in SavePrimitive and co.
void BrowseElement(ElementId_t id)
Activate EVE browser (summary view) for specified element id.
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:491
basic_json<> json
Definition: REveElement.hxx:58
Bool_t InsertVizDBEntry(const TString &tag, REveElement *model, Bool_t replace, Bool_t update)
Insert a new visualization-parameter database entry.
Definition: Rtypes.h:65
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
virtual void DestroyElements()
Destroy all children of this element.
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
#define c(i)
Definition: RSha256.hxx:101
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
void DoRedraw3D()
Perform 3D redraw of scenes and viewers whose contents has changed.
virtual void Stop()
Definition: TTimer.h:93
void ResetBit(UInt_t f)
Definition: TObject.h:171
void WindowDisconnect(unsigned connid)
Process disconnect of web window.
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1265
REveSelection Container for selected and highlighted elements.
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:530
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
void SetVizModel(REveElement *model)
Set visualization-parameter model element.
static TGeoManager * Import(const char *filename, const char *name="", Option_t *option="")
static function Import a geometry from a gdml or ROOT file
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
const Bool_t kTRUE
Definition: RtypesCore.h:87
void SaveVizParams(std::ostream &out, const TString &tag, const TString &var)
Save visualization parameters for this element with given tag.
Double_t ex[n]
Definition: legend1.C:17
static void UnlockGeometry()
Unlock current geometry.
char name[80]
Definition: TGX11.cxx:109
REveException Exception-type thrown by Eve classes.
Definition: REveTypes.hxx:40
void SaveVizDB(const TString &filename)
Save visualization-parameter database to file filename.
TGeoManager * GetDefaultGeometry()
Get the default geometry.
const char * Data() const
Definition: TString.h:364
void SetDefaultHtmlPage(const std::string &path)
Set content of default window HTML page.
void AddGlobalElement(REveElement *element, REveElement *parent=nullptr)
Add a global element, i.e.