diff --git a/DDCore/include/DD4hep/Factories.h b/DDCore/include/DD4hep/Factories.h index 04a372779a22a5fd13fa1882b56c68e83e983b67..82aee8e4820178e98ec3501ec30033cd11eb0bc2 100644 --- a/DDCore/include/DD4hep/Factories.h +++ b/DDCore/include/DD4hep/Factories.h @@ -173,6 +173,19 @@ namespace { } }; + template <typename P> class Factory<P, TGeoVolume*(DD4hep::Geometry::LCDD*, DD4hep::XML::Handle_t*)> { + public: + typedef DD4hep::Geometry::LCDD LCDD; + typedef DD4hep::XML::Handle_t xml_h; + typedef DD4hep::Geometry::Ref_t Ref_t; + static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) { + LCDD* lcdd = (LCDD*) arg[0]; + xml_h* elt = (xml_h*) arg[1]; + Ref_t handle = DD4hep::Geometry::XMLElementFactory<P>::create(*lcdd, *elt); + *(void**) retaddr = handle.ptr(); + } + }; + template <typename P> class Factory<P, long(DD4hep::Geometry::LCDD*, DD4hep::XML::Handle_t*)> { public: typedef DD4hep::Geometry::LCDD LCDD; @@ -213,6 +226,14 @@ namespace { #define DECLARE_NAMED_DETELEMENT_FACTORY(n,x) \ DD4HEP_PLUGINSVC_FACTORY(n::x,x,DD4hep::NamedObject*(DD4hep::Geometry::LCDD*,DD4hep::XML::Handle_t*,DD4hep::Geometry::Ref_t*),__LINE__) + +#define DECLARE_VOLUME_FACTORY(x) \ + DD4HEP_PLUGINSVC_FACTORY(x,x,TGeoVolume*(DD4hep::Geometry::LCDD*,DD4hep::XML::Handle_t*),__LINE__) +#define DECLARE_NAMED_VOLUME_FACTORY(n,x) \ + DD4HEP_PLUGINSVC_FACTORY(n::x,x,TGeoVolume*(DD4hep::Geometry::LCDD*,DD4hep::XML::Handle_t*),__LINE__) + + + #define DECLARE_APPLY(name,func) \ namespace DD4hep { namespace Geometry { namespace { struct name {}; } \ template <> long ApplyFactory<name>::create(DD4hep::Geometry::LCDD& l,int n,char** a) {return func(l,n,a);} }} \ @@ -235,6 +256,15 @@ namespace { using DD4hep::Geometry::xml_element_##name; \ DD4HEP_PLUGINSVC_FACTORY(xml_element_##name,name,DD4hep::NamedObject*(DD4hep::Geometry::LCDD*,DD4hep::XML::Handle_t*),__LINE__) +#define DECLARE_XMLVOLUME(name,func) \ + namespace DD4hep { namespace Geometry { namespace { struct xml_element_##name {}; } \ + template <> DD4hep::Geometry::Ref_t XMLElementFactory<DD4hep::Geometry::xml_element_##name>::create(DD4hep::Geometry::LCDD& l,DD4hep::XML::Handle_t e) {return func(l,e);} }} \ + using DD4hep::Geometry::xml_element_##name; \ + DD4HEP_PLUGINSVC_FACTORY(xml_element_##name,name,TGeoVolume*(DD4hep::Geometry::LCDD*,DD4hep::XML::Handle_t*),__LINE__) + + + + #define DECLARE_XML_DOC_READER(name,func) \ namespace DD4hep { namespace Geometry { namespace { struct xml_document_##name {}; } \ template <> long XMLDocumentReaderFactory<DD4hep::Geometry::xml_document_##name>::create(DD4hep::Geometry::LCDD& l,DD4hep::XML::Handle_t e) {return func(l,e);} }} \ diff --git a/DDCore/include/XML/Utilities.h b/DDCore/include/XML/Utilities.h index 788e7df679375bc5d9989401cea1e36a8719bda9..caf83c2ca38f02f79112d8bdf2e18161b0a7edb0 100644 --- a/DDCore/include/XML/Utilities.h +++ b/DDCore/include/XML/Utilities.h @@ -21,6 +21,7 @@ namespace DD4hep { /// Create a solid shape using the plugin mechanism from the attributes of the XML element Geometry::Solid createShape(Geometry::LCDD& lcdd, const std::string& shape_type, XML::Element element); + Geometry::Volume createVolume(Geometry::LCDD& lcdd, const std::string& volume_type, XML::Element element); } /* End namespace XML */ } /* End namespace DD4hep */ diff --git a/DDCore/src/Plugins.cpp b/DDCore/src/Plugins.cpp index e50412325930e8fa166ed5f5ea0bc52c83ee334a..c405237f45215fc23f9597266e1ecfa3f4b65f73 100644 --- a/DDCore/src/Plugins.cpp +++ b/DDCore/src/Plugins.cpp @@ -80,6 +80,7 @@ string PluginDebug::missingFactory(const string& name) const { DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(NamedObject*, (Geometry::LCDD*,XML::Handle_t*,Geometry::Ref_t*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(NamedObject*, (Geometry::LCDD*,XML::Handle_t*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(NamedObject*, (Geometry::LCDD*)) +DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(TGeoVolume*, (Geometry::LCDD*,XML::Handle_t*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*,XML::Handle_t*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*,XML::Handle_t const*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*, int, char**)) diff --git a/DDCore/src/XML/Utilities.cpp b/DDCore/src/XML/Utilities.cpp index dfe91e777cf136e7585ec7c5b467aa8c6a09a7aa..64b30e5594fd5d20fdbb88da63b3d30d1b56d8e3 100644 --- a/DDCore/src/XML/Utilities.cpp +++ b/DDCore/src/XML/Utilities.cpp @@ -29,3 +29,19 @@ DD4hep::XML::createShape(Geometry::LCDD& lcdd, const std::string& shape_type, XM } return solid; } + + +/// Create a solid shape using the plugin mechanism from the attributes of the XML element +Geometry::Volume +DD4hep::XML::createVolume(Geometry::LCDD& lcdd, const std::string& volume_type, XML::Element element) { + string fac = volume_type + "_volume"; + XML::Handle_t volume_elt = element; + Geometry::Volume volume = Geometry::Ref_t(PluginService::Create<TGeoVolume*>(fac, &lcdd, &volume_elt)); + if ( !volume.isValid() ) { + PluginDebug dbg; + PluginService::Create<NamedObject*>(volume_type, &lcdd, &volume_elt); + except("XML::createVolume","Failed to create volume of type %s [%s]", + volume_type.c_str(),dbg.missingFactory(fac).c_str()); + } + return volume; +} diff --git a/DDDetectors/src/Envelope_geo.cpp b/DDDetectors/src/Envelope_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e220f3522295eecebe0894925f5e0b140ff83428 --- /dev/null +++ b/DDDetectors/src/Envelope_geo.cpp @@ -0,0 +1,92 @@ +// $Id: $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : F.Gaede +// +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "XML/Utilities.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +/** Create an envelope for subdetectors - calls a plugin + * for the volume to be used, which is specified in the type attribute + * of the <volume/> child element. If no volume is specified + * an assembly is created. The actual subdetector is specified + * in the <composite/> elements' name attribute. The placement + * of the envelope volume can be optionally specified in the + * <position/> and <rotation/> elements. + * + * @author F.Gaede CERN/DESY + * @version $Id:$ + */ +static Ref_t create_Envelope(LCDD& lcdd, xml_h e, Ref_t) { + + xml_det_t x_det (e); + string det_name = x_det.nameStr(); + DetElement sdet(det_name, x_det.id()); + Volume vol; + + double xpos = 0. ; + double ypos = 0. ; + double zpos = 0. ; + double xrot = 0. ; + double yrot = 0. ; + double zrot = 0. ; + + if ( x_det.hasChild(_U(volume)) ) { + + xml_comp_t x_vol = x_det.child(_U(volume)); + + string type = x_vol.typeStr(); + + vol = XML::createVolume(lcdd, type, x_vol); + + if( x_vol.hasChild( _U(position) ) ){ + xpos = x_vol.position().x() ; + ypos = x_vol.position().y() ; + zpos = x_vol.position().z() ; + } + + if( x_vol.hasChild( _U(rotation) ) ){ + xrot = x_vol.rotation().x() ; + yrot = x_vol.rotation().y() ; + zrot = x_vol.rotation().z() ; + } + + printout(DEBUG,det_name,"+++ Creating envelope volume with of type:%s",type.c_str()); + + } + else { + printout(DEBUG,det_name,"+++ Creating detector assembly without shape"); + vol = Assembly(det_name); + } + + for(xml_coll_t c(x_det,_U(composite)); c; ++c) { + xml_dim_t component = c; + string nam = component.nameStr(); + lcdd.declareMotherVolume( nam, vol); + } + + vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + + Position pos( xpos, ypos, zpos ) ; + RotationZYX rot( zrot, yrot , xrot ); + Transform3D trans( rot, pos); + + Volume mother = lcdd.pickMotherVolume(sdet) ; + + PlacedVolume pv = mother.placeVolume( vol, trans ); + + sdet.setPlacement( pv ); + return sdet; +} + +DECLARE_DETELEMENT(DD4hep_Envelope,create_Envelope)