Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveGeomData.hxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Author: Sergey Linev, 14.12.2018
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT7_REveGeomData
13 #define ROOT7_REveGeomData
14 
15 #include <ROOT/REveRenderData.hxx>
16 
17 #include <vector>
18 #include <string>
19 #include <functional>
20 #include <memory>
21 
22 class TGeoNode;
23 class TGeoManager;
24 class TGeoShape;
25 class TGeoMatrix;
26 class TGeoVolume;
27 
28 // do not use namespace to avoid too long JSON
29 
30 namespace ROOT {
31 namespace Experimental {
32 
33 class REveRenderData;
34 class RGeomBrowserIter;
35 
36 /** Base description of geometry node, required only to build hierarchy */
37 
38 class REveGeomNodeBase {
39 public:
40  int id{0}; ///< node id, index in array
41  std::string name; ///< node name
42  std::vector<int> chlds; ///< list of childs id
43  int vis{0}; ///< visibility flag, 0 - off, 1 - only when level==0, 99 - always
44  bool nochlds{false}; ///< how far in hierarchy depth should be scanned
45 
46  std::string color; ///< rgb code without rgb() prefix
47  int sortid{0}; ///<! place in sorted array, to check cuts, or id of original node when used search structures
48 
49  REveGeomNodeBase(int _id = 0) : id(_id) {}
50 
51  bool IsVisible() const { return vis > 0; }
52 };
53 
54 /** Full node description including matrices and other attributes */
55 
56 class REveGeomNode : public REveGeomNodeBase {
57 public:
58  std::vector<float> matr; ///< matrix for the node, can have reduced number of elements
59  double vol{0}; ///<! volume estimation
60  int nfaces{0}; ///<! number of shape faces
61  int idshift{-1}; ///<! used to jump over then scan all geom hierarchy
62  bool useflag{false}; ///<! extra flag, used for selection
63  float opacity{1.}; ///<! opacity of the color
64 
65  REveGeomNode(int _id = 0) : REveGeomNodeBase(_id) {}
66 
67  /** True when there is shape and it can be displayed */
68  bool CanDisplay() const { return (vol > 0.) && (nfaces > 0); }
69 };
70 
71 /** Base class for render info block */
72 class RGeomRenderInfo {
73 public:
74  /// virtual destructor required for the I/O
75  virtual ~RGeomRenderInfo() = default;
76 };
77 
78 /** Render info with raw data */
79 class RGeomRawRenderInfo : public RGeomRenderInfo {
80 public:
81  // render data, equivalent of REveElement::WriteCoreJson
82  int sz[3]={0,0, 0}; ///< fRenderData: [SizeV(), SizeN(), SizeI()];
83  std::vector<unsigned char> raw; ///< raw shape data with render information, JSON_base64
84  virtual ~RGeomRawRenderInfo() = default;
85 };
86 
87 /** Render info with shape itself - client can produce shape better */
88 class RGeomShapeRenderInfo : public RGeomRenderInfo {
89 public:
90  TGeoShape *shape{nullptr}; ///< original shape - can be much less than binary data
91  virtual ~RGeomShapeRenderInfo() = default;
92 };
93 
94 
95 /** REveGeomVisible contains description of visible node
96  * It is path to the node plus reference to shape rendering data */
97 
98 class REveGeomVisible {
99 public:
100  int nodeid{0}; ///< selected node id,
101  int seqid{0}; ///< sequence id, used for merging later
102  std::vector<int> stack; ///< path to the node, index in list of childs
103  std::string color; ///< color in rgb format
104  double opacity{1}; ///< opacity
105  RGeomRenderInfo *ri{nullptr}; ///< render information for the shape, can be same for different nodes
106 
107  REveGeomVisible() = default;
108  REveGeomVisible(int _nodeid, int _seqid, const std::vector<int> &_stack) : nodeid(_nodeid), seqid(_seqid), stack(_stack) {}
109 };
110 
111 
112 /** Configuration parameters which can be configured on the client
113  * Send as is to-from client */
114 
115 class REveGeomConfig {
116 public:
117  int vislevel{0}; ///< visible level
118  int maxnumnodes{0}; ///< maximal number of nodes
119  int maxnumfaces{0}; ///< maximal number of faces
120  bool showtop{false}; ///< show geometry top volume, off by default
121  int build_shapes{1}; ///< when shapes build on server 0 - never, 1 - TGeoComposite, 2 - plus non-cylindrical, 3 - all
122  int nsegm{0}; ///< number of segments for cylindrical shapes
123  std::string drawopt; ///< draw options for TGeoPainter
124 };
125 
126 
127 /** Object with full description for drawing geometry
128  * It includes list of visible items and list of nodes required to build them */
129 
130 class REveGeomDrawing {
131 public:
132  REveGeomConfig *cfg{nullptr}; ///< current configurations
133  int numnodes{0}; ///< total number of nodes in description
134  std::vector<REveGeomNode*> nodes; ///< all used nodes to display visible items and not known for client
135  std::vector<REveGeomVisible> visibles; ///< all visible items
136 };
137 
138 
139 /** Request object send from client for different operations */
140 class REveGeomRequest {
141 public:
142  std::string oper; ///< operation like HIGHL or HOVER
143  std::string path; ///< path parameter, used with HOVER
144  std::vector<int> stack; ///< stack parameter, used with HIGHL
145 };
146 
147 class REveGeomNodeInfo {
148 public:
149  std::string fullpath; ///< full path to node
150  std::string node_type; ///< node class name
151  std::string node_name; ///< node name
152  std::string shape_type; ///< shape type (if any)
153  std::string shape_name; ///< shape class name (if any)
154 
155  RGeomRenderInfo *ri{nullptr}; ///< rendering information (if applicable)
156 };
157 
158 using REveGeomScanFunc_t = std::function<bool(REveGeomNode &, std::vector<int> &, bool, int)>;
159 
160 
161 class REveGeomDescription {
162 
163  friend class RGeomBrowserIter;
164 
165  class ShapeDescr {
166  public:
167  int id{0}; ///<! sequential id
168  TGeoShape *fShape{nullptr}; ///<! original shape
169  int nfaces{0}; ///<! number of faces in render data
170  RGeomRawRenderInfo fRawInfo; ///<! raw render info
171  RGeomShapeRenderInfo fShapeInfo; ///<! shape itself as info
172  ShapeDescr(TGeoShape *s) : fShape(s) {}
173 
174  bool has_shape() const { return nfaces == 1; }
175  bool has_raw() const { return nfaces > 1; }
176 
177  /// Provide render info for visible item
178  RGeomRenderInfo *rndr_info()
179  {
180  if (has_shape()) return &fShapeInfo;
181  if (has_raw()) return &fRawInfo;
182  return nullptr;
183  }
184 
185  void reset()
186  {
187  nfaces = 0;
188  fShapeInfo.shape = nullptr;
189  fRawInfo.raw.clear();
190  }
191  };
192 
193  std::vector<TGeoNode *> fNodes; ///<! flat list of all nodes
194  std::vector<REveGeomNode> fDesc; ///< converted description, send to client
195 
196  std::vector<int> fSortMap; ///<! nodes in order large -> smaller volume
197  std::vector<ShapeDescr> fShapes; ///<! shapes with created descriptions
198 
199  std::string fDrawJson; ///<! JSON with main nodes drawn by client
200  int fDrawIdCut{0}; ///<! sortid used for selection of most-significant nodes
201  int fActualLevel{0}; ///<! level can be reduced when selecting nodes
202  bool fPreferredOffline{false}; ///<! indicates that full description should be provided to client
203  int fJsonComp{0}; ///<! default JSON compression
204 
205  REveGeomConfig fCfg; ///<! configuration parameter editable from GUI
206 
207  void PackMatrix(std::vector<float> &arr, TGeoMatrix *matr);
208 
209  int MarkVisible(bool on_screen = false);
210 
211  void ProduceIdShifts();
212 
213  int ScanNodes(bool only_visible, int maxlvl, REveGeomScanFunc_t func);
214 
215  void ResetRndrInfos();
216 
217  ShapeDescr &FindShapeDescr(TGeoShape *shape);
218 
219  ShapeDescr &MakeShapeDescr(TGeoShape *shape);
220 
221  void CopyMaterialProperties(TGeoVolume *vol, REveGeomNode &node);
222 
223  void CollectNodes(REveGeomDrawing &drawing);
224 
225  std::string MakeDrawingJson(REveGeomDrawing &drawing, bool has_shapes = false);
226 
227 public:
228  REveGeomDescription() = default;
229 
230  void Build(TGeoManager *mgr, const std::string &volname = "");
231 
232  /** Number of unique nodes in the geometry */
233  int GetNumNodes() const { return fDesc.size(); }
234 
235  bool IsBuild() const { return GetNumNodes() > 0; }
236 
237  /** Set maximal number of nodes which should be selected for drawing */
238  void SetMaxVisNodes(int cnt) { fCfg.maxnumnodes = cnt; }
239 
240  /** Returns maximal visible number of nodes, ignored when non-positive */
241  int GetMaxVisNodes() const { return fCfg.maxnumnodes; }
242 
243  /** Set maximal number of faces which should be selected for drawing */
244  void SetMaxVisFaces(int cnt) { fCfg.maxnumfaces = cnt; }
245 
246  /** Returns maximal visible number of faces, ignored when non-positive */
247  int GetMaxVisFaces() const { return fCfg.maxnumfaces; }
248 
249  /** Set maximal visible level */
250  void SetVisLevel(int lvl = 3) { fCfg.vislevel = lvl; }
251 
252  /** Returns maximal visible level */
253  int GetVisLevel() const { return fCfg.vislevel; }
254 
255  /** Set preference of offline operations.
256  * Server provides more info to client from the begin on to avoid communication */
257  void SetPreferredOffline(bool on) { fPreferredOffline = on; }
258 
259  /** Is offline operations preferred.
260  * After get full description, client can do most operations without extra requests */
261  bool IsPreferredOffline() const { return fPreferredOffline; }
262 
263  bool CollectVisibles();
264 
265  bool IsPrincipalEndNode(int nodeid);
266 
267  std::string ProcessBrowserRequest(const std::string &req = "");
268 
269  bool HasDrawData() const { return (fDrawJson.length() > 0) && (fDrawIdCut > 0); }
270  const std::string &GetDrawJson() const { return fDrawJson; }
271  void ClearDrawData();
272 
273  int SearchVisibles(const std::string &find, std::string &hjson, std::string &json);
274 
275  int FindNodeId(const std::vector<int> &stack);
276 
277  std::string ProduceModifyReply(int nodeid);
278 
279  std::vector<int> MakeStackByIds(const std::vector<int> &ids);
280 
281  std::vector<int> MakeIdsByStack(const std::vector<int> &stack);
282 
283  std::vector<int> MakeStackByPath(const std::string &path);
284 
285  std::string MakePathByStack(const std::vector<int> &stack);
286 
287  bool ProduceDrawingFor(int nodeid, std::string &json, bool check_volume = false);
288 
289  bool ChangeNodeVisibility(int nodeid, bool selected);
290 
291  /** Set number of segments for cylindrical shapes, if 0 - default value will be used */
292  void SetNSegments(int n = 0) { fCfg.nsegm = n; }
293  /** Return of segments for cylindrical shapes, if 0 - default value will be used */
294  int GetNSegments() const { return fCfg.nsegm; }
295 
296  /** Set JSON compression level for data transfer */
297  void SetJsonComp(int comp = 0) { fJsonComp = comp; }
298  /** Returns JSON compression level for data transfer */
299  int GetJsonComp() const { return fJsonComp; }
300 
301  /** Set draw options as string for JSROOT TGeoPainter */
302  void SetDrawOptions(const std::string &opt = "") { fCfg.drawopt = opt; }
303  /** Returns draw options, used for JSROOT TGeoPainter */
304  std::string GetDrawOptions() const { return fCfg.drawopt; }
305 
306  /** Instruct to build binary 3D model already on the server (true) or send TGeoShape as is to client, which can build model itself */
307  void SetBuildShapes(int lvl = 1) { fCfg.build_shapes = lvl; }
308  /** Returns true if binary 3D model build already by C++ server (default) */
309  int IsBuildShapes() const { return fCfg.build_shapes; }
310 
311  bool ChangeConfiguration(const std::string &json);
312 
313  std::unique_ptr<REveGeomNodeInfo> MakeNodeInfo(const std::string &path);
314 };
315 
316 
317 } // namespace Experimental
318 } // namespace ROOT
319 
320 #endif