Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REveGeoTopNode.cxx
Go to the documentation of this file.
1
3
6
8#include <ROOT/RGeomData.hxx>
9#include <ROOT/RWebWindow.hxx>
10#include <ROOT/REveManager.hxx>
12
14
15#include <ROOT/REveUtil.hxx>
16#include <ROOT/RLogger.hxx>
17#include <ROOT/REveUtil.hxx>
18#include "TBufferJSON.h"
19#include "TMath.h"
20
21#include "TGeoCompositeShape.h"
22#include "TGeoManager.h"
23#include "TClass.h"
24#include "TGeoNode.h"
25#include "TGeoMatrix.h"
26#include "TBase64.h"
27#include "TStopwatch.h"
28
29
30#include <cassert>
31#include <iostream>
32#include <regex>
33#include <nlohmann/json.hpp>
34
35
36using namespace ROOT::Experimental;
37
38thread_local ElementId_t gSelId;
39
40#define REVEGEO_DEBUG
41#ifdef REVEGEO_DEBUG
42#define REVEGEO_DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
43#else
44#define REVEGEO_DEBUG_PRINT(fmt, ...)
45#endif
46
47
49
50/*
51namespace {
52void PrintStackPath(const std::vector<int>& stack)
53{
54 printf("Path: ");
55
56 for (auto idx : stack)
57 printf("/%d", idx);
58
59 printf("\n");
60}
61}*/
62
63
64bool REveGeomDescription::ChangeEveVisibility(const std::vector<int> &stack, ERnrFlags flags, bool on)
65{
66 std::vector<RGeomNodeVisibility> &visVec = (flags == kRnrSelf) ? fVisibilitySelf : fVisibilityRec;
67
68 for (auto iter = visVec.begin(); iter != visVec.end(); iter++) {
69 if (iter->stack == stack) {
70 // AMT TODO remove path fom the vsibilirt vector if it is true
71 iter->visible = on;
72 return true;
73 }
74 }
75
76 visVec.emplace_back(stack, on);
77 return true;
78}
79
80void REveGeomDescription::RefineGeoItem(ROOT::RGeoItem &item, const std::vector<int> &iStack)
81{
82 std::vector<int> stack = fApex.GetIndexStack();
83 stack.insert(stack.end(), iStack.begin(), iStack.end());
84
85 auto isVisible = [&stack](std::vector<RGeomNodeVisibility> &visVec) -> bool {
86 for (auto &visVecEl : visVec) {
87 /*
88 printf("compare ======\n");
89 PrintStackPath(stack);
90 PrintStackPath(visVecEl.stack);
91*/
92 if (stack == visVecEl.stack)
93 return visVecEl.visible ? 1 : 0;
94 }
95 return true;
96 };
97
98 int visSelf = isVisible(fVisibilitySelf);
99 int visRec = isVisible(fVisibilityRec);
100
101 item.SetLogicalVisibility(visRec);
102 item.SetPhysicalVisibility(visSelf);
103
104 //return RGeoItem(node.name, node.chlds.size(), node.id, node.color, node.material,
105 // visRec, vis);
106}
107
108void REveGeomDescription::InitPath(const std::vector<std::string>& path)
109{
110 fApex.SetFromPath(path);
111 Build(fApex.GetNode()->GetVolume()); // rebuild geo-webviewer
112}
113
114bool REveGeomDescription::GetVisiblityForStack(const std::vector<int> &nodeStack)
115{
116 // visibility self
117 for (auto &visVecEl : fVisibilitySelf) {
118 if (nodeStack == visVecEl.stack) {
119 return false;
120 }
121 }
122
123 // visibility recurse/children
124 for (auto &visVecEl : fVisibilityRec) {
125 bool inside =
126 nodeStack.size() >= visVecEl.stack.size() && std::equal(visVecEl.stack.begin(), visVecEl.stack.end(), nodeStack.begin());
127 if (inside)
128 return false;
129 }
130
131 return true;
132}
133
134////////////////////////////////////////////////////////////////////////////////
135/// Table signal handling
136
137void REveGeomHierarchy::WebWindowCallback(unsigned connid, const std::string &arg)
138{
139 using namespace std::string_literals;
140 REveGeomDescription &eveDesc = dynamic_cast<REveGeomDescription &>(fDesc);
141
143 if (arg.compare(0, 6, "CDTOP:") == 0)
144 {
145 std::vector<std::string> ep;
146 eveDesc.InitPath(ep);
147 fDesc.IssueSignal(this, "CdTop");
148 fWebWindow->Send(connid, "RELOAD"s);
149 }
150 else if (arg.compare(0, 5, "CDUP:") == 0)
151 {
152 std::vector<std::string> result = eveDesc.GetApexPath();
153 result.pop_back();
154 eveDesc.InitPath(result);
155 fDesc.IssueSignal(this, "CdUp");
156 fWebWindow->Send(connid, "RELOAD"s);
157 }
158 else if (arg.compare(0, 8, "SETAPEX:") == 0) {
159 auto path = TBufferJSON::FromJSON<std::vector<std::string>>(arg.substr(8));
160
161 //const std::vector<int> &sstack = fDesc.GetSelectedStack();
162 // std::vector<std::string> sspath = fDesc.MakePathByStack(sstack);
163 std::vector<std::string> result = eveDesc.GetApexPath();
164 if (path->size() > 1) {
165 result.insert(result.end(), path->begin() + 1, path->end());
166 eveDesc.InitPath(result);
167 fDesc.IssueSignal(this, "SelectTop");
168 fWebWindow->Send(connid, "RELOAD"s);
169 }
170 }
171 else if ((arg.compare(0, 7, "SETVI0:") == 0) || (arg.compare(0, 7, "SETVI1:") == 0)) {
172 {
174 bool on = (arg[5] == '1');
175 auto path = TBufferJSON::FromJSON<std::vector<std::string>>(arg.substr(7));
176 // Get integer stack from string stack
177 std::vector<int> base = eveDesc.GetIndexStack();
178 std::vector<int> stack = fDesc.MakeStackByPath(*path);
179 stack.insert(stack.begin(), base.begin(), base.end());
180
182 std::cout << "Set visibilty rnr CHIDLREN \n";
184 }
185 }
186 }
187 else if ((arg.compare(0, 5, "SHOW:") == 0) || (arg.compare(0, 5, "HIDE:") == 0)) {
188 {
189 auto path = TBufferJSON::FromJSON<std::vector<std::string>>(arg.substr(5));
190 bool on = (arg.compare(0, 5, "SHOW:") == 0);
191 // Get integer stack from string stack
192
193 std::vector<int> base = eveDesc.GetIndexStack();
194 std::vector<int> stack = fDesc.MakeStackByPath(*path);
195 stack.insert(stack.begin(), base.begin(), base.end());
196
197 if (path && eveDesc.ChangeEveVisibility(stack, REveGeomDescription::kRnrSelf, on)) {
198 std::cout << "Set visibility rnr PHY \n";
201 }
202 }
203 }
204 else if (arg.compare(0, 9, "PrintInfo") == 0)
205 {
206 auto a = TBufferJSON::FromJSON<std::vector<std::string>>(arg.substr(10));
207 auto prefix = eveDesc.GetApexPath();
208
209 std::ostringstream oss;
210 if (!prefix.empty()) {
211 a->erase(a->begin());
212 a->insert(a->begin(), prefix.begin(), prefix.end());
213 std::string topName = eveDesc.GetGeoManager()->GetTopNode()->GetName();
214 // strip "_1"
215 // TGeoNodeInterator does not hold _1 in the top node
216 if (topName.rfind("_1") != std::string::npos) {
217 topName = topName.substr(0, topName.size() - 2);
218 }
219 oss << topName << "/";
220 }
221 for (size_t i = 0; i < a->size(); ++i) {
222 if (i > 0)
223 oss << "/";
224 oss << a->at(i);
225 }
226
227 std::string targetPath = oss.str();
228 const char* savedPath = gGeoManager->GetPath();
229 bool res = gGeoManager->cd(targetPath.c_str());
230 printf("Node path:\n%s \n", targetPath.c_str());
231 if (res) {
233 node->GetVolume()->InspectShape();
234
235 }
236 else {
237 printf("ERROR locating the node with given path\n");
238 }
239 gGeoManager->cd(savedPath);
240
241 }
242 else {
244 }
245}
246
247
248////////////////////////////////////////////////////////////////////////////////
249////////////////////////////////////////////////////////////////////////////////
250////////////////////////////////////////////////////////////////////////////////
251
257
258void REveGeomDescription::Apex::SetFromPath(std::vector<std::string> absPath)
259{
260 fPath = absPath;
261 fNode = LocateNodeWithPath(absPath);
262}
263
264TGeoNode *REveGeomDescription::Apex::LocateNodeWithPath(const std::vector<std::string> &path) const
265{
267 // printf("Top node name from geoData name (%s)\n", top->GetName());
268 for (size_t t = 0; t < path.size(); t++) {
269 std::string s = path[t];
270 std::cout << s << std::endl;
271 TGeoNode *ntop = top->GetVolume()->FindNode(s.c_str());
272 if (!ntop)
273 throw std::runtime_error("Apex::LocateNodeWithPath(), can't locate node with path " + s);
274 top = ntop;
275 }
276 return top;
277}
278
280{
281 if (fPath.empty())
282 return "";
283
284 std::ostringstream oss;
285
286 oss << fPath[0];
287
288 for (size_t i = 1; i < fPath.size(); ++i)
289 oss << "/" << fPath[i];
290
291 return oss.str();
292}
293
295{
296 std::vector<int> indexStack;
297
299
300 // optional: skip first if it is top itself
301 size_t start = 0;
302 std::vector<std::string> nameStack = fPath;
303 if (!nameStack.empty() && nameStack[0] == current->GetName())
304 start = 1;
305
306 for (size_t i = start; i < nameStack.size(); ++i)
307 {
308 const std::string& targetName = nameStack[i];
309
310 TGeoVolume* vol = current->GetVolume();
311
312 int nd = vol->GetNdaughters();
313
314 int foundIndex = -1;
315
316 for (int j = 0; j < nd; ++j)
317 {
318 TGeoNode* daughter = vol->GetNode(j);
319
320 if (targetName == daughter->GetName())
321 {
322 foundIndex = j;
323 current = daughter;
324 break;
325 }
326 }
327
328 if (foundIndex == -1)
329 {
330 std::cerr << "Node not found: " << targetName << std::endl;
331 return {};
332 }
333
334 indexStack.push_back(foundIndex);
335 }
336
337 // PrintStackPath(indexStack);
338 return indexStack;
339}
340
342{
344 if (!s_geoManager) {
345 throw std::runtime_error("Critical Error: Failed to import geometry file");
346 }
347}
348
349////////////////////////////////////////////////////////////////////////////////
350///
351/// Constructor.
352
354{
355 // this below will be obsolete
356 fDesc.AddSignalHandler(this, [this](const std::string &kind) { ProcessSignal(kind); });
357 fDesc.ImportFile(filename);
358
359
360 fWebHierarchy = std::make_shared<REveGeomHierarchy>(fDesc, true);
361 fWebHierarchy->SetReceiver(this);
362}
363
364void REveGeoTopNodeData::InitPath(const std::string &path)
365{
366 std::regex re(R"([/\\]+)"); // split on one or more slashes
367 std::sregex_token_iterator it(path.begin(), path.end(), re, -1);
368 std::sregex_token_iterator end;
369 std::vector<std::string> result;
370
371 for (; it != end; ++it) {
372 if (!it->str().empty()) { // skip empty parts
373 result.push_back(*it);
374 }
375 }
376
377 fDesc.InitPath(result);
378
379 for (auto &el : fNieces) {
380 REveGeoTopNodeViz *etn = dynamic_cast<REveGeoTopNodeViz *>(el);
381 etn->BuildDesc();
382 }
383}
384
385void REveGeoTopNodeData::VisibilityChanged(bool on, REveGeomDescription::ERnrFlags flag, const std::vector<int>& path)
386{
387
388 for (auto &el : fNieces) {
389 REveGeoTopNodeViz *etn = dynamic_cast<REveGeoTopNodeViz *>(el);
390 etn->VisibilityChanged(on, flag, path);
391 }
392}
393
394////////////////////////////////////////////////////////////////////////////////
395
396void REveGeoTopNodeData::SetChannel(unsigned connid, int chid)
397{
398 fWebHierarchy->Show({gEve->GetWebWindow(), connid, chid});
399}
400
401////////////////////////////////////////////////////////////////////////////////
402void REveGeoTopNodeData::ProcessSignal(const std::string &kind)
403{
405 if ((kind == "SelectTop") || (kind == "CdTop") || (kind == "CdUp"))
406 {
407 for (auto &el : fNieces) {
408 REveGeoTopNodeViz *etn = dynamic_cast<REveGeoTopNodeViz *>(el);
409 etn->BuildDesc();
410 }
411 }
412 else if (kind == "HighlightItem") {
413 /*
414 printf("REveGeoTopNodeData element highlighted --------------------------------"\n);
415 */
416
417 } else if (kind == "ClickItem") {
418 printf("REveGeoTopNodeData element CLICKED selected --------------------------------\n");
419 auto sstack = fDesc.GetClickedItem();
420 std::set<int> ss;
421
422 for (auto &n : fNieces) {
423 REveGeoTopNodeViz* viz = dynamic_cast<REveGeoTopNodeViz*>(n);
424 viz->GetIndicesFromBrowserStack(sstack, ss);
425 bool multi = false;
426 bool secondary = true;
427 gEve->GetSelection()->NewElementPicked(n->GetElementId(), multi, secondary, ss);
428 }
429 }
430}
431
432////////////////////////////////////////////////////////////////////////////////
433/// Fill core part of JSON representation.
434
435Int_t REveGeoTopNodeData::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
436{
437 Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
438
439 return ret;
440}
441
442////////////////////////////////////////////////////////////////////////////////
443// REveGeoTopNodeViz
444////////////////////////////////////////////////////////////////////////////////
445////////////////////////////////////////////////////////////////////////////////
446
451
456
458{
460 {
461 if (it.GetLevel() > fGeoData->fDesc.GetVisLevel()) {
462 it.Skip();
463 return false;
464 }
465 }
466 else if (fMode == EMode::kModeLeafOnly)
467 {
468 // printf("accep mkod eleaf node ptr %p \n", (void*)it.GetNode(it.GetLevel()));
469 if (it.GetNode(it.GetLevel())->GetNdaughters())
470 return false;
471 } else if (fMode == EMode::kModeMixed) {
472 if (it.GetLevel() > fGeoData->fDesc.GetVisLevel()) {
473 if (skip) it.Skip();
474 return false;
475 }
476 // printf("accep mkod eleaf node ptr %p \n", (void*)it.GetNode(it.GetLevel()));
477 if (it.GetNode(it.GetLevel())->GetNdaughters())
478 return false;
479 }
480
481 return true;
482}
483
484std::string REveGeoTopNodeViz::GetHighlightTooltip(const std::set<int> & set) const
485{
487 if (set.empty()) {
488 return "";
489 } else {
490 auto it = set.begin();
491 int pos = *it;
492 //const BNode &bn = fNodes[pos];
493 std::cout << "highlight node with ID " << pos << "\n";
494
495 std::string res = "GeoNode name";
496
498 TGeoIterator git(top->GetVolume());
499 TGeoNode *node;
500 int i = 0;
501 TString path;
502 while ((node = git.Next()))
503 {
504 if (!AcceptNode(git))
505 continue;
506 if (i == pos) {
507 git.GetPath(path);
508 res = path;
509 break;
510 }
511 i++;
512 }
513
514 // print complete path to stdcout for debug info
515 std::string topName = fGeoData->fDesc.GetGeoManager()->GetTopNode()->GetName();
516 // strip "_1", TGeoNodeInterator does not hold _1 in the top node
517 if (topName.rfind("_1") != std::string::npos) {
518 topName = topName.substr(0, topName.size() - 2);
519 std::cout << topName << "/";
520 }
521 auto prefix = fGeoData->fDesc.GetApexPath();
522
523 for (size_t f = 0; f < prefix.size(); ++f) {
524 std::cout << prefix[f];
525 std::cout << "/";
526 }
527 std::cout << res << "\n";
528
529 return res;
530 }
531}
532
534{
535 // locate top node
537
538 fNodes.clear();
539 fShapes.clear();
540 // shape array
541 std::set<TGeoShape *> shapes;
542 TStopwatch timer;
543 timer.Start();
544 CollectShapes(top, shapes, fShapes);
545 std::cout << "Shape size " << shapes.size() << "\n";
546
547 timer.Stop();
548
549 printf("Collect Shapes Real time: %.3f s\n", timer.RealTime());
550 // printf("CPU time: %.3f s\n", timer.CpuTime());
551
552 // node array
553 timer.Start();
555 // std::cout << "Node size " << fNodes.size() << "\n";
556
557 timer.Stop();
558
559 printf("Collect Nodes Real time: %.3f s\n", timer.RealTime());
560 // printf("NODES CPU time: %.3f s\n", timer.CpuTime());
561
563}
564
565void REveGeoTopNodeViz::CollectNodes(TGeoVolume *volume, std::vector<BNode> &bnl, std::vector<BShape> &browsables)
566{
567 printf("collect nodes \n");
568 TGeoIterator it(volume);
569 TGeoNode *node;
570 int nodeId = 0;
571
572 std::vector<int> apexStack = fGeoData->RefDescription().GetIndexStack();
573
574 // get top node transformation
575 TGeoHMatrix global;
576 {
578 for (int idx : apexStack) {
579 inode = inode->GetDaughter(idx);
580 global.Multiply(inode->GetMatrix());
581 }
582 }
583
584 while ((node = it.Next()))
585 {
586 if (!AcceptNode(it))
587 continue;
588
589 TGeoHMatrix full = global; // identity if global is identity
590 full.Multiply(it.GetCurrentMatrix());
591 const TGeoMatrix *mat = &full;
592
593 // const TGeoMatrix *mat = it.GetCurrentMatrix();
594 const Double_t *t = mat->GetTranslation(); // size 3
595 const Double_t *r = mat->GetRotationMatrix(); // size 9 (3x3)
596
597 Double_t m[16];
598 if (mat->IsScale()) {
599 const Double_t *s = mat->GetScale();
600 m[0] = r[0] * s[0];
601 m[1] = r[3] * s[0];
602 m[2] = r[6] * s[0];
603 m[3] = 0;
604 m[4] = r[1] * s[1];
605 m[5] = r[4] * s[1];
606 m[6] = r[7] * s[1];
607 m[7] = 0;
608 m[8] = r[2] * s[2];
609 m[9] = r[5] * s[2];
610 m[10] = r[8] * s[2];
611 m[11] = 0;
612 m[12] = t[0];
613 m[13] = t[1];
614 m[14] = t[2];
615 m[15] = 1;
616 } else {
617 m[0] = r[0];
618 m[1] = r[3];
619 m[2] = r[6];
620 m[3] = 0;
621 m[4] = r[1];
622 m[5] = r[4];
623 m[6] = r[7];
624 m[7] = 0;
625 m[8] = r[2];
626 m[9] = r[5];
627 m[10] = r[8];
628 m[11] = 0;
629 m[12] = t[0];
630 m[13] = t[1];
631 m[14] = t[2];
632 m[15] = 1;
633 }
634
635 BNode b;
636 b.node = node;
637 b.nodeId = nodeId;
638 b.color = node->GetVolume()->GetLineColor();
639
640 // TString path; it.GetPath(path);
641 // printf("[%d] %d %s \n", node->GetNdaughters(), it.GetLevel(), path.Data());
642
643
644 // set BNode transformation matrix
645 for (int i = 0; i < 16; ++i)
646 b.trans[i] = m[i];
647
648 // find shape
649 TGeoShape *shape = node->GetVolume()->GetShape();
650 b.shapeId = -1; // mark invalid at start
651 for (size_t i = 0; i < browsables.size(); i++) {
652 if (shape == browsables[i].shape) {
653 b.shapeId = i;
654 break;
655 }
656 }
657 assert(b.shapeId >= 0);
658
659
660 // set visibility flag
661 std::vector<int> visStack = apexStack;
662 for (int i = 1; i <= it.GetLevel(); ++i)
663 visStack.push_back(it.GetIndex(i));
664 // PrintStackPath(visStack);
665 b.visible = fGeoData->RefDescription().GetVisiblityForStack(visStack);
666
667 // printf("Node %d shape id %d \n", (int)bnl.size(), b.shapeId);
668 bnl.push_back(b);
669 nodeId++;
670
671 if (nodeId > 300000) {
672 R__LOG_ERROR(REveLog()) << "Max number of nodes reached ... breaking the loop \n";
673 printf("num nodes locked !!! \n");
674 break;
675 }
676 }
677}
678
679void REveGeoTopNodeViz::CollectShapes(TGeoNode *tnode, std::set<TGeoShape *> &shapes, std::vector<BShape> &browsables)
680{
681 printf("collect shapes \n");
682 TGeoIterator geoit(tnode->GetVolume());
683 TGeoNode *node = nullptr;
684 while ((node = geoit.Next()))
685 {
686 if (!AcceptNode(geoit))
687 continue;
688
689 TGeoVolume *vol = node->GetVolume();
690 if (vol) {
691 TGeoShape *shape = vol->GetShape();
692 if (shape) {
693 auto it = shapes.find(shape);
694 if (it == shapes.end()) {
695 shapes.insert(shape); // use set to avoid duplicates
696 REveGeoPolyShape polyShape;
697 TGeoCompositeShape *compositeShape = dynamic_cast<TGeoCompositeShape *>(shape);
698 int n_seg = 60; // default value in the geo manager and poly shape
699 if (compositeShape)
700 polyShape.BuildFromComposite(compositeShape, n_seg);
701 else
702 polyShape.BuildFromShape(shape, n_seg);
703
704 // printf("[%d] Shape name %s %s \n",(int)browsables.size(), shape->GetName(), shape->ClassName());
705
706 // printf("vertices %lu: \n", polyShape.fVertices.size());
707
708 // create browser shape
709 BShape browserShape;
710 browserShape.shape = shape;
711 browsables.push_back(browserShape);
712
713 // copy vertices transform vec double to float
714 browsables.back().vertices.reserve(polyShape.GetVertices().size());
715 for (size_t i = 0; i < polyShape.GetVertices().size(); i++)
716 browsables.back().vertices.push_back(polyShape.GetVertices()[i]);
717
718 // copy indices kip the first integer in the sequence of 4
719 for (size_t i = 0; i < polyShape.GetPolyDesc().size(); i += 4) {
720 browsables.back().indices.push_back(polyShape.GetPolyDesc()[i + 1]);
721 browsables.back().indices.push_back(polyShape.GetPolyDesc()[i + 2]);
722 browsables.back().indices.push_back(polyShape.GetPolyDesc()[i + 3]);
723 }
724 // printf("last browsable size indices size %lu \n", browsables.back().indices.size());
725 }
726 }
727 }
728 }
729}
730
732{
733 fRenderData = std::make_unique<REveRenderData>("makeGeoTopNode");
734 for (size_t i = 0; i < fNodes.size(); ++i) {
735
736 UChar_t c[4] = {1, 2, 3, 4};
738 // if (i < 400) printf("%d > %d %d %d %d \n",fNodes[i].color, c[0], c[1], c[2], c[3]);
739 uint32_t v = (c[0] << 16) + (c[1] << 8) + c[2];
740 float pc;
741 std::memcpy(&pc, &v, sizeof(pc));
742 GetRenderData()->PushV(pc);
743 }
744}
745////////////////////////////////////////////////////////////////////////////////
746/// Fill the bounding box (virtual from REveElement) from the box of the apex
747/// node's shape. Called from WriteCoreJson() inside its REveGeoManagerHolder.
748
750{
751 TGeoNode *top = fGeoData ? fGeoData->fDesc.GetApexNode() : nullptr;
752 TGeoShape *shape = top ? top->GetVolume()->GetShape() : nullptr;
753 if (shape)
754 shape->ComputeBBox();
755 TGeoBBox *box = dynamic_cast<TGeoBBox *>(shape);
756 if (!box) {
757 BBoxZero();
758 return;
759 }
760 const Double_t *o = box->GetOrigin();
761 BBoxInit();
762 BBoxCheckBox(REveVector(o[0], o[1], o[2]), REveVector(box->GetDX(), box->GetDY(), box->GetDZ()));
763}
764
765//------------------------------------------------------------------------------
766//------------------------------------------------------------------------------
768{
769 fGeoData = d;
770 if (rebuild)
771 BuildDesc();
772}
773
774//------------------------------------------------------------------------------
775
776int REveGeoTopNodeViz::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
777{
779 Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
780
781 if (!fGeoData) {
782 j["dataId"] = -1;
783 } else {
784 // std::string json = fGeoData->fDesc.ProduceJson();
785 // j["geomDescription"] = TBase64::Encode(json.c_str());
786 j["dataId"] = fGeoData->GetElementId();
787 }
788 j["visLevel"] = fGeoData ? fGeoData->fDesc.GetVisLevel() : 0;
789
790 // put shapes vector in json array
791 using namespace nlohmann;
792
793 json shapeVertexArr = json::array();
794 int vertexOff = 0;
795
796 json shapeIndexArr = json::array();
797 json shapePolySizeArr = json::array();
798 json shapePolyOffArr = json::array();
799
800 json nodeVisibility = json::array();
801
802 int polyOff = 0;
803
804 // need four integers for
805 for (size_t i = 0; i < fShapes.size(); ++i) {
806 // vertices
807
808 std::copy(fShapes[i].vertices.begin(), fShapes[i].vertices.end(), std::back_inserter(shapeVertexArr));
809
810 int numVertices = int(fShapes[i].vertices.size());
811 // indices
812 // write shape indices with the vertexOff
813 for (size_t p = 0; p < fShapes[i].indices.size(); ++p)
814 shapeIndexArr.push_back(fShapes[i].indices[p] + vertexOff);
815
816 int numIndices = int(fShapes[i].indices.size());
817 shapePolySizeArr.push_back(numIndices);
818 shapePolyOffArr.push_back(polyOff);
819
820 // printf("shape [%d] numIndices %d \n", i, numIndices);
821
822 polyOff += numIndices;
823 vertexOff += numVertices / 3;
824 }
825
826 // write vector of shape ids for visible nodes
827 json nodeShapeIds = json::array();
828 json nodeTrans = json::array();
829 json nodeColors = json::array();
830
831 for (size_t i = 0; i < fNodes.size(); ++i) {
832 nodeShapeIds.push_back(fNodes[i].shapeId);
833 nodeVisibility.push_back(fNodes[i].visible);
834 for (int t = 0; t < 16; t++)
835 nodeTrans.push_back(fNodes[i].trans[t]);
836 }
837 // shape basic array
838
839 j["shapeVertices"] = shapeVertexArr;
840
841 // shape basic indices array
842 j["shapeIndices"] = shapeIndexArr;
843
844 // shape poly offset array
845 j["shapeIndicesOff"] = shapePolyOffArr;
846 j["shapeIndicesSize"] = shapePolySizeArr;
847
848 j["nodeShapeIds"] = nodeShapeIds;
849 j["nodeTrans"] = nodeTrans;
850 j["nodeVisibility"] = nodeVisibility;
851 j["fSecondarySelect"] = fAlwaysSecSelect;
852
853 // std::cout << "Write Core json " << j.dump(1) << "\n";
854 return ret;
855}
856
858{
859 if (fGeoData) {
862 }
863}
864
865void REveGeoTopNodeViz::GetIndicesFromBrowserStack(const std::vector<int> &stack, std::set<int> &res)
866{
868 TGeoIterator it(top->GetVolume());
869 std::vector<int> nodeStack;
870 int cnt = 0;
871 TGeoNode *node;
872
873 while ((node = it.Next())) {
874 int level = it.GetLevel();
875
876 bool accept = AcceptNode(it, false);
877
878 nodeStack.resize(level);
879 if (level > 0)
880 nodeStack[level - 1] = it.GetIndex(level);
881
882 bool inside = nodeStack.size() >= stack.size() && std::equal(stack.begin(), stack.end(), nodeStack.begin());
883 if (inside) {
884 res.insert(cnt);
885 } // rnr flags
886 if (accept) cnt++;
887 } // while it
888
889 printf("GetIndicesFromBrowserStack stack size %zu res size %zu\n", stack.size(), res.size());
890}
891
892void REveGeoTopNodeViz::VisibilityChanged(bool on, REveGeomDescription::ERnrFlags flag, const std::vector<int> &iStack)
893{
894 // function argument is full stack, we remove the apex path
895 size_t apexDepth = fGeoData->RefDescription().GetApexPath().size();
896 std::vector<int> stack(iStack.begin() + apexDepth, iStack.end());
897
898 // PrintStackPath(stack);
899
901 TGeoIterator it(top->GetVolume());
902 std::vector<int> nodeStack;
903 int cnt = 0;
904 TGeoNode *node;
905 while ((node = it.Next())) {
906
907 int level = it.GetLevel();
908 if (!AcceptNode(it))
909 continue;
910
911 nodeStack.resize(level);
912 if (level > 0)
913 nodeStack[level - 1] = it.GetIndex(level);
914
915 if (flag == REveGeomDescription::kRnrSelf) {
916 /*
917 printf("nODEcompare ======\n");
918 PrintStackPath(stack);
919 PrintStackPath(nodeStack);
920 */
921 if (nodeStack == stack) {
922 fNodes[cnt].visible = on;
923
924 break;
925 }
926 } else {
927 bool inside = nodeStack.size() >= stack.size() && std::equal(stack.begin(), stack.end(), nodeStack.begin());
928 if (inside) {
929 fNodes[cnt].visible = on;
930 }
931 } // rnr flags
932 cnt++;
933 } // while it
935}
nlohmann::json json
thread_local ElementId_t gSelId
#define R__LOG_ERROR(...)
Definition RLogger.hxx:356
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
char Text_t
General string (char)
Definition RtypesCore.h:77
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:53
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char mode
R__EXTERN TGeoManager * gGeoManager
virtual Int_t WriteCoreJson(nlohmann::json &cj, Int_t rnr_offset)
Write core json.
std::unique_ptr< REveRenderData > fRenderData
! Vertex / normal / triangle index information for rendering.
void BBoxZero(Float_t epsilon=0, Float_t x=0, Float_t y=0, Float_t z=0)
Set the bounding box to a cube of half-side epsilon at (x, y, z); with the defaults,...
void BBoxInit()
Start filling the bounding box with BBoxCheckPoint(): min at +infinity, max at -infinity,...
ElementId_t GetElementId() const
void BBoxCheckBox(const REveVector &c, const REveVector &h)
Grow the box to hold the axis-aligned box with centre c and half sizes h.
REveRenderData * GetRenderData() const
REveGeoManagerHolder Exception-safe global variable holders.
Definition REveUtil.hxx:95
const std::vector< UInt_t > & GetPolyDesc() const
void BuildFromShape(TGeoShape *shape, Int_t n_seg=60)
Produce all polygons from normal shape.
void BuildFromComposite(TGeoCompositeShape *cshp, Int_t n_seg=60)
Produce all polygons from composite shape.
const std::vector< Double_t > & GetVertices() const
void SetChannel(unsigned connid, int chid)
Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override
Fill core part of JSON representation.
void InitPath(const std::string &path)
void VisibilityChanged(bool on, REveGeomDescription::ERnrFlags flag, const std::vector< int > &path)
REveGeoTopNodeData(const REveGeoTopNodeData &)=delete
void ProcessSignal(const std::string &)
void GetIndicesFromBrowserStack(const std::vector< int > &stack, std::set< int > &outStack)
std::string GetHighlightTooltip(const std::set< int > &secondary_idcs) const override
REveGeoTopNodeViz(const REveGeoTopNodeViz &)=delete
void CollectNodes(TGeoVolume *volume, std::vector< BNode > &bnl, std::vector< BShape > &browsables)
void BuildRenderData() override
Build fRenderData, what the client draws.
void ComputeBBox() override
Fill the bounding box (virtual from REveElement) from the box of the apex node's shape.
void VisibilityChanged(bool on, REveGeomDescription::ERnrFlags flag, const std::vector< int > &path)
Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override
Write core json.
void SetGeoData(REveGeoTopNodeData *d, bool rebuild=true)
bool AcceptNode(TGeoIterator &it, bool skip=true) const
void CollectShapes(TGeoNode *node, std::set< TGeoShape * > &shapes, std::vector< BShape > &browsables)
void SetFromPath(std::vector< std::string > absPath)
TGeoNode * LocateNodeWithPath(const std::vector< std::string > &path) const
void InitPath(const std::vector< std::string > &path)
bool ChangeEveVisibility(const std::vector< int > &stack, ERnrFlags rnrFlag, bool on)
std::vector< RGeomNodeVisibility > fVisibilitySelf
virtual void RefineGeoItem(ROOT::RGeoItem &item, const std::vector< int > &stack) override
Method which allows to add/modify information in RGeoItem which will be provided to client - like tit...
bool GetVisiblityForStack(const std::vector< int > &stack)
const std::vector< std::string > & GetApexPath() const
std::vector< RGeomNodeVisibility > fVisibilityRec
virtual void WebWindowCallback(unsigned connid, const std::string &kind) override
Table signal handling.
REveSelection * GetSelection() const
std::shared_ptr< ROOT::RWebWindow > GetWebWindow() const
void NewElementPicked(ElementId_t id, bool multi, bool secondary, const std::set< int > &secondary_idcs={})
Called from GUI when user picks or un-picks an element.
static void ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha=kTRUE)
Fill col with RGBA values corresponding to index ci.
Definition REveUtil.cxx:187
Representation of single item in the geometry browser.
Definition RGeomData.hxx:88
void SetPhysicalVisibility(int physicalVis)
void SetLogicalVisibility(int logicalVis)
std::vector< RGeomNode > fDesc
! converted description, send to client
void SetVisLevel(int lvl=3)
Set maximal visible level.
void IssueSignal(const void *handler, const std::string &kind)
Issue signal, which distributed on all handlers - excluding source handler.
int GetVisLevel() const
Returns maximal visible level.
std::vector< int > MakeStackByPath(const std::vector< std::string > &path)
Produce stack based on string path Used to highlight geo volumes by browser hover event.
void Build(TGeoManager *mgr, const std::string &volname="")
Collect information about geometry hierarchy into flat list like it done in JSROOT ClonedNodes....
std::shared_ptr< RWebWindow > fWebWindow
! web window to show geometry
virtual void WebWindowCallback(unsigned connid, const std::string &arg)
Process data from client.
RGeomDescription & fDesc
! geometry description, shared with external
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
Box class.
Definition TGeoBBox.h:18
Composite shapes are Boolean combinations of two or more shape components.
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:459
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return
A geometry iterator.
Definition TGeoNode.h:249
const TGeoMatrix * GetCurrentMatrix() const
Returns global matrix for current node.
Int_t GetLevel() const
Definition TGeoNode.h:295
void GetPath(TString &path) const
Returns the path for the current node.
TGeoNode * GetNode(Int_t level) const
Returns current node at a given level.
Int_t GetIndex(Int_t i) const
Definition TGeoNode.h:294
TGeoNode * Next()
Returns next node.
void Skip()
Stop iterating the current branch.
The manager class for any TGeo geometry.
Definition TGeoManager.h:46
virtual Bool_t cd(const char *path="")
Browse the tree of nodes starting from fTopNode according to pathname.
TGeoNode * GetCurrentNode() const
static TGeoManager * Import(const char *filename, const char *name="", Option_t *option="")
static function Import a geometry from a gdml or ROOT file
TGeoNode * GetTopNode() const
const char * GetPath() const
Get path to the current node in the form /node0/node1/...
Geometrical transformation package.
Definition TGeoMatrix.h:39
Bool_t IsScale() const
Definition TGeoMatrix.h:68
virtual const Double_t * GetTranslation() const =0
virtual const Double_t * GetScale() const =0
virtual const Double_t * GetRotationMatrix() const =0
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition TGeoNode.h:39
TGeoVolume * GetVolume() const
Definition TGeoNode.h:100
Int_t GetNdaughters() const
Definition TGeoNode.h:92
TGeoNode * GetDaughter(Int_t ind) const
Definition TGeoNode.h:84
virtual TGeoMatrix * GetMatrix() const =0
Base abstract class for all shapes.
Definition TGeoShape.h:25
virtual void ComputeBBox()=0
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:45
Int_t GetNdaughters() const
Definition TGeoVolume.h:371
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
TGeoShape * GetShape() const
Definition TGeoVolume.h:193
void InspectShape() const
Definition TGeoVolume.h:198
TGeoNode * FindNode(const char *name) const
search a daughter inside the list of nodes
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Stopwatch class.
Definition TStopwatch.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
void Stop()
Stop the stopwatch.
Basic string class.
Definition TString.h:137
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
const Int_t n
Definition legend1.C:16
Namespace for ROOT features in testing.
Definition TROOT.h:100
ROOT::RLogChannel & REveLog()
Log channel for Eve diagnostics.
Definition REveTypes.cxx:52
R__EXTERN REveManager * gEve
REveVectorT< Float_t > REveVector
TMarker m
Definition textangle.C:8