# class TGeoCompositeShape: public TGeoBBox

``` 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.
```

## Function Members (Methods)

public:
 TGeoCompositeShape() TGeoCompositeShape(const char* expression) TGeoCompositeShape(const char* name, const char* expression) TGeoCompositeShape(const char* name, TGeoBoolNode* node) virtual ~TGeoCompositeShape() void TObject::AbstractMethod(const char* method) const virtual void TObject::AppendPad(Option_t* option = "") static Bool_t TGeoBBox::AreOverlapping(const TGeoBBox* box1, const TGeoMatrix* mat1, const TGeoBBox* box2, const TGeoMatrix* mat2) static Double_t TGeoShape::Big() virtual void TObject::Browse(TBrowser* b) virtual Double_t Capacity() const static TClass* Class() virtual const char* TObject::ClassName() const virtual void TNamed::Clear(Option_t* option = "") virtual TObject* TNamed::Clone(const char* newname = "") const virtual Int_t TNamed::Compare(const TObject* obj) const virtual void ComputeBBox() virtual void ComputeNormal(Double_t* point, Double_t* dir, Double_t* norm) virtual Bool_t Contains(Double_t* point) const virtual void TNamed::Copy(TObject& named) const virtual Bool_t TGeoBBox::CouldBeCrossed(Double_t* point, Double_t* dir) const virtual void TObject::Delete(Option_t* option = "") virtual Int_t TGeoBBox::DistancetoPrimitive(Int_t px, Int_t py) 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 static Double_t TGeoShape::DistToPhiMin(Double_t* point, Double_t* dir, Double_t s1, Double_t c1, Double_t s2, Double_t c2, Double_t sm, Double_t cm, Bool_t in = kTRUE) virtual TGeoVolume* Divide(TGeoVolume* voldiv, const char* divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step) virtual void TGeoShape::Draw(Option_t* option = "") virtual void TObject::DrawClass() const virtual TObject* TObject::DrawClone(Option_t* option = "") const virtual void TObject::Dump() const virtual void TObject::Error(const char* method, const char* msgfmt) const virtual void TObject::Execute(const char* method, const char* params, Int_t* error = 0) virtual void TObject::Execute(TMethod* method, TObjArray* params, Int_t* error = 0) virtual void TGeoShape::ExecuteEvent(Int_t event, Int_t px, Int_t py) virtual void TObject::Fatal(const char* method, const char* msgfmt) const virtual void TNamed::FillBuffer(char*& buffer) virtual TObject* TObject::FindObject(const char* name) const virtual TObject* TObject::FindObject(const TObject* obj) const virtual const char* TGeoBBox::GetAxisName(Int_t iaxis) const virtual Double_t TGeoBBox::GetAxisRange(Int_t iaxis, Double_t& xlo, Double_t& xhi) const TGeoBoolNode* GetBoolNode() const virtual void GetBoundingCylinder(Double_t*) const virtual const TBuffer3D& TGeoBBox::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const virtual Int_t TGeoBBox::GetByteCount() const virtual Option_t* TObject::GetDrawOption() const static Long_t TObject::GetDtorOnly() virtual Double_t TGeoBBox::GetDX() const virtual Double_t TGeoBBox::GetDY() const virtual Double_t TGeoBBox::GetDZ() const virtual Int_t TGeoBBox::GetFittingBox(const TGeoBBox* parambox, TGeoMatrix* mat, Double_t& dx, Double_t& dy, Double_t& dz) const virtual const char* TObject::GetIconName() const Int_t TGeoShape::GetId() const virtual TGeoShape* GetMakeRuntimeShape(TGeoShape*, TGeoMatrix*) const virtual void GetMeshNumbers(Int_t& nvert, Int_t& nsegs, Int_t& npols) const virtual const char* TGeoShape::GetName() const virtual Int_t GetNmeshVertices() const virtual char* TObject::GetObjectInfo(Int_t px, Int_t py) const static Bool_t TObject::GetObjectStat() virtual Option_t* TObject::GetOption() const virtual const Double_t* TGeoBBox::GetOrigin() const char* TGeoShape::GetPointerName() const virtual const char* TNamed::GetTitle() const static TGeoMatrix* TGeoShape::GetTransform() virtual UInt_t TObject::GetUniqueID() const virtual Bool_t TObject::HandleTimer(TTimer* timer) virtual ULong_t TNamed::Hash() const virtual void TObject::Info(const char* method, const char* msgfmt) const virtual Bool_t TObject::InheritsFrom(const char* classname) const virtual Bool_t TObject::InheritsFrom(const TClass* cl) const virtual void TObject::Inspect() const virtual void InspectShape() const void TObject::InvertBit(UInt_t f) void TGeoShape::InvertShapeBit(UInt_t f) virtual TClass* IsA() const static Bool_t TGeoShape::IsCloseToPhi(Double_t epsil, Double_t* point, Double_t c1, Double_t s1, Double_t c2, Double_t s2) virtual Bool_t IsComposite() const static Bool_t TGeoShape::IsCrossingSemiplane(Double_t* point, Double_t* dir, Double_t cphi, Double_t sphi, Double_t& snext, Double_t& rxy) virtual Bool_t IsCylType() const virtual Bool_t TObject::IsEqual(const TObject* obj) const virtual Bool_t TObject::IsFolder() const static Bool_t TGeoShape::IsInPhiRange(Double_t* point, Double_t phi1, Double_t phi2) virtual Bool_t TGeoBBox::IsNullBox() const Bool_t TObject::IsOnHeap() const virtual Bool_t TGeoShape::IsReflected() const Bool_t TGeoShape::IsRunTimeShape() const virtual Bool_t TNamed::IsSortable() const Bool_t TGeoShape::IsValid() const virtual Bool_t TGeoBBox::IsValidBox() const Bool_t TObject::IsZombie() const virtual void TNamed::ls(Option_t* option = "") const virtual TBuffer3D* TGeoBBox::MakeBuffer3D() const void MakeNode(const char* expression) void TObject::MayNotUse(const char* method) const static void TGeoShape::NormalPhi(Double_t* point, Double_t* dir, Double_t* norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2) virtual Bool_t TObject::Notify() static void TObject::operator delete(void* ptr) static void TObject::operator delete(void* ptr, void* vp) static void TObject::operator delete[](void* ptr) static void TObject::operator delete[](void* ptr, void* vp) void* TObject::operator new(size_t sz) void* TObject::operator new(size_t sz, void* vp) void* TObject::operator new[](size_t sz) void* TObject::operator new[](size_t sz, void* vp) virtual void TGeoShape::Paint(Option_t* option = "") virtual Bool_t PaintComposite(Option_t* option = "") const virtual void TObject::Pop() virtual void TNamed::Print(Option_t* option = "") const virtual Int_t TObject::Read(const char* name) virtual void TObject::RecursiveRemove(TObject* obj) void RegisterYourself() void TObject::ResetBit(UInt_t f) void TGeoShape::ResetShapeBit(UInt_t f) virtual Double_t Safety(Double_t* point, Bool_t in = kTRUE) const static Double_t TGeoShape::SafetyPhi(Double_t* point, Bool_t in, Double_t phi1, Double_t phi2) virtual void TObject::SaveAs(const char* filename = "", Option_t* option = "") const virtual void SavePrimitive(ostream& out, Option_t* option = "") void TObject::SetBit(UInt_t f) void TObject::SetBit(UInt_t f, Bool_t set) void TGeoBBox::SetBoxDimensions(Double_t dx, Double_t dy, Double_t dz, Double_t* origin = 0) void TGeoBBox::SetBoxPoints(Double_t* points) const virtual void SetDimensions(Double_t*) virtual void TObject::SetDrawOption(Option_t* option = "") static void TObject::SetDtorOnly(void* obj) void TGeoShape::SetId(Int_t id) virtual void TNamed::SetName(const char* name) virtual void TNamed::SetNameTitle(const char* name, const char* title) static void TObject::SetObjectStat(Bool_t stat) virtual void SetPoints(Double_t* points) const virtual void SetPoints(Float_t* points) const void TGeoShape::SetRuntime(Bool_t flag = kTRUE) virtual void TGeoBBox::SetSegsAndPols(TBuffer3D& buffer) const void TGeoShape::SetShapeBit(UInt_t f) void TGeoShape::SetShapeBit(UInt_t f, Bool_t set) virtual void TNamed::SetTitle(const char* title = "") static void TGeoShape::SetTransform(TGeoMatrix* matrix) virtual void TObject::SetUniqueID(UInt_t uid) Int_t TGeoShape::ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const virtual void ShowMembers(TMemberInspector& insp, char* parent) virtual Int_t TNamed::Sizeof() const virtual void Sizeof3D() const virtual void Streamer(TBuffer& b) void StreamerNVirtual(TBuffer& b) virtual void TObject::SysError(const char* method, const char* msgfmt) const Bool_t TObject::TestBit(UInt_t f) const Int_t TObject::TestBits(UInt_t f) const Bool_t TGeoShape::TestShapeBit(UInt_t f) const Int_t TGeoShape::TestShapeBits(UInt_t f) const static Double_t TGeoShape::Tolerance() virtual void TObject::UseCurrentStyle() virtual void TObject::Warning(const char* method, const char* msgfmt) const virtual Int_t TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) virtual Int_t TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) const
protected:
 TGeoCompositeShape(const TGeoCompositeShape& gcs) virtual void TObject::DoError(int level, const char* location, const char* fmt, va_list va) const virtual void TGeoBBox::FillBuffer3D(TBuffer3D& buffer, Int_t reqSections, Bool_t localFrame) const Int_t TGeoShape::GetBasicColor() const void TObject::MakeZombie() TGeoCompositeShape& operator=(const TGeoCompositeShape& gcs) void TGeoShape::SetOnBoundary(Bool_t) void TGeoShape::TransformPoints(Double_t* points, UInt_t NbPoints) const

## Data Members

public:
 enum TGeoShape::EShapeType { kBitMask32 kGeoNoShape kGeoBad kGeoRSeg kGeoPhiSeg kGeoThetaSeg kGeoVisX kGeoVisY kGeoVisZ kGeoRunTimeShape kGeoInvalidShape kGeoTorus kGeoBox kGeoPara kGeoSph kGeoTube kGeoTubeSeg kGeoCone kGeoConeSeg kGeoPcon kGeoPgon kGeoArb8 kGeoEltu kGeoTrap kGeoCtub kGeoTrd1 kGeoTrd2 kGeoComb kGeoClosedShape kGeoXtru kGeoParaboloid kGeoHalfSpace kGeoHype kGeoSavePrimitive }; enum TObject::EStatusBits { kCanDelete kMustCleanup kObjInCanvas kIsReferenced kHasUUID kCannotPick kNoContextMenu kInvalidObject }; enum TObject::[unnamed] { kIsOnHeap kNotDeleted kZombie kBitMask kSingleKey kOverwrite kWriteDelete };
protected:
 Double_t TGeoBBox::fDX X half-length Double_t TGeoBBox::fDY Y half-length Double_t TGeoBBox::fDZ Z half-length TString TNamed::fName object identifier Double_t TGeoBBox::fOrigin[3] box origin UInt_t TGeoShape::fShapeBits shape bits Int_t TGeoShape::fShapeId shape id TString TNamed::fTitle object title
private:
 TGeoBoolNode* fNode top boolean node

## Function documentation

``` Default constructor
```
TGeoCompositeShape(const char *name, const char *expression)
``` Default constructor
```
TGeoCompositeShape(const char *expression)
``` Default constructor
```
TGeoCompositeShape(const char *name, TGeoBoolNode *node)
``` Constructor with a Boolean node
```

``` destructor
```

``` Computes capacity of this shape [length^3] by sampling with 1% error.
```
void ComputeBBox()
``` compute bounding box of the sphere
```
void ComputeNormal(Double_t* point, Double_t* dir, Double_t* norm)
``` Computes normal vector in POINT to the composite shape.
```
Bool_t Contains(Double_t* point) const
``` Tests if point is inside the shape.
```
Double_t DistFromOutside(Double_t* point, Double_t* dir, Int_t iact = 1, Double_t step = TGeoShape::Big(), Double_t* safe = 0) const
``` Compute distance from outside point to this composite shape.
Check if the bounding box is crossed within the requested distance
```
Double_t DistFromInside(Double_t* point, Double_t* dir, Int_t iact = 1, Double_t step = TGeoShape::Big(), Double_t* safe = 0) 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 GetMeshNumbers(Int_t& nvert, Int_t& nsegs, Int_t& npols) const
``` Returns numbers of vertices, segments and polygons composing the shape mesh.
```
void InspectShape()
``` 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
```
void RegisterYourself()
``` Register the shape and all components to TGeoManager class.
```
Double_t Safety(Double_t* point, Bool_t in = kTRUE) 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(ostream& out, Option_t* option = "")
``` Save a primitive as a C++ statement(s) on output stream "out".
```
void SetPoints(Double_t *points)
``` create points for a composite shape
```
void SetPoints(Float_t *points)
``` create points for a composite shape
```
void Sizeof3D()
``` compute size of this 3D object
```

``` Return number of vertices of the mesh representation
```
TGeoCompositeShape(const TGeoCompositeShape& gcs)
`{ }`
TGeoCompositeShape& operator=(const TGeoCompositeShape& gcs)

`{return fNode;}`
void GetBoundingCylinder(Double_t* ) const
`{;}`
TGeoShape * GetMakeRuntimeShape(TGeoShape* , TGeoMatrix* ) const
`{return 0;}`

`{return kTRUE;}`

`{return kFALSE;}`
void SetDimensions(Double_t* )
`{;}`

Author: Andrei Gheata 31/01/02
Last update: root/geom:\$Id: TGeoCompositeShape.h 21425 2007-12-17 15:59:27Z brun \$