23 #include "TGeoShape.h"
24 #include "TGeoVolume.h"
26 #include "TGeoMatrix.h"
27 #include "TGeoMedium.h"
29 #include "TGeoVoxelFinder.h"
30 #include "TGeoShapeAssembly.h"
39 using namespace DD4hep::Geometry;
41 #ifdef DD4HEP_EMULATE_TGEOEXTENSIONS
47 DDExtension() : m_extension(0) {}
48 DDExtension(
const DDExtension& c) : m_extension(0) {
49 if ( c.m_extension ) m_extension = c.m_extension->Grab();
51 virtual ~DDExtension() {
52 if ( m_extension ) m_extension->Release();
54 DDExtension& operator=(
const DDExtension& c) {
59 if (m_extension) m_extension->Release();
61 if (ext) m_extension = ext->
Grab();
67 struct DD_TGeoNodeMatrix :
public TGeoNodeMatrix,
public DDExtension {
69 DD_TGeoNodeMatrix& operator=(
const DD_TGeoNodeMatrix&) {
return *
this; }
71 DD_TGeoNodeMatrix(
const TGeoVolume*
v,
const TGeoMatrix*
m)
72 : TGeoNodeMatrix(v, m), DDExtension() {
75 DD_TGeoNodeMatrix(
const DD_TGeoNodeMatrix& c)
76 : TGeoNodeMatrix(c.GetVolume(), c.GetMatrix()), DDExtension(c) {
79 virtual ~DD_TGeoNodeMatrix() {
82 virtual TGeoNode *MakeCopyNode()
const {
83 TGeoNodeMatrix *node =
new DD_TGeoNodeMatrix(*
this);
86 node->SetMotherVolume(fMother);
88 node->SetNumber(fNumber);
92 Int_t *ovlps =
new Int_t[fNovlp];
93 memcpy(ovlps, fOverlaps, fNovlp *
sizeof(Int_t));
94 node->SetOverlaps(ovlps, fNovlp);
97 node->SetOverlaps(fOverlaps, fNovlp);
107 template <
class T>
struct _VolWrap:
public T,
public DDExtension {
109 _VolWrap(
const char* name) :
T(name), DDExtension() {
112 virtual ~_VolWrap() {
115 virtual void AddNode(
const TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t* =
"") {
116 TGeoMatrix *matrix = mat;
118 matrix = gGeoIdentity;
120 matrix->RegisterYourself();
122 this->T::Error(
"AddNode",
"Volume is NULL");
125 if (!vol->IsValid()) {
126 this->T::Error(
"AddNode",
"Won't add node with invalid shape");
127 printf(
"### invalid volume was : %s\n", vol->GetName());
130 if (!this->T::fNodes)
131 this->T::fNodes =
new TObjArray();
133 if (this->T::fFinder) {
135 this->T::Error(
"AddNode",
"Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no,
140 TGeoNodeMatrix *node =
new DD_TGeoNodeMatrix(vol, matrix);
142 node->SetMotherVolume(
this);
143 this->T::fNodes->Add(node);
144 TString name = TString::Format(
"%s_%d", vol->GetName(), copy_no);
145 if (this->T::fNodes->FindObject(name))
146 this->T::Warning(
"AddNode",
"Volume %s : added node %s with same name", this->
T::GetName(), name.Data());
148 node->SetNumber(copy_no);
152 template <> _VolWrap<TGeoVolume>::_VolWrap(
const char* name) : TGeoVolume(name,0,0), DDExtension() {
156 struct TGeoVolumeValue :
public _VolWrap<TGeoVolume> {
157 TGeoVolumeValue(
const char* name, TGeoShape*
s, TGeoMedium*
m) : _VolWrap<TGeoVolume>(name) {
161 virtual ~TGeoVolumeValue() { }
162 TGeoVolume *_copyVol(TGeoShape *newshape)
const {
164 if ( m_extension ) vol->m_extension = m_extension->Grab();
168 virtual TGeoVolume* MakeCopyVolume(TGeoShape *newshape) {
170 TGeoVolume *vol = _copyVol(newshape);
171 vol->SetVisibility(IsVisible());
172 vol->SetLineColor(GetLineColor());
173 vol->SetLineStyle(GetLineStyle());
174 vol->SetLineWidth(GetLineWidth());
175 vol->SetFillColor(GetFillColor());
176 vol->SetFillStyle(GetFillStyle());
177 vol->SetField(fField);
179 vol->SetFinder(fFinder);
180 CloneNodesAndConnect(vol);
181 ((
TObject*) vol)->SetBit(kVolumeClone);
184 virtual TGeoVolume* CloneVolume()
const {
185 TGeoVolume *vol = _copyVol(fShape);
188 vol->SetLineColor(GetLineColor());
189 vol->SetLineStyle(GetLineStyle());
190 vol->SetLineWidth(GetLineWidth());
191 vol->SetFillColor(GetFillColor());
192 vol->SetFillStyle(GetFillStyle());
194 Int_t nbits = 8 *
sizeof(UInt_t);
195 for (i = 0; i < nbits; i++)
196 vol->SetAttBit(1 << i, TGeoAtt::TestAttBit(1 << i));
197 for (i = 14; i < 24; i++)
198 vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i));
201 vol->SetField(fField);
203 for (i = 0; i < nbits; i++)
204 vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i));
205 vol->SetBit(kVolumeClone);
208 vol->MakeCopyNodes(
this);
210 vol->SetFinder(fFinder);
213 TGeoVoxelFinder *voxels =
new TGeoVoxelFinder(vol);
214 vol->SetVoxelFinder(voxels);
217 vol->SetOption(fOption);
218 vol->SetNumber(fNumber);
219 vol->SetNtotal(fNtotal);
224 struct TGeoVolumeAssemblyValue :
public _VolWrap<TGeoVolumeAssembly> {
225 TGeoVolumeAssemblyValue(
const char* name) : _VolWrap<TGeoVolumeAssembly>(name) {
227 virtual ~TGeoVolumeAssemblyValue() {
229 TGeoVolume *CloneVolume()
const {
231 if ( m_extension ) vol->m_extension = m_extension->Grab();
234 Int_t nbits = 8 *
sizeof(UInt_t);
235 for (i = 0; i < nbits; i++)
236 vol->SetAttBit(1 << i, TGeoAtt::TestAttBit(1 << i));
237 for (i = 14; i < 24; i++)
238 vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i));
241 vol->SetField(fField);
243 for (i = 0; i < nbits; i++)
244 vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i));
245 vol->SetBit(kVolumeClone);
247 vol->MakeCopyNodes(
this);
248 ((TGeoShapeAssembly*) vol->GetShape())->NeedsBBoxRecompute();
251 TGeoVoxelFinder *voxels =
new TGeoVoxelFinder(vol);
252 vol->SetVoxelFinder(voxels);
255 vol->SetOption(fOption);
256 vol->SetNumber(fNumber);
257 vol->SetNtotal(fNtotal);
268 template <
typename T>
static typename T::Object*
_userExtension(
const T&
v) {
269 typedef typename T::Object O;
270 const DDExtension* p =
dynamic_cast<const DDExtension*
>(v.ptr());
271 O* o = (O*)(p ? p->GetUserExtension() : 0);
287 typedef typename T::Object O;
288 O* o = (O*)(v.ptr()->GetUserExtension());
294 static TGeoVolume* _createTGeoVolume(const
string& name, TGeoShape*
s, TGeoMedium*
m) {
301 e->SetUserExtension(
new Assembly::Object());
306 PlacedVolumeExtension::PlacedVolumeExtension()
314 :
TGeoExtension(), magic(c.magic), refCount(0), volIDs(c.volIDs) {
327 else cout <<
"Placement grabbed....." << endl;
336 if ( 0 == ext->
refCount )
delete ext;
340 vector<PlacedVolumeExtension::VolID>::const_iterator
342 for (Base::const_iterator i = this->Base::begin(); i != this->Base::end(); ++i)
343 if (name == (*i).first)
349 std::pair<vector<PlacedVolumeExtension::VolID>::iterator,
bool>
351 Base::iterator i = this->Base::begin();
352 for (; i != this->Base::end(); ++i)
353 if (name == (*i).first)
356 if (i != this->Base::end()) {
357 return make_pair(i,
false);
359 i = this->Base::insert(this->Base::end(), make_pair(name, value));
360 return make_pair(i,
true);
367 throw runtime_error(
"DD4hep: Attempt to access invalid handle of type: PlacedVolume");
407 s << m_element->GetName() <<
": vol='" << m_element->GetVolume()->GetName() <<
"' mat:'" << m_element->GetMatrix()->GetName()
408 <<
"' volID[" << obj->
volIDs.size() <<
"] ";
409 for (VolIDs::const_iterator i = obj->
volIDs.begin(); i != obj->
volIDs.end(); ++i)
410 s << (*i).first <<
"=" << (*i).second <<
" ";
439 cout <<
"Volume grabbed with valid sensitive detector....." << endl;
441 cout <<
"Volume grabbed....." << endl;
452 cout <<
"Volume deleted....." << endl;
458 cout <<
"VolumeExtension::Release::refCount:" << ext->
refCount << endl;
469 else if (!throw_exception)
471 throw runtime_error(
"DD4hep: Attempt to access invalid handle of type: PlacedVolume");
476 m_element = _createTGeoVolume(nam,0,0);
481 m_element = _createTGeoVolume(nam,s.
ptr(),m.
ptr());
492 throw runtime_error(
"DD4hep: Volume: Attempt to assign an invalid physical daughter volume.");
494 TGeoVolume* parent = par;
495 TObjArray* a = parent->GetNodes();
496 Int_t
id = a ? a->GetEntries() : 0;
498 string nam = string(daughter->GetName()) +
"_placement";
499 transform->SetName(nam.c_str());
501 TGeoShape* shape = daughter->GetShape();
503 if ( shape->IsA() == TGeoShapeAssembly::Class() ) {
504 TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
505 if ( std::fabs(as->GetDX()) < numeric_limits<double>::epsilon() &&
506 std::fabs(as->GetDY()) < numeric_limits<double>::epsilon() &&
507 std::fabs(as->GetDZ()) < numeric_limits<double>::epsilon() ) {
508 as->NeedsBBoxRecompute();
512 parent->AddNode(daughter,
id, transform);
546 TGeoMedium* medium = m.
_ptr<TGeoMedium>();
548 m_element->SetMedium(medium);
551 throw runtime_error(
"DD4hep: Volume: Medium " +
string(m.
name()) +
" is not registered with geometry manager.");
553 throw runtime_error(
"DD4hep: Volume: Attempt to assign invalid material.");
558 return Ref_t(m_element->GetMedium());
567 Color_t bright = vis->
color;
568 Color_t dark = vis->
color;
569 TColor* c = vis->
col;
573 m_element->SetVisibility(vis->
visible ? kTRUE : kFALSE);
574 m_element->SetVisContainers(kTRUE);
576 m_element->SetVisDaughters(vis->
showDaughters ? kTRUE : kFALSE);
578 "Set color %3d [%02X,%02X,%02X] DrawingStyle:%9s LineStyle:%6s for volume %s",
580 c ?
int(255*c->GetRed()) : 0xFF,
581 c ?
int(255*c->GetGreen()) : 0xFF,
582 c ?
int(255*c->GetBlue()) : 0xFF,
587 m_element->SetLineWidth(10);
588 m_element->SetLineColor(dark);
590 m_element->SetLineColor(bright);
591 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,34,25)
592 m_element->SetFillColorAlpha(bright,vis->
alpha);
594 m_element->SetFillColor(bright);
596 m_element->SetFillStyle(1001);
600 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0)
607 m_element->SetTransparency((1-vis->
alpha)*100);
611 printout(
DEBUG,
"setVisAttributes",
"Set to wireframe vis:%s",name());
612 m_element->SetLineColor(kBlack);
613 m_element->SetFillColor(0);
614 m_element->SetFillStyle(0);
617 m_element->SetLineStyle(1);
619 m_element->SetLineStyle(2);
621 m_element->SetLineStyle(line_style);
642 if ( o ) o->
vis = attr;
650 setVisAttributes(attr);
671 setRegion(lcdd.
region(rg));
674 setVisAttributes(lcdd, vis);
688 m_element->SetShape(s);
694 return Solid((*this)->GetShape());
700 return setRegion(lcdd.
region(nam));
707 _data(*this)->region = obj;
713 return _data(*this)->region;
719 return setLimitSet(lcdd.
limitSet(nam));
726 _data(*this)->limits = obj;
732 return _data(*this)->limits;
738 _data(*this)->sens_det = obj;
750 return _data(*this)->sens_det.isValid();
static PlacedVolume _addNode(TGeoVolume *par, TGeoVolume *daughter, TGeoMatrix *transform)
Handle class to hold the information of a sensitive detector.
virtual ~PlacedVolumeExtension()
Default destructor.
virtual void Release() const
TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore...
VisAttr vis
Reference to visualization attributes.
Ref_t sensitiveDetector() const
Access to the handle to the sensitive detector.
const Volume & setLimitSet(const LCDD &lcdd, const std::string &name) const
Set the limits to the volume. Note: If the name string is empty, the action is ignored.
Handle class holding a placed volume (also called physical volume)
Solid solid() const
Access to Solid (Shape)
Volume volume() const
Logical volume of this placement.
const VolIDs & volIDs() const
Access to the volume IDs.
const char * name() const
Access the object name (or "" if not supported by the object)
long refCount
Reference count on object (used to implement Grab/Release)
Handle class describing a material.
bool isValid() const
Check the validity of the object held by the handle.
LimitSet limitSet() const
Access to the limit set.
#define INCREMENT_COUNTER
TGeoTranslation * _translation(const Geometry::Position &pos)
Convert a Position object to a TGeoTranslation
Q * data() const
Access to an unrelated object type.
virtual TGeoExtension * Grab()
TGeoExtension overload: Method called whenever requiring a pointer to the extension.
TGeoRotation * _rotationZYX(const Geometry::RotationZYX &rot)
Convert a RotationZYX object to a TGeoRotation
Object * data() const
Check if placement is properly instrumented.
Implementation class extending the ROOT placed volume.
Ref_t sens_det
Reference to the sensitive detector.
VolIDs volIDs
ID container.
virtual void Release() const
TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore...
VisAttr visAttributes() const
Access the visualisation attributes.
ClassImp(PlacedVolumeExtension) static TGeoVolume *_createTGeoVolume(const string &name
static T::Object * _userExtension(const T &v)
virtual TGeoExtension * Grab()
TGeoExtension overload: Method called whenever requiring a pointer to the extension.
T * ptr() const
Access to the held object.
std::string toString() const
String dump.
Handle class holding a placed volume (also called physical volume)
std::pair< std::vector< VolID >::iterator, bool > insert(const std::string &name, int value)
Inert new entry.
Material material() const
Volume material.
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
virtual LimitSet limitSet(const std::string &name) const =0
Retrieve a limitset by it's name from the detector description.
long refCount
Reference count on object (used to implement Grab/Release)
std::pair< std::string, int > VolID
ROOT::Math::RotationZYX RotationZYX
Assembly()
Default constructor.
const Volume & setMaterial(const Material &m) const
Set the volume's material.
TGeoIdentity * identityTransform()
Access the TGeo identity transformation
static TGeoVolume * _createTGeoVolumeAssembly(const string &name)
ROOT::Math::Rotation3D Rotation3D
const char * GetName(T *p)
TGeoRotation * _rotation3D(const Geometry::Rotation3D &rot)
Convert a Rotation3D object to a TGeoRotation
Volume motherVol() const
Parent volume (envelope)
unsigned char showDaughters
TGeoHMatrix * _transform(const Geometry::Transform3D &trans)
Convert a Transform3D object to a TGeoHMatrix
Q * _ptr() const
Access to an unrelated object type.
TGeoVolumeAssembly geo_assembly_t
virtual ~VolumeExtension()
Default destructor.
const Volume & setAttributes(const LCDD &lcdd, const std::string ®ion, const std::string &limits, const std::string &vis) const
Attach attributes to the volume.
#define DECREMENT_COUNTER
ROOT::Math::XYZVector Position
Volume()
Default constructor.
Solid_type< TGeoShape > Solid
Implementation class extending the ROOT volume (TGeoVolume)
unsigned long magic
Magic word to detect memory corruptions.
Region region() const
Access to the handle to the region structure.
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
unsigned char drawingStyle
e SetUserExtension(new Volume::Object())
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Handle< Implementation > handle_t
Declaration of 'self'.
virtual Region region(const std::string &name) const =0
Retrieve a region object by it's name from the detector description.
Handle class describing visualization attributes.
Object * data() const
Check if placement is properly instrumented.
std::vector< VolID >::const_iterator find(const std::string &name) const
Find entry.
virtual TGeoExtension * Grab()=0
TGeoExtension overload: Method called whenever requiring a pointer to the extension.
Handle class describing a set of limits as they are used for simulation.
Handle class describing a region as used in simulation.
const Volume & setRegion(const LCDD &lcdd, const std::string &name) const
Set the regional attributes to the volume. Note: If the name string is empty, the action is ignored...
PlacedVolume & addPhysVolID(const std::string &name, int value)
Add identifier.
The main interface to the DD4hep detector description package.
static PlacedVolume::Object * _data(const PlacedVolume &v)
const Volume & setSensitiveDetector(const SensitiveDetector &obj) const
Assign the sensitive detector structure.
virtual const HandleMap & visAttributes() const =0
Accessor to the map of visualisation attributes.
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Material material() const
Access to the Volume material.
ROOT::Math::Transform3D Transform3D
const Volume & setSolid(const Solid &s) const
Set the volume's solid shape.
PlacedVolumeExtension()
Default constructor.
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
PlacedVolume placeVolume(const Volume &vol) const
Place daughter volume. The position and rotation are the identity.
unsigned long long int magic_word()
Access to the magic word, which is protecting some objects against memory corruptions.
Concrete object implementation of the VisAttr Handle.
bool isSensitive() const
Accessor if volume is sensitive (ie. is attached to a sensitive detector)