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";
183 fReceiver->VisibilityChanged(on, REveGeomDescription::kRnrChildren, stack);
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";
200 fReceiver->VisibilityChanged(on, REveGeomDescription::kRnrSelf, stack);
201 }
202 }
203 }
204 else if (arg.compare(0, 9, "PrintInfo") == 0)
205 {
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) {
232 TGeoNode* node = gGeoManager->GetCurrentNode();
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
341void REveGeomDescription::ImportFile(const char* filename)
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
453 {
454 fMode = mode;
455}
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
497 TGeoNode *top = fGeoData->fDesc.GetApexNode();
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 return res;
514 }
515}
516
518{
519 // locate top node
520 TGeoNode* top = fGeoData->fDesc.GetApexNode();
521
522 fNodes.clear();
523 fShapes.clear();
524 // shape array
525 std::set<TGeoShape *> shapes;
526 TStopwatch timer;
527 timer.Start();
528 CollectShapes(top, shapes, fShapes);
529 std::cout << "Shape size " << shapes.size() << "\n";
530
531 timer.Stop();
532
533 printf("Collect Shapes Real time: %.3f s\n", timer.RealTime());
534 // printf("CPU time: %.3f s\n", timer.CpuTime());
535
536 // node array
537 timer.Start();
539 // std::cout << "Node size " << fNodes.size() << "\n";
540
541 timer.Stop();
542
543 printf("Collect Nodes Real time: %.3f s\n", timer.RealTime());
544 // printf("NODES CPU time: %.3f s\n", timer.CpuTime());
545
547}
548
549void REveGeoTopNodeViz::CollectNodes(TGeoVolume *volume, std::vector<BNode> &bnl, std::vector<BShape> &browsables)
550{
551 printf("collect nodes \n");
552 TGeoIterator it(volume);
553 TGeoNode *node;
554 int nodeId = 0;
555
556 std::vector<int> apexStack = fGeoData->RefDescription().GetIndexStack();
557
558 // get top node transformation
559 TGeoHMatrix global;
560 {
562 for (int idx : apexStack) {
563 inode = inode->GetDaughter(idx);
564 global.Multiply(inode->GetMatrix());
565 }
566 }
567
568 while ((node = it.Next()))
569 {
570 if (!AcceptNode(it))
571 continue;
572
573 TGeoHMatrix full = global; // identity if global is identity
574 full.Multiply(it.GetCurrentMatrix());
575 const TGeoMatrix *mat = &full;
576
577 // const TGeoMatrix *mat = it.GetCurrentMatrix();
578 const Double_t *t = mat->GetTranslation(); // size 3
579 const Double_t *r = mat->GetRotationMatrix(); // size 9 (3x3)
580
581 Double_t m[16];
582 if (mat->IsScale()) {
583 const Double_t *s = mat->GetScale();
584 m[0] = r[0] * s[0];
585 m[1] = r[3] * s[0];
586 m[2] = r[6] * s[0];
587 m[3] = 0;
588 m[4] = r[1] * s[1];
589 m[5] = r[4] * s[1];
590 m[6] = r[7] * s[1];
591 m[7] = 0;
592 m[8] = r[2] * s[2];
593 m[9] = r[5] * s[2];
594 m[10] = r[8] * s[2];
595 m[11] = 0;
596 m[12] = t[0];
597 m[13] = t[1];
598 m[14] = t[2];
599 m[15] = 1;
600 } else {
601 m[0] = r[0];
602 m[1] = r[3];
603 m[2] = r[6];
604 m[3] = 0;
605 m[4] = r[1];
606 m[5] = r[4];
607 m[6] = r[7];
608 m[7] = 0;
609 m[8] = r[2];
610 m[9] = r[5];
611 m[10] = r[8];
612 m[11] = 0;
613 m[12] = t[0];
614 m[13] = t[1];
615 m[14] = t[2];
616 m[15] = 1;
617 }
618
619 BNode b;
620 b.node = node;
621 b.nodeId = nodeId;
622 b.color = node->GetVolume()->GetLineColor();
623
624 // TString path; it.GetPath(path);
625 // printf("[%d] %d %s \n", node->GetNdaughters(), it.GetLevel(), path.Data());
626
627
628 // set BNode transformation matrix
629 for (int i = 0; i < 16; ++i)
630 b.trans[i] = m[i];
631
632 // find shape
633 TGeoShape *shape = node->GetVolume()->GetShape();
634 b.shapeId = -1; // mark invalid at start
635 for (size_t i = 0; i < browsables.size(); i++) {
636 if (shape == browsables[i].shape) {
637 b.shapeId = i;
638 break;
639 }
640 }
641 assert(b.shapeId >= 0);
642
643
644 // set visibility flag
645 std::vector<int> visStack = apexStack;
646 for (int i = 1; i <= it.GetLevel(); ++i)
647 visStack.push_back(it.GetIndex(i));
648 // PrintStackPath(visStack);
649 b.visible = fGeoData->RefDescription().GetVisiblityForStack(visStack);
650
651 // printf("Node %d shape id %d \n", (int)bnl.size(), b.shapeId);
652 bnl.push_back(b);
653 nodeId++;
654
655 if (nodeId > 300000) {
656 R__LOG_ERROR(REveLog()) << "Max number of nodes reached ... breaking the loop \n";
657 printf("num nodes locked !!! \n");
658 break;
659 }
660 }
661}
662
663void REveGeoTopNodeViz::CollectShapes(TGeoNode *tnode, std::set<TGeoShape *> &shapes, std::vector<BShape> &browsables)
664{
665 printf("collect shapes \n");
666 TGeoIterator geoit(tnode->GetVolume());
667 TGeoNode *node = nullptr;
668 while ((node = geoit.Next()))
669 {
670 if (!AcceptNode(geoit))
671 continue;
672
673 TGeoVolume *vol = node->GetVolume();
674 if (vol) {
675 TGeoShape *shape = vol->GetShape();
676 if (shape) {
677 auto it = shapes.find(shape);
678 if (it == shapes.end()) {
679 shapes.insert(shape); // use set to avoid duplicates
680 REveGeoPolyShape polyShape;
681 TGeoCompositeShape *compositeShape = dynamic_cast<TGeoCompositeShape *>(shape);
682 int n_seg = 60; // default value in the geo manager and poly shape
683 if (compositeShape)
684 polyShape.BuildFromComposite(compositeShape, n_seg);
685 else
686 polyShape.BuildFromShape(shape, n_seg);
687
688 // printf("[%d] Shape name %s %s \n",(int)browsables.size(), shape->GetName(), shape->ClassName());
689
690 // printf("vertices %lu: \n", polyShape.fVertices.size());
691
692 // create browser shape
693 BShape browserShape;
694 browserShape.shape = shape;
695 browsables.push_back(browserShape);
696
697 // copy vertices transform vec double to float
698 browsables.back().vertices.reserve(polyShape.GetVertices().size());
699 for (size_t i = 0; i < polyShape.GetVertices().size(); i++)
700 browsables.back().vertices.push_back(polyShape.GetVertices()[i]);
701
702 // copy indices kip the first integer in the sequence of 4
703 for (size_t i = 0; i < polyShape.GetPolyDesc().size(); i += 4) {
704 browsables.back().indices.push_back(polyShape.GetPolyDesc()[i + 1]);
705 browsables.back().indices.push_back(polyShape.GetPolyDesc()[i + 2]);
706 browsables.back().indices.push_back(polyShape.GetPolyDesc()[i + 3]);
707 }
708 // printf("last browsable size indices size %lu \n", browsables.back().indices.size());
709 }
710 }
711 }
712 }
713}
714
716{
717 fRenderData = std::make_unique<REveRenderData>("makeGeoTopNode");
718 for (size_t i = 0; i < fNodes.size(); ++i) {
719
720 UChar_t c[4] = {1, 2, 3, 4};
722 // if (i < 400) printf("%d > %d %d %d %d \n",fNodes[i].color, c[0], c[1], c[2], c[3]);
723 uint32_t v = (c[0] << 16) + (c[1] << 8) + c[2];
724 float pc;
725 std::memcpy(&pc, &v, sizeof(pc));
726 GetRenderData()->PushV(pc);
727 }
728}
729//------------------------------------------------------------------------------
730//------------------------------------------------------------------------------
732{
733 fGeoData = d;
734 if (rebuild)
735 BuildDesc();
736}
737
738//------------------------------------------------------------------------------
739
740int REveGeoTopNodeViz::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
741{
743 Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
744
745 if (!fGeoData) {
746 j["dataId"] = -1;
747 } else {
748 // std::string json = fGeoData->fDesc.ProduceJson();
749 // j["geomDescription"] = TBase64::Encode(json.c_str());
750 j["dataId"] = fGeoData->GetElementId();
751 }
752 j["visLevel"] = fGeoData ? fGeoData->fDesc.GetVisLevel() : 0;
753
754 // put shapes vector in json array
755 using namespace nlohmann;
756
757 json shapeVertexArr = json::array();
758 int vertexOff = 0;
759
760 json shapeIndexArr = json::array();
761 json shapePolySizeArr = json::array();
762 json shapePolyOffArr = json::array();
763
764 json nodeVisibility = json::array();
765
766 int polyOff = 0;
767
768 // need four integers for
769 for (size_t i = 0; i < fShapes.size(); ++i) {
770 // vertices
771
772 std::copy(fShapes[i].vertices.begin(), fShapes[i].vertices.end(), std::back_inserter(shapeVertexArr));
773
774 int numVertices = int(fShapes[i].vertices.size());
775 // indices
776 // write shape indices with the vertexOff
777 for (size_t p = 0; p < fShapes[i].indices.size(); ++p)
778 shapeIndexArr.push_back(fShapes[i].indices[p] + vertexOff);
779
780 int numIndices = int(fShapes[i].indices.size());
781 shapePolySizeArr.push_back(numIndices);
782 shapePolyOffArr.push_back(polyOff);
783
784 // printf("shape [%d] numIndices %d \n", i, numIndices);
785
786 polyOff += numIndices;
787 vertexOff += numVertices / 3;
788 }
789
790 // write vector of shape ids for visible nodes
791 json nodeShapeIds = json::array();
792 json nodeTrans = json::array();
793 json nodeColors = json::array();
794
795 for (size_t i = 0; i < fNodes.size(); ++i) {
796 nodeShapeIds.push_back(fNodes[i].shapeId);
797 nodeVisibility.push_back(fNodes[i].visible);
798 for (int t = 0; t < 16; t++)
799 nodeTrans.push_back(fNodes[i].trans[t]);
800 }
801 // shape basic array
802
803 j["shapeVertices"] = shapeVertexArr;
804
805 // shape basic indices array
806 j["shapeIndices"] = shapeIndexArr;
807
808 // shape poly offset array
809 j["shapeIndicesOff"] = shapePolyOffArr;
810 j["shapeIndicesSize"] = shapePolySizeArr;
811
812 j["nodeShapeIds"] = nodeShapeIds;
813 j["nodeTrans"] = nodeTrans;
814 j["nodeVisibility"] = nodeVisibility;
815 j["fSecondarySelect"] = fAlwaysSecSelect;
816
817
818
819
820 // ship bounding box info
821 TGeoNode* top = fGeoData->fDesc.GetApexNode();
822 TGeoVolume *vol = top->GetVolume();
823 TGeoShape *shape = vol->GetShape();
824 shape->ComputeBBox();
825 TGeoBBox *box = dynamic_cast<TGeoBBox *>(shape);
826 if (box) {
827 const Double_t *origin = box->GetOrigin();
828
829 // printf("BBox center: (%f, %f, %f)\n", origin[0], origin[1], origin[2]);
830 //printf("origin lengths: (%f, %f, %f)\n", origin[0], origin[1], origin[2]);
831
832 auto jbb = json::array();
833 jbb.push_back(origin[0] - box->GetDX());
834 jbb.push_back(origin[0] + box->GetDX());
835 jbb.push_back(origin[1] - box->GetDY());
836 jbb.push_back(origin[1] + box->GetDY());
837 jbb.push_back(origin[2] - box->GetDZ());
838 jbb.push_back(origin[2] + box->GetDZ());
839 j["bbox"] = jbb;
840 }
841 // std::cout << "Write Core json " << j.dump(1) << "\n";
842 return ret;
843}
844
846{
847 if (fGeoData) {
848 fGeoData->fDesc.SetVisLevel(vl);
850 }
851}
852
853void REveGeoTopNodeViz::GetIndicesFromBrowserStack(const std::vector<int> &stack, std::set<int> &res)
854{
855 TGeoNode *top = fGeoData->fDesc.GetApexNode();
856 TGeoIterator it(top->GetVolume());
857 std::vector<int> nodeStack;
858 int cnt = 0;
859 TGeoNode *node;
860
861 while ((node = it.Next())) {
862 int level = it.GetLevel();
863
864 bool accept = AcceptNode(it, false);
865
866 nodeStack.resize(level);
867 if (level > 0)
868 nodeStack[level - 1] = it.GetIndex(level);
869
870 bool inside = nodeStack.size() >= stack.size() && std::equal(stack.begin(), stack.end(), nodeStack.begin());
871 if (inside) {
872 res.insert(cnt);
873 } // rnr flags
874 if (accept) cnt++;
875 } // while it
876
877 printf("GetIndicesFromBrowserStack stack size %zu res size %zu\n", stack.size(), res.size());
878}
879
880void REveGeoTopNodeViz::VisibilityChanged(bool on, REveGeomDescription::ERnrFlags flag, const std::vector<int> &iStack)
881{
882 // function argument is full stack, we remove the apex path
883 size_t apexDepth = fGeoData->RefDescription().GetApexPath().size();
884 std::vector<int> stack(iStack.begin() + apexDepth, iStack.end());
885
886 // PrintStackPath(stack);
887
888 TGeoNode *top = fGeoData->fDesc.GetApexNode();
889 TGeoIterator it(top->GetVolume());
890 std::vector<int> nodeStack;
891 int cnt = 0;
892 TGeoNode *node;
893 while ((node = it.Next())) {
894
895 int level = it.GetLevel();
896 if (!AcceptNode(it))
897 continue;
898
899 nodeStack.resize(level);
900 if (level > 0)
901 nodeStack[level - 1] = it.GetIndex(level);
902
903 if (flag == REveGeomDescription::kRnrSelf) {
904 /*
905 printf("nODEcompare ======\n");
906 PrintStackPath(stack);
907 PrintStackPath(nodeStack);
908 */
909 if (nodeStack == stack) {
910 fNodes[cnt].visible = on;
911
912 break;
913 }
914 } else {
915 bool inside = nodeStack.size() >= stack.size() && std::equal(stack.begin(), stack.end(), nodeStack.begin());
916 if (inside) {
917 fNodes[cnt].visible = on;
918 }
919 } // rnr flags
920 cnt++;
921 } // while it
923}
ROOT::R::TRInterface & r
Definition Object.C:4
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 c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
char * ret
Definition Rotated.cxx:221
start
Definition Rotated.cxx:223
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
char Text_t
General string (char).
Definition RtypesCore.h:76
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char).
Definition RtypesCore.h:52
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
externTGeoManager * 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.
REveElement(const std::string &name="", const std::string &title="")
Default constructor.
REveRenderData * GetRenderData() const
REveGeoManagerHolder Exception-safe global variable holders.
Definition REveUtil.hxx:90
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)
std::shared_ptr< REveGeomHierarchy > fWebHierarchy
! web handle for hierarchy part
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
Write transformation Matrix to render data.
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.
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:138
Representation of single item in the geometry browser.
Definition RGeomData.hxx:88
void SetPhysicalVisibility(int physicalVis)
void SetLogicalVisibility(int logicalVis)
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
static Bool_t FromJSON(T *&obj, const char *json)
Definition TBufferJSON.h:85
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
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
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:43
Int_t GetNdaughters() const
Definition TGeoVolume.h:363
TGeoNode * GetNode(const char *name) const
get the pointer to a daughter node
TGeoShape * GetShape() const
Definition TGeoVolume.h:191
void InspectShape() const
Definition TGeoVolume.h:196
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:138
STL class.
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
externREveManager * gEve
unsigned int ElementId_t
Definition REveTypes.hxx:28
TMarker m
Definition textangle.C:8