Logo ROOT  
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>
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 "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
45using namespace ROOT::Experimental;
46namespace REX = ROOT::Experimental;
47
48REveManager *REX::gEve = nullptr;
49
50
51/** \class REveManager
52\ingroup REve
53Central application manager for Eve.
54Manages elements, GUI, GL scenes and GL viewers.
55
56Following parameters can be specified in .rootrc file
57
58WebEve.GLViewer: Three # kind of GLViewer, either Three, JSRoot or RCore
59WebEve.DisableShow: 1 # do not start new web browser when REveManager::Show is called
60WebEve.HTimeout: 200 # timeout in ms for elements highlight
61WebEve.DblClick: Off # mouse double click handling in GL viewer: Off or Reset
62WebEve.TableRowHeight: 33 # size of each row in pixels in the Table view, can be used to make design more compact
63*/
64
65////////////////////////////////////////////////////////////////////////////////
66
67REveManager::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.
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
205REveViewer* 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
215REveScene* REveManager::SpawnNewScene(const char* name, const char* title)
216{
217 REveScene* s = new REveScene(name, title);
219 return s;
220}
221
222////////////////////////////////////////////////////////////////////////////////
223/// Find macro in fMacroFolder by name.
224
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
267void 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
343next_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));
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);
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
489void 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
507void REveManager::LoadVizDB(const TString& filename)
508{
509 REveUtil::Macro(filename);
510 Redraw3D();
511}
512
513////////////////////////////////////////////////////////////////////////////////
514/// Save visualization-parameter database to file filename.
515
516void 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
646void 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//
668void 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//
677void 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
688void 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
723Exception 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
746void 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
791void 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
822void 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
882void REveManager::Send(unsigned connid, const std::string &data)
883{
884 fWebWindow->Send(connid, data);
885}
886
887
888void 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
975std::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}
ROOT::R::TRInterface & r
Definition: Object.C:4
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
#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
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:90
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
const Bool_t kTRUE
Definition: RtypesCore.h:89
@ kRed
Definition: Rtypes.h:64
@ kGreen
Definition: Rtypes.h:64
@ kCyan
Definition: Rtypes.h:64
@ kViolet
Definition: Rtypes.h:65
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
void Warning(const char *location, const char *msgfmt,...)
R__EXTERN TEveManager * gEve
Definition: TEveManager.h:243
XFontStruct * id
Definition: TGX11.cxx:108
char name[80]
Definition: TGX11.cxx:109
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:600
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
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
Definition: REveManager.hxx:88
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.
std::vector< Conn > fConnList
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.
Definition: REveScene.cxx:471
void AcceptChanges(bool)
Set accept changes flag on all scenes.
Definition: REveScene.cxx:485
void AddSubscriber(std::unique_ptr< REveClient > &&sub)
Definition: REveScene.cxx:61
std::vector< char > fOutputBinary
!
Definition: REveScene.hxx:78
void RemoveSubscriber(unsigned int)
Definition: REveScene.cxx:72
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.
Definition: REveViewer.hxx:53
void AddElement(REveElement *el) override
Call base-class implementation.
Definition: REveViewer.cxx:133
REveViewer Reve representation of TGLViewer.
Definition: REveViewer.hxx:28
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:53
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:310
An identity transformation.
Definition: TGeoMatrix.h:384
The manager class for any TGeo geometry.
Definition: TGeoManager.h:43
static void UnlockGeometry()
Unlock current geometry.
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:491
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:488
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
Definition: TGeoManager.h:530
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:47
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:865
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:131
const char * Data() const
Definition: TString.h:364
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
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:322
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1269
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
static constexpr double s
basic_json<> json
default JSON class
Definition: REveElement.hxx:88