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
22#include "TGeoManager.h"
23#include "TObjString.h"
24#include "TROOT.h"
25#include "TFile.h"
26#include "TMap.h"
27#include "TExMap.h"
28#include "TMacro.h"
29#include "TFolder.h"
30#include "TSystem.h"
31#include "TRint.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
49
50
51
52
53/** \class REveManager
54\ingroup REve
55Central application manager for Eve.
56Manages elements, GUI, GL scenes and GL viewers.
57*/
58
59////////////////////////////////////////////////////////////////////////////////
60
61REveManager::REveManager() : // (Bool_t map_window, Option_t* opt) :
62 fExcHandler (nullptr),
63 fVizDB (nullptr),
64 fVizDBReplace(kTRUE),
65 fVizDBUpdate(kTRUE),
66 fGeometries (nullptr),
67 fGeometryAliases (nullptr),
68
69 fMacroFolder (nullptr),
70
71 fRedrawDisabled (0),
72 fResetCameras (kFALSE),
73 fDropLogicals (kFALSE),
74 fKeepEmptyCont (kFALSE),
75 fTimerActive (kFALSE),
76 fRedrawTimer ()
77{
78 // Constructor.
79
80 static const REveException eh("REveManager::REveManager ");
81
82 if (REX::gEve)
83 throw eh + "There can be only one REve!";
84
85 REX::gEve = this;
86
88
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 // this is call-back, invoked when message received via websocket
144 fWebWindow->SetCallBacks([this](unsigned connid) { WindowConnect(connid); },
145 [this](unsigned connid, const std::string &arg) { WindowData(connid, arg); },
146 [this](unsigned connid) { WindowDisconnect(connid); });
147 fWebWindow->SetGeometry(900, 700); // configure predefined window geometry
148 fWebWindow->SetConnLimit(100); // maximal number of connections
149 fWebWindow->SetMaxQueueLength(30); // number of allowed entries in the window queue
150}
151
152////////////////////////////////////////////////////////////////////////////////
153/// Destructor.
154
156{
157 // Stop timer and deny further redraw requests.
160
165 // Not needed - no more top-items: fScenes->Destroy();
166 fScenes = nullptr;
167
170 // Not needed - no more top-items: fViewers->Destroy();
171 fViewers = nullptr;
172
173 // fWindowManager->DestroyWindows();
174 // fWindowManager->DecDenyDestroy();
175 // fWindowManager->Destroy();
176 // fWindowManager = 0;
177
180
181 gROOT->GetListOfBrowsables()->Remove(fMacroFolder);
182 delete fMacroFolder;
183
184 delete fGeometryAliases;
185 delete fGeometries;
186 delete fVizDB;
187 delete fExcHandler;
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Create a new GL viewer.
192
193REveViewer* REveManager::SpawnNewViewer(const char* name, const char* title)
194{
195 REveViewer* v = new REveViewer(name, title);
197 return v;
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// Create a new scene.
202
203REveScene* REveManager::SpawnNewScene(const char* name, const char* title)
204{
205 REveScene* s = new REveScene(name, title);
207 return s;
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Find macro in fMacroFolder by name.
212
214{
215 return dynamic_cast<TMacro*>(fMacroFolder->FindObject(name));
216}
217
218////////////////////////////////////////////////////////////////////////////////
219/// Register a request for 3D redraw.
220
222{
225}
226
227////////////////////////////////////////////////////////////////////////////////
228/// Perform 3D redraw of scenes and viewers whose contents has
229/// changed.
230
232{
233 static const REveException eh("REveManager::DoRedraw3D ");
234 nlohmann::json jobj = {};
235
236 jobj["content"] = "BeginChanges";
237 fWebWindow->Send(0, jobj.dump());
238
239 // Process changes in scenes.
242
243 jobj["content"] = "EndChanges";
244 fWebWindow->Send(0, jobj.dump());
245
248
250}
251
252////////////////////////////////////////////////////////////////////////////////
253/// Perform 3D redraw of all scenes and viewers.
254
255void REveManager::FullRedraw3D(Bool_t /*resetCameras*/, Bool_t /*dropLogicals*/)
256{
257 // XXXX fScenes ->RepaintAllScenes (dropLogicals);
258 // XXXX fViewers->RepaintAllViewers(resetCameras, dropLogicals);
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Clear all selection objects. Can make things easier for EVE when going to
263/// the next event. Still, destruction os selected object should still work
264/// correctly as long as it is executed within a change cycle.
265
267{
268 for (auto el : fSelectionList->fChildren)
269 {
270 dynamic_cast<REveSelection*>(el)->ClearSelection();
271 }
272}
273
274////////////////////////////////////////////////////////////////////////////////
275/// Add an element. If parent is not specified it is added into
276/// current event (which is created if does not exist).
277
279{
280 if (parent == nullptr) {
281 // XXXX
282 }
283
284 parent->AddElement(element);
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Add a global element, i.e. one that does not change on each
289/// event, like geometry or projection manager.
290/// If parent is not specified it is added to a global scene.
291
293{
294 if (!parent)
295 parent = fGlobalScene;
296
297 parent->AddElement(element);
298}
299
300////////////////////////////////////////////////////////////////////////////////
301/// Remove element from parent.
302
304 REveElement* parent)
305{
306 parent->RemoveElement(element);
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// Lookup ElementId in element map and return corresponding REveElement*.
311/// Returns nullptr if the id is not found
312
314{
315 static const REveException eh("REveManager::FindElementById ");
316
317 auto it = fElementIdMap.find(id);
318 return (it != fElementIdMap.end()) ? it->second : nullptr;
319}
320
321////////////////////////////////////////////////////////////////////////////////
322/// Assign a unique ElementId to given element.
323
325{
326 static const REveException eh("REveManager::AssignElementId ");
327
329 throw eh + "ElementId map is full.";
330
331next_free_id:
332 while (fElementIdMap.find(++fLastElementId) != fElementIdMap.end());
333 if (fLastElementId == 0) goto next_free_id;
334 // MT - alternatively, we could spawn a thread to find next thousand or so ids and
335 // put them in a vector of ranges. Or collect them when they are freed.
336 // Don't think this won't happen ... online event display can run for months
337 // and easily produce 100000 objects per minute -- about a month to use up all id space!
338
339 element->fElementId = fLastElementId;
340 fElementIdMap.insert(std::make_pair(fLastElementId, element));
342}
343
344////////////////////////////////////////////////////////////////////////////////
345/// Called from REveElement prior to its destruction so the
346/// framework components (like object editor) can unreference it.
347
349{
350 if (el->fImpliedSelected > 0)
351 {
352 for (auto slc : fSelectionList->fChildren)
353 {
354 REveSelection *sel = dynamic_cast<REveSelection*>(slc);
356 }
357
358 if (el->fImpliedSelected != 0)
359 Error("REveManager::PreDeleteElement", "ImpliedSelected not zero (%d) after cleanup of selections.", el->fImpliedSelected);
360 }
361 // Primary selection deregistration is handled through Niece removal from Aunts.
362
363 if (el->fElementId != 0)
364 {
365 auto it = fElementIdMap.find(el->fElementId);
366 if (it != fElementIdMap.end())
367 {
368 if (it->second == el)
369 {
370 fElementIdMap.erase(it);
372 }
373 else Error("PreDeleteElement", "element ptr in ElementIdMap does not match the argument element.");
374 }
375 else Error("PreDeleteElement", "element id %u was not registered in ElementIdMap.", el->fElementId);
376 }
377 else Error("PreDeleteElement", "element with 0 ElementId passed in.");
378}
379
380////////////////////////////////////////////////////////////////////////////////
381/// Insert a new visualization-parameter database entry. Returns
382/// true if the element is inserted successfully.
383/// If entry with the same key already exists the behaviour depends on the
384/// 'replace' flag:
385/// - true - The old model is deleted and new one is inserted (default).
386/// Clients of the old model are transferred to the new one and
387/// if 'update' flag is true (default), the new model's parameters
388/// are assigned to all clients.
389/// - false - The old model is kept, false is returned.
390///
391/// If insert is successful, the ownership of the model-element is
392/// transferred to the manager.
393
395 Bool_t replace, Bool_t update)
396{
397 TPair* pair = (TPair*) fVizDB->FindObject(tag);
398 if (pair)
399 {
400 if (replace)
401 {
402 model->IncDenyDestroy();
403 model->SetRnrChildren(kFALSE);
404
405 REveElement* old_model = dynamic_cast<REveElement*>(pair->Value());
406 if (old_model)
407 {
408 while (old_model->HasChildren())
409 {
410 REveElement *el = old_model->FirstChild();
411 el->SetVizModel(model);
412 if (update)
413 {
414 el->CopyVizParams(model);
416 }
417 }
418 old_model->DecDenyDestroy();
419 }
420 pair->SetValue(dynamic_cast<TObject*>(model));
421 return kTRUE;
422 }
423 else
424 {
425 return kFALSE;
426 }
427 }
428 else
429 {
430 model->IncDenyDestroy();
431 model->SetRnrChildren(kFALSE);
432 fVizDB->Add(new TObjString(tag), dynamic_cast<TObject*>(model));
433 return kTRUE;
434 }
435}
436
437////////////////////////////////////////////////////////////////////////////////
438/// Insert a new visualization-parameter database entry with the default
439/// parameters for replace and update, as specified by members
440/// fVizDBReplace(default=kTRUE) and fVizDBUpdate(default=kTRUE).
441/// See docs of the above function.
442
444{
445 return InsertVizDBEntry(tag, model, fVizDBReplace, fVizDBUpdate);
446}
447
448////////////////////////////////////////////////////////////////////////////////
449/// Find a visualization-parameter database entry corresponding to tag.
450/// If the entry is not found 0 is returned.
451
453{
454 return dynamic_cast<REveElement*>(fVizDB->GetValue(tag));
455}
456
457////////////////////////////////////////////////////////////////////////////////
458/// Load visualization-parameter database from file filename. The
459/// replace, update arguments replace the values of fVizDBReplace
460/// and fVizDBUpdate members for the duration of the macro
461/// execution.
462
463void REveManager::LoadVizDB(const TString& filename, Bool_t replace, Bool_t update)
464{
465 Bool_t ex_replace = fVizDBReplace;
466 Bool_t ex_update = fVizDBUpdate;
467 fVizDBReplace = replace;
469
470 LoadVizDB(filename);
471
472 fVizDBReplace = ex_replace;
473 fVizDBUpdate = ex_update;
474}
475
476////////////////////////////////////////////////////////////////////////////////
477/// Load visualization-parameter database from file filename.
478/// State of data-members fVizDBReplace and fVizDBUpdate determine
479/// how the registered entries are handled.
480
481void REveManager::LoadVizDB(const TString& filename)
482{
483 REveUtil::Macro(filename);
484 Redraw3D();
485}
486
487////////////////////////////////////////////////////////////////////////////////
488/// Save visualization-parameter database to file filename.
489
490void REveManager::SaveVizDB(const TString& filename)
491{
492 TPMERegexp re("(.+)\\.\\w+");
493 if (re.Match(filename) != 2) {
494 Error("SaveVizDB", "filename does not match required format '(.+)\\.\\w+'.");
495 return;
496 }
497
498 TString exp_filename(filename);
499 gSystem->ExpandPathName(exp_filename);
500
501 std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
502 out << "void " << re[1] << "()\n";
503 out << "{\n";
504 out << " REveManager::Create();\n";
505
507
508 Int_t var_id = 0;
509 TString var_name;
510 TIter next(fVizDB);
511 TObjString *key;
512 while ((key = (TObjString*)next()))
513 {
514 REveElement* mdl = dynamic_cast<REveElement*>(fVizDB->GetValue(key));
515 if (mdl)
516 {
517 var_name.Form("x%03d", var_id++);
518 mdl->SaveVizParams(out, key->String(), var_name);
519 }
520 else
521 {
522 Warning("SaveVizDB", "Saving failed for key '%s'.", key->String().Data());
523 }
524 }
525
526 out << "}\n";
527 out.close();
528}
529
530////////////////////////////////////////////////////////////////////////////////
531/// Get geometry with given filename.
532/// This is cached internally so the second time this function is
533/// called with the same argument the same geo-manager is returned.
534/// gGeoManager is set to the return value.
535
537{
538 static const REveException eh("REveManager::GetGeometry ");
539
540 TString exp_filename = filename;
541 gSystem->ExpandPathName(exp_filename);
542 printf("REveManager::GetGeometry loading: '%s' -> '%s'.\n",
543 filename.Data(), exp_filename.Data());
544
546 if (gGeoManager)
547 {
549 }
550 else
551 {
552 Bool_t locked = TGeoManager::IsLocked();
553 if (locked) {
554 Warning("REveManager::GetGeometry", "TGeoManager is locked ... unlocking it.");
556 }
557 if (TGeoManager::Import(filename) == 0) {
558 throw eh + "TGeoManager::Import() failed for '" + exp_filename + "'.";
559 }
560 if (locked) {
562 }
563
565
566 // Import colors exported by Gled, if they exist.
567 {
568 TFile f(exp_filename, "READ");
569 TObjArray* collist = (TObjArray*) f.Get("ColorList");
570 f.Close();
571 if (collist) {
573 TGeoVolume* vol;
574 while ((vol = (TGeoVolume*) next()) != nullptr)
575 {
576 Int_t oldID = vol->GetLineColor();
577 TColor* col = (TColor*)collist->At(oldID);
578 Float_t r, g, b;
579 col->GetRGB(r, g, b);
580 Int_t newID = TColor::GetColor(r,g,b);
581 vol->SetLineColor(newID);
582 }
583 }
584 }
585
586 fGeometries->Add(new TObjString(filename), gGeoManager);
587 }
588 return gGeoManager;
589}
590
591////////////////////////////////////////////////////////////////////////////////
592/// Get geometry with given alias.
593/// The alias must be registered via RegisterGeometryAlias().
594
596{
597 static const REveException eh("REveManager::GetGeometry ");
598
599 TObjString* full_name = (TObjString*) fGeometryAliases->GetValue(alias);
600 if (!full_name)
601 throw eh + "geometry alias '" + alias + "' not registered.";
602 return GetGeometry(full_name->String());
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Get the default geometry.
607/// It should be registered via RegisterGeometryName("Default", <URL>).
608
610{
611 return GetGeometryByAlias("Default");
612}
613
614////////////////////////////////////////////////////////////////////////////////
615/// Register 'name' as an alias for geometry file 'filename'.
616/// The old aliases are silently overwritten.
617/// After that the geometry can be retrieved also by calling:
618/// REX::gEve->GetGeometryByName(name);
619
620void REveManager::RegisterGeometryAlias(const TString& alias, const TString& filename)
621{
622 fGeometryAliases->Add(new TObjString(alias), new TObjString(filename));
623}
624
625////////////////////////////////////////////////////////////////////////////////
626/// Work-around uber ugly hack used in SavePrimitive and co.
627
629{
630 TIter nextcl(gROOT->GetListOfClasses());
631 TClass *cls;
632 while((cls = (TClass *)nextcl()))
633 {
635 }
636}
637
638////////////////////////////////////////////////////////////////////////////////
639/// Register new directory to THttpServer
640// For example: AddLocation("mydir/", "/test/EveWebApp/ui5");
641//
642void REveManager::AddLocation(const std::string& locationName, const std::string& path)
643{
644 fWebWindow->GetServer()->AddLocation(locationName.c_str(), path.c_str());
645}
646
647////////////////////////////////////////////////////////////////////////////////
648/// Set content of default window HTML page
649// Got example: SetDefaultHtmlPage("file:currentdir/test.html")
650//
651void REveManager::SetDefaultHtmlPage(const std::string& path)
652{
653 fWebWindow->SetDefaultPage(path.c_str());
654}
655
656
657////////////////////////////////////////////////////////////////////////////////
658/// Set client version, used as prefix in scripts URL
659/// When changed, web browser will reload all related JS files while full URL will be different
660/// Default is empty value - no extra string in URL
661/// Version should be string like "1.2" or "ver1.subv2" and not contain any special symbols
662void REveManager::SetClientVersion(const std::string& version)
663{
664 fWebWindow->SetClientVersion(version);
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// If global REveManager* REX::gEve is not set initialize it.
669/// Returns REX::gEve.
670
672{
673 static const REveException eh("REveManager::Create ");
674
675 if (!REX::gEve)
676 {
677 // XXXX Initialize some server stuff ???
678
679 REX::gEve = new REveManager();
680 }
681 return REX::gEve;
682}
683
684////////////////////////////////////////////////////////////////////////////////
685/// Properly terminate global REveManager.
686
688{
689 if (!REX::gEve) return;
690
691 delete REX::gEve;
692 REX::gEve = nullptr;
693}
694
695/** \class REveManager::RExceptionHandler
696\ingroup REve
697Exception handler for Eve exceptions.
698*/
699
700
701////////////////////////////////////////////////////////////////////////////////
702/// Handle exceptions deriving from REveException.
703
706{
707 REveException *ex = dynamic_cast<REveException *>(&exc);
708 if (ex) {
709 Info("Handle", "Exception %s", ex->what());
710 // REX::gEve->SetStatusLine(ex->Data());
711 gSystem->Beep();
712 return kSEHandled;
713 }
714 return kSEProceed;
715}
716
717////////////////////////////////////////////////////////////////////////////////
718/// Process new connection from web window
719
720void REveManager::WindowConnect(unsigned connid)
721{
722 fConnList.emplace_back(connid);
723 printf("connection established %u\n", connid);
724
725 // This prepares core and render data buffers.
726 printf("\nEVEMNG ............. streaming the world scene.\n");
727
728 fWorld->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
730
731 printf(" sending json, len = %d\n", (int) fWorld->fOutputJson.size());
732 Send(connid, fWorld->fOutputJson);
733 printf(" for now assume world-scene has no render data, binary-size=%d\n", fWorld->fTotalBinarySize);
734 assert(fWorld->fTotalBinarySize == 0);
735
736 for (auto &c: fScenes->RefChildren())
737 {
738 REveScene* scene = dynamic_cast<REveScene *>(c);
739
740 scene->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
741 printf("\nEVEMNG ............. streaming scene %s [%s]\n",
742 scene->GetCTitle(), scene->GetCName());
743
744 // This prepares core and render data buffers.
745 scene->StreamElements();
746
747 printf(" sending json, len = %d\n", (int) scene->fOutputJson.size());
748 Send(connid, scene->fOutputJson);
749
750 if (scene->fTotalBinarySize > 0)
751 {
752 printf(" sending binary, len = %d\n", scene->fTotalBinarySize);
753 SendBinary(connid, &scene->fOutputBinary[0], scene->fTotalBinarySize);
754 }
755 else
756 {
757 printf(" NOT sending binary, len = %d\n", scene->fTotalBinarySize);
758 }
759 }
760}
761
762////////////////////////////////////////////////////////////////////////////////
763/// Process disconnect of web window
764
765void REveManager::WindowDisconnect(unsigned connid)
766{
767 auto conn = fConnList.end();
768 for (auto i = fConnList.begin(); i != fConnList.end(); ++i)
769 {
770 if (i->fId == connid)
771 {
772 conn = i;
773 break;
774 }
775 }
776 // this should not happen, just check
777 if (conn == fConnList.end()) {
778 printf("error, connection not found!");
779 } else {
780 printf("connection closed %u\n", connid);
781 fConnList.erase(conn);
782 for (auto &c: fScenes->RefChildren())
783 {
784 REveScene* scene = dynamic_cast<REveScene *>(c);
785 scene->RemoveSubscriber(connid);
786 }
787 fWorld->RemoveSubscriber(connid);
788
789 }
790
791}
792
793////////////////////////////////////////////////////////////////////////////////
794/// Process data from web window
795
796void REveManager::WindowData(unsigned connid, const std::string &arg)
797{
798 static const REveException eh("REveManager::WindowData ");
799
800 // find connection object
801 auto conn = fConnList.end();
802 for (auto i = fConnList.begin(); i != fConnList.end(); ++i)
803 {
804 if (i->fId == connid)
805 {
806 conn = i;
807 break;
808 }
809 }
810 // this should not happen, just check
811 if (conn == fConnList.end()) {
812 printf("error, connection not found!");
813 return;
814 }
815
817 fScenes->AcceptChanges(true);
818
819 // MIR
820 nlohmann::json cj = nlohmann::json::parse(arg);
821 if (gDebug > 0)
822 ::Info("REveManager::WindowData", "MIR test %s", cj.dump().c_str());
823 std::string mir = cj["mir"];
824 std::string ctype = cj["class"];
825 int id = cj["fElementId"];
826
827 auto el = FindElementById(id);
828 std::stringstream cmd;
829 cmd << "((" << ctype << "*)" << std::hex << std::showbase << (size_t)el << ")->" << mir << ";";
830 if (gDebug > 0)
831 ::Info("REveManager::WindowData", "MIR cmd %s", cmd.str().c_str());
832 gROOT->ProcessLine(cmd.str().c_str());
833
834 fScenes->AcceptChanges(false);
836
837 Redraw3D();
838
839 /*
840 nlohmann::json resp;
841 resp["function"] = "replaceElement";
842 //el->SetCoreJson(resp);
843 for (auto &conn : fConnList)
844 fWebWindow->Send(conn.fId, resp.dump());
845 */
846}
847
848void REveManager::Send(unsigned connid, const std::string &data)
849{
850 fWebWindow->Send(connid, data);
851}
852
853
854void REveManager::SendBinary(unsigned connid, const void *data, std::size_t len)
855{
856 fWebWindow->SendBinary(connid, data, len);
857}
858
859//------------------------------------------------------------------------------
860
862{
863 // XXXXX - not called, what's with end accepting changes?
864
866 fScenes->AcceptChanges(false);
867
868 nlohmann::json jarr = nlohmann::json::array();
869
870 nlohmann::json jhdr = {};
871 jhdr["content"] = "REveManager::DestroyElementsOf";
872
873 nlohmann::json jels = nlohmann::json::array();
874
875 for (auto &ep : els) {
876 jels.push_back(ep->GetElementId());
877
878 ep->DestroyElements();
879 }
880
881 jhdr["element_ids"] = jels;
882
883 jarr.push_back(jhdr);
884
885 std::string msg = jarr.dump();
886
887 // XXXX Do we have broadcast?
888
889 for (auto &conn : fConnList) {
890 fWebWindow->Send(conn.fId, msg);
891 }
892}
893
895{
896 // XXXXX - not called, what's with begin accepting changes?
897
898 for (auto &ep : els)
899 {
900 REveScene* scene = dynamic_cast<REveScene*>(ep);
901 assert (scene != nullptr);
902
903 printf("\nEVEMNG ............. streaming scene %s [%s]\n",
904 scene->GetCTitle(), scene->GetCName());
905
906 // This prepares core and render data buffers.
907 scene->StreamElements();
908
909 for (auto &conn : fConnList) {
910 printf(" sending json, len = %d --> to conn_id = %d\n", (int)scene->fOutputJson.size(), conn.fId);
911 fWebWindow->Send(conn.fId, scene->fOutputJson);
912 printf(" sending binary, len = %d --> to conn_id = %d\n", scene->fTotalBinarySize, conn.fId);
913 fWebWindow->SendBinary(conn.fId, &scene->fOutputBinary[0], scene->fTotalBinarySize);
914 }
915 }
916
917 // AMT: These calls may not be necessary
918 fScenes->AcceptChanges(true);
920}
921
922//////////////////////////////////////////////////////////////////
923/// Show eve manager in specified browser.
924
925/// If rootrc variable WebEve.DisableShow is set, HTTP server will be
926/// started and access URL printed on stdout.
927
929{
930 if (gEnv->GetValue("WebEve.DisableShow", 0) != 0) {
931 std::string url = fWebWindow->GetUrl(true);
932 printf("EVE URL %s\n", url.c_str());
933 } else {
934 fWebWindow->Show(args);
935 }
936}
937
938//////////////////////////////////////////////////////////////////
939/// Show current geometry in web browser
940
941std::shared_ptr<REveGeomViewer> REveManager::ShowGeometry(const RWebDisplayArgs &args)
942{
943 if (!gGeoManager) {
944 Error("ShowGeometry", "No geometry is loaded");
945 return nullptr;
946 }
947
948 auto viewer = std::make_shared<REveGeomViewer>(gGeoManager);
949
950 viewer->Show(args);
951
952 return viewer;
953}
ROOT::R::TRInterface & r
Definition: Object.C:4
#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)
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
@ kRed
Definition: Rtypes.h:64
@ kGreen
Definition: Rtypes.h:64
@ kCyan
Definition: Rtypes.h:64
@ kViolet
Definition: Rtypes.h:65
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
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
char name[80]
Definition: TGX11.cxx:109
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:601
R__EXTERN TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.h:478
#define gROOT
Definition: TROOT.h:415
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
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
Definition: REveElement.hxx:77
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 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:134
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:75
@ kClassSaved
Definition: TClass.h:88
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:1764
static void SetColorThreshold(Float_t t)
This method specifies the color threshold used by GetColor to retrieve a color.
Definition: TColor.cxx:1831
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:48
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:492
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:489
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:531
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:53
virtual void SetOwnerKeyValue(Bool_t ownkeys=kTRUE, Bool_t ownvals=kTRUE)
Set ownership for keys and values.
Definition: TMap.cxx:351
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
TObject * FindObject(const char *keyname) const
Check if a (key,value) pair exists with keyname as name of the key.
Definition: TMap.cxx:214
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:171
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
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:867
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:334
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1265
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
unsigned int ElementId_t
Definition: REveTypes.hxx:25
static constexpr double s