14 #include <ROOT/RBrowserItem.hxx>
36 using namespace std::string_literals;
42 namespace Experimental {
45 class RGeomBrowserIter {
47 REveGeomDescription &fDesc;
52 std::vector<int> fStackParents;
53 std::vector<int> fStackChilds;
57 RGeomBrowserIter(REveGeomDescription &desc) : fDesc(desc) {}
59 const std::string &GetName()
const {
return fDesc.fDesc[fNodeId].name; }
61 bool IsValid()
const {
return fNodeId >= 0; }
63 int GetNodeId()
const {
return fNodeId; }
65 bool HasChilds()
const {
return (fNodeId < 0) ?
true : fDesc.fDesc[fNodeId].chlds.size() > 0; }
67 int NumChilds()
const {
return (fNodeId < 0) ? 1 : fDesc.fDesc[fNodeId].chlds.size(); }
77 auto &node = fDesc.fDesc[fNodeId];
78 if (node.chlds.size() == 0)
return false;
79 fStackParents.emplace_back(fParentId);
80 fStackChilds.emplace_back(fChild);
83 fNodeId = node.chlds[fChild];
89 if (fStackParents.size() == 0) {
93 fParentId = fStackParents.back();
94 fChild = fStackChilds.back();
96 fStackParents.pop_back();
97 fStackChilds.pop_back();
102 fNodeId = fDesc.fDesc[fParentId].chlds[fChild];
110 if ((fNodeId <= 0) || (fParentId < 0)) {
115 auto &prnt = fDesc.fDesc[fParentId];
116 if (++fChild >= prnt.chlds.size()) {
121 fNodeId = prnt.chlds[fChild];
130 fStackParents.clear();
131 fStackChilds.clear();
138 if (Enter())
return true;
140 if (Next())
return true;
143 if (Next())
return true;
151 bool Navigate(
const std::string &path)
153 size_t pos = path.find(
"/");
154 if (pos != 0)
return false;
158 while (++pos < path.length()) {
161 pos = path.find(
"/", last);
163 if (pos == std::string::npos) pos = path.length();
165 std::string folder = path.substr(last, pos-last);
167 if (!Enter())
return false;
172 find = (folder.compare(GetName()) == 0);
173 }
while (!find && Next());
175 if (!find)
return false;
182 std::vector<int> CurrentIds()
const
184 std::vector<int> res;
186 for (
unsigned n=1;n<fStackParents.size();++n)
187 res.emplace_back(fStackParents[n]);
188 if (fParentId >= 0) res.emplace_back(fParentId);
189 res.emplace_back(fNodeId);
207 void ROOT::Experimental::REveGeomDescription::PackMatrix(std::vector<float> &vect, TGeoMatrix *matr)
211 if (!matr || matr->IsIdentity()) {
215 auto trans = matr->GetTranslation();
216 auto scale = matr->GetScale();
217 auto rotate = matr->GetRotationMatrix();
219 bool is_translate = matr->IsA() == TGeoTranslation::Class(),
220 is_scale = matr->IsA() == TGeoScale::Class(),
221 is_rotate = matr->IsA() == TGeoRotation::Class();
223 if (!is_translate && !is_scale && !is_rotate) {
226 auto test = [](
double val,
double chk) {
return (val==chk) || (TMath::Abs(val-chk) < 1e-20); };
228 bool no_scale = test(scale[0],1) && test(scale[1],1) && test(scale[2],1);
229 bool no_trans = test(trans[0],0) && test(trans[1],0) && test(trans[2],0);
230 bool no_rotate = test(rotate[0],1) && test(rotate[1],0) && test(rotate[2],0) &&
231 test(rotate[3],0) && test(rotate[4],1) && test(rotate[5],0) &&
232 test(rotate[6],0) && test(rotate[7],0) && test(rotate[8],1);
234 if (no_scale && no_trans && no_rotate)
237 if (no_scale && no_trans && !no_rotate) {
239 }
else if (no_scale && !no_trans && no_rotate) {
241 }
else if (!no_scale && no_trans && no_rotate) {
265 for (
int n=0;n<9;++n)
271 vect[0] = rotate[0]; vect[4] = rotate[1]; vect[8] = rotate[2]; vect[12] = trans[0];
272 vect[1] = rotate[3]; vect[5] = rotate[4]; vect[9] = rotate[5]; vect[13] = trans[1];
273 vect[2] = rotate[6]; vect[6] = rotate[7]; vect[10] = rotate[8]; vect[14] = trans[2];
274 vect[3] = 0; vect[7] = 0; vect[11] = 0; vect[15] = 1;
281 void ROOT::Experimental::REveGeomDescription::Build(TGeoManager *mgr,
const std::string &volname)
291 auto topnode = mgr->GetTopNode();
292 if (!volname.empty()) {
293 auto vol = mgr->GetVolume(volname.c_str());
296 TGeoIterator next(mgr->GetTopVolume());
297 while ((node=next())) {
298 if (node->GetVolume() == vol)
break;
300 if (node) { topnode = node; printf(
"Find node with volume\n"); }
308 int maxnodes = mgr->GetMaxVisNodes();
310 SetNSegments(mgr->GetNsegments());
311 SetVisLevel(mgr->GetVisLevel());
312 SetMaxVisNodes(maxnodes);
313 SetMaxVisFaces( (maxnodes > 5000 ? 5000 : (maxnodes < 1000 ? 1000 : maxnodes)) * 100);
316 std::vector<int> numbers;
317 int offset = 1000000000;
320 TGeoNode *snode = topnode;
321 TGeoIterator iter(topnode->GetVolume());
324 if (snode->GetNumber() >= offset) {
327 numbers.emplace_back(snode->GetNumber());
328 snode->SetNumber(offset + fNodes.size());
329 fNodes.emplace_back(snode);
331 }
while ((snode = iter()) !=
nullptr);
333 fDesc.reserve(fNodes.size());
334 numbers.reserve(fNodes.size());
335 fSortMap.reserve(fNodes.size());
338 std::vector<REveGeomNode *> sortarr;
339 sortarr.reserve(fNodes.size());
343 for (
auto &node: fNodes) {
345 fDesc.emplace_back(node->GetNumber() - offset);
346 auto &desc = fDesc[cnt++];
348 sortarr.emplace_back(&desc);
350 desc.name = node->GetName();
352 auto shape =
dynamic_cast<TGeoBBox *
>(node->GetVolume()->GetShape());
354 desc.vol = shape->GetDX()*shape->GetDY()*shape->GetDZ();
358 CopyMaterialProperties(node->GetVolume(), desc);
360 auto chlds = node->GetNodes();
362 PackMatrix(desc.matr, node->GetMatrix());
365 for (
int n = 0; n <= chlds->GetLast(); ++n) {
366 auto chld =
dynamic_cast<TGeoNode *
> (chlds->At(n));
367 desc.chlds.emplace_back(chld->GetNumber()-offset);
373 for (
auto &node: fNodes)
374 node->SetNumber(numbers[cnt++]);
377 std::sort(sortarr.begin(), sortarr.end(), [](REveGeomNode *a, REveGeomNode * b) {
return a->vol > b->vol; });
380 for (
auto &elem: sortarr) {
381 fSortMap.emplace_back(elem->id);
382 elem->sortid = cnt++;
393 int ROOT::Experimental::REveGeomDescription::MarkVisible(
bool on_screen)
395 int res = 0, cnt = 0;
396 for (
auto &node: fNodes) {
397 auto &desc = fDesc[cnt++];
399 desc.nochlds =
false;
402 if (node->IsOnScreen())
405 auto vol = node->GetVolume();
407 if (vol->IsVisible() && !vol->TestAttBit(TGeoAtt::kVisNone))
410 if (!node->IsVisDaughters())
413 if ((desc.vis > 0) && (desc.chlds.size() > 0) && !desc.nochlds)
417 if (desc.IsVisible() && desc.CanDisplay()) res++;
426 void ROOT::Experimental::REveGeomDescription::ProduceIdShifts()
428 for (
auto &node : fDesc)
431 using ScanFunc_t = std::function<int(REveGeomNode &)>;
433 ScanFunc_t scan_func = [&,
this](REveGeomNode &node) {
434 if (node.idshift < 0) {
436 for(
auto id : node.chlds)
437 node.idshift += scan_func(fDesc[
id]);
440 return node.idshift + 1;
443 if (fDesc.size() > 0)
450 int ROOT::Experimental::REveGeomDescription::ScanNodes(
bool only_visible,
int maxlvl, REveGeomScanFunc_t func)
452 std::vector<int> stack;
456 using ScanFunc_t = std::function<int(int, int)>;
458 ScanFunc_t scan_func = [&,
this](
int nodeid,
int lvl) {
459 auto &desc = fDesc[nodeid];
462 if (desc.nochlds && (lvl > 0)) lvl = 0;
465 bool is_visible = (lvl >= 0) && (desc.vis > lvl) && desc.CanDisplay();
467 if (is_visible || !only_visible)
468 if (func(desc, stack, is_visible, counter))
473 if ((desc.chlds.size() > 0) && ((lvl > 0) || !only_visible)) {
474 auto pos = stack.size();
475 stack.emplace_back(0);
476 for (
unsigned k = 0; k < desc.chlds.size(); ++k) {
478 res += scan_func(desc.chlds[k], lvl - 1);
482 counter += desc.idshift;
488 if (!maxlvl && (GetVisLevel() > 0)) maxlvl = GetVisLevel();
489 if (!maxlvl) maxlvl = 4;
490 if (maxlvl > 97) maxlvl = 97;
492 return scan_func(0, maxlvl);
498 void ROOT::Experimental::REveGeomDescription::CollectNodes(REveGeomDrawing &drawing)
501 for (
auto &node : fDesc)
502 node.useflag =
false;
506 drawing.numnodes = fDesc.size();
508 for (
auto &item : drawing.visibles) {
510 for (
auto &chindx : item.stack) {
511 auto &node = fDesc[nodeid];
514 drawing.nodes.emplace_back(&node);
516 if (chindx >= (
int)node.chlds.size())
518 nodeid = node.chlds[chindx];
521 auto &node = fDesc[nodeid];
524 drawing.nodes.emplace_back(&node);
528 printf(
"SELECT NODES %d\n", (
int) drawing.nodes.size());
535 std::string ROOT::Experimental::REveGeomDescription::ProcessBrowserRequest(
const std::string &msg)
539 auto request = TBufferJSON::FromJSON<RBrowserRequest>(msg);
542 request = std::make_unique<RBrowserRequest>();
545 request->number = 100;
551 if ((request->path.compare(
"/") == 0) && (request->first == 0) && (GetNumNodes() < (IsPreferredOffline() ? 1000000 : 1000))) {
553 std::vector<REveGeomNodeBase *> vect(fDesc.size(),
nullptr);
556 for (
auto &item : fDesc)
559 res =
"DESCR:"s + TBufferJSON::ToJSON(&vect,GetJsonComp()).Data();
562 RGeomBrowserIter iter(*
this);
564 while (iter.NextNode())
566 printf(
"Total number of valid nodes %d\n", nelements);
569 std::vector<RBrowserItem> temp_nodes;
570 bool toplevel = (request->path.compare(
"/") == 0);
574 reply.path = request->path;
575 reply.first = request->first;
577 RGeomBrowserIter iter(*
this);
578 if (iter.Navigate(request->path)) {
580 reply.nchilds = iter.NumChilds();
584 while ((request->first > 0) && iter.Next()) {
588 while (iter.IsValid() && (request->number > 0)) {
589 temp_nodes.emplace_back(iter.GetName(), iter.NumChilds());
590 if (toplevel) temp_nodes.back().SetExpanded(
true);
592 if (!iter.Next())
break;
597 for (
auto &n : temp_nodes)
598 reply.nodes.emplace_back(&n);
600 res =
"BREPL:"s + TBufferJSON::ToJSON(&reply, GetJsonComp()).Data();
610 ROOT::Experimental::REveGeomDescription::ShapeDescr &ROOT::Experimental::REveGeomDescription::FindShapeDescr(TGeoShape *shape)
612 for (
auto &descr : fShapes)
613 if (descr.fShape == shape)
616 fShapes.emplace_back(shape);
617 auto &elem = fShapes.back();
618 elem.id = fShapes.size() - 1;
625 ROOT::Experimental::REveGeomDescription::ShapeDescr &
626 ROOT::Experimental::REveGeomDescription::MakeShapeDescr(TGeoShape *shape)
628 auto &elem = FindShapeDescr(shape);
630 if (elem.nfaces == 0) {
632 TGeoCompositeShape *comp =
nullptr;
635 if (shape->IsComposite()) {
636 comp =
dynamic_cast<TGeoCompositeShape *
>(shape);
639 }
else if (!shape->IsCylType()) {
644 if (IsBuildShapes() < boundary) {
646 elem.fShapeInfo.shape = shape;
649 auto poly = std::make_unique<REveGeoPolyShape>();
652 poly->BuildFromComposite(comp, GetNSegments());
654 poly->BuildFromShape(shape, GetNSegments());
659 poly->FillRenderData(rd);
661 elem.nfaces = poly->GetNumFaces();
663 elem.fRawInfo.raw.resize(rd.GetBinarySize());
664 rd.Write( reinterpret_cast<char *>(elem.fRawInfo.raw.data()), elem.fRawInfo.raw.size() );
665 elem.fRawInfo.sz[0] = rd.SizeV();
666 elem.fRawInfo.sz[1] = rd.SizeN();
667 elem.fRawInfo.sz[2] = rd.SizeI();
678 void ROOT::Experimental::REveGeomDescription::CopyMaterialProperties(TGeoVolume *volume, REveGeomNode &node)
682 TColor *col{
nullptr};
684 if ((volume->GetFillColor() > 1) && (volume->GetLineColor() == 1))
685 col = gROOT->GetColor(volume->GetFillColor());
686 else if (volume->GetLineColor() >= 0)
687 col = gROOT->GetColor(volume->GetLineColor());
689 if (volume->GetMedium() && (volume->GetMedium() != TGeoVolume::DummyMedium()) && volume->GetMedium()->GetMaterial()) {
690 auto material = volume->GetMedium()->GetMaterial();
692 auto fillstyle = material->GetFillStyle();
693 if ((fillstyle>=3000) && (fillstyle<=3100)) node.opacity = (3100 - fillstyle) / 100.;
694 if (!col) col = gROOT->GetColor(material->GetFillColor());
698 node.color = std::to_string((
int)(col->GetRed()*255)) +
"," +
699 std::to_string((
int)(col->GetGreen()*255)) +
"," +
700 std::to_string((
int)(col->GetBlue()*255));
701 if (node.opacity == 1.)
702 node.opacity = col->GetAlpha();
711 void ROOT::Experimental::REveGeomDescription::ResetRndrInfos()
713 for (
auto &s: fShapes)
721 bool ROOT::Experimental::REveGeomDescription::CollectVisibles()
723 std::vector<int> viscnt(fDesc.size(), 0);
725 int level = GetVisLevel();
728 int numnodes = ScanNodes(
true, level, [&viscnt](REveGeomNode &node, std::vector<int> &,
bool,
int) {
733 if (GetMaxVisNodes() > 0) {
734 while ((numnodes > GetMaxVisNodes()) && (level > 1)) {
736 viscnt.assign(viscnt.size(), 0);
737 numnodes = ScanNodes(
true, level, [&viscnt](REveGeomNode &node, std::vector<int> &,
bool,
int) {
744 fActualLevel = level;
747 int totalnumfaces{0}, totalnumnodes{0};
753 for (
auto &sid: fSortMap) {
755 auto &desc = fDesc[sid];
757 if ((viscnt[sid] <= 0) || (desc.vol <= 0))
continue;
759 auto shape = fNodes[sid]->GetVolume()->GetShape();
760 if (!shape)
continue;
763 auto &shape_descr = MakeShapeDescr(shape);
766 if (shape_descr.nfaces <= 0) {
767 R__ERROR_HERE(
"webeve") <<
"No faces for the shape " << shape->GetName() <<
" class " << shape->ClassName();
772 totalnumfaces += shape_descr.nfaces * viscnt[sid];
773 if ((GetMaxVisFaces() > 0) && (totalnumfaces > GetMaxVisFaces()))
break;
776 totalnumnodes += viscnt[sid];
777 if ((GetMaxVisNodes() > 0) && (totalnumnodes > GetMaxVisNodes()))
break;
785 REveGeomDrawing drawing;
787 bool has_shape =
false;
789 ScanNodes(
true, level, [&,
this](REveGeomNode &node, std::vector<int> &stack,
bool,
int seqid) {
790 if (node.sortid < fDrawIdCut) {
791 drawing.visibles.emplace_back(node.id, seqid, stack);
793 auto &item = drawing.visibles.back();
794 item.color = node.color;
795 item.opacity = node.opacity;
797 auto volume = fNodes[node.id]->GetVolume();
799 auto &sd = MakeShapeDescr(volume->GetShape());
801 item.ri = sd.rndr_info();
802 if (sd.has_shape()) has_shape =
true;
807 CollectNodes(drawing);
809 fDrawJson =
"GDRAW:"s + MakeDrawingJson(drawing, has_shape);
817 void ROOT::Experimental::REveGeomDescription::ClearDrawData()
826 bool ROOT::Experimental::REveGeomDescription::IsPrincipalEndNode(
int nodeid)
828 if ((nodeid < 0) || (nodeid >= (
int)fDesc.size()))
831 auto &desc = fDesc[nodeid];
833 return (desc.sortid < fDrawIdCut) && desc.IsVisible() && desc.CanDisplay() && (desc.chlds.size()==0);
842 int ROOT::Experimental::REveGeomDescription::SearchVisibles(
const std::string &find, std::string &hjson, std::string &json)
848 hjson =
"FOUND:RESET";
852 std::vector<int> nodescnt(fDesc.size(), 0), viscnt(fDesc.size(), 0);
856 auto match_func = [&find](REveGeomNode &node) {
857 return (node.vol > 0) && (node.name.compare(0, find.length(), find) == 0);
861 ScanNodes(
false, 0, [&nodescnt,&viscnt,&match_func,&nmatches](REveGeomNode &node, std::vector<int> &,
bool is_vis,
int) {
863 if (match_func(node)) {
866 if (is_vis) viscnt[node.id]++;
877 if (nmatches > 10 * GetMaxVisNodes()) {
878 hjson =
"FOUND:Too many " + std::to_string(nmatches);
884 int totalnumfaces{0}, totalnumnodes{0}, scnt{0};
885 bool send_rawdata{
true};
888 for (
auto &sid: fSortMap) {
889 if (scnt++ < fDrawIdCut)
continue;
891 if (viscnt[sid] == 0)
continue;
893 auto &desc = fDesc[sid];
894 if ((viscnt[sid] <= 0) && (desc.vol <= 0))
continue;
896 auto shape = fNodes[sid]->GetVolume()->GetShape();
897 if (!shape)
continue;
900 auto &shape_descr = MakeShapeDescr(shape);
903 if (shape_descr.nfaces <= 0) {
904 R__ERROR_HERE(
"webeve") <<
"No faces for the shape " << shape->GetName() <<
" class " << shape->ClassName();
909 totalnumfaces += shape_descr.nfaces * viscnt[sid];
910 if ((GetMaxVisFaces() > 0) && (totalnumfaces > GetMaxVisFaces())) { send_rawdata =
false;
break; }
913 totalnumnodes += viscnt[sid];
914 if ((GetMaxVisNodes() > 0) && (totalnumnodes > GetMaxVisNodes())) { send_rawdata =
false;
break; }
924 std::vector<REveGeomNodeBase> found_desc;
925 std::vector<int> found_map(fDesc.size(), -1);
929 found_desc.emplace_back(0);
930 found_desc[0].vis = fDesc[0].vis;
931 found_desc[0].name = fDesc[0].name;
932 found_desc[0].color = fDesc[0].color;
937 REveGeomDrawing drawing;
938 bool has_shape =
true;
940 ScanNodes(
false, 0, [&,
this](REveGeomNode &node, std::vector<int> &stack,
bool is_vis,
int seqid) {
942 if (!match_func(node))
947 for (
auto &s : stack) {
948 int chldid = fDesc[prntid].chlds[s];
949 if (found_map[chldid] <= 0) {
950 int newid = found_desc.size();
951 found_desc.emplace_back(newid);
952 found_map[chldid] = newid;
954 found_desc.back().vis = fDesc[chldid].vis;
955 found_desc.back().name = fDesc[chldid].name;
956 found_desc.back().color = fDesc[chldid].color;
959 auto pid = found_map[prntid];
960 auto cid = found_map[chldid];
963 auto &pchlds = found_desc[pid].chlds;
964 if (std::find(pchlds.begin(), pchlds.end(), cid) == pchlds.end())
965 pchlds.emplace_back(cid);
971 if (!is_vis)
return true;
973 drawing.visibles.emplace_back(node.id, seqid, stack);
977 if (!send_rawdata || (node.sortid < fDrawIdCut)) {
982 auto &item = drawing.visibles.back();
983 auto volume = fNodes[node.id]->GetVolume();
985 item.color = node.color;
986 item.opacity = node.opacity;
988 auto &sd = MakeShapeDescr(volume->GetShape());
990 item.ri = sd.rndr_info();
991 if (sd.has_shape()) has_shape =
true;
995 hjson =
"FESCR:"s + TBufferJSON::ToJSON(&found_desc, GetJsonComp()).Data();
997 CollectNodes(drawing);
999 json =
"FDRAW:"s + MakeDrawingJson(drawing, has_shape);
1007 int ROOT::Experimental::REveGeomDescription::FindNodeId(
const std::vector<int> &stack)
1011 for (
auto &chindx: stack) {
1012 auto &node = fDesc[nodeid];
1013 if (chindx >= (
int) node.chlds.size())
return -1;
1014 nodeid = node.chlds[chindx];
1023 std::vector<int> ROOT::Experimental::REveGeomDescription::MakeStackByIds(
const std::vector<int> &ids)
1025 std::vector<int> stack;
1028 printf(
"Wrong first id\n");
1034 for (
unsigned k = 1; k < ids.size(); ++k) {
1036 int prntid = nodeid;
1039 if (nodeid >= (
int) fDesc.size()) {
1040 printf(
"Wrong node id %d\n", nodeid);
1044 auto &chlds = fDesc[prntid].chlds;
1045 auto pos = std::find(chlds.begin(), chlds.end(), nodeid);
1046 if (pos == chlds.end()) {
1047 printf(
"Wrong id %d not a child of %d - fail to find stack num %d\n", nodeid, prntid, (
int) chlds.size());
1052 stack.emplace_back(std::distance(chlds.begin(), pos));
1062 std::vector<int> ROOT::Experimental::REveGeomDescription::MakeStackByPath(
const std::string &path)
1064 std::vector<int> res;
1066 RGeomBrowserIter iter(*
this);
1068 if (iter.Navigate(path)) {
1074 res = MakeStackByIds(iter.CurrentIds());
1084 std::vector<int> ROOT::Experimental::REveGeomDescription::MakeIdsByStack(
const std::vector<int> &stack)
1086 std::vector<int> ids;
1088 ids.emplace_back(0);
1090 bool failure =
false;
1092 for (
auto s : stack) {
1093 auto &chlds = fDesc[nodeid].chlds;
1094 if (s >= (
int) chlds.size()) { failure =
true;
break; }
1096 ids.emplace_back(chlds[s]);
1102 printf(
"Fail to convert stack into list of nodes\n");
1112 std::string ROOT::Experimental::REveGeomDescription::MakePathByStack(
const std::vector<int> &stack)
1116 auto ids = MakeIdsByStack(stack);
1117 if (ids.size() > 0) {
1119 for (
auto &
id : ids) {
1120 path.append(fDesc[
id].name);
1133 std::string ROOT::Experimental::REveGeomDescription::ProduceModifyReply(
int nodeid)
1135 std::vector<REveGeomNodeBase *> nodes;
1136 auto vol = fNodes[nodeid]->GetVolume();
1142 for (
auto &desc : fDesc)
1143 if (fNodes[
id++]->GetVolume() == vol)
1144 nodes.emplace_back(&desc);
1146 return "MODIF:"s + TBufferJSON::ToJSON(&nodes, GetJsonComp()).Data();
1155 bool ROOT::Experimental::REveGeomDescription::ProduceDrawingFor(
int nodeid, std::string &json,
bool check_volume)
1159 TGeoVolume *vol = (nodeid < 0) ?
nullptr : fNodes[nodeid]->GetVolume();
1161 if (!vol || !vol->GetShape()) {
1166 REveGeomDrawing drawing;
1168 ScanNodes(
true, 0, [&,
this](REveGeomNode &node, std::vector<int> &stack,
bool,
int seq_id) {
1172 if (fNodes[node.id]->GetVolume() != vol)
return true;
1174 if (node.id != nodeid)
return true;
1177 drawing.visibles.emplace_back(node.id, seq_id, stack);
1179 auto &item = drawing.visibles.back();
1181 item.color = node.color;
1182 item.opacity = node.opacity;
1187 if (drawing.visibles.size()==0) {
1194 bool has_shape =
false, has_raw =
false;
1196 auto &sd = MakeShapeDescr(vol->GetShape());
1199 for (
auto &item : drawing.visibles) {
1200 item.ri = sd.rndr_info();
1201 if (sd.has_shape()) has_shape =
true;
1202 if (sd.has_raw()) has_raw =
true;
1205 CollectNodes(drawing);
1207 json.append(MakeDrawingJson(drawing, has_shape));
1209 return has_raw || has_shape;
1218 std::string ROOT::Experimental::REveGeomDescription::MakeDrawingJson(REveGeomDrawing &drawing,
bool has_shapes)
1220 int comp = GetJsonComp();
1222 if (!has_shapes || (comp < TBufferJSON::kSkipTypeInfo))
1223 return TBufferJSON::ToJSON(&drawing, comp).Data();
1225 comp = comp % TBufferJSON::kSkipTypeInfo;
1228 json.SetCompact(comp);
1229 json.SetSkipClassInfo(TClass::GetClass<REveGeomDrawing>());
1230 json.SetSkipClassInfo(TClass::GetClass<REveGeomNode>());
1231 json.SetSkipClassInfo(TClass::GetClass<REveGeomVisible>());
1232 json.SetSkipClassInfo(TClass::GetClass<RGeomShapeRenderInfo>());
1233 json.SetSkipClassInfo(TClass::GetClass<RGeomRawRenderInfo>());
1235 return json.StoreObject(&drawing, TClass::GetClass<REveGeomDrawing>()).Data();
1242 bool ROOT::Experimental::REveGeomDescription::ChangeNodeVisibility(
int nodeid,
bool selected)
1244 auto &dnode = fDesc[nodeid];
1246 auto vol = fNodes[nodeid]->GetVolume();
1249 if (vol->IsVisible() == selected)
1252 dnode.vis = selected ? 99 : 0;
1253 vol->SetVisibility(selected);
1254 if (dnode.chlds.size() > 0) {
1255 if (selected) dnode.vis = 1;
1256 vol->SetVisDaughters(selected);
1260 for (
auto &desc: fDesc)
1261 if (fNodes[
id++]->GetVolume() == vol)
1262 desc.vis = dnode.vis;
1273 std::unique_ptr<ROOT::Experimental::REveGeomNodeInfo> ROOT::Experimental::REveGeomDescription::MakeNodeInfo(
const std::string &path)
1275 std::unique_ptr<REveGeomNodeInfo> res;
1277 RGeomBrowserIter iter(*
this);
1279 if (iter.Navigate(path)) {
1281 auto node = fNodes[iter.GetNodeId()];
1283 auto &desc = fDesc[iter.GetNodeId()];
1285 res = std::make_unique<REveGeomNodeInfo>();
1287 res->fullpath = path;
1288 res->node_name = node->GetName();
1289 res->node_type = node->ClassName();
1291 TGeoShape *shape = node->GetVolume() ? node->GetVolume()->GetShape() :
nullptr;
1294 res->shape_name = shape->GetName();
1295 res->shape_type = shape->ClassName();
1298 if (shape && desc.CanDisplay()) {
1300 auto &shape_descr = MakeShapeDescr(shape);
1302 res->ri = shape_descr.rndr_info();
1313 bool ROOT::Experimental::REveGeomDescription::ChangeConfiguration(
const std::string &json)
1315 auto cfg = TBufferJSON::FromJSON<REveGeomConfig>(json);
1316 if (!cfg)
return false;
1318 auto json1 = TBufferJSON::ToJSON(cfg.get());
1319 auto json2 = TBufferJSON::ToJSON(&fCfg);