From 36280e888f84915a6a296fa55a0d26d06eff9bcf Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 11 Mar 2020 11:31:44 +0100 Subject: [PATCH] Finalize CAD volume plugin --- DDCAD/include/DDCAD/ASSIMPReader.h | 2 +- DDCAD/include/DDCAD/InputReader.h | 2 +- DDCAD/src/ASSIMPReader.cpp | 10 +- DDCAD/src/plugins/CADPlugins.cpp | 145 ++++++++++++++- DDCore/include/DD4hep/DDTest.h | 176 ++++++++++++++++++ DDCore/src/plugins/ShapePlugins.cpp | 14 +- examples/ClientTests/compact/CheckShape.xml | 19 +- .../DDCAD/compact/Check_Shape_MS3D_jeep.xml | 2 +- .../DDCAD/compact/Check_Shape_OBJ_spider.xml | 2 +- examples/DDCAD/compact/Check_Shape_Test1.xml | 2 +- .../DDCAD/compact/MultiShape_MS3D_jeep.xml | 52 ++++++ 11 files changed, 403 insertions(+), 23 deletions(-) create mode 100644 DDCore/include/DD4hep/DDTest.h create mode 100644 examples/DDCAD/compact/MultiShape_MS3D_jeep.xml diff --git a/DDCAD/include/DDCAD/ASSIMPReader.h b/DDCAD/include/DDCAD/ASSIMPReader.h index 8f87caac2..c1c71e330 100644 --- a/DDCAD/include/DDCAD/ASSIMPReader.h +++ b/DDCAD/include/DDCAD/ASSIMPReader.h @@ -31,7 +31,7 @@ namespace dd4hep { virtual ~ASSIMPReader() = default; /// Read input file virtual std::vector<std::unique_ptr<TGeoTessellated> > - read(const std::string& source) const override; + read(const std::string& source, double unit_Length) const override; }; } /* End namespace cad */ diff --git a/DDCAD/include/DDCAD/InputReader.h b/DDCAD/include/DDCAD/InputReader.h index f7ecaa573..33047cfab 100644 --- a/DDCAD/include/DDCAD/InputReader.h +++ b/DDCAD/include/DDCAD/InputReader.h @@ -37,7 +37,7 @@ namespace dd4hep { virtual ~InputReader(); /// Read input file virtual std::vector<std::unique_ptr<TGeoTessellated> > - read(const std::string& source) const = 0; + read(const std::string& source, double unit_length) const = 0; }; } /* End namespace cad */ diff --git a/DDCAD/src/ASSIMPReader.cpp b/DDCAD/src/ASSIMPReader.cpp index d6ff10966..4b7ffd606 100644 --- a/DDCAD/src/ASSIMPReader.cpp +++ b/DDCAD/src/ASSIMPReader.cpp @@ -28,7 +28,7 @@ using namespace dd4hep::cad; /// Read input file vector<unique_ptr<TGeoTessellated> > -ASSIMPReader::read(const string& source) const { +ASSIMPReader::read(const string& source, double unit_length) const { vector<unique_ptr<TGeoTessellated> > result; unique_ptr<Assimp::Importer> importer = make_unique<Assimp::Importer>(); int flags = aiProcess_Triangulate|aiProcess_JoinIdenticalVertices|aiProcess_CalcTangentSpace; @@ -36,6 +36,7 @@ ASSIMPReader::read(const string& source) const { if ( !scene ) { except("ASSIMPReader","+++ FileNotFound: %s",source.c_str()); } + double unit = unit_length; for (unsigned int index = 0; index < scene->mNumMeshes; index++) { aiMesh* mesh = scene->mMeshes[index]; if ( mesh->mNumFaces > 0 ) { @@ -45,9 +46,9 @@ ASSIMPReader::read(const string& source) const { for(unsigned int i=0; i < mesh->mNumFaces; i++) { const aiFace& face = mesh->mFaces[i]; const unsigned int* idx = face.mIndices; - Tessellated::Vertex_t a(v[idx[0]].x, v[idx[0]].y, v[idx[0]].z); - Tessellated::Vertex_t b(v[idx[1]].x, v[idx[1]].y, v[idx[1]].z); - Tessellated::Vertex_t c(v[idx[2]].x, v[idx[2]].y, v[idx[2]].z); + Tessellated::Vertex_t a(v[idx[0]].x*unit, v[idx[0]].y*unit, v[idx[0]].z*unit); + Tessellated::Vertex_t b(v[idx[1]].x*unit, v[idx[1]].y*unit, v[idx[1]].z*unit); + Tessellated::Vertex_t c(v[idx[2]].x*unit, v[idx[2]].y*unit, v[idx[2]].z*unit); shape->AddFacet(a,b,c); #if 0 if ( scene->HasMaterials() ) { @@ -65,4 +66,3 @@ ASSIMPReader::read(const string& source) const { } return result; } - diff --git a/DDCAD/src/plugins/CADPlugins.cpp b/DDCAD/src/plugins/CADPlugins.cpp index bd9df0b9c..62a98425e 100644 --- a/DDCAD/src/plugins/CADPlugins.cpp +++ b/DDCAD/src/plugins/CADPlugins.cpp @@ -26,7 +26,8 @@ using namespace dd4hep::detail; static Handle<TObject> create_CAD_Shape(Detector&, xml_h e) { xml_elt_t elt(e); string fname = elt.attr<string>(_U(ref)); - auto shapes = cad::ASSIMPReader().read(fname); + double unit = elt.hasAttr(_U(unit)) ? elt.attr<double>(_U(unit)) : dd4hep::cm; + auto shapes = cad::ASSIMPReader().read(fname, unit); if ( shapes.empty() ) { except("CAD_Shape","+++ CAD file: %s does not contain any " "understandable tessellated shapes.", fname.c_str()); @@ -56,10 +57,11 @@ static Handle<TObject> create_CAD_Shape(Detector&, xml_h e) { DECLARE_XML_SHAPE(CAD_Shape__shape_constructor,create_CAD_Shape) -static Handle<TObject> create_CAD_MultiShape(Detector&, xml_h e) { +static Handle<TObject> create_CAD_MultiShape_Assembly(Detector&, xml_h e) { xml_elt_t elt(e); string fname = elt.attr<string>(_U(ref)); - auto shapes = cad::ASSIMPReader().read(fname); + double unit = elt.hasAttr(_U(unit)) ? elt.attr<double>(_U(unit)) : dd4hep::cm; + auto shapes = cad::ASSIMPReader().read(fname, unit); if ( shapes.empty() ) { except("CAD_Shape","+++ CAD file: %s does not contain any " "understandable tessellated shapes.", fname.c_str()); @@ -75,4 +77,139 @@ static Handle<TObject> create_CAD_MultiShape(Detector&, xml_h e) { if ( elt.hasAttr(_U(name)) ) assembly->SetName(elt.attr<string>(_U(name)).c_str()); return assembly; } -DECLARE_XML_SHAPE(CAD_MultiShape__volume_constructor,create_CAD_MultiShape) +DECLARE_XML_VOLUME(CAD_Assembly__volume_constructor,create_CAD_MultiShape_Assembly) + + +/** + * <XXX ref="file-name" material="material-name"> + * <material name="material-name"/> <!-- alternative: child or attr --> + * + * Envelope: Use special envelop shape (default: assembly) + * The envelope tag must match the expected pattern of the utility + * dd4hep::xml::createStdVolume(Detector& desc, xml::Element e) + * <envelope name="volume-name" material="material-name"> + * <shape name="shape-name" type="shape-type" args....> + * </shape> + * </envelope> + * + * Option 1: No additional children. use default material + * and place all children in the origin of the envelope + * + * Option 2: Volume with default material + * <volume name="vol-name"/> + * + * Option 3: Volume with non-default material + * <volume name="vol-name" material="material-name"/> + * + * Option 4: Volume with optional placement. No position = (0,0,0), No rotation = (0,0,0) + * <volume name="vol-name" material="material-name"/> + * <position x="0" y="0" z="5*cm"/> + * <rotation x="0" y="0" z="0.5*pi*rad"/> + * </volume> + * + * For sensitive volumes: add physical volume IDs: + * <volume name="vol-name" material="material-name"/> + * <physvolid name="layer" value="1"/> + * <physvolid name="slice" value="10"/> + * </volume> + * + * </XXX> + */ +static Handle<TObject> create_CAD_Volume(Detector& dsc, xml_h e) { + xml_elt_t elt(e); + string fname = elt.attr<string>(_U(ref)); + double unit = elt.attr<double>(_U(unit)); + auto shapes = cad::ASSIMPReader().read(fname, unit); + if ( shapes.empty() ) { + except("CAD_Volume","+++ CAD file: %s does not contain any " + "understandable tessellated shapes.", fname.c_str()); + } + Volume envelope; + if ( elt.hasChild(_U(envelope)) ) { + string typ = "DD4hep_StdVolume"; + xml_h x_env = elt.child(_U(envelope)); + TObject* pvol = PluginService::Create<TObject*>(typ, &dsc, &x_env); + envelope = dynamic_cast<TGeoVolume*>(pvol); + if ( !envelope.isValid() ) { + except("CAD_Volume", + "+++ Unable to determine envelope to CAD shape: %s",fname.c_str()); + } + } + else { + envelope = Assembly("envelope"); + } + xml_dim_t x_envpos = elt.child(_U(position),false); + xml_dim_t x_envrot = elt.child(_U(rotation),false); + Position env_pos; + RotationZYX env_rot; + if ( x_envpos && x_envrot ) { + env_rot = RotationZYX(x_envrot.z(0), x_envrot.y(0), x_envrot.x(0)); + env_pos = Position(x_envpos.x(0), x_envpos.y(0), x_envpos.z(0)); + } + else if ( x_envpos ) + env_pos = Position(x_envpos.x(0), x_envpos.y(0), x_envpos.z(0)); + else if ( x_envrot ) + env_rot = RotationZYX(x_envrot.z(0), x_envrot.y(0), x_envrot.x(0)); + + Transform3D env_trafo(env_rot, env_pos); + Material default_material; + xml_dim_t x_mat = elt.child(_U(material),false); + if ( x_mat.ptr() ) default_material = dsc.material(x_mat.nameStr()); + else if ( elt.hasAttr(_U(material)) ) default_material = dsc.material(elt.attr<string>(_U(material))); + + if ( elt.hasChild(_U(volume)) ) { + map<int, xml_h> shape_map; + for (xml_coll_t c(elt,_U(volume)); c; ++c ) + shape_map.emplace(xml_dim_t(c).id(),c); + + for (size_t i=0; i < shapes.size(); ++i) { + Solid sol = shapes[i].release(); + Material mat = default_material; + auto is = shape_map.find(i); + if ( is == shape_map.end() ) { + Volume vol(_toString(int(i),"vol_%d"), sol, mat); + envelope.placeVolume(vol); + } + else { + xml_dim_t x_vol = (*is).second; + xml_dim_t x_pos = x_vol.child(_U(position),false); + xml_dim_t x_rot = x_vol.child(_U(rotation),false); + string vnam = x_vol.hasAttr(_U(name)) ? x_vol.attr<string>(_U(name)) : _toString(int(i),"vol_%d"); + + if ( x_vol.hasAttr(_U(material)) ) { + mat = dsc.material(x_vol.attr<string>(_U(material))); + } + Position pos; + RotationZYX rot; + if ( x_pos && x_rot ) { + rot = RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)); + pos = Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)); + } + else if ( x_pos ) + pos = Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)); + else if ( x_rot ) + rot = RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)); + + Volume vol(vnam, sol, mat); + PlacedVolume pv = envelope.placeVolume(vol,env_trafo*Transform3D(rot, pos)); + vol.setAttributes(dsc, x_vol.regionStr(), x_vol.limitsStr(), x_vol.visStr()); + for (xml_coll_t cc(x_vol,_U(physvolid)); cc; ++cc ) { + xml_dim_t vid = cc; + pv.addPhysVolID(vid.nameStr(), vid.attr<int>(_U(value))); + } + } + } + } + else { + for(size_t i=0; i < shapes.size(); ++i) { + Solid solid = shapes[i].release(); + if ( solid.isValid() ) { + Volume vol(_toString(int(i),"vol_%d"), solid, default_material); + envelope.placeVolume(vol); + } + } + } + if ( elt.hasAttr(_U(name)) ) envelope->SetName(elt.attr<string>(_U(name)).c_str()); + return envelope; +} +DECLARE_XML_VOLUME(CAD_MultiVolume__volume_constructor,create_CAD_Volume) diff --git a/DDCore/include/DD4hep/DDTest.h b/DDCore/include/DD4hep/DDTest.h new file mode 100644 index 000000000..9c91a727b --- /dev/null +++ b/DDCore/include/DD4hep/DDTest.h @@ -0,0 +1,176 @@ +#include <iostream> +#include <sstream> +#include <stdlib.h> + +namespace dd4hep{ + + /// Simple class for defining unit tests. + /** Use in main program that is added as a test to ctest: + * + * DDTest test = DDTest( "example" ) ; + * test.log( "example test" ); + * test( "Example", "Example", "example test - string comparison " ); // this test will pass + * test( "Example", "BadExample", "example test - string comparison " ); // this test will fail + * + * @author F.Gaede, DESY, 2014 + * based on original version from J.Engels + */ + class DDTest{ + + public: + /// Default constructor + DDTest() = delete; + + /// Copy constructor + DDTest(const DDTest& copy) = delete; + + /// Assignment operator + DDTest& operator=(const DDTest& copy) = delete; + + + /** Only constructor + */ + DDTest( const std::string& testname, std::ostream& stream=std::cout ) : + _testname(testname), + _out(stream), + _failed(0), + _passed(0), + _last_test_status(false) { + + _out << std::endl << "[" << _testname << "] "; + + _out << "****************************** TEST_BEGIN ******************************" << std::endl << std::endl; + } + + + + /** Destructor - print summary of tests passed and failed + */ + ~DDTest(){ + + std::stringstream sstr ; + + sstr << std::endl; + sstr << "[" << _testname << "] number of tests PASSED : " << _passed << std::endl ; + sstr << "[" << _testname << "] number of tests FAILED : " << _failed << std::endl ; + sstr << std::endl; + + sstr << "[" << _testname << "] " ; + sstr << "****************************** " ; + sstr << ( _failed == 0 ? "TEST_PASSED" : "TEST_FAILED" ) ; + sstr << " ******************************" ; + sstr << std::endl << std::endl ; + + _out << sstr.str() ; + + if( _failed != 0 ) exit(1) ; + + } + + + /** Operator for calling a test - test is passed if v1 == v2 + */ + template <class V1, class V2 > + void operator()(const V1& v1, const V2& v2, const std::string& name ) { + + if ( ! (v1 == v2) ) { + + std::stringstream sstr ; + sstr << " " << name<< " : [" << v1 << "] != [" << v2 <<"]" ; + + error( sstr.str() ) ; + + } else { + + std::stringstream sstr ; + sstr << " " << name<< " : [" << v1 << "] == [" << v2 <<"]" ; + + pass( sstr.str() ) ; + } + + return ; + } + + /** Operator for calling a test - test is passed if (!c)==false + */ + template <class Cond > + void operator()(const Cond& c, const std::string& name ) { + + if ( ! (c) ) { + + std::stringstream sstr ; + sstr << " " << name<< " : [" << c << "] " ; + + error( sstr.str() ) ; + + } else { + + std::stringstream sstr ; + sstr << " " << name<< " : [" << c << "] " ; + + pass( sstr.str() ) ; + } + return ; + } + + + /** Simple log message */ + void log( const std::string& msg ){ + _out << "[" << _testname << "] " << msg << std::endl; + } + + + /** print message when test passed */ + void pass( const std::string& msg ){ + + _passed++; + _last_test_status = true ; + + _out << "[" << _testname << "] test " << last_test_status() << ": " << msg << std::endl; + } + + + + /** print message when test failed */ + void error( const std::string& msg ){ + + _failed++; + _last_test_status = false ; + + std::stringstream errmsg; + // errmsg << std::endl; + errmsg << "[" << _testname << "] ##################### TEST_FAILED ######################" << std::endl; + errmsg << "[" << _testname << "] ### ERROR: " << msg << std::endl; + errmsg << "[" << _testname << "] ########################################################" << std::endl; + // errmsg << std::endl; + + _out << errmsg.str(); + + // also send error to stderr + //std::cerr << errmsg.str(); + } + + /** Fatal error ...*/ + void fatal_error( const std::string& msg ){ + error( msg ); + _out << "FATAL ERROR OCCURRED, program will exit now !!" << std::endl ; + exit(1); + } + + /** Return the status from the last test - either PASSED or FAILED */ + const char* last_test_status(){ + return ( _last_test_status ? "PASSED" : "FAILED" ) ; + } + + private: + + std::string _testname ; + std::ostream& _out = std::cout; + + unsigned int _failed = 0; // number of failed tests + unsigned int _passed = 0; // number of passed tests + bool _last_test_status = false; // true if last test succeeded, false otherwise + }; + + +} // end namespace diff --git a/DDCore/src/plugins/ShapePlugins.cpp b/DDCore/src/plugins/ShapePlugins.cpp index e9427fce0..6724799e3 100644 --- a/DDCore/src/plugins/ShapePlugins.cpp +++ b/DDCore/src/plugins/ShapePlugins.cpp @@ -541,6 +541,18 @@ static Handle<TObject> create_BooleanMulti(Detector& description, xml_h element) } DECLARE_XML_SHAPE(BooleanShape__shape_constructor,create_BooleanMulti) +static Handle<TObject> create_std_volume(Detector& description, xml_h e) { + return xml::createStdVolume(description, e); +} +DECLARE_XML_VOLUME(DD4hep_StdVolume,create_std_volume) + +static Handle<TObject> create_gen_volume(Detector& description, xml_h e) { + xml_dim_t elt = e; + string typ = elt.attr<string>(_U(type)); + return xml::createVolume(description, typ, e); +} +DECLARE_XML_VOLUME(DD4hep_GenericVolume,create_gen_volume) + TGeoCombiTrans* createPlacement(const Rotation3D& iRot, const Position& iTrans) { double elements[9]; iRot.GetComponents(elements); @@ -569,7 +581,7 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */) { Volume volume; string shape_type = shape.typeStr(); - if ( shape_type == "CAD_MultiShape" ) { + if ( shape_type == "CAD_Assembly" || shape_type == "CAD_MultiVolume" ) { volume = xml::createVolume(description, shape_type, shape); solid = volume->GetShape(); } diff --git a/examples/ClientTests/compact/CheckShape.xml b/examples/ClientTests/compact/CheckShape.xml index c15280102..12a6d2db9 100644 --- a/examples/ClientTests/compact/CheckShape.xml +++ b/examples/ClientTests/compact/CheckShape.xml @@ -26,14 +26,17 @@ <display> <vis name="InvisibleNoDaughters" showDaughters="false" visible="false"/> <vis name="InvisibleWithDaughters" showDaughters="true" visible="false"/> - <vis name="Shape1_vis_20" alpha="0.2" r="0.9" g="0.8" b="0.8" showDaughters="true" visible="true"/> + <vis name="Shape1_vis_20" alpha="0.2" r="0.9" g="0.8" b="0.8" showDaughters="true" visible="true"/> <vis name="ShapeGray_vis_50" alpha="0.5" r="0.9" g="0.8" b="0.8" showDaughters="true" visible="true"/> - <vis name="Shape1_vis" alpha="1.0" r="1" g="0" b="0" showDaughters="true" visible="true"/> - <vis name="Shape2_vis" alpha="1.0" r="0" g="1" b="0" showDaughters="true" visible="true"/> - <vis name="Shape3_vis" alpha="1.0" r="0" g="0" b="1" showDaughters="true" visible="true"/> - <vis name="Shape4_vis" alpha="1.0" r="1" g="1" b="0" showDaughters="true" visible="true"/> - <vis name="Shape5_vis" alpha="1.0" r="1" g="0" b="1" showDaughters="true" visible="true"/> - <vis name="Shape6_vis" alpha="1.0" r="0" g="1" b="1" showDaughters="true" visible="true"/> - <vis name="Shape_grey" alpha="1.0" r="0.4" g="0.4" b="0.4" showDaughters="true" visible="true"/> + <vis name="Shape0_vis" alpha="1.0" r="0" g="1" b="1" showDaughters="true" visible="true"/> + <vis name="Shape1_vis" alpha="1.0" r="1" g="0" b="0" showDaughters="true" visible="true"/> + <vis name="Shape2_vis" alpha="1.0" r="0" g="1" b="0" showDaughters="true" visible="true"/> + <vis name="Shape3_vis" alpha="1.0" r="0" g="0" b="1" showDaughters="true" visible="true"/> + <vis name="Shape4_vis" alpha="1.0" r="1" g="1" b="0" showDaughters="true" visible="true"/> + <vis name="Shape5_vis" alpha="1.0" r="1" g="0" b="1" showDaughters="true" visible="true"/> + <vis name="Shape6_vis" alpha="1.0" r="0.5" g="0.5" b="0" showDaughters="true" visible="true"/> + <vis name="Shape7_vis" alpha="1.0" r="0" g="0.5" b="0.5" showDaughters="true" visible="true"/> + <vis name="Shape8_vis" alpha="0.5" r="0.0" g="0.4" b="0.4" showDaughters="true" visible="true"/> + <vis name="Shape_grey" alpha="0.5" r="0.0" g="0.4" b="0.4" showDaughters="true" visible="true"/> </display> </lccdd> diff --git a/examples/DDCAD/compact/Check_Shape_MS3D_jeep.xml b/examples/DDCAD/compact/Check_Shape_MS3D_jeep.xml index ddf46cabb..5fd5ac794 100644 --- a/examples/DDCAD/compact/Check_Shape_MS3D_jeep.xml +++ b/examples/DDCAD/compact/Check_Shape_MS3D_jeep.xml @@ -6,7 +6,7 @@ <detectors> <detector id="1" name="Shape_OBJ" type="DD4hep_TestShape_Creator"> <check vis="Shape1_vis"> - <shape type="CAD_MultiShape" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/MS3D/jeep1.ms3d"/> + <shape type="CAD_Assembly" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/MS3D/jeep1.ms3d"/> </check> <test1 type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/ref/Ref_OBJ_spider.txt" create="CheckShape_create"/> </detector> diff --git a/examples/DDCAD/compact/Check_Shape_OBJ_spider.xml b/examples/DDCAD/compact/Check_Shape_OBJ_spider.xml index d6f421edf..6654a13f4 100644 --- a/examples/DDCAD/compact/Check_Shape_OBJ_spider.xml +++ b/examples/DDCAD/compact/Check_Shape_OBJ_spider.xml @@ -6,7 +6,7 @@ <detectors> <detector id="1" name="Shape_OBJ" type="DD4hep_TestShape_Creator"> <check vis="Shape1_vis"> - <shape type="CAD_MultiShape" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/OBJ/spider.obj" mesh="0"/> + <shape type="CAD_Assembly" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/OBJ/spider.obj" mesh="0"/> </check> <test1 type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/ref/Ref_OBJ_spider.txt" create="CheckShape_create"/> </detector> diff --git a/examples/DDCAD/compact/Check_Shape_Test1.xml b/examples/DDCAD/compact/Check_Shape_Test1.xml index 4ccb12eeb..6553694a2 100644 --- a/examples/DDCAD/compact/Check_Shape_Test1.xml +++ b/examples/DDCAD/compact/Check_Shape_Test1.xml @@ -6,7 +6,7 @@ <detectors> <detector id="1" name="Shape_Collada" type="DD4hep_TestShape_Creator"> <check vis="Shape1_vis"> - <shape type="CAD_MultiShape" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/OBJ/spider.obj" mesh="0"/> + <shape type="CAD_Assembly" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/OBJ/spider.obj" mesh="0"/> </check> <test111 type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/ref/Ref_test.txt" create="CheckShape_create"/> <test type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/ref/Ref_test.txt" create="1"/> diff --git a/examples/DDCAD/compact/MultiShape_MS3D_jeep.xml b/examples/DDCAD/compact/MultiShape_MS3D_jeep.xml new file mode 100644 index 000000000..5853f9842 --- /dev/null +++ b/examples/DDCAD/compact/MultiShape_MS3D_jeep.xml @@ -0,0 +1,52 @@ +<lccdd> + <includes> + <gdmlFile ref="../../ClientTests/compact/CheckShape.xml"/> + </includes> + + <detectors> + <detector id="1" name="Shape_OBJ" type="DD4hep_TestShape_Creator"> + <check> + <shape type="CAD_MultiVolume" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/MS3D/jeep1.ms3d" unit="cm"> + + <!-- Envelope definition + This is optional: By default the child volumes are placed in an assembly. + --> + <envelope name="Garage" material="Air" vis="Shape_grey"> + <shape type="Box" dx="10*cm" dy="10*cm" dz="10*cm"/> + </envelope> + + <!-- Transformation defining the positioning of all sub-volumes within the envelope --> + <position x="-5*cm" y="0" z="0"/> + <rotation x="0" y="0" z="-pi/2*rad"/> + + <!-- These are the 4 wheels --> + <volume id="0" name="Wheel1" material="Iron" vis="Shape0_vis"> + <position x="5*cm" y="5*cm" z="0"/> + <rotation x="0" y="0" z="-pi/2*rad"/> + </volume> + <volume id="1" name="Wheel2" material="Iron" vis="Shape1_vis"> + <position x="2*cm" y="5*cm" z="0"/> + <rotation x="0" y="0" z="-pi/4*rad"/> + </volume> + <volume id="2" name="Wheel3" material="Iron" vis="Shape2_vis"> + <position x="-5*cm" y="5*cm" z="0"/> + <rotation x="0" y="0" z="pi/2*rad"/> + </volume> + <volume id="3" name="Wheel4" material="Iron" vis="Shape3_vis"> + <position x="-2*cm" y="5*cm" z="0"/> + <rotation x="0" y="0" z="pi/4*rad"/> + </volume> + + <!-- This is the rest of the jeep --> + <volume id="4" name="E" material="Iron" vis="Shape4_vis"> + </volume> + <volume id="5" name="F" material="Iron" vis="Shape5_vis"> + </volume> + <volume id="6" name="C" material="Iron" vis="Shape6_vis"> + </volume> + </shape> + </check> + + </detector> + </detectors> +</lccdd> -- GitLab