25 using namespace ROOT::Experimental;
26 namespace REX = ROOT::Experimental;
42 REveScene::REveScene(
const std::string& n,
const std::string& t) :
51 REveScene::~REveScene()
53 fDestructing = kStandard;
55 REX::gEve->GetViewers()->SceneDestructing(
this);
56 REX::gEve->GetScenes()->RemoveElement(
this);
61 void REveScene::AddSubscriber(std::unique_ptr<REveClient> &&sub)
63 assert(sub.get() !=
nullptr && fAcceptingChanges == kFALSE);
65 fSubscribers.emplace_back(std::move(sub));
72 void REveScene::RemoveSubscriber(
unsigned id)
74 assert(fAcceptingChanges == kFALSE);
76 auto pred = [&](std::unique_ptr<REveClient> &client) {
77 return client->fId == id;
80 fSubscribers.erase(std::remove_if(fSubscribers.begin(), fSubscribers.end(), pred), fSubscribers.end());
83 void REveScene::BeginAcceptingChanges()
85 if (fAcceptingChanges)
return;
87 if (HasSubscribers()) fAcceptingChanges = kTRUE;
90 void REveScene::SceneElementChanged(REveElement* element)
92 assert(fAcceptingChanges);
94 fChangedElements.push_back(element);
97 void REveScene::SceneElementRemoved(ElementId_t
id)
99 fRemovedElements.push_back(
id);
102 void REveScene::EndAcceptingChanges()
104 if ( ! fAcceptingChanges)
return;
106 fAcceptingChanges = kFALSE;
109 void REveScene::ProcessChanges()
113 StreamRepresentationChanges();
114 SendChangesToSubscribers();
118 void REveScene::StreamElements()
121 fOutputBinary.clear();
123 fElsWithBinaryData.clear();
124 fTotalBinarySize = 0;
126 nlohmann::json jarr = nlohmann::json::array();
128 nlohmann::json jhdr = {};
129 jhdr[
"content"] =
"REveScene::StreamElements";
130 jhdr[
"fSceneId"] = fElementId;
132 if (fCommands.size() > 0) {
133 jhdr[
"commands"] = nlohmann::json::array();
134 for (
auto &&cmd : fCommands) {
135 nlohmann::json jcmd = {};
136 jcmd[
"name"] = cmd.fName;
137 jcmd[
"icon"] = cmd.fIcon;
138 jcmd[
"elementid"] = cmd.fElementId;
139 jcmd[
"elementclass"] = cmd.fElementClass;
140 jcmd[
"func"] = cmd.fAction;
141 jhdr[
"commands"].push_back(jcmd);
145 jarr.push_back(jhdr);
147 StreamJsonRecurse(
this, jarr);
153 fOutputBinary.resize(fTotalBinarySize);
156 for (
auto &&e : fElsWithBinaryData)
158 auto rd_size = e->fRenderData->Write(&fOutputBinary[off], fOutputBinary.size() - off);
161 assert(off == fTotalBinarySize);
163 jarr.front()[
"fTotalBinarySize"] = fTotalBinarySize;
165 fOutputJson = jarr.dump();
168 void REveScene::StreamJsonRecurse(REveElement *el, nlohmann::json &jarr)
170 nlohmann::json jobj = {};
171 Int_t rd_size = el->WriteCoreJson(jobj, fTotalBinarySize);
172 jarr.push_back(jobj);
177 if (el->fScene == el && el !=
this)
184 assert (rd_size % 4 == 0);
186 fTotalBinarySize += rd_size;
187 fElsWithBinaryData.push_back(el);
190 for (
auto &&c : el->fChildren)
205 if (c->GetMother() == el)
207 StreamJsonRecurse(c, jarr);
218 void REveScene::StreamRepresentationChanges()
221 fOutputBinary.clear();
223 fElsWithBinaryData.clear();
224 fTotalBinarySize = 0;
226 nlohmann::json jarr = nlohmann::json::array();
228 nlohmann::json jhdr = {};
229 jhdr[
"content"] =
"ElementsRepresentaionChanges";
230 jhdr[
"fSceneId"] = fElementId;
232 jhdr[
"removedElements"] = nlohmann::json::array();
233 for (
auto &re : fRemovedElements)
234 jhdr[
"removedElements"].push_back(re);
236 jhdr[
"numRepresentationChanged"] = fChangedElements.size();
240 for (
auto &el: fChangedElements)
242 UChar_t bits = el->GetChangeBits();
244 nlohmann::json jobj = {};
245 jobj[
"fElementId"] = el->GetElementId();
246 jobj[
"changeBit"] = bits;
248 if (bits & kCBElementAdded || bits & kCBObjProps)
250 if (gDebug > 0 && bits & kCBElementAdded)
252 Info(
"REveScene::StreamRepresentationChanges",
"new element change %s %d\n",
253 el->GetCName(), bits);
256 Int_t rd_size = el->WriteCoreJson(jobj, fTotalBinarySize);
258 assert (rd_size % 4 == 0);
259 fTotalBinarySize += rd_size;
260 fElsWithBinaryData.push_back(el);
265 if (bits & kCBVisibility)
267 jobj[
"fRnrSelf"] = el->GetRnrSelf();
268 jobj[
"fRnrChildren"] = el->GetRnrChildren();
271 if (bits & kCBColorSelection)
273 el->WriteCoreJson(jobj, -1);
276 if (bits & kCBTransBBox)
281 jarr.push_back(jobj);
286 fChangedElements.clear();
287 fRemovedElements.clear();
290 fOutputBinary.resize(fTotalBinarySize);
293 for (
auto &e : fElsWithBinaryData) {
294 auto rd_size = e->fRenderData->Write(&fOutputBinary[off], fOutputBinary.size() - off);
298 assert(off == fTotalBinarySize);
300 jhdr[
"fTotalBinarySize"] = fTotalBinarySize;
302 nlohmann::json msg = { {
"header", jhdr}, {
"arr", jarr}};
303 fOutputJson = msg.dump();
306 Info(
"REveScene::StreamRepresentationChanges",
"class: %s changes %s ...", GetCName(), msg.dump(1).c_str() );
309 void REveScene::SendChangesToSubscribers()
311 for (
auto && client : fSubscribers) {
313 printf(
" sending json, len = %d --> to conn_id = %d\n", (
int) fOutputJson.size(), client->fId);
314 client->fWebWindow->Send(client->fId, fOutputJson);
315 if (fTotalBinarySize) {
317 printf(
" sending binary, len = %d --> to conn_id = %d\n", fTotalBinarySize, client->fId);
318 client->fWebWindow->SendBinary(client->fId, &fOutputBinary[0], fTotalBinarySize);
323 Bool_t REveScene::IsChanged()
const
326 ::Info(
"REveScene::IsChanged",
"%s (changed_or_added=%d, removed=%d)", GetCName(),
327 (
int) fChangedElements.size(), (int) fRemovedElements.size());
329 return ! (fChangedElements.empty() && fRemovedElements.empty());
337 void REveScene::Repaint(Bool_t dropLogicals)
339 if (dropLogicals) fGLScene->SetSmartRefresh(kFALSE);
340 fGLScene->PadPaint(fPad);
341 if (dropLogicals) fGLScene->SetSmartRefresh(kTRUE);
344 // Hack to propagate selection state to physical shapes.
346 // Should actually be published in PadPaint() following a direct
347 // AddObject() call, but would need some other stuff for that.
348 // Optionally, this could be exported via the TAtt3D and everything
351 TGLScene::LogicalShapeMap_t& logs = fGLScene->RefLogicalShapes();
353 for (TGLScene::LogicalShapeMapIt_t li = logs.begin(); li != logs.end(); ++li)
355 elm = dynamic_cast<REveElement*>(li->first);
356 if (elm && li->second->Ref() == 1)
358 TGLPhysicalShape* pshp = const_cast<TGLPhysicalShape*>(li->second->GetFirstPhysical());
359 pshp->Select(elm->GetSelectedLevel());
363 // Fix positions for hierarchical scenes.
366 RetransHierarchically();
374 void REveScene::RetransHierarchically()
376 fGLScene->BeginUpdate();
378 RetransHierarchicallyRecurse(this, RefMainTrans());
380 fGLScene->EndUpdate();
387 void REveScene::RetransHierarchicallyRecurse(REveElement* el, const REveTrans& tp)
389 static const REveException eh("REveScene::RetransHierarchicallyRecurse ");
392 if (el->HasMainTrans())
393 t *= el->RefMainTrans();
395 if (el->GetRnrSelf() && el != this)
397 fGLScene->UpdatePhysioLogical(el->GetRenderObject(eh), t.Array(), 0);
400 if (el->GetRnrChildren())
402 for (auto &c: el->RefChildren())
404 if (c->GetRnrAnything())
405 RetransHierarchicallyRecurse(c, t);
416 void REveScene::Paint(Option_t* option)
420 for (auto &c: fChildren)
422 // c->PadPaint(option);
431 void REveScene::DestroyElementRenderers(REveElement* element)
433 static const REveException eh("REveScene::DestroyElementRenderers ");
435 fGLScene->BeginUpdate();
436 Bool_t changed = fGLScene->DestroyLogical(element->GetRenderObject(eh), kFALSE);
437 fGLScene->EndUpdate(changed, changed);
444 void REveScene::DestroyElementRenderers(TObject* rnrObj)
446 fGLScene->BeginUpdate();
447 Bool_t changed = fGLScene->DestroyLogical(rnrObj, kFALSE);
448 fGLScene->EndUpdate(changed, changed);
461 REveSceneList::REveSceneList(
const std::string& n,
const std::string& t) :
464 SetChildClass(TClass::GetClass<REveScene>());
471 void REveSceneList::DestroyScenes()
473 auto i = fChildren.begin();
474 while (i != fChildren.end())
476 REveScene* s = (REveScene*) *(i++);
477 s->DestroyElements();
485 void REveSceneList::AcceptChanges(
bool on)
487 for (
auto &c: fChildren)
489 REveScene *s = (REveScene *)c;
491 s->BeginAcceptingChanges();
493 s->EndAcceptingChanges();
500 void REveSceneList::RepaintChangedScenes(Bool_t dropLogicals)
502 for (auto &c: fChildren)
504 REveScene* s = (REveScene*) c;
507 s->Repaint(dropLogicals);
515 void REveSceneList::RepaintAllScenes(Bool_t dropLogicals)
517 for (auto &c: fChildren)
519 ((REveScene *)c)->Repaint(dropLogicals);
526 void REveSceneList::DestroyElementRenderers(REveElement* element)
528 static const REveException eh("REveSceneList::DestroyElementRenderers ");
530 TObject* obj = element->GetRenderObject(eh);
531 for (auto &c: fChildren)
533 ((REveScene *)c)->DestroyElementRenderers(obj);
545 void REveSceneList::ProcessSceneChanges()
548 ::Info(
"REveSceneList::ProcessSceneChanges",
"processing");
550 for (
auto &el : fChildren)
552 ((REveScene*) el)->ProcessChanges();