diff --git a/FullSimLight/include/FSLSDPluginLoader.h b/FullSimLight/include/FSLSDPluginLoader.h index 2bbfa7e370de7b0453fafe4a75ce9b2b5bf5eef6..9bdb306085b3a37ccc739d92ff0bd40fe98f1fb0 100644 --- a/FullSimLight/include/FSLSDPluginLoader.h +++ b/FullSimLight/include/FSLSDPluginLoader.h @@ -1,10 +1,9 @@ /* - Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2017 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 62320def6a0d519ba93943e89ac0cb19edd8d3db..249c84b9f654b83ddef745195208a4b45500ff77 100644 --- a/FullSimLight/include/MassCalculator.hh +++ b/FullSimLight/include/MassCalculator.hh @@ -1,23 +1,24 @@ #ifndef MassCalculator_h #define MassCalculator_h 1 -#include "G4LogicalVolume.hh" -#include "G4Material.hh" -#include "G4String.hh" #include "G4Types.hh" +#include "G4String.hh" +#include "G4LogicalVolume.hh" #include "G4VPhysicalVolume.hh" +#include "G4Material.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 <nlohmann/json.hpp> #include <vector> +#include <nlohmann/json.hpp> using json = nlohmann::json; @@ -29,40 +30,33 @@ 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, - 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 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 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 4c995d3d518c9c4f17a7f9cf3408c1d8c582b3b7..904d3e096b55ab9175a9cda07c7d876fcea8279b 100644 --- a/FullSimLight/src/FSLDetectorConstruction.cc +++ b/FullSimLight/src/FSLDetectorConstruction.cc @@ -139,7 +139,7 @@ G4VPhysicalVolume *FSLDetectorConstruction::Construct() { fTimer.Start(); - GeoVPhysVol* world = nullptr; + GeoPhysVol* world = nullptr; G4LogicalVolume* envelope; if (fGeometryFileName.contains(".dylib") || fGeometryFileName.contains(".so")) { @@ -152,9 +152,8 @@ G4VPhysicalVolume *FSLDetectorConstruction::Construct() } - world = nullptr; world = CreateTheWorld(nullptr); - factory->create(dynamic_cast<GeoPhysVol*>(world)); + factory->create(world); G4cout << "ReadGeoModel::buildGeoModel() done." << G4endl; fTimer.Stop(); @@ -219,10 +218,8 @@ G4VPhysicalVolume *FSLDetectorConstruction::Construct() /* build the GeoModel geometry */ - // builds the whole GeoModel tree in memory - // and get an handle to the 'world' volume - world = readInGeo.buildGeoModel(); - + //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 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 aad6381cab960d03843768ec99386f9f31d8a96a..b5e491fc6d5bab90ef18e9423a9eac6074bb776d 100644 --- a/FullSimLight/src/MassCalculator.cc +++ b/FullSimLight/src/MassCalculator.cc @@ -1,550 +1,439 @@ #include "MassCalculator.hh" - #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 +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; - if (writeRep) { +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){ 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, - GeoVPhysVol* /*worldgeoModel*/, - std::vector<json>& jlist) { +void MassCalculator::recursiveMassCalculation (G4VPhysicalVolume* worldg4, GeoPhysVol* /*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 2eacec9b86671ec94c091b712c8dbb4524c281d2..73b0b93bd0152c9681c1be013e5f4d590b4e6af3 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoGeometryPluginLoader.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoGeometryPluginLoader.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2017 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 20556f73344d33b499de44d5949a3dee23c79c30..b2c29a63682f7df1fff2227f72bf9a247da90716 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVGeometryPlugin.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVGeometryPlugin.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef GEOMODELKERNEL_GEOVGEOMETRYPLUGIN_H @@ -12,48 +12,50 @@ * The geometry plugin builds the raw geometry */ -#include <memory> // smart pointers - -#include "GeoModelKernel/GeoPublisher.h" // to publish lists of FullPhysVol and AlignableTransform nodes in create() #include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoPublisher.h" // to publish lists of FullPhysVol and AlignableTransform nodes in create() + +#include <memory> // smart pointers 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(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; +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; + }; #endif diff --git a/GeoModelTools/GDMLtoGM/src/GDMLtoGM.cxx b/GeoModelTools/GDMLtoGM/src/GDMLtoGM.cxx index 4b8ed534a4d2f0177e03fe1f658441b44bb6eef5..4530b696d4113a92841a03f1b5e0fc90762737fb 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(GeoVPhysVol *world, bool publish = false ) override; + virtual void create(GeoPhysVol *world, bool publish = false ) override; private: @@ -43,11 +43,12 @@ class GDMLtoGM : public GeoVGeometryPlugin { GDMLtoGM::~GDMLtoGM() -{} +{ +} //## Other Operations (implementation) -void GDMLtoGM::create(GeoVPhysVol *world, bool /* 'publish' is not used here */) +void GDMLtoGM::create(GeoPhysVol *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 983d30388602a3ce43c361ff65f05562156fca76..f2d37bbaa3224828b8298c78b6b88ad2773d51d7 100644 --- a/GeoModelTools/GMCAT/src/gmcat.cxx +++ b/GeoModelTools/GMCAT/src/gmcat.cxx @@ -1,274 +1,266 @@ /* - * Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration - */ - -#include <stdlib.h> // setenv -#include <unistd.h> - -#include <cstdio> -#include <iostream> -#include <string> -#include <vector> + * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ +#include "GeoModelKernel/GeoVGeometryPlugin.h" #include "GeoModelDBManager/GMDBManager.h" -#include "GeoModelKernel/GeoAccessVolumeAction.h" -#include "GeoModelKernel/GeoBox.h" -#include "GeoModelKernel/GeoCountVolAction.h" -#include "GeoModelKernel/GeoElement.h" +#include "GeoModelRead/ReadGeoModel.h" +#include "GeoModelWrite/WriteGeoModel.h" + #include "GeoModelKernel/GeoGeometryPluginLoader.h" +#include "GeoModelKernel/GeoVolumeCursor.h" #include "GeoModelKernel/GeoMaterial.h" -#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoElement.h" #include "GeoModelKernel/GeoPVLink.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoCountVolAction.h" +#include "GeoModelKernel/GeoAccessVolumeAction.h" +#include "GeoModelKernel/GeoNameTag.h" #include "GeoModelKernel/GeoPublisher.h" -#include "GeoModelKernel/GeoVGeometryPlugin.h" -#include "GeoModelKernel/GeoVolumeCursor.h" -#include "GeoModelRead/ReadGeoModel.h" -#include "GeoModelWrite/WriteGeoModel.h" + +#include <iostream> +#include <string> +#include <vector> +#include <cstdio> +#include <unistd.h> +#include <stdlib.h> // setenv #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) { - 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); - } + + 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); } + } - // - // 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; + 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); } - // - // 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; - } + } + + + // + // 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; + } } - if (!outputFileSet) { - std::cerr << "\nERROR! You should set an output file.\n" << std::endl; - std::cerr << usage << std::endl; - return 3; + else { + std::cerr << "gmcat -- Error, cannot overwrite existing file " << outputFile << " (permission denied)" << std::endl; + return 4; } + } - // - // 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; - } - } - // - // 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 - } - } + // + // 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); - // - // 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; + 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; } - // - // 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; + + // 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 } - // - // 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(); + } + + // + // 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; } - world->unref(); + /* set the GeoModel reader */ + GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); - return 0; + /* 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(); + } + + 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; } diff --git a/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx b/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx index 6fe46685ff0616e342ec77a59b6d9e614144f0c1..f04800be9a091cc7e2a896a43390220d8231c8a8 100644 --- a/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx +++ b/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx @@ -1,118 +1,137 @@ /* - Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration */ -#include "GeoModelKernel/GeoNameTag.h" -#include "GeoModelKernel/GeoPhysVol.h" + #include "GeoModelKernel/GeoVGeometryPlugin.h" + + +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoNameTag.h" #include "GeoModelKernel/Units.h" -#define SYSTEM_OF_UNITS \ - GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' +#define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' + +#include "GeoModelXml/GmxInterface.h" +#include "GeoModelXml/Gmx2Geo.h" -#include <fstream> #include <iostream> +#include <fstream> #include <sstream> -#include "GeoModelXml/Gmx2Geo.h" -#include "GeoModelXml/GmxInterface.h" +class GMXPlugin : public GeoVGeometryPlugin { -class GMXPlugin : public GeoVGeometryPlugin { - public: - // Constructor: - GMXPlugin(); + public: - // Constructor with name to provide to publisher - GMXPlugin(std::string name) : GeoVGeometryPlugin(name) {} + // Constructor: + GMXPlugin(); - // Destructor: - ~GMXPlugin(); + // Constructor with name to provide to publisher + GMXPlugin(std::string name):GeoVGeometryPlugin(name){} - // Creation of geometry: - virtual void create(GeoVPhysVol *world, bool publish) override; + // Destructor: + ~GMXPlugin(); - private: - // Illegal operations: - const GMXPlugin &operator=(const GMXPlugin &right) = delete; - GMXPlugin(const GMXPlugin &right) = delete; + // Creation of geometry: + virtual void create(GeoPhysVol *world, bool publish) override; - bool exists(const std::string &name) { - std::ifstream f(name.c_str()); - return f.good(); - } + private: + + // Illegal operations: + const GMXPlugin & operator=(const GMXPlugin &right)=delete; + GMXPlugin(const GMXPlugin &right) = delete; - 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; + bool exists (const std::string& name) + { + std::ifstream f(name.c_str()); + return f.good(); + } - 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); - } + 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; - res.push_back(s.substr(pos_start)); - return 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); } + + res.push_back (s.substr (pos_start)); + return res; + } + }; -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); - } - 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; - } - 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); + + +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; } + 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(); - 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 d823082e873e266487ef923666db80b269578b88..b6b1d0f9a233c1852b14e69898016d0bfbcbec8c 100644 --- a/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx +++ b/GeoModelVisualization/VP1GeometrySystems/src/VP1GeometrySystem.cxx @@ -1,1993 +1,1865 @@ /* - Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 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/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/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> +#include <Inventor/nodes/SoLineSet.h> +#include <Inventor/nodes/SoCoordinate3.h> +#include <Inventor/nodes/SoDrawStyle.h> +#include <Inventor/nodes/SoLightModel.h> +#include <Inventor/nodes/SoTransform.h> +#include <Inventor/nodes/SoScale.h> // GeoModelCore includes -#include "GeoModelKernel/GeoAccessVolumeAction.h" +#include "GeoModelKernel/GeoVolumeCursor.h" +#include "GeoModelKernel/GeoPrintGraphAction.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoPVLink.h" #include "GeoModelKernel/GeoBox.h" #include "GeoModelKernel/GeoCountVolAction.h" -#include "GeoModelKernel/GeoElement.h" -#include "GeoModelKernel/GeoGeometryPluginLoader.h" -#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoAccessVolumeAction.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 "GeoModelRead/ReadGeoModel.h" #include "GeoModelWrite/WriteGeoModel.h" +#include "GeoModelRead/ReadGeoModel.h" -// WARNING: classes making use of 'Persistifier' should be included AFTER -// 'GeoModelIO/ReadGeoModel' -#include "GeoModelKernel/GeoShapeShift.h" +// WARNING: classes making use of 'Persistifier' should be included AFTER 'GeoModelIO/ReadGeoModel' #include "GeoModelKernel/GeoShapeUnion.h" +#include "GeoModelKernel/GeoShapeShift.h" // Qt includes -#include <QApplication> -#include <QByteArray> -#include <QCheckBox> +#include <QStack> +#include <QString> +#include <QSettings> #include <QDebug> -#include <QFileDialog> -#include <QFileInfo> +#include <QRegExp> +#include <QByteArray> +#include <QTimer> #include <QHeaderView> +#include <QApplication> +#include <QCheckBox> #include <QMessageBox> +#include <QFileInfo> +#include <QFileDialog> #include <QPushButton> -#include <QRegExp> -#include <QSettings> -#include <QStack> -#include <QString> -#include <QTimer> // C++ includes -#include <unistd.h> - #include <map> +#include <unistd.h> #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; - - 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; - }; +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(); - 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(); + 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) + { } - 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; + //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; + }; + + 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. + + + 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(); } -//_____________________________________________________________________________________ -VP1GeometrySystem::~VP1GeometrySystem() { - delete m_d; - m_d = 0; -} //_____________________________________________________________________________________ -void VP1GeometrySystem::setGeometrySelectable(bool b) { - ensureBuildController(); - m_d->controller->setGeometrySelectable(b); -} +void VP1GeometrySystem::systemuncreate() +{ -//_____________________________________________________________________________________ -void VP1GeometrySystem::setZoomToVolumeOnClick(bool b) { - ensureBuildController(); - m_d->controller->setZoomToVolumeOnClick(b); -} + 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; -//_____________________________________________________________________________________ -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; - } - } + foreach (Imp::SubSystemInfo * subsys, m_d->subsysInfoList) + delete subsys; + m_d->subsysInfoList.clear(); - 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; +VP1GeometrySystem::~VP1GeometrySystem() +{ + delete m_d; + m_d = 0; } //_____________________________________________________________________________________ -void VP1GeometrySystem::systemcreate(StoreGateSvc *) { - m_d->ensureInitVisAttributes(); +void VP1GeometrySystem::setGeometrySelectable(bool b) { + ensureBuildController(); + m_d->controller->setGeometrySelectable(b); } //_____________________________________________________________________________________ -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()); +void VP1GeometrySystem::setZoomToVolumeOnClick(bool b) { + ensureBuildController(); + m_d->controller->setZoomToVolumeOnClick(b); } + //_____________________________________________________________________________________ -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); +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!!! +} - // 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); +//_____________________________________________________________________________________ +QWidget * VP1GeometrySystem::buildController() +{ + message("VP1GeometrySystem::buildController"); - bool save = root->enableNotify(false); + m_d->controller = new GeoSysController(this); - // Catch keyboard events: - SoEventCallback *catchEvents = new SoEventCallback(); - catchEvents->addEventCallback(SoKeyboardEvent::getClassTypeId(), - Imp::catchKbdState, m_d); - root->addChild(catchEvents); + m_d->phisectormanager = new PhiSectorManager(m_d->controller->phiSectionWidget(),this,this); - root->addChild(m_d->controller->drawOptions()); - root->addChild(m_d->controller->pickStyle()); - { - GeoVolumeCursor av(world); - while (!av.atEnd()) { - m_d->addSubSystem(av.getName(), av.getName().c_str()); - av.next(); - } - } + 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))); - foreach (Imp::SubSystemInfo *subsys, m_d->subsysInfoList) { - connect(subsys->checkbox, SIGNAL(toggled(bool)), this, - SLOT(checkboxChanged())); - } + connect(m_d->controller,SIGNAL(transparencyChanged(float)),this,SLOT(updateTransparency())); - 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(); + 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))); - // 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); - } + //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); - root->enableNotify(save); - if (save) root->touch(); + return m_d->controller; } -//_____________________________________________________________________________________ -GeoVPhysVol *VP1GeometrySystem::Imp::getGeometry() { - return getGeometryFromLocalDB(); // for production -} //_____________________________________________________________________________________ -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; +void VP1GeometrySystem::systemcreate(StoreGateSvc*) +{ + m_d->ensureInitVisAttributes(); } -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; +//_____________________________________________________________________________________ +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()); } //_____________________________________________________________________________________ -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(); - } +void VP1GeometrySystem::buildPermanentSceneGraph(StoreGateSvc*/*detstore*/, SoSeparator *root) +{ + m_d->sceneroot = root; - m_existingGeoInput = path; - } - if (path == "") return nullptr; + PVConstLink world(m_d->getGeometry()); + if (!world) return; - GeoVPhysVol *world = - getenv("GX_GEOMETRY_FILE1") ? createTheWorld(nullptr) : nullptr; + 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); - 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 - } + // 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); + + bool save = root->enableNotify(false); + + //Catch keyboard events: + SoEventCallback *catchEvents = new SoEventCallback(); + catchEvents->addEventCallback(SoKeyboardEvent::getClassTypeId(),Imp::catchKbdState, m_d); + root->addChild(catchEvents); + + root->addChild(m_d->controller->drawOptions()); + root->addChild(m_d->controller->pickStyle()); + + { + 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(); - 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 = ""; - } - } - 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; +GeoPhysVol* VP1GeometrySystem::Imp::getGeometry() +{ + return getGeometryFromLocalDB(); // for production } //_____________________________________________________________________________________ -void VP1GeometrySystem::setAxesScale(int i) { - double x = (i - 50) / 25.0; - double scale = pow(10, x); - m_d->axesScale->scaleFactor.setValue(scale, scale, scale); +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; } -//_____________________________________________________________________________________ -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); - } + +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; } -// 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; - } +GeoPhysVol* VP1GeometrySystem::Imp::getGeometryFromLocalDB() +{ - 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; + 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"); } - VolumeHandle *volhandle = m_d->sonodesep2volhandle[nodesep]; - if (!volhandle) { - message("Found NULL volume handle"); - return; + else { + path=selectGeometryFile(); } - ///////////////////////////////////////////////////////////////////////// - // 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; - } + m_existingGeoInput = path; + } - 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; - } - 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); + if (path=="") return nullptr; - 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; - } + GeoPhysVol *world=getenv("GX_GEOMETRY_FILE1") ? createTheWorld(nullptr) : nullptr; - 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); - } - } + 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 "); - if (m_d->controller->displayLocalAxesOnClick()) { - SbMatrix mtx = volhandle->getGlobalTransformToVolume(); - m_d->axesSwitch->whichChild = SO_SWITCH_ALL; - m_d->axesTransform->setMatrix(mtx); - } + /* set the GeoModel reader */ + GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); - /////////////////////////////////// - // Update last-select controls // - /////////////////////////////////// + /* build the GeoModel geometry */ + GeoPhysVol* dbPhys = readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory - m_d->controller->setLastSelectedVolume(volhandle); + if (world) { - ///////////////////////////////////////////////////////// - // OK, time to print some information for the volume // - ///////////////////////////////////////////////////////// + //world->add(dbPhys); + GeoVolumeCursor aV(dbPhys); - message("===> Selected Node: " + volhandle->getName()); - if (m_d->controller->printInfoOnClick_Shape()) { - foreach (QString str, - DumpShape::shapeToStringList( - volhandle->geoPVConstLink()->getLogVol()->getShape())) - message(str); - } + 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(); + } - 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 { + world = createTheWorld(dbPhys); + } - if (m_d->controller->printInfoOnClick_CopyNumber()) { - int cn = volhandle->copyNumber(); - message("===> CopyNo : " + - (cn >= 0 - ? QString::number(cn) - : QString(cn == -1 ? "Invalid" - : "Error reconstructing copynumber"))); } + else if (path.contains(".dylib") || path.contains(".so")) { - 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"); - } + 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 - 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"); + 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=""; } + } + + return world; } //_____________________________________________________________________________________ -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::toggleLocalAxes(int i) { + if (i==0) m_d->axesSwitch->whichChild=SO_SWITCH_NONE; + else m_d->axesSwitch->whichChild=SO_SWITCH_ALL; } + //_____________________________________________________________________________________ -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; +void VP1GeometrySystem::setAxesScale(int i) { + double x=(i-50)/25.0; + double scale = pow(10,x); + m_d->axesScale->scaleFactor.setValue(scale,scale,scale); } //_____________________________________________________________________________________ -void VP1GeometrySystem::Imp::buildSystem(SubSystemInfo *si) { - if (!si || si->isbuilt) { - return; - } - si->isbuilt = true; - int ichild(0); +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); + } +} - ensureInitVisAttributes(); +// 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(); - assert(si->soswitch); - SoSeparator *subsystemsep = new SoSeparator; - phisectormanager->registerSubSystemSeparator(si->flag, subsystemsep); - phisectormanager->largeChangesBegin(); + VolumeHandle * parent=volhandle->parent(); + if (parent) parent->setState(VP1GeoFlags::CONTRACTED); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + return; + } - SbBool save = si->soswitch->enableNotify(false); + 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)) ) ); - { - // 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); - } + 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; + } + + 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); - volumetreemodel->addSubSystem(si->flag, si->vollist); + 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; - // 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. + GMDBManager db(path.toStdString()); - // 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(); + // 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; } - phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - phisectormanager->largeChangesEnd(); - si->soswitch->addChild(subsystemsep); - si->soswitch->enableNotify(save); - if (save) si->soswitch->touch(); - VP1Msg::messageDebug("END of VP1GeometrySystem::Imp::buildSystem() "); + 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"); + + { + 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"); + } + } //_____________________________________________________________________________________ -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); +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; } +//_____________________________________________________________________________________ +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::volume(const PVConstLink &pv) { - const GeoLogVol *lv = pv->getLogVol(); - const GeoShape *shape = lv->getShape(); - return shape->volume(); +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::inclusiveMass(const PVConstLink &pv) { - const GeoLogVol *lv = pv->getLogVol(); - const GeoMaterial *material = lv->getMaterial(); - double density = material->getDensity(); +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 mass = exclusiveMass(pv); - 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::volume(const PVConstLink& pv) { + const GeoLogVol * lv = pv->getLogVol(); + const GeoShape *shape = lv->getShape(); + return shape->volume(); } + //_____________________________________________________________________________________ -QByteArray VP1GeometrySystem::saveState() { - ensureBuildController(); +double VP1GeometrySystem::Imp::inclusiveMass(const PVConstLink& pv) { - VP1Serialise serialise(7 /*version*/, this); - serialise.save(IVP13DSystemSimple::saveState()); + const GeoLogVol* lv = pv->getLogVol(); + const GeoMaterial *material = lv->getMaterial(); + double density = material->getDensity(); - // Controller: - serialise.save(m_d->controller->saveSettings()); + double mass = exclusiveMass(pv); - // 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()); + 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. } - 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()); + else { + double delta = inclusiveMass(av.getVolume()) - (volume(av.getVolume())*density); + mass += delta; } - serialise.save(topvolstates); + av.next(); + } + return mass; +} - 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+ +//_____________________________________________________________________________________ +QByteArray VP1GeometrySystem::saveState() { - serialise.disableUnsavedChecks(); // We do the testing in the controller - return serialise.result(); + 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(); } //_____________________________________________________________________________________ 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); - } + 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()); + } - // 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 - 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(); - 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::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); } //_____________________________________________________________________________________ -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; - +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 { 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 { - 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); - } - } - - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); - } - } -} - -//_____________________________________________________________________________________ -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; - } + deselectAll(); - 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; - } + for (unsigned i = 0; i<roothandles.size();++i) { + it = roothandles.at(i).first; + itE = roothandles.at(i).second; + bool matchFound = false; - // 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; + 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); + } } - // 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); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); + m_d->phisectormanager->largeChangesEnd(); + if (save) { + m_d->sceneroot->enableNotify(true); + m_d->sceneroot->touch(); } + } } //_____________________________________________________________________________________ -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::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); + } } + //_____________________________________________________________________________________ -void VP1GeometrySystem::volumeResetRequested(VolumeHandle *vh) { - if (!vh) return; - deselectAll(); - vh->reset(); - 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::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::volumeResetRequested(VolumeHandle*vh) +{ + if (!vh) + return; + deselectAll(); + vh->reset(); + m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); } + //_____________________________________________________________________________________ -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; - } - } +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); +} - 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; - } +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); +} - 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); - } - - } // 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)); +//_____________________________________________________________________________________ +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); } - } - VP1Msg::messageDebug("largeChangesEnding..."); - m_d->phisectormanager->updateRepresentationsOfVolsAroundZAxis(); - m_d->phisectormanager->largeChangesEnd(); - if (save) { - m_d->sceneroot->enableNotify(true); - m_d->sceneroot->touch(); - } + } // 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 - } - } - } // 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); - } + if(handle->state()!=VP1GeoFlags::CONTRACTED) { + VP1Msg::messageDebug2("resetView --> contracting it"); + handle->setState(VP1GeoFlags::CONTRACTED); // open the volume to show its children + } } - } - - 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(); + } } +