From d3019abf890cee7736f809f1c88f8585b0bf1952 Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Tue, 16 Jan 2024 13:52:34 +0100 Subject: [PATCH 1/8] Fix facetIsDegenerated utility function --- DDCAD/CMakeLists.txt | 4 +- DDCAD/include/DDCAD/Utilities.h | 15 +- examples/AlignDet/src/AlephTPC_geo.cpp | 282 ++++++++++++------------- 3 files changed, 151 insertions(+), 150 deletions(-) diff --git a/DDCAD/CMakeLists.txt b/DDCAD/CMakeLists.txt index a85572aff..8e9df077d 100644 --- a/DDCAD/CMakeLists.txt +++ b/DDCAD/CMakeLists.txt @@ -37,8 +37,8 @@ elseif(DD4HEP_LOAD_ASSIMP) ExternalProject_Add( assimp_project - SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/external/assimp - INSTALL_DIR ${CMAKE_INSTALL_PREFIX} + SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/external/assimp + INSTALL_DIR ${CMAKE_INSTALL_PREFIX} GIT_REPOSITORY https://github.com/assimp/assimp.git GIT_TAG v5.0.1 CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} diff --git a/DDCAD/include/DDCAD/Utilities.h b/DDCAD/include/DDCAD/Utilities.h index 6e12f0401..effbbeb5d 100644 --- a/DDCAD/include/DDCAD/Utilities.h +++ b/DDCAD/include/DDCAD/Utilities.h @@ -14,6 +14,7 @@ #define DDCAD_UTILITIES_H #include +#include #include #include @@ -63,13 +64,13 @@ namespace dd4hep { // // v1.z v2.z v3.z v1.z v2.z double det = 0.0 - + v1.x() * v2.y() * v3.z() - + v2.x() * v3.y() * v1.z() - + v3.x() * v1.y() * v2.z() - - v1.z() * v2.y() * v3.x() - - v2.z() * v3.y() * v1.x() - - v3.z() * v1.y() * v2.x(); - return det < epsilon; + + v1.x() * v2.y() * v3.z() + + v2.x() * v3.y() * v1.z() + + v3.x() * v1.y() * v2.z() + - v1.z() * v2.y() * v3.x() + - v2.z() * v3.y() * v1.x() + - v3.z() * v1.y() * v2.x(); + return std::fabs(det) < epsilon; } } } diff --git a/examples/AlignDet/src/AlephTPC_geo.cpp b/examples/AlignDet/src/AlephTPC_geo.cpp index 0c0fe041d..b4a089d03 100644 --- a/examples/AlignDet/src/AlephTPC_geo.cpp +++ b/examples/AlignDet/src/AlephTPC_geo.cpp @@ -164,133 +164,133 @@ static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector se if ( layer_vis.empty() ) layer_vis = sector_vis; if ( sector_type == 'K' ) { - double angle = M_PI/12.0; - double angle1 = std::tan(angle); - double v[8][2]; - v[0][0] = rmin; - v[0][1] = 0; - v[1][0] = rmin; - v[1][1] = rmin*angle1; - v[2][0] = rmax; - v[2][1] = rmax*angle1; - v[3][0] = rmax; - v[3][1] = 0; - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - EightPointSolid upper(layer_thickness/2,&v[0][0]); - - v[0][0] = rmin; - v[0][1] = 0; - v[1][0] = rmax; - v[1][1] = 0; - v[2][0] = rmax; - v[2][1] = -rmax*angle1; - v[3][0] = rmin; - v[3][1] = -rmin*angle1; - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - EightPointSolid lower(layer_thickness/2,&v[0][0]); - - v[0][0] = rmin; - v[0][1] = gap_half; - v[1][0] = rmin; - v[1][1] = rmin*angle1; - v[2][0] = rmax; - v[2][1] = rmax*angle1; - v[3][0] = rmax; - v[3][1] = gap_half; - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - EightPointSolid top(layer_thickness/2,&v[0][0]); - - v[0][0] = rmin; - v[0][1] = -gap_half; - v[1][0] = rmax; - v[1][1] = -gap_half; - v[2][0] = rmax; - v[2][1] = -rmax*angle1; - v[3][0] = rmin; - v[3][1] = -rmin*angle1; - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - EightPointSolid bottom(layer_thickness/2,&v[0][0]); - - UnionSolid u(UnionSolid(upper,lower),top,Rotation3D(RotationZ(2*(angle)))); - tm = UnionSolid(u,bottom,Rotation3D(RotationZ(-2*(angle)))); + double angle = M_PI/12.0; + double angle1 = std::tan(angle); + double v[8][2]; + v[0][0] = rmin; + v[0][1] = 0; + v[1][0] = rmin; + v[1][1] = rmin*angle1; + v[2][0] = rmax; + v[2][1] = rmax*angle1; + v[3][0] = rmax; + v[3][1] = 0; + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + EightPointSolid upper(layer_thickness/2,&v[0][0]); + + v[0][0] = rmin; + v[0][1] = 0; + v[1][0] = rmax; + v[1][1] = 0; + v[2][0] = rmax; + v[2][1] = -rmax*angle1; + v[3][0] = rmin; + v[3][1] = -rmin*angle1; + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + EightPointSolid lower(layer_thickness/2,&v[0][0]); + + v[0][0] = rmin; + v[0][1] = gap_half; + v[1][0] = rmin; + v[1][1] = rmin*angle1; + v[2][0] = rmax; + v[2][1] = rmax*angle1; + v[3][0] = rmax; + v[3][1] = gap_half; + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + EightPointSolid top(layer_thickness/2,&v[0][0]); + + v[0][0] = rmin; + v[0][1] = -gap_half; + v[1][0] = rmax; + v[1][1] = -gap_half; + v[2][0] = rmax; + v[2][1] = -rmax*angle1; + v[3][0] = rmin; + v[3][1] = -rmin*angle1; + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + EightPointSolid bottom(layer_thickness/2,&v[0][0]); + + UnionSolid u(UnionSolid(upper,lower),top,Rotation3D(RotationZ(2*(angle)))); + tm = UnionSolid(u,bottom,Rotation3D(RotationZ(-2*(angle)))); } else { - double overlap = sector_type=='W' ? 20 : -20; - double angle = M_PI/12.0; - double angle1 = std::tan(angle); - double v[8][2], dr = 0; - - if ( sector_type == 'W' ) { - rmax += overlap*std::tan(angle/2); - dr = overlap*std::tan(angle/2); - } - - v[0][0] = rmin; - v[0][1] = -rmin*angle1+gap_half; - v[1][0] = rmin; - v[1][1] = rmin*angle1-gap_half; - v[2][0] = rmax; - v[2][1] = rmax*angle1-gap_half; - v[3][0] = rmax; - v[3][1] = -rmax*angle1+gap_half; - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - printCoordinates(sector_type,"t2:",v); - EightPointSolid sectorSolid(layer_thickness/2,&v[0][0]); - - if ( sector_type=='W' ) { - v[0][0] = (rmax+rmin)/2-dr; - v[0][1] = (rmax+rmin)/2*angle1-gap_half; - v[1][0] = rmax+0.0001; - v[1][1] = rmax*angle1-gap_half; - v[2][0] = rmax+0.0001; - v[2][1] = (rmax-overlap)*angle1-gap_half; - v[3][0] = (rmax+rmin)/2-dr; - v[3][1] = (rmax+rmin-overlap)/2*angle1-gap_half; - } - else { - v[0][0] = (rmax+rmin)/2-dr; - v[0][1] = (rmax+rmin)/2*angle1-gap_half; - v[3][0] = rmax+0.0001; - v[3][1] = rmax*angle1-gap_half; - v[2][0] = rmax+0.0001; - v[2][1] = (rmax-overlap)*angle1-gap_half; - v[1][0] = (rmax+rmin)/2-dr; - v[1][1] = (rmax+rmin-overlap)/2*angle1-gap_half; - } - printCoordinates(sector_type,"upper_boolean:",v); - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - EightPointSolid upper_boolean((sector_type == 'W' ? 1.1 : 1.0) * layer_thickness/2,&v[0][0]); - - if ( sector_type=='W' ) { - v[0][0] = (rmax+rmin)/2-dr; - v[0][1] = -((rmax+rmin)/2*angle1-gap_half); - v[1][0] = (rmax+rmin)/2-dr; - v[1][1] = -((rmax+rmin-overlap)/2*angle1-gap_half); - v[2][0] = rmax+0.0001; - v[2][1] = -((rmax-overlap)*angle1-gap_half); - v[3][0] = rmax+0.0001; - v[3][1] = -(rmax*angle1-gap_half); - } - else { - v[0][0] = (rmax+rmin)/2-dr; - v[0][1] = -((rmax+rmin)/2*angle1-gap_half); - v[3][0] = (rmax+rmin)/2-dr; - v[3][1] = -((rmax+rmin-overlap)/2*angle1-gap_half); - v[2][0] = rmax+0.0001; - v[2][1] = -((rmax-overlap)*angle1-gap_half); - v[1][0] = rmax+0.0001; - v[1][1] = -(rmax*angle1-gap_half); - } - printCoordinates(sector_type,"lower_boolean:",v); - ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); - - // For W sectors make the subtraction solid slightly thicker to ensure everything is cut off - // and no left-overs from numerical precision are left. - EightPointSolid lower_boolean((sector_type == 'W' ? 1.1 : 1.0) * layer_thickness/2,&v[0][0]); - if ( sector_type == 'W' ) - tm = SubtractionSolid(SubtractionSolid(sectorSolid,upper_boolean),lower_boolean); - else - tm = UnionSolid(UnionSolid(sectorSolid,upper_boolean),lower_boolean); + double overlap = sector_type=='W' ? 20 : -20; + double angle = M_PI/12.0; + double angle1 = std::tan(angle); + double v[8][2], dr = 0; + + if ( sector_type == 'W' ) { + rmax += overlap*std::tan(angle/2); + dr = overlap*std::tan(angle/2); + } + + v[0][0] = rmin; + v[0][1] = -rmin*angle1+gap_half; + v[1][0] = rmin; + v[1][1] = rmin*angle1-gap_half; + v[2][0] = rmax; + v[2][1] = rmax*angle1-gap_half; + v[3][0] = rmax; + v[3][1] = -rmax*angle1+gap_half; + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + printCoordinates(sector_type,"t2:",v); + EightPointSolid sectorSolid(layer_thickness/2,&v[0][0]); + + if ( sector_type=='W' ) { + v[0][0] = (rmax+rmin)/2-dr; + v[0][1] = (rmax+rmin)/2*angle1-gap_half; + v[1][0] = rmax+0.0001; + v[1][1] = rmax*angle1-gap_half; + v[2][0] = rmax+0.0001; + v[2][1] = (rmax-overlap)*angle1-gap_half; + v[3][0] = (rmax+rmin)/2-dr; + v[3][1] = (rmax+rmin-overlap)/2*angle1-gap_half; + } + else { + v[0][0] = (rmax+rmin)/2-dr; + v[0][1] = (rmax+rmin)/2*angle1-gap_half; + v[3][0] = rmax+0.0001; + v[3][1] = rmax*angle1-gap_half; + v[2][0] = rmax+0.0001; + v[2][1] = (rmax-overlap)*angle1-gap_half; + v[1][0] = (rmax+rmin)/2-dr; + v[1][1] = (rmax+rmin-overlap)/2*angle1-gap_half; + } + printCoordinates(sector_type,"upper_boolean:",v); + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + EightPointSolid upper_boolean((sector_type == 'W' ? 1.1 : 1.0) * layer_thickness/2,&v[0][0]); + + if ( sector_type=='W' ) { + v[0][0] = (rmax+rmin)/2-dr; + v[0][1] = -((rmax+rmin)/2*angle1-gap_half); + v[1][0] = (rmax+rmin)/2-dr; + v[1][1] = -((rmax+rmin-overlap)/2*angle1-gap_half); + v[2][0] = rmax+0.0001; + v[2][1] = -((rmax-overlap)*angle1-gap_half); + v[3][0] = rmax+0.0001; + v[3][1] = -(rmax*angle1-gap_half); + } + else { + v[0][0] = (rmax+rmin)/2-dr; + v[0][1] = -((rmax+rmin)/2*angle1-gap_half); + v[3][0] = (rmax+rmin)/2-dr; + v[3][1] = -((rmax+rmin-overlap)/2*angle1-gap_half); + v[2][0] = rmax+0.0001; + v[2][1] = -((rmax-overlap)*angle1-gap_half); + v[1][0] = rmax+0.0001; + v[1][1] = -(rmax*angle1-gap_half); + } + printCoordinates(sector_type,"lower_boolean:",v); + ::memcpy(&v[4][0],&v[0][0],8*sizeof(double)); + + // For W sectors make the subtraction solid slightly thicker to ensure everything is cut off + // and no left-overs from numerical precision are left. + EightPointSolid lower_boolean((sector_type == 'W' ? 1.1 : 1.0) * layer_thickness/2,&v[0][0]); + if ( sector_type == 'W' ) + tm = SubtractionSolid(SubtractionSolid(sectorSolid,upper_boolean),lower_boolean); + else + tm = UnionSolid(UnionSolid(sectorSolid,upper_boolean),lower_boolean); } Volume secVol(name+"_sector_"+sector_type+_toString(i_layer,"_layer%d"),tm,description.material(layer_mat)); @@ -304,22 +304,22 @@ static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector se int j = i + (sector_type=='W' ? 1 : 0); double phi = dphi*j+shift + (sector_type=='K' ? 0 : M_PI/12.0); if ( sector_type == 'K' || (i%2)==0 ) { - Transform3D trA(RotationZYX(phi,0,0),Position(0,0,0.00001)); - Transform3D trB(RotationZYX(phi,0,0),Position(0,0,0.00001)); - - pv = endCapAVol.placeVolume(sector,trA); - pv.addPhysVolID("type", sector_type=='K' ? 1 : sector_type=='M' ? 2 : 3); - pv.addPhysVolID("sector",j); - DetElement sectorA(detA,detA.name()+_toString(sector_count,"_sector%02d"),1); - sectorA.setPlacement(pv); - - pv = endCapBVol.placeVolume(sector,trB); - pv.addPhysVolID("type", sector_type=='K' ? 1 : sector_type=='M' ? 2 : 3); - pv.addPhysVolID("sector",j); - DetElement sectorB(detB,detB.name()+_toString(sector_count,"_sector%02d"),1); - sectorB.setPlacement(pv); - cout << "Placed " << sector_type << " sector at phi=" << phi << endl; - ++sector_count; + Transform3D trA(RotationZYX(phi,0,0),Position(0,0,0.00001)); + Transform3D trB(RotationZYX(phi,0,0),Position(0,0,0.00001)); + + pv = endCapAVol.placeVolume(sector,trA); + pv.addPhysVolID("type", sector_type=='K' ? 1 : sector_type=='M' ? 2 : 3); + pv.addPhysVolID("sector",j); + DetElement sectorA(detA,detA.name()+_toString(sector_count,"_sector%02d"),1); + sectorA.setPlacement(pv); + + pv = endCapBVol.placeVolume(sector,trB); + pv.addPhysVolID("type", sector_type=='K' ? 1 : sector_type=='M' ? 2 : 3); + pv.addPhysVolID("sector",j); + DetElement sectorB(detB,detB.name()+_toString(sector_count,"_sector%02d"),1); + sectorB.setPlacement(pv); + cout << "Placed " << sector_type << " sector at phi=" << phi << endl; + ++sector_count; } } } From 8add72eac38112f95edf4ce81059a992801c93fe Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Tue, 16 Jan 2024 17:38:41 +0100 Subject: [PATCH 2/8] Add FiberTubeCalorimeter test detector. See https://github.com/AIDASoft/DD4hep/issues/1173 --- DDCore/src/plugins/DetectorCheck.cpp | 73 ++++---- .../compact/FiberTubeCalorimeter.xml | 110 +++++++++++ .../src/FiberTubeCalorimeter_geo.cpp | 177 ++++++++++++++++++ 3 files changed, 328 insertions(+), 32 deletions(-) create mode 100644 examples/ClientTests/compact/FiberTubeCalorimeter.xml create mode 100644 examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp diff --git a/DDCore/src/plugins/DetectorCheck.cpp b/DDCore/src/plugins/DetectorCheck.cpp index 21421a8a1..2add90095 100644 --- a/DDCore/src/plugins/DetectorCheck.cpp +++ b/DDCore/src/plugins/DetectorCheck.cpp @@ -97,6 +97,7 @@ namespace { bool check_placements { false }; bool check_volmgr { false }; bool check_sensitive { false }; + bool ignore_detector { false }; SensitiveDetector get_current_sensitive_detector(); @@ -449,7 +450,7 @@ void DetectorCheck::checkManagerSingleVolume(DetElement detector, PlacedVolume p if ( pv.volume().isSensitive() ) { PlacedVolume det_place = m_volMgr.lookupDetElementPlacement(vid); ++m_sens_counters.elements; - if ( pv.ptr() != det_place.ptr() ) { + if ( !ignore_detector && pv.ptr() != det_place.ptr() ) { err << "VolumeMgrTest: Wrong placement " << " got " << det_place.name() << " (" << (void*)det_place.ptr() << ")" << " instead of " << pv.name() << " (" << (void*)pv.ptr() << ") " @@ -551,33 +552,35 @@ void DetectorCheck::checkManagerSingleVolume(DetElement detector, PlacedVolume p printout(ERROR, m_det.name(), "DETELEMENT_PERSISTENCY FAILED: World transformation have DIFFERET pointer!"); ++m_place_counters.errors; } - - if ( pv.ptr() == det_elem.placement().ptr() ) { - // The computed transformation 'trafo' MUST be equal to: - // m_volMgr.worldTransformation(vid) AND det_elem.nominal().worldTransformation() - int res1 = detail::matrix::_matrixEqual(trafo, det_elem.nominal().worldTransformation()); - int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); - if ( res1 != detail::matrix::MATRICES_EQUAL || res2 != detail::matrix::MATRICES_EQUAL ) { - printout(ERROR, m_det.name(), "DETELEMENT_PLACEMENT FAILED: World transformation DIFFER."); - ++m_place_counters.errors; - } - else { - printout(INFO, m_det.name(), "DETELEMENT_PLACEMENT: PASSED. All matrices equal: %s", - volumeID(vid).c_str()); - } - } - else { - // The computed transformation 'trafo' MUST be equal to: - // m_volMgr.worldTransformation(vid) - // The det_elem.nominal().worldTransformation() however is DIFFERENT! - int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); - if ( res2 != detail::matrix::MATRICES_EQUAL ) { - printout(ERROR, m_det.name(), "VOLUME_PLACEMENT FAILED: World transformation DIFFER."); - ++m_place_counters.errors; + + if ( !ignore_detector ) { + if ( pv.ptr() == det_elem.placement().ptr() ) { + // The computed transformation 'trafo' MUST be equal to: + // m_volMgr.worldTransformation(vid) AND det_elem.nominal().worldTransformation() + int res1 = detail::matrix::_matrixEqual(trafo, det_elem.nominal().worldTransformation()); + int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); + if ( res1 != detail::matrix::MATRICES_EQUAL || res2 != detail::matrix::MATRICES_EQUAL ) { + printout(ERROR, m_det.name(), "DETELEMENT_PLACEMENT FAILED: World transformation DIFFER."); + ++m_place_counters.errors; + } + else { + printout(INFO, m_det.name(), "DETELEMENT_PLACEMENT: PASSED. All matrices equal: %s", + volumeID(vid).c_str()); + } } else { - printout(INFO, m_det.name(), "VOLUME_PLACEMENT: PASSED. All matrices equal: %s", - volumeID(vid).c_str()); + // The computed transformation 'trafo' MUST be equal to: + // m_volMgr.worldTransformation(vid) + // The det_elem.nominal().worldTransformation() however is DIFFERENT! + int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid)); + if ( res2 != detail::matrix::MATRICES_EQUAL ) { + printout(ERROR, m_det.name(), "VOLUME_PLACEMENT FAILED: World transformation DIFFER."); + ++m_place_counters.errors; + } + else { + printout(INFO, m_det.name(), "VOLUME_PLACEMENT: PASSED. All matrices equal: %s", + volumeID(vid).c_str()); + } } } } @@ -643,6 +646,7 @@ void DetectorCheck::help(int argc,char** argv) { " sensitive volume placements. \n\n" " NOTE: Option requires proper PhysVolID setup \n" " of the sensitive volume placements ! \n" + " -ignore_detector Ignore DetElement placement check for -volmgr \n" << std::endl; std::cout << "Arguments: " << std::endl; for(int iarg=0; iarg + + The compact format for the SCEPCAL IDEA from Sarah Eno + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:8,layer:12,tube:12,hole:3,type:3 + + + + + + + + + + + + + + + + + + diff --git a/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp new file mode 100644 index 000000000..ed2251b2b --- /dev/null +++ b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp @@ -0,0 +1,177 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// Specialized generic detector constructor for fiber tube calorimeter. +// See https://github.com/AIDASoft/DD4hep/issues/1173 for details +// +// Detector geometry structure +// +// /world_volume/FiberCalo/rowtube_1/brass_1/hole_1/quartz_1 +// /brass_2/hole_1/scintillator_1 brass_1 == brass_2 == brass....n +// /brass_3/hole_1/quartz_1 +// /brass_4/hole_1/scintillator_1 +// /brass_5/hole_1/quartz_1 +// brass_1/quartz_1 Volume(brass) / hole +// Volume(hole) / quartz +// alt: Volume(hole) / scintillator +// +// /world_volume/FiberCalo/rowtube_1/brass/quartz +// +// Dump using: +// geoPluginRun -input examples/ClientTests/compact/FiberTubeCalorimeter.xml \ +// -volmgr -print 3 -plugin DD4hep_DetectorCheck \ +// -name FiberTubeCalorimeter -geometry -structure -sensitive -volmgr -ignore +// +//========================================================================== +#include "DD4hep/DetFactoryHelper.h" + +using namespace std; +using namespace dd4hep; +using namespace dd4hep::detail; + +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { + constexpr double tol = 0.0; + xml_det_t x_det = e; + + // for volume tags in detector + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + Material air = description.air(); + + // pointer to finding dimensins text in xml file + // look in DDCore/include/Parsers/detail/Dimension.h for arguments + xml_comp_t x_dim = x_det.dimensions(); + double hthick = x_dim.thickness(); + double hzlength = x_dim.z_length()/2.; + double hzph = x_dim.z1(); + int Ncount = x_dim.numsides(); + double agap = x_dim.gap(); + double azmin = x_dim.zmin(); + + // these refer to different fields in the xml file for this detector + xml_comp_t fX_struct( x_det.child( _Unicode(structure) ) ); + xml_comp_t fX_absorb( fX_struct.child( _Unicode(absorb) ) ); + xml_comp_t fX_core1( fX_struct.child( _Unicode(core1) ) ); + xml_comp_t fX_core2( fX_struct.child( _Unicode(core2) ) ); + xml_comp_t fX_hole( fX_struct.child( _Unicode(hole) ) ); + xml_comp_t fX_phdet1( fX_struct.child( _Unicode(phdet1) ) ); + xml_comp_t fX_phdet2( fX_struct.child( _Unicode(phdet2) ) ); + + // detector element for entire detector. + DetElement sdet (det_name, det_id); + Volume motherVol = description.pickMotherVolume(sdet); + Box env_box ((2*Ncount+1)*(hthick+agap+tol),(2*Ncount+1)*(hthick+agap+tol), (hzlength+hzph+tol)); + Volume envelopeVol (det_name, env_box, air); + envelopeVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + Material mat; + Transform3D trafo; + PlacedVolume pv; + + pv = motherVol.placeVolume(envelopeVol, Position(0.,0.,azmin+hzlength+hzph+tol)); + pv.addPhysVolID("system", det_id); + sdet.setPlacement(pv); // associate the placed volume to the detector element + sens.setType("calorimeter"); + + // scint fiber + mat = description.material(fX_core1.materialStr()); + Volume fiber_scint_vol("fiber1", Tube(0.,fX_core1.rmax(), hzlength), mat); + fiber_scint_vol.setAttributes(description,fX_core1.regionStr(),fX_core1.limitsStr(),fX_core1.visStr()); + if ( fX_core1.isSensitive() ) { + fiber_scint_vol.setSensitiveDetector(sens); + } + + // quartz fiber + Tube fiber_quartz_tub(0.,fX_core2.rmax(), hzlength); + Volume fiber_quartz_vol("fiber_quartz", fiber_quartz_tub, description.material(fX_core2.materialStr())); + fiber_quartz_vol.setAttributes(description,fX_core2.regionStr(),fX_core2.limitsStr(),fX_core2.visStr()); + cout<<"fiber_quartz vis is "< Date: Wed, 17 Jan 2024 11:08:57 +0100 Subject: [PATCH 3/8] Polish FiberTubeCalorimeter example --- .../compact/FiberTubeCalorimeter.xml | 6 +- .../src/FiberTubeCalorimeter_geo.cpp | 89 ++++++++++++++----- 2 files changed, 68 insertions(+), 27 deletions(-) diff --git a/examples/ClientTests/compact/FiberTubeCalorimeter.xml b/examples/ClientTests/compact/FiberTubeCalorimeter.xml index 44cf6321e..41b322b38 100644 --- a/examples/ClientTests/compact/FiberTubeCalorimeter.xml +++ b/examples/ClientTests/compact/FiberTubeCalorimeter.xml @@ -98,9 +98,9 @@ zmin="-world_side/2.+2*killthick+edgeoffset+DRcrystallength+EcalHcalgap" z1="killthick"/> - - - + + + diff --git a/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp index ed2251b2b..99e50aacb 100644 --- a/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp +++ b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp @@ -28,12 +28,19 @@ // /world_volume/FiberCalo/rowtube_1/brass/quartz // // Dump using: -// geoPluginRun -input examples/ClientTests/compact/FiberTubeCalorimeter.xml \ -// -volmgr -print 3 -plugin DD4hep_DetectorCheck \ -// -name FiberTubeCalorimeter -geometry -structure -sensitive -volmgr -ignore +// $> geoPluginRun -input examples/ClientTests/compact/FiberTubeCalorimeter.xml +// -volmgr -print 3 -plugin DD4hep_DetectorCheck +// -name FiberTubeCalorimeter -geometry -structure -sensitive -volmgr -ignore +// +// Display using: +// $> geoDisplay examples/ClientTests/compact/FiberTubeCalorimeter.xml // //========================================================================== -#include "DD4hep/DetFactoryHelper.h" +#include +#include + + +#include using namespace std; using namespace dd4hep; @@ -77,6 +84,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s Material mat; Transform3D trafo; PlacedVolume pv; + Solid sol; pv = motherVol.placeVolume(envelopeVol, Position(0.,0.,azmin+hzlength+hzph+tol)); pv.addPhysVolID("system", det_id); @@ -84,84 +92,113 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s sens.setType("calorimeter"); // scint fiber + sol = Tube(0.,fX_core1.rmax(), hzlength); mat = description.material(fX_core1.materialStr()); - Volume fiber_scint_vol("fiber1", Tube(0.,fX_core1.rmax(), hzlength), mat); + Volume fiber_scint_vol(fX_core1.nameStr(), sol, mat); fiber_scint_vol.setAttributes(description,fX_core1.regionStr(),fX_core1.limitsStr(),fX_core1.visStr()); if ( fX_core1.isSensitive() ) { fiber_scint_vol.setSensitiveDetector(sens); } - + cout << setw(28) << left << fiber_scint_vol.name() + << " mat: " << setw(15) << left << mat.name() + << " vis: " << setw(15) << left<< fX_core1.visStr() + << " solid: " << setw(20) << left << sol.type() + << " sensitive: " << yes_no(fX_core1.isSensitive()) << endl; + // quartz fiber - Tube fiber_quartz_tub(0.,fX_core2.rmax(), hzlength); - Volume fiber_quartz_vol("fiber_quartz", fiber_quartz_tub, description.material(fX_core2.materialStr())); + sol = Tube(0.,fX_core2.rmax(), hzlength); + mat = description.material(fX_core2.materialStr()); + Volume fiber_quartz_vol(fX_core2.nameStr(), sol, mat); fiber_quartz_vol.setAttributes(description,fX_core2.regionStr(),fX_core2.limitsStr(),fX_core2.visStr()); - cout<<"fiber_quartz vis is "< Date: Wed, 17 Jan 2024 11:18:43 +0100 Subject: [PATCH 4/8] Increase tolerance when checking for degenerated facets. --- DDCAD/include/DDCAD/Utilities.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DDCAD/include/DDCAD/Utilities.h b/DDCAD/include/DDCAD/Utilities.h index effbbeb5d..ef5a4c89b 100644 --- a/DDCAD/include/DDCAD/Utilities.h +++ b/DDCAD/include/DDCAD/Utilities.h @@ -57,7 +57,7 @@ namespace dd4hep { const ROOT::Geom::Vertex_t& v1 = vertices[0]; const ROOT::Geom::Vertex_t& v2 = vertices[1]; const ROOT::Geom::Vertex_t& v3 = vertices[2]; - constexpr double epsilon = 1.e-20; + constexpr double epsilon = 1.0e-10; // v1.x v2.x v3.x v1.x v2.x // // v1.y v2.y v3.y v1.y v2.y From 420e4cff0bed220c16c601cd7d478c0c2af09b47 Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Wed, 17 Jan 2024 13:35:02 +0100 Subject: [PATCH 5/8] Try to fix (some) CAD interface tests --- DDCAD/include/DDCAD/Utilities.h | 41 ++++++++++++++++++++++++++++----- DDCAD/src/ASSIMPReader.cpp | 30 ++++++++++++++---------- DDCAD/src/ASSIMPWriter.cpp | 6 ++--- DDCore/include/DD4hep/Handle.h | 4 +++- DDCore/src/Handle.cpp | 4 ++++ 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/DDCAD/include/DDCAD/Utilities.h b/DDCAD/include/DDCAD/Utilities.h index ef5a4c89b..1b0a86f08 100644 --- a/DDCAD/include/DDCAD/Utilities.h +++ b/DDCAD/include/DDCAD/Utilities.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -25,7 +26,7 @@ namespace dd4hep { /// Namespace for implementation details of the AIDA detector description toolkit namespace cad { - inline std::stringstream streamFacet(TGeoFacet const& facet, + inline std::string streamFacet(TGeoFacet const& facet, TGeoTessellated const& shape) { using ::operator<<; std::stringstream str; @@ -40,24 +41,24 @@ namespace dd4hep { #else str << facet; #endif - return str; + return str.str(); } - inline std::stringstream streamVertices(ROOT::Geom::Vertex_t const& v1, + inline std::string streamVertices(ROOT::Geom::Vertex_t const& v1, ROOT::Geom::Vertex_t const& v2, ROOT::Geom::Vertex_t const& v3) { using ::operator<<; std::stringstream str; str << "{" << v1 << ", " << v2 << ", " << v3 << "}"; - return str; + return str.str(); } - // Determine if the facet is degenerated by calculating its determinant inline bool facetIsDegenerated(std::vector const& vertices){ +#if 0 const ROOT::Geom::Vertex_t& v1 = vertices[0]; const ROOT::Geom::Vertex_t& v2 = vertices[1]; const ROOT::Geom::Vertex_t& v3 = vertices[2]; - constexpr double epsilon = 1.0e-10; + constexpr double epsilon = std::numeric_limits::epsilon(); // v1.x v2.x v3.x v1.x v2.x // // v1.y v2.y v3.y v1.y v2.y @@ -71,6 +72,34 @@ namespace dd4hep { - v2.z() * v3.y() * v1.x() - v3.z() * v1.y() * v2.x(); return std::fabs(det) < epsilon; +#else + using ROOT::Geom::Vertex_t; + // Compute normal using non-zero segments + constexpr double kTolerance = 1.e-20; + bool degenerated = true; + Vertex_t normal; + int fNvert = int(vertices.size()); + for (int i = 0; i < fNvert - 1; ++i) { + Vertex_t e1 = vertices[i + 1] - vertices[i]; + if (e1.Mag2() < kTolerance) + continue; + for (int j = i + 1; j < fNvert; ++j) { + Vertex_t e2 = vertices[(j + 1) % fNvert] - vertices[j]; + if (e2.Mag2() < kTolerance) + continue; + normal = Vertex_t::Cross(e1, e2); + // e1 and e2 may be colinear + if (normal.Mag2() < kTolerance) + continue; + normal.Normalize(); + degenerated = false; + break; + } + if (!degenerated) + break; + } + return degenerated; +#endif } } } diff --git a/DDCAD/src/ASSIMPReader.cpp b/DDCAD/src/ASSIMPReader.cpp index 67a1c37a0..5a22c5b3b 100644 --- a/DDCAD/src/ASSIMPReader.cpp +++ b/DDCAD/src/ASSIMPReader.cpp @@ -63,9 +63,9 @@ ASSIMPReader::readShapes(const std::string& source, double unit_length) const if ( dump_facets ) { for( size_t i=0, n=shape->GetNfacets(); i < n; ++i ) { const auto& facet = shape->GetFacet(i); - std::stringstream str = dd4hep::cad::streamFacet(facet, shape); + std::string str = dd4hep::cad::streamFacet(facet, shape); printout(ALWAYS,"ASSIMPReader","++ Facet %4ld : %s", - i, str.str().c_str()); + i, str.c_str()); } } shape->SetTitle(TESSELLATEDSOLID_TAG); @@ -90,7 +90,6 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const bool dump_facets = ((flags>>8)&0x1) == 1; int aiflags = aiProcess_Triangulate|aiProcess_JoinIdenticalVertices|aiProcess_CalcTangentSpace; auto scene = importer->ReadFile( source.c_str(), aiflags); - char text[1048]; if ( !scene ) { except("ASSIMPReader","+++ FileNotFound: %s",source.c_str()); @@ -108,9 +107,20 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const vertices.emplace_back(Vertex(v[i].x*unit, v[i].y*unit, v[i].z*unit)); } TessellatedSolid shape(name,vertices); + if ( name.empty() ) { + name = _toString(result.size(), "tessellated_%ld"); + } + for(unsigned int i=0; i < mesh->mNumFaces; i++) { const unsigned int* idx = mesh->mFaces[i].mIndices; - shape->AddFacet(idx[0], idx[1], idx[2]); + bool degenerated = dd4hep::cad::facetIsDegenerated({vertices[idx[0]], vertices[idx[1]], vertices[idx[2]]}); + if ( !degenerated ) { + shape->AddFacet(idx[0], idx[1], idx[2]); + continue; + } + printout(INFO, "ASSIMPReader", "+++ %s: Drop degenerated facet: %d %d %d", + name.c_str(), idx[0], idx[1], idx[2]); + } if ( shape->GetNfacets() > 2 ) { std::string mat_name; @@ -124,14 +134,9 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const if ( !mat.isValid() ) { printout(ERROR, "ASSIMPReader", "+++ %s: No material named '%s' FOUND. Will use Air. [Missing material]", - text, mat_name.c_str()); + name.c_str(), mat_name.c_str()); mat = detector.air(); } - if ( name.empty() ) { - ::snprintf(text,sizeof(text),"tessellated_%ld", result.size()); - text[sizeof(text)-1] = 0; - name = text; - } Volume vol(name, Solid(shape.ptr()), mat); if ( mesh->HasVertexColors(0) ) { const aiColor4D* col = mesh->mColors[0]; @@ -146,6 +151,7 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const } } if ( !vis.isValid() ) { + char text[1024]; ::snprintf(text,sizeof(text),"vis_%s_%p", name.c_str(), (void*)vol.ptr()); text[sizeof(text)-1] = 0; vis = VisAttr(text); @@ -162,9 +168,9 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const if ( dump_facets ) { for( size_t i=0, n=shape->GetNfacets(); i < n; ++i ) { const auto& facet = shape->GetFacet(i); - std::stringstream str = dd4hep::cad::streamFacet(facet, shape); + std::string str = dd4hep::cad::streamFacet(facet, shape); printout(ALWAYS,"ASSIMPReader","++ Facet %4ld : %s", - i, str.str().c_str()); + i, str.c_str()); } } result.emplace_back(std::unique_ptr(vol.ptr())); diff --git a/DDCAD/src/ASSIMPWriter.cpp b/DDCAD/src/ASSIMPWriter.cpp index f31219174..f468c63e0 100644 --- a/DDCAD/src/ASSIMPWriter.cpp +++ b/DDCAD/src/ASSIMPWriter.cpp @@ -159,7 +159,7 @@ namespace { continue; } #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1) - bool degenerated = dd4hep::cad::facetIsDegenerated(vertices); + bool degenerated = dd4hep::cad::facetIsDegenerated({vertices[vv0],vertices[vv1],vertices[vv2]}); #else bool degenerated = true; TGeoFacet f(&vertices, 3, vv0, vv1, vv2); @@ -426,8 +426,8 @@ int ASSIMPWriter::write(const std::string& file_name, ROOT::Geom::Vertex_t v1(vv[id[0]].x, vv[id[0]].y, vv[id[0]].z); ROOT::Geom::Vertex_t v2(vv[id[1]].x, vv[id[1]].y, vv[id[1]].z); ROOT::Geom::Vertex_t v3(vv[id[2]].x, vv[id[2]].y, vv[id[2]].z); - std::stringstream str = dd4hep::cad::streamVertices(v1, v2, v3); - printout(ALWAYS,"ASSIMPWriter","++ Facet %4ld : %s", j, str.str().c_str()); + std::string str = dd4hep::cad::streamVertices(v1, v2, v3); + printout(ALWAYS,"ASSIMPWriter","++ Facet %4ld : %s", j, str.c_str()); } } else { diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index f337140b0..8dfdbce70 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -239,10 +239,12 @@ namespace dd4hep { /// String conversions: boolean value to string \ingroup DD4HEP_CORE std::string _toString(bool value); - /// String conversions: integer value to string \ingroup DD4HEP_CORE + /// String conversions: short integer value to string \ingroup DD4HEP_CORE std::string _toString(short value, const char* fmt = "%d"); /// String conversions: integer value to string \ingroup DD4HEP_CORE std::string _toString(int value, const char* fmt = "%d"); + /// String conversions: unsigned long integer value to string \ingroup DD4HEP_CORE + std::string _toString(unsigned long value, const char* fmt = "%ld"); /// String conversions: float value to string \ingroup DD4HEP_CORE std::string _toString(float value, const char* fmt = "%.17e"); /// String conversions: double value to string \ingroup DD4HEP_CORE diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 7cfa46fcb..cbc9b1b7b 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -344,6 +344,10 @@ namespace dd4hep { return __to_string(value, fmt); } + string _toString(unsigned long value, const char* fmt) { + return __to_string(value, fmt); + } + string _toString(float value, const char* fmt) { return __to_string(value, fmt); } From 63aa094d04be4fb8a9a572107194e4378c4dd6e2 Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Wed, 17 Jan 2024 14:12:42 +0100 Subject: [PATCH 6/8] Fix creation of tessellated shapes from CAD files. --- DDCAD/src/ASSIMPReader.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/DDCAD/src/ASSIMPReader.cpp b/DDCAD/src/ASSIMPReader.cpp index 5a22c5b3b..78e9e7f5c 100644 --- a/DDCAD/src/ASSIMPReader.cpp +++ b/DDCAD/src/ASSIMPReader.cpp @@ -111,16 +111,27 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const name = _toString(result.size(), "tessellated_%ld"); } + /// NOTE: IMPORTANT! + /// ALWAYS add facets using the physical vertices! + /// TGeoTessellated takes care that the vertex map is unique and + /// assigns the proper indices to the facet. for(unsigned int i=0; i < mesh->mNumFaces; i++) { const unsigned int* idx = mesh->mFaces[i].mIndices; bool degenerated = dd4hep::cad::facetIsDegenerated({vertices[idx[0]], vertices[idx[1]], vertices[idx[2]]}); - if ( !degenerated ) { - shape->AddFacet(idx[0], idx[1], idx[2]); - continue; + if ( degenerated ) { + printout(DEBUG, "ASSIMPReader", "+++ %s: Drop degenerated facet: %d %d %d", + name.c_str(), idx[0], idx[1], idx[2]); + } + else if ( mesh->mFaces[i].mNumIndices == 3 ) { + shape->AddFacet(vertices[idx[0]], vertices[idx[1]], vertices[idx[2]]); + } + else if ( mesh->mFaces[i].mNumIndices == 4 ) { + shape->AddFacet(vertices[idx[0]], vertices[idx[1]], vertices[idx[2]], vertices[idx[3]]); + } + else { + printout(INFO, "ASSIMPReader", "+++ %s: Fancy facet with %d indices.", + name.c_str(), mesh->mFaces[i].mNumIndices); } - printout(INFO, "ASSIMPReader", "+++ %s: Drop degenerated facet: %d %d %d", - name.c_str(), idx[0], idx[1], idx[2]); - } if ( shape->GetNfacets() > 2 ) { std::string mat_name; From 11aa3392f65175f6c73bbad0c16e281d66b2d7d5 Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Wed, 17 Jan 2024 14:25:06 +0100 Subject: [PATCH 7/8] Correctly handle quadrilinear facets in tessellated shapes. --- DDCAD/include/DDCAD/Utilities.h | 20 -------------------- DDCAD/src/ASSIMPReader.cpp | 7 ++++++- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/DDCAD/include/DDCAD/Utilities.h b/DDCAD/include/DDCAD/Utilities.h index 1b0a86f08..a7e8f511d 100644 --- a/DDCAD/include/DDCAD/Utilities.h +++ b/DDCAD/include/DDCAD/Utilities.h @@ -54,25 +54,6 @@ namespace dd4hep { } // Determine if the facet is degenerated by calculating its determinant inline bool facetIsDegenerated(std::vector const& vertices){ -#if 0 - const ROOT::Geom::Vertex_t& v1 = vertices[0]; - const ROOT::Geom::Vertex_t& v2 = vertices[1]; - const ROOT::Geom::Vertex_t& v3 = vertices[2]; - constexpr double epsilon = std::numeric_limits::epsilon(); - // v1.x v2.x v3.x v1.x v2.x - // - // v1.y v2.y v3.y v1.y v2.y - // - // v1.z v2.z v3.z v1.z v2.z - double det = 0.0 - + v1.x() * v2.y() * v3.z() - + v2.x() * v3.y() * v1.z() - + v3.x() * v1.y() * v2.z() - - v1.z() * v2.y() * v3.x() - - v2.z() * v3.y() * v1.x() - - v3.z() * v1.y() * v2.x(); - return std::fabs(det) < epsilon; -#else using ROOT::Geom::Vertex_t; // Compute normal using non-zero segments constexpr double kTolerance = 1.e-20; @@ -99,7 +80,6 @@ namespace dd4hep { break; } return degenerated; -#endif } } } diff --git a/DDCAD/src/ASSIMPReader.cpp b/DDCAD/src/ASSIMPReader.cpp index 78e9e7f5c..03b9166f5 100644 --- a/DDCAD/src/ASSIMPReader.cpp +++ b/DDCAD/src/ASSIMPReader.cpp @@ -117,7 +117,12 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const /// assigns the proper indices to the facet. for(unsigned int i=0; i < mesh->mNumFaces; i++) { const unsigned int* idx = mesh->mFaces[i].mIndices; - bool degenerated = dd4hep::cad::facetIsDegenerated({vertices[idx[0]], vertices[idx[1]], vertices[idx[2]]}); + bool degenerated = false; + if ( mesh->mFaces[i].mNumIndices == 3 ) + degenerated = dd4hep::cad::facetIsDegenerated({vertices[idx[0]], vertices[idx[1]], vertices[idx[2]]}); + else if ( mesh->mFaces[i].mNumIndices == 4 ) + degenerated = dd4hep::cad::facetIsDegenerated({vertices[idx[0]], vertices[idx[1]], vertices[idx[2]], vertices[idx[3]]}); + if ( degenerated ) { printout(DEBUG, "ASSIMPReader", "+++ %s: Drop degenerated facet: %d %d %d", name.c_str(), idx[0], idx[1], idx[2]); From c0120cdf1b691406545edd995e2625e90720ffba Mon Sep 17 00:00:00 2001 From: Markus Frank Date: Wed, 17 Jan 2024 15:18:16 +0100 Subject: [PATCH 8/8] Correctly handle quadrilinear facets in tessellated shapes. --- DDCAD/include/DDCAD/Utilities.h | 20 +++++++++++++------- DDCAD/src/ASSIMPReader.cpp | 9 +++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/DDCAD/include/DDCAD/Utilities.h b/DDCAD/include/DDCAD/Utilities.h index a7e8f511d..dcd5b21f6 100644 --- a/DDCAD/include/DDCAD/Utilities.h +++ b/DDCAD/include/DDCAD/Utilities.h @@ -26,24 +26,30 @@ namespace dd4hep { /// Namespace for implementation details of the AIDA detector description toolkit namespace cad { +#if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1) inline std::string streamFacet(TGeoFacet const& facet, - TGeoTessellated const& shape) { + TGeoTessellated const& shape) { using ::operator<<; std::stringstream str; -#if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1) str << "{"; for (int i = 0; i < facet.GetNvert(); ++i) { - str << shape.GetVertex(facet[i]); - if (i != facet.GetNvert() - 1) - str << ", "; + str << shape.GetVertex(facet[i]); + if (i != facet.GetNvert() - 1) + str << ", "; } str << "}"; + return str.str(); + } #else + inline std::string streamFacet(TGeoFacet const& facet, + TGeoTessellated const& /* shape */) { + using ::operator<<; + std::stringstream str; str << facet; -#endif return str.str(); } - +#endif + inline std::string streamVertices(ROOT::Geom::Vertex_t const& v1, ROOT::Geom::Vertex_t const& v2, ROOT::Geom::Vertex_t const& v3) { diff --git a/DDCAD/src/ASSIMPReader.cpp b/DDCAD/src/ASSIMPReader.cpp index 03b9166f5..07fa11651 100644 --- a/DDCAD/src/ASSIMPReader.cpp +++ b/DDCAD/src/ASSIMPReader.cpp @@ -127,12 +127,21 @@ ASSIMPReader::readVolumes(const std::string& source, double unit_length) const printout(DEBUG, "ASSIMPReader", "+++ %s: Drop degenerated facet: %d %d %d", name.c_str(), idx[0], idx[1], idx[2]); } +#if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1) else if ( mesh->mFaces[i].mNumIndices == 3 ) { shape->AddFacet(vertices[idx[0]], vertices[idx[1]], vertices[idx[2]]); } else if ( mesh->mFaces[i].mNumIndices == 4 ) { shape->AddFacet(vertices[idx[0]], vertices[idx[1]], vertices[idx[2]], vertices[idx[3]]); } +#else + else if ( mesh->mFaces[i].mNumIndices == 3 ) { + shape->AddFacet(idx[0], idx[1], idx[2]); + } + else if ( mesh->mFaces[i].mNumIndices == 4 ) { + shape->AddFacet(idx[0], idx[1], idx[2], idx[3]); + } +#endif else { printout(INFO, "ASSIMPReader", "+++ %s: Fancy facet with %d indices.", name.c_str(), mesh->mFaces[i].mNumIndices);