diff --git a/DDCAD/src/plugins/CADPlugins.cpp b/DDCAD/src/plugins/CADPlugins.cpp index 8a646ebe9aa2041a7082a8891ae9534f9c408f6c..17f9c037a9c8b91549ec8359c9ac6acc6857e689 100644 --- a/DDCAD/src/plugins/CADPlugins.cpp +++ b/DDCAD/src/plugins/CADPlugins.cpp @@ -20,11 +20,36 @@ #include <DDCAD/ASSIMPWriter.h> // C/C++ include files +#include <filesystem> using namespace std; using namespace dd4hep; using namespace dd4hep::detail; +/// If the path to the CAD file does not directly exist try to resolve it: +static string resolve_path(xml_h e, const string& file) { + error_code errc; + std::string fname; + /// Use the xml utilities in the DocumentHandler to resolve the relative path + if ( file.length() > 7 && file.substr(0,7) == "file://" ) + fname = file.substr(7); + else + fname = file; + if ( !filesystem::exists(fname, errc) ) { + string fn = xml::DocumentHandler::system_path(e, fname); + if ( fn.length() > 7 && fn.substr(0,7) == "file://" ) + fn = fn.substr(7); + if ( !std::filesystem::exists(fn, errc) ) { + auto fp = filesystem::path(xml::DocumentHandler::system_path(e)).parent_path(); + except("CAD_Shape","+++ CAD file: %s (= %s + %s) is not accessible [%d: %s]", + fn.c_str(), fp.c_str(), fname.c_str(), + errc.value(), errc.message().c_str()); + } + return fn; + } + return fname; +} + static void* read_CAD_Volume(Detector& dsc, int argc, char** argv) { string fname; double scale = 1.0; @@ -61,7 +86,7 @@ DECLARE_DD4HEP_CONSTRUCTOR(DD4hep_read_CAD_volumes,read_CAD_Volume) static Handle<TObject> create_CAD_Shape(Detector& dsc, xml_h e) { xml_elt_t elt(e); cad::ASSIMPReader rdr(dsc); - string fname = elt.attr<string>(_U(ref)); + string fname = resolve_path(e, elt.attr<string>(_U(ref))); long flags = elt.hasAttr(_U(flags)) ? elt.attr<long>(_U(flags)) : 0; double unit = elt.hasAttr(_U(unit)) ? elt.attr<double>(_U(unit)) : dd4hep::cm; @@ -97,7 +122,7 @@ DECLARE_XML_SHAPE(CAD_Shape__shape_constructor,create_CAD_Shape) static Handle<TObject> create_CAD_Assembly(Detector& dsc, xml_h e) { xml_elt_t elt(e); - string fname = elt.attr<string>(_U(ref)); + string fname = resolve_path(e, elt.attr<string>(_U(ref))); double unit = elt.hasAttr(_U(unit)) ? elt.attr<double>(_U(unit)) : dd4hep::cm; auto volumes = cad::ASSIMPReader(dsc).readVolumes(fname, unit); if ( volumes.empty() ) { @@ -159,8 +184,8 @@ DECLARE_XML_VOLUME(CAD_Assembly__volume_constructor,create_CAD_Assembly) */ 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)); + string fname = resolve_path(e, elt.attr<string>(_U(ref))); long flags = elt.hasAttr(_U(flags)) ? elt.attr<long>(_U(flags)) : 0; cad::ASSIMPReader rdr(dsc); diff --git a/examples/DDCAD/CMakeLists.txt b/examples/DDCAD/CMakeLists.txt index 91f2d8a2f37cf5c87016a284a263728615b233c0..0d9e38ec7edcf9fa7435addd5f837463ae17d3af 100644 --- a/examples/DDCAD/CMakeLists.txt +++ b/examples/DDCAD/CMakeLists.txt @@ -72,7 +72,7 @@ endforeach() # # Multi-shape tests # Not working: OBJ_spider -list(APPEND DDCAD_Tests_MV COB_dwarf MS3D_jeep) +list(APPEND DDCAD_Tests_MV COB_dwarf MS3D_jeep RelativePath) foreach (test ${DDCAD_Tests_MV}) dd4hep_add_test_reg( DDCAD_Check_Shape_${test} COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDCAD.sh" diff --git a/examples/DDCAD/compact/Check_Shape_RelativePath.xml b/examples/DDCAD/compact/Check_Shape_RelativePath.xml new file mode 100644 index 0000000000000000000000000000000000000000..39b1627b222476b68d3d04cce63c94ec652c0e3c --- /dev/null +++ b/examples/DDCAD/compact/Check_Shape_RelativePath.xml @@ -0,0 +1,30 @@ +<lccdd> +<!-- #========================================================================== + # 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. + # + #========================================================================== + + Test to verify functionality of loading CAD files with pathes relative + to the declaring xml file. [See Issue 1166: Allow to give CAD files with + relative paths similar to importing xml files (DDCAD) ] + +--> + + <includes> + <gdmlFile ref="../../ClientTests/compact/CheckShape.xml"/> + </includes> + + <detectors> + <detector id="1" name="Shape_MS3D" type="DD4hep_TestShape_Creator"> + <check vis="Shape1_vis"> + <shape type="CAD_MultiVolume" ref="../models/MS3D/jeep1.ms3d" unit="cm"/> + </check> + </detector> + </detectors> +</lccdd>