diff --git a/FullSimLight/include/FSLSDPluginLoader.h b/FullSimLight/include/FSLSDPluginLoader.h index 9bdb306085b3a37ccc739d92ff0bd40fe98f1fb0..2bbfa7e370de7b0453fafe4a75ce9b2b5bf5eef6 100644 --- a/FullSimLight/include/FSLSDPluginLoader.h +++ b/FullSimLight/include/FSLSDPluginLoader.h @@ -1,9 +1,10 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration */ #ifndef FSLSDPLUGINLOADER_H_ #define FSLSDPLUGINLOADER_H_ +#include "FullSimLight/FSLSensitiveDetectorPlugin.h" #include "GeoModelKernel/GeoPluginLoader.h" typedef GeoPluginLoader<FSLSensitiveDetectorPlugin> FSLSDPluginLoader; #endif diff --git a/FullSimLight/include/MassCalculator.hh b/FullSimLight/include/MassCalculator.hh index 249c84b9f654b83ddef745195208a4b45500ff77..62320def6a0d519ba93943e89ac0cb19edd8d3db 100644 --- a/FullSimLight/include/MassCalculator.hh +++ b/FullSimLight/include/MassCalculator.hh @@ -1,24 +1,23 @@ #ifndef MassCalculator_h #define MassCalculator_h 1 -#include "G4Types.hh" -#include "G4String.hh" #include "G4LogicalVolume.hh" -#include "G4VPhysicalVolume.hh" #include "G4Material.hh" +#include "G4String.hh" +#include "G4Types.hh" +#include "G4VPhysicalVolume.hh" #include "G4VSolid.hh" - -//#include "GeoModelKernel/GeoBox.h" +// #include "GeoModelKernel/GeoBox.h" #include "GeoModelKernel/GeoPhysVol.h" -//#include "GeoModelKernel/GeoFullPhysVol.h" +// #include "GeoModelKernel/GeoFullPhysVol.h" // Units #include "GeoModelKernel/Units.h" #define SYSTEM_OF_UNITS GeoModelKernelUnits -#include <vector> #include <nlohmann/json.hpp> +#include <vector> using json = nlohmann::json; @@ -30,33 +29,40 @@ using json = nlohmann::json; */ class MassCalculator { - -public: - - //static MassCalculator& Instance(); + public: + // static MassCalculator& Instance(); MassCalculator(){}; ~MassCalculator(){}; MassCalculator(const MassCalculator&) = delete; MassCalculator& operator=(const MassCalculator&) = delete; - + double volume(const PVConstLink& pv); double exclusiveMass(const PVConstLink& pv); double inclusiveMass(const PVConstLink& pv); - void calculateMass(G4LogicalVolume* logVol, G4VPhysicalVolume * physVol, std::vector<json>& jlist, double& exclusiveMass, bool writeRep); - void iterateFromWorldMass(G4LogicalVolume* logVolume, std::vector<json>& jlist, double& inclusiveMass, double& exclusiveMass, G4String prefix, G4String material); - void recursiveMassCalculation (G4VPhysicalVolume* worldg4, GeoPhysVol* /*worldgeoModel*/, std::vector<json>& jlist); - void SetPrefixLogicalVolume(const G4String &prefixLV) { fPrefixLogicalVolume = prefixLV; } - void SetMaterial(const G4String &material) { fMaterial = material; } - void SetVerbosity(const int verbosity){ fVerbosityFlag = verbosity; } + void calculateMass(G4LogicalVolume* logVol, G4VPhysicalVolume* physVol, + std::vector<json>& jlist, double& exclusiveMass, + bool writeRep); + void iterateFromWorldMass(G4LogicalVolume* logVolume, + std::vector<json>& jlist, double& inclusiveMass, + double& exclusiveMass, G4String prefix, + G4String material); + void recursiveMassCalculation(G4VPhysicalVolume* worldg4, + GeoVPhysVol* /*worldgeoModel*/, + std::vector<json>& jlist); + void SetPrefixLogicalVolume(const G4String& prefixLV) { + fPrefixLogicalVolume = prefixLV; + } + void SetMaterial(const G4String& material) { fMaterial = material; } + void SetVerbosity(const int verbosity) { fVerbosityFlag = verbosity; } void printGeometryInfo(G4LogicalVolume* lv, G4int verbosity); -private: - + private: G4String fPrefixLogicalVolume; G4String fMaterial; - const G4double fDensityThreshold = 0.02 * SYSTEM_OF_UNITS::g/SYSTEM_OF_UNITS::cm3; - G4int fVerbosityFlag; - -}; // MassCalculator + const G4double fDensityThreshold = + 0.02 * SYSTEM_OF_UNITS::g / SYSTEM_OF_UNITS::cm3; + G4int fVerbosityFlag; + +}; // MassCalculator -#endif // MassCalculator_h 1 +#endif // MassCalculator_h 1 diff --git a/FullSimLight/src/FSLDetectorConstruction.cc b/FullSimLight/src/FSLDetectorConstruction.cc index 904d3e096b55ab9175a9cda07c7d876fcea8279b..4c995d3d518c9c4f17a7f9cf3408c1d8c582b3b7 100644 --- a/FullSimLight/src/FSLDetectorConstruction.cc +++ b/FullSimLight/src/FSLDetectorConstruction.cc @@ -139,7 +139,7 @@ G4VPhysicalVolume *FSLDetectorConstruction::Construct() { fTimer.Start(); - GeoPhysVol* world = nullptr; + GeoVPhysVol* world = nullptr; G4LogicalVolume* envelope; if (fGeometryFileName.contains(".dylib") || fGeometryFileName.contains(".so")) { @@ -152,8 +152,9 @@ G4VPhysicalVolume *FSLDetectorConstruction::Construct() } + world = nullptr; world = CreateTheWorld(nullptr); - factory->create(world); + factory->create(dynamic_cast<GeoPhysVol*>(world)); G4cout << "ReadGeoModel::buildGeoModel() done." << G4endl; fTimer.Stop(); @@ -218,8 +219,10 @@ G4VPhysicalVolume *FSLDetectorConstruction::Construct() /* build the GeoModel geometry */ - //GeoPhysVol* world = readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory and get an handle to the 'world' volume - world = readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory and get an handle to the 'world' volume + // builds the whole GeoModel tree in memory + // and get an handle to the 'world' volume + world = readInGeo.buildGeoModel(); + G4cout << "ReadGeoModel::buildGeoModel() done." << G4endl; fTimer.Stop(); G4cout << "First step done. GeoModelTree built from the SQLite file." << G4endl; diff --git a/FullSimLight/src/MassCalculator.cc b/FullSimLight/src/MassCalculator.cc index b5e491fc6d5bab90ef18e9423a9eac6074bb776d..aad6381cab960d03843768ec99386f9f31d8a96a 100644 --- a/FullSimLight/src/MassCalculator.cc +++ b/FullSimLight/src/MassCalculator.cc @@ -1,439 +1,550 @@ #include "MassCalculator.hh" -#include "GeoModelKernel/GeoVolumeCursor.h" +#include "GeoModelKernel/GeoVolumeCursor.h" namespace masscalc { - - // a simple struct to model a mass calculation report - struct massReport { - std::string logicalVolumeName; - std::string physicalVolumeName; - int volumeCopyNo; - std::string material; - double density; - std::string volumeEntityType; - double inclusiveMass; //mass of the volume, that includes the real mass of the daughters volumes - double exclusiveMass; //mass of the volume, from which the mass of the daughters is subtracted - }; - - // a simple struct to model a mass calculation report - struct finalMassReport { - std::string logicalVolumeName; - //std::string physicalVolumeName; - //int volumeCopyNo; - std::string material; - double densityThreshold; - std::string volumeEntityType; - double inclusiveMass; //total inclusice mass of the geometry, that includes the real mass of the daughters volumes - double exclusiveMass; //total exclusive mass of the geometry, from which the mass of the daughters is subtracted - double apparentWeight; //apparent weight in Air of the whole geometry - double exclusiveMassFiltered; //total mass of the volumes with density > threshold - double excludedMass; //total mass of the volumes with density < threshold - }; - - void to_json(json& j, const massReport& p) { - j = json{{"logicalVolumeName", p.logicalVolumeName}, json{"physicalVolumeName", p.physicalVolumeName}, {"volumeCopyNo", p.volumeCopyNo}, {"material", p.material},{"density[g/cm3]", p.density}, {"volumeEntityType", p.volumeEntityType}, {"inclusiveMass[kg]", p.inclusiveMass}, {"exclusiveMass[kg]", p.exclusiveMass} }; - } - - void from_json(const json& j, massReport& p) { - p.logicalVolumeName=j.at("logicalVolumeName").get<std::string>(); - p.physicalVolumeName=j.at("physicalVolumeName").get<std::string>(); - p.volumeCopyNo=j.at("volumeCopyNo").get<int>(); - p.material=j.at("material").get<std::string>(); - p.density=j.at("density[g/cm3]").get<double>(); - p.volumeEntityType=j.at("volumeEntityType").get<std::string>(); - p.inclusiveMass=j.at("inclusiveMass[kg]").get<double>(); - p.exclusiveMass=j.at("exclusiveMass[kg]").get<double>(); - - } - - void to_json(json& j, const finalMassReport& p) { - j = json{{"logicalVolumeName", p.logicalVolumeName}, {"material", p.material}, {"densityThreshold[g/cm3]", p.densityThreshold}, {"volumeEntityType", p.volumeEntityType}, {"inclusiveMass[kg]", p.inclusiveMass}, {"exclusiveMass[kg]", p.exclusiveMass}, {"apparentWeightInAir[kg]", p.apparentWeight}, {"exclusiveFilteredMass[kg]", p.exclusiveMassFiltered}, {"excludedFilteredMass[kg]", p.excludedMass} }; - } - - void from_json(const json& j, finalMassReport& p) { - p.logicalVolumeName=j.at("logicalVolumeName").get<std::string>(); - p.material=j.at("material").get<std::string>(); - p.densityThreshold=j.at("densityThreshold[g/cm3]").get<double>(); - p.volumeEntityType=j.at("volumeEntityType").get<std::string>(); - p.inclusiveMass=j.at("inclusiveMass[kg]").get<double>(); - p.exclusiveMass=j.at("exclusiveMass[kg]").get<double>(); - p.apparentWeight=j.at("apparentWeightInAir[kg]").get<double>(); - p.exclusiveMassFiltered=j.at("exclusiveFilteredMass[kg]").get<double>(); - p.excludedMass=j.at("excludedFilteredMass[kg]").get<double>(); - - } -} // namespace masscalc + +// a simple struct to model a mass calculation report +struct massReport { + std::string logicalVolumeName; + std::string physicalVolumeName; + int volumeCopyNo; + std::string material; + double density; + std::string volumeEntityType; + double inclusiveMass; // mass of the volume, that includes the real mass of + // the daughters volumes + double exclusiveMass; // mass of the volume, from which the mass of the + // daughters is subtracted +}; + +// a simple struct to model a mass calculation report +struct finalMassReport { + std::string logicalVolumeName; + // std::string physicalVolumeName; + // int volumeCopyNo; + std::string material; + double densityThreshold; + std::string volumeEntityType; + double inclusiveMass; // total inclusice mass of the geometry, that + // includes the real mass of the daughters volumes + double exclusiveMass; // total exclusive mass of the geometry, from which + // the mass of the daughters is subtracted + double apparentWeight; // apparent weight in Air of the whole geometry + double exclusiveMassFiltered; // total mass of the volumes with density > + // threshold + double excludedMass; // total mass of the volumes with density < threshold +}; + +void to_json(json& j, const massReport& p) { + j = json{{"logicalVolumeName", p.logicalVolumeName}, + json{"physicalVolumeName", p.physicalVolumeName}, + {"volumeCopyNo", p.volumeCopyNo}, + {"material", p.material}, + {"density[g/cm3]", p.density}, + {"volumeEntityType", p.volumeEntityType}, + {"inclusiveMass[kg]", p.inclusiveMass}, + {"exclusiveMass[kg]", p.exclusiveMass}}; +} + +void from_json(const json& j, massReport& p) { + p.logicalVolumeName = j.at("logicalVolumeName").get<std::string>(); + p.physicalVolumeName = j.at("physicalVolumeName").get<std::string>(); + p.volumeCopyNo = j.at("volumeCopyNo").get<int>(); + p.material = j.at("material").get<std::string>(); + p.density = j.at("density[g/cm3]").get<double>(); + p.volumeEntityType = j.at("volumeEntityType").get<std::string>(); + p.inclusiveMass = j.at("inclusiveMass[kg]").get<double>(); + p.exclusiveMass = j.at("exclusiveMass[kg]").get<double>(); +} + +void to_json(json& j, const finalMassReport& p) { + j = json{{"logicalVolumeName", p.logicalVolumeName}, + {"material", p.material}, + {"densityThreshold[g/cm3]", p.densityThreshold}, + {"volumeEntityType", p.volumeEntityType}, + {"inclusiveMass[kg]", p.inclusiveMass}, + {"exclusiveMass[kg]", p.exclusiveMass}, + {"apparentWeightInAir[kg]", p.apparentWeight}, + {"exclusiveFilteredMass[kg]", p.exclusiveMassFiltered}, + {"excludedFilteredMass[kg]", p.excludedMass}}; +} + +void from_json(const json& j, finalMassReport& p) { + p.logicalVolumeName = j.at("logicalVolumeName").get<std::string>(); + p.material = j.at("material").get<std::string>(); + p.densityThreshold = j.at("densityThreshold[g/cm3]").get<double>(); + p.volumeEntityType = j.at("volumeEntityType").get<std::string>(); + p.inclusiveMass = j.at("inclusiveMass[kg]").get<double>(); + p.exclusiveMass = j.at("exclusiveMass[kg]").get<double>(); + p.apparentWeight = j.at("apparentWeightInAir[kg]").get<double>(); + p.exclusiveMassFiltered = j.at("exclusiveFilteredMass[kg]").get<double>(); + p.excludedMass = j.at("excludedFilteredMass[kg]").get<double>(); +} +} // namespace masscalc double MassCalculator::volume(const PVConstLink& pv) { - const GeoLogVol * lv = pv->getLogVol(); - const GeoShape *shape = lv->getShape(); + const GeoLogVol* lv = pv->getLogVol(); + const GeoShape* shape = lv->getShape(); return shape->volume(); } - double MassCalculator::exclusiveMass(const PVConstLink& pv) { - const GeoLogVol* lv = pv->getLogVol(); - const GeoMaterial *material = lv->getMaterial(); + const GeoLogVol* lv = pv->getLogVol(); + const GeoMaterial* material = lv->getMaterial(); double density = material->getDensity(); - return density*volume(pv); + return density * volume(pv); } double MassCalculator::inclusiveMass(const PVConstLink& pv) { - - const GeoLogVol* lv = pv->getLogVol(); - const GeoMaterial *material = lv->getMaterial(); + const GeoLogVol* lv = pv->getLogVol(); + const GeoMaterial* material = lv->getMaterial(); // Exclude from the calculation the EMEC special shape // cause the corresponding methods are not implemented in GeoModel if (lv->getName() == "LAr::EMEC::Pos::InnerWheel" || lv->getName() == "LAr::EMEC::Neg::InnerWheel" || lv->getName() == "LAr::EMEC::Pos::OuterWheel" || lv->getName() == "LAr::EMEC::Neg::OuterWheel" || - lv->getName() == "LAr::EMEC::Pos::InnerCone" || - lv->getName() == "LAr::EMEC::Neg::InnerCone" || + lv->getName() == "LAr::EMEC::Pos::InnerCone" || + lv->getName() == "LAr::EMEC::Neg::InnerCone" || lv->getName() == "LAr::EMEC::Pos::OuterFrontCone" || lv->getName() == "LAr::EMEC::Neg::OuterFrontCone" || - lv->getName() == "LAr::EMEC::Pos::OuterBackCone" || - lv->getName() == "LAr::EMEC::Neg::OuterBackCone" || - lv->getName() == "LAr::EMEC::Pos::InnerSlice00" || - lv->getName() == "LAr::EMEC::Neg::InnerSlice00" || - lv->getName() == "LAr::EMEC::Pos::OuterSlice00" || - lv->getName() == "LAr::EMEC::Neg::OuterSlice00" || - lv->getName() == "UnidentifiedShape"){ + lv->getName() == "LAr::EMEC::Pos::OuterBackCone" || + lv->getName() == "LAr::EMEC::Neg::OuterBackCone" || + lv->getName() == "LAr::EMEC::Pos::InnerSlice00" || + lv->getName() == "LAr::EMEC::Neg::InnerSlice00" || + lv->getName() == "LAr::EMEC::Pos::OuterSlice00" || + lv->getName() == "LAr::EMEC::Neg::OuterSlice00" || + lv->getName() == "UnidentifiedShape") { // This is one to remove - std::cout<<" !REMOVING Unidentified shapes: "<< lv->getName()<<", shape is not implemented in GeoModel, it will account zero in the mass calculation!"<<std::endl; + std::cout << " !REMOVING Unidentified shapes: " << lv->getName() + << ", shape is not implemented in GeoModel, it will account " + "zero in the mass calculation!" + << std::endl; return 0; } double density = material->getDensity(); double mass = exclusiveMass(pv); - + GeoVolumeCursor av(pv); while (!av.atEnd()) { mass += inclusiveMass(av.getVolume()); - mass -= volume(av.getVolume())*density; + mass -= volume(av.getVolume()) * density; av.next(); } - + return mass; } +void MassCalculator::calculateMass(G4LogicalVolume* logVol, + G4VPhysicalVolume* physVol, + std::vector<json>& jlist, + double& exclusiveMass, bool writeRep) { + double tmpInclusive, tmpExclusive; + + // By setting the 'propagate' boolean flag - the second one - to 'false' + // the + // method returns the mass of the present logical volume only + // (subtracted for the volume occupied by the daughter volumes). + + tmpInclusive = logVol->GetMass( + true, + true); // real mass of the LV, inclusive of the masses of the daughters + tmpExclusive = + logVol->GetMass(true, false); // mass of the LV substracted for the + // volume occupied by the daughters + + // if the method is called iteratively, the only mass cumulative mass that + // makes sense to retrieve is the sum of the exclusive masses of all the + // volumes satisfying the filters criteria + exclusiveMass += tmpExclusive; -void MassCalculator::calculateMass(G4LogicalVolume* logVol, G4VPhysicalVolume * physVol, std::vector<json>& jlist, double& exclusiveMass, bool writeRep){ - - double tmpInclusive,tmpExclusive; - - //By setting the 'propagate' boolean flag - the second one - to 'false' the - // method returns the mass of the present logical volume only - // (subtracted for the volume occupied by the daughter volumes). - - tmpInclusive = logVol->GetMass(true, true); //real mass of the LV, inclusive of the masses of the daughters - tmpExclusive = logVol->GetMass(true, false); //mass of the LV substracted for the volume occupied by the daughters - - //if the method is called iteratively, the only mass cumulative mass that makes sense - //to retrieve is the sum of the exclusive masses of all the volumes - //satisfying the filters criteria - exclusiveMass+= tmpExclusive; - - if(writeRep){ + if (writeRep) { masscalc::massReport singleMassReport; json jSingleMassReport; - //fill the singleMassReport struct - singleMassReport.logicalVolumeName=logVol->GetName(); - singleMassReport.physicalVolumeName=physVol->GetName(); - singleMassReport.volumeCopyNo =physVol->GetCopyNo(); - singleMassReport.material =logVol->GetMaterial()->GetName(); - singleMassReport.density =logVol->GetMaterial()->GetDensity()/SYSTEM_OF_UNITS::g*SYSTEM_OF_UNITS::cm3; - singleMassReport.volumeEntityType=logVol->GetSolid()->GetEntityType(); - singleMassReport.inclusiveMass = tmpInclusive/(CLHEP::kg); - singleMassReport.exclusiveMass = tmpExclusive/(CLHEP::kg); - - //write the singleMassReport in the json file + // fill the singleMassReport struct + singleMassReport.logicalVolumeName = logVol->GetName(); + singleMassReport.physicalVolumeName = physVol->GetName(); + singleMassReport.volumeCopyNo = physVol->GetCopyNo(); + singleMassReport.material = logVol->GetMaterial()->GetName(); + singleMassReport.density = logVol->GetMaterial()->GetDensity() / + SYSTEM_OF_UNITS::g * SYSTEM_OF_UNITS::cm3; + singleMassReport.volumeEntityType = logVol->GetSolid()->GetEntityType(); + singleMassReport.inclusiveMass = tmpInclusive / (CLHEP::kg); + singleMassReport.exclusiveMass = tmpExclusive / (CLHEP::kg); + + // write the singleMassReport in the json file to_json(jSingleMassReport, singleMassReport); // write prettified JSON to another file jlist.push_back(jSingleMassReport); } - } -void MassCalculator::iterateFromWorldMass(G4LogicalVolume* logVolume, std::vector<json>& jlist, double& inclusiveMass, double& exclusiveMass, G4String prefix, G4String material){ - +void MassCalculator::iterateFromWorldMass(G4LogicalVolume* logVolume, + std::vector<json>& jlist, + double& inclusiveMass, + double& exclusiveMass, + G4String prefix, G4String material) { int nDaughters = logVolume->GetNoDaughters(); - //std::cout<<"Total n. of Daughters of "<<logVolume->GetName()<<" is : "<<nDaughters<<std::endl; - G4VPhysicalVolume *daughterPV = nullptr; - G4LogicalVolume *daughterLV = nullptr; + // std::cout<<"Total n. of Daughters of "<<logVolume->GetName()<<" is : + // "<<nDaughters<<std::endl; + G4VPhysicalVolume* daughterPV = nullptr; + G4LogicalVolume* daughterLV = nullptr; G4double density; - - for (int n=0; n<nDaughters; n++) - { - daughterPV=logVolume->GetDaughter(n); + + for (int n = 0; n < nDaughters; n++) { + daughterPV = logVolume->GetDaughter(n); daughterLV = daughterPV->GetLogicalVolume(); - density=daughterLV->GetMaterial()->GetDensity(); - //fAnalysisManager->FillH1(fHistoID, density/(SYSTEM_OF_UNITS::g/SYSTEM_OF_UNITS::cm3), 1); - - //1. look only for the logVol - if(prefix!="" && material==""){ - if (daughterLV->GetName().contains(prefix) || daughterPV->GetName().contains(prefix)){ - // std::cout<<"Found the LV "<<prefix<<" and its full name is "<<daughterLV->GetName()<<std::endl; - // std::cout<<"Found the Daughter "<<prefix<<" and its full name is "<<daughterPV->GetName()<<std::endl; - std::cout<<"Cubic Volume of "<<daughterLV->GetName()<<" is "<<daughterLV->GetSolid()->GetCubicVolume()/SYSTEM_OF_UNITS::cm3<<" [cm3]"<<std::endl; - - calculateMass(daughterLV, daughterPV, jlist, exclusiveMass, true ); + density = daughterLV->GetMaterial()->GetDensity(); + // fAnalysisManager->FillH1(fHistoID, + // density/(SYSTEM_OF_UNITS::g/SYSTEM_OF_UNITS::cm3), 1); + + // 1. look only for the logVol + if (prefix != "" && material == "") { + if (daughterLV->GetName().contains(prefix) || + daughterPV->GetName().contains(prefix)) { + // std::cout<<"Found the LV "<<prefix<<" and its + // full name is + // "<<daughterLV->GetName()<<std::endl; + // std::cout<<"Found the Daughter "<<prefix<<" + // and its full name is + // "<<daughterPV->GetName()<<std::endl; + std::cout << "Cubic Volume of " << daughterLV->GetName() + << " is " + << daughterLV->GetSolid()->GetCubicVolume() / + SYSTEM_OF_UNITS::cm3 + << " [cm3]" << std::endl; + + calculateMass(daughterLV, daughterPV, jlist, exclusiveMass, + true); } - + } - //2. look only for the material - else if(prefix=="" && material!=""){ - // std::cout<<"Looking for a specific material: "<<material<<std::endl; - // std::cout<<"daughterLV->GetMaterial()->GetName(): "<<daughterLV->GetMaterial()->GetName()<<std::endl; - if (daughterLV->GetMaterial()->GetName().contains(material)){ - calculateMass(daughterLV, daughterPV, jlist, exclusiveMass, true ); + // 2. look only for the material + else if (prefix == "" && material != "") { + // std::cout<<"Looking for a specific material: + // "<<material<<std::endl; + // std::cout<<"daughterLV->GetMaterial()->GetName(): + // "<<daughterLV->GetMaterial()->GetName()<<std::endl; + if (daughterLV->GetMaterial()->GetName().contains(material)) { + calculateMass(daughterLV, daughterPV, jlist, exclusiveMass, + true); } - + } - //3. look for both - else if(prefix!="" && material!=""){ - if ((daughterLV->GetName().contains(prefix) || daughterPV->GetName().contains(prefix)) && daughterLV->GetMaterial()->GetName().contains(material)){ - calculateMass(daughterLV, daughterPV, jlist, exclusiveMass, true ); + // 3. look for both + else if (prefix != "" && material != "") { + if ((daughterLV->GetName().contains(prefix) || + daughterPV->GetName().contains(prefix)) && + daughterLV->GetMaterial()->GetName().contains(material)) { + calculateMass(daughterLV, daughterPV, jlist, exclusiveMass, + true); } - + } - //4. loop on the whole geometry tree, filtering w.r.t density of the material - else - { - //Calculate the mass of volumes that are above a certain density threshold - if (density > fDensityThreshold) - { - //sum of the exclusive masses of all the volumes that have density > threshold - inclusiveMass+=daughterLV->GetMass(true, false); - - } - else - { - //Sum of the ignored mass - exclusiveMass+=daughterLV->GetMass(true, false); + // 4. loop on the whole geometry tree, filtering w.r.t density of the + // material + else { + // Calculate the mass of volumes that are above a certain density + // threshold + if (density > fDensityThreshold) { + // sum of the exclusive masses of all the volumes that have + // density > threshold + inclusiveMass += daughterLV->GetMass(true, false); + + } else { + // Sum of the ignored mass + exclusiveMass += daughterLV->GetMass(true, false); } - } - if (daughterLV->GetNoDaughters()>0){ - iterateFromWorldMass(daughterLV, jlist, inclusiveMass, exclusiveMass, prefix, material); + if (daughterLV->GetNoDaughters() > 0) { + iterateFromWorldMass(daughterLV, jlist, inclusiveMass, + exclusiveMass, prefix, material); } - } - } -void MassCalculator::recursiveMassCalculation (G4VPhysicalVolume* worldg4, GeoPhysVol* /*worldgeoModel*/, std::vector<json>& jlist){ - +void MassCalculator::recursiveMassCalculation(G4VPhysicalVolume* worldg4, + GeoVPhysVol* /*worldgeoModel*/, + std::vector<json>& jlist) { masscalc::massReport singleMassReport; json jSingleMassReport; int localNoDaughters = worldg4->GetLogicalVolume()->GetNoDaughters(); - //std::cout<<"Total n. of Daughters of "<<worldg4->GetLogicalVolume()->GetName()<<" is : "<<localNoDaughters<<std::endl; - G4VPhysicalVolume *daughter; - G4LogicalVolume *daughterLV; + // std::cout<<"Total n. of Daughters of + // "<<worldg4->GetLogicalVolume()->GetName()<<" is : + // "<<localNoDaughters<<std::endl; + G4VPhysicalVolume* daughter; + G4LogicalVolume* daughterLV; G4double cubicVolumeWorld, globalDensityWorld, globalMassWorld; - - //Instance of the G4AnalysisManager used to fill the density_histogram - // fAnalysisManager = G4AnalysisManager::Instance(); - // if (!fAnalysisManager->OpenFile("density_histogram")){ - // G4cout<<"RecursiveMassCalculation ERROR: File cannot be opened!"<<G4endl; - // exit(-1); - // } else - // G4cout<<"\n...output File density_histogram opened!"<<G4endl; - - if (fVerbosityFlag>0) { - std::cout<<"\n========== Printing geometry info ============\n "<<std::endl; - printGeometryInfo (worldg4->GetLogicalVolume(), fVerbosityFlag); - std::cout<<"\n========== Printing geometry info: DONE! ============ \n"<<std::endl; - + + // Instance of the G4AnalysisManager used to fill the density_histogram + // fAnalysisManager = G4AnalysisManager::Instance(); + // if (!fAnalysisManager->OpenFile("density_histogram")){ + // G4cout<<"RecursiveMassCalculation ERROR: File cannot be + // opened!"<<G4endl; exit(-1); + // } else + // G4cout<<"\n...output File density_histogram opened!"<<G4endl; + + if (fVerbosityFlag > 0) { + std::cout << "\n========== Printing geometry info ============\n " + << std::endl; + printGeometryInfo(worldg4->GetLogicalVolume(), fVerbosityFlag); + std::cout + << "\n========== Printing geometry info: DONE! ============ \n" + << std::endl; } - - // fHistoID = fAnalysisManager->CreateH1("density", "density", 300, 10e-3, 30, "none", "none", "log"); + + // fHistoID = fAnalysisManager->CreateH1("density", "density", 300, + // 10e-3, 30, "none", "none", "log"); // fAnalysisManager->SetH1Ascii(fHistoID,true); // misi: always ascii // fAnalysisManager->SetH1XAxisTitle(fHistoID, "density [g/cm3]]"); - - //Debug information about World volume, Name, Material, Solid name of the LV, density and cubic volume - std::cout<<"Checking World volume "<<std::endl; - std::cout<<"-----> World Name is: "<<worldg4->GetName()<<std::endl; - std::cout<<"-----> WorldLV Name is: "<<worldg4->GetLogicalVolume()->GetName()<< " it has "<<localNoDaughters<<" daughters."<<std::endl; - std::cout<<"-----> World Material is: "<<worldg4->GetLogicalVolume()->GetMaterial()<<std::endl; - std::cout<<"-----> World Solid name is: "<<worldg4->GetLogicalVolume()->GetSolid()->GetName()<<std::endl; - cubicVolumeWorld = worldg4->GetLogicalVolume()->GetSolid()->GetCubicVolume(); - std::cout<<"-----> World Solid cubic volume is: "<<cubicVolumeWorld/CLHEP::m3<<" m3"<<std::endl; - std::cout<<"-----> World Solid entity type: "<<worldg4->GetLogicalVolume()->GetSolid()->GetEntityType()<<std::endl; - globalDensityWorld = worldg4->GetLogicalVolume()->GetMaterial()->GetDensity(); - std::cout<<"-----> World Solid density is: "<<globalDensityWorld/ (CLHEP::g / CLHEP::cm3)<<" [g/cm3]"<<std::endl; - std::cout<<"-----> World Solid density is: "<<globalDensityWorld/ (CLHEP::kg / CLHEP::m3)<<" [kg/m3]"<<std::endl; - // std::cout<<"-----> Minimum density is: "<<0/ (CLHEP::g / CLHEP::cm3)<<" [g/cm3]"<<std::endl; - // std::cout<<"-----> Maximum density is: "<<30<<" [g/cm3]"<<std::endl; + + // Debug information about World volume, Name, Material, Solid name of the + // LV, density and cubic volume + std::cout << "Checking World volume " << std::endl; + std::cout << "-----> World Name is: " << worldg4->GetName() << std::endl; + std::cout << "-----> WorldLV Name is: " + << worldg4->GetLogicalVolume()->GetName() << " it has " + << localNoDaughters << " daughters." << std::endl; + std::cout << "-----> World Material is: " + << worldg4->GetLogicalVolume()->GetMaterial() << std::endl; + std::cout << "-----> World Solid name is: " + << worldg4->GetLogicalVolume()->GetSolid()->GetName() + << std::endl; + cubicVolumeWorld = + worldg4->GetLogicalVolume()->GetSolid()->GetCubicVolume(); + std::cout << "-----> World Solid cubic volume is: " + << cubicVolumeWorld / CLHEP::m3 << " m3" << std::endl; + std::cout << "-----> World Solid entity type: " + << worldg4->GetLogicalVolume()->GetSolid()->GetEntityType() + << std::endl; + globalDensityWorld = + worldg4->GetLogicalVolume()->GetMaterial()->GetDensity(); + std::cout << "-----> World Solid density is: " + << globalDensityWorld / (CLHEP::g / CLHEP::cm3) << " [g/cm3]" + << std::endl; + std::cout << "-----> World Solid density is: " + << globalDensityWorld / (CLHEP::kg / CLHEP::m3) << " [kg/m3]" + << std::endl; + // std::cout<<"-----> Minimum density is: "<<0/ (CLHEP::g / + // CLHEP::cm3)<<" [g/cm3]"<<std::endl; std::cout<<"-----> Maximum density + // is: "<<30<<" [g/cm3]"<<std::endl; globalMassWorld = globalDensityWorld * cubicVolumeWorld; - std::cout<<"-----> World mass is: "<< globalMassWorld / (CLHEP::kg) <<" [Kg]"<<std::endl; - std::cout<<"\n *** --------------- ***\n"<<std::endl; - - double inclusiveMassG4 = 0., exclusiveMassG4=0., apparentWeightG4=0.; - double totalInclusiveMassG4 = 0., totalExclusiveMassG4 =0.; - //double inclusiveMassGeoModel = 0., exclusiveMassGeoModel = 0.; - - - //CASE 1: DEFAULT BEHAVIOUR - //No filter is applied -- calculate the inclusiveMass, exclusiveMass and apparentWeigth of the whole geometry - //For the inclusive and exclusive mass calculation uses a filter on the density of the material - //Ignoring the materials for which density is < 0.02 g/cm3 (density of the less dense solid - aerogel) - if(fPrefixLogicalVolume=="" && fMaterial=="") - { - //Loop over the daughters of the worls volume - Tree top daughters - only - for (int n=0; n<localNoDaughters; n++) - { - daughter=worldg4->GetLogicalVolume()->GetDaughter(n); + std::cout << "-----> World mass is: " << globalMassWorld / (CLHEP::kg) + << " [Kg]" << std::endl; + std::cout << "\n *** --------------- ***\n" << std::endl; + + double inclusiveMassG4 = 0., exclusiveMassG4 = 0., apparentWeightG4 = 0.; + double totalInclusiveMassG4 = 0., totalExclusiveMassG4 = 0.; + // double inclusiveMassGeoModel = 0., exclusiveMassGeoModel = 0.; + + // CASE 1: DEFAULT BEHAVIOUR + // No filter is applied -- calculate the inclusiveMass, exclusiveMass and + // apparentWeigth of the whole geometry For the inclusive and exclusive mass + // calculation uses a filter on the density of the material Ignoring the + // materials for which density is < 0.02 g/cm3 (density of the less dense + // solid - aerogel) + if (fPrefixLogicalVolume == "" && fMaterial == "") { + // Loop over the daughters of the worls volume - Tree top daughters - + // only + for (int n = 0; n < localNoDaughters; n++) { + daughter = worldg4->GetLogicalVolume()->GetDaughter(n); daughterLV = daughter->GetLogicalVolume(); - std::cout<<"\n****** Checking daughter "<< n+1 <<" out of "<<localNoDaughters<<std::endl; - std::cout<<"---> Daughter Name is: "<<daughter->GetName()<<std::endl; - std::cout<<"---> DaughterLV Name is: "<<daughterLV->GetName()<< " it has "<<daughterLV->GetNoDaughters()<< " daughters" <<std::endl; - std::cout<<"---> DaughterLV Material is: "<<daughterLV->GetMaterial()<<std::endl; - std::cout<<"---> DaughterLV Solid name is: "<<daughterLV->GetSolid()->GetName()<<std::endl; - std::cout<<"---> DaughterLV Solid cubic volume is: "<<daughterLV->GetSolid()->GetCubicVolume()/CLHEP::m3<<" m3"<<std::endl; - std::cout<<"---> DaughterLV Solid entity type: "<<daughterLV->GetSolid()->GetEntityType()<<std::endl; + std::cout << "\n****** Checking daughter " << n + 1 << " out of " + << localNoDaughters << std::endl; + std::cout << "---> Daughter Name is: " << daughter->GetName() + << std::endl; + std::cout << "---> DaughterLV Name is: " << daughterLV->GetName() + << " it has " << daughterLV->GetNoDaughters() + << " daughters" << std::endl; + std::cout << "---> DaughterLV Material is: " + << daughterLV->GetMaterial() << std::endl; + std::cout << "---> DaughterLV Solid name is: " + << daughterLV->GetSolid()->GetName() << std::endl; + std::cout << "---> DaughterLV Solid cubic volume is: " + << daughterLV->GetSolid()->GetCubicVolume() / CLHEP::m3 + << " m3" << std::endl; + std::cout << "---> DaughterLV Solid entity type: " + << daughterLV->GetSolid()->GetEntityType() << std::endl; G4double globalDensity = daughterLV->GetMaterial()->GetDensity(); - std::cout<<"---> DaughterLV Solid density is: "<<globalDensity/ (CLHEP::g / CLHEP::cm3)<<" [gr/cm3]"<<std::endl; - - // //GeoModel mass calculation invoked only if the geometry is not in GDML format - // //NB exclusive mass concept in GeoModel is different than the Geant4 one - // //So do not expect that the exclusive masses of the 2 calculations are the same - // if (!fGeometryFileName.contains(".gdml")){ - // const PVConstLink FSLpv = worldgeoModel->getChildVol(n); - // inclusiveMassGeoModel+= inclusiveMass(FSLpv); //real mass of the whole volume, including the real masses of the daughters - // //exclusiveMassGeoModel+= exclusiveMass(FSLpv); //mass of the whole volume, as it would not have daughters + std::cout << "---> DaughterLV Solid density is: " + << globalDensity / (CLHEP::g / CLHEP::cm3) << " [gr/cm3]" + << std::endl; + + // //GeoModel mass calculation invoked only if the + // geometry is not in GDML format + // //NB exclusive mass concept in GeoModel is different + // than the Geant4 one + // //So do not expect that the exclusive masses of the 2 + // calculations are the same if + // (!fGeometryFileName.contains(".gdml")){ + // const PVConstLink FSLpv = + // worldgeoModel->getChildVol(n); + // inclusiveMassGeoModel+= inclusiveMass(FSLpv); + // //real mass of the whole volume, including the + // real masses of the daughters + // //exclusiveMassGeoModel+= exclusiveMass(FSLpv); + // //mass of the whole volume, as it would not have + // daughters // // } - - //Here is already excluding the world volume from the calculation, - //Being it made by AIR by default - //calculateMass of each daughter and since the last flag is true, write out results in the json file - //I call this only once -- no iteration - //calculateMass(daughterLV, daughter, jlist, inclusiveMassG4, exclusiveMassG4, true); - - inclusiveMassG4 = daughterLV->GetMass(true, true); //real mass of the LV, inclusive of the masses of the daughters - exclusiveMassG4 = daughterLV->GetMass(true, false); //mass of the LV substracted for the volume occupied by the daughters - totalInclusiveMassG4+=inclusiveMassG4; - totalExclusiveMassG4+=exclusiveMassG4; - - //fill the singleMassReport struct - singleMassReport.logicalVolumeName=daughterLV->GetName(); - singleMassReport.physicalVolumeName=daughter->GetName(); - singleMassReport.volumeCopyNo =daughter->GetCopyNo(); - singleMassReport.material =daughterLV->GetMaterial()->GetName(); - singleMassReport.density =daughterLV->GetMaterial()->GetDensity()/SYSTEM_OF_UNITS::g*SYSTEM_OF_UNITS::cm3; - singleMassReport.volumeEntityType=daughterLV->GetSolid()->GetEntityType(); - singleMassReport.inclusiveMass = inclusiveMassG4/(CLHEP::kg); - singleMassReport.exclusiveMass = exclusiveMassG4/(CLHEP::kg); - //std::cout<<"-----> DaughterLV inclusive mass is: "<<singleMassReport.inclusiveMass<<" [kg]"<<std::endl; - - //write the singleMassReport in the json file + + // Here is already excluding the world volume from the calculation, + // Being it made by AIR by default + // calculateMass of each daughter and since the last flag is true, + // write out results in the json file I call this only once -- no + // iteration calculateMass(daughterLV, daughter, jlist, + // inclusiveMassG4, exclusiveMassG4, true); + + inclusiveMassG4 = daughterLV->GetMass( + true, true); // real mass of the LV, inclusive of the masses of + // the daughters + exclusiveMassG4 = daughterLV->GetMass( + true, false); // mass of the LV substracted for the volume + // occupied by the daughters + totalInclusiveMassG4 += inclusiveMassG4; + totalExclusiveMassG4 += exclusiveMassG4; + + // fill the singleMassReport struct + singleMassReport.logicalVolumeName = daughterLV->GetName(); + singleMassReport.physicalVolumeName = daughter->GetName(); + singleMassReport.volumeCopyNo = daughter->GetCopyNo(); + singleMassReport.material = daughterLV->GetMaterial()->GetName(); + singleMassReport.density = daughterLV->GetMaterial()->GetDensity() / + SYSTEM_OF_UNITS::g * + SYSTEM_OF_UNITS::cm3; + singleMassReport.volumeEntityType = + daughterLV->GetSolid()->GetEntityType(); + singleMassReport.inclusiveMass = inclusiveMassG4 / (CLHEP::kg); + singleMassReport.exclusiveMass = exclusiveMassG4 / (CLHEP::kg); + // std::cout<<"-----> DaughterLV inclusive mass is: + // "<<singleMassReport.inclusiveMass<<" [kg]"<<std::endl; + + // write the singleMassReport in the json file to_json(jSingleMassReport, singleMassReport); // write prettified JSON to another file jlist.push_back(jSingleMassReport); - } - - //Calculate the apparentWeight for the whole geometry - //mass of the LV substracted for the volume occupied by the daughters - double exclusiveWorld = worldg4->GetLogicalVolume()->GetMass(true, false); - apparentWeightG4 = exclusiveWorld + totalInclusiveMassG4 - globalMassWorld; - + + // Calculate the apparentWeight for the whole geometry + // mass of the LV substracted for the volume occupied by the daughters + double exclusiveWorld = + worldg4->GetLogicalVolume()->GetMass(true, false); + apparentWeightG4 = + exclusiveWorld + totalInclusiveMassG4 - globalMassWorld; + masscalc::finalMassReport finalMassReport; json jsonFinalMassReport; - //fill the finalMassReport struct - finalMassReport.logicalVolumeName = worldg4->GetLogicalVolume()->GetName(); + // fill the finalMassReport struct + finalMassReport.logicalVolumeName = + worldg4->GetLogicalVolume()->GetName(); finalMassReport.densityThreshold = 0.02; - finalMassReport.material = worldg4->GetLogicalVolume()->GetMaterial()->GetName(); - finalMassReport.volumeEntityType="World Volume"; - finalMassReport.inclusiveMass = totalInclusiveMassG4/(CLHEP::kg); - finalMassReport.exclusiveMass = totalExclusiveMassG4/(CLHEP::kg); - finalMassReport.apparentWeight = apparentWeightG4/(CLHEP::kg); - - std::cout<<"\n=== Calculated total masses ==="<<std::endl; - std::cout<<"Total inclusive mass of the detector is ... "<<totalInclusiveMassG4 / (CLHEP::kg) <<" [kg]."<<std::endl; - std::cout<<"Total exclusive mass of the detector is ... "<<totalExclusiveMassG4 / (CLHEP::kg) <<" [kg]."<<std::endl; - std::cout<<"Total apparent weight in Air of the detector is ... "<<apparentWeightG4 / (CLHEP::kg) <<" [kg]."<<std::endl; - - //Do the same calculation but with a filter on the density - double exclusiveFilteredMass=0.; - double excludedFilteredMass=0.; - iterateFromWorldMass(worldg4->GetLogicalVolume(),jlist, exclusiveFilteredMass, excludedFilteredMass, fPrefixLogicalVolume, fMaterial); - - finalMassReport.exclusiveMassFiltered = exclusiveFilteredMass/(CLHEP::kg); - finalMassReport.excludedMass = excludedFilteredMass/(CLHEP::kg); - - std::cout<<"\n==== Filters by density ===="<<std::endl; - std::cout<<"Total exclusive mass for Geometry filtered by density ... "<<exclusiveFilteredMass / (CLHEP::kg) <<" [kg]."<<std::endl; - std::cout<<"Total ignored mass cause below density threshold ... "<<excludedFilteredMass / (CLHEP::kg) <<" [kg]."<<std::endl; - + finalMassReport.material = + worldg4->GetLogicalVolume()->GetMaterial()->GetName(); + finalMassReport.volumeEntityType = "World Volume"; + finalMassReport.inclusiveMass = totalInclusiveMassG4 / (CLHEP::kg); + finalMassReport.exclusiveMass = totalExclusiveMassG4 / (CLHEP::kg); + finalMassReport.apparentWeight = apparentWeightG4 / (CLHEP::kg); + + std::cout << "\n=== Calculated total masses ===" << std::endl; + std::cout << "Total inclusive mass of the detector is ... " + << totalInclusiveMassG4 / (CLHEP::kg) << " [kg]." + << std::endl; + std::cout << "Total exclusive mass of the detector is ... " + << totalExclusiveMassG4 / (CLHEP::kg) << " [kg]." + << std::endl; + std::cout << "Total apparent weight in Air of the detector is ... " + << apparentWeightG4 / (CLHEP::kg) << " [kg]." << std::endl; + + // Do the same calculation but with a filter on the density + double exclusiveFilteredMass = 0.; + double excludedFilteredMass = 0.; + iterateFromWorldMass(worldg4->GetLogicalVolume(), jlist, + exclusiveFilteredMass, excludedFilteredMass, + fPrefixLogicalVolume, fMaterial); + + finalMassReport.exclusiveMassFiltered = + exclusiveFilteredMass / (CLHEP::kg); + finalMassReport.excludedMass = excludedFilteredMass / (CLHEP::kg); + + std::cout << "\n==== Filters by density ====" << std::endl; + std::cout + << "Total exclusive mass for Geometry filtered by density ... " + << exclusiveFilteredMass / (CLHEP::kg) << " [kg]." << std::endl; + std::cout << "Total ignored mass cause below density threshold ... " + << excludedFilteredMass / (CLHEP::kg) << " [kg]." + << std::endl; + // //This might be misleading, better to comment it out // if (!fGeometryFileName.contains(".gdml")){ - // std::cout<<"\nGeoModel: Total inclusive mass of the detector is ... "<<inclusiveMassGeoModel / (SYSTEM_OF_UNITS::kg) <<" [kg]."<<std::endl; - // std::cout<<"GeoModel: Total exclusive mass of the detector is ... "<<exclusiveMassGeoModel / (SYSTEM_OF_UNITS::kg) <<" [kg]."<<std::endl; + // std::cout<<"\nGeoModel: Total inclusive mass of the + // detector is ... "<<inclusiveMassGeoModel / + // (SYSTEM_OF_UNITS::kg) <<" [kg]."<<std::endl; + // std::cout<<"GeoModel: Total exclusive mass of the detector + // is ... "<<exclusiveMassGeoModel / (SYSTEM_OF_UNITS::kg) + // <<" [kg]."<<std::endl; // } // - //write the finalMassReport in the json file + // write the finalMassReport in the json file to_json(jsonFinalMassReport, finalMassReport); // write prettified JSON to another file jlist.push_back(jsonFinalMassReport); - - + } - //CASE 2: One of the 2 filters or both are used - // Iterate on the whole geometry tree, looking for the logical volumes that correspond to the - // filter research and for those calculate the inclusive and exclusive masses, and write the - // corresponding filled struct in the json file - else - { - iterateFromWorldMass(worldg4->GetLogicalVolume(),jlist, inclusiveMassG4, exclusiveMassG4, fPrefixLogicalVolume, fMaterial); - - //fill the finalMassReport struct + // CASE 2: One of the 2 filters or both are used + // Iterate on the whole geometry tree, looking for the logical volumes that + // correspond to the filter research and for those calculate the inclusive + // and exclusive masses, and write the corresponding filled struct in the + // json file + else { + iterateFromWorldMass(worldg4->GetLogicalVolume(), jlist, + inclusiveMassG4, exclusiveMassG4, + fPrefixLogicalVolume, fMaterial); + + // fill the finalMassReport struct singleMassReport.logicalVolumeName = fPrefixLogicalVolume; - //singleMassReport.physicalVolumeName = fPrefixLogicalVolume; + // singleMassReport.physicalVolumeName = fPrefixLogicalVolume; singleMassReport.volumeCopyNo = worldg4->GetCopyNo(); singleMassReport.material = fMaterial; - singleMassReport.volumeEntityType="Total for filtered Geometry"; - singleMassReport.inclusiveMass = -999; //inclusiveMassG4/(CLHEP::kg); - singleMassReport.exclusiveMass = exclusiveMassG4/(CLHEP::kg); - - - //std::cout<<"\nTotal inclusive mass for the requested Geometry is ... "<<inclusiveMassG4 / (CLHEP::kg) <<" [kg]."<<std::endl; - std::cout<<"Total exclusive mass for the filtered Geometry is ... "<<exclusiveMassG4 / (CLHEP::kg) <<" [kg]."<<std::endl; - - - //write the finalMassReport in the json file + singleMassReport.volumeEntityType = "Total for filtered Geometry"; + singleMassReport.inclusiveMass = -999; // inclusiveMassG4/(CLHEP::kg); + singleMassReport.exclusiveMass = exclusiveMassG4 / (CLHEP::kg); + + // std::cout<<"\nTotal inclusive mass for the requested Geometry is ... + // "<<inclusiveMassG4 / (CLHEP::kg) <<" [kg]."<<std::endl; + std::cout << "Total exclusive mass for the filtered Geometry is ... " + << exclusiveMassG4 / (CLHEP::kg) << " [kg]." << std::endl; + + // write the finalMassReport in the json file to_json(jSingleMassReport, singleMassReport); // write prettified JSON to another file jlist.push_back(jSingleMassReport); } - - + // fAnalysisManager->Write(); // fAnalysisManager->CloseFile(); - } - -void MassCalculator::printGeometryInfo(G4LogicalVolume* lv, G4int verbosity){ - +void MassCalculator::printGeometryInfo(G4LogicalVolume* lv, G4int verbosity) { int localNoDaughters = lv->GetNoDaughters(); - G4VPhysicalVolume *daughter; - G4LogicalVolume *daughterLV; - for (int n=0; n<localNoDaughters; n++) - { - daughter=lv->GetDaughter(n); + G4VPhysicalVolume* daughter; + G4LogicalVolume* daughterLV; + for (int n = 0; n < localNoDaughters; n++) { + daughter = lv->GetDaughter(n); daughterLV = daughter->GetLogicalVolume(); - - std::cout<< "LV_name: "; - std::cout.width(40); std::cout << std::left <<daughter->GetLogicalVolume()->GetName(); - std::cout << std::left << "\tMaterial: "<<daughter->GetLogicalVolume()->GetMaterial()->GetName()<<std::endl; - if (verbosity>1) - std::cout <<daughter->GetLogicalVolume()->GetMaterial()<<std::endl; - - if(daughterLV->GetNoDaughters()>0) + + std::cout << "LV_name: "; + std::cout.width(40); + std::cout << std::left << daughter->GetLogicalVolume()->GetName(); + std::cout << std::left << "\tMaterial: " + << daughter->GetLogicalVolume()->GetMaterial()->GetName() + << std::endl; + if (verbosity > 1) + std::cout << daughter->GetLogicalVolume()->GetMaterial() + << std::endl; + + if (daughterLV->GetNoDaughters() > 0) printGeometryInfo(daughterLV, verbosity); } - } diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoGeometryPluginLoader.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoGeometryPluginLoader.h index 73b0b93bd0152c9681c1be013e5f4d590b4e6af3..2eacec9b86671ec94c091b712c8dbb4524c281d2 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoGeometryPluginLoader.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoGeometryPluginLoader.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration */ #ifndef GEOGEOMETRYPLUGINLOADER_H_ diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVGeometryPlugin.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVGeometryPlugin.h index b2c29a63682f7df1fff2227f72bf9a247da90716..20556f73344d33b499de44d5949a3dee23c79c30 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVGeometryPlugin.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVGeometryPlugin.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration */ #ifndef GEOMODELKERNEL_GEOVGEOMETRYPLUGIN_H @@ -12,50 +12,48 @@ * The geometry plugin builds the raw geometry */ -#include "GeoModelKernel/GeoVPhysVol.h" -#include "GeoModelKernel/GeoPublisher.h" // to publish lists of FullPhysVol and AlignableTransform nodes in create() +#include <memory> // smart pointers -#include <memory> // smart pointers +#include "GeoModelKernel/GeoPublisher.h" // to publish lists of FullPhysVol and AlignableTransform nodes in create() +#include "GeoModelKernel/GeoVPhysVol.h" class GeoPhysVol; -class GeoVGeometryPlugin -{ - public: - - //! Default constructor. - GeoVGeometryPlugin() : m_publisher(nullptr) {} - - //! Parametrized constructor for plugins that publish lists of nodes - GeoVGeometryPlugin(std::string name) : m_publisher(std::make_unique<GeoPublisher>()), m_pluginName( name ) { m_publisher->setName(m_pluginName); } - - - virtual ~GeoVGeometryPlugin() {} - - //! Create the system geometry. - /// Note: this is a pure virtual method, so you need to implement it in your derived plugin class - virtual void create ( GeoPhysVol* world, bool publish = false ) = 0; - - //! Returns the plugin's name - std::string getName() { return m_pluginName; } - - //! Returns the Publisher that publishes the lists of the GeoFullPhysVol and AlignableTransform nodes - GeoPublisher* getPublisher() { return m_publisher.get(); } - - protected: - - //! A GeoPublisher instance is used to publish lists of nodes. - std::unique_ptr<GeoPublisher> m_publisher; - - private: - - /// We prohibit copy constructor, and assignment operator - GeoVGeometryPlugin(const GeoVGeometryPlugin &right)=delete; - GeoVGeometryPlugin & operator=(const GeoVGeometryPlugin &right)=delete; - - - //! The name of the plugin, used to store plugin's published nodes. - std::string m_pluginName; - +class GeoVGeometryPlugin { + public: + //! Default constructor. + GeoVGeometryPlugin() : m_publisher(nullptr) {} + + //! Parametrized constructor for plugins that publish lists of nodes + GeoVGeometryPlugin(std::string name) + : m_publisher(std::make_unique<GeoPublisher>()), m_pluginName(name) { + m_publisher->setName(m_pluginName); + } + + virtual ~GeoVGeometryPlugin() {} + + //! Create the system geometry. + /// Note: this is a pure virtual method, so you need to implement it in your + /// derived plugin class + virtual void create(GeoVPhysVol* world, bool publish = false) = 0; + + //! Returns the plugin's name + std::string getName() { return m_pluginName; } + + //! Returns the Publisher that publishes the lists of the GeoFullPhysVol and + //! AlignableTransform nodes + GeoPublisher* getPublisher() { return m_publisher.get(); } + + protected: + //! A GeoPublisher instance is used to publish lists of nodes. + std::unique_ptr<GeoPublisher> m_publisher; + + private: + /// We prohibit copy constructor, and assignment operator + GeoVGeometryPlugin(const GeoVGeometryPlugin& right) = delete; + GeoVGeometryPlugin& operator=(const GeoVGeometryPlugin& right) = delete; + + //! The name of the plugin, used to store plugin's published nodes. + std::string m_pluginName; }; #endif diff --git a/GeoModelTools/GDMLtoGM/src/GDMLtoGM.cxx b/GeoModelTools/GDMLtoGM/src/GDMLtoGM.cxx index 4530b696d4113a92841a03f1b5e0fc90762737fb..4b8ed534a4d2f0177e03fe1f658441b44bb6eef5 100644 --- a/GeoModelTools/GDMLtoGM/src/GDMLtoGM.cxx +++ b/GeoModelTools/GDMLtoGM/src/GDMLtoGM.cxx @@ -31,7 +31,7 @@ class GDMLtoGM : public GeoVGeometryPlugin { ~GDMLtoGM(); // Creation of geometry: - virtual void create(GeoPhysVol *world, bool publish = false ) override; + virtual void create(GeoVPhysVol *world, bool publish = false ) override; private: @@ -43,12 +43,11 @@ class GDMLtoGM : public GeoVGeometryPlugin { GDMLtoGM::~GDMLtoGM() -{ -} +{} //## Other Operations (implementation) -void GDMLtoGM::create(GeoPhysVol *world, bool /* 'publish' is not used here */) +void GDMLtoGM::create(GeoVPhysVol *world, bool /* 'publish' is not used here */) { char* fPath=getenv("GDML_FILE_NAME"); std::string fileName; diff --git a/GeoModelTools/GMCAT/src/gmcat.cxx b/GeoModelTools/GMCAT/src/gmcat.cxx index f2d37bbaa3224828b8298c78b6b88ad2773d51d7..983d30388602a3ce43c361ff65f05562156fca76 100644 --- a/GeoModelTools/GMCAT/src/gmcat.cxx +++ b/GeoModelTools/GMCAT/src/gmcat.cxx @@ -1,266 +1,274 @@ /* - * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration -*/ + * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + */ -#include "GeoModelKernel/GeoVGeometryPlugin.h" -#include "GeoModelDBManager/GMDBManager.h" -#include "GeoModelRead/ReadGeoModel.h" -#include "GeoModelWrite/WriteGeoModel.h" +#include <stdlib.h> // setenv +#include <unistd.h> -#include "GeoModelKernel/GeoGeometryPluginLoader.h" -#include "GeoModelKernel/GeoVolumeCursor.h" -#include "GeoModelKernel/GeoMaterial.h" -#include "GeoModelKernel/GeoElement.h" -#include "GeoModelKernel/GeoPVLink.h" +#include <cstdio> +#include <iostream> +#include <string> +#include <vector> + +#include "GeoModelDBManager/GMDBManager.h" +#include "GeoModelKernel/GeoAccessVolumeAction.h" #include "GeoModelKernel/GeoBox.h" #include "GeoModelKernel/GeoCountVolAction.h" -#include "GeoModelKernel/GeoAccessVolumeAction.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoGeometryPluginLoader.h" +#include "GeoModelKernel/GeoMaterial.h" #include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPVLink.h" #include "GeoModelKernel/GeoPublisher.h" - -#include <iostream> -#include <string> -#include <vector> -#include <cstdio> -#include <unistd.h> -#include <stdlib.h> // setenv +#include "GeoModelKernel/GeoVGeometryPlugin.h" +#include "GeoModelKernel/GeoVolumeCursor.h" +#include "GeoModelRead/ReadGeoModel.h" +#include "GeoModelWrite/WriteGeoModel.h" #ifdef __APPLE__ -const std::string shared_obj_extension=".dylib"; +const std::string shared_obj_extension = ".dylib"; #else -const std::string shared_obj_extension=".so"; +const std::string shared_obj_extension = ".so"; #endif -#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm' - -int main(int argc, char ** argv) { - - - struct Metadata { - std::string dateString; - std::string geoModelDataBranch; - } metadata; - - // Fill metadata; - - { - // Ceci n'es pas une pipe: - FILE *ceci=popen("date -Im","r"); - if (ceci) { - char buff[1024]; - if (fscanf(ceci,"%s",buff)) { - metadata.dateString=buff; - } - pclose(ceci); +#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm' + +int main(int argc, char **argv) { + struct Metadata { + std::string dateString; + std::string geoModelDataBranch; + } metadata; + + // Fill metadata; + + { + // Ceci n'es pas une pipe: + FILE *ceci = popen("date -Im", "r"); + if (ceci) { + char buff[1024]; + if (fscanf(ceci, "%s", buff)) { + metadata.dateString = buff; + } + pclose(ceci); + } } - } - char *geomodel_xml_dir=getenv("GEOMODEL_XML_DIR"); - if (geomodel_xml_dir) { - std::string cmd="git -C "+ std::string(geomodel_xml_dir) + " rev-parse --abbrev-ref HEAD"; - // Ceci n'es pas une pipe: - FILE *ceci=popen(cmd.c_str(),"r"); - if (ceci) { - char buff[1024]; - if (fscanf(ceci,"%s",buff)) { - metadata.geoModelDataBranch=buff; - } - pclose(ceci); + char *geomodel_xml_dir = getenv("GEOMODEL_XML_DIR"); + if (geomodel_xml_dir) { + std::string cmd = "git -C " + std::string(geomodel_xml_dir) + + " rev-parse --abbrev-ref HEAD"; + // Ceci n'es pas une pipe: + FILE *ceci = popen(cmd.c_str(), "r"); + if (ceci) { + char buff[1024]; + if (fscanf(ceci, "%s", buff)) { + metadata.geoModelDataBranch = buff; + } + pclose(ceci); + } } - } - - - // - // Usage message: - // - std::string gmcat= argv[0]; - std::string usage= "usage: " + gmcat + " [plugin1"+shared_obj_extension - + "] [plugin2" + shared_obj_extension - + "] ...[file1.db] [file2.db].. -o outputFile]"; - // - // Print usage message if no args given: - // - if (argc==1) { - std::cerr << usage << std::endl; - return 0; - } - // - // Parse the command line: - // - std::vector<std::string> inputFiles; - std::vector<std::string> inputPlugins; - std::string outputFile; - bool outputFileSet = false; - for (int argi=1;argi<argc;argi++) { - std::string argument=argv[argi]; - if (argument.find("-o")!=std::string::npos) { - argi++; - if (argi>=argc) { - std::cerr << usage << std::endl; - return 1; - } - outputFile=argv[argi]; - outputFileSet = true; - } - else if (argument.find("-v")!=std::string::npos) { - setenv("GEOMODEL_GEOMODELIO_VERBOSE", "1", 1); // does overwrite - std::cout << "You set the verbosity level to 1" << std::endl; - } - else if (argument.find(shared_obj_extension)!=std::string::npos) { - inputPlugins.push_back(argument); - } - else if (argument.find(".db")!=std::string::npos) { - inputFiles.push_back(argument); - } - else { - std::cerr << "Unrecognized argument " << argument << std::endl; - std::cerr << usage << std::endl; - return 2; - } - } - if( !outputFileSet ) { - std::cerr << "\nERROR! You should set an output file.\n" << std::endl; - std::cerr << usage << std::endl; - return 3; - } - - // - // Check that we can access the output file - // - if (access(outputFile.c_str(),F_OK)==0) { - if (!access(outputFile.c_str(),W_OK)) { - if (system(("rm -f "+ outputFile).c_str())) { - std::cerr << "gmcat -- Error, cannot overwrite existing file " << outputFile << std::endl; - return 3; - } + // + // Usage message: + // + + std::string gmcat = argv[0]; + std::string usage = "usage: " + gmcat + " [plugin1" + shared_obj_extension + + "] [plugin2" + shared_obj_extension + + "] ...[file1.db] [file2.db].. -o outputFile]"; + // + // Print usage message if no args given: + // + if (argc == 1) { + std::cerr << usage << std::endl; + return 0; } - else { - std::cerr << "gmcat -- Error, cannot overwrite existing file " << outputFile << " (permission denied)" << std::endl; - return 4; + // + // Parse the command line: + // + std::vector<std::string> inputFiles; + std::vector<std::string> inputPlugins; + std::string outputFile; + bool outputFileSet = false; + for (int argi = 1; argi < argc; argi++) { + std::string argument = argv[argi]; + if (argument.find("-o") != std::string::npos) { + argi++; + if (argi >= argc) { + std::cerr << usage << std::endl; + return 1; + } + outputFile = argv[argi]; + outputFileSet = true; + } else if (argument.find("-v") != std::string::npos) { + setenv("GEOMODEL_GEOMODELIO_VERBOSE", "1", 1); // does overwrite + std::cout << "You set the verbosity level to 1" << std::endl; + } else if (argument.find(shared_obj_extension) != std::string::npos) { + inputPlugins.push_back(argument); + } else if (argument.find(".db") != std::string::npos) { + inputFiles.push_back(argument); + } else { + std::cerr << "Unrecognized argument " << argument << std::endl; + std::cerr << usage << std::endl; + return 2; + } } - } - - - // - // Create elements and materials for the "World" volume, which is the container: - // - - const double gr = SYSTEM_OF_UNITS::gram; - const double mole = SYSTEM_OF_UNITS::mole; - const double cm3 = SYSTEM_OF_UNITS::cm3; - - // Define the chemical elements - GeoElement* Nitrogen = new GeoElement ("Nitrogen" ,"N" , 7.0 , 14.0067 *gr/mole); - GeoElement* Oxygen = new GeoElement ("Oxygen" ,"O" , 8.0 , 15.9995 *gr/mole); - GeoElement* Argon = new GeoElement ("Argon" ,"Ar" , 18.0 , 39.948 *gr/mole); - GeoElement* Hydrogen = new GeoElement ("Hydrogen" ,"H" , 1.0 , 1.00797 *gr/mole); - - double densityOfAir=0.001214 *gr/cm3; - GeoMaterial *air = new GeoMaterial("Air", densityOfAir); - air->add(Nitrogen , 0.7494); - air->add(Oxygen, 0.2369); - air->add(Argon, 0.0129); - air->add(Hydrogen, 0.0008); - air->lock(); - - // - // Create a huge world volume made of Air: - // - - const GeoBox* worldBox = new GeoBox(2000*SYSTEM_OF_UNITS::cm, 2000*SYSTEM_OF_UNITS::cm, 2500*SYSTEM_OF_UNITS::cm); - const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); - GeoPhysVol *world=new GeoPhysVol(worldLog); - world->ref(); - // - // Loop over plugins, create the geometry and put it under the world: - // - std::vector<GeoPublisher*> vecPluginsPublishers; // caches the stores from all plugins - for (const std::string & plugin : inputPlugins) { - GeoGeometryPluginLoader loader; - GeoVGeometryPlugin *factory=loader.load(plugin); - if (!factory) { - std::cerr << "gmcat -- Could not load plugin " << plugin << std::endl; - return 5; + if (!outputFileSet) { + std::cerr << "\nERROR! You should set an output file.\n" << std::endl; + std::cerr << usage << std::endl; + return 3; } - - // NOTE: we want the plugin to publish lits FPV and AXF nodes, - // if it is intended to do that, and store them in the DB. - // For that, we pass a true to the plugin's `create()` method, - // which will use it to publish nodes, - // and then we get from the plugin the pointer to the GeoPublisher instance - // and we cache it for later, to dump the published nodes into the DB. - factory->create(world, true); - if( nullptr != factory->getPublisher() ) { - vecPluginsPublishers.push_back( factory->getPublisher() ); // cache the publisher, if any, for later - } - } - // - // Loop over files, create the geometry and put it under the world: - // - for (const std::string & file : inputFiles) { - GMDBManager* db = new GMDBManager(file); - if (!db->checkIsDBOpen()){ - std::cerr << "gmcat -- Error opening the input file: " << file << std::endl; - return 6; + // + // Check that we can access the output file + // + if (access(outputFile.c_str(), F_OK) == 0) { + if (!access(outputFile.c_str(), W_OK)) { + if (system(("rm -f " + outputFile).c_str())) { + std::cerr << "gmcat -- Error, cannot overwrite existing file " + << outputFile << std::endl; + return 3; + } + } else { + std::cerr << "gmcat -- Error, cannot overwrite existing file " + << outputFile << " (permission denied)" << std::endl; + return 4; + } } - /* set the GeoModel reader */ - GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); - - /* build the GeoModel geometry */ - GeoPhysVol* dbPhys = readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory - - /* get an handle on a Volume Cursor, to traverse the whole set of Volumes */ - GeoVolumeCursor aV(dbPhys); - - /* loop over the Volumes in the tree */ - while (!aV.atEnd()) { - - if (aV.getName()!="ANON") { - GeoNameTag *nameTag=new GeoNameTag(aV.getName()); - world->add(nameTag); - } - GeoTransform *transform= new GeoTransform(aV.getTransform()); - world->add(transform); - world->add((GeoVPhysVol *) &*aV.getVolume()); - aV.next(); + // + // Create elements and materials for the "World" volume, which is the + // container: + // + + const double gr = SYSTEM_OF_UNITS::gram; + const double mole = SYSTEM_OF_UNITS::mole; + const double cm3 = SYSTEM_OF_UNITS::cm3; + + // Define the chemical elements + GeoElement *Nitrogen = + new GeoElement("Nitrogen", "N", 7.0, 14.0067 * gr / mole); + GeoElement *Oxygen = + new GeoElement("Oxygen", "O", 8.0, 15.9995 * gr / mole); + GeoElement *Argon = new GeoElement("Argon", "Ar", 18.0, 39.948 * gr / mole); + GeoElement *Hydrogen = + new GeoElement("Hydrogen", "H", 1.0, 1.00797 * gr / mole); + + double densityOfAir = 0.001214 * gr / cm3; + GeoMaterial *air = new GeoMaterial("Air", densityOfAir); + air->add(Nitrogen, 0.7494); + air->add(Oxygen, 0.2369); + air->add(Argon, 0.0129); + air->add(Hydrogen, 0.0008); + air->lock(); + + // + // Create a huge world volume made of Air: + // + + const GeoBox *worldBox = + new GeoBox(2000 * SYSTEM_OF_UNITS::cm, 2000 * SYSTEM_OF_UNITS::cm, + 2500 * SYSTEM_OF_UNITS::cm); + const GeoLogVol *worldLog = new GeoLogVol("WorldLog", worldBox, air); + GeoPhysVol *world = new GeoPhysVol(worldLog); + world->ref(); + // + // Loop over plugins, create the geometry and put it under the world: + // + std::vector<GeoPublisher *> + vecPluginsPublishers; // caches the stores from all plugins + for (const std::string &plugin : inputPlugins) { + GeoGeometryPluginLoader loader; + GeoVGeometryPlugin *factory = loader.load(plugin); + if (!factory) { + std::cerr << "gmcat -- Could not load plugin " << plugin + << std::endl; + return 5; + } + + // NOTE: we want the plugin to publish lits FPV and AXF nodes, + // if it is intended to do that, and store them in the DB. + // For that, we pass a true to the plugin's `create()` method, + // which will use it to publish nodes, + // and then we get from the plugin the pointer to the GeoPublisher + // instance and we cache it for later, to dump the published nodes into + // the DB. + factory->create(world, true); + if (nullptr != factory->getPublisher()) { + vecPluginsPublishers.push_back( + factory->getPublisher()); // cache the publisher, if any, for + // later + } } - delete db; - } - // - // Open a new database: - // - GMDBManager db(outputFile); - // - // check the DB connection - // - if (!db.checkIsDBOpen()) { - std::cerr << "gmcat -- Error opening the output file: " << outputFile << std::endl; - return 7; - } - // - // Fill the header file with metadata - // - std::vector<std::string> gmcatColNames={"Date", "GeoModelDataBranch"}; - std::vector<std::string> gmcatColTypes={"STRING", "STRING" }; - std::vector<std::vector<std::variant<int,long,float,double,std::string>>> gmcatData ={{metadata.dateString, metadata.geoModelDataBranch}}; - - db.createCustomTable("AAHEADER", gmcatColNames,gmcatColTypes,gmcatData); - GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); - world->exec(&dumpGeoModelGraph); - - - if (vecPluginsPublishers.size() > 0) { - dumpGeoModelGraph.saveToDB(vecPluginsPublishers); - } else { - dumpGeoModelGraph.saveToDB(); - } - - world->unref(); + // + // Loop over files, create the geometry and put it under the world: + // + for (const std::string &file : inputFiles) { + GMDBManager *db = new GMDBManager(file); + if (!db->checkIsDBOpen()) { + std::cerr << "gmcat -- Error opening the input file: " << file + << std::endl; + return 6; + } + + /* set the GeoModel reader */ + GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); + + /* build the GeoModel geometry */ + // builds the whole GeoModel tree in memory + GeoVPhysVol *dbPhys = readInGeo.buildGeoModel(); + + /* get an handle on a Volume Cursor, to traverse the whole set of + * Volumes */ + GeoVolumeCursor aV(dbPhys); + + /* loop over the Volumes in the tree */ + while (!aV.atEnd()) { + if (aV.getName() != "ANON") { + GeoNameTag *nameTag = new GeoNameTag(aV.getName()); + world->add(nameTag); + } + GeoTransform *transform = new GeoTransform(aV.getTransform()); + world->add(transform); + world->add((GeoVPhysVol *)&*aV.getVolume()); + aV.next(); + } + + delete db; + } + // + // Open a new database: + // + GMDBManager db(outputFile); + // + // check the DB connection + // + if (!db.checkIsDBOpen()) { + std::cerr << "gmcat -- Error opening the output file: " << outputFile + << std::endl; + return 7; + } + // + // Fill the header file with metadata + // + std::vector<std::string> gmcatColNames = {"Date", "GeoModelDataBranch"}; + std::vector<std::string> gmcatColTypes = {"STRING", "STRING"}; + std::vector< + std::vector<std::variant<int, long, float, double, std::string>>> + gmcatData = {{metadata.dateString, metadata.geoModelDataBranch}}; + + db.createCustomTable("AAHEADER", gmcatColNames, gmcatColTypes, gmcatData); + GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); + world->exec(&dumpGeoModelGraph); + + if (vecPluginsPublishers.size() > 0) { + dumpGeoModelGraph.saveToDB(vecPluginsPublishers); + } else { + dumpGeoModelGraph.saveToDB(); + } + world->unref(); - return 0; + return 0; } diff --git a/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx b/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx index f04800be9a091cc7e2a896a43390220d8231c8a8..6fe46685ff0616e342ec77a59b6d9e614144f0c1 100644 --- a/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx +++ b/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx @@ -1,137 +1,118 @@ /* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration */ - -#include "GeoModelKernel/GeoVGeometryPlugin.h" - - -#include "GeoModelKernel/GeoPhysVol.h" #include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVGeometryPlugin.h" #include "GeoModelKernel/Units.h" -#define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' - -#include "GeoModelXml/GmxInterface.h" -#include "GeoModelXml/Gmx2Geo.h" +#define SYSTEM_OF_UNITS \ + GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' -#include <iostream> #include <fstream> +#include <iostream> #include <sstream> -class GMXPlugin : public GeoVGeometryPlugin { - - public: +#include "GeoModelXml/Gmx2Geo.h" +#include "GeoModelXml/GmxInterface.h" - // Constructor: - GMXPlugin(); +class GMXPlugin : public GeoVGeometryPlugin { + public: + // Constructor: + GMXPlugin(); - // Constructor with name to provide to publisher - GMXPlugin(std::string name):GeoVGeometryPlugin(name){} + // Constructor with name to provide to publisher + GMXPlugin(std::string name) : GeoVGeometryPlugin(name) {} - // Destructor: - ~GMXPlugin(); + // Destructor: + ~GMXPlugin(); - // Creation of geometry: - virtual void create(GeoPhysVol *world, bool publish) override; + // Creation of geometry: + virtual void create(GeoVPhysVol *world, bool publish) override; - private: + private: + // Illegal operations: + const GMXPlugin &operator=(const GMXPlugin &right) = delete; + GMXPlugin(const GMXPlugin &right) = delete; - // Illegal operations: - const GMXPlugin & operator=(const GMXPlugin &right)=delete; - GMXPlugin(const GMXPlugin &right) = delete; + bool exists(const std::string &name) { + std::ifstream f(name.c_str()); + return f.good(); + } - bool exists (const std::string& name) - { - std::ifstream f(name.c_str()); - return f.good(); - } + std::vector<std::string> parseFiles(const std::string s, + std::string delimiter = ";") { + size_t pos_start = 0, pos_end, delim_len = delimiter.length(); + std::string token; + std::vector<std::string> res; - std::vector<std::string> parseFiles(const std::string s, std::string delimiter=";") - { - size_t pos_start = 0, pos_end, delim_len = delimiter.length(); - std::string token; - std::vector<std::string> res; + while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) { + token = s.substr(pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + res.push_back(token); + } - while ((pos_end = s.find (delimiter, pos_start)) != std::string::npos) { - token = s.substr (pos_start, pos_end - pos_start); - pos_start = pos_end + delim_len; - res.push_back (token); + res.push_back(s.substr(pos_start)); + return res; } - - res.push_back (s.substr (pos_start)); - return res; - } - }; - - - - -GMXPlugin::GMXPlugin() -{ -} - - -GMXPlugin::~GMXPlugin() -{ -} - - -//## Other Operations (implementation) -void GMXPlugin::create(GeoPhysVol *world, bool publish) -{ - std::cout<< "This is GMXPlugin: creating a GeoModelXml detector "<<std::endl; - std::vector<std::string> filesToParse; - char* fPath=getenv("GMX_FILES"); - std::string fileName; - if (fPath!=NULL) { - std::cout<<" Environment variable GMX_FILES set to "<<fPath<<std::endl; - fileName=std::string(fPath); - filesToParse=parseFiles(fileName,":"); - } - else { - fileName="gmx.xml"; - filesToParse.push_back(fileName); - } - - char* matManager=getenv("GMX_USE_MATMANAGER"); - bool matman=0; - if (matManager!=nullptr) - { - std::cout<<" Environment variable GMX_USE_MATMANAGER set to "<<matManager<<std::endl; - std::istringstream ss(matManager); - ss>>matman; - std::cout<<"matman set to "<<matman<<std::endl; - } - - char* levelmaps=getenv("GMX_DUMP_LEVEL_MAPS"); - - for (auto f: filesToParse) - { - if (!exists(f)) { - std::cout <<"GDMLtoGeo: input file "<<f<< - " does not exist. quitting and returning nicely! "<<std::endl; - return; +GMXPlugin::GMXPlugin() {} + +GMXPlugin::~GMXPlugin() {} + +// ## Other Operations (implementation) +void GMXPlugin::create(GeoVPhysVol *world, bool publish) { + std::cout << "This is GMXPlugin: creating a GeoModelXml detector " + << std::endl; + std::vector<std::string> filesToParse; + char *fPath = getenv("GMX_FILES"); + std::string fileName; + if (fPath != NULL) { + std::cout << " Environment variable GMX_FILES set to " << fPath + << std::endl; + fileName = std::string(fPath); + filesToParse = parseFiles(fileName, ":"); + } else { + fileName = "gmx.xml"; + filesToParse.push_back(fileName); } - GmxInterface gmxInterface; - //If we want to write the SQLite, pass a publisher through to fill Aux tables - //(needed for ReadoutGeometry) - if(publish) gmxInterface.setPublisher(getPublisher()); - - if (levelmaps!=nullptr){ - std::string mapname = f.substr(0, f.length() - 4); - mapname+="_levelMap.txt"; - std::cout<<"Dumping Copy Number Level Map to "<<mapname<<std::endl; - Gmx2Geo gmx2Geo(f, world, gmxInterface, 0 , matman, mapname); + + char *matManager = getenv("GMX_USE_MATMANAGER"); + bool matman = 0; + if (matManager != nullptr) { + std::cout << " Environment variable GMX_USE_MATMANAGER set to " + << matManager << std::endl; + std::istringstream ss(matManager); + ss >> matman; + std::cout << "matman set to " << matman << std::endl; } - else Gmx2Geo gmx2Geo(f, world, gmxInterface, 0 , matman); - } - if (matman) MaterialManager::getManager()->printAll(); + char *levelmaps = getenv("GMX_DUMP_LEVEL_MAPS"); + + for (auto f : filesToParse) { + if (!exists(f)) { + std::cout << "GDMLtoGeo: input file " << f + << " does not exist. quitting and returning nicely! " + << std::endl; + return; + } + GmxInterface gmxInterface; + // If we want to write the SQLite, pass a publisher through to fill Aux + // tables (needed for ReadoutGeometry) + if (publish) gmxInterface.setPublisher(getPublisher()); + + if (levelmaps != nullptr) { + std::string mapname = f.substr(0, f.length() - 4); + mapname += "_levelMap.txt"; + std::cout << "Dumping Copy Number Level Map to " << mapname + << std::endl; + Gmx2Geo gmx2Geo(f, world, gmxInterface, 0, matman, mapname); + } else + Gmx2Geo gmx2Geo(f, world, gmxInterface, 0, matman); + } + if (matman) MaterialManager::getManager()->printAll(); } -extern "C" GMXPlugin *createGMXPlugin() { - return new GMXPlugin("GeoModelXML"); -} +extern "C" GMXPlugin *createGMXPlugin() { return new GMXPlugin("GeoModelXML"); } diff --git a/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx b/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx index b6b1d0f9a233c1852b14e69898016d0bfbcbec8c..d823082e873e266487ef923666db80b269578b88 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx @@ -1,1865 +1,1993 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration */ ///////////////////////////////////////////////////////////////////////// -// -// Implementation of class VP1GeometrySystem -// -// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> -// -// Derived from V-atlas geometry system by Joe Boudreau. -// Origins of initial version dates back to ~1996, initial VP1 -// version by TK (May 2007) and almost entirely rewritten Oct 2007. -// Major refactoring october 2008. -// -// Updates: -// - Aug 2019, Riccardo Maria Bianchi @ CERN -// - Aug 2020, Riccardo Maria Bianchi @ CERN -// - Jul 2021, Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> +// +// Implementation of class VP1GeometrySystem +// +// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> +// +// Derived from V-atlas geometry system by Joe Boudreau. +// Origins of initial version dates back to ~1996, initial VP1 +// version by TK (May 2007) and almost entirely rewritten Oct 2007. +// Major refactoring october 2008. +// +// Updates: +// - Aug 2019, Riccardo Maria Bianchi @ CERN +// - Aug 2020, Riccardo Maria Bianchi @ CERN +// - Jul 2021, Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> // * Added the 'filter volumes' tool // * Added signal/slot to update transparency type in the 3D window -// +// ///////////////////////////////////////////////////////////////////////// // local includes #include "VP1GeometrySystems/VP1GeometrySystem.h" + +#include "VP1Base/VP1CameraHelper.h" +#include "VP1Base/VP1Deserialise.h" +#include "VP1Base/VP1Msg.h" +#include "VP1Base/VP1QtInventorUtils.h" +#include "VP1Base/VP1Serialise.h" +#include "VP1GeometrySystems/DumpShape.h" #include "VP1GeometrySystems/GeoSysController.h" +#include "VP1GeometrySystems/PhiSectorManager.h" #include "VP1GeometrySystems/VP1GeoTreeView.h" +#include "VP1GeometrySystems/VP1GeomUtils.h" +#include "VP1GeometrySystems/VisAttributes.h" #include "VP1GeometrySystems/VolumeHandle.h" #include "VP1GeometrySystems/VolumeHandleSharedData.h" #include "VP1GeometrySystems/VolumeTreeModel.h" -#include "VP1GeometrySystems/VP1GeomUtils.h" -#include "VP1GeometrySystems/VisAttributes.h" -#include "VP1GeometrySystems/DumpShape.h" -#include "VP1GeometrySystems/PhiSectorManager.h" -#include "VP1Base/VP1CameraHelper.h" -#include "VP1Base/VP1QtInventorUtils.h" -#include "VP1Base/VP1Serialise.h" -#include "VP1Base/VP1Deserialise.h" -#include "VP1Base/VP1Msg.h" - // Coin/OpenInventor includes -#include <Inventor/nodes/SoSeparator.h> -#include <Inventor/nodes/SoSwitch.h> -#include <Inventor/nodes/SoMaterial.h> -#include <Inventor/nodes/SoTexture2.h> #include <Inventor/events/SoKeyboardEvent.h> -#include <Inventor/nodes/SoPickStyle.h> -#include <Inventor/nodes/SoEventCallback.h> #include <Inventor/nodes/SoCamera.h> -#include <Inventor/nodes/SoCylinder.h> -#include <Inventor/nodes/SoFont.h> -#include <Inventor/nodes/SoText2.h> -#include <Inventor/nodes/SoTranslation.h> -#include <Inventor/nodes/SoLineSet.h> #include <Inventor/nodes/SoCoordinate3.h> +#include <Inventor/nodes/SoCylinder.h> #include <Inventor/nodes/SoDrawStyle.h> +#include <Inventor/nodes/SoEventCallback.h> +#include <Inventor/nodes/SoFont.h> #include <Inventor/nodes/SoLightModel.h> -#include <Inventor/nodes/SoTransform.h> +#include <Inventor/nodes/SoLineSet.h> +#include <Inventor/nodes/SoMaterial.h> +#include <Inventor/nodes/SoPickStyle.h> #include <Inventor/nodes/SoScale.h> +#include <Inventor/nodes/SoSeparator.h> +#include <Inventor/nodes/SoSwitch.h> +#include <Inventor/nodes/SoText2.h> +#include <Inventor/nodes/SoTexture2.h> +#include <Inventor/nodes/SoTransform.h> +#include <Inventor/nodes/SoTranslation.h> // GeoModelCore includes -#include "GeoModelKernel/GeoVolumeCursor.h" -#include "GeoModelKernel/GeoPrintGraphAction.h" -#include "GeoModelKernel/GeoMaterial.h" -#include "GeoModelKernel/GeoElement.h" -#include "GeoModelKernel/GeoPVLink.h" +#include "GeoModelKernel/GeoAccessVolumeAction.h" #include "GeoModelKernel/GeoBox.h" #include "GeoModelKernel/GeoCountVolAction.h" -#include "GeoModelKernel/GeoAccessVolumeAction.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoGeometryPluginLoader.h" +#include "GeoModelKernel/GeoMaterial.h" #include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPVLink.h" +#include "GeoModelKernel/GeoPrintGraphAction.h" +#include "GeoModelKernel/GeoPublisher.h" #include "GeoModelKernel/GeoVGeometryPlugin.h" +#include "GeoModelKernel/GeoVolumeCursor.h" #include "GeoModelKernel/Units.h" -#include "GeoModelKernel/GeoNameTag.h" -#include "GeoModelKernel/GeoGeometryPluginLoader.h" -#include "GeoModelKernel/GeoPublisher.h" // GeoModelIO includes #include "GeoModelDBManager/GMDBManager.h" -#include "GeoModelWrite/WriteGeoModel.h" #include "GeoModelRead/ReadGeoModel.h" +#include "GeoModelWrite/WriteGeoModel.h" -// WARNING: classes making use of 'Persistifier' should be included AFTER 'GeoModelIO/ReadGeoModel' -#include "GeoModelKernel/GeoShapeUnion.h" +// WARNING: classes making use of 'Persistifier' should be included AFTER +// 'GeoModelIO/ReadGeoModel' #include "GeoModelKernel/GeoShapeShift.h" +#include "GeoModelKernel/GeoShapeUnion.h" // Qt includes -#include <QStack> -#include <QString> -#include <QSettings> -#include <QDebug> -#include <QRegExp> -#include <QByteArray> -#include <QTimer> -#include <QHeaderView> #include <QApplication> +#include <QByteArray> #include <QCheckBox> -#include <QMessageBox> -#include <QFileInfo> +#include <QDebug> #include <QFileDialog> +#include <QFileInfo> +#include <QHeaderView> +#include <QMessageBox> #include <QPushButton> +#include <QRegExp> +#include <QSettings> +#include <QStack> +#include <QString> +#include <QTimer> // C++ includes -#include <map> #include <unistd.h> + +#include <map> #include <stdexcept> -#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm' +#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm' static QString m_existingGeoInput; - - class VP1GeometrySystem::Imp { -public: - Imp (VP1GeometrySystem*gs) - : theclass(gs), sceneroot(0), - detVisAttributes(0), matVisAttributes(0), volVisAttributes(0), - controller(0),phisectormanager(0), - volumetreemodel(0),kbEvent(0),m_textSep(0) {} - - - VP1GeometrySystem * theclass; - SoSeparator * sceneroot; - - std::map<SoSeparator*,VolumeHandle*> sonodesep2volhandle; - //Might be needed later: std::map<GeoPVConstLink,VolumeHandle*> pv2volhandle; - - GeoPhysVol* getGeometry(); - GeoPhysVol* createTheWorld(GeoPhysVol* world = nullptr); - GeoPhysVol* getGeometryFromLocalDB(); - - SoTexture2* getDummyTexture(); - SoMaterial* getDummyMaterial(); - - QString selectGeometryFile(); - - class SubSystemInfo { - public: - // "geomodellocation" contains name of tree tops, - // or possible a bit more complex info in case of muons. - SubSystemInfo( QCheckBox* cb, const std::string &systemName, - VP1GeoFlags::SubSystemFlag the_flag, - const std::string& the_matname) - - : isbuilt(false), checkbox(cb), - systemName(systemName), - matname(the_matname), flag(the_flag), soswitch(0) - { - } - - //Info needed to define the system (along with the checkbox pointer in the map below): - bool isbuilt; - VolumeHandle::VolumeHandleList vollist; - QCheckBox* checkbox; - - std::string systemName; //For picking the geomodel treetops - - std::string matname; //if nonempty, use this from detvisattr instead of the top volname. - VP1GeoFlags::SubSystemFlag flag; - - - //Information needed to initialise the system: - class TreetopInfo { public: - TreetopInfo() {} - PVConstLink pV; - GeoTrf::Transform3D xf;// = av.getTransform(); - std::string volname; + public: + Imp(VP1GeometrySystem *gs) + : theclass(gs), + sceneroot(0), + detVisAttributes(0), + matVisAttributes(0), + volVisAttributes(0), + controller(0), + phisectormanager(0), + volumetreemodel(0), + kbEvent(0), + m_textSep(0) {} + + VP1GeometrySystem *theclass; + SoSeparator *sceneroot; + + std::map<SoSeparator *, VolumeHandle *> sonodesep2volhandle; + // Might be needed later: std::map<GeoPVConstLink,VolumeHandle*> + // pv2volhandle; + + GeoVPhysVol *getGeometry(); + GeoVPhysVol *createTheWorld(GeoVPhysVol *world = nullptr); + GeoVPhysVol *getGeometryFromLocalDB(); + + SoTexture2 *getDummyTexture(); + SoMaterial *getDummyMaterial(); + + QString selectGeometryFile(); + + class SubSystemInfo { + public: + // "geomodellocation" contains name of tree tops, + // or possible a bit more complex info in case of muons. + SubSystemInfo(QCheckBox *cb, const std::string &systemName, + VP1GeoFlags::SubSystemFlag the_flag, + const std::string &the_matname) + + : isbuilt(false), + checkbox(cb), + systemName(systemName), + matname(the_matname), + flag(the_flag), + soswitch(0) {} + + // Info needed to define the system (along with the checkbox pointer in + // the map below): + bool isbuilt; + VolumeHandle::VolumeHandleList vollist; + QCheckBox *checkbox; + + std::string systemName; // For picking the geomodel treetops + + std::string matname; // if nonempty, use this from detvisattr instead + // of the top volname. + VP1GeoFlags::SubSystemFlag flag; + + // Information needed to initialise the system: + class TreetopInfo { + public: + TreetopInfo() {} + PVConstLink pV; + GeoTrf::Transform3D xf; // = av.getTransform(); + std::string volname; + }; + std::vector<TreetopInfo> treetopinfo; + + // Switch associated with the system - it is initialised only if the + // system has info available: + SoSwitch *soswitch; }; - std::vector<TreetopInfo> treetopinfo; - - //Switch associated with the system - it is initialised only if the system has info available: - SoSwitch * soswitch; - }; - - QList<SubSystemInfo*> subsysInfoList;//We need to keep and ordered version also (since wildcards in regexp might match more than one subsystem info). - void addSubSystem(const VP1GeoFlags::SubSystemFlag&, const std::string & systemName, const std::string& matname=""); - - DetVisAttributes *detVisAttributes; - MatVisAttributes *matVisAttributes; - VolVisAttributes *volVisAttributes; - void ensureInitVisAttributes() { - if (!detVisAttributes) detVisAttributes = new DetVisAttributes(); - if (!matVisAttributes) matVisAttributes = new MatVisAttributes(); - if (!volVisAttributes) volVisAttributes = new VolVisAttributes(); - } - - - void buildSystem(SubSystemInfo*); - GeoSysController * controller; - PhiSectorManager * phisectormanager; - VolumeTreeModel * volumetreemodel; - - //Helpers used for printouts://FIXME: To VolumeHandle!! - static double exclusiveMass(const PVConstLink& pv); - static double inclusiveMass(const PVConstLink& pv); - static double volume(const PVConstLink& pv); - - //Basically for the zapping, and to ignore all clicks with ctrl/shift: - static void catchKbdState(void *userData, SoEventCallback *CB); - const SoKeyboardEvent *kbEvent; - - void changeStateOfVisibleNonStandardVolumesRecursively(VolumeHandle*,VP1GeoFlags::VOLSTATE); - void changeStateOfAllVolumesRecursively(VolumeHandle*,VP1GeoFlags::VOLSTATE); - void expandVisibleVolumesRecursively(VolumeHandle*,const QRegExp&,bool bymatname); - bool filterVolumesRec(VolumeHandle* vol, QRegExp selregexp, bool bymatname, bool stopAtFirst, bool visitChildren, bool resetView, bool &zapAll, bool &matchFound, unsigned &nFound, int maxIter = 1, unsigned int iter = 0); - - SoSeparator* m_textSep;//!< Separator used to hold all visible labels. + QList<SubSystemInfo *> + subsysInfoList; // We need to keep and ordered version also (since + // wildcards in regexp might match more than one + // subsystem info). + void addSubSystem(const VP1GeoFlags::SubSystemFlag &, + const std::string &systemName, + const std::string &matname = ""); + + DetVisAttributes *detVisAttributes; + MatVisAttributes *matVisAttributes; + VolVisAttributes *volVisAttributes; + void ensureInitVisAttributes() { + if (!detVisAttributes) detVisAttributes = new DetVisAttributes(); + if (!matVisAttributes) matVisAttributes = new MatVisAttributes(); + if (!volVisAttributes) volVisAttributes = new VolVisAttributes(); + } - QMap<quint32,QByteArray> restoredTopvolstates; - void applyTopVolStates(const QMap<quint32,QByteArray>&, bool disablenotif = false); - SoSwitch *axesSwitch; - SoScale *axesScale; - SoTransform *axesTransform; + void buildSystem(SubSystemInfo *); + GeoSysController *controller; + PhiSectorManager *phisectormanager; + VolumeTreeModel *volumetreemodel; + + // Helpers used for printouts://FIXME: To VolumeHandle!! + static double exclusiveMass(const PVConstLink &pv); + static double inclusiveMass(const PVConstLink &pv); + static double volume(const PVConstLink &pv); + + // Basically for the zapping, and to ignore all clicks with ctrl/shift: + static void catchKbdState(void *userData, SoEventCallback *CB); + const SoKeyboardEvent *kbEvent; + + void changeStateOfVisibleNonStandardVolumesRecursively( + VolumeHandle *, VP1GeoFlags::VOLSTATE); + void changeStateOfAllVolumesRecursively(VolumeHandle *, + VP1GeoFlags::VOLSTATE); + void expandVisibleVolumesRecursively(VolumeHandle *, const QRegExp &, + bool bymatname); + bool filterVolumesRec(VolumeHandle *vol, QRegExp selregexp, bool bymatname, + bool stopAtFirst, bool visitChildren, bool resetView, + bool &zapAll, bool &matchFound, unsigned &nFound, + int maxIter = 1, unsigned int iter = 0); + + SoSeparator *m_textSep; //!< Separator used to hold all visible labels. + + QMap<quint32, QByteArray> restoredTopvolstates; + void applyTopVolStates(const QMap<quint32, QByteArray> &, + bool disablenotif = false); + SoSwitch *axesSwitch; + SoScale *axesScale; + SoTransform *axesTransform; }; //_____________________________________________________________________________________ -VP1GeometrySystem::VP1GeometrySystem(QString name ) - : IVP13DSystemSimple(name, - "This system displays the geometry as defined in the GeoModel tree.", - "Riccardo.Maria.Bianchi@cern.ch"), - m_d(new Imp(this)) -{ - -} - +VP1GeometrySystem::VP1GeometrySystem(QString name) + : IVP13DSystemSimple( + name, + "This system displays the geometry as defined in the GeoModel tree.", + "Riccardo.Maria.Bianchi@cern.ch"), + m_d(new Imp(this)) {} //_____________________________________________________________________________________ -void VP1GeometrySystem::systemuncreate() -{ - - m_d->volumetreemodel->cleanup(); - delete m_d->matVisAttributes; m_d->matVisAttributes = 0; - delete m_d->detVisAttributes; m_d->detVisAttributes = 0; - delete m_d->volVisAttributes; m_d->volVisAttributes = 0; - - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) - delete subsys; - m_d->subsysInfoList.clear(); - +void VP1GeometrySystem::systemuncreate() { + m_d->volumetreemodel->cleanup(); + delete m_d->matVisAttributes; + m_d->matVisAttributes = 0; + delete m_d->detVisAttributes; + m_d->detVisAttributes = 0; + delete m_d->volVisAttributes; + m_d->volVisAttributes = 0; + + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) delete subsys; + m_d->subsysInfoList.clear(); } //_____________________________________________________________________________________ -VP1GeometrySystem::~VP1GeometrySystem() -{ - delete m_d; - m_d = 0; +VP1GeometrySystem::~VP1GeometrySystem() { + delete m_d; + m_d = 0; } //_____________________________________________________________________________________ void VP1GeometrySystem::setGeometrySelectable(bool b) { - ensureBuildController(); - m_d->controller->setGeometrySelectable(b); + ensureBuildController(); + m_d->controller->setGeometrySelectable(b); } //_____________________________________________________________________________________ void VP1GeometrySystem::setZoomToVolumeOnClick(bool b) { - ensureBuildController(); - m_d->controller->setZoomToVolumeOnClick(b); + ensureBuildController(); + m_d->controller->setZoomToVolumeOnClick(b); } - //_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::addSubSystem(const VP1GeoFlags::SubSystemFlag& f, - const std::string & systemName, - const std::string& matname) -{ - QCheckBox * cb = controller->subSystemCheckBox(f); - if (!cb) { - theclass->message(("Error: Problems retrieving checkbox for subsystem "+f).c_str()); - return; - } - //int counter(0); // RMB: removed to stop the 'unused variable' warning - for (auto i=subsysInfoList.begin();i!=subsysInfoList.end();i++) { - if (systemName==(*i)->systemName) { - //std::cout << "Very severe warning. You create duplicate systems! " << std::endl; - //... er, just bail out. Subsystem exists, everything fine. - return; - } - } - - subsysInfoList << new SubSystemInfo(cb,systemName,f,matname); - //FIXME: DELETE!!! +void VP1GeometrySystem::Imp::addSubSystem(const VP1GeoFlags::SubSystemFlag &f, + const std::string &systemName, + const std::string &matname) { + QCheckBox *cb = controller->subSystemCheckBox(f); + if (!cb) { + theclass->message( + ("Error: Problems retrieving checkbox for subsystem " + f).c_str()); + return; + } + // int counter(0); // RMB: removed to stop the 'unused variable' warning + for (auto i = subsysInfoList.begin(); i != subsysInfoList.end(); i++) { + if (systemName == (*i)->systemName) { + // std::cout << "Very severe warning. You create duplicate systems! + // " << std::endl; + //... er, just bail out. Subsystem exists, everything fine. + return; + } + } + + subsysInfoList << new SubSystemInfo(cb, systemName, f, matname); + // FIXME: DELETE!!! } //_____________________________________________________________________________________ -QWidget * VP1GeometrySystem::buildController() -{ - message("VP1GeometrySystem::buildController"); - - m_d->controller = new GeoSysController(this); - - m_d->phisectormanager = new PhiSectorManager(m_d->controller->phiSectionWidget(),this,this); - - - connect(m_d->controller,SIGNAL(showVolumeOutLinesChanged(bool)),this,SLOT(setShowVolumeOutLines(bool))); - setShowVolumeOutLines(m_d->controller->showVolumeOutLines()); - connect(m_d->controller,SIGNAL(saveMaterialsToFile(QString,bool)),this,SLOT(saveMaterialsToFile(QString,bool))); - connect(m_d->controller,SIGNAL(loadMaterialsFromFile(QString)),this,SLOT(loadMaterialsFromFile(QString))); - - connect(m_d->controller,SIGNAL(transparencyChanged(float)),this,SLOT(updateTransparency())); - - connect (m_d->controller,SIGNAL(volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE)), this,SLOT(volumeStateChangeRequested(VolumeHandle*,VP1GeoFlags::VOLSTATE))); - connect (m_d->controller,SIGNAL(volumeResetRequested(VolumeHandle*)), this,SLOT(volumeResetRequested(VolumeHandle*))); - - - connect(m_d->controller,SIGNAL(actionOnAllNonStandardVolumes(bool)),this,SLOT(actionOnAllNonStandardVolumes(bool))); - connect(m_d->controller,SIGNAL(autoExpandByVolumeOrMaterialName(bool,QString)),this,SLOT(autoExpandByVolumeOrMaterialName(bool,QString))); - connect(m_d->controller,SIGNAL(signalFilterVolumes(QString, bool, int, bool, bool, bool)),this,SLOT(filterVolumes(QString, bool, int, bool, bool, bool))); - - connect(m_d->controller->requestOutputButton(), SIGNAL(clicked()), this, SLOT(saveTrees())); - connect(m_d->controller,SIGNAL(displayLocalAxesChanged(int)), this, SLOT(toggleLocalAxes(int))); - connect(m_d->controller,SIGNAL(axesScaleChanged(int)), this, SLOT(setAxesScale(int))); - - //Setup models/views for volume tree browser and zapped volumes list: - m_d->volumetreemodel = new VolumeTreeModel(m_d->controller->volumeTreeBrowser()); - m_d->controller->volumeTreeBrowser()->header()->hide(); - m_d->controller->volumeTreeBrowser()->uniformRowHeights(); - m_d->controller->volumeTreeBrowser()->setModel(m_d->volumetreemodel); - - return m_d->controller; +QWidget *VP1GeometrySystem::buildController() { + message("VP1GeometrySystem::buildController"); + + m_d->controller = new GeoSysController(this); + + m_d->phisectormanager = + new PhiSectorManager(m_d->controller->phiSectionWidget(), this, this); + + connect(m_d->controller, SIGNAL(showVolumeOutLinesChanged(bool)), this, + SLOT(setShowVolumeOutLines(bool))); + setShowVolumeOutLines(m_d->controller->showVolumeOutLines()); + connect(m_d->controller, SIGNAL(saveMaterialsToFile(QString, bool)), this, + SLOT(saveMaterialsToFile(QString, bool))); + connect(m_d->controller, SIGNAL(loadMaterialsFromFile(QString)), this, + SLOT(loadMaterialsFromFile(QString))); + + connect(m_d->controller, SIGNAL(transparencyChanged(float)), this, + SLOT(updateTransparency())); + + connect(m_d->controller, + SIGNAL(volumeStateChangeRequested(VolumeHandle *, + VP1GeoFlags::VOLSTATE)), + this, + SLOT(volumeStateChangeRequested(VolumeHandle *, + VP1GeoFlags::VOLSTATE))); + connect(m_d->controller, SIGNAL(volumeResetRequested(VolumeHandle *)), this, + SLOT(volumeResetRequested(VolumeHandle *))); + + connect(m_d->controller, SIGNAL(actionOnAllNonStandardVolumes(bool)), this, + SLOT(actionOnAllNonStandardVolumes(bool))); + connect(m_d->controller, + SIGNAL(autoExpandByVolumeOrMaterialName(bool, QString)), this, + SLOT(autoExpandByVolumeOrMaterialName(bool, QString))); + connect(m_d->controller, + SIGNAL(signalFilterVolumes(QString, bool, int, bool, bool, bool)), + this, SLOT(filterVolumes(QString, bool, int, bool, bool, bool))); + + connect(m_d->controller->requestOutputButton(), SIGNAL(clicked()), this, + SLOT(saveTrees())); + connect(m_d->controller, SIGNAL(displayLocalAxesChanged(int)), this, + SLOT(toggleLocalAxes(int))); + connect(m_d->controller, SIGNAL(axesScaleChanged(int)), this, + SLOT(setAxesScale(int))); + + // Setup models/views for volume tree browser and zapped volumes list: + m_d->volumetreemodel = + new VolumeTreeModel(m_d->controller->volumeTreeBrowser()); + m_d->controller->volumeTreeBrowser()->header()->hide(); + m_d->controller->volumeTreeBrowser()->uniformRowHeights(); + m_d->controller->volumeTreeBrowser()->setModel(m_d->volumetreemodel); + + return m_d->controller; } - //_____________________________________________________________________________________ -void VP1GeometrySystem::systemcreate(StoreGateSvc*) -{ - m_d->ensureInitVisAttributes(); +void VP1GeometrySystem::systemcreate(StoreGateSvc *) { + m_d->ensureInitVisAttributes(); } //_____________________________________________________________________________________ void VP1GeometrySystem::Imp::catchKbdState(void *address, SoEventCallback *CB) { - VP1GeometrySystem::Imp *This=static_cast<VP1GeometrySystem::Imp*>(address); - if (This) - This->kbEvent = static_cast<const SoKeyboardEvent *>(CB->getEvent()); + VP1GeometrySystem::Imp *This = + static_cast<VP1GeometrySystem::Imp *>(address); + if (This) + This->kbEvent = static_cast<const SoKeyboardEvent *>(CB->getEvent()); } //_____________________________________________________________________________________ -void VP1GeometrySystem::buildPermanentSceneGraph(StoreGateSvc*/*detstore*/, SoSeparator *root) -{ - m_d->sceneroot = root; - +void VP1GeometrySystem::buildPermanentSceneGraph(StoreGateSvc * /*detstore*/, + SoSeparator *root) { + m_d->sceneroot = root; + + PVConstLink world(m_d->getGeometry()); + if (!world) return; + + if (!m_d->m_textSep) { + // FIXME! + // std::cout<<"Making new Text sep"<<std::endl; + m_d->m_textSep = new SoSeparator; + m_d->m_textSep->setName("TextSep"); + m_d->m_textSep->ref(); + } + m_d->sceneroot->addChild(m_d->m_textSep); - PVConstLink world(m_d->getGeometry()); - if (!world) return; + // FIXME - what if font is missing? + SoFont *myFont = new SoFont; + myFont->name.setValue("Arial"); + myFont->size.setValue(12.0); + m_d->m_textSep->addChild(myFont); - if (!m_d->m_textSep) { - // FIXME! - // std::cout<<"Making new Text sep"<<std::endl; - m_d->m_textSep = new SoSeparator; - m_d->m_textSep->setName("TextSep"); - m_d->m_textSep->ref(); - } - m_d->sceneroot->addChild(m_d->m_textSep); + bool save = root->enableNotify(false); - // FIXME - what if font is missing? - SoFont *myFont = new SoFont; - myFont->name.setValue("Arial"); - myFont->size.setValue(12.0); - m_d->m_textSep->addChild(myFont); + // Catch keyboard events: + SoEventCallback *catchEvents = new SoEventCallback(); + catchEvents->addEventCallback(SoKeyboardEvent::getClassTypeId(), + Imp::catchKbdState, m_d); + root->addChild(catchEvents); - bool save = root->enableNotify(false); + root->addChild(m_d->controller->drawOptions()); + root->addChild(m_d->controller->pickStyle()); - //Catch keyboard events: - SoEventCallback *catchEvents = new SoEventCallback(); - catchEvents->addEventCallback(SoKeyboardEvent::getClassTypeId(),Imp::catchKbdState, m_d); - root->addChild(catchEvents); + { + GeoVolumeCursor av(world); + while (!av.atEnd()) { + m_d->addSubSystem(av.getName(), av.getName().c_str()); + av.next(); + } + } - root->addChild(m_d->controller->drawOptions()); - root->addChild(m_d->controller->pickStyle()); + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + connect(subsys->checkbox, SIGNAL(toggled(bool)), this, + SLOT(checkboxChanged())); + } - { + if (VP1Msg::debug()) { + qDebug() << "Looping on volumes from the input GeoModel..."; + } GeoVolumeCursor av(world); while (!av.atEnd()) { - m_d->addSubSystem(av.getName(), av.getName().c_str()); - av.next(); - } - } - - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - connect(subsys->checkbox,SIGNAL(toggled(bool)),this,SLOT(checkboxChanged())); - } - - - if(VP1Msg::debug()){ - qDebug() << "Looping on volumes from the input GeoModel..."; - } - GeoVolumeCursor av(world); - while (!av.atEnd()) { - - std::string name = av.getName(); - - //Let us see if we recognize this volume: - bool found = false; - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - if (subsys->systemName==name){ - { - - found = true; - //We did... now, time to extract info: - subsys->treetopinfo.resize(subsys->treetopinfo.size()+1); - subsys->treetopinfo.back().pV = av.getVolume(); - subsys->treetopinfo.back().xf = av.getTransform(); - subsys->treetopinfo.back().volname = av.getName(); - - //Add a switch for this system (turned off for now): - SoSwitch * sw = new SoSwitch(); - //But add a separator on top of it (for caching): - subsys->soswitch = sw; - if (sw->whichChild.getValue() != SO_SWITCH_NONE) - sw->whichChild = SO_SWITCH_NONE; - SoSeparator * sep = new SoSeparator; - sep->addChild(sw); - root->addChild(sep); - //Enable the corresponding checkbox: - subsys->checkbox->setEnabled(true); - subsys->checkbox->setToolTip("Toggle the display of the "+subsys->checkbox->text()+" sub system"); - } - } - } - av.next(); // increment volume cursor. - } - //Build the geometry for those (available) subsystems that starts out being turned on: - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - if (!subsys->soswitch||!subsys->checkbox->isChecked()) - continue; - m_d->buildSystem(subsys); - //Enable in 3D view: - if (subsys->soswitch->whichChild.getValue() != SO_SWITCH_ALL) - subsys->soswitch->whichChild = SO_SWITCH_ALL; - //Enable in tree browser: - m_d->volumetreemodel->enableSubSystem(subsys->flag); - } - if (!m_d->restoredTopvolstates.isEmpty()) { - m_d->applyTopVolStates(m_d->restoredTopvolstates,false); - m_d->restoredTopvolstates.clear(); - } - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - - - // Build some axes for the display of the local coordinate system. - { - m_d->axesSwitch = new SoSwitch(); - SoSeparator *axesSeparator = new SoSeparator; - m_d->axesScale = new SoScale; - m_d->axesTransform = new SoTransform; - m_d->axesSwitch->whichChild=SO_SWITCH_NONE ; - - SoLightModel *lModel=new SoLightModel; - lModel->model=SoLightModel::BASE_COLOR; - SoDrawStyle *drawStyle=new SoDrawStyle; - drawStyle->style=SoDrawStyle::LINES; - drawStyle->lineWidth=5; - axesSeparator->addChild(lModel); - axesSeparator->addChild(drawStyle); - axesSeparator->addChild(m_d->axesTransform); - axesSeparator->addChild(m_d->axesScale); - axesSeparator->addChild(m_d->axesSwitch); - - - std::string label[]={"X", "Y", "Z"}; - - for (int i=0;i<3;i++) { - SoSeparator *sep = new SoSeparator; - SoCoordinate3 *coord = new SoCoordinate3; - SoLineSet *lineSet=new SoLineSet; - SoMaterial *material=new SoMaterial; - coord->point.set1Value(0,SbVec3f(0,0,0)); - coord->point.set1Value(1,SbVec3f((i==0 ? 1500:0), (i==1? 1500: 0), (i==2 ? 1500: 0))); - material->diffuseColor.setValue((i==0 ? 1:0), (i==1? 1:0), (i==2 ? 1:0)); - m_d->axesSwitch->addChild(sep); - sep->addChild(material); - sep->addChild(coord); - sep->addChild(lineSet); - SoTranslation *translation = new SoTranslation; - translation->translation.setValue((i==0 ? 1520:0), (i==1? 1520: 0), (i==2 ? 1520: 0)); - SoFont *font= new SoFont; - font->size=32; - - SoText2 *text = new SoText2; - text->string=label[i].c_str(); - sep->addChild(translation); - sep->addChild(font); - sep->addChild(text); - } - m_d->sceneroot->addChild(axesSeparator); - } - - root->enableNotify(save); - if (save) - root->touch(); + std::string name = av.getName(); + + // Let us see if we recognize this volume: + bool found = false; + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + if (subsys->systemName == name) { + { + found = true; + // We did... now, time to extract info: + subsys->treetopinfo.resize(subsys->treetopinfo.size() + 1); + subsys->treetopinfo.back().pV = av.getVolume(); + subsys->treetopinfo.back().xf = av.getTransform(); + subsys->treetopinfo.back().volname = av.getName(); + + // Add a switch for this system (turned off for now): + SoSwitch *sw = new SoSwitch(); + // But add a separator on top of it (for caching): + subsys->soswitch = sw; + if (sw->whichChild.getValue() != SO_SWITCH_NONE) + sw->whichChild = SO_SWITCH_NONE; + SoSeparator *sep = new SoSeparator; + sep->addChild(sw); + root->addChild(sep); + // Enable the corresponding checkbox: + subsys->checkbox->setEnabled(true); + subsys->checkbox->setToolTip("Toggle the display of the " + + subsys->checkbox->text() + + " sub system"); + } + } + } + av.next(); // increment volume cursor. + } + // Build the geometry for those (available) subsystems that starts out being + // turned on: + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + if (!subsys->soswitch || !subsys->checkbox->isChecked()) continue; + m_d->buildSystem(subsys); + // Enable in 3D view: + if (subsys->soswitch->whichChild.getValue() != SO_SWITCH_ALL) + subsys->soswitch->whichChild = SO_SWITCH_ALL; + // Enable in tree browser: + m_d->volumetreemodel->enableSubSystem(subsys->flag); + } + if (!m_d->restoredTopvolstates.isEmpty()) { + m_d->applyTopVolStates(m_d->restoredTopvolstates, false); + m_d->restoredTopvolstates.clear(); + } + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + // Build some axes for the display of the local coordinate system. + { + m_d->axesSwitch = new SoSwitch(); + SoSeparator *axesSeparator = new SoSeparator; + m_d->axesScale = new SoScale; + m_d->axesTransform = new SoTransform; + m_d->axesSwitch->whichChild = SO_SWITCH_NONE; + + SoLightModel *lModel = new SoLightModel; + lModel->model = SoLightModel::BASE_COLOR; + SoDrawStyle *drawStyle = new SoDrawStyle; + drawStyle->style = SoDrawStyle::LINES; + drawStyle->lineWidth = 5; + axesSeparator->addChild(lModel); + axesSeparator->addChild(drawStyle); + axesSeparator->addChild(m_d->axesTransform); + axesSeparator->addChild(m_d->axesScale); + axesSeparator->addChild(m_d->axesSwitch); + + std::string label[] = {"X", "Y", "Z"}; + + for (int i = 0; i < 3; i++) { + SoSeparator *sep = new SoSeparator; + SoCoordinate3 *coord = new SoCoordinate3; + SoLineSet *lineSet = new SoLineSet; + SoMaterial *material = new SoMaterial; + coord->point.set1Value(0, SbVec3f(0, 0, 0)); + coord->point.set1Value( + 1, SbVec3f((i == 0 ? 1500 : 0), (i == 1 ? 1500 : 0), + (i == 2 ? 1500 : 0))); + material->diffuseColor.setValue((i == 0 ? 1 : 0), (i == 1 ? 1 : 0), + (i == 2 ? 1 : 0)); + m_d->axesSwitch->addChild(sep); + sep->addChild(material); + sep->addChild(coord); + sep->addChild(lineSet); + SoTranslation *translation = new SoTranslation; + translation->translation.setValue( + (i == 0 ? 1520 : 0), (i == 1 ? 1520 : 0), (i == 2 ? 1520 : 0)); + SoFont *font = new SoFont; + font->size = 32; + + SoText2 *text = new SoText2; + text->string = label[i].c_str(); + sep->addChild(translation); + sep->addChild(font); + sep->addChild(text); + } + m_d->sceneroot->addChild(axesSeparator); + } + root->enableNotify(save); + if (save) root->touch(); } //_____________________________________________________________________________________ -GeoPhysVol* VP1GeometrySystem::Imp::getGeometry() -{ - return getGeometryFromLocalDB(); // for production +GeoVPhysVol *VP1GeometrySystem::Imp::getGeometry() { + return getGeometryFromLocalDB(); // for production } //_____________________________________________________________________________________ -GeoPhysVol* VP1GeometrySystem::Imp::createTheWorld(GeoPhysVol* world) -{ - if (world == nullptr) - { - // Setup the 'World' volume from which everything else will be suspended - double densityOfAir=0.1; - const GeoMaterial* worldMat = new GeoMaterial("std::Air", densityOfAir); - const GeoBox* worldBox = new GeoBox(2000*SYSTEM_OF_UNITS::cm, 2000*SYSTEM_OF_UNITS::cm, 2500*SYSTEM_OF_UNITS::cm); - const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, worldMat); - world = new GeoPhysVol(worldLog); - } - return world; +GeoVPhysVol *VP1GeometrySystem::Imp::createTheWorld(GeoVPhysVol *world) { + if (world == nullptr) { + // Setup the 'World' volume from which everything else will be suspended + double densityOfAir = 0.1; + const GeoMaterial *worldMat = new GeoMaterial("std::Air", densityOfAir); + const GeoBox *worldBox = + new GeoBox(2000 * SYSTEM_OF_UNITS::cm, 2000 * SYSTEM_OF_UNITS::cm, + 2500 * SYSTEM_OF_UNITS::cm); + const GeoLogVol *worldLog = + new GeoLogVol("WorldLog", worldBox, worldMat); + world = new GeoPhysVol(worldLog); + } + return world; } - QString VP1GeometrySystem::Imp::selectGeometryFile() { - std::cout << "selectGeometryFile()" << std::endl; - QString path; - char buffer[1024]; - char *wd=getcwd(buffer,1024); - path = QFileDialog::getOpenFileName(nullptr, tr("Open Geometry File"), - wd, - tr("Geometry files (*.db *.so* *.dylib)"),0,QFileDialog::DontUseNativeDialog); - return path; + std::cout << "selectGeometryFile()" << std::endl; + QString path; + char buffer[1024]; + char *wd = getcwd(buffer, 1024); + path = + QFileDialog::getOpenFileName(nullptr, tr("Open Geometry File"), wd, + tr("Geometry files (*.db *.so* *.dylib)"), + 0, QFileDialog::DontUseNativeDialog); + return path; } //_____________________________________________________________________________________ -GeoPhysVol* VP1GeometrySystem::Imp::getGeometryFromLocalDB() -{ - - QString path; - std::cout << "m_existingGeoInput: " << m_existingGeoInput.toStdString() << std::endl; - if (m_existingGeoInput.size() > 0 ) { - path = m_existingGeoInput; - } else { +GeoVPhysVol *VP1GeometrySystem::Imp::getGeometryFromLocalDB() { + QString path; + std::cout << "m_existingGeoInput: " << m_existingGeoInput.toStdString() + << std::endl; + if (m_existingGeoInput.size() > 0) { + path = m_existingGeoInput; + } else { + char *pEnv = getenv("GX_GEOMETRY_FILE0"); + if (pEnv) { + path = pEnv; + unsetenv("GX_GEOMETRY_FILE0"); + } else { + path = selectGeometryFile(); + } - char *pEnv=getenv("GX_GEOMETRY_FILE0"); - if (pEnv) { - path=pEnv; - unsetenv("GX_GEOMETRY_FILE0"); + m_existingGeoInput = path; } - else { - path=selectGeometryFile(); + + if (path == "") return nullptr; + + GeoVPhysVol *world = + getenv("GX_GEOMETRY_FILE1") ? createTheWorld(nullptr) : nullptr; + + int g = 0; + while (path != "") { + // check if DB file exists. If not, return + if (!QFileInfo(path).exists()) { + QMessageBox::warning( + 0, "Error!", "Warning, geometry input does not exist. Exiting.", + QMessageBox::Ok, QMessageBox::Ok); + exit(0); + } + if (path.contains(".db")) { + // open the DB + GMDBManager *db = new GMDBManager(path.toStdString()); + if (!db->checkIsDBOpen()) + throw std::runtime_error("Error, database is not open "); + + /* set the GeoModel reader */ + GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); + + /* build the GeoModel geometry */ + GeoVPhysVol *dbPhys = + readInGeo.buildGeoModel(); // builds the whole GeoModel tree in + // memory + + if (world) { + // world->add(dbPhys); + GeoVolumeCursor aV(dbPhys); + + while (!aV.atEnd()) { + GeoNameTag *nameTag = new GeoNameTag(aV.getName()); + GeoTransform *transform = + new GeoTransform(aV.getTransform()); + world->add(nameTag); + world->add(transform); + world->add((GeoVPhysVol *)&*aV.getVolume()); + aV.next(); + } + + } else { + world = createTheWorld(dbPhys); + } + + } else if (path.contains(".dylib") || path.contains(".so")) { + std::cout << "path=" << path.toStdString() << std::endl; + GeoGeometryPluginLoader loader; + GeoVGeometryPlugin *factory = loader.load(path.toStdString()); + if (!factory) { + QMessageBox::warning( + 0, "Error!", + "The factory could not be created (hint: probably the " + "plugin is missing. Check that). Cannot load geometry from " + "factory. Exiting.", + QMessageBox::Ok, QMessageBox::Ok); + exit(0); + } + + if (!world) world = createTheWorld(nullptr); + + // TODO: check this with simple and more complex plugins! Also, get + // lists of FPV and AXF and show them or highlight them in the + // viewer somehow... + + factory->create(world); + // factory->create(world, true); // if we want to get lists of nodes + // published by plugins, if any + } + + g++; + char *pEnv = getenv( + (std::string("GX_GEOMETRY_FILE") + std::to_string(g)).c_str()); + if (pEnv) { + path = pEnv; + unsetenv( + (std::string("GX_GEOMETRY_FILE") + std::to_string(g)).c_str()); + } else { + path = ""; + } } - m_existingGeoInput = path; - } + return world; +} +//_____________________________________________________________________________________ +void VP1GeometrySystem::toggleLocalAxes(int i) { + if (i == 0) + m_d->axesSwitch->whichChild = SO_SWITCH_NONE; + else + m_d->axesSwitch->whichChild = SO_SWITCH_ALL; +} +//_____________________________________________________________________________________ +void VP1GeometrySystem::setAxesScale(int i) { + double x = (i - 50) / 25.0; + double scale = pow(10, x); + m_d->axesScale->scaleFactor.setValue(scale, scale, scale); +} - if (path=="") return nullptr; +//_____________________________________________________________________________________ +void VP1GeometrySystem::checkboxChanged() { + QCheckBox *cb = static_cast<QCheckBox *>(sender()); + Imp::SubSystemInfo *subsys(0); + foreach (Imp::SubSystemInfo *ss, m_d->subsysInfoList) { + if (cb == ss->checkbox) { + subsys = ss; + break; + } + } + if (!subsys) { + message("ERROR: Unknown checkbox"); + return; + } + SoSwitch *sw = subsys->soswitch; + assert(sw); + if (cb->isChecked()) { + SbBool save = sw->enableNotify(false); + if (sw->getNumChildren() == 0) { + m_d->buildSystem(subsys); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); // + } + if (sw->whichChild.getValue() != SO_SWITCH_ALL) + sw->whichChild = SO_SWITCH_ALL; + sw->enableNotify(save); + // Enable in tree browser: + m_d->volumetreemodel->enableSubSystem(subsys->flag); + if (save) sw->touch(); + } else { + if (sw->whichChild.getValue() != SO_SWITCH_NONE) + sw->whichChild = SO_SWITCH_NONE; + m_d->volumetreemodel->disableSubSystem(subsys->flag); + } +} - GeoPhysVol *world=getenv("GX_GEOMETRY_FILE1") ? createTheWorld(nullptr) : nullptr; +// NOTE: before arriving here, events are intercepted by +// VP1Base/SoCooperativeSelection and VP1Gui/GXExecutionScheduler, in this +// order. +//_____________________________________________________________________________________ +void VP1GeometrySystem::userPickedNode(SoNode *, SoPath *pickedPath) { + ////////////////////////////////////////////////////////////////////////// + // We want to find the volumehandle for the volume. To do so, we look // + // for the SoSeparator identifying the actual picked shape node, and // + // use it to look up the handle: // + ////////////////////////////////////////////////////////////////////////// + + // Looking for the identifying "nodesep", there are three scenarios + // for the type signatures of the final part of the path: + // + // 1) Most shapes: + // nodesep -> pickedNode (but we must pop to a group node in case of + // SoCylinders) + // + // 2) Volumes Around Z (all phi sectors enabled): + // nodesep -> switch -> pickedNode + // + // 3) Volumes Around Z (only some phi sectors enabled): + // nodesep -> switch -> sep -> pickedNode + // + // In the third scenario we also have to pop the path, in order for + // all phi-slices of the part gets highlighted (since more than one + // soshape node represents the volume). + + VP1Msg::messageDebug("VP1GeometrySystem::userPickedNode()"); + + if (pickedPath->getNodeFromTail(0)->getTypeId() == + SoCylinder::getClassTypeId()) + pickedPath->pop(); + + if (pickedPath->getLength() < 5) { + message("Path too short"); + return; + } - int g=0; - while (path!="") { - // check if DB file exists. If not, return - if (! QFileInfo(path).exists() ) { - QMessageBox::warning(0, "Error!","Warning, geometry input does not exist. Exiting.",QMessageBox::Ok,QMessageBox::Ok); - exit(0); + SoSeparator *nodesep(0); + + if (pickedPath->getNodeFromTail(1)->getTypeId() == + SoSeparator::getClassTypeId() && + pickedPath->getNodeFromTail(2)->getTypeId() == + SoSwitch::getClassTypeId() && + pickedPath->getNodeFromTail(3)->getTypeId() == + SoSeparator::getClassTypeId()) { + // Scenario 3: + nodesep = static_cast<SoSeparator *>(pickedPath->getNodeFromTail(3)); + pickedPath->pop(); // To get highlighting of siblings also. + } else if (pickedPath->getNodeFromTail(1)->getTypeId() == + SoSwitch::getClassTypeId() && + pickedPath->getNodeFromTail(2)->getTypeId() == + SoSeparator::getClassTypeId()) { + // Scenario 2: + nodesep = static_cast<SoSeparator *>(pickedPath->getNodeFromTail(2)); + } else if (pickedPath->getNodeFromTail(1)->getTypeId() == + SoSeparator::getClassTypeId()) { + // Scenario 1 (normal): + nodesep = static_cast<SoSeparator *>(pickedPath->getNodeFromTail(1)); + } + if (!nodesep) { + message("Unexpected picked path"); + return; + } + if ((!(nodesep)) || (m_d->sonodesep2volhandle.find(nodesep) == + m_d->sonodesep2volhandle.end())) { + message("Problems finding volume handle"); + return; + } + VolumeHandle *volhandle = m_d->sonodesep2volhandle[nodesep]; + if (!volhandle) { + message("Found NULL volume handle"); + return; } - if (path.contains(".db")) { - // open the DB - GMDBManager* db = new GMDBManager(path.toStdString()); - if (!db->checkIsDBOpen()) throw std::runtime_error ("Error, database is not open "); - /* set the GeoModel reader */ - GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); + ///////////////////////////////////////////////////////////////////////// + // Next thing to do is to check whether volume was clicked on with a // + // modifier of SHIFT/CTRL/Z. If so, we have to change the state on // + // the volume handle. Otherwise, we need to print some information: // + ///////////////////////////////////////////////////////////////////////// + + // For focus reason, and since Qt doesn't allow standard keys such as + //'z' as modifiers, we check for keypress states using a combination + // of the inventor and Qt way + + bool shift_isdown = (Qt::ShiftModifier & QApplication::keyboardModifiers()); + // || ( m_d->kbEvent && (SO_KEY_PRESS_EVENT(m_d->kbEvent, + // SoKeyboardEvent::LEFT_SHIFT)|| + // SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::RIGHT_SHIFT)) ) ); + + if (shift_isdown) { + // Parent of volume should be put in CONTRACTED state. + deselectAll(); + + VolumeHandle *parent = volhandle->parent(); + if (parent) parent->setState(VP1GeoFlags::CONTRACTED); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + return; + } - /* build the GeoModel geometry */ - GeoPhysVol* dbPhys = readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory + bool ctrl_isdown = + (Qt::ControlModifier & QApplication::keyboardModifiers()); + // || ( m_d->kbEvent && (SO_KEY_PRESS_EVENT(m_d->kbEvent, + // SoKeyboardEvent::LEFT_CONTROL)|| + // SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::RIGHT_CONTROL)) ) ); + + if (ctrl_isdown) { + // Volume should be put in EXPANDED state if it has children. + deselectAll(); + if (volhandle->nChildren() > 0) { + volhandle->setState(VP1GeoFlags::EXPANDED); + } + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + return; + } - if (world) { + bool z_isdown = + m_d->kbEvent && SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::Z); + if (z_isdown) { + // Volume should be put in ZAPPED state. + deselectAll(); + volhandle->setState(VP1GeoFlags::ZAPPED); + message("===> Zapping Node: " + volhandle->getName()); + return; + } - //world->add(dbPhys); - GeoVolumeCursor aV(dbPhys); + bool s_isdown = + m_d->kbEvent && SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::S); + if (s_isdown) { + deselectAll(); +#ifdef __APPLE__ + char buffer[1024]; + char *wd = getcwd(buffer, 1024); - while (!aV.atEnd()) { - GeoNameTag *nameTag=new GeoNameTag(aV.getName()); - GeoTransform *transform= new GeoTransform(aV.getTransform()); - world->add(nameTag); - world->add(transform); - world->add((GeoVPhysVol *) &*aV.getVolume()); - aV.next(); - } + QString path = QFileDialog::getSaveFileName( + nullptr, tr("Save Geometry File"), wd, tr("Geometry files (*.db)"), + 0, QFileDialog::DontUseNativeDialog); +#else + QString path = QFileDialog::getSaveFileName( + nullptr, tr("Save Geometry File"), get_current_dir_name(), + tr("Geometry files (*.db)"), 0, QFileDialog::DontUseNativeDialog); +#endif + if (path.isEmpty()) return; + + GMDBManager db(path.toStdString()); + + // check the DB connection + if (db.checkIsDBOpen()) { + std::cout << "OK! Database is created: " << path.toStdString() + << std::endl; + } else { + std::cout << "ERROR! Database could not be created! Returning..." + << std::endl; + return; + } - } - else { - world = createTheWorld(dbPhys); - } + GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); + PVConstLink pV = volhandle->geoPVConstLink(); + SbMatrix sbMtx = volhandle->getGlobalTransformToVolume(); + GeoTrf::Transform3D::MatrixType mtx; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + mtx(j, i) = sbMtx[i][j]; + } + } + GeoTrf::Transform3D tx; + tx.matrix() = mtx; + GeoTransform *xf = new GeoTransform(tx); + GeoPhysVol *world = newWorld(); + GeoNameTag *nameTag = + new GeoNameTag(volhandle->getName().toStdString()); + world->add(nameTag); + world->add(xf); + GeoPhysVol *pVMutable = (GeoPhysVol *)&*pV; + world->add(pVMutable); + world->exec(&dumpGeoModelGraph); + dumpGeoModelGraph.saveToDB(); + world->unref(); + return; + } + ////////////////////////////////////////////////////////////////// + // Depending on settings, we are to realign the camera if the // + // clicked volume is (daughter of) a muon chamber // + ////////////////////////////////////////////////////////////////// + + bool orientedView(false); + + ////////////////////// + // Zoom to volume // + ////////////////////// + + if (!orientedView && m_d->controller->zoomToVolumeOnClick()) { + if (m_d->sceneroot && volhandle->nodeSoSeparator()) { + std::set<SoCamera *> cameras = getCameraList(); + std::set<SoCamera *>::iterator it, itE = cameras.end(); + for (it = cameras.begin(); it != itE; ++it) { + VP1CameraHelper::animatedZoomToSubTree( + *it, m_d->sceneroot, volhandle->nodeSoSeparator(), 2.0, + 1.0); + } + } + } + if (m_d->controller->displayLocalAxesOnClick()) { + SbMatrix mtx = volhandle->getGlobalTransformToVolume(); + m_d->axesSwitch->whichChild = SO_SWITCH_ALL; + m_d->axesTransform->setMatrix(mtx); } - else if (path.contains(".dylib") || path.contains(".so")) { - std::cout << "path=" << path.toStdString() << std::endl; - GeoGeometryPluginLoader loader; - GeoVGeometryPlugin *factory=loader.load(path.toStdString()); - if (!factory) { - QMessageBox::warning(0, "Error!","The factory could not be created (hint: probably the plugin is missing. Check that). Cannot load geometry from factory. Exiting.",QMessageBox::Ok,QMessageBox::Ok); - exit(0); - } + /////////////////////////////////// + // Update last-select controls // + /////////////////////////////////// + + m_d->controller->setLastSelectedVolume(volhandle); - if (!world) world=createTheWorld(nullptr); - - // TODO: check this with simple and more complex plugins! Also, get lists of FPV and AXF and show them or highlight them in the viewer somehow... - - factory->create(world); - //factory->create(world, true); // if we want to get lists of nodes published by plugins, if any + ///////////////////////////////////////////////////////// + // OK, time to print some information for the volume // + ///////////////////////////////////////////////////////// + message("===> Selected Node: " + volhandle->getName()); + if (m_d->controller->printInfoOnClick_Shape()) { + foreach (QString str, + DumpShape::shapeToStringList( + volhandle->geoPVConstLink()->getLogVol()->getShape())) + message(str); } - g++; - char *pEnv=getenv((std::string("GX_GEOMETRY_FILE")+std::to_string(g)).c_str()); - if (pEnv) { - path=pEnv; - unsetenv((std::string("GX_GEOMETRY_FILE")+std::to_string(g)).c_str()); + if (m_d->controller->printInfoOnClick_Material()) { + const GeoMaterial *mat = volhandle->geoMaterial(); + message("===> Material:"); + QStringList out; + out << VP1GeomUtils::geoMaterialToStringList(mat); + message(" " + out.join(" ")); + unsigned int nEl = mat->getNumElements(); + if (nEl) { + for (unsigned int i = 0; i < nEl; ++i) { + QStringList out; + out << QString::number(i + 1) + ")" + << "fraction:" << QString::number(mat->getFraction(i)) + << "-"; + out << VP1GeomUtils::geoElementToStringList(mat->getElement(i)); + message(" " + out.join(" ")); + } + } else { + message(" (the material has no elements defined)"); + } } - else { - path=""; + + if (m_d->controller->printInfoOnClick_CopyNumber()) { + int cn = volhandle->copyNumber(); + message("===> CopyNo : " + + (cn >= 0 + ? QString::number(cn) + : QString(cn == -1 ? "Invalid" + : "Error reconstructing copynumber"))); } - } - return world; -} + if (m_d->controller->printInfoOnClick_Transform()) { + float translation_x, translation_y, translation_z, rotaxis_x, rotaxis_y, + rotaxis_z, rotangle_radians; + { + SbMatrix mtx = volhandle->getLocalTransformToVolume(); + SbVec3f t, s, axis; + SbRotation r, so; + float angle; + mtx.getTransform(t, r, s, + so); // translation, rotation, scaling, scale + // orientation -- in this order + translation_x = t[0]; + translation_y = t[1]; + translation_z = t[2]; + r.getValue(axis, angle); + rotaxis_x = axis[0]; + rotaxis_y = axis[1]; + rotaxis_z = axis[2]; + rotangle_radians = angle; + } + message("===> Local Translation:"); + message(" x = " + + QString::number(translation_x / SYSTEM_OF_UNITS::mm) + " mm"); + message(" y = " + + QString::number(translation_y / SYSTEM_OF_UNITS::mm) + " mm"); + message(" z = " + + QString::number(translation_z / SYSTEM_OF_UNITS::mm) + " mm"); + message("===> Local Rotation:"); + message(" axis x = " + QString::number(rotaxis_x)); + message(" axis y = " + QString::number(rotaxis_y)); + message(" axis z = " + QString::number(rotaxis_z)); + message(" angle = " + + QString::number(rotangle_radians * 180.0 / M_PI) + " deg"); + + { + SbMatrix mtx = volhandle->getGlobalTransformToVolume(); + SbVec3f t, s, axis; + SbRotation r, so; + float angle; + mtx.getTransform(t, r, s, so); + translation_x = t[0]; + translation_y = t[1]; + translation_z = t[2]; + r.getValue(axis, angle); + rotaxis_x = axis[0]; + rotaxis_y = axis[1]; + rotaxis_z = axis[2]; + rotangle_radians = angle; + } + message("===> Global Translation:"); + message(" x = " + + QString::number(translation_x / SYSTEM_OF_UNITS::mm) + " mm"); + message(" y = " + + QString::number(translation_y / SYSTEM_OF_UNITS::mm) + " mm"); + message(" z = " + + QString::number(translation_z / SYSTEM_OF_UNITS::mm) + " mm"); + message("===> Global Rotation:"); + message(" axis x = " + QString::number(rotaxis_x)); + message(" axis y = " + QString::number(rotaxis_y)); + message(" axis z = " + QString::number(rotaxis_z)); + message(" angle = " + + QString::number(rotangle_radians * 180.0 / M_PI) + " deg"); + } -//_____________________________________________________________________________________ -void VP1GeometrySystem::toggleLocalAxes(int i) { - if (i==0) m_d->axesSwitch->whichChild=SO_SWITCH_NONE; - else m_d->axesSwitch->whichChild=SO_SWITCH_ALL; + if (m_d->controller->printInfoOnClick_Tree()) { + std::ostringstream str; + GeoPrintGraphAction pg(str); + volhandle->geoPVConstLink()->exec(&pg); + message("===> Tree:"); + foreach (QString line, QString(str.str().c_str()).split("\n")) + message(" " + line); + } + + if (m_d->controller->printInfoOnClick_Mass()) { + // FIXME: Move the mass calculations to the volume handles, and let + // the common data cache some of the volume information by + // logVolume). + message("===> Total Mass <==="); + message( + "Inclusive " + + QString::number(Imp::inclusiveMass(volhandle->geoPVConstLink()) / + SYSTEM_OF_UNITS::kilogram) + + " kg"); + message( + "Exclusive " + + QString::number(Imp::exclusiveMass(volhandle->geoPVConstLink()) / + SYSTEM_OF_UNITS::kilogram) + + " kg"); + } } //_____________________________________________________________________________________ -void VP1GeometrySystem::setAxesScale(int i) { - double x=(i-50)/25.0; - double scale = pow(10,x); - m_d->axesScale->scaleFactor.setValue(scale,scale,scale); +SoTexture2 *VP1GeometrySystem::Imp::getDummyTexture() { + SoTexture2 *texture = new SoTexture2; + // texture->diffuseColor.setValue(0.40,0.60,0.40); + // texture->ambientColor.setValue(0.57,0.57,0.57); + // texture->specularColor.setValue(0.27,0.27,0.27); + // texture->shininess.setValue(.80); + return texture; } - //_____________________________________________________________________________________ -void VP1GeometrySystem::checkboxChanged() -{ - QCheckBox * cb = static_cast<QCheckBox*>(sender()); - Imp::SubSystemInfo * subsys(0); - foreach (Imp::SubSystemInfo * ss, m_d->subsysInfoList) { - if (cb==ss->checkbox) { - subsys=ss; - break; - } - } - if (!subsys) { - message("ERROR: Unknown checkbox"); - return; - } - SoSwitch * sw = subsys->soswitch; - assert(sw); - if (cb->isChecked()) { - SbBool save = sw->enableNotify(false); - if (sw->getNumChildren()==0) { - m_d->buildSystem(subsys); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis();// - } - if (sw->whichChild.getValue() != SO_SWITCH_ALL) - sw->whichChild = SO_SWITCH_ALL; - sw->enableNotify(save); - //Enable in tree browser: - m_d->volumetreemodel->enableSubSystem(subsys->flag); - if (save) - sw->touch(); - } else { - if (sw->whichChild.getValue() != SO_SWITCH_NONE) - sw->whichChild = SO_SWITCH_NONE; - m_d->volumetreemodel->disableSubSystem(subsys->flag); - } +SoMaterial *VP1GeometrySystem::Imp::getDummyMaterial() { + SoMaterial *material = new SoMaterial; + material->diffuseColor.setValue(0.40, 0.60, 0.40); + material->ambientColor.setValue(0.57, 0.57, 0.57); + material->specularColor.setValue(0.27, 0.27, 0.27); + material->shininess.setValue(.80); + return material; } -// NOTE: before arriving here, events are intercepted by VP1Base/SoCooperativeSelection -// and VP1Gui/GXExecutionScheduler, in this order. //_____________________________________________________________________________________ -void VP1GeometrySystem::userPickedNode(SoNode* , SoPath *pickedPath) -{ - - ////////////////////////////////////////////////////////////////////////// - // We want to find the volumehandle for the volume. To do so, we look // - // for the SoSeparator identifying the actual picked shape node, and // - // use it to look up the handle: // - ////////////////////////////////////////////////////////////////////////// - - //Looking for the identifying "nodesep", there are three scenarios - //for the type signatures of the final part of the path: - // - // 1) Most shapes: - // nodesep -> pickedNode (but we must pop to a group node in case of SoCylinders) - // - // 2) Volumes Around Z (all phi sectors enabled): - // nodesep -> switch -> pickedNode - // - // 3) Volumes Around Z (only some phi sectors enabled): - // nodesep -> switch -> sep -> pickedNode - // - // In the third scenario we also have to pop the path, in order for - // all phi-slices of the part gets highlighted (since more than one - // soshape node represents the volume). - - - VP1Msg::messageDebug("VP1GeometrySystem::userPickedNode()"); - - if (pickedPath->getNodeFromTail(0)->getTypeId()==SoCylinder::getClassTypeId()) - pickedPath->pop(); - - if (pickedPath->getLength()<5) { - message("Path too short"); - return; - } - - SoSeparator * nodesep(0); - - if (pickedPath->getNodeFromTail(1)->getTypeId()==SoSeparator::getClassTypeId() - && pickedPath->getNodeFromTail(2)->getTypeId()==SoSwitch::getClassTypeId() - && pickedPath->getNodeFromTail(3)->getTypeId()==SoSeparator::getClassTypeId()) - { - //Scenario 3: - nodesep = static_cast<SoSeparator*>(pickedPath->getNodeFromTail(3)); - pickedPath->pop();//To get highlighting of siblings also. - } - else if (pickedPath->getNodeFromTail(1)->getTypeId()==SoSwitch::getClassTypeId() - && pickedPath->getNodeFromTail(2)->getTypeId()==SoSeparator::getClassTypeId()) - { - //Scenario 2: - nodesep = static_cast<SoSeparator*>(pickedPath->getNodeFromTail(2)); - } - else if (pickedPath->getNodeFromTail(1)->getTypeId()==SoSeparator::getClassTypeId()) { - //Scenario 1 (normal): - nodesep = static_cast<SoSeparator*>(pickedPath->getNodeFromTail(1)); - } - if (!nodesep) { - message("Unexpected picked path"); - return; - } - if ( (!(nodesep)) || (m_d->sonodesep2volhandle.find(nodesep) == m_d->sonodesep2volhandle.end()) ) { - message("Problems finding volume handle"); - return; - } - VolumeHandle * volhandle = m_d->sonodesep2volhandle[nodesep]; - if (!volhandle) { - message("Found NULL volume handle"); - return; - } - - ///////////////////////////////////////////////////////////////////////// - // Next thing to do is to check whether volume was clicked on with a // - // modifier of SHIFT/CTRL/Z. If so, we have to change the state on // - // the volume handle. Otherwise, we need to print some information: // - ///////////////////////////////////////////////////////////////////////// - - //For focus reason, and since Qt doesn't allow standard keys such as - //'z' as modifiers, we check for keypress states using a combination - //of the inventor and Qt way - - bool shift_isdown = (Qt::ShiftModifier & QApplication::keyboardModifiers()); -// || ( m_d->kbEvent && (SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::LEFT_SHIFT)|| -// SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::RIGHT_SHIFT)) ) ); - - if (shift_isdown) { - //Parent of volume should be put in CONTRACTED state. - deselectAll(); - - VolumeHandle * parent=volhandle->parent(); - if (parent) parent->setState(VP1GeoFlags::CONTRACTED); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - return; - } - - bool ctrl_isdown = (Qt::ControlModifier & QApplication::keyboardModifiers()); -// || ( m_d->kbEvent && (SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::LEFT_CONTROL)|| -// SO_KEY_PRESS_EVENT(m_d->kbEvent, SoKeyboardEvent::RIGHT_CONTROL)) ) ); - - if (ctrl_isdown) { - //Volume should be put in EXPANDED state if it has children. - deselectAll(); - if (volhandle->nChildren()>0) { - volhandle->setState(VP1GeoFlags::EXPANDED); +void VP1GeometrySystem::Imp::buildSystem(SubSystemInfo *si) { + if (!si || si->isbuilt) { + return; } - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - return; - } + si->isbuilt = true; + int ichild(0); - bool z_isdown = m_d->kbEvent && SO_KEY_PRESS_EVENT(m_d->kbEvent,SoKeyboardEvent::Z); - if (z_isdown) { - //Volume should be put in ZAPPED state. - deselectAll(); - volhandle->setState(VP1GeoFlags::ZAPPED); - message("===> Zapping Node: "+volhandle->getName()); - return; - } - - bool s_isdown = m_d->kbEvent && SO_KEY_PRESS_EVENT(m_d->kbEvent,SoKeyboardEvent::S); - if (s_isdown) { - deselectAll(); -#ifdef __APPLE__ - char buffer[1024]; - char *wd=getcwd(buffer,1024); + ensureInitVisAttributes(); - QString path = QFileDialog::getSaveFileName(nullptr, tr("Save Geometry File"), - wd, - tr("Geometry files (*.db)"),0,QFileDialog::DontUseNativeDialog); -#else - QString path = QFileDialog::getSaveFileName(nullptr, tr("Save Geometry File"), - get_current_dir_name(), - tr("Geometry files (*.db)"),0,QFileDialog::DontUseNativeDialog); -#endif - if (path.isEmpty()) return; + assert(si->soswitch); + SoSeparator *subsystemsep = new SoSeparator; + phisectormanager->registerSubSystemSeparator(si->flag, subsystemsep); + phisectormanager->largeChangesBegin(); - GMDBManager db(path.toStdString()); + SbBool save = si->soswitch->enableNotify(false); - // check the DB connection - if (db.checkIsDBOpen()) { - std::cout << "OK! Database is created: " << path.toStdString() << std::endl; - } else { - std::cout << "ERROR! Database could not be created! Returning..." << std::endl; - return; + { + // Loop over the treetop's that we previously selected: + + std::vector<SubSystemInfo::TreetopInfo>::const_iterator it, + itE = si->treetopinfo.end(); + for (it = si->treetopinfo.begin(); it != itE; ++it) { + VP1Msg::messageDebug("-- toptree vol: " + + QString(it->volname.c_str())); + + // Get the material name from the top volume and search for it + // in the list of "default" materials for the sub-detectors: + QString topMaterialName = QString::fromStdString( + it->pV->getLogVol()->getMaterial()->getName()); + VP1Msg::messageDebug("topMaterial: " + topMaterialName); + SoMaterial *topMaterial = detVisAttributes->get(it->volname); + + // replace with special Dummy material if user uses this + if (topMaterialName == "Dummy") { + VP1Msg::messageWarning("the volume uses the 'Dummy' material!"); + topMaterial = getDummyMaterial(); + } + + VolumeHandleSharedData *volhandle_subsysdata = + new VolumeHandleSharedData( + controller, si->flag, &sonodesep2volhandle, it->pV, + phisectormanager, topMaterial, matVisAttributes, + volVisAttributes, controller->zappedVolumeListModel(), + controller->volumeTreeBrowser(), m_textSep); + const GeoTrf::Transform3D::MatrixType &mtx = it->xf.matrix(); + SbMatrix matr( + mtx(0, 0), mtx(1, 0), mtx(2, 0), + mtx(3, 0), // Beware, Eigen and SoQt have different conventions + mtx(0, 1), mtx(1, 1), mtx(2, 1), + mtx(3, 1), // For the matrix of homogenous transformations. + mtx(0, 2), mtx(1, 2), mtx(2, 2), mtx(3, 2), mtx(0, 3), + mtx(1, 3), mtx(2, 3), mtx(3, 3)); + + VolumeHandle *vh = new VolumeHandle(volhandle_subsysdata, 0, it->pV, + ichild++, matr); + si->vollist.push_back(vh); + } } - GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); - PVConstLink pV=volhandle->geoPVConstLink(); - SbMatrix sbMtx=volhandle->getGlobalTransformToVolume(); - GeoTrf::Transform3D::MatrixType mtx; - for (int i=0;i<4;i++) { - for (int j=0;j<4;j++) { - mtx(j,i)=sbMtx[i][j]; - } - } - GeoTrf::Transform3D tx; - tx.matrix()=mtx; - GeoTransform *xf=new GeoTransform(tx); - GeoPhysVol *world=newWorld(); - GeoNameTag *nameTag = new GeoNameTag(volhandle->getName().toStdString()); - world->add(nameTag); - world->add(xf); - GeoPhysVol *pVMutable=(GeoPhysVol *) &*pV; - world->add(pVMutable); - world->exec(&dumpGeoModelGraph); - dumpGeoModelGraph.saveToDB(); - world->unref(); - return; - - } - ////////////////////////////////////////////////////////////////// - // Depending on settings, we are to realign the camera if the // - // clicked volume is (daughter of) a muon chamber // - ////////////////////////////////////////////////////////////////// - - bool orientedView(false); - - ////////////////////// - // Zoom to volume // - ////////////////////// - - if (!orientedView&&m_d->controller->zoomToVolumeOnClick()) { - if (m_d->sceneroot&&volhandle->nodeSoSeparator()) { - std::set<SoCamera*> cameras = getCameraList(); - std::set<SoCamera*>::iterator it,itE = cameras.end(); - for (it=cameras.begin();it!=itE;++it) { - VP1CameraHelper::animatedZoomToSubTree(*it,m_d->sceneroot,volhandle->nodeSoSeparator(),2.0,1.0); - } - } - } - - - if (m_d->controller->displayLocalAxesOnClick()) { - SbMatrix mtx=volhandle->getGlobalTransformToVolume(); - m_d->axesSwitch->whichChild=SO_SWITCH_ALL; - m_d->axesTransform->setMatrix(mtx); - } - - - /////////////////////////////////// - // Update last-select controls // - /////////////////////////////////// - - m_d->controller->setLastSelectedVolume(volhandle); - - ///////////////////////////////////////////////////////// - // OK, time to print some information for the volume // - ///////////////////////////////////////////////////////// - - message("===> Selected Node: "+volhandle->getName()); - if (m_d->controller->printInfoOnClick_Shape()) { - foreach (QString str, DumpShape::shapeToStringList(volhandle->geoPVConstLink()->getLogVol()->getShape())) - message(str); - } - - if (m_d->controller->printInfoOnClick_Material()) { - const GeoMaterial* mat = volhandle->geoMaterial(); - message("===> Material:"); - QStringList out; - out << VP1GeomUtils::geoMaterialToStringList(mat); - message(" "+out.join(" ")); - unsigned int nEl = mat->getNumElements(); - if (nEl) { - for (unsigned int i=0; i<nEl; ++i) { - QStringList out; - out << QString::number(i+1)+")" - << "fraction:" << QString::number(mat->getFraction(i)) << "-"; - out << VP1GeomUtils::geoElementToStringList(mat->getElement(i)); - message(" " + out.join(" ")); - } - } else { - message(" (the material has no elements defined)"); - } - } - - if ( m_d->controller->printInfoOnClick_CopyNumber() ) { - int cn = volhandle->copyNumber(); - message("===> CopyNo : "+(cn>=0?QString::number(cn):QString(cn==-1?"Invalid":"Error reconstructing copynumber"))); - } - - if ( m_d->controller->printInfoOnClick_Transform() ) { - float translation_x, translation_y, translation_z, rotaxis_x, rotaxis_y, rotaxis_z, rotangle_radians; - { - SbMatrix mtx=volhandle->getLocalTransformToVolume(); - SbVec3f t,s,axis; - SbRotation r,so; - float angle; - mtx.getTransform(t,r,s,so); // translation, rotation, scaling, scale orientation -- in this order - translation_x=t[0]; - translation_y=t[1]; - translation_z=t[2]; - r.getValue(axis,angle); - rotaxis_x=axis[0]; - rotaxis_y=axis[1]; - rotaxis_z=axis[2]; - rotangle_radians=angle; - } - message("===> Local Translation:"); - message(" x = "+QString::number(translation_x/SYSTEM_OF_UNITS::mm)+" mm"); - message(" y = "+QString::number(translation_y/SYSTEM_OF_UNITS::mm)+" mm"); - message(" z = "+QString::number(translation_z/SYSTEM_OF_UNITS::mm)+" mm"); - message("===> Local Rotation:"); - message(" axis x = "+QString::number(rotaxis_x)); - message(" axis y = "+QString::number(rotaxis_y)); - message(" axis z = "+QString::number(rotaxis_z)); - message(" angle = "+QString::number(rotangle_radians*180.0/M_PI)+" deg"); + volumetreemodel->addSubSystem(si->flag, si->vollist); - { - SbMatrix mtx=volhandle->getGlobalTransformToVolume(); - SbVec3f t,s,axis; - SbRotation r,so; - float angle; - mtx.getTransform(t,r,s,so); - translation_x=t[0]; - translation_y=t[1]; - translation_z=t[2]; - r.getValue(axis,angle); - rotaxis_x=axis[0]; - rotaxis_y=axis[1]; - rotaxis_z=axis[2]; - rotangle_radians=angle; - } - message("===> Global Translation:"); - message(" x = "+QString::number(translation_x/SYSTEM_OF_UNITS::mm)+" mm"); - message(" y = "+QString::number(translation_y/SYSTEM_OF_UNITS::mm)+" mm"); - message(" z = "+QString::number(translation_z/SYSTEM_OF_UNITS::mm)+" mm"); - message("===> Global Rotation:"); - message(" axis x = "+QString::number(rotaxis_x)); - message(" axis y = "+QString::number(rotaxis_y)); - message(" axis z = "+QString::number(rotaxis_z)); - message(" angle = "+QString::number(rotangle_radians*180.0/M_PI)+" deg"); - } - - if (m_d->controller->printInfoOnClick_Tree()) { - std::ostringstream str; - GeoPrintGraphAction pg(str); - volhandle->geoPVConstLink()->exec(&pg); - message("===> Tree:"); - foreach (QString line, QString(str.str().c_str()).split("\n")) - message(" "+line); - } - - if (m_d->controller->printInfoOnClick_Mass()) { - //FIXME: Move the mass calculations to the volume handles, and let - //the common data cache some of the volume information by - //logVolume). - message("===> Total Mass <==="); - message("Inclusive "+QString::number(Imp::inclusiveMass(volhandle->geoPVConstLink())/SYSTEM_OF_UNITS::kilogram)+" kg"); - message("Exclusive "+QString::number(Imp::exclusiveMass(volhandle->geoPVConstLink())/SYSTEM_OF_UNITS::kilogram)+" kg"); - } + // NB: We let the destructor of volumetreemodel take care of deleting + // our (top) volume handles, since it has to keep a list of them + // anyway. -} + // Perform auto expansion of all ether volumes (needed for muon dead + // material): + VolumeHandle::VolumeHandleListItr it, itE(si->vollist.end()); + for (it = si->vollist.begin(); it != itE; ++it) { + (*it)->expandMothersRecursivelyToNonEther(); + } -//_____________________________________________________________________________________ -SoTexture2* VP1GeometrySystem::Imp::getDummyTexture() -{ - SoTexture2* texture = new SoTexture2; - // texture->diffuseColor.setValue(0.40,0.60,0.40); - // texture->ambientColor.setValue(0.57,0.57,0.57); - // texture->specularColor.setValue(0.27,0.27,0.27); - // texture->shininess.setValue(.80); - return texture; + phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + phisectormanager->largeChangesEnd(); + si->soswitch->addChild(subsystemsep); + si->soswitch->enableNotify(save); + if (save) si->soswitch->touch(); + VP1Msg::messageDebug("END of VP1GeometrySystem::Imp::buildSystem() "); } + //_____________________________________________________________________________________ -SoMaterial* VP1GeometrySystem::Imp::getDummyMaterial() -{ - SoMaterial* material = new SoMaterial; - material->diffuseColor.setValue(0.40,0.60,0.40); - material->ambientColor.setValue(0.57,0.57,0.57); - material->specularColor.setValue(0.27,0.27,0.27); - material->shininess.setValue(.80); - return material; +double VP1GeometrySystem::Imp::exclusiveMass(const PVConstLink &pv) { + const GeoLogVol *lv = pv->getLogVol(); + const GeoMaterial *material = lv->getMaterial(); + double density = material->getDensity(); + return density * volume(pv); } - //_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::buildSystem(SubSystemInfo* si) -{ - - if (!si||si->isbuilt) { - return; - } - si->isbuilt = true; - int ichild(0); - - ensureInitVisAttributes(); - - assert(si->soswitch); - SoSeparator * subsystemsep = new SoSeparator; - phisectormanager->registerSubSystemSeparator(si->flag,subsystemsep); - phisectormanager->largeChangesBegin(); - - SbBool save = si->soswitch->enableNotify(false); - - { - //Loop over the treetop's that we previously selected: - - std::vector<SubSystemInfo::TreetopInfo>::const_iterator it, itE = si->treetopinfo.end(); - for (it=si->treetopinfo.begin(); it!=itE; ++it) - { - VP1Msg::messageDebug("-- toptree vol: " + QString(it->volname.c_str()) ); - - // Get the material name from the top volume and search for it - // in the list of "default" materials for the sub-detectors: - QString topMaterialName = QString::fromStdString(it->pV->getLogVol()->getMaterial()->getName()); - VP1Msg::messageDebug("topMaterial: " + topMaterialName); - SoMaterial* topMaterial = detVisAttributes->get(it->volname); - - // replace with special Dummy material if user uses this - if (topMaterialName == "Dummy") { - VP1Msg::messageWarning("the volume uses the 'Dummy' material!"); - topMaterial = getDummyMaterial(); - } - - VolumeHandleSharedData* volhandle_subsysdata = new VolumeHandleSharedData(controller, - si->flag, - &sonodesep2volhandle, - it->pV, - phisectormanager, - topMaterial, - matVisAttributes, - volVisAttributes, - controller->zappedVolumeListModel(), - controller->volumeTreeBrowser(), - m_textSep); - const GeoTrf::Transform3D::MatrixType & mtx=it->xf.matrix(); - SbMatrix matr(mtx(0,0),mtx(1,0),mtx(2,0),mtx(3,0), // Beware, Eigen and SoQt have different conventions - mtx(0,1),mtx(1,1),mtx(2,1),mtx(3,1), // For the matrix of homogenous transformations. - mtx(0,2),mtx(1,2),mtx(2,2),mtx(3,2), - mtx(0,3),mtx(1,3),mtx(2,3),mtx(3,3)); - - VolumeHandle * vh = new VolumeHandle(volhandle_subsysdata,0,it->pV,ichild++,matr); - si->vollist.push_back(vh); - } - } - - - volumetreemodel->addSubSystem( si->flag, si->vollist ); - - //NB: We let the destructor of volumetreemodel take care of deleting - //our (top) volume handles, since it has to keep a list of them - //anyway. - - - //Perform auto expansion of all ether volumes (needed for muon dead material): - VolumeHandle::VolumeHandleListItr it, itE(si->vollist.end()); - for (it = si->vollist.begin(); it!=itE; ++it){ - (*it)->expandMothersRecursivelyToNonEther(); - } - - - phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - phisectormanager->largeChangesEnd(); - si->soswitch->addChild(subsystemsep); - si->soswitch->enableNotify(save); - if (save) - si->soswitch->touch(); - VP1Msg::messageDebug("END of VP1GeometrySystem::Imp::buildSystem() " ); +double VP1GeometrySystem::Imp::volume(const PVConstLink &pv) { + const GeoLogVol *lv = pv->getLogVol(); + const GeoShape *shape = lv->getShape(); + return shape->volume(); } //_____________________________________________________________________________________ -double VP1GeometrySystem::Imp::exclusiveMass(const PVConstLink& pv) { - const GeoLogVol* lv = pv->getLogVol(); - const GeoMaterial *material = lv->getMaterial(); - double density = material->getDensity(); - return density*volume(pv); -} +double VP1GeometrySystem::Imp::inclusiveMass(const PVConstLink &pv) { + const GeoLogVol *lv = pv->getLogVol(); + const GeoMaterial *material = lv->getMaterial(); + double density = material->getDensity(); + double mass = exclusiveMass(pv); -//_____________________________________________________________________________________ -double VP1GeometrySystem::Imp::volume(const PVConstLink& pv) { - const GeoLogVol * lv = pv->getLogVol(); - const GeoShape *shape = lv->getShape(); - return shape->volume(); + GeoVolumeCursor av(pv); + while (!av.atEnd()) { + std::string materialName = + av.getVolume()->getLogVol()->getMaterial()->getName(); + + if (QString(materialName.c_str()).endsWith("Ether") || + QString(materialName.c_str()).endsWith("HyperUranium")) { + // Do nothing. These are not real volumes. + } else { + double delta = inclusiveMass(av.getVolume()) - + (volume(av.getVolume()) * density); + mass += delta; + } + av.next(); + } + return mass; } - //_____________________________________________________________________________________ -double VP1GeometrySystem::Imp::inclusiveMass(const PVConstLink& pv) { +QByteArray VP1GeometrySystem::saveState() { + ensureBuildController(); - const GeoLogVol* lv = pv->getLogVol(); - const GeoMaterial *material = lv->getMaterial(); - double density = material->getDensity(); + VP1Serialise serialise(7 /*version*/, this); + serialise.save(IVP13DSystemSimple::saveState()); - double mass = exclusiveMass(pv); + // Controller: + serialise.save(m_d->controller->saveSettings()); - GeoVolumeCursor av(pv); - while (!av.atEnd()) { - std::string materialName=av.getVolume()->getLogVol()->getMaterial()->getName(); - - if (QString(materialName.c_str()).endsWith("Ether") || QString(materialName.c_str()).endsWith("HyperUranium")) { - // Do nothing. These are not real volumes. + // Subsystem checkboxes: + QMap<QString, bool> subsysstate; + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + serialise.widgetHandled(subsys->checkbox); + subsysstate.insert(subsys->checkbox->text(), + subsys->checkbox->isChecked()); } - else { - double delta = inclusiveMass(av.getVolume()) - (volume(av.getVolume())*density); - mass += delta; + serialise.save(subsysstate); + + // Volume states: + QMap<quint32, QByteArray> topvolstates; + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + VolumeHandle::VolumeHandleListItr it(subsys->vollist.begin()), + itE(subsys->vollist.end()); + for (; it != itE; ++it) + topvolstates.insert((*it)->hashID(), + (*it)->getPersistifiableState()); } - av.next(); - } - return mass; -} + serialise.save(topvolstates); -//_____________________________________________________________________________________ -QByteArray VP1GeometrySystem::saveState() { + m_d->ensureInitVisAttributes(); + serialise.save(m_d->detVisAttributes->getState()); // version 7+ + serialise.save(m_d->matVisAttributes->getState()); // version 7+ + serialise.save(m_d->volVisAttributes->getState()); // version 7+ - ensureBuildController(); - - VP1Serialise serialise(7/*version*/,this); - serialise.save(IVP13DSystemSimple::saveState()); - - //Controller: - serialise.save(m_d->controller->saveSettings()); - - //Subsystem checkboxes: - QMap<QString,bool> subsysstate; - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - serialise.widgetHandled(subsys->checkbox); - subsysstate.insert(subsys->checkbox->text(),subsys->checkbox->isChecked()); - } - serialise.save(subsysstate); - - //Volume states: - QMap<quint32,QByteArray> topvolstates; - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - VolumeHandle::VolumeHandleListItr it(subsys->vollist.begin()),itE(subsys->vollist.end()); - for (;it!=itE;++it) - topvolstates.insert((*it)->hashID(),(*it)->getPersistifiableState()); - } - serialise.save(topvolstates); - - m_d->ensureInitVisAttributes(); - serialise.save(m_d->detVisAttributes->getState());//version 7+ - serialise.save(m_d->matVisAttributes->getState());//version 7+ - serialise.save(m_d->volVisAttributes->getState());//version 7+ - - serialise.disableUnsavedChecks();//We do the testing in the controller - return serialise.result(); + serialise.disableUnsavedChecks(); // We do the testing in the controller + return serialise.result(); } //_____________________________________________________________________________________ void VP1GeometrySystem::restoreFromState(QByteArray ba) { - VP1Deserialise state(ba,this); - if (state.version()<0||state.version()>7) { - message("Warning: State data in .vp1 file is in wrong format - ignoring!"); - return; - } - if (state.version()<=5) { - message("Warning: State data in .vp1 file is in obsolete format - ignoring!"); - return; - } - - ensureBuildController(); - IVP13DSystemSimple::restoreFromState(state.restoreByteArray()); - - //Controller: - m_d->controller->restoreSettings(state.restoreByteArray()); - - //Subsystem checkboxes: - VP1GeoFlags::SubSystemFlags flags(0); - QMap<QString,bool> subsysstate = state.restore<QMap<QString,bool> >(); - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - state.widgetHandled(subsys->checkbox); - if (subsysstate.contains(subsys->checkbox->text())&&subsysstate[subsys->checkbox->text()]) - flags.push_back(subsys->flag); - } - - //Volume states: - QMap<quint32,QByteArray> topvolstates; - topvolstates = state.restore<QMap<quint32,QByteArray> >(); - if (m_d->sceneroot)//(for some reason) we already have been in buildPermanentScenegraph - m_d->applyTopVolStates(topvolstates,true); - else - m_d->restoredTopvolstates = topvolstates;//save until buildPermanentScenegraph - - if (state.version()>=7) { - m_d->ensureInitVisAttributes(); - m_d->detVisAttributes->applyState(state.restoreByteArray()); - m_d->matVisAttributes->applyState(state.restoreByteArray()); - m_d->volVisAttributes->applyState(state.restoreByteArray()); - } + VP1Deserialise state(ba, this); + if (state.version() < 0 || state.version() > 7) { + message( + "Warning: State data in .vp1 file is in wrong format - ignoring!"); + return; + } + if (state.version() <= 5) { + message( + "Warning: State data in .vp1 file is in obsolete format - " + "ignoring!"); + return; + } + + ensureBuildController(); + IVP13DSystemSimple::restoreFromState(state.restoreByteArray()); + + // Controller: + m_d->controller->restoreSettings(state.restoreByteArray()); + + // Subsystem checkboxes: + VP1GeoFlags::SubSystemFlags flags(0); + QMap<QString, bool> subsysstate = state.restore<QMap<QString, bool> >(); + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + state.widgetHandled(subsys->checkbox); + if (subsysstate.contains(subsys->checkbox->text()) && + subsysstate[subsys->checkbox->text()]) + flags.push_back(subsys->flag); + } - state.disableUnrestoredChecks();//We do the testing in the controller + // Volume states: + QMap<quint32, QByteArray> topvolstates; + topvolstates = state.restore<QMap<quint32, QByteArray> >(); + if (m_d->sceneroot) //(for some reason) we already have been in + // buildPermanentScenegraph + m_d->applyTopVolStates(topvolstates, true); + else + m_d->restoredTopvolstates = + topvolstates; // save until buildPermanentScenegraph + + if (state.version() >= 7) { + m_d->ensureInitVisAttributes(); + m_d->detVisAttributes->applyState(state.restoreByteArray()); + m_d->matVisAttributes->applyState(state.restoreByteArray()); + m_d->volVisAttributes->applyState(state.restoreByteArray()); + } + state.disableUnrestoredChecks(); // We do the testing in the controller } //_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::applyTopVolStates(const QMap<quint32,QByteArray>&topvolstates,bool disablenotif) -{ - if (disablenotif) - phisectormanager->largeChangesBegin(); - QMap<quint32,QByteArray>::const_iterator topvolstatesItr; - foreach (Imp::SubSystemInfo * subsys, subsysInfoList) { - VolumeHandle::VolumeHandleListItr it(subsys->vollist.begin()),itE(subsys->vollist.end()); - for (;it!=itE;++it) { - topvolstatesItr = topvolstates.find((*it)->hashID()); - if (topvolstatesItr!=topvolstates.end()) - (*it)->applyPersistifiableState(topvolstatesItr.value()); - } - } - if (disablenotif) { - phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - phisectormanager->largeChangesEnd(); - } +void VP1GeometrySystem::Imp::applyTopVolStates( + const QMap<quint32, QByteArray> &topvolstates, bool disablenotif) { + if (disablenotif) phisectormanager->largeChangesBegin(); + QMap<quint32, QByteArray>::const_iterator topvolstatesItr; + foreach (Imp::SubSystemInfo *subsys, subsysInfoList) { + VolumeHandle::VolumeHandleListItr it(subsys->vollist.begin()), + itE(subsys->vollist.end()); + for (; it != itE; ++it) { + topvolstatesItr = topvolstates.find((*it)->hashID()); + if (topvolstatesItr != topvolstates.end()) + (*it)->applyPersistifiableState(topvolstatesItr.value()); + } + } + if (disablenotif) { + phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + phisectormanager->largeChangesEnd(); + } } //_____________________________________________________________________________________ -void VP1GeometrySystem::setCurvedSurfaceRealism(int val) -{ - ensureBuildController(); - if (val<0||val>100) { - message("setCurvedSurfaceRealism Error: Value "+str(val)+"out of range!"); - return; - } - m_d->controller->setComplexity(val==100?1.0:(val==0?0.0:val/100.0)); +void VP1GeometrySystem::setCurvedSurfaceRealism(int val) { + ensureBuildController(); + if (val < 0 || val > 100) { + message("setCurvedSurfaceRealism Error: Value " + str(val) + + "out of range!"); + return; + } + m_d->controller->setComplexity(val == 100 ? 1.0 + : (val == 0 ? 0.0 : val / 100.0)); } +//_____________________________________________________________________________________ +void VP1GeometrySystem::updateTransparency() { + ensureBuildController(); + float transparency = m_d->controller->transparency(); -//_____________________________________________________________________________________ -void VP1GeometrySystem::updateTransparency() -{ - ensureBuildController(); - - float transparency = m_d->controller->transparency(); - - VolumeHandle* lastSelVol = m_d->controller->lastSelectedVolume(); - m_d->controller->setLastSelectedVolume(0); - m_d->ensureInitVisAttributes(); - m_d->detVisAttributes->overrideTransparencies(transparency); - m_d->matVisAttributes->overrideTransparencies(transparency); - m_d->volVisAttributes->overrideTransparencies(transparency); - m_d->controller->setLastSelectedVolume(lastSelVol); + VolumeHandle *lastSelVol = m_d->controller->lastSelectedVolume(); + m_d->controller->setLastSelectedVolume(0); + m_d->ensureInitVisAttributes(); + m_d->detVisAttributes->overrideTransparencies(transparency); + m_d->matVisAttributes->overrideTransparencies(transparency); + m_d->volVisAttributes->overrideTransparencies(transparency); + m_d->controller->setLastSelectedVolume(lastSelVol); } //_____________________________________________________________________________________ -void VP1GeometrySystem::resetSubSystems(VP1GeoFlags::SubSystemFlags f) -{ - if (f.empty()) { - return; - } - - deselectAll(); - foreach(Imp::SubSystemInfo*si,m_d->subsysInfoList) { - if (std::find(f.begin(),f.end(),si->flag)!=f.end()) { - if (!si->isbuilt) { - continue; - } - VolumeHandle::VolumeHandleListItr it(si->vollist.begin()),itE(si->vollist.end()); - for (;it!=itE;++it) { - messageDebug("resetting volume --> " + (*it)->getName() ); - (*it)->reset(); +void VP1GeometrySystem::resetSubSystems(VP1GeoFlags::SubSystemFlags f) { + if (f.empty()) { + return; + } + + deselectAll(); + foreach (Imp::SubSystemInfo *si, m_d->subsysInfoList) { + if (std::find(f.begin(), f.end(), si->flag) != f.end()) { + if (!si->isbuilt) { + continue; + } + VolumeHandle::VolumeHandleListItr it(si->vollist.begin()), + itE(si->vollist.end()); + for (; it != itE; ++it) { + messageDebug("resetting volume --> " + (*it)->getName()); + (*it)->reset(); + } } } - } } //_____________________________________________________________________________________ -void VP1GeometrySystem::autoExpandByVolumeOrMaterialName(bool bymatname,QString targetname) -{ - if (targetname.isEmpty()) { - VP1Msg::messageDebug("targetname is empty."); - return; - } - - messageVerbose("Auto expansions of **visible** volumes requested. Target all volumes with " - +str(bymatname?"material name":"name")+" matching "+targetname); - - //QRegExp selregexp(targetname,Qt::CaseSensitive,QRegExp::Wildcard); - QRegExp selregexp(targetname, Qt::CaseSensitive, QRegExp::RegExp); - VP1Msg::messageDebug("RegExp pattern: " + selregexp.pattern() ); - - std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; - m_d->volumetreemodel->getRootHandles(roothandles); - VolumeHandle::VolumeHandleListItr it, itE; - - bool save = m_d->sceneroot->enableNotify(false); - m_d->phisectormanager->largeChangesBegin(); - - if (roothandles.size() == 0) { - VP1Msg::messageWarningRed("No root nodes selected! Please select at least a root node before trying to apply filters. Ideally, you should turn on only the root node containing the volumes you are interested in; e.g., turn on the 'Endcap MDT' root node, if you are looking for an EIL chamber."); - } else { +void VP1GeometrySystem::autoExpandByVolumeOrMaterialName(bool bymatname, + QString targetname) { + if (targetname.isEmpty()) { + VP1Msg::messageDebug("targetname is empty."); + return; + } + + messageVerbose( + "Auto expansions of **visible** volumes requested. Target all volumes " + "with " + + str(bymatname ? "material name" : "name") + " matching " + targetname); + + // QRegExp selregexp(targetname,Qt::CaseSensitive,QRegExp::Wildcard); + QRegExp selregexp(targetname, Qt::CaseSensitive, QRegExp::RegExp); + VP1Msg::messageDebug("RegExp pattern: " + selregexp.pattern()); + + std::vector<std::pair<VolumeHandle::VolumeHandleListItr, + VolumeHandle::VolumeHandleListItr> > + roothandles; + m_d->volumetreemodel->getRootHandles(roothandles); + VolumeHandle::VolumeHandleListItr it, itE; + bool save = m_d->sceneroot->enableNotify(false); m_d->phisectormanager->largeChangesBegin(); - deselectAll(); + if (roothandles.size() == 0) { + VP1Msg::messageWarningRed( + "No root nodes selected! Please select at least a root node before " + "trying to apply filters. Ideally, you should turn on only the " + "root node containing the volumes you are interested in; e.g., " + "turn on the 'Endcap MDT' root node, if you are looking for an EIL " + "chamber."); + } else { + bool save = m_d->sceneroot->enableNotify(false); + m_d->phisectormanager->largeChangesBegin(); + + deselectAll(); + + for (unsigned i = 0; i < roothandles.size(); ++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + bool matchFound = false; + + for (; it != itE; ++it) { + VolumeHandle *vol = *it; + VP1Msg::messageDebug( + "Looking inside the root node [name: " + vol->getName() + + ", material: " + + QString::fromStdString(vol->geoMaterial()->getName()) + + "]"); + m_d->expandVisibleVolumesRecursively(vol, selregexp, bymatname); + } + } - for (unsigned i = 0; i<roothandles.size();++i) { - it = roothandles.at(i).first; - itE = roothandles.at(i).second; - bool matchFound = false; + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); + } + } +} - for(;it!=itE;++it) { - VolumeHandle* vol = *it; - VP1Msg::messageDebug("Looking inside the root node [name: " + vol->getName() + ", material: " + QString::fromStdString(vol->geoMaterial()->getName()) + "]" ); - m_d->expandVisibleVolumesRecursively(vol, selregexp, bymatname); - } +//_____________________________________________________________________________________ +void VP1GeometrySystem::Imp::expandVisibleVolumesRecursively( + VolumeHandle *handle, const QRegExp &selregexp, bool bymatname) { + // if (handle->state()==VP1GeoFlags::ZAPPED) + // return; + VP1Msg::messageDebug( + "VP1GeometrySystem::Imp::expandVisibleVolumesRecursively()"); + if (handle->state() == VP1GeoFlags::ZAPPED) { + VP1Msg::messageDebug(handle->getName() + " is ZAPPED. Returning..."); + return; } - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); + if (handle->state() == VP1GeoFlags::CONTRACTED) { + VP1Msg::messageDebug(handle->getName() + " is CONTRACTED. Going on..."); + // See if we match (and have children) - if so, update state. + if (handle->nChildren() > 0 && + selregexp.exactMatch( + bymatname ? QString(handle->geoMaterial()->getName().c_str()) + : handle->getName())) { + VP1Msg::messageDebug( + handle->getName() + + " has >0 children: OK! Setting it to 'EXPANDED'."); + handle->setState(VP1GeoFlags::EXPANDED); + } + VP1Msg::messageDebug(handle->getName() + " - Now returning..."); + return; } - } -} -//_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::expandVisibleVolumesRecursively(VolumeHandle* handle,const QRegExp& selregexp,bool bymatname) -{ - //if (handle->state()==VP1GeoFlags::ZAPPED) - // return; - VP1Msg::messageDebug("VP1GeometrySystem::Imp::expandVisibleVolumesRecursively()"); - if (handle->state()==VP1GeoFlags::ZAPPED) { - VP1Msg::messageDebug(handle->getName() +" is ZAPPED. Returning..."); - return; - } - - if (handle->state()==VP1GeoFlags::CONTRACTED) { - VP1Msg::messageDebug(handle->getName() +" is CONTRACTED. Going on..."); - //See if we match (and have children) - if so, update state. - if (handle->nChildren()>0 - && selregexp.exactMatch(bymatname?QString(handle->geoMaterial()->getName().c_str()):handle->getName())) - { - VP1Msg::messageDebug(handle->getName() +" has >0 children: OK! Setting it to 'EXPANDED'."); - handle->setState(VP1GeoFlags::EXPANDED); - } - VP1Msg::messageDebug(handle->getName() +" - Now returning..."); - return; - } - - //Must be expanded: Let us call on any (initialised) children instead. - if (handle->nChildren()==0||!handle->childrenAreInitialised()) { - VP1Msg::messageDebug(handle->getName() +" has NO children or they are not initialized. Returning..."); - return; - } - - //TODO: does the code comes here ever??? Check! - VP1Msg::messageDebug(handle->getName() +" - Now looping over children..."); - VolumeHandle::VolumeHandleListItr it(handle->childrenBegin()), itE(handle->childrenEnd()); - for(;it!=itE;++it) { - expandVisibleVolumesRecursively(*it,selregexp,bymatname); - } -} + // Must be expanded: Let us call on any (initialised) children instead. + if (handle->nChildren() == 0 || !handle->childrenAreInitialised()) { + VP1Msg::messageDebug( + handle->getName() + + " has NO children or they are not initialized. Returning..."); + return; + } + // TODO: does the code comes here ever??? Check! + VP1Msg::messageDebug(handle->getName() + " - Now looping over children..."); + VolumeHandle::VolumeHandleListItr it(handle->childrenBegin()), + itE(handle->childrenEnd()); + for (; it != itE; ++it) { + expandVisibleVolumesRecursively(*it, selregexp, bymatname); + } +} //_____________________________________________________________________________________ -void VP1GeometrySystem::volumeStateChangeRequested(VolumeHandle*vh,VP1GeoFlags::VOLSTATE state) -{ - //might not use this slot presently... - if (!vh) - return; - deselectAll(); - vh->setState(state); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); +void VP1GeometrySystem::volumeStateChangeRequested( + VolumeHandle *vh, VP1GeoFlags::VOLSTATE state) { + // might not use this slot presently... + if (!vh) return; + deselectAll(); + vh->setState(state); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); } - //_____________________________________________________________________________________ -void VP1GeometrySystem::volumeResetRequested(VolumeHandle*vh) -{ - if (!vh) - return; - deselectAll(); - vh->reset(); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); +void VP1GeometrySystem::volumeResetRequested(VolumeHandle *vh) { + if (!vh) return; + deselectAll(); + vh->reset(); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); } - //_____________________________________________________________________________________ -void VP1GeometrySystem::setShowVolumeOutLines(bool b) -{ - std::map<SoSeparator*,VolumeHandle*>::iterator it,itE(m_d->sonodesep2volhandle.end()); - for (it =m_d->sonodesep2volhandle.begin();it!=itE;++it) - VolumeHandleSharedData::setShowVolumeOutlines(it->first,b); +void VP1GeometrySystem::setShowVolumeOutLines(bool b) { + std::map<SoSeparator *, VolumeHandle *>::iterator it, + itE(m_d->sonodesep2volhandle.end()); + for (it = m_d->sonodesep2volhandle.begin(); it != itE; ++it) + VolumeHandleSharedData::setShowVolumeOutlines(it->first, b); } - //_____________________________________________________________________________________ -void VP1GeometrySystem::saveMaterialsToFile(QString filename,bool onlyChangedMaterials) -{ - if (filename.isEmpty()) - return; - - //If file exists, ask to overwrite. - QFileInfo fi(filename); - if (fi.exists()) { - if (!fi.isWritable()) { - QMessageBox::critical(0, "Error - could not save to file "+filename, - "Could not save to file: <i>"+filename+"</i>" - +"<br/><br/>Reason: File exists already and is write protected",QMessageBox::Ok,QMessageBox::Ok); - return; - } - } - - QFile file(filename); - if (!file.open(QIODevice::WriteOnly)) { - QMessageBox::critical(0, "Error - problems writing to file "+filename, - "Problems writing to file: <i>"+filename+"</i>",QMessageBox::Ok,QMessageBox::Ok); - return; - } - - m_d->ensureInitVisAttributes(); - VP1Serialise s(0/*version*/,this); - //Save some file ID info!! - s.save(QString("VP1GeoMaterialsBegin")); - s.save(m_d->detVisAttributes->getState(onlyChangedMaterials)); - s.save(m_d->matVisAttributes->getState(onlyChangedMaterials)); - s.save(m_d->volVisAttributes->getState(onlyChangedMaterials)); - s.save(QString("VP1GeoMaterialsEnd")); - s.disableUnsavedChecks(); - - QDataStream outfile(&file); - outfile<<qCompress(s.result()).toBase64(); +void VP1GeometrySystem::saveMaterialsToFile(QString filename, + bool onlyChangedMaterials) { + if (filename.isEmpty()) return; + + // If file exists, ask to overwrite. + QFileInfo fi(filename); + if (fi.exists()) { + if (!fi.isWritable()) { + QMessageBox::critical( + 0, "Error - could not save to file " + filename, + "Could not save to file: <i>" + filename + "</i>" + + "<br/><br/>Reason: File exists already and is write " + "protected", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + } + QFile file(filename); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::critical( + 0, "Error - problems writing to file " + filename, + "Problems writing to file: <i>" + filename + "</i>", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + + m_d->ensureInitVisAttributes(); + VP1Serialise s(0 /*version*/, this); + // Save some file ID info!! + s.save(QString("VP1GeoMaterialsBegin")); + s.save(m_d->detVisAttributes->getState(onlyChangedMaterials)); + s.save(m_d->matVisAttributes->getState(onlyChangedMaterials)); + s.save(m_d->volVisAttributes->getState(onlyChangedMaterials)); + s.save(QString("VP1GeoMaterialsEnd")); + s.disableUnsavedChecks(); + + QDataStream outfile(&file); + outfile << qCompress(s.result()).toBase64(); } //_____________________________________________________________________________________ -void VP1GeometrySystem::loadMaterialsFromFile(QString filename) -{ - if (filename.isEmpty()) - return; - QFileInfo fi(filename); - if (!fi.exists()) { - QMessageBox::critical(0, "Error - file does not exists: "+filename, - "File does not exists: <i>"+filename+"</i>",QMessageBox::Ok,QMessageBox::Ok); - return; - } - if (!fi.isReadable()) { - QMessageBox::critical(0, "Error - file is not readable: "+filename, - "File is not readable: <i>"+filename+"</i>",QMessageBox::Ok,QMessageBox::Ok); - return; - } - //open file - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) { - QMessageBox::critical(0, "Error - problems opening file "+filename, - "Problems opening file: <i>"+filename+"</i>",QMessageBox::Ok,QMessageBox::Ok); - return; - } - QByteArray byteArray64; - QDataStream infile(&file); - infile >> byteArray64; - QByteArray byteArray = qUncompress(QByteArray::fromBase64(byteArray64)); - - VP1Deserialise s(byteArray,this); - if (s.version()!=0) { - QMessageBox::critical(0, "Error - File in wrong format "+filename, - "File in wrong format: <i>"+filename+"</i>",QMessageBox::Ok,QMessageBox::Ok); - return; - } - QString txtbegin, txtend; - QByteArray baDet, baMat, baVol; - txtbegin = s.restoreString(); - baDet = s.restoreByteArray(); - baMat = s.restoreByteArray(); - baVol = s.restoreByteArray(); - txtend = s.restoreString(); - s.disableUnrestoredChecks(); - if (txtbegin!="VP1GeoMaterialsBegin"||txtend!="VP1GeoMaterialsEnd") { - QMessageBox::critical(0, "Error - File in wrong format "+filename, - "File in wrong format: <i>"+filename+"</i>",QMessageBox::Ok,QMessageBox::Ok); - return; - } - - m_d->ensureInitVisAttributes(); - m_d->detVisAttributes->applyState(baDet); - m_d->matVisAttributes->applyState(baMat); - m_d->volVisAttributes->applyState(baVol); - - VolumeHandle* lastsel = m_d->controller->lastSelectedVolume(); - m_d->controller->setLastSelectedVolume(0); - m_d->controller->setLastSelectedVolume(lastsel); -} +void VP1GeometrySystem::loadMaterialsFromFile(QString filename) { + if (filename.isEmpty()) return; + QFileInfo fi(filename); + if (!fi.exists()) { + QMessageBox::critical(0, "Error - file does not exists: " + filename, + "File does not exists: <i>" + filename + "</i>", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + if (!fi.isReadable()) { + QMessageBox::critical(0, "Error - file is not readable: " + filename, + "File is not readable: <i>" + filename + "</i>", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + // open file + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(0, "Error - problems opening file " + filename, + "Problems opening file: <i>" + filename + "</i>", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + QByteArray byteArray64; + QDataStream infile(&file); + infile >> byteArray64; + QByteArray byteArray = qUncompress(QByteArray::fromBase64(byteArray64)); + + VP1Deserialise s(byteArray, this); + if (s.version() != 0) { + QMessageBox::critical(0, "Error - File in wrong format " + filename, + "File in wrong format: <i>" + filename + "</i>", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + QString txtbegin, txtend; + QByteArray baDet, baMat, baVol; + txtbegin = s.restoreString(); + baDet = s.restoreByteArray(); + baMat = s.restoreByteArray(); + baVol = s.restoreByteArray(); + txtend = s.restoreString(); + s.disableUnrestoredChecks(); + if (txtbegin != "VP1GeoMaterialsBegin" || txtend != "VP1GeoMaterialsEnd") { + QMessageBox::critical(0, "Error - File in wrong format " + filename, + "File in wrong format: <i>" + filename + "</i>", + QMessageBox::Ok, QMessageBox::Ok); + return; + } + m_d->ensureInitVisAttributes(); + m_d->detVisAttributes->applyState(baDet); + m_d->matVisAttributes->applyState(baMat); + m_d->volVisAttributes->applyState(baVol); + VolumeHandle *lastsel = m_d->controller->lastSelectedVolume(); + m_d->controller->setLastSelectedVolume(0); + m_d->controller->setLastSelectedVolume(lastsel); +} //_____________________________________________________________________________________ void VP1GeometrySystem::saveTrees() { #ifdef __APPLE__ - char buffer[1024]; - char *wd=getcwd(buffer,1024); + char buffer[1024]; + char *wd = getcwd(buffer, 1024); - QString path = QFileDialog::getSaveFileName(nullptr, tr("Save Geometry File"), - wd, - tr("Geometry files (*.db)"),0,QFileDialog::DontUseNativeDialog); + QString path = QFileDialog::getSaveFileName( + nullptr, tr("Save Geometry File"), wd, tr("Geometry files (*.db)"), 0, + QFileDialog::DontUseNativeDialog); #else - QString path = QFileDialog::getSaveFileName(nullptr, tr("Save Geometry File"), - get_current_dir_name(), - tr("Geometry files (*.db)"),0,QFileDialog::DontUseNativeDialog); + QString path = QFileDialog::getSaveFileName( + nullptr, tr("Save Geometry File"), get_current_dir_name(), + tr("Geometry files (*.db)"), 0, QFileDialog::DontUseNativeDialog); #endif - if (path.isEmpty()) return; - - GMDBManager db(path.toStdString()); - - // check the DB connection - if (db.checkIsDBOpen()) - std::cout << "OK! Local GeoModel database has been created: " << path.toStdString() << std::endl; - else { - std::cout << "GeoModel database ERROR!! Exiting..."; - return; - } - GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); - - - GeoPhysVol *world=newWorld(); - - foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) { - if (subsys->checkbox->isChecked()){ - std::vector<Imp::SubSystemInfo::TreetopInfo> & ttInfo=subsys->treetopinfo; - foreach (const Imp::SubSystemInfo::TreetopInfo & treeTop, ttInfo) { - - GeoNameTag *nameTag = new GeoNameTag(treeTop.volname); - GeoTransform *transform=new GeoTransform(treeTop.xf); - world->add(transform); - world->add(nameTag); - GeoPhysVol *pV=(GeoPhysVol *) &*treeTop.pV; - world->add(pV); - } - } - } - world->exec(&dumpGeoModelGraph); - dumpGeoModelGraph.saveToDB(); - world->unref(); + if (path.isEmpty()) return; + + GMDBManager db(path.toStdString()); + + // check the DB connection + if (db.checkIsDBOpen()) + std::cout << "OK! Local GeoModel database has been created: " + << path.toStdString() << std::endl; + else { + std::cout << "GeoModel database ERROR!! Exiting..."; + return; + } + GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); + + GeoPhysVol *world = newWorld(); + + foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { + if (subsys->checkbox->isChecked()) { + std::vector<Imp::SubSystemInfo::TreetopInfo> &ttInfo = + subsys->treetopinfo; + foreach (const Imp::SubSystemInfo::TreetopInfo &treeTop, ttInfo) { + GeoNameTag *nameTag = new GeoNameTag(treeTop.volname); + GeoTransform *transform = new GeoTransform(treeTop.xf); + world->add(transform); + world->add(nameTag); + GeoPhysVol *pV = (GeoPhysVol *)&*treeTop.pV; + world->add(pV); + } + } + } + world->exec(&dumpGeoModelGraph); + dumpGeoModelGraph.saveToDB(); + world->unref(); } //_____________________________________________________________________________________ -GeoPhysVol *VP1GeometrySystem::newWorld() const { - const double gr = SYSTEM_OF_UNITS::gram; - const double mole = SYSTEM_OF_UNITS::mole; - const double cm3 = SYSTEM_OF_UNITS::cm3; - - // Define the chemical elements - GeoElement* Nitrogen = new GeoElement ("Nitrogen" ,"N" , 7.0 , 14.0067 *gr/mole); - GeoElement* Oxygen = new GeoElement ("Oxygen" ,"O" , 8.0 , 15.9995 *gr/mole); - GeoElement* Argon = new GeoElement ("Argon" ,"Ar" , 18.0 , 39.948 *gr/mole); - GeoElement* Hydrogen = new GeoElement ("Hydrogen" ,"H" , 1.0 , 1.00797 *gr/mole); - - double densityOfAir=0.001214 *gr/cm3; - GeoMaterial *air = new GeoMaterial("Air", densityOfAir); - air->add(Nitrogen , 0.7494); - air->add(Oxygen, 0.2369); - air->add(Argon, 0.0129); - air->add(Hydrogen, 0.0008); - air->lock(); - - const GeoBox* worldBox = new GeoBox(2000*SYSTEM_OF_UNITS::cm, 2000*SYSTEM_OF_UNITS::cm, 2500*SYSTEM_OF_UNITS::cm); - const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); - GeoPhysVol* world = new GeoPhysVol(worldLog); - return world; +GeoPhysVol *VP1GeometrySystem::newWorld() const { + const double gr = SYSTEM_OF_UNITS::gram; + const double mole = SYSTEM_OF_UNITS::mole; + const double cm3 = SYSTEM_OF_UNITS::cm3; + + // Define the chemical elements + GeoElement *Nitrogen = + new GeoElement("Nitrogen", "N", 7.0, 14.0067 * gr / mole); + GeoElement *Oxygen = + new GeoElement("Oxygen", "O", 8.0, 15.9995 * gr / mole); + GeoElement *Argon = new GeoElement("Argon", "Ar", 18.0, 39.948 * gr / mole); + GeoElement *Hydrogen = + new GeoElement("Hydrogen", "H", 1.0, 1.00797 * gr / mole); + + double densityOfAir = 0.001214 * gr / cm3; + GeoMaterial *air = new GeoMaterial("Air", densityOfAir); + air->add(Nitrogen, 0.7494); + air->add(Oxygen, 0.2369); + air->add(Argon, 0.0129); + air->add(Hydrogen, 0.0008); + air->lock(); + + const GeoBox *worldBox = + new GeoBox(2000 * SYSTEM_OF_UNITS::cm, 2000 * SYSTEM_OF_UNITS::cm, + 2500 * SYSTEM_OF_UNITS::cm); + const GeoLogVol *worldLog = new GeoLogVol("WorldLog", worldBox, air); + GeoPhysVol *world = new GeoPhysVol(worldLog); + return world; } - //_____________________________________________________________________________________ -void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, int maxDepth = 1, bool stopAtFirst = true, bool visitChildren = false, bool resetView = false) -{ - - // initialize the regular expression - QRegExp selregexp(targetname, Qt::CaseSensitive, QRegExp::RegExp); - // VP1Msg::messageDebug("RegExp pattern: " + selregexp.pattern() ); - - QStringList ll; - ll << "VP1GeometrySystem::filterVolumes" << "RegExp pattern:" << selregexp.pattern() - << "- maxDepth:" << QString::number(maxDepth) - << "- stopAtFirst:" << QString::number(stopAtFirst) - << "- visitChildren:" << QString::number(visitChildren) - << "- resetView:" << QString::number(resetView); - VP1Msg::messageDebug(ll.join(" ")); - - - // get root handles list - std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; - m_d->volumetreemodel->getRootHandles(roothandles); - VolumeHandle::VolumeHandleListItr it, itE; - - bool save = m_d->sceneroot->enableNotify(false); - m_d->phisectormanager->largeChangesBegin(); - deselectAll(); - - bool zapAll = false; // TODO: do we need that? - bool matchFound = false; - unsigned nFound = 0; - - // loop over root handles - for (unsigned i = 0; i<roothandles.size();++i) { - it = roothandles.at(i).first; - itE = roothandles.at(i).second; - - // loop over root volumes - for(;it!=itE;++it) { - - VolumeHandle* handle = (*it); - - VP1Msg::messageDebug("Looking at the root node [name: " + handle->getName() + ", mat: " + QString::fromStdString(handle->geoMaterial()->getName()) + "]" ); - m_d->filterVolumesRec(handle, selregexp, bymatname, stopAtFirst, visitChildren, resetView, zapAll, matchFound, nFound, maxDepth); - VP1Msg::messageDebug("matchFound: " + QString::number(matchFound)); - - if (resetView) { - VP1Msg::messageDebug("'expanding' and 'contracting' the root volume..."); - // in the call to 'filterVolumesRec' above, when resetting the view, - // we have 'contracted' the root volume and all the children we had 'zapped' before. - // So, now we need to open ('expand'), and then close ('contract') the root volume again, - // in order to get rid of the manually-contracted volumes. - handle->setState(VP1GeoFlags::EXPANDED); - handle->setState(VP1GeoFlags::CONTRACTED); - } +void VP1GeometrySystem::filterVolumes(QString targetname, bool bymatname, + int maxDepth = 1, bool stopAtFirst = true, + bool visitChildren = false, + bool resetView = false) { + // initialize the regular expression + QRegExp selregexp(targetname, Qt::CaseSensitive, QRegExp::RegExp); + // VP1Msg::messageDebug("RegExp pattern: " + selregexp.pattern() ); + + QStringList ll; + ll << "VP1GeometrySystem::filterVolumes" + << "RegExp pattern:" << selregexp.pattern() + << "- maxDepth:" << QString::number(maxDepth) + << "- stopAtFirst:" << QString::number(stopAtFirst) + << "- visitChildren:" << QString::number(visitChildren) + << "- resetView:" << QString::number(resetView); + VP1Msg::messageDebug(ll.join(" ")); + + // get root handles list + std::vector<std::pair<VolumeHandle::VolumeHandleListItr, + VolumeHandle::VolumeHandleListItr> > + roothandles; + m_d->volumetreemodel->getRootHandles(roothandles); + VolumeHandle::VolumeHandleListItr it, itE; + + bool save = m_d->sceneroot->enableNotify(false); + m_d->phisectormanager->largeChangesBegin(); + deselectAll(); - } // end loop over root volumes - } // loop over root handles - - // give feedback to the user - message("[filter volumes] # of matching volumes: " + QString::number(nFound)); - - //if user chose to visit children of matching volumes, - //then we change transparency type to 'Sorted Object Blend', usually better to visualize nested volumes - if (visitChildren && (nFound>0) ) { - message( QString("[filter volumes] NOTE: to show both matching mother and matching daughter volumes, ") - + QString("transparency has been set to 50% and transparency type has been changed to 'Sorted Object Blend', ") - + QString("which is usually better to visualize nested geometry volumes. ") - + QString("You can disable this auto-setting by checking the 'lock'.") ); - if ( ! m_d->controller->isTranspLocked()) { - m_d->controller->setTransparency(50); - emit updateTransparencyType( VP1QtInventorUtils::transparencyTypeToInt(SoGLRenderAction::SORTED_OBJECT_BLEND) ); - } - } - - - VP1Msg::messageDebug("largeChangesEnding..."); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); - } + bool zapAll = false; // TODO: do we need that? + bool matchFound = false; + unsigned nFound = 0; + + // loop over root handles + for (unsigned i = 0; i < roothandles.size(); ++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + + // loop over root volumes + for (; it != itE; ++it) { + VolumeHandle *handle = (*it); + + VP1Msg::messageDebug( + "Looking at the root node [name: " + handle->getName() + + ", mat: " + + QString::fromStdString(handle->geoMaterial()->getName()) + "]"); + m_d->filterVolumesRec(handle, selregexp, bymatname, stopAtFirst, + visitChildren, resetView, zapAll, matchFound, + nFound, maxDepth); + VP1Msg::messageDebug("matchFound: " + QString::number(matchFound)); + + if (resetView) { + VP1Msg::messageDebug( + "'expanding' and 'contracting' the root volume..."); + // in the call to 'filterVolumesRec' above, when resetting the + // view, we have 'contracted' the root volume and all the + // children we had 'zapped' before. So, now we need to open + // ('expand'), and then close ('contract') the root volume + // again, in order to get rid of the manually-contracted + // volumes. + handle->setState(VP1GeoFlags::EXPANDED); + handle->setState(VP1GeoFlags::CONTRACTED); + } + + } // end loop over root volumes + } // loop over root handles + + // give feedback to the user + message("[filter volumes] # of matching volumes: " + + QString::number(nFound)); + + // if user chose to visit children of matching volumes, + // then we change transparency type to 'Sorted Object Blend', usually better + // to visualize nested volumes + if (visitChildren && (nFound > 0)) { + message( + QString("[filter volumes] NOTE: to show both matching mother and " + "matching daughter volumes, ") + + QString("transparency has been set to 50% and transparency type " + "has been changed to 'Sorted Object Blend', ") + + QString("which is usually better to visualize nested geometry " + "volumes. ") + + QString( + "You can disable this auto-setting by checking the 'lock'.")); + if (!m_d->controller->isTranspLocked()) { + m_d->controller->setTransparency(50); + emit updateTransparencyType( + VP1QtInventorUtils::transparencyTypeToInt( + SoGLRenderAction::SORTED_OBJECT_BLEND)); + } + } + VP1Msg::messageDebug("largeChangesEnding..."); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); + } } //_____________________________________________________________________________________ -bool VP1GeometrySystem::Imp::filterVolumesRec(VolumeHandle* handle, QRegExp selregexp, bool bymatname, bool stopAtFirst, bool visitChildren, bool resetView, bool &zapAll, bool &matchFound, unsigned &nFound, int maxIter, unsigned int iter) -{ - if (!zapAll) { - VP1Msg::messageDebug2("iteration: " + QString::number(iter) + ", maxIter: " + QString::number(maxIter)); +bool VP1GeometrySystem::Imp::filterVolumesRec( + VolumeHandle *handle, QRegExp selregexp, bool bymatname, bool stopAtFirst, + bool visitChildren, bool resetView, bool &zapAll, bool &matchFound, + unsigned &nFound, int maxIter, unsigned int iter) { + if (!zapAll) { + VP1Msg::messageDebug2("iteration: " + QString::number(iter) + + ", maxIter: " + QString::number(maxIter)); VP1Msg::messageDebug2("looking into volume: " + handle->getName()); - } - - // zap the current volume by default... - handle->setState(VP1GeoFlags::ZAPPED); - - VP1Msg::messageDebug2("filtering: " + handle->getName() ); - - if ( !zapAll ) { - if ( !resetView ) { - //... then unzap the volume if it matches the filter regex - if (selregexp.exactMatch( bymatname ? QString(handle->geoMaterial()->getName().c_str()) : handle->getName()) ) - { - matchFound = true; - ++nFound; - VP1Msg::messageDebug(handle->getName() +" - **MATCH!** - 'Contracting' it (-->make it visible)..."); - handle->setState(VP1GeoFlags::CONTRACTED); // match, make the matching volume visible - // if a matching volume was found and 'stop at first' option was choosen, then stop here - //VP1Msg::messageDebug2("matchFound: " + QString::number(matchFound) + " - stopAtFirst: " + QString::number(stopAtFirst)); - - if (stopAtFirst && matchFound) { - VP1Msg::messageDebug("\tYou chose to show only the first matching volume, so we stop here - exiting from the inner children loop..."); - //return matchFound; - zapAll = true; - } - } else { - VP1Msg::messageDebug2("not matching --> zapping it"); - handle->setState(VP1GeoFlags::ZAPPED); // no match, open the volume to show its children - } + } + + // zap the current volume by default... + handle->setState(VP1GeoFlags::ZAPPED); + + VP1Msg::messageDebug2("filtering: " + handle->getName()); + + if (!zapAll) { + if (!resetView) { + //... then unzap the volume if it matches the filter regex + if (selregexp.exactMatch( + bymatname + ? QString(handle->geoMaterial()->getName().c_str()) + : handle->getName())) { + matchFound = true; + ++nFound; + VP1Msg::messageDebug( + handle->getName() + + " - **MATCH!** - 'Contracting' it (-->make it visible)..."); + handle->setState( + VP1GeoFlags::CONTRACTED); // match, make the matching + // volume visible + // if a matching volume was found and 'stop at first' option was + // choosen, then stop here + // VP1Msg::messageDebug2("matchFound: " + + // QString::number(matchFound) + " - stopAtFirst: " + + // QString::number(stopAtFirst)); + + if (stopAtFirst && matchFound) { + VP1Msg::messageDebug( + "\tYou chose to show only the first matching volume, " + "so we stop here - exiting from the inner children " + "loop..."); + // return matchFound; + zapAll = true; + } + } else { + VP1Msg::messageDebug2("not matching --> zapping it"); + handle->setState( + VP1GeoFlags::ZAPPED); // no match, open the volume to show + // its children + } } if (resetView) { - if(handle->state()!=VP1GeoFlags::CONTRACTED) { - VP1Msg::messageDebug2("resetView --> contracting it"); - handle->setState(VP1GeoFlags::CONTRACTED); // open the volume to show its children - } + if (handle->state() != VP1GeoFlags::CONTRACTED) { + VP1Msg::messageDebug2("resetView --> contracting it"); + handle->setState( + VP1GeoFlags::CONTRACTED); // open the volume to show its + // children + } } - } // end if !zapAll - - - // check iterations, a.k.a., the 'maxDepth', i.e., the number of layers of daughter volumes visited - if( maxIter != -1 && iter == maxIter) { - VP1Msg::messageDebug("maxIter [" + QString::number(iter) + "] reached, returning from the recursive method and go to the next upper volume..."); - return matchFound; - } - // increment the iteration number - iter++; - - // if no match yet, - // or if user asked to visit children of matching volumes too, - // then loop over children - if ( !matchFound || (matchFound && visitChildren) ) { - if (!zapAll) { - VP1Msg::messageDebug2("No match, or you chose to inspect all child volumes, so we look into the children..."); - } - if (handle->nChildren()>0) { - // get children list - handle->initialiseChildren(); - VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()),itChlE(handle->childrenEnd()); - for (;itChl!=itChlE;++itChl) { - - VolumeHandle* child = (*itChl); - - // filter children volumes recursively - filterVolumesRec(child, selregexp, bymatname, stopAtFirst, visitChildren, resetView, zapAll, matchFound, nFound, maxIter, iter); - if (stopAtFirst && matchFound) { - //return matchFound; - zapAll = true; - } - } // end loop over children - - if (resetView) { - // in the call to 'filterVolumesRec' above, when resetting the view, - // we have 'contracted' the root volume and all the children we had 'zapped' before. - // So, now we need to open ('expand'), and then close ('contract') the root volume again, - // in order to get rid of the manually-contracted volumes. - handle->setState(VP1GeoFlags::EXPANDED); - handle->setState(VP1GeoFlags::CONTRACTED); - } - } - } - - return matchFound; -} - - - - - - - - - + } // end if !zapAll + + // check iterations, a.k.a., the 'maxDepth', i.e., the number of layers of + // daughter volumes visited + if (maxIter != -1 && iter == maxIter) { + VP1Msg::messageDebug("maxIter [" + QString::number(iter) + + "] reached, returning from the recursive method " + "and go to the next upper volume..."); + return matchFound; + } + // increment the iteration number + iter++; + + // if no match yet, + // or if user asked to visit children of matching volumes too, + // then loop over children + if (!matchFound || (matchFound && visitChildren)) { + if (!zapAll) { + VP1Msg::messageDebug2( + "No match, or you chose to inspect all child volumes, so we " + "look into the children..."); + } + if (handle->nChildren() > 0) { + // get children list + handle->initialiseChildren(); + VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()), + itChlE(handle->childrenEnd()); + for (; itChl != itChlE; ++itChl) { + VolumeHandle *child = (*itChl); + + // filter children volumes recursively + filterVolumesRec(child, selregexp, bymatname, stopAtFirst, + visitChildren, resetView, zapAll, matchFound, + nFound, maxIter, iter); + if (stopAtFirst && matchFound) { + // return matchFound; + zapAll = true; + } + } // end loop over children + + if (resetView) { + // in the call to 'filterVolumesRec' above, when resetting the + // view, we have 'contracted' the root volume and all the + // children we had 'zapped' before. So, now we need to open + // ('expand'), and then close ('contract') the root volume + // again, in order to get rid of the manually-contracted + // volumes. + handle->setState(VP1GeoFlags::EXPANDED); + handle->setState(VP1GeoFlags::CONTRACTED); + } + } + } + return matchFound; +} // ========================= //////// -// Methods which come from VP1 and have been rplaced by other methods, +// Methods which come from VP1 and have been rplaced by other methods, // but they are useful for later use, // when we try to act on all volumes //////// // Not used at the moment, but useful //_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::changeStateOfAllVolumesRecursively(VolumeHandle*handle,VP1GeoFlags::VOLSTATE target) -{ +void VP1GeometrySystem::Imp::changeStateOfAllVolumesRecursively( + VolumeHandle *handle, VP1GeoFlags::VOLSTATE target) { handle->initialiseChildren(); handle->setState(target); - VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()),itChlE(handle->childrenEnd()); + VolumeHandle::VolumeHandleListItr itChl(handle->childrenBegin()), + itChlE(handle->childrenEnd()); - // loop over second level children - for (;itChl!=itChlE;++itChl) { + // loop over second level children + for (; itChl != itChlE; ++itChl) { changeStateOfAllVolumesRecursively(*itChl, target); } } - // Not used at the moment, but useful //_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::changeStateOfVisibleNonStandardVolumesRecursively(VolumeHandle*handle,VP1GeoFlags::VOLSTATE target) -{ - assert(target!=VP1GeoFlags::CONTRACTED); - if (handle->isAttached()) { - //The volume is visible, so ignore daughters - if (handle->isInitialisedAndHasNonStandardShape()) { - if (target!=VP1GeoFlags::EXPANDED||handle->nChildren()>0) - handle->setState(target); - } - return; - } else if (handle->state()==VP1GeoFlags::ZAPPED) - return; - //Must be expanded: Let us call on any (initialised) children instead. - if (handle->nChildren()==0||!handle->childrenAreInitialised()) - return; - VolumeHandle::VolumeHandleListItr it(handle->childrenBegin()), itE(handle->childrenEnd()); - for(;it!=itE;++it) - changeStateOfVisibleNonStandardVolumesRecursively(*it, target); +void VP1GeometrySystem::Imp::changeStateOfVisibleNonStandardVolumesRecursively( + VolumeHandle *handle, VP1GeoFlags::VOLSTATE target) { + assert(target != VP1GeoFlags::CONTRACTED); + if (handle->isAttached()) { + // The volume is visible, so ignore daughters + if (handle->isInitialisedAndHasNonStandardShape()) { + if (target != VP1GeoFlags::EXPANDED || handle->nChildren() > 0) + handle->setState(target); + } + return; + } else if (handle->state() == VP1GeoFlags::ZAPPED) + return; + // Must be expanded: Let us call on any (initialised) children instead. + if (handle->nChildren() == 0 || !handle->childrenAreInitialised()) return; + VolumeHandle::VolumeHandleListItr it(handle->childrenBegin()), + itE(handle->childrenEnd()); + for (; it != itE; ++it) + changeStateOfVisibleNonStandardVolumesRecursively(*it, target); } // Not used at the moment, but useful //_____________________________________________________________________________________ -void VP1GeometrySystem::actionOnAllNonStandardVolumes(bool zap) -{ - actionOnAllVolumes(zap, false); +void VP1GeometrySystem::actionOnAllNonStandardVolumes(bool zap) { + actionOnAllVolumes(zap, false); } // Not used at the moment, but useful //_____________________________________________________________________________________ -void VP1GeometrySystem::actionOnAllVolumes(bool zap, bool standardVolumes /* default: true*/) -{ - //VP1GeoFlags::VOLSTATE target = zap ? VP1GeoFlags::ZAPPED : VP1GeoFlags::EXPANDED; - VP1GeoFlags::VOLSTATE target = zap ? VP1GeoFlags::ZAPPED : VP1GeoFlags::CONTRACTED; - messageVerbose("Action on volumes with non-standard VRML representations. Target state is "+VP1GeoFlags::toString(target)); - - std::vector<std::pair<VolumeHandle::VolumeHandleListItr,VolumeHandle::VolumeHandleListItr> > roothandles; - m_d->volumetreemodel->getRootHandles(roothandles); - VolumeHandle::VolumeHandleListItr it, itE; - - bool save = m_d->sceneroot->enableNotify(false); - m_d->phisectormanager->largeChangesBegin(); - - deselectAll(); - - for (unsigned i = 0; i<roothandles.size();++i) { - it = roothandles.at(i).first; - itE = roothandles.at(i).second; - for(;it!=itE;++it) { - if (standardVolumes) { - m_d->changeStateOfAllVolumesRecursively(*it, target); - } else { - m_d->changeStateOfVisibleNonStandardVolumesRecursively(*it, target); - } - } - } - - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); - } -} +void VP1GeometrySystem::actionOnAllVolumes( + bool zap, bool standardVolumes /* default: true*/) { + // VP1GeoFlags::VOLSTATE target = zap ? VP1GeoFlags::ZAPPED : + // VP1GeoFlags::EXPANDED; + VP1GeoFlags::VOLSTATE target = + zap ? VP1GeoFlags::ZAPPED : VP1GeoFlags::CONTRACTED; + messageVerbose( + "Action on volumes with non-standard VRML representations. Target " + "state is " + + VP1GeoFlags::toString(target)); + + std::vector<std::pair<VolumeHandle::VolumeHandleListItr, + VolumeHandle::VolumeHandleListItr> > + roothandles; + m_d->volumetreemodel->getRootHandles(roothandles); + VolumeHandle::VolumeHandleListItr it, itE; + + bool save = m_d->sceneroot->enableNotify(false); + m_d->phisectormanager->largeChangesBegin(); + + deselectAll(); + + for (unsigned i = 0; i < roothandles.size(); ++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + for (; it != itE; ++it) { + if (standardVolumes) { + m_d->changeStateOfAllVolumesRecursively(*it, target); + } else { + m_d->changeStateOfVisibleNonStandardVolumesRecursively(*it, + target); + } + } + } + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); + } +}