45 using namespace ROOT::Experimental;
46 namespace REX = ROOT::Experimental;
48 REveManager* REX::gEve = 0;
61 REveManager::REveManager() :
62 fExcHandler (nullptr),
66 fGeometries (nullptr),
67 fGeometryAliases (nullptr),
69 fMacroFolder (nullptr),
72 fResetCameras (kFALSE),
73 fDropLogicals (kFALSE),
74 fKeepEmptyCont (kFALSE),
75 fTimerActive (kFALSE),
80 static const REveException eh(
"REveManager::REveManager ");
83 throw eh +
"There can be only one REve!";
87 fExcHandler =
new RExceptionHandler;
89 fGeometries =
new TMap; fGeometries->SetOwnerKeyValue();
90 fGeometryAliases =
new TMap; fGeometryAliases->SetOwnerKeyValue();
91 fVizDB =
new TMap; fVizDB->SetOwnerKeyValue();
93 fElementIdMap[0] =
nullptr;
95 fRedrawTimer.Connect(
"Timeout()",
"ROOT::Experimental::REveManager",
this,
"DoRedraw3D()");
96 fMacroFolder =
new TFolder(
"EVE",
"Visualization macros");
97 gROOT->GetListOfBrowsables()->Add(fMacroFolder);
99 fWorld =
new REveScene(
"EveWorld",
"Top-level Eve Scene");
100 fWorld->IncDenyDestroy();
101 AssignElementId(fWorld);
103 fSelectionList =
new REveElement(
"Selection List");
104 fSelectionList->SetChildClass(TClass::GetClass<REveSelection>());
105 fSelectionList->IncDenyDestroy();
106 fWorld->AddElement(fSelectionList);
107 fSelection =
new REveSelection(
"Global Selection",
"", kRed, kViolet);
108 fSelection->IncDenyDestroy();
109 fSelectionList->AddElement(fSelection);
110 fHighlight =
new REveSelection(
"Global Highlight",
"", kGreen, kCyan);
111 fHighlight->SetHighlightMode();
112 fHighlight->IncDenyDestroy();
113 fSelectionList->AddElement(fHighlight);
115 fViewers =
new REveViewerList(
"Viewers");
116 fViewers->IncDenyDestroy();
117 fWorld->AddElement(fViewers);
119 fScenes =
new REveSceneList (
"Scenes");
120 fScenes->IncDenyDestroy();
121 fWorld->AddElement(fScenes);
123 fGlobalScene =
new REveScene(
"Geometry scene");
124 fGlobalScene->IncDenyDestroy();
125 fScenes->AddElement(fGlobalScene);
127 fEventScene =
new REveScene(
"Event scene");
128 fEventScene->IncDenyDestroy();
129 fScenes->AddElement(fEventScene);
132 REveViewer *v = SpawnNewViewer(
"Default Viewer");
133 v->AddScene(fGlobalScene);
134 v->AddScene(fEventScene);
138 TColor::SetColorThreshold(0.1);
140 fWebWindow = RWebWindow::Create();
141 fWebWindow->SetDefaultPage(
"file:rootui5sys/eve7/index.html");
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);
148 fWebWindow->SetConnLimit(100);
149 fWebWindow->SetMaxQueueLength(30);
155 REveManager::~REveManager()
159 fTimerActive = kTRUE;
161 fGlobalScene->DecDenyDestroy();
162 fEventScene->DecDenyDestroy();
163 fScenes->DestroyScenes();
164 fScenes->DecDenyDestroy();
168 fViewers->DestroyElements();
169 fViewers->DecDenyDestroy();
178 fHighlight->DecDenyDestroy();
179 fSelection->DecDenyDestroy();
181 gROOT->GetListOfBrowsables()->Remove(fMacroFolder);
184 delete fGeometryAliases;
193 REveViewer* REveManager::SpawnNewViewer(
const char* name,
const char* title)
195 REveViewer* v =
new REveViewer(name, title);
196 fViewers->AddElement(v);
203 REveScene* REveManager::SpawnNewScene(
const char* name,
const char* title)
205 REveScene* s =
new REveScene(name, title);
206 AddElement(s, fScenes);
213 TMacro* REveManager::GetMacro(
const char* name)
const
215 return dynamic_cast<TMacro*
>(fMacroFolder->FindObject(name));
221 void REveManager::RegisterRedraw3D()
223 fRedrawTimer.Start(0, kTRUE);
224 fTimerActive = kTRUE;
231 void REveManager::DoRedraw3D()
233 static const REveException eh(
"REveManager::DoRedraw3D ");
234 nlohmann::json jobj = {};
236 jobj[
"content"] =
"BeginChanges";
237 fWebWindow->Send(0, jobj.dump());
240 fWorld ->ProcessChanges();
241 fScenes->ProcessSceneChanges();
243 jobj[
"content"] =
"EndChanges";
244 fWebWindow->Send(0, jobj.dump());
246 fResetCameras = kFALSE;
247 fDropLogicals = kFALSE;
249 fTimerActive = kFALSE;
255 void REveManager::FullRedraw3D(Bool_t , Bool_t )
266 void REveManager::ClearAllSelections()
268 for (
auto el : fSelectionList->fChildren)
270 dynamic_cast<REveSelection*
>(el)->ClearSelection();
278 void REveManager::AddElement(REveElement *element, REveElement *parent)
280 if (parent ==
nullptr) {
284 parent->AddElement(element);
292 void REveManager::AddGlobalElement(REveElement* element, REveElement* parent)
295 parent = fGlobalScene;
297 parent->AddElement(element);
303 void REveManager::RemoveElement(REveElement* element,
306 parent->RemoveElement(element);
313 REveElement* REveManager::FindElementById(ElementId_t
id)
const
315 static const REveException eh(
"REveManager::FindElementById ");
317 auto it = fElementIdMap.find(
id);
318 return (it != fElementIdMap.end()) ? it->second :
nullptr;
324 void REveManager::AssignElementId(REveElement* element)
326 static const REveException eh(
"REveManager::AssignElementId ");
328 if (fNumElementIds == fMaxElementIds)
329 throw eh +
"ElementId map is full.";
332 while (fElementIdMap.find(++fLastElementId) != fElementIdMap.end());
333 if (fLastElementId == 0)
goto next_free_id;
339 element->fElementId = fLastElementId;
340 fElementIdMap.insert(std::make_pair(fLastElementId, element));
348 void REveManager::PreDeleteElement(REveElement* el)
350 if (el->fImpliedSelected > 0)
352 for (
auto slc : fSelectionList->fChildren)
354 REveSelection *sel =
dynamic_cast<REveSelection*
>(slc);
355 sel->RemoveImpliedSelectedReferencesTo(el);
358 if (el->fImpliedSelected != 0)
359 Error(
"REveManager::PreDeleteElement",
"ImpliedSelected not zero (%d) after cleanup of selections.", el->fImpliedSelected);
363 if (el->fElementId != 0)
365 auto it = fElementIdMap.find(el->fElementId);
366 if (it != fElementIdMap.end())
368 if (it->second == el)
370 fElementIdMap.erase(it);
373 else Error(
"PreDeleteElement",
"element ptr in ElementIdMap does not match the argument element.");
375 else Error(
"PreDeleteElement",
"element id %u was not registered in ElementIdMap.", el->fElementId);
377 else Error(
"PreDeleteElement",
"element with 0 ElementId passed in.");
394 Bool_t REveManager::InsertVizDBEntry(
const TString& tag, REveElement* model,
395 Bool_t replace, Bool_t update)
397 TPair* pair = (TPair*) fVizDB->FindObject(tag);
402 model->IncDenyDestroy();
403 model->SetRnrChildren(kFALSE);
405 REveElement* old_model =
dynamic_cast<REveElement*
>(pair->Value());
408 while (old_model->HasChildren())
410 REveElement *el = old_model->FirstChild();
411 el->SetVizModel(model);
414 el->CopyVizParams(model);
415 el->PropagateVizParamsToProjecteds();
418 old_model->DecDenyDestroy();
420 pair->SetValue(dynamic_cast<TObject*>(model));
430 model->IncDenyDestroy();
431 model->SetRnrChildren(kFALSE);
432 fVizDB->Add(
new TObjString(tag), dynamic_cast<TObject*>(model));
443 Bool_t REveManager::InsertVizDBEntry(
const TString& tag, REveElement* model)
445 return InsertVizDBEntry(tag, model, fVizDBReplace, fVizDBUpdate);
452 REveElement* REveManager::FindVizDBEntry(
const TString& tag)
454 return dynamic_cast<REveElement*
>(fVizDB->GetValue(tag));
463 void REveManager::LoadVizDB(
const TString& filename, Bool_t replace, Bool_t update)
465 Bool_t ex_replace = fVizDBReplace;
466 Bool_t ex_update = fVizDBUpdate;
467 fVizDBReplace = replace;
468 fVizDBUpdate = update;
472 fVizDBReplace = ex_replace;
473 fVizDBUpdate = ex_update;
481 void REveManager::LoadVizDB(
const TString& filename)
483 REveUtil::Macro(filename);
490 void REveManager::SaveVizDB(
const TString& filename)
492 TPMERegexp re(
"(.+)\\.\\w+");
493 if (re.Match(filename) != 2) {
494 Error(
"SaveVizDB",
"filename does not match required format '(.+)\\.\\w+'.");
498 TString exp_filename(filename);
499 gSystem->ExpandPathName(exp_filename);
501 std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
502 out <<
"void " << re[1] <<
"()\n";
504 out <<
" REveManager::Create();\n";
506 ClearROOTClassSaved();
512 while ((key = (TObjString*)next()))
514 REveElement* mdl =
dynamic_cast<REveElement*
>(fVizDB->GetValue(key));
517 var_name.Form(
"x%03d", var_id++);
518 mdl->SaveVizParams(out, key->String(), var_name);
522 Warning(
"SaveVizDB",
"Saving failed for key '%s'.", key->String().Data());
536 TGeoManager* REveManager::GetGeometry(
const TString& filename)
538 static const REveException eh(
"REveManager::GetGeometry ");
540 TString exp_filename = filename;
541 gSystem->ExpandPathName(exp_filename);
542 printf(
"REveManager::GetGeometry loading: '%s' -> '%s'.\n",
543 filename.Data(), exp_filename.Data());
545 gGeoManager = (TGeoManager*) fGeometries->GetValue(filename);
548 gGeoIdentity = (TGeoIdentity*) gGeoManager->GetListOfMatrices()->At(0);
552 Bool_t locked = TGeoManager::IsLocked();
554 Warning(
"REveManager::GetGeometry",
"TGeoManager is locked ... unlocking it.");
555 TGeoManager::UnlockGeometry();
557 if (TGeoManager::Import(filename) == 0) {
558 throw eh +
"TGeoManager::Import() failed for '" + exp_filename +
"'.";
561 TGeoManager::LockGeometry();
564 gGeoManager->GetTopVolume()->VisibleDaughters(1);
568 TFile f(exp_filename,
"READ");
569 TObjArray* collist = (TObjArray*) f.Get(
"ColorList");
572 TIter next(gGeoManager->GetListOfVolumes());
574 while ((vol = (TGeoVolume*) next()) !=
nullptr)
576 Int_t oldID = vol->GetLineColor();
577 TColor* col = (TColor*)collist->At(oldID);
579 col->GetRGB(r, g, b);
580 Int_t newID = TColor::GetColor(r,g,b);
581 vol->SetLineColor(newID);
586 fGeometries->Add(
new TObjString(filename), gGeoManager);
595 TGeoManager* REveManager::GetGeometryByAlias(
const TString& alias)
597 static const REveException eh(
"REveManager::GetGeometry ");
599 TObjString* full_name = (TObjString*) fGeometryAliases->GetValue(alias);
601 throw eh +
"geometry alias '" + alias +
"' not registered.";
602 return GetGeometry(full_name->String());
609 TGeoManager* REveManager::GetDefaultGeometry()
611 return GetGeometryByAlias(
"Default");
620 void REveManager::RegisterGeometryAlias(
const TString& alias,
const TString& filename)
622 fGeometryAliases->Add(
new TObjString(alias),
new TObjString(filename));
628 void REveManager::ClearROOTClassSaved()
630 TIter nextcl(gROOT->GetListOfClasses());
632 while((cls = (TClass *)nextcl()))
634 cls->ResetBit(TClass::kClassSaved);
642 void REveManager::AddLocation(
const std::string& locationName,
const std::string& path)
644 fWebWindow->GetServer()->AddLocation(locationName.c_str(), path.c_str());
651 void REveManager::SetDefaultHtmlPage(
const std::string& path)
653 fWebWindow->SetDefaultPage(path.c_str());
662 void REveManager::SetClientVersion(
const std::string& version)
664 fWebWindow->SetClientVersion(version);
671 REveManager* REveManager::Create()
673 static const REveException eh(
"REveManager::Create ");
679 REX::gEve =
new REveManager();
687 void REveManager::Terminate()
689 if (!REX::gEve)
return;
704 TStdExceptionHandler::EStatus
705 REveManager::RExceptionHandler::Handle(std::exception &exc)
707 REveException *ex =
dynamic_cast<REveException *
>(&exc);
709 Info(
"Handle",
"Exception %s", ex->what());
720 void REveManager::WindowConnect(
unsigned connid)
722 fConnList.emplace_back(connid);
723 printf(
"connection established %u\n", connid);
726 printf(
"\nEVEMNG ............. streaming the world scene.\n");
728 fWorld->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
729 fWorld->StreamElements();
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);
736 for (
auto &c: fScenes->RefChildren())
738 REveScene* scene =
dynamic_cast<REveScene *
>(c);
740 scene->AddSubscriber(std::make_unique<REveClient>(connid, fWebWindow));
741 printf(
"\nEVEMNG ............. streaming scene %s [%s]\n",
742 scene->GetCTitle(), scene->GetCName());
745 scene->StreamElements();
747 printf(
" sending json, len = %d\n", (
int) scene->fOutputJson.size());
748 Send(connid, scene->fOutputJson);
750 if (scene->fTotalBinarySize > 0)
752 printf(
" sending binary, len = %d\n", scene->fTotalBinarySize);
753 SendBinary(connid, &scene->fOutputBinary[0], scene->fTotalBinarySize);
757 printf(
" NOT sending binary, len = %d\n", scene->fTotalBinarySize);
765 void REveManager::WindowDisconnect(
unsigned connid)
767 auto conn = fConnList.end();
768 for (
auto i = fConnList.begin(); i != fConnList.end(); ++i)
770 if (i->fId == connid)
777 if (conn == fConnList.end()) {
778 printf(
"error, connection not found!");
780 printf(
"connection closed %u\n", connid);
781 fConnList.erase(conn);
782 for (
auto &c: fScenes->RefChildren())
784 REveScene* scene =
dynamic_cast<REveScene *
>(c);
785 scene->RemoveSubscriber(connid);
787 fWorld->RemoveSubscriber(connid);
796 void REveManager::WindowData(
unsigned connid,
const std::string &arg)
798 static const REveException eh(
"REveManager::WindowData ");
801 auto conn = fConnList.end();
802 for (
auto i = fConnList.begin(); i != fConnList.end(); ++i)
804 if (i->fId == connid)
811 if (conn == fConnList.end()) {
812 printf(
"error, connection not found!");
816 fWorld->BeginAcceptingChanges();
817 fScenes->AcceptChanges(
true);
820 nlohmann::json cj = nlohmann::json::parse(arg);
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"];
827 auto el = FindElementById(
id);
828 std::stringstream cmd;
829 cmd <<
"((" << ctype <<
"*)" << std::hex << std::showbase << (size_t)el <<
")->" << mir <<
";";
831 ::Info(
"REveManager::WindowData",
"MIR cmd %s", cmd.str().c_str());
832 gROOT->ProcessLine(cmd.str().c_str());
834 fScenes->AcceptChanges(
false);
835 fWorld->EndAcceptingChanges();
848 void REveManager::Send(
unsigned connid,
const std::string &data)
850 fWebWindow->Send(connid, data);
854 void REveManager::SendBinary(
unsigned connid,
const void *data, std::size_t len)
856 fWebWindow->SendBinary(connid, data, len);
861 void REveManager::DestroyElementsOf(REveElement::List_t& els)
865 fWorld->EndAcceptingChanges();
866 fScenes->AcceptChanges(
false);
868 nlohmann::json jarr = nlohmann::json::array();
870 nlohmann::json jhdr = {};
871 jhdr[
"content"] =
"REveManager::DestroyElementsOf";
873 nlohmann::json jels = nlohmann::json::array();
875 for (
auto &ep : els) {
876 jels.push_back(ep->GetElementId());
878 ep->DestroyElements();
881 jhdr[
"element_ids"] = jels;
883 jarr.push_back(jhdr);
885 std::string msg = jarr.dump();
889 for (
auto &conn : fConnList) {
890 fWebWindow->Send(conn.fId, msg);
894 void REveManager::BroadcastElementsOf(REveElement::List_t &els)
900 REveScene* scene =
dynamic_cast<REveScene*
>(ep);
901 assert (scene !=
nullptr);
903 printf(
"\nEVEMNG ............. streaming scene %s [%s]\n",
904 scene->GetCTitle(), scene->GetCName());
907 scene->StreamElements();
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);
918 fScenes->AcceptChanges(
true);
919 fWorld->BeginAcceptingChanges();
928 void REveManager::Show(
const RWebDisplayArgs &args)
930 if (gEnv->GetValue(
"WebEve.DisableShow", 0) != 0) {
931 std::string url = fWebWindow->GetUrl(
true);
932 printf(
"EVE URL %s\n", url.c_str());
934 fWebWindow->Show(args);
941 std::shared_ptr<REveGeomViewer> REveManager::ShowGeometry(
const RWebDisplayArgs &args)
944 Error(
"ShowGeometry",
"No geometry is loaded");
948 auto viewer = std::make_shared<REveGeomViewer>(gGeoManager);