Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:22:34

0001 // Author: Sergey Linev, 14.12.2018
0002 
0003 /*************************************************************************
0004  * Copyright (C) 1995-2023, Rene Brun and Fons Rademakers.               *
0005  * All rights reserved.                                                  *
0006  *                                                                       *
0007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0009  *************************************************************************/
0010 
0011 #ifndef ROOT7_RGeomData
0012 #define ROOT7_RGeomData
0013 
0014 #include <vector>
0015 #include <string>
0016 #include <functional>
0017 #include <memory>
0018 
0019 #include <ROOT/Browsable/RItem.hxx>
0020 
0021 #include "TVirtualMutex.h"
0022 
0023 class TGeoNode;
0024 class TGeoManager;
0025 class TGeoShape;
0026 class TGeoMatrix;
0027 class TGeoVolume;
0028 
0029 // do not use namespace to avoid too long JSON
0030 
0031 namespace ROOT {
0032 
0033 class RGeomBrowserIter;
0034 
0035 namespace Experimental {
0036 class RLogChannel;
0037 } // namespace Experimental
0038 
0039 /// Log channel for Geomviewer diagnostics.
0040 Experimental::RLogChannel &RGeomLog();
0041 
0042 /** Base description of geometry node, required only to build hierarchy */
0043 
0044 class RGeomNodeBase {
0045 public:
0046    int id{0};               ///< node id, index in array
0047    std::string name;        ///< node name
0048    std::vector<int> chlds;  ///< list of childs id
0049    int vis{0};              ///< visibility flag, 0 - off, 1 - only when level==0, 99 - always
0050    bool nochlds{false};     ///< how far in hierarchy depth should be scanned
0051 
0052    std::string color;       ///< rgb code in hex format
0053    std::string material;    ///< name of the material
0054    int sortid{0};           ///<! place in sorted array, to check cuts, or id of original node when used search structures
0055 
0056    RGeomNodeBase(int _id = 0) : id(_id) {}
0057 
0058    bool IsVisible() const { return vis > 0; }
0059 
0060    /** Returns argument for regexp */
0061    const char *GetArg(int kind)
0062    {
0063       if (kind == 1) return color.c_str();
0064       if (kind == 2) return material.c_str();
0065       return name.c_str();
0066    }
0067 };
0068 
0069 /** Full node description including matrices and other attributes */
0070 
0071 class RGeomNode : public RGeomNodeBase  {
0072 public:
0073    std::vector<float> matr; ///< matrix for the node, can have reduced number of elements
0074    double vol{0};           ///<! volume estimation
0075    int nfaces{0};           ///<! number of shape faces
0076    int idshift{-1};         ///<! used to jump over then scan all geom hierarchy
0077    bool useflag{false};     ///<! extra flag, used for selection
0078    float opacity{1.};       ///<! opacity of the color
0079 
0080    RGeomNode(int _id = 0) : RGeomNodeBase(_id) {}
0081 
0082    /** True when there is shape and it can be displayed */
0083    bool CanDisplay() const { return (vol > 0.) && (nfaces > 0); }
0084 };
0085 
0086 /** \class RGeoItem
0087 \ingroup rbrowser
0088 \brief Representation of single item in the geometry browser
0089 */
0090 
0091 class RGeoItem : public Browsable::RItem {
0092 
0093 protected:
0094    // this is part for browser, visible for I/O
0095    int id{0};              ///< node id
0096    std::string color;      ///< color
0097    std::string material;   ///< material
0098    int vis{0};             ///< visibility of logical node
0099    int pvis{0};            ///< visibility of physical node
0100    bool top{false};        ///< indicates if node selected as top
0101 
0102 public:
0103 
0104    /** Default constructor */
0105    RGeoItem() = default;
0106 
0107    RGeoItem(const std::string &_name, int _nchilds, int _nodeid, const std::string &_color,
0108          const std::string &_material = "", int _vis = 0, int _pvis = 0) :
0109          Browsable::RItem(_name, _nchilds), id(_nodeid), color(_color), material(_material), vis(_vis), pvis(_pvis) {
0110    }
0111 
0112    // should be here, one needs virtual table for correct streaming of RRootBrowserReply
0113    ~RGeoItem() override = default;
0114 
0115    void SetTop(bool on = true) { top = on; }
0116 };
0117 
0118 
0119 /** Base class for render info block */
0120 class RGeomRenderInfo {
0121 public:
0122    /// virtual destructor required for the I/O
0123    virtual ~RGeomRenderInfo() = default;
0124 };
0125 
0126 /** Render info with raw data */
0127 class RGeomRawRenderInfo : public RGeomRenderInfo  {
0128 public:
0129    std::vector<unsigned char> raw;  ///< float vertices as raw data, JSON_base64
0130    std::vector<int> idx;            ///< vertex indexes, always triangles
0131    ~RGeomRawRenderInfo() override = default;
0132 };
0133 
0134 /** Render info with shape itself - client can produce shape better */
0135 class RGeomShapeRenderInfo : public RGeomRenderInfo  {
0136 public:
0137    TGeoShape *shape{nullptr}; ///< original shape - can be much less than binary data
0138    ~RGeomShapeRenderInfo() override = default;
0139 };
0140 
0141 
0142 /** RGeomVisible contains description of visible node
0143  * It is path to the node plus reference to shape rendering data */
0144 
0145 class RGeomVisible {
0146 public:
0147    int nodeid{0};                    ///< selected node id,
0148    int seqid{0};                     ///< sequence id, used for merging later
0149    std::vector<int> stack;           ///< path to the node, index in list of childs
0150    std::string color;                ///< color in rgb format
0151    double opacity{1};                ///< opacity
0152    RGeomRenderInfo *ri{nullptr};     ///< render information for the shape, can be same for different nodes
0153 
0154    RGeomVisible() = default;
0155    RGeomVisible(int _nodeid, int _seqid, const std::vector<int> &_stack) : nodeid(_nodeid), seqid(_seqid), stack(_stack) {}
0156 };
0157 
0158 
0159 /** Configuration parameters which can be configured on the client
0160  * Send as is to-from client */
0161 
0162 class RGeomConfig {
0163 public:
0164    int vislevel{0};                         ///< visible level
0165    int maxnumnodes{0};                      ///< maximal number of nodes
0166    int maxnumfaces{0};                      ///< maximal number of faces
0167    bool showtop{false};                     ///< show geometry top volume, off by default
0168    int build_shapes{1};                     ///< when shapes build on server  0 - never, 1 - TGeoComposite, 2 - plus non-cylindrical, 3 - all
0169    int nsegm{0};                            ///< number of segments for cylindrical shapes
0170    std::string drawopt;                     ///< draw options for TGeoPainter
0171 };
0172 
0173 
0174 /** Object with full description for drawing geometry
0175  * It includes list of visible items and list of nodes required to build them */
0176 
0177 class RGeomDrawing {
0178 public:
0179    RGeomConfig *cfg{nullptr};            ///< current configurations
0180    int numnodes{0};                      ///< total number of nodes in description
0181    std::vector<RGeomNode*> nodes;        ///< all used nodes to display visible items and not known for client
0182    std::vector<RGeomVisible> visibles;   ///< all visible items
0183 };
0184 
0185 
0186 /** Node information including rendering data */
0187 class RGeomNodeInfo {
0188 public:
0189    std::vector<std::string> path;  ///< full path to node
0190    std::string node_type;  ///< node class name
0191    std::string node_name;  ///< node name
0192    std::string shape_type; ///< shape type (if any)
0193    std::string shape_name; ///< shape class name (if any)
0194 
0195    RGeomRenderInfo *ri{nullptr};  ///< rendering information (if applicable)
0196 };
0197 
0198 /** Custom settings for physical Node visibility */
0199 class RGeomNodeVisibility {
0200 public:
0201    std::vector<int> stack;        ///< path to the node
0202    bool visible{false};           ///< visible flag
0203    RGeomNodeVisibility(const std::vector<int> &_stack, bool _visible) : stack(_stack), visible(_visible) {}
0204 };
0205 
0206 using RGeomScanFunc_t = std::function<bool(RGeomNode &, std::vector<int> &, bool, int)>;
0207 
0208 using RGeomSignalFunc_t = std::function<void(const std::string &)>;
0209 
0210 class RGeomDescription {
0211 
0212    friend class RGeomBrowserIter;
0213 
0214    class ShapeDescr {
0215    public:
0216       int id{0};                                   ///<! sequential id
0217       TGeoShape *fShape{nullptr};                  ///<! original shape
0218       int nfaces{0};                               ///<! number of faces in render data
0219       RGeomRawRenderInfo fRawInfo;                 ///<! raw render info
0220       RGeomShapeRenderInfo fShapeInfo;             ///<! shape itself as info
0221       ShapeDescr(TGeoShape *s) : fShape(s) {}
0222 
0223       bool has_shape() const { return nfaces == 1; }
0224       bool has_raw() const { return nfaces > 1; }
0225 
0226       /// Provide render info for visible item
0227       RGeomRenderInfo *rndr_info()
0228       {
0229          if (has_shape()) return &fShapeInfo;
0230          if (has_raw()) return &fRawInfo;
0231          return nullptr;
0232       }
0233 
0234       void reset()
0235       {
0236          nfaces = 0;
0237          fShapeInfo.shape = nullptr;
0238          fRawInfo.raw.clear();
0239       }
0240    };
0241 
0242    std::vector<TGeoNode *> fNodes;  ///<! flat list of all nodes
0243    std::vector<RGeomNode> fDesc;    ///<! converted description, send to client
0244    std::vector<RGeomNodeVisibility> fVisibility; ///<! custom visibility flags for physical nodes
0245 
0246    TGeoVolume *fDrawVolume{nullptr};///<! select volume independent from TGeoManager
0247    std::vector<int> fSelectedStack; ///<! selected branch of geometry by stack
0248 
0249    std::vector<int> fHighlightedStack; ///<! highlighted element by stack
0250    std::vector<int> fClickedStack;     ///<! clicked element by stack
0251 
0252    std::vector<int> fSortMap;       ///<! nodes in order large -> smaller volume
0253    std::vector<ShapeDescr> fShapes; ///<! shapes with created descriptions
0254 
0255    std::string fSearch;             ///<! search string in hierarchy
0256    std::string fSearchJson;         ///<! drawing json for search
0257    std::string fDrawJson;           ///<! JSON with main nodes drawn by client
0258    int fDrawIdCut{0};               ///<! sortid used for selection of most-significant nodes
0259    int fActualLevel{0};             ///<! level can be reduced when selecting nodes
0260    bool fPreferredOffline{false};   ///<! indicates that full description should be provided to client
0261    int fJsonComp{0};                ///<! default JSON compression
0262    std::string fActiveItemName;     ///<! name of item which should be activated in hierarchy
0263 
0264    RGeomConfig fCfg;                ///<! configuration parameter editable from GUI
0265 
0266    TVirtualMutex *fMutex{nullptr};  ///<! external mutex used to protect all data
0267 
0268    std::vector<std::pair<const void *, RGeomSignalFunc_t>> fSignals; ///<! registered signals
0269 
0270    void PackMatrix(std::vector<float> &arr, TGeoMatrix *matr);
0271 
0272    int MarkVisible(bool on_screen = false);
0273 
0274    void ProduceIdShifts();
0275 
0276    int ScanNodes(bool only_visible, int maxlvl, RGeomScanFunc_t func);
0277 
0278    void ResetRndrInfos();
0279 
0280    ShapeDescr &FindShapeDescr(TGeoShape *shape);
0281 
0282    ShapeDescr &MakeShapeDescr(TGeoShape *shape);
0283 
0284    int GetUsedNSegments(int min = 20);
0285 
0286    int CountShapeFaces(TGeoShape *shape);
0287 
0288    void CopyMaterialProperties(TGeoVolume *vol, RGeomNode &node);
0289 
0290    void CollectNodes(RGeomDrawing &drawing, bool all_nodes = false);
0291 
0292    std::string MakeDrawingJson(RGeomDrawing &drawing, bool has_shapes = false);
0293 
0294    void ClearDescription();
0295 
0296    void BuildDescription(TGeoNode *topnode, TGeoVolume *topvolume);
0297 
0298    TGeoVolume *GetVolume(int nodeid);
0299 
0300    int IsPhysNodeVisible(const std::vector<int> &stack);
0301 
0302 public:
0303    RGeomDescription() = default;
0304 
0305    void AddSignalHandler(const void *handler, RGeomSignalFunc_t func);
0306 
0307    void RemoveSignalHandler(const void *handler);
0308 
0309    void IssueSignal(const void *handler, const std::string &kind);
0310 
0311    /** Set mutex, it must be recursive one */
0312    void SetMutex(TVirtualMutex *mutex) { fMutex = mutex; }
0313    /** Return currently used mutex */
0314    TVirtualMutex *GetMutex() const { return fMutex; }
0315 
0316    /** Set maximal number of nodes which should be selected for drawing */
0317    void SetMaxVisNodes(int cnt) { TLockGuard lock(fMutex); fCfg.maxnumnodes = cnt; }
0318    /** Returns maximal visible number of nodes, ignored when non-positive */
0319    int GetMaxVisNodes() const { TLockGuard lock(fMutex); return fCfg.maxnumnodes; }
0320 
0321    /** Set maximal number of faces which should be selected for drawing */
0322    void SetMaxVisFaces(int cnt) { TLockGuard lock(fMutex); fCfg.maxnumfaces = cnt; }
0323    /** Returns maximal visible number of faces, ignored when non-positive */
0324    int GetMaxVisFaces() const { TLockGuard lock(fMutex); return fCfg.maxnumfaces; }
0325 
0326    /** Set maximal visible level */
0327    void SetVisLevel(int lvl = 3) { TLockGuard lock(fMutex); fCfg.vislevel = lvl; }
0328    /** Returns maximal visible level */
0329    int GetVisLevel() const { TLockGuard lock(fMutex); return fCfg.vislevel; }
0330 
0331    /** Set draw options as string for JSROOT TGeoPainter */
0332    void SetTopVisible(bool on = true) { TLockGuard lock(fMutex); fCfg.showtop = on; }
0333    /** Returns draw options, used for JSROOT TGeoPainter */
0334    bool GetTopVisible() const { TLockGuard lock(fMutex); return fCfg.showtop; }
0335 
0336    /** Instruct to build binary 3D model already on the server (true) or send TGeoShape as is to client, which can build model itself */
0337    void SetBuildShapes(int lvl = 1) { TLockGuard lock(fMutex); fCfg.build_shapes = lvl; }
0338    /** Returns true if binary 3D model build already by C++ server (default) */
0339    int IsBuildShapes() const { TLockGuard lock(fMutex); return fCfg.build_shapes; }
0340 
0341    /** Set number of segments for cylindrical shapes, if 0 - default value will be used */
0342    void SetNSegments(int n = 0) { TLockGuard lock(fMutex); fCfg.nsegm = n; }
0343    /** Return of segments for cylindrical shapes, if 0 - default value will be used */
0344    int GetNSegments() const { TLockGuard lock(fMutex); return fCfg.nsegm; }
0345 
0346    /** Set draw options as string for JSROOT TGeoPainter */
0347    void SetDrawOptions(const std::string &opt = "") { TLockGuard lock(fMutex); fCfg.drawopt = opt; }
0348    /** Returns draw options, used for JSROOT TGeoPainter */
0349    std::string GetDrawOptions() const { TLockGuard lock(fMutex); return fCfg.drawopt; }
0350 
0351    /** Set JSON compression level for data transfer */
0352    void SetJsonComp(int comp = 0) { TLockGuard lock(fMutex); fJsonComp = comp; }
0353    /** Returns JSON compression level for data transfer */
0354    int GetJsonComp() const  { TLockGuard lock(fMutex); return fJsonComp; }
0355 
0356    /** Set preference of offline operations.
0357     * Server provides more info to client from the begin on to avoid communication */
0358    void SetPreferredOffline(bool on) { TLockGuard lock(fMutex); fPreferredOffline = on; }
0359    /** Is offline operations preferred.
0360     * After get full description, client can do most operations without extra requests */
0361    bool IsPreferredOffline() const { TLockGuard lock(fMutex); return fPreferredOffline; }
0362 
0363 
0364    void Build(TGeoManager *mgr, const std::string &volname = "");
0365 
0366    void Build(TGeoVolume *vol);
0367 
0368    /** Number of unique nodes in the geometry */
0369    int GetNumNodes() const { TLockGuard lock(fMutex); return fDesc.size(); }
0370 
0371    bool IsBuild() const { return GetNumNodes() > 0; }
0372 
0373    std::string ProduceJson(bool all_nodes = false);
0374 
0375    bool IsPrincipalEndNode(int nodeid);
0376 
0377    std::string ProcessBrowserRequest(const std::string &req = "");
0378 
0379    bool HasDrawData() const;
0380    void ProduceDrawData();
0381    void ProduceSearchData();
0382    std::string GetDrawJson() const { TLockGuard lock(fMutex); return fDrawJson; }
0383    std::string GetSearch() const { TLockGuard lock(fMutex); return fSearch; }
0384    std::string GetSearchJson() const { TLockGuard lock(fMutex); return fSearchJson; }
0385    void ClearDrawData();
0386 
0387    void ClearCache();
0388 
0389    int SearchVisibles(const std::string &find, std::string &hjson, std::string &json);
0390 
0391    int FindNodeId(const std::vector<int> &stack);
0392 
0393    std::string ProduceModifyReply(int nodeid);
0394 
0395    std::vector<int> MakeStackByIds(const std::vector<int> &ids);
0396 
0397    std::vector<int> MakeIdsByStack(const std::vector<int> &stack);
0398 
0399    std::vector<int> MakeStackByPath(const std::vector<std::string> &path);
0400 
0401    std::vector<std::string> MakePathByStack(const std::vector<int> &stack);
0402 
0403    bool ProduceDrawingFor(int nodeid, std::string &json, bool check_volume = false);
0404 
0405    bool SetHighlightedItem(const std::vector<int> &stack)
0406    {
0407       TLockGuard lock(fMutex);
0408       bool changed = fHighlightedStack != stack;
0409       fHighlightedStack = stack;
0410       return changed;
0411    }
0412 
0413    std::vector<int> GetHighlightedItem() const
0414    {
0415       TLockGuard lock(fMutex);
0416       return fHighlightedStack;
0417    }
0418 
0419    bool SetClickedItem(const std::vector<int> &stack)
0420    {
0421       TLockGuard lock(fMutex);
0422       bool changed = fClickedStack != stack;
0423       fClickedStack = stack;
0424       return changed;
0425    }
0426 
0427    std::vector<int> GetClickedItem() const
0428    {
0429       TLockGuard lock(fMutex);
0430       return fClickedStack;
0431    }
0432 
0433    bool SetActiveItem(const std::string &itemname)
0434    {
0435       TLockGuard lock(fMutex);
0436       bool changed = (fActiveItemName != itemname);
0437       fActiveItemName = itemname;
0438       return changed;
0439    }
0440 
0441    std::string GetActiveItem() const
0442    {
0443       TLockGuard lock(fMutex);
0444       return fActiveItemName;
0445    }
0446 
0447    bool ChangeConfiguration(const std::string &json);
0448 
0449    std::unique_ptr<RGeomNodeInfo> MakeNodeInfo(const std::vector<int> &stack);
0450 
0451    bool ChangeNodeVisibility(const std::vector<std::string> &path, bool on);
0452 
0453    bool SelectTop(const std::vector<std::string> &path);
0454 
0455    bool SetPhysNodeVisibility(const std::vector<std::string> &path, bool on = true);
0456 
0457    bool SetPhysNodeVisibility(const std::string &path, bool on = true);
0458 
0459    bool ClearPhysNodeVisibility(const std::vector<std::string> &path);
0460 
0461    bool ClearAllPhysVisibility();
0462 
0463    bool SetSearch(const std::string &query, const std::string &json);
0464 
0465    void SavePrimitive(std::ostream &fs, const std::string &name);
0466 };
0467 
0468 } // namespace ROOT
0469 
0470 #endif