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);