library: libGeom #include "TGeoCompositeShape.h"

# TGeoCompositeShape

class description - source file - inheritance tree (.pdf)

## class TGeoCompositeShape : public TGeoBBox

| Inheritance Chart:
`TObject`
| <- | `TNamed`
| <- | `TGeoShape`
| <- | `TGeoBBox`
| <- | `TGeoCompositeShape` |

        public:

                              TGeoCompositeShape()
                              TGeoCompositeShape(const char* name, const char* expression)
                              TGeoCompositeShape(const char* expression)
                              TGeoCompositeShape(const char* name, TGeoBoolNode* node)
                              TGeoCompositeShape(const TGeoCompositeShape&)
                      virtual ~TGeoCompositeShape()
               static TClass* Class()
                 virtual void ComputeBBox()
                 virtual void ComputeNormal(Double_t* point, Double_t* dir, Double_t* norm)
               virtual Bool_t Contains(Double_t* point) const
             virtual Double_t DistFromInside(Double_t* point, Double_t* dir, Int_t iact = 1, Double_t step = TGeoShape::Big(), Double_t* safe = 0) const
             virtual Double_t DistFromOutside(Double_t* point, Double_t* dir, Int_t iact = 1, Double_t step = TGeoShape::Big(), Double_t* safe = 0) const
          virtual TGeoVolume* Divide(TGeoVolume* voldiv, const char* divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
                TGeoBoolNode* GetBoolNode() const
                 virtual void GetBoundingCylinder(Double_t*) const
           virtual TGeoShape* GetMakeRuntimeShape(TGeoShape*, TGeoMatrix*) const
                virtual Int_t GetNmeshVertices() const
                 virtual void InspectShape() const
              virtual TClass* IsA() const
               virtual Bool_t IsComposite() const
               virtual Bool_t IsCylType() const
                         void MakeNode(const char* expression)
          TGeoCompositeShape& operator=(const TGeoCompositeShape&)
               virtual Bool_t PaintComposite(Option_t* option = "") const
             virtual Double_t Safety(Double_t* point, Bool_t in = kTRUE) const
                 virtual void SavePrimitive(ofstream& out, Option_t* option)
                 virtual void SetDimensions(Double_t*)
                 virtual void SetPoints(Double_t* points) const
                 virtual void SetPoints(Float_t* points) const
                 virtual void ShowMembers(TMemberInspector& insp, char* parent)
                 virtual void Sizeof3D() const
                 virtual void Streamer(TBuffer& b)
                         void StreamerNVirtual(TBuffer& b)

### Data Members

        private:

          TGeoBoolNode* fNode  top boolean node

## Class Description

     TGeoCompositeShape - class handling Boolean composition of shapes

       Composite shapes are Boolean combination of two or more shape
     components. The supported boolean operations are union (+), intersection (*)
     and subtraction. Composite shapes derive from the base TGeoShape class,
     therefore providing all shape features : computation of bounding box, finding
     if a given point is inside or outside the combination, as well as computing the
     distance to entering/exiting. It can be directly used for creating volumes or
     used in the definition of other composite shapes.
       Composite shapes are provided in order to complement and extend the set of
     basic shape primitives. They have a binary tree internal structure, therefore
     all shape-related geometry queries are signals propagated from top level down
     to the final leaves, while the provided answers are assembled and interpreted
     back at top. This CSG hierarchy is effective for small number of components,
     while performance drops dramatically for large structures. Building a complete
     geometry in this style is virtually possible but highly not recommended.

       Structure of composite shapes

       A composite shape can always be regarded as the result of a Boolean operation
     between only two shape components. All information identifying these two
     components as well as their positions with respect to the frame of the composite
     is represented by an object called Boolean node. A composite shape just have
     a pointer to such a Boolean node. Since the shape components may also be
     composites, they will also contain binary Boolean nodes branching other two
     shapes in the hierarcy. Any such branch ends-up when the final leaves are no
     longer composite shapes, but basic primitives.

/* */

       Suppose that A, B, C and D represent basic shapes, we will illustrate
     how the internal representation of few combinations look like. We do this
     only for the sake of understanding how to create them in a proper way, since
     the user interface for this purpose is in fact very simple. We will ignore
     for the time being the positioning of components. The definition of a composite
     shape takes an expression where the identifiers are shape names. The
     expression is parsed and decomposed in 2 sub-expressions and the top-level
     Boolean operator.

     1.     A+B+C
       This represent the union of A, B and C. Both union operators are at the
     same level. Since:
            A+B+C = (A+B)+C = A+(B+C)
     the first (+) is taken as separator, hence the expression splitted:
            A and B+C
     A Boolean node of type TGeoUnion("A", "B+C") is created. This tries to replace
     the 2 expressions by actual pointers to corresponding shapes.
     The first expression (A) contains no operators therefore is interpreted as
     representing a shape. The shape named "A" is searched into the list of shapes
     handled by the manager class and stored as the "left" shape in the Boolean
     union node. Since the second expression is not yet fully decomposed, the "right"
     shape in the combination is created as a new composite shape. This will split
     at its turn B+C into B and C and create a TGeoUnion("B","C"). The B and C
     identifiers will be looked for and replaced by the pointers to the actual shapes
     into the new node. Finally, the composite "A+B+C" will be represented as:

                     A
                    |
       [A+B+C] = (+)             B
                    |           |
                     [B+C] = (+)
                                |
                                 C

     where [] is a composite shape, (+) is a Boolean node of type union and A, B,
     C are pointers to the corresponding shapes.
       Building this composite shapes takes the following line :
          TGeoCompositeShape *cs1 = new TGeoCompositeShape("CS1", "A+B+C");

     2.      (A+B)\(C+D)
       This expression means: subtract the union of C and D from the union of A and
     B. The usage of paranthesys to force operator precedence is always recommended.
     The representation of the corresponding composite shape looks like:

                                       A
                                      |
                           [A+B] = (+)
                          |           |
       [(A+B)\(C+D)] = (\)           C B
                          |         |
                           [C+D]=(+)
                                    |
                                     D

          TGeoCompositeShape *cs2 = new TGeoCompositeShape("CS2", "(A+B)\(C+D)");

       Building composite shapes as in the 2 examples above is not always quite
     usefull since we were using unpositioned shapes. When suplying just shape
     names as identifiers, the created boolean nodes will assume that the shapes
     are positioned with an identity transformation with respect to the frame of
     the created composite. In order to provide some positioning of the combination
     components, we have to attach after each shape identifier the name of an
     existing transformation, separated by a colon. Obviously all transformations
     created for this purpose have to be objects with unique names in order to be
     properly substituted during parsing.
       Let's look at the code implementing the second example :

          TGeoTranslation *t1 = new TGeoTranslation("T1",0,0,-20);
          TGeoTranslation *t2 = new TGeoTranslation("T2",0,0, 20);
          TGeoRotation *r1 = new TGeoRotation("R1"); // transformations need names
          r1->SetAngles(90,30,90,120,0,0); // rotation with 30 degrees about Z
          TGeoTube *a = new TGeoTube(0, 10,20);
          a->SetName("A");                 // shapes need names too
          TGeoTube *b = new TGeoTube(0, 20,20);
          b->SetName("B");
          TGeoBBox *c = new TGeoBBox(10,10,50);
          c->SetName("C");
          TGeoBBox *d = new TGeoBBox(50,10,10);
          d->SetName("D");

          TGeoCompositeShape *cs;
          cs = new TGeoCompositeShape("CS", "(A:t1+B:t2)\(C+D:r1)");

       The newly created composite looks like 2 cylinders of different radii sitting
     one on top of the other and having 2 rectangular holes : a longitudinal one
     along Z axis corresponding to C and an other one in the XY plane due to D.
       One should have in mind that the same shape or matrix identifier can be
     used many times in the same expression. For instance:

          (A:t1-A:t2)*B:t1

     is a valid expression. Expressions that cannot be parsed or identifiers that
     cannot be substituted by existing objects generate error messages.
       Composite shapes can be subsequently used for defining volumes. Moreover,
     these volumes may have daughters but these have to obbey overlapping/extruding
     rules (see TGeoVolume). Volumes created based on composite shapes cannot be
     divided. Visualization of such volumes is currently not implemented.

TGeoCompositeShape() :TGeoBBox(0, 0, 0)

     Default constructor

TGeoCompositeShape(const char *name, const char *expression) :TGeoBBox(0, 0, 0)

     Default constructor

TGeoCompositeShape(const char *expression) :TGeoBBox(0, 0, 0)

     Default constructor

TGeoCompositeShape(const char *name, TGeoBoolNode *node) :TGeoBBox(0,0,0)

     Constructor with a Boolean node

~TGeoCompositeShape()

     destructor

void ComputeBBox()

     compute bounding box of the sphere

void ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)

Bool_t Contains(Double_t *point) const

     test if point is inside this sphere

Double_t DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const

     Compute distance from outside point to this composite shape.

Double_t DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const

     Compute distance from inside point to outside of this composite shape.

TGeoVolume* Divide(TGeoVolume * /*voldiv*/, const char * /*divname*/, Int_t /*iaxis*/, Int_t /*ndiv*/, Double_t /*start*/, Double_t /*step*/)

     Divide all range of iaxis in range/step cells

void InspectShape() const

     print shape parameters

void MakeNode(const char *expression)

     Make a booleann node according to the top level boolean operation of expression.
     Propagates signal to branches until expression is fully decomposed.
       printf("Making node for : %s\n", expression);

Bool_t PaintComposite(Option_t *option) const

     Paint this composite shape into the current 3D viewer
     Returns bool flag indicating if the caller should continue to
     paint child objects

Double_t Safety(Double_t *point, Bool_t in) const

     computes the closest distance from given point to this shape, according
     to option. The matching point on the shape is stored in spoint.

void SavePrimitive(ofstream &out, Option_t *option)

     Save a primitive as a C++ statement(s) on output stream "out".

void SetPoints(Double_t *points) const

     create points for a composite shape

void SetPoints(Float_t *points) const

     create points for a composite shape

void Sizeof3D() const

     compute size of this 3D object

Int_t GetNmeshVertices() const

     Return number of vertices of the mesh representation

### Inline Functions

                  TGeoBoolNode* GetBoolNode() const
                           void GetBoundingCylinder(Double_t*) const
                     TGeoShape* GetMakeRuntimeShape(TGeoShape*, TGeoMatrix*) const
                         Bool_t IsComposite() const
                         Bool_t IsCylType() const
                           void SetDimensions(Double_t*)
                        TClass* Class()
                        TClass* IsA() const
                           void ShowMembers(TMemberInspector& insp, char* parent)
                           void Streamer(TBuffer& b)
                           void StreamerNVirtual(TBuffer& b)
             TGeoCompositeShape TGeoCompositeShape(const TGeoCompositeShape&)
            TGeoCompositeShape& operator=(const TGeoCompositeShape&)

Author: Andrei Gheata 31/01/02
Last update: root/geom:$Name: $:$Id: TGeoCompositeShape.cxx,v 1.32 2005/05/25 14:25:16 brun Exp $
Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *