// @(#):$Id$
// Author: Andrei Gheata   30/05/02

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TGeoBoolNode
#define ROOT_TGeoBoolNode

#ifndef ROOT_TObject
#include "TObject.h"
#endif

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// TGeoBoolNode - Base class for boolean nodes. A boolean node has pointers //
//  to two shapes having two transformations with respect to the mother     //
//  composite shape they belong to. It represents the boolean operation     //
//  between the two component shapes.                                       //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

// forward declarations
class TGeoShape;
class TGeoMatrix;
class TGeoHMatrix;

class TGeoBoolNode : public TObject
{
public:
enum EGeoBoolType {
   kGeoUnion,
   kGeoIntersection,
   kGeoSubtraction
};
   struct ThreadData_t
   {
      Int_t          fSelected;       // ! selected branch

      ThreadData_t();
      ~ThreadData_t();
   };
   ThreadData_t&     GetThreadData()   const;
   void              ClearThreadData() const;
   void              CreateThreadData(Int_t nthreads);
private:
   TGeoBoolNode(const TGeoBoolNode&); // Not implemented
   TGeoBoolNode& operator=(const TGeoBoolNode&); // Not implemented

protected:
   TGeoShape        *fLeft;           // shape on the left branch
   TGeoShape        *fRight;          // shape on the right branch
   TGeoMatrix       *fLeftMat;        // transformation that applies to the left branch
   TGeoMatrix       *fRightMat;       // transformation that applies to the right branch
   Int_t             fNpoints;        //! number of points on the mesh
   Double_t         *fPoints;         //! array of mesh points

   mutable std::vector<ThreadData_t*> fThreadData; //! Navigation data per thread
   mutable Int_t                      fThreadSize; //! Size for the navigation data array
// methods
   Bool_t            MakeBranch(const char *expr, Bool_t left);
public:
   // constructors
   TGeoBoolNode();
   TGeoBoolNode(const char *expr1, const char *expr2);
   TGeoBoolNode(TGeoShape *left, TGeoShape *right, TGeoMatrix *lmat=0, TGeoMatrix *rmat=0);

   // destructor
   virtual ~TGeoBoolNode();
   // methods
   virtual void      ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin) = 0;
   virtual void      ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) = 0;
   virtual Bool_t    Contains(const Double_t *point) const         = 0;
   virtual Int_t     DistanceToPrimitive(Int_t px, Int_t py) = 0;
   virtual Double_t  DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const = 0;
   virtual Double_t  DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const = 0;
   virtual EGeoBoolType GetBooleanOperator() const = 0;
   virtual Int_t     GetNpoints() = 0;
   TGeoMatrix       *GetLeftMatrix() const {return fLeftMat;}
   TGeoMatrix       *GetRightMatrix() const {return fRightMat;}
   TGeoShape        *GetLeftShape() const {return fLeft;}
   TGeoShape        *GetRightShape() const {return fRight;}
   virtual TGeoBoolNode *MakeClone() const = 0;
   virtual void      Paint(Option_t *option);
   void              RegisterMatrices();
   Bool_t            ReplaceMatrix(TGeoMatrix *mat, TGeoMatrix *newmat);
   virtual Double_t  Safety(const Double_t *point, Bool_t in=kTRUE) const = 0;
   virtual void      SavePrimitive(std::ostream &out, Option_t *option = "");
   virtual void      SetPoints(Double_t *points) const;
   virtual void      SetPoints(Float_t *points)  const;
   void              SetSelected(Int_t sel);
   virtual void      Sizeof3D() const;

   ClassDef(TGeoBoolNode, 1)              // a boolean node
};

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// TGeoUnion - Boolean node representing a union between two components.    //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

class TGeoUnion : public TGeoBoolNode
{
public:
   // constructors
   TGeoUnion();
   TGeoUnion(const char *expr1, const char *expr2);
   TGeoUnion(TGeoShape *left, TGeoShape *right, TGeoMatrix *lmat=0, TGeoMatrix *rmat=0);

   // destructor
   virtual ~TGeoUnion();
   // methods
   virtual void      ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin);
   virtual void      ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm);
   virtual Bool_t    Contains(const Double_t *point) const;
   virtual Int_t     DistanceToPrimitive(Int_t px, Int_t py);
   virtual Double_t  DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const;
   virtual Double_t  DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const;
   virtual EGeoBoolType GetBooleanOperator() const {return kGeoUnion;}
   virtual Int_t     GetNpoints();
   virtual Double_t  Safety(const Double_t *point, Bool_t in=kTRUE) const;
   virtual void      SavePrimitive(std::ostream &out, Option_t *option = "");
   virtual void      Sizeof3D() const;

   //CS specific
   virtual TGeoBoolNode *MakeClone() const;
   virtual void      Paint(Option_t *option);

   ClassDef(TGeoUnion, 1)              // union node
};

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// TGeoIntersection - Boolean node representing an intersection between two //
// components.                                                              //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

class TGeoIntersection : public TGeoBoolNode
{
public:
   // constructors
   TGeoIntersection();
   TGeoIntersection(const char *expr1, const char *expr2);
   TGeoIntersection(TGeoShape *left, TGeoShape *right, TGeoMatrix *lmat=0, TGeoMatrix *rmat=0);

   // destructor
   virtual ~TGeoIntersection();
   // methods
   virtual void      ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin);
   virtual void      ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm);
   virtual Bool_t    Contains(const Double_t *point) const;
   virtual Int_t     DistanceToPrimitive(Int_t px, Int_t py);
   virtual Double_t  DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const;
   virtual Double_t  DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const;
   virtual EGeoBoolType GetBooleanOperator() const {return kGeoIntersection;}
   virtual Int_t     GetNpoints();
   virtual Double_t  Safety(const Double_t *point, Bool_t in=kTRUE) const;
   virtual void      SavePrimitive(std::ostream &out, Option_t *option = "");
   virtual void      Sizeof3D() const;

   //CS specific
   virtual TGeoBoolNode *MakeClone() const;
   virtual void      Paint(Option_t *option);

   ClassDef(TGeoIntersection, 1)              // intersection node
};

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// TGeoSubtraction - Boolean node representing a subtraction.               //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

class TGeoSubtraction : public TGeoBoolNode
{
public:
   // constructors
   TGeoSubtraction();
   TGeoSubtraction(const char *expr1, const char *expr2);
   TGeoSubtraction(TGeoShape *left, TGeoShape *right, TGeoMatrix *lmat=0, TGeoMatrix *rmat=0);

   // destructor
   virtual ~TGeoSubtraction();
   // methods
   virtual void      ComputeBBox(Double_t &dx, Double_t &dy, Double_t &dz, Double_t *origin);
   virtual void      ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm);
   virtual Bool_t    Contains(const Double_t *point) const;
   virtual Int_t     DistanceToPrimitive(Int_t px, Int_t py);
   virtual Double_t  DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const;
   virtual Double_t  DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1,
                               Double_t step=0, Double_t *safe=0) const;
   virtual EGeoBoolType GetBooleanOperator() const {return kGeoSubtraction;}
   virtual Int_t     GetNpoints();
   virtual Double_t  Safety(const Double_t *point, Bool_t in=kTRUE) const;
   virtual void      SavePrimitive(std::ostream &out, Option_t *option = "");
   virtual void      Sizeof3D() const;

   //CS specific
   virtual TGeoBoolNode *MakeClone() const;
   virtual void      Paint(Option_t *option);

   ClassDef(TGeoSubtraction, 1)              // subtraction node
};
#endif

 TGeoBoolNode.h:1
 TGeoBoolNode.h:2
 TGeoBoolNode.h:3
 TGeoBoolNode.h:4
 TGeoBoolNode.h:5
 TGeoBoolNode.h:6
 TGeoBoolNode.h:7
 TGeoBoolNode.h:8
 TGeoBoolNode.h:9
 TGeoBoolNode.h:10
 TGeoBoolNode.h:11
 TGeoBoolNode.h:12
 TGeoBoolNode.h:13
 TGeoBoolNode.h:14
 TGeoBoolNode.h:15
 TGeoBoolNode.h:16
 TGeoBoolNode.h:17
 TGeoBoolNode.h:18
 TGeoBoolNode.h:19
 TGeoBoolNode.h:20
 TGeoBoolNode.h:21
 TGeoBoolNode.h:22
 TGeoBoolNode.h:23
 TGeoBoolNode.h:24
 TGeoBoolNode.h:25
 TGeoBoolNode.h:26
 TGeoBoolNode.h:27
 TGeoBoolNode.h:28
 TGeoBoolNode.h:29
 TGeoBoolNode.h:30
 TGeoBoolNode.h:31
 TGeoBoolNode.h:32
 TGeoBoolNode.h:33
 TGeoBoolNode.h:34
 TGeoBoolNode.h:35
 TGeoBoolNode.h:36
 TGeoBoolNode.h:37
 TGeoBoolNode.h:38
 TGeoBoolNode.h:39
 TGeoBoolNode.h:40
 TGeoBoolNode.h:41
 TGeoBoolNode.h:42
 TGeoBoolNode.h:43
 TGeoBoolNode.h:44
 TGeoBoolNode.h:45
 TGeoBoolNode.h:46
 TGeoBoolNode.h:47
 TGeoBoolNode.h:48
 TGeoBoolNode.h:49
 TGeoBoolNode.h:50
 TGeoBoolNode.h:51
 TGeoBoolNode.h:52
 TGeoBoolNode.h:53
 TGeoBoolNode.h:54
 TGeoBoolNode.h:55
 TGeoBoolNode.h:56
 TGeoBoolNode.h:57
 TGeoBoolNode.h:58
 TGeoBoolNode.h:59
 TGeoBoolNode.h:60
 TGeoBoolNode.h:61
 TGeoBoolNode.h:62
 TGeoBoolNode.h:63
 TGeoBoolNode.h:64
 TGeoBoolNode.h:65
 TGeoBoolNode.h:66
 TGeoBoolNode.h:67
 TGeoBoolNode.h:68
 TGeoBoolNode.h:69
 TGeoBoolNode.h:70
 TGeoBoolNode.h:71
 TGeoBoolNode.h:72
 TGeoBoolNode.h:73
 TGeoBoolNode.h:74
 TGeoBoolNode.h:75
 TGeoBoolNode.h:76
 TGeoBoolNode.h:77
 TGeoBoolNode.h:78
 TGeoBoolNode.h:79
 TGeoBoolNode.h:80
 TGeoBoolNode.h:81
 TGeoBoolNode.h:82
 TGeoBoolNode.h:83
 TGeoBoolNode.h:84
 TGeoBoolNode.h:85
 TGeoBoolNode.h:86
 TGeoBoolNode.h:87
 TGeoBoolNode.h:88
 TGeoBoolNode.h:89
 TGeoBoolNode.h:90
 TGeoBoolNode.h:91
 TGeoBoolNode.h:92
 TGeoBoolNode.h:93
 TGeoBoolNode.h:94
 TGeoBoolNode.h:95
 TGeoBoolNode.h:96
 TGeoBoolNode.h:97
 TGeoBoolNode.h:98
 TGeoBoolNode.h:99
 TGeoBoolNode.h:100
 TGeoBoolNode.h:101
 TGeoBoolNode.h:102
 TGeoBoolNode.h:103
 TGeoBoolNode.h:104
 TGeoBoolNode.h:105
 TGeoBoolNode.h:106
 TGeoBoolNode.h:107
 TGeoBoolNode.h:108
 TGeoBoolNode.h:109
 TGeoBoolNode.h:110
 TGeoBoolNode.h:111
 TGeoBoolNode.h:112
 TGeoBoolNode.h:113
 TGeoBoolNode.h:114
 TGeoBoolNode.h:115
 TGeoBoolNode.h:116
 TGeoBoolNode.h:117
 TGeoBoolNode.h:118
 TGeoBoolNode.h:119
 TGeoBoolNode.h:120
 TGeoBoolNode.h:121
 TGeoBoolNode.h:122
 TGeoBoolNode.h:123
 TGeoBoolNode.h:124
 TGeoBoolNode.h:125
 TGeoBoolNode.h:126
 TGeoBoolNode.h:127
 TGeoBoolNode.h:128
 TGeoBoolNode.h:129
 TGeoBoolNode.h:130
 TGeoBoolNode.h:131
 TGeoBoolNode.h:132
 TGeoBoolNode.h:133
 TGeoBoolNode.h:134
 TGeoBoolNode.h:135
 TGeoBoolNode.h:136
 TGeoBoolNode.h:137
 TGeoBoolNode.h:138
 TGeoBoolNode.h:139
 TGeoBoolNode.h:140
 TGeoBoolNode.h:141
 TGeoBoolNode.h:142
 TGeoBoolNode.h:143
 TGeoBoolNode.h:144
 TGeoBoolNode.h:145
 TGeoBoolNode.h:146
 TGeoBoolNode.h:147
 TGeoBoolNode.h:148
 TGeoBoolNode.h:149
 TGeoBoolNode.h:150
 TGeoBoolNode.h:151
 TGeoBoolNode.h:152
 TGeoBoolNode.h:153
 TGeoBoolNode.h:154
 TGeoBoolNode.h:155
 TGeoBoolNode.h:156
 TGeoBoolNode.h:157
 TGeoBoolNode.h:158
 TGeoBoolNode.h:159
 TGeoBoolNode.h:160
 TGeoBoolNode.h:161
 TGeoBoolNode.h:162
 TGeoBoolNode.h:163
 TGeoBoolNode.h:164
 TGeoBoolNode.h:165
 TGeoBoolNode.h:166
 TGeoBoolNode.h:167
 TGeoBoolNode.h:168
 TGeoBoolNode.h:169
 TGeoBoolNode.h:170
 TGeoBoolNode.h:171
 TGeoBoolNode.h:172
 TGeoBoolNode.h:173
 TGeoBoolNode.h:174
 TGeoBoolNode.h:175
 TGeoBoolNode.h:176
 TGeoBoolNode.h:177
 TGeoBoolNode.h:178
 TGeoBoolNode.h:179
 TGeoBoolNode.h:180
 TGeoBoolNode.h:181
 TGeoBoolNode.h:182
 TGeoBoolNode.h:183
 TGeoBoolNode.h:184
 TGeoBoolNode.h:185
 TGeoBoolNode.h:186
 TGeoBoolNode.h:187
 TGeoBoolNode.h:188
 TGeoBoolNode.h:189
 TGeoBoolNode.h:190
 TGeoBoolNode.h:191
 TGeoBoolNode.h:192
 TGeoBoolNode.h:193
 TGeoBoolNode.h:194
 TGeoBoolNode.h:195
 TGeoBoolNode.h:196
 TGeoBoolNode.h:197
 TGeoBoolNode.h:198
 TGeoBoolNode.h:199
 TGeoBoolNode.h:200
 TGeoBoolNode.h:201
 TGeoBoolNode.h:202
 TGeoBoolNode.h:203
 TGeoBoolNode.h:204
 TGeoBoolNode.h:205
 TGeoBoolNode.h:206
 TGeoBoolNode.h:207
 TGeoBoolNode.h:208
 TGeoBoolNode.h:209
 TGeoBoolNode.h:210
 TGeoBoolNode.h:211
 TGeoBoolNode.h:212
 TGeoBoolNode.h:213
 TGeoBoolNode.h:214
 TGeoBoolNode.h:215
 TGeoBoolNode.h:216
 TGeoBoolNode.h:217
 TGeoBoolNode.h:218
 TGeoBoolNode.h:219