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