Skip to content
Snippets Groups Projects
Commit cb49ce12 authored by Johannes Junggeburth's avatar Johannes Junggeburth :dog2: Committed by Johannes Junggeburth
Browse files

Introduce GeoModelXML dumper

parent f4a67c74
No related branches found
No related tags found
1 merge request!246Developments for the GeoModelXMLDumper - The first nail in AGDD's coffin
Showing with 902 additions and 4 deletions
......@@ -48,6 +48,7 @@ include( GNUInstallDirs )
# Set up the build of the libraries of the project.
add_subdirectory( GeoModelXML )
add_subdirectory( GeoModelXMLParser )
add_subdirectory( GeoModelXMLDumper )
add_subdirectory( GeoModelJSONParser )
add_subdirectory( ExpressionEvaluator )
add_subdirectory( GMCAT )
......
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef GEO_MODEL_XML_GMXUTIL_H
......@@ -54,6 +54,8 @@
#include "GeoModelXml/shape/MakeSubtraction.h"
#include "GeoModelXml/shape/MakeShaperef.h"
#include "GeoModelXml/shape/AddPlane.h"
#include "GeoModelXml/shape/MakeShapeShift.h"
#include "GeoModelXml/PositionIndex.h"
//#include "GeoModelXml/SensitiveId.h"
......@@ -114,6 +116,7 @@ public:
MakeUnion onion; // union is reserved
MakeSubtraction subtraction;
MakeShaperef shaperef;
MakeShapeShift shapeshift;
MakeTransformation transformation;
MakeTransformationref transformationref;
//
......
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef GEO_MODEL_XML_MAKE_SHAPESHIFT_H
#define GEO_MODEL_XML_MAKE_SHAPESHIFT_H
#include <xercesc/util/XercesDefs.hpp>
#include "GeoModelXml/Element2GeoItem.h"
//
// Create and return a HepRotation3d. Caller must delete it.
//
XERCES_CPP_NAMESPACE_BEGIN
class DOMElement;
XERCES_CPP_NAMESPACE_END
class GmxUtil;
class MakeShapeShift: public Element2GeoItem {
public:
MakeShapeShift() = default;
virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
};
#endif // MAKE_ROTATION_H
......@@ -65,7 +65,7 @@
<!ELEMENT addindex EMPTY>
<!ATTLIST addindex name ID #REQUIRED>
<!ELEMENT shapes ((box|cons|generictrap|para|pcon|pgon|trap|tube|tubs|trd|intersection|subtraction|union|simplepolygonbrep|ellipticaltube|twistedtrap|torus)+)>
<!ELEMENT shapes ((box|cons|generictrap|para|pcon|pgon|trap|tube|tubs|trd|intersection|subtraction|union|simplepolygonbrep|ellipticaltube|twistedtrap|torus|shapeshift)+)>
<!-- All shapes allowed in GeoModel manual. Same name, parameters, parameter order, but always lower case -->
<!ELEMENT box EMPTY>
......@@ -168,6 +168,9 @@
<!ELEMENT intersection (shaperef, (transformation|transformationref), shaperef)>
<!ATTLIST intersection name ID #REQUIRED>
<!ELEMENT shapeshift ( (shaperef|transformation|transformationref)+)>
<!ATTLIST shapeshift name ID #REQUIRED>
<!ELEMENT subtraction (shaperef, (transformation|transformationref), shaperef)>
<!ATTLIST subtraction name ID #REQUIRED>
......@@ -268,7 +271,7 @@
<!ATTLIST assemblyref ref IDREF #REQUIRED
zeroid (true|false) "false">
<!ELEMENT multicopy (transformation, (transform|logvolref|assemblyref))>
<!ELEMENT multicopy ( (transformation|transformationref), (transform|logvolref|assemblyref))>
<!-- Removed logvol and assembly from multicopy content. There is no particular reason
why they shouldn't be allowed there. But in practice one uses refs, and forbidding them simplifies coding
the index stuff. If you need them, put them back. Got rid of transformref; never used. -->
......
......@@ -85,7 +85,8 @@ GmxUtil::GmxUtil(GmxInterface &gmxInterface):
geoItemRegistry.enregister("shaperef", &tagHandler.shaperef);
geoItemRegistry.enregister("transformation", &tagHandler.transformation);
geoItemRegistry.enregister("transformationref", &tagHandler.transformationref);
geoItemRegistry.enregister("shapeshift", &tagHandler.shapeshift);
tagHandler.addplane.gmxUtil=this;
}
......
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "GeoModelXml/shape/MakeShapeShift.h"
#include "OutputDirector.h"
#include <string>
#include <xercesc/dom/DOM.hpp>
#include "GeoModelKernel/GeoShapeShift.h"
#include "GeoModelKernel/GeoTransform.h"
#include "xercesc/util/XMLString.hpp"
#include "GeoModelXml/GmxUtil.h"
#include "GeoModelHelpers/TransformSorter.h"
#include "GeoModelHelpers/throwExcept.h"
#include "GeoModelHelpers/GeoShapeUtils.h"
#include "xercesc/util/XMLString.hpp"
#include "GeoModelXml/GmxUtil.h"
using namespace xercesc;
GeoIntrusivePtr<RCBase> MakeShapeShift::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
unsigned int elementIndex = 0;
GeoShape* shape{nullptr};
GeoTrf::Transform3D hepXf{GeoTrf::Transform3D::Identity()};
for (DOMNode *child = element->getFirstChild(); child != nullptr; child = child->getNextSibling()) {
if (child->getNodeType() != DOMNode::ELEMENT_NODE) {
continue;
}
switch (elementIndex) {
case 0: { // First element is first shaperef
shape = static_cast<GeoShape*>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement*> (child), gmxUtil));
break;
} case 1: { // Second element is transformation or transformationref
char *toRelease = XMLString::transcode(child->getNodeName());
std::string nodeName{toRelease};
XMLString::release(&toRelease);
const GeoTransform *geoXf = (nodeName == "transformation")
? static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil))
: static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
hepXf = geoXf->getTransform();
break;
} default: // More than 3 elements?
THROW_EXCEPTION("Only transofrmation & geoshaperef are accepted");
}
++elementIndex;
}
if (!shape) {
THROW_EXCEPTION("No shape has been given");
}
static const GeoTrf::TransformSorter sorter{};
if (!sorter.compare(GeoTrf::Transform3D::Identity(), hepXf)) {
return shape;
}
return cacheShape(make_intrusive<GeoShapeShift>(shape, hepXf));
}
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
# Find the header and source files.
file( GLOB SOURCES src/*.cxx )
file( GLOB HEADERS GeoModelXMLDumper/*.h GeoModelXMLDumper/*.icc )
# Create the library.
add_library( GeoModelXMLDumper SHARED ${HEADERS} ${SOURCES} )
target_link_libraries( GeoModelXMLDumper PUBLIC GeoModelCore::GeoModelKernel
GeoModelCore::GeoModelHelpers )
target_include_directories( GeoModelXMLDumper PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> )
source_group( "GeoModelXMLDumper" FILES ${HEADERS} )
source_group( "src" FILES ${SOURCES} )
set_target_properties( GeoModelXMLDumper PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR} )
# Set up an alias with the same name that you would get by "finding" a pre-built
# version of the library.
add_library( GeoModelTools::GeoModelXMLDumper ALIAS GeoModelXMLDumper )
# Install the library.
install(TARGETS GeoModelXMLDumper
EXPORT ${PROJECT_NAME}-export
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT Runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Runtime
NAMELINK_COMPONENT Development # Requires CMake 3.12
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT Development
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GeoModelXMLDumper
COMPONENT Development
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install( FILES ${HEADERS}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GeoModelXMLDumper
COMPONENT Development )
# Declare the package's executable.
add_executable( dumpGeoXML util/main.cxx)
target_link_libraries( dumpGeoXML PRIVATE GeoModelCore::GeoModelKernel
GeoModelCore::GeoModelHelpers
GeoModelIO::GeoModelRead
GeoModelTools::GeoModelXMLDumper)
# Tweak how debug information should be attached to the executable, in Debug
# builds.
if( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND
"${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" )
target_compile_options( dumpGeoXML PRIVATE "-gdwarf-2" )
endif()
# Install the executable.
install( TARGETS dumpGeoXML
EXPORT ${PROJECT_NAME}-export
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT Runtime )
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef GEOMODELXMLDUMPER_GEOXMLDUMPER_H
#define GEOMODELXMLDUMPER_GEOXMLDUMPER_H
#include "GeoModelKernel/GeoVPhysVol.h"
#include "GeoModelKernel/GeoTransform.h"
#include "GeoModelKernel/GeoIntrusivePtr.h"
#include "GeoModelHelpers/GeoShapeSorter.h"
#include "GeoModelHelpers/GeoPhysVolSorter.h"
#include "GeoModelHelpers/TransformSorter.h"
#include <string>
#include <map>
/** @brief: The GeoXmlDumper class traverses the GeoModel tree and translates its content
* into plain GeoModelXML
*
*/
class GeoXMLDumper {
public:
GeoXMLDumper(const std::string& outDir,
const std::string& systemName,
const std::string& xmlLayoutFile);
bool publishWorld(PVConstLink world);
private:
std::string m_outDir{};
std::string m_systemName{};
std::string m_xmlLayoutFile{};
void countVolume(PVConstLink volume);
private:
/// @brief
/// @param outStream
/// @param physVol
/// @param volName
/// @param indentation
/// @return
std::string publishPhysVol(std::ostream& outStream,
PVConstLink physVol,
const std::string& volName,
unsigned int indentation = 0);
std::string publishShape(std::ostream& shapeStream,
GeoIntrusivePtr<const GeoShape> shape,
const std::string& shapeName);
/// @brief Creates the actual header file of the GeoModel description
/// @param ostr
using topVolWithPathList = std::vector<std::pair<std::string, std::string>>;
void dumpGeoModelHeader(std::ostream& ostr,
const topVolWithPathList& pubVolsWithFiles) const;
void writeMaterials(std::ostream& ostr,
unsigned int indentation = 0) const;
void dumpTransform(std::ostream& ostr,
const GeoTrf::Transform3D& trans,
const std::string& refName,
unsigned int indentation = 0);
std::string uniqueNameTag(std::string nameTag,
const std::string_view idToken);
using shapeMap = std::map<GeoIntrusivePtr<const GeoShape>, std::string, GeoShapeSorter>;
using physVolMap = std::map<PVConstLink, std::string, GeoPhysVolSorter>;
using transformMap = std::map<GeoTrf::Transform3D, std::string, GeoTrf::TransformSorter>;
using physVolCounter = std::map<PVConstLink, unsigned int, GeoPhysVolSorter>;
using nameTagCounter = std::map<std::string, unsigned int>;
physVolMap m_physVolNameTags{};
shapeMap m_shapeNameTags{};
transformMap m_transformNameTags{};
nameTagCounter m_nameTagCounts{};
physVolCounter m_physVolCounts{};
};
#endif
\ No newline at end of file
This diff is collapsed.
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "GeoModelHelpers/defineWorld.h"
#include "GeoModelKernel/GeoGeometryPluginLoader.h"
#include "GeoModelXMLDumper/GeoXMLDumper.h"
#include "GeoModelHelpers/FileUtils.h"
#include "GeoModelHelpers/StringUtils.h"
#include <vector>
#include <string>
#include <iostream>
using namespace GeoFileUtils;
using namespace GeoStrUtils;
int main(int argc, char ** argv) {
const std::string stdDtdFile{"geomodel_v0.dtd"};
std::vector<std::string> plugins{};
std::string outDir{};
std::string detectorName{"ForkLiftGarage"};
std::string xmlLayoutFile{};
for (int k =1 ; k < argc; ++k) {
const std::string the_arg{argv[k]};
if (the_arg=="-p" || the_arg=="--plugin") {
bool added{false};
while (k+1 < argc) {
const std::string toLoad{argv[k+1]};
if (toLoad[0] == '-') break;
plugins.push_back(toLoad);
++k;
added = true;
}
if (!added) {
std::cerr<<"Please give at least one follow-up argument to "<<the_arg<<std::endl;
return EXIT_FAILURE;
}
} else if (the_arg == "-o" || the_arg=="--outDir"){
if (k+1 < argc) {
outDir = argv[k+1];
++k;
} else {
std::cerr<<"Please give one follow-up argument to "<<the_arg<<std::endl;
return EXIT_FAILURE;
}
} else {
std::cerr<<"Unknown argument "<<the_arg<<std::endl;
return EXIT_FAILURE;
}
}
if(plugins.empty()) {
std::cerr<<"Please specify at least one plugin via -p / --plugin "<<std::endl;
return EXIT_FAILURE;
}
if (outDir.empty()) {
std::cerr<<"Please specify an output file via -o "<<std::endl;
return EXIT_FAILURE;
}
if (!mkdir(outDir)) {
std::cerr<<"Failed to create directory "<<outDir<<std::endl;
return EXIT_FAILURE;
}
if (xmlLayoutFile.empty()) {
const std::string ldEnvVar = resolveEnviromentVariables("${LD_LIBRARY_PATH}");
const std::vector<std::string> ldLibPaths{tokenize(ldEnvVar, ":")};
for (const std::string& ld_lib : ldLibPaths){
const std::string sharePath{ld_lib+"/../share/"};
if (!doesDirectoryExist(sharePath)) {
continue;
}
//
const std::vector<std::string> dtdPaths{findFile(sharePath, stdDtdFile)};
if (dtdPaths.size() && !copyFile(dtdPaths[0], outDir + "/" + stdDtdFile)) {
return EXIT_FAILURE;
}
xmlLayoutFile = stdDtdFile;
}
if (xmlLayoutFile.empty()) {
return EXIT_FAILURE;
}
}
GeoIntrusivePtr<GeoVPhysVol> world{createGeoWorld()};
for (const std::string& load_me : plugins) {
std::cout<<"Load plugin "<<load_me<<std::endl;
GeoGeometryPluginLoader loader;
std::unique_ptr<GeoVGeometryPlugin> factory{loader.load(load_me)};
if (!factory) {
std::cerr << "Could not load plugin " << load_me << std::endl;
return EXIT_FAILURE;
}
factory->create(world);
}
GeoXMLDumper dumper{outDir, detectorName, xmlLayoutFile};
dumper.publishWorld(world);
return EXIT_SUCCESS;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment