Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4tgbVolume implementation << 27 // 26 // 28 // Author: P.Arce, CIEMAT (November 2007) << 27 // 29 // ------------------------------------------- << 28 // class G4tgbVolume 30 29 31 #include "G4tgbVolume.hh" << 30 // History: >> 31 // - Created. P.Arce, CIEMAT (November 2007) >> 32 // ------------------------------------------------------------------------- 32 33 >> 34 #include "G4tgbVolume.hh" 33 #include "G4tgbVolumeMgr.hh" 35 #include "G4tgbVolumeMgr.hh" 34 #include "G4tgbMaterialMgr.hh" 36 #include "G4tgbMaterialMgr.hh" 35 #include "G4tgbRotationMatrixMgr.hh" 37 #include "G4tgbRotationMatrixMgr.hh" 36 #include "G4tgbPlaceParamLinear.hh" 38 #include "G4tgbPlaceParamLinear.hh" 37 #include "G4tgbPlaceParamSquare.hh" 39 #include "G4tgbPlaceParamSquare.hh" 38 #include "G4tgbPlaceParamCircle.hh" 40 #include "G4tgbPlaceParamCircle.hh" 39 41 40 #include "G4tgrSolid.hh" 42 #include "G4tgrSolid.hh" 41 #include "G4tgrSolidBoolean.hh" 43 #include "G4tgrSolidBoolean.hh" 42 #include "G4tgrSolidMultiUnion.hh" << 43 #include "G4tgrSolidScaled.hh" << 44 #include "G4tgrVolume.hh" 44 #include "G4tgrVolume.hh" 45 #include "G4tgrVolumeDivision.hh" 45 #include "G4tgrVolumeDivision.hh" 46 #include "G4tgrVolumeAssembly.hh" 46 #include "G4tgrVolumeAssembly.hh" 47 #include "G4tgrVolumeMgr.hh" 47 #include "G4tgrVolumeMgr.hh" 48 #include "G4tgrPlace.hh" 48 #include "G4tgrPlace.hh" 49 #include "G4tgrPlaceSimple.hh" 49 #include "G4tgrPlaceSimple.hh" 50 #include "G4tgrPlaceDivRep.hh" 50 #include "G4tgrPlaceDivRep.hh" 51 #include "G4tgrPlaceParameterisation.hh" 51 #include "G4tgrPlaceParameterisation.hh" 52 #include "G4tgrUtils.hh" 52 #include "G4tgrUtils.hh" 53 53 54 #include "G4VSolid.hh" 54 #include "G4VSolid.hh" 55 #include "G4UnionSolid.hh" 55 #include "G4UnionSolid.hh" 56 #include "G4SubtractionSolid.hh" 56 #include "G4SubtractionSolid.hh" 57 #include "G4IntersectionSolid.hh" 57 #include "G4IntersectionSolid.hh" 58 #include "G4MultiUnion.hh" << 59 #include "G4ScaledSolid.hh" << 60 #include "G4LogicalVolume.hh" 58 #include "G4LogicalVolume.hh" 61 #include "G4VPhysicalVolume.hh" 59 #include "G4VPhysicalVolume.hh" 62 #include "G4PVPlacement.hh" 60 #include "G4PVPlacement.hh" 63 #include "G4PVDivision.hh" 61 #include "G4PVDivision.hh" 64 #include "G4PVReplica.hh" 62 #include "G4PVReplica.hh" 65 #include "G4PVParameterised.hh" 63 #include "G4PVParameterised.hh" 66 #include "G4Box.hh" 64 #include "G4Box.hh" 67 #include "G4Tubs.hh" 65 #include "G4Tubs.hh" 68 #include "G4Cons.hh" 66 #include "G4Cons.hh" 69 #include "G4Trap.hh" 67 #include "G4Trap.hh" 70 #include "G4Sphere.hh" 68 #include "G4Sphere.hh" 71 #include "G4Orb.hh" 69 #include "G4Orb.hh" 72 #include "G4Trd.hh" 70 #include "G4Trd.hh" 73 #include "G4Para.hh" 71 #include "G4Para.hh" 74 #include "G4Torus.hh" 72 #include "G4Torus.hh" 75 #include "G4Hype.hh" 73 #include "G4Hype.hh" 76 #include "G4Polycone.hh" 74 #include "G4Polycone.hh" 77 #include "G4GenericPolycone.hh" << 78 #include "G4Polyhedra.hh" 75 #include "G4Polyhedra.hh" 79 #include "G4EllipticalTube.hh" 76 #include "G4EllipticalTube.hh" 80 #include "G4Ellipsoid.hh" 77 #include "G4Ellipsoid.hh" 81 #include "G4EllipticalCone.hh" 78 #include "G4EllipticalCone.hh" 82 #include "G4Hype.hh" 79 #include "G4Hype.hh" 83 #include "G4Tet.hh" 80 #include "G4Tet.hh" 84 #include "G4TwistedBox.hh" 81 #include "G4TwistedBox.hh" 85 #include "G4TwistedTrap.hh" 82 #include "G4TwistedTrap.hh" 86 #include "G4TwistedTrd.hh" 83 #include "G4TwistedTrd.hh" 87 #include "G4TwistedTubs.hh" 84 #include "G4TwistedTubs.hh" 88 #include "G4AssemblyVolume.hh" 85 #include "G4AssemblyVolume.hh" >> 86 #include "G4BREPSolidBox.hh" >> 87 #include "G4BREPSolidCylinder.hh" >> 88 #include "G4BREPSolidCone.hh" >> 89 #include "G4BREPSolidSphere.hh" >> 90 #include "G4BREPSolidTorus.hh" >> 91 #include "G4BREPSolidPCone.hh" >> 92 #include "G4BREPSolidPolyhedra.hh" >> 93 #include "G4BREPSolidOpenPCone.hh" 89 #include "G4TessellatedSolid.hh" 94 #include "G4TessellatedSolid.hh" 90 #include "G4TriangularFacet.hh" 95 #include "G4TriangularFacet.hh" 91 #include "G4QuadrangularFacet.hh" 96 #include "G4QuadrangularFacet.hh" 92 #include "G4ExtrudedSolid.hh" 97 #include "G4ExtrudedSolid.hh" 93 98 94 #include "G4VisExtent.hh" 99 #include "G4VisExtent.hh" 95 #include "G4Material.hh" 100 #include "G4Material.hh" 96 #include "G4RotationMatrix.hh" 101 #include "G4RotationMatrix.hh" 97 #include "G4ReflectionFactory.hh" 102 #include "G4ReflectionFactory.hh" 98 103 99 #include "G4VisAttributes.hh" 104 #include "G4VisAttributes.hh" 100 #include "G4RegionStore.hh" 105 #include "G4RegionStore.hh" 101 #include "G4tgrMessenger.hh" 106 #include "G4tgrMessenger.hh" 102 #include "G4UIcommand.hh" 107 #include "G4UIcommand.hh" 103 #include "G4GeometryTolerance.hh" 108 #include "G4GeometryTolerance.hh" 104 109 105 #include "G4PhysicalConstants.hh" << 110 //------------------------------------------------------------------- 106 #include "G4SystemOfUnits.hh" << 107 << 108 // ------------------------------------------- << 109 G4tgbVolume::G4tgbVolume() 111 G4tgbVolume::G4tgbVolume() 110 { 112 { 111 } 113 } 112 114 113 // ------------------------------------------- << 115 >> 116 //------------------------------------------------------------------- 114 G4tgbVolume::~G4tgbVolume() 117 G4tgbVolume::~G4tgbVolume() 115 { 118 { 116 } 119 } 117 120 118 // ------------------------------------------- << 121 119 G4tgbVolume::G4tgbVolume(G4tgrVolume* vol) << 122 //------------------------------------------------------------------- >> 123 G4tgbVolume::G4tgbVolume( G4tgrVolume* vol) 120 { 124 { 121 theTgrVolume = vol; 125 theTgrVolume = vol; >> 126 theG4AssemblyVolume = 0; 122 } 127 } 123 128 124 // ------------------------------------------- << 129 125 void G4tgbVolume::ConstructG4Volumes(const G4t << 130 //------------------------------------------------------------------- 126 const G4L << 131 void G4tgbVolume::ConstructG4Volumes( const G4tgrPlace* place, >> 132 const G4LogicalVolume* parentLV ) 127 { 133 { 128 #ifdef G4VERBOSE 134 #ifdef G4VERBOSE 129 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 135 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 130 { 136 { 131 G4cout << G4endl << "@@@ G4tgbVolume::Cons << 137 G4cout << G4endl << "@@@ G4tgbVolume::ConstructG4Volumes - " << GetName() << G4endl; 132 << G4endl; << 138 if( place && parentLV ) G4cout << " place in LV " << parentLV->GetName() << G4endl; 133 if(place && parentLV) << 134 G4cout << " place in LV " << parentLV- << 135 } 139 } 136 #endif 140 #endif 137 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeMgr: << 141 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeMgr::GetInstance(); 138 G4LogicalVolume* logvol = g4vmgr->FindG4L << 142 G4LogicalVolume* logvol = g4vmgr->FindG4LogVol( GetName() ); 139 G4bool bFirstCopy = false; << 143 G4bool bFirstCopy = false; 140 G4VPhysicalVolume* physvol = nullptr; << 144 if( (logvol == 0) ) 141 if(logvol == nullptr) << 142 { 145 { 143 bFirstCopy = true; 146 bFirstCopy = true; 144 if(theTgrVolume->GetType() != "VOLDivision << 147 if( theTgrVolume->GetType() != "VOLDivision" ) 145 { 148 { 146 //--- If first time build solid and LogV 149 //--- If first time build solid and LogVol 147 G4VSolid* solid = FindOrConstructG4Solid << 150 G4VSolid* solid = FindOrConstructG4Solid( theTgrVolume->GetSolid() ); 148 if(solid != nullptr) // for G4AssemblyV << 151 if( solid != 0 ) // for G4AssemblyVolume it is 0 149 { 152 { 150 g4vmgr->RegisterMe(solid); << 153 g4vmgr->RegisterMe( solid ); 151 logvol = ConstructG4LogVol(solid); << 154 logvol = ConstructG4LogVol( solid ); 152 g4vmgr->RegisterMe(logvol); << 155 g4vmgr->RegisterMe( logvol ); 153 g4vmgr->RegisterChildParentLVs(logvol, << 156 g4vmgr->RegisterChildParentLVs( logvol, parentLV ); >> 157 154 } 158 } 155 } << 159 } 156 else << 160 } 157 { << 158 return; << 159 } << 160 } << 161 //--- Construct PhysVol 161 //--- Construct PhysVol 162 physvol = ConstructG4PhysVol(place, logvol, << 162 G4VPhysicalVolume* physvol = ConstructG4PhysVol( place, logvol, parentLV ); 163 << 163 if( physvol != 0 ) // 0 for G4AssemblyVolumes 164 if(physvol != nullptr) // nullptr for G4Ass << 165 { 164 { 166 g4vmgr->RegisterMe(physvol); << 165 g4vmgr->RegisterMe( physvol ); 167 166 168 if(logvol == nullptr) // case of division << 167 if( logvol == 0 ) // case of divisions 169 { 168 { 170 logvol = physvol->GetLogicalVolume(); 169 logvol = physvol->GetLogicalVolume(); 171 } 170 } 172 } 171 } 173 else << 172 else 174 { 173 { 175 return; 174 return; 176 } 175 } 177 176 178 //--- If first copy build children placement 177 //--- If first copy build children placements in this LogVol 179 if(bFirstCopy) 178 if(bFirstCopy) 180 { 179 { 181 std::pair<G4mmapspl::iterator, G4mmapspl:: << 180 std::pair<G4mmapspl::iterator, G4mmapspl::iterator> children 182 G4tgrVolumeMgr::GetInstance()->GetChildr << 181 = G4tgrVolumeMgr::GetInstance()->GetChildren( GetName() ); 183 for(auto cite = children.first; cite != ch << 182 G4mmapspl::iterator cite; >> 183 for( cite = children.first; cite != children.second; cite++ ) 184 { 184 { 185 //----- Call G4tgrPlace ->constructG4Vol << 185 //----- Call G4tgrPlace ->constructG4Volumes 186 //---- find G4tgbVolume corresponding to 186 //---- find G4tgbVolume corresponding to the G4tgrVolume 187 // pointed by G4tgrPlace 187 // pointed by G4tgrPlace 188 G4tgrPlace* pl = const_cast<G4tgrPlac << 188 G4tgrPlace* pl = const_cast<G4tgrPlace*>((*cite).second); 189 G4tgbVolume* svol = g4vmgr->FindVolume(p << 189 G4tgbVolume* svol = g4vmgr->FindVolume( pl->GetVolume()->GetName() ); 190 //--- find copyNo 190 //--- find copyNo 191 #ifdef G4VERBOSE 191 #ifdef G4VERBOSE 192 if(G4tgrMessenger::GetVerboseLevel() >= << 192 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 193 { 193 { 194 G4cout << " G4tgbVolume::ConstructG4Vo << 194 G4cout << " G4tgbVolume::ConstructG4Volumes - construct daughter " << pl->GetVolume()->GetName() << " # " << pl->GetCopyNo() << G4endl; 195 << pl->GetVolume()->GetName() < << 196 << G4endl; << 197 } 195 } 198 #endif 196 #endif 199 svol->ConstructG4Volumes(pl, logvol); << 197 svol->ConstructG4Volumes( pl, logvol ); 200 } 198 } 201 } 199 } >> 200 202 } 201 } 203 202 204 // ------------------------------------------- << 203 205 G4VSolid* G4tgbVolume::FindOrConstructG4Solid( << 204 >> 205 //------------------------------------------------------------------- >> 206 G4VSolid* G4tgbVolume::FindOrConstructG4Solid( const G4tgrSolid* sol ) 206 { 207 { 207 G4double angularTolerance = << 208 G4double angularTolerance = G4GeometryTolerance::GetInstance() 208 G4GeometryTolerance::GetInstance()->GetAng << 209 ->GetAngularTolerance(); 209 210 210 if(sol == nullptr) << 211 if( sol == 0 ) { return 0; } 211 { << 212 return nullptr; << 213 } << 214 212 215 #ifdef G4VERBOSE 213 #ifdef G4VERBOSE 216 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 214 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 217 { 215 { 218 G4cout << " G4tgbVolume::FindOrConstructG4 216 G4cout << " G4tgbVolume::FindOrConstructG4Solid():" << G4endl 219 << " SOLID = " << sol << G4endl < << 217 << " SOLID = " << sol << G4endl 220 << " of type " << sol->GetType() << << 218 << " " << sol->GetName() << " of type " << sol->GetType() >> 219 << G4endl; 221 } 220 } 222 #endif << 221 #endif 223 222 224 //----- Check if solid exists already 223 //----- Check if solid exists already 225 G4VSolid* solid = G4tgbVolumeMgr::GetInstanc << 224 G4VSolid* solid = G4tgbVolumeMgr::GetInstance() 226 if(solid != nullptr) << 225 ->FindG4Solid( sol->GetName() ); 227 { << 226 if( solid ) { return solid; } 228 return solid; << 229 } << 230 227 231 // Give 'sol' as Boolean solids needs to cal 228 // Give 'sol' as Boolean solids needs to call this method twice 232 229 233 #ifdef G4VERBOSE 230 #ifdef G4VERBOSE 234 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 231 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 235 { 232 { 236 G4cout << " G4tgbVolume::FindOrConstructG4 233 G4cout << " G4tgbVolume::FindOrConstructG4Solid() - " 237 << sol->GetSolidParams().size() << 234 << sol->GetSolidParams().size() << G4endl; 238 } 235 } 239 #endif 236 #endif 240 << 237 241 std::vector<G4double> solParam; 238 std::vector<G4double> solParam; 242 239 243 // In case of BOOLEAN solids, solidParams ar 240 // In case of BOOLEAN solids, solidParams are taken from components 244 241 245 if(sol->GetSolidParams().size() == 1) << 242 if( sol->GetSolidParams().size() == 1) 246 { << 243 { 247 solParam = *sol->GetSolidParams()[0]; << 244 solParam = * sol->GetSolidParams()[ 0 ]; 248 } 245 } 249 246 250 //----------- instantiate the appropiate G4V 247 //----------- instantiate the appropiate G4VSolid type 251 G4String stype = sol->GetType(); 248 G4String stype = sol->GetType(); 252 G4String sname = sol->GetName(); 249 G4String sname = sol->GetName(); 253 250 254 if(stype == "BOX") << 251 if( stype == "BOX" ) 255 { 252 { 256 CheckNoSolidParams(stype, 3, (G4int)solPar << 253 CheckNoSolidParams( stype, 3, solParam.size() ); 257 solid = new G4Box(sname, solParam[0], solP << 254 solid = new G4Box( sname, solParam[0], solParam[1], solParam[2] ); >> 255 258 } 256 } 259 else if(stype == "TUBE") << 257 else if( stype == "TUBE" ) 260 { 258 { 261 CheckNoSolidParams(stype, 3, (G4int)solPar << 259 CheckNoSolidParams( stype, 3, solParam.size() ); 262 solid = new G4Tubs(sname, solParam[0], sol << 260 solid = new G4Tubs( sname, solParam[0], solParam[1], solParam[2], 263 360. * deg); << 261 0.*deg, 360.*deg ); 264 } 262 } 265 else if(stype == "TUBS") << 263 else if( stype == "TUBS" ) 266 { 264 { 267 CheckNoSolidParams(stype, 5, (G4int)solPar << 265 CheckNoSolidParams( stype, 5, solParam.size() ); 268 G4double phiDelta = solParam[4]; 266 G4double phiDelta = solParam[4]; 269 if(std::fabs(phiDelta - twopi) < angularTo << 267 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; } 270 { << 268 solid = new G4Tubs( sname, solParam[0], solParam[1], solParam[2], 271 phiDelta = twopi; << 269 solParam[3], phiDelta ); 272 } << 273 solid = new G4Tubs(sname, solParam[0], sol << 274 solParam[3], phiDelta); << 275 } 270 } 276 else if(stype == "TRAP") << 271 else if( stype == "TRAP" ) 277 { 272 { 278 if(solParam.size() == 11) << 273 if( solParam.size() == 11 ) 279 { 274 { 280 solid = new G4Trap(sname, solParam[0], s << 275 solid = new G4Trap( sname, solParam[0], solParam[1], solParam[2], 281 solParam[3], solParam << 276 solParam[3], solParam[4], solParam[5], solParam[6], 282 solParam[7], solParam << 277 solParam[7], solParam[8], solParam[9], solParam[10] ); 283 } 278 } 284 else if(solParam.size() == 4) << 279 else if( solParam.size() == 4 ) 285 { 280 { 286 solid = new G4Trap(sname, solParam[0], s << 281 solid = new G4Trap( sname, solParam[0], solParam[1]/deg, 287 solParam[2] / deg, so << 282 solParam[2]/deg, solParam[3]); 288 } 283 } 289 else 284 else 290 { 285 { 291 G4String ErrMessage1 = "Solid type " + s 286 G4String ErrMessage1 = "Solid type " + stype; 292 G4String ErrMessage2 = " should have 11 287 G4String ErrMessage2 = " should have 11 or 4 parameters,\n"; 293 G4String ErrMessage3 = << 288 G4String ErrMessage3 = "and it has " 294 "and it has " + G4UIcommand::ConvertTo << 289 + G4UIcommand::ConvertToString(G4int(solParam.size())); 295 G4String ErrMessage = ErrMessage1 + ErrM 290 G4String ErrMessage = ErrMessage1 + ErrMessage2 + ErrMessage3 + " !"; 296 G4Exception("G4tgbVolume::FindOrConstruc << 291 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", 297 FatalException, ErrMessage); << 292 "InvalidSetup", FatalException, ErrMessage); 298 return 0; << 299 } 293 } >> 294 300 } 295 } 301 else if(stype == "TRD") << 296 else if( stype == "TRD" ) 302 { 297 { 303 CheckNoSolidParams(stype, 5, (G4int)solPar << 298 CheckNoSolidParams( stype, 5, solParam.size() ); 304 solid = new G4Trd(sname, solParam[0], solP << 299 solid = new G4Trd( sname, solParam[0], solParam[1], solParam[2], 305 solParam[4]); << 300 solParam[3], solParam[4] ); 306 } 301 } 307 else if(stype == "PARA") << 302 else if( stype == "PARA" ) 308 { 303 { 309 CheckNoSolidParams(stype, 6, (G4int)solPar << 304 CheckNoSolidParams( stype, 6, solParam.size() ); 310 solid = new G4Para(sname, solParam[0], sol << 305 solid = new G4Para( sname, solParam[0], solParam[1], solParam[2], 311 solParam[3], solParam[4 << 306 solParam[3], solParam[4], solParam[5] ); 312 } 307 } 313 else if(stype == "CONE") << 308 else if( stype == "CONE" ) 314 { 309 { 315 CheckNoSolidParams(stype, 5, (G4int)solPar << 310 CheckNoSolidParams( stype, 5, solParam.size() ); 316 solid = new G4Cons(sname, solParam[0], sol << 311 solid = new G4Cons( sname, solParam[0], solParam[1], solParam[2], 317 solParam[3], solParam[4 << 312 solParam[3], solParam[4], 0., 360.*deg); 318 } 313 } 319 else if(stype == "CONS") << 314 else if( stype == "CONS" ) 320 { 315 { 321 CheckNoSolidParams(stype, 7, (G4int)solPar << 316 CheckNoSolidParams( stype, 7, solParam.size() ); 322 G4double phiDelta = solParam[6]; 317 G4double phiDelta = solParam[6]; 323 if(std::fabs(phiDelta - twopi) < angularTo << 318 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; } 324 { << 319 solid = new G4Cons( sname, solParam[0], solParam[1], solParam[2], 325 phiDelta = twopi; << 320 solParam[3], solParam[4], solParam[5], phiDelta); 326 } << 327 solid = new G4Cons(sname, solParam[0], sol << 328 solParam[3], solParam[4 << 329 } 321 } 330 else if(stype == "SPHERE") << 322 else if( stype == "SPHERE" ) 331 { 323 { 332 CheckNoSolidParams(stype, 6, (G4int)solPar << 324 CheckNoSolidParams( stype, 6, solParam.size() ); 333 G4double phiDelta = solParam[3]; 325 G4double phiDelta = solParam[3]; 334 if(std::fabs(phiDelta - twopi) < angularTo << 326 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; } 335 { << 336 phiDelta = twopi; << 337 } << 338 G4double thetaDelta = solParam[5]; 327 G4double thetaDelta = solParam[5]; 339 if(std::fabs(thetaDelta - pi) < angularTol << 328 if( std::fabs(thetaDelta - pi) < angularTolerance ) { thetaDelta = pi; } 340 { << 329 solid = new G4Sphere( sname, solParam[0], solParam[1], solParam[2], 341 thetaDelta = pi; << 330 phiDelta, solParam[4], thetaDelta); 342 } << 343 solid = new G4Sphere(sname, solParam[0], s << 344 solParam[4], thetaDel << 345 } 331 } 346 else if(stype == "ORB") << 332 else if( stype == "ORB" ) 347 { 333 { 348 CheckNoSolidParams(stype, 1, (G4int)solPar << 334 CheckNoSolidParams( stype, 1, solParam.size() ); 349 solid = new G4Orb(sname, solParam[0]); << 335 solid = new G4Orb( sname, solParam[0] ); 350 } 336 } 351 else if(stype == "TORUS") << 337 else if( stype == "TORUS" ) 352 { 338 { 353 CheckNoSolidParams(stype, 5, (G4int)solPar << 339 CheckNoSolidParams( stype, 5, solParam.size() ); 354 G4double phiDelta = solParam[4]; 340 G4double phiDelta = solParam[4]; 355 if(std::fabs(phiDelta - twopi) < angularTo << 341 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; } 356 { << 342 solid = new G4Torus( sname, solParam[0], solParam[1], solParam[2], 357 phiDelta = twopi; << 343 solParam[3], phiDelta ); 358 } << 359 solid = new G4Torus(sname, solParam[0], so << 360 solParam[3], phiDelta) << 361 } 344 } 362 else if(stype == "POLYCONE" << 345 else if( stype == "POLYCONE" ) 363 || stype == "GENERICPOLYCONE") << 364 { 346 { 365 std::size_t nplanes = std::size_t(solParam << 347 size_t nplanes = size_t(solParam[2]); 366 G4bool genericPoly = false; 348 G4bool genericPoly = false; 367 if(solParam.size() == 3 + nplanes * 3) << 349 if( solParam.size() == 3+nplanes*3 ) 368 { << 350 { 369 genericPoly = false; << 370 } << 371 else if(solParam.size() == 3 + nplanes * 2 << 372 { << 373 genericPoly = true; 351 genericPoly = true; 374 } 352 } >> 353 else if( solParam.size() == 3+nplanes*2 ) >> 354 { >> 355 genericPoly = false; >> 356 } 375 else 357 else 376 { 358 { 377 G4String Err1 = "Solid type " + stype + 359 G4String Err1 = "Solid type " + stype + " should have "; 378 G4String Err2 = G4UIcommand::ConvertToSt << 360 G4String Err2 = G4UIcommand::ConvertToString(G4int(3+nplanes*3)) 379 " (Z,Rmin,Rmax)\n"; << 361 + " (Z,Rmin,Rmax)\n"; 380 G4String Err3 = << 362 G4String Err3 = "or " + G4UIcommand::ConvertToString(G4int(3+nplanes*2)); 381 "or " + G4UIcommand::ConvertToString(G << 382 G4String Err4 = " (RZ corners) parameter 363 G4String Err4 = " (RZ corners) parameters,\n"; 383 G4String Err5 = << 364 G4String Err5 = "and it has " 384 "and it has " + G4UIcommand::ConvertTo << 365 + G4UIcommand::ConvertToString(G4int(solParam.size())); 385 G4String ErrMessage = Err1 + Err2 + Err3 366 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 + " !"; 386 G4Exception("G4tgbVolume::FindOrConstruc << 367 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", 387 FatalException, ErrMessage); << 368 "InvalidSetup", FatalException, ErrMessage); 388 return nullptr; << 389 } 369 } 390 370 391 if(!genericPoly) << 371 if( genericPoly ) 392 { 372 { 393 std::vector<G4double>* z_p = new std: << 373 std::vector<G4double>* z_p = new std::vector<G4double>; 394 std::vector<G4double>* rmin_p = new std: 374 std::vector<G4double>* rmin_p = new std::vector<G4double>; 395 std::vector<G4double>* rmax_p = new std: 375 std::vector<G4double>* rmax_p = new std::vector<G4double>; 396 for(std::size_t ii = 0; ii < nplanes; ++ << 376 for( size_t ii = 0; ii < nplanes; ii++ ) 397 { 377 { 398 (*z_p).push_back(solParam[3 + 3 * ii]) << 378 (*z_p).push_back( solParam[3+3*ii] ); 399 (*rmin_p).push_back(solParam[3 + 3 * i << 379 (*rmin_p).push_back( solParam[3+3*ii+1] ); 400 (*rmax_p).push_back(solParam[3 + 3 * i << 380 (*rmax_p).push_back( solParam[3+3*ii+2] ); 401 } 381 } 402 G4double phiTotal = solParam[1]; 382 G4double phiTotal = solParam[1]; 403 if(std::fabs(phiTotal - twopi) < angular << 383 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 404 { << 384 solid = new G4Polycone( sname, solParam[0], phiTotal, // start,delta-phi 405 phiTotal = twopi; << 385 nplanes, // sections 406 } << 386 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0])); 407 solid = new G4Polycone(sname, solParam[0 << 408 (G4int)nplanes, << 409 &((*z_p)[0]), &(( << 410 } 387 } 411 else 388 else 412 { 389 { 413 std::vector<G4double>* R_c = new std::ve 390 std::vector<G4double>* R_c = new std::vector<G4double>; 414 std::vector<G4double>* Z_c = new std::ve 391 std::vector<G4double>* Z_c = new std::vector<G4double>; 415 for(size_t ii = 0; ii < nplanes; ii++) << 392 for( size_t ii = 0; ii < nplanes; ii++ ) 416 { 393 { 417 (*R_c).push_back(solParam[3 + 2 * ii]) << 394 (*R_c).push_back( solParam[3+2*ii] ); 418 (*Z_c).push_back(solParam[3 + 2 * ii + << 395 (*Z_c).push_back( solParam[3+2*ii+1] ); 419 } 396 } 420 G4double phiTotal = solParam[1]; 397 G4double phiTotal = solParam[1]; 421 if(std::fabs(phiTotal - twopi) < angular << 398 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 422 { << 399 solid = new G4Polycone( sname, solParam[0], phiTotal, // start,delta-phi 423 phiTotal = twopi; << 400 nplanes, // sections 424 } << 425 solid = << 426 new G4GenericPolycone(sname, solParam[ << 427 (G4int)nplanes, << 428 &((*R_c)[0]), &( 401 &((*R_c)[0]), &((*Z_c)[0])); 429 } 402 } >> 403 430 } 404 } 431 else if(stype == "POLYHEDRA") << 405 else if( stype == "POLYHEDRA" ) 432 { 406 { 433 std::size_t nplanes = std::size_t(solParam << 407 size_t nplanes = size_t(solParam[3]); 434 G4bool genericPoly = false; 408 G4bool genericPoly = false; 435 if(solParam.size() == 4 + nplanes * 3) << 409 if( solParam.size() == 4+nplanes*3 ) 436 { << 410 { 437 genericPoly = false; << 438 } << 439 else if(solParam.size() == 4 + nplanes * 2 << 440 { << 441 genericPoly = true; 411 genericPoly = true; 442 } 412 } >> 413 else if( solParam.size() == 4+nplanes*2 ) >> 414 { >> 415 genericPoly = false; >> 416 } 443 else 417 else 444 { 418 { 445 G4String Err1 = "Solid type " + stype + 419 G4String Err1 = "Solid type " + stype + " should have "; 446 G4String Err2 = G4UIcommand::ConvertToSt << 420 G4String Err2 = G4UIcommand::ConvertToString(G4int(4+nplanes*3)) 447 " (Z,Rmin,Rmax)\n"; << 421 + " (Z,Rmin,Rmax)\n"; 448 G4String Err3 = << 422 G4String Err3 = "or " + G4UIcommand::ConvertToString(G4int(4+nplanes*2)); 449 "or " + G4UIcommand::ConvertToString(G << 450 G4String Err4 = " (RZ corners) parameter 423 G4String Err4 = " (RZ corners) parameters,\n"; 451 G4String Err5 = << 424 G4String Err5 = "and it has " 452 "and it has " + G4UIcommand::ConvertTo << 425 + G4UIcommand::ConvertToString(G4int(solParam.size())); 453 G4String ErrMessage = Err1 + Err2 + Err3 426 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 + " !"; 454 G4Exception("G4tgbVolume::FindOrConstruc << 427 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", 455 FatalException, ErrMessage); << 428 "InvalidSetup", FatalException, ErrMessage); 456 return nullptr; << 457 } 429 } 458 << 430 459 if(!genericPoly) << 431 if( genericPoly ) 460 { 432 { 461 std::vector<G4double>* z_p = new std: << 433 std::vector<G4double>* z_p = new std::vector<G4double>; 462 std::vector<G4double>* rmin_p = new std: 434 std::vector<G4double>* rmin_p = new std::vector<G4double>; 463 std::vector<G4double>* rmax_p = new std: 435 std::vector<G4double>* rmax_p = new std::vector<G4double>; 464 for(std::size_t ii = 0; ii < nplanes; ++ << 436 for( size_t ii = 0; ii < nplanes; ii++ ) 465 { 437 { 466 (*z_p).push_back(solParam[4 + 3 * ii]) << 438 (*z_p).push_back( solParam[4+3*ii] ); 467 (*rmin_p).push_back(solParam[4 + 3 * i << 439 (*rmin_p).push_back( solParam[4+3*ii+1] ); 468 (*rmax_p).push_back(solParam[4 + 3 * i << 440 (*rmax_p).push_back( solParam[4+3*ii+2] ); 469 } 441 } 470 G4double phiTotal = solParam[1]; 442 G4double phiTotal = solParam[1]; 471 if(std::fabs(phiTotal - twopi) < angular << 443 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 472 { << 444 solid = new G4Polyhedra( sname, solParam[0], phiTotal, 473 phiTotal = twopi; << 445 G4int(solParam[2]), nplanes, 474 } << 446 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0])); 475 solid = new G4Polyhedra(sname, solParam[ << 476 (G4int)nplanes, << 477 &((*rmax_p)[0])) << 478 } 447 } 479 else 448 else 480 { 449 { 481 std::vector<G4double>* R_c = new std::ve 450 std::vector<G4double>* R_c = new std::vector<G4double>; 482 std::vector<G4double>* Z_c = new std::ve 451 std::vector<G4double>* Z_c = new std::vector<G4double>; 483 for(std::size_t ii = 0; ii < nplanes; ++ << 452 for( size_t ii = 0; ii < nplanes; ii++ ) 484 { 453 { 485 (*R_c).push_back(solParam[4 + 2 * ii]) << 454 (*R_c).push_back( solParam[4+2*ii] ); 486 (*Z_c).push_back(solParam[4 + 2 * ii + << 455 (*Z_c).push_back( solParam[4+2*ii+1] ); 487 } 456 } 488 G4double phiTotal = solParam[1]; 457 G4double phiTotal = solParam[1]; 489 if(std::fabs(phiTotal - twopi) < angular << 458 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 490 { << 459 solid = new G4Polyhedra( sname, solParam[0], phiTotal, 491 phiTotal = twopi; << 460 G4int(solParam[2]), nplanes, 492 } << 461 &((*R_c)[0]), &((*Z_c)[0])); 493 solid = new G4Polyhedra(sname, solParam[ << 494 (G4int)nplanes, << 495 } 462 } 496 } 463 } 497 else if(stype == "ELLIPTICALTUBE") << 464 else if( stype == "ELLIPTICALTUBE" ) 498 { 465 { 499 CheckNoSolidParams(stype, 3, (G4int)solPar << 466 CheckNoSolidParams( stype, 3, solParam.size() ); 500 solid = new G4EllipticalTube(sname, solPar << 467 solid = new G4EllipticalTube( sname, solParam[0], solParam[1], solParam[2]); 501 } 468 } 502 else if(stype == "ELLIPSOID") << 469 else if( stype == "ELLIPSOID" ) 503 { 470 { 504 CheckNoSolidParams(stype, 5, (G4int)solPar << 471 CheckNoSolidParams( stype, 5, solParam.size() ); 505 solid = new G4Ellipsoid(sname, solParam[0] << 472 solid = new G4Ellipsoid( sname, solParam[0], solParam[1], solParam[2], 506 solParam[3], solPa << 473 solParam[3], solParam[4] ); 507 } 474 } 508 else if(stype == "ELLIPTICALCONE") << 475 else if( stype == "ELLIPTICALCONE" ) 509 { 476 { 510 CheckNoSolidParams(stype, 4, (G4int)solPar << 477 CheckNoSolidParams( stype, 4, solParam.size() ); 511 solid = new G4EllipticalCone(sname, solPar << 478 solid = new G4EllipticalCone( sname, solParam[0], solParam[1], 512 solParam[3]); << 479 solParam[2], solParam[3] ); 513 } 480 } 514 else if(stype == "HYPE") << 481 else if( stype == "HYPE" ) 515 { 482 { 516 CheckNoSolidParams(stype, 5, (G4int)solPar << 483 CheckNoSolidParams( stype, 5, solParam.size() ); 517 solid = new G4Hype(sname, solParam[0], sol << 484 solid = new G4Hype( sname, solParam[0], solParam[1], solParam[2], 518 solParam[3], solParam[4 << 485 solParam[3], solParam[4] ); 519 } 486 } 520 else if(stype == "TET") << 487 else if( stype == "TET" ) 521 { 488 { 522 CheckNoSolidParams(stype, 12, (G4int)solPa << 489 CheckNoSolidParams( stype, 12, solParam.size() ); 523 G4ThreeVector anchor(solParam[0], solParam 490 G4ThreeVector anchor(solParam[0], solParam[1], solParam[2]); 524 G4ThreeVector p2(solParam[3], solParam[4], 491 G4ThreeVector p2(solParam[3], solParam[4], solParam[5]); 525 G4ThreeVector p3(solParam[6], solParam[7], 492 G4ThreeVector p3(solParam[6], solParam[7], solParam[8]); 526 G4ThreeVector p4(solParam[9], solParam[10] 493 G4ThreeVector p4(solParam[9], solParam[10], solParam[11]); 527 solid = new G4Tet(sname, anchor, p2, p3, p << 494 solid = new G4Tet( sname, anchor, p2, p3, p4 ); 528 } 495 } 529 else if(stype == "TWISTEDBOX") << 496 else if( stype == "TWISTEDBOX" ) 530 { 497 { 531 CheckNoSolidParams(stype, 4, (G4int)solPar << 498 CheckNoSolidParams( stype, 4, solParam.size() ); 532 solid = new G4TwistedBox(sname, solParam[0 << 499 solid = new G4TwistedBox( sname, solParam[0], solParam[1], 533 solParam[3]); << 500 solParam[2], solParam[3]); 534 } 501 } 535 else if(stype == "TWISTEDTRAP") << 502 else if( stype == "TWISTEDTRAP" ) 536 { 503 { 537 CheckNoSolidParams(stype, 11, (G4int)solPa << 504 CheckNoSolidParams( stype, 11, solParam.size() ); 538 solid = << 505 solid = new G4TwistedTrap( sname, solParam[0], solParam[1], solParam[2], 539 new G4TwistedTrap(sname, solParam[0], so << 540 solParam[3], solParam[ 506 solParam[3], solParam[4], solParam[5], solParam[6], 541 solParam[7], solParam[ << 507 solParam[7], solParam[8], solParam[9], solParam[10] ); 542 } << 543 else if(stype == "TWISTEDTRD") << 544 { << 545 CheckNoSolidParams(stype, 6, (G4int)solPar << 546 solid = new G4TwistedTrd(sname, solParam[0 << 547 solParam[3], solP << 548 } 508 } 549 else if(stype == "SCALED") << 509 else if( stype == "TWISTEDTRD" ) 550 { 510 { 551 const G4tgrSolidScaled* tgrSol = dynamic_c << 511 CheckNoSolidParams( stype, 6, solParam.size() ); 552 if(tgrSol == nullptr) << 512 solid = new G4TwistedTrd( sname, solParam[0], solParam[1], solParam[2], 553 { << 513 solParam[3], solParam[4], solParam[5]); 554 G4Exception("G4tgbVolume::FindOrConstruc << 555 FatalException, "Invalid Sol << 556 return nullptr; << 557 } << 558 G4VSolid* sol0 = FindOrConstructG4Solid( << 559 G4Scale3D scale = tgrSol->GetScale3d(); << 560 solid = new G4ScaledSolid(sname, sol0, sc << 561 } 514 } 562 else if(stype == "TWISTEDTUBS") << 515 else if( stype == "TWISTEDTUBS" ) 563 { 516 { 564 CheckNoSolidParams(stype, 5, (G4int)solPar << 517 CheckNoSolidParams( stype, 5, solParam.size() ); 565 G4double phiTotal = solParam[4]; 518 G4double phiTotal = solParam[4]; 566 if(std::fabs(phiTotal - twopi) < angularTo << 519 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 567 { << 520 solid = new G4TwistedTubs( sname, solParam[0], solParam[1], solParam[2], 568 phiTotal = twopi; << 521 solParam[3], phiTotal); 569 } << 522 } 570 solid = new G4TwistedTubs(sname, solParam[ << 523 else if( stype == "BREPBOX" ) // EntityType is = "Closed_Shell" 571 solParam[3], phi << 524 { 572 } << 525 CheckNoSolidParams( stype, 24, solParam.size() ); 573 else if(stype == "TESSELLATED") << 526 std::vector<G4Point3D> points; 574 { << 527 for( size_t ii = 0; ii < 8; ii++ ) 575 G4int nFacets = G4int(solPar << 528 { 576 G4int jj = 0; << 529 points.push_back( G4Point3D(solParam[ii*3+0], 577 solid = new G4Tessel << 530 solParam[ii*3+1], 578 G4TessellatedSolid* solidTS = (G4Tessellat << 531 solParam[ii*3+2]) ); 579 G4VFacet* facet = nullptr; << 532 } 580 << 533 solid = new G4BREPSolidBox( sname, points[0], points[1], points[2], 581 for(G4int ii = 0; ii < nFacets; ++ii) << 534 points[3], points[4], points[5], points[6], 582 { << 535 points[7] ); 583 G4int nPoints = G4int(solParam[jj + 1]); << 536 } 584 if(G4int(solParam.size()) < jj + nPoints << 537 else if( stype == "BREPCYLINDER" ) // EntityType is = "Closed_Shell" 585 { << 538 { 586 G4String Err1 = "Too small number of p << 539 CheckNoSolidParams( stype, 11, solParam.size() ); 587 "it should be at least << 540 solid = new G4BREPSolidCylinder( sname, 588 G4UIcommand::ConvertTo << 541 G4ThreeVector( solParam[0], solParam[1], solParam[2] ), 589 G4String Err2 = " facet number " + G4U << 542 G4ThreeVector( solParam[3], solParam[4], solParam[5] ), 590 G4String Err3 = " number of parameters << 543 G4ThreeVector( solParam[6], solParam[7], solParam[8] ), 591 G4UIcommand::ConvertTo << 544 solParam[9], solParam[10] ); 592 G4String ErrMessage = Err1 + Err2 + Er << 545 } 593 G4Exception("G4tgbVolume::FindOrConstr << 546 else if( stype == "BREPCONE" ) // EntityType is = "Closed_Shell" 594 FatalException, ErrMessage << 547 { 595 return nullptr; << 548 CheckNoSolidParams( stype, 12, solParam.size() ); 596 } << 549 solid = new G4BREPSolidCone( sname, 597 << 550 G4ThreeVector( solParam[0], solParam[1], solParam[2] ), 598 if(nPoints == 3) << 551 G4ThreeVector( solParam[3], solParam[4], solParam[5] ), 599 { << 552 G4ThreeVector( solParam[6], solParam[7], solParam[8] ), 600 G4ThreeVector pt0(solParam[jj + 2], so << 553 solParam[9], solParam[10], solParam[11] ); 601 G4ThreeVector vt1(solParam[jj + 5], so << 554 } 602 G4ThreeVector vt2(solParam[jj + 8], so << 555 else if( stype == "BREPSPHERE" ) // EntityType is = "Closed_Shell" 603 solParam[jj + 10]); << 556 { 604 G4FacetVertexType vertexType = ABSOLUT << 557 CheckNoSolidParams( stype, 10, solParam.size() ); 605 if(solParam[jj + 11] == 0) << 558 solid = new G4BREPSolidSphere( sname, 606 { << 559 G4ThreeVector( solParam[0], solParam[1], solParam[2] ), 607 vertexType = ABSOLUTE; << 560 G4ThreeVector( solParam[3], solParam[4], solParam[5] ), 608 } << 561 G4ThreeVector( solParam[6], solParam[7], solParam[8] ), 609 else if(solParam[jj + 11] == 1) << 562 solParam[9] ); 610 { << 563 611 vertexType = RELATIVE; << 564 } 612 } << 565 else if( stype == "BREPTORUS" ) // EntityType is = "Closed_Shell" 613 else << 566 { 614 { << 567 CheckNoSolidParams( stype, 11, solParam.size() ); 615 G4String Err1 = "Wrong number of ver << 568 solid = new G4BREPSolidTorus( sname, 616 "should be 0 =ABSOLU << 569 G4ThreeVector( solParam[0], solParam[1], solParam[2] ), 617 G4String Err2 = << 570 G4ThreeVector( solParam[3], solParam[4], solParam[5] ), 618 " facet number " + G4UIcommand::Co << 571 G4ThreeVector( solParam[6], solParam[7], solParam[8] ), 619 G4String Err3 = " vertex type is " + << 572 solParam[9], solParam[10] ); 620 G4UIcommand::Convert << 573 } 621 G4String ErrMessage = Err1 + Err2 + << 574 else if( stype == "BREPPCONE" ) // EntityType is = "Closed_Shell" 622 G4Exception("G4tgbVolume::FindOrCons << 575 { 623 FatalException, ErrMessa << 576 size_t nplanes = size_t(solParam[2]); 624 return nullptr; << 577 CheckNoSolidParams( stype, 4+3*nplanes, solParam.size() ); 625 } << 578 std::vector<G4double>* z_p = new std::vector<G4double>; 626 facet = new G4TriangularFacet(pt0, vt1 << 579 std::vector<G4double>* rmin_p = new std::vector<G4double>; 627 } << 580 std::vector<G4double>* rmax_p = new std::vector<G4double>; 628 else if(nPoints == 4) << 581 for( size_t ii = 0; ii < nplanes; ii++ ) 629 { << 582 { 630 G4ThreeVector pt0(solParam[jj + 2], so << 583 (*z_p).push_back( solParam[4+3*ii] ); 631 G4ThreeVector vt1(solParam[jj + 5], so << 584 (*rmin_p).push_back( solParam[4+3*ii+1] ); 632 G4ThreeVector vt2(solParam[jj + 8], so << 585 (*rmax_p).push_back( solParam[4+3*ii+2] ); 633 solParam[jj + 10]); << 586 } 634 G4ThreeVector vt3(solParam[jj + 11], s << 587 G4double phiTotal = solParam[1]; 635 solParam[jj + 13]); << 588 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 636 G4FacetVertexType vertexType = ABSOLUT << 589 CheckNoSolidParams( stype, 12, solParam.size() ); 637 if(solParam[jj + 14] == 0) << 590 solid = new G4BREPSolidPCone( sname, solParam[0], phiTotal, // start,dph 638 { << 591 nplanes, // sections 639 vertexType = ABSOLUTE; << 592 solParam[3], // z_start 640 } << 593 &((*z_p)[0]), &((*rmin_p)[0]), 641 else if(solParam[jj + 14] == 1) << 594 &((*rmax_p)[0])); 642 { << 595 } 643 vertexType = RELATIVE; << 596 else if( stype == "BREPPOLYHEDRA" ) // EntityType is = "Closed_Shell" 644 } << 597 { 645 else << 598 size_t nplanes = size_t(solParam[3]); 646 { << 599 CheckNoSolidParams( stype, 5+3*nplanes, solParam.size() ); 647 G4String Err1 = "Wrong number of ver << 600 std::vector<G4double>* z_p = new std::vector<G4double>; 648 "should be 0 =ABSOLU << 601 std::vector<G4double>* rmin_p = new std::vector<G4double>; 649 G4String Err2 = << 602 std::vector<G4double>* rmax_p = new std::vector<G4double>; 650 " facet number " + G4UIcommand::Co << 603 for( size_t ii = 0; ii < nplanes; ii++ ) 651 G4String Err3 = " vertex type is " + << 604 { 652 G4UIcommand::Convert << 605 (*z_p).push_back( solParam[5+3*ii] ); 653 G4String ErrMessage = Err1 + Err2 + << 606 (*rmin_p).push_back( solParam[5+3*ii+1] ); 654 G4Exception("G4tgbVolume::FindOrCons << 607 (*rmax_p).push_back( solParam[5+3*ii+2] ); 655 FatalException, ErrMessa << 608 } 656 return nullptr; << 609 G4double phiTotal = solParam[1]; 657 } << 610 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } 658 facet = new G4QuadrangularFacet(pt0, v << 611 CheckNoSolidParams( stype, 12, solParam.size() ); 659 } << 612 solid = new G4BREPSolidPolyhedra( sname, solParam[0], phiTotal, // start,dph 660 else << 613 G4int(solParam[2]), // sides 661 { << 614 nplanes, // sections 662 G4String Err1 = << 615 solParam[4], // z_start 663 "Wrong number of points in tesselate << 616 &((*z_p)[0]), &((*rmin_p)[0]), 664 G4String Err2 = << 617 &((*rmax_p)[0])); 665 " facet number " + G4UIcommand::Conv << 618 } 666 G4String Err3 = " number of points is << 619 else if( stype == "BREPOPENPCONE" ) // EntityType is = "Closed_Shell" 667 G4UIcommand::ConvertTo << 620 { 668 G4String ErrMessage = Err1 + Err2 + Er << 621 size_t nplanes = size_t(solParam[2]); 669 G4Exception("G4tgbVolume::FindOrConstr << 622 std::vector<G4double>* z_p = new std::vector<G4double>; 670 FatalException, ErrMessage << 623 std::vector<G4double>* rmin_p = new std::vector<G4double>; 671 return nullptr; << 624 std::vector<G4double>* rmax_p = new std::vector<G4double>; 672 } << 625 for( size_t ii = 0; ii < nplanes; ii++ ) 673 << 626 { 674 solidTS->AddFacet(facet); << 627 (*z_p).push_back( solParam[4+3*ii] ); 675 jj += nPoints * 3 + 2; << 628 (*rmin_p).push_back( solParam[4+3*ii+1] ); 676 } << 629 (*rmax_p).push_back( solParam[4+3*ii+2] ); 677 } << 630 } 678 else if(stype == "EXTRUDED") << 631 G4double phiTotal = solParam[1]; >> 632 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; } >> 633 CheckNoSolidParams( stype, 12, solParam.size() ); >> 634 solid = new G4BREPSolidOpenPCone( sname, solParam[0], phiTotal, // start,dph >> 635 nplanes, // sections >> 636 solParam[3], // z_start >> 637 &((*z_p)[0]), &((*rmin_p)[0]), >> 638 &((*rmax_p)[0])); >> 639 } >> 640 else if( stype == "TESSELLATED" ) >> 641 { >> 642 G4int nFacets = G4int(solParam[0]); >> 643 G4int jj = 0; >> 644 solid = new G4TessellatedSolid(sname); >> 645 G4TessellatedSolid* solidTS = (G4TessellatedSolid*)(solid); >> 646 G4VFacet* facet=0; >> 647 >> 648 for( G4int ii = 0; ii < nFacets; ii++){ >> 649 G4int nPoints = G4int(solParam[jj+1]); >> 650 if( G4int(solParam.size()) < jj + nPoints*3 + 2 ) { >> 651 G4String Err1 = "Too small number of parameters in tesselated solid, it should be at least " + G4UIcommand::ConvertToString(jj + nPoints*3 + 2 ); >> 652 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(ii); >> 653 G4String Err3 = " number of parameters is " + G4UIcommand::ConvertToString(G4int(solParam.size())); >> 654 G4String ErrMessage = Err1 + Err2 + Err3 + " !"; >> 655 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", >> 656 "InvalidSetup", FatalException, ErrMessage); >> 657 } >> 658 >> 659 if( nPoints == 3 ) >> 660 { >> 661 G4ThreeVector pt0(solParam[jj+2],solParam[jj+3],solParam[jj+4]); >> 662 G4ThreeVector vt1(solParam[jj+5],solParam[jj+6],solParam[jj+7]); >> 663 G4ThreeVector vt2(solParam[jj+8],solParam[jj+9],solParam[jj+10]); >> 664 G4FacetVertexType vertexType = ABSOLUTE; >> 665 if( solParam[jj+11] == 0 ) >> 666 { >> 667 vertexType = ABSOLUTE; >> 668 } >> 669 else if( solParam[jj+11] == 0 ) >> 670 { >> 671 vertexType = RELATIVE; >> 672 } >> 673 else >> 674 { >> 675 G4String Err1 = "Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)"; >> 676 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii)); >> 677 G4String Err3 = " vertex type is " + G4UIcommand::ConvertToString(solParam[jj+11]); >> 678 G4String ErrMessage = Err1 + Err2 + Err3 + " !"; >> 679 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", >> 680 "InvalidSetup", FatalException, ErrMessage); >> 681 } >> 682 facet = new G4TriangularFacet( pt0, vt1, vt2, vertexType ); >> 683 } >> 684 else if( nPoints == 4 ) >> 685 { >> 686 G4ThreeVector pt0(solParam[jj+2],solParam[jj+3],solParam[jj+4]); >> 687 G4ThreeVector vt1(solParam[jj+5],solParam[jj+6],solParam[jj+7]); >> 688 G4ThreeVector vt2(solParam[jj+8],solParam[jj+9],solParam[jj+10]); >> 689 G4ThreeVector vt3(solParam[jj+11],solParam[jj+12],solParam[jj+13]); >> 690 G4FacetVertexType vertexType = ABSOLUTE; >> 691 if( solParam[jj+14] == 0 ) >> 692 { >> 693 vertexType = ABSOLUTE; >> 694 } >> 695 else if( solParam[jj+14] == 0 ) >> 696 { >> 697 vertexType = RELATIVE; >> 698 } >> 699 else >> 700 { >> 701 G4String Err1 = "Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)"; >> 702 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii)); >> 703 G4String Err3 = " vertex type is " + G4UIcommand::ConvertToString(solParam[jj+14]); >> 704 G4String ErrMessage = Err1 + Err2 + Err3 + " !"; >> 705 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", >> 706 "InvalidSetup", FatalException, ErrMessage); >> 707 } >> 708 facet = new G4QuadrangularFacet( pt0, vt1, vt2, vt3, vertexType ); >> 709 } >> 710 else >> 711 { >> 712 G4String Err1 = "Wrong number of points in tesselated solid, it should be 3 or 4"; >> 713 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii)); >> 714 G4String Err3 = " number of points is " + G4UIcommand::ConvertToString(G4int(nPoints)); >> 715 G4String ErrMessage = Err1 + Err2 + Err3 + " !"; >> 716 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", >> 717 "InvalidSetup", FatalException, ErrMessage); >> 718 } >> 719 >> 720 solidTS->AddFacet( facet ); >> 721 jj += nPoints*3 + 2; >> 722 } >> 723 >> 724 } >> 725 else if( stype == "EXTRUDED" ) 679 { 726 { 680 std::vector<G4TwoVector> polygonList; 727 std::vector<G4TwoVector> polygonList; 681 std::vector<G4ExtrudedSolid::ZSection> zse 728 std::vector<G4ExtrudedSolid::ZSection> zsectionList; 682 G4int nPolygons = G4int(solParam[0]); 729 G4int nPolygons = G4int(solParam[0]); 683 G4int ii = 1; << 730 G4int ii = 1; 684 G4int nMax = nPolygons * 2 + 1; << 731 G4int nMax = nPolygons*2+1; 685 for(; ii < nMax; ii += 2) << 732 for( ;ii < nMax; ii+=2 ) 686 { 733 { 687 polygonList.push_back(G4TwoVector(solPar << 734 polygonList.push_back( G4TwoVector(solParam[ii],solParam[ii+1]) ); 688 } 735 } 689 G4int nZSections = G4int(solParam[ii]); 736 G4int nZSections = G4int(solParam[ii]); 690 nMax = nPolygons * 2 + nZSecti << 737 nMax = nPolygons*2 + nZSections*4 + 2; 691 ++ii; << 738 ii++; 692 for(; ii < nMax; ii += 4) << 739 for( ; ii < nMax; ii+=4 ) 693 { 740 { 694 G4TwoVector offset(solParam[ii + 1], sol << 741 G4TwoVector offset(solParam[ii+1],solParam[ii+2]); 695 zsectionList.push_back( << 742 zsectionList.push_back( G4ExtrudedSolid::ZSection(solParam[ii],offset,solParam[ii+3]) ); 696 G4ExtrudedSolid::ZSection(solParam[ii] << 697 } 743 } 698 solid = new G4ExtrudedSolid(sname, polygon << 744 solid = new G4ExtrudedSolid( sname, polygonList, zsectionList ); >> 745 699 } 746 } 700 else if(stype.substr(0, 7) == "Boolean") << 747 else if( stype.substr(0,7) == "Boolean" ) 701 { 748 { 702 const G4tgrSolidBoolean* solb = dynamic_ca 749 const G4tgrSolidBoolean* solb = dynamic_cast<const G4tgrSolidBoolean*>(sol); 703 if(solb == nullptr) << 750 G4VSolid* sol1 = FindOrConstructG4Solid( solb->GetSolid(0)); 704 { << 751 G4VSolid* sol2 = FindOrConstructG4Solid( solb->GetSolid(1)); 705 G4Exception("G4tgbVolume::FindOrConstruc << 752 G4RotationMatrix* relRotMat = G4tgbRotationMatrixMgr::GetInstance() 706 FatalException, "Invalid Sol << 753 ->FindOrBuildG4RotMatrix( sol->GetRelativeRotMatName() ); 707 return nullptr; << 708 } << 709 G4VSolid* sol1 = FindOrConstructG4Solid(so << 710 G4VSolid* sol2 = FindOrConstructG4Solid(so << 711 G4RotationMatrix* relRotMat = << 712 G4tgbRotationMatrixMgr::GetInstance()->F << 713 sol->GetRelativeRotMatName()); << 714 G4ThreeVector relPlace = solb->GetRelative 754 G4ThreeVector relPlace = solb->GetRelativePlace(); 715 755 716 if(stype == "Boolean_UNION") << 756 if( stype == "Boolean_UNION" ) 717 { 757 { 718 solid = new G4UnionSolid(sname, sol1, so << 758 solid = new G4UnionSolid( sname, sol1, sol2, relRotMat, relPlace ); 719 } 759 } 720 else if(stype == "Boolean_SUBTRACTION") << 760 else if( stype == "Boolean_SUBTRACTION" ) 721 { 761 { 722 solid = new G4SubtractionSolid(sname, so << 762 solid = new G4SubtractionSolid( sname, sol1, sol2, relRotMat, relPlace ); 723 } 763 } 724 else if(stype == "Boolean_INTERSECTION") << 764 else if( stype == "Boolean_INTERSECTION" ) 725 { 765 { 726 solid = new G4IntersectionSolid(sname, s << 766 solid = new G4IntersectionSolid( sname, sol1, sol2, relRotMat, relPlace ); 727 } 767 } 728 else 768 else 729 { 769 { 730 G4String ErrMessage = "Unknown Boolean t 770 G4String ErrMessage = "Unknown Boolean type " + stype; 731 G4Exception("G4tgbVolume::FindOrConstruc << 771 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", 732 FatalException, ErrMessage); << 772 "InvalidSetup", FatalException, ErrMessage); 733 return nullptr; << 734 } << 735 } << 736 else if(stype == "MULTIUNION") << 737 { << 738 const G4tgrSolidMultiUnion* tgrSol = dynam << 739 if(tgrSol == nullptr) << 740 { << 741 G4Exception("G4tgbVolume::FindOrConstruc << 742 FatalException, "Invalid Sol << 743 return nullptr; << 744 } << 745 << 746 G4int nsol = tgrSol->GetNSolid(); << 747 G4VSolid* soli; << 748 G4Transform3D tri; << 749 G4MultiUnion* solidu = new G4MultiUnion(sn << 750 << 751 for (G4int i=0; i<nsol; ++i) << 752 { << 753 soli = FindOrConstructG4Solid(tgrSol->Ge << 754 tri = tgrSol->GetTransformation(i); << 755 solidu->AddNode(*soli, tri); << 756 } 773 } 757 solidu->Voxelize(); << 758 solid = dynamic_cast<G4VSolid*>(solidu); << 759 } 774 } 760 else 775 else 761 { 776 { 762 G4String ErrMessage = << 777 G4String ErrMessage = "Solids of type " + stype 763 "Solids of type " + stype + " not implem << 778 + " not implemented yet, sorry..."; 764 G4Exception("G4tgbVolume::FindOrConstructG 779 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", "NotImplemented", 765 FatalException, ErrMessage); 780 FatalException, ErrMessage); 766 return nullptr; << 781 } 767 } << 782 768 << 769 #ifdef G4VERBOSE 783 #ifdef G4VERBOSE 770 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 784 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 771 { 785 { 772 G4cout << " G4tgbVolume::FindOrConstructG4 786 G4cout << " G4tgbVolume::FindOrConstructG4Solid()" << G4endl 773 << " Created solid " << sname << << 787 << " Created solid " << sname 774 << solid->GetEntityType() << G4endl << 788 << " of type " << solid->GetEntityType() << G4endl; 775 } 789 } 776 #endif 790 #endif 777 791 778 #ifdef G4VERBOSE 792 #ifdef G4VERBOSE 779 if(G4tgrMessenger::GetVerboseLevel() >= 1) << 793 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 780 { << 794 { 781 G4cout << " Constructing new G4Solid: " << << 795 G4cout << " Constructing new G4Solid: " 782 } << 796 << *solid << G4endl; >> 797 } 783 #endif 798 #endif 784 << 799 785 return solid; 800 return solid; 786 } 801 } 787 802 788 // ------------------------------------------- << 803 //------------------------------------------------------------------- 789 void G4tgbVolume::CheckNoSolidParams(const G4S << 804 void G4tgbVolume::CheckNoSolidParams( const G4String& solidType, 790 const uns << 805 const unsigned int NoParamExpected, 791 const uns << 806 const unsigned int NoParam ) 792 { 807 { 793 if(NoParamExpected != NoParam) << 808 if( NoParamExpected != NoParam ) 794 { 809 { 795 G4String Err1 = "Solid type " + solidType 810 G4String Err1 = "Solid type " + solidType + " should have "; 796 G4String Err2 = << 811 G4String Err2 = G4UIcommand::ConvertToString(G4int(NoParamExpected)) 797 G4UIcommand::ConvertToString(G4int(NoPar << 812 + " parameters,\n"; 798 G4String Err3 = << 813 G4String Err3 = "and it has " 799 "and it has " + G4UIcommand::ConvertToSt << 814 + G4UIcommand::ConvertToString(G4int(NoParam)); 800 G4String ErrMessage = Err1 + Err2 + Err3 + 815 G4String ErrMessage = Err1 + Err2 + Err3 + " !"; 801 G4Exception("G4tgbVolume::CheckNoSolidPara 816 G4Exception("G4tgbVolume::CheckNoSolidParams()", "InvalidSetup", 802 FatalException, ErrMessage); 817 FatalException, ErrMessage); 803 } 818 } 804 } 819 } 805 820 806 // ------------------------------------------- << 821 807 G4LogicalVolume* G4tgbVolume::ConstructG4LogVo << 822 //------------------------------------------------------------------- >> 823 G4LogicalVolume* G4tgbVolume::ConstructG4LogVol( const G4VSolid* solid ) 808 { 824 { 809 G4LogicalVolume* logvol; 825 G4LogicalVolume* logvol; 810 826 811 #ifdef G4VERBOSE 827 #ifdef G4VERBOSE 812 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 828 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 813 { 829 { 814 G4cout << " G4tgbVolume::ConstructG4LogVol 830 G4cout << " G4tgbVolume::ConstructG4LogVol() - " << GetName() << G4endl; 815 } 831 } 816 #endif 832 #endif 817 833 818 //----------- Get the material first 834 //----------- Get the material first 819 G4Material* mate = G4tgbMaterialMgr::GetInst << 835 G4Material* mate = G4tgbMaterialMgr::GetInstance() 820 theTgrVolume->GetMaterialName()); << 836 ->FindOrBuildG4Material( theTgrVolume->GetMaterialName() ); 821 if(mate == nullptr) << 837 if( mate == 0 ) 822 { << 838 { 823 G4String ErrMessage = "Material not found << 839 G4String ErrMessage = "Material not found " 824 theTgrVolume->GetMat << 840 + theTgrVolume->GetMaterialName() 825 GetName() + "."; << 841 + " for volume " + GetName() + "."; 826 G4Exception("G4tgbVolume::ConstructG4LogVo 842 G4Exception("G4tgbVolume::ConstructG4LogVol()", "InvalidSetup", 827 FatalException, ErrMessage); 843 FatalException, ErrMessage); 828 } 844 } 829 #ifdef G4VERBOSE 845 #ifdef G4VERBOSE 830 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 846 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 831 { 847 { 832 G4cout << " G4tgbVolume::ConstructG4LogVol 848 G4cout << " G4tgbVolume::ConstructG4LogVol() -" 833 << " Material constructed: " << mat << 849 << " Material constructed: " << mate->GetName() << G4endl; 834 } 850 } 835 #endif 851 #endif 836 << 852 837 //---------- Construct the LV 853 //---------- Construct the LV 838 logvol = new G4LogicalVolume(const_cast<G4VS << 854 logvol = new G4LogicalVolume( const_cast<G4VSolid*>(solid), 839 const_cast<G4Ma << 855 const_cast<G4Material*>(mate), GetName() ); 840 856 841 #ifdef G4VERBOSE 857 #ifdef G4VERBOSE 842 if(G4tgrMessenger::GetVerboseLevel() >= 1) << 858 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 843 { << 859 { 844 G4cout << " Constructing new G4LogicalVolu << 860 G4cout << " Constructing new G4LogicalVolume: " 845 << " mate " << mate->GetName() << G << 861 << logvol->GetName() << " mate " << mate->GetName() << G4endl; 846 } << 862 } 847 #endif 863 #endif 848 << 864 849 //---------- Set visibility and colour 865 //---------- Set visibility and colour 850 if(!GetVisibility() || GetColour()[0] != -1) << 866 if( !GetVisibility() || GetColour()[0] != -1 ) 851 { 867 { 852 G4VisAttributes* visAtt = new G4VisAttribu 868 G4VisAttributes* visAtt = new G4VisAttributes(); 853 #ifdef G4VERBOSE 869 #ifdef G4VERBOSE 854 if(G4tgrMessenger::GetVerboseLevel() >= 1) << 870 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 855 { 871 { 856 G4cout << " Constructing new G4VisAttrib << 872 G4cout << " Constructing new G4VisAttributes: " >> 873 << *visAtt << G4endl; 857 } 874 } 858 #endif 875 #endif 859 << 876 860 if(!GetVisibility()) << 877 if( !GetVisibility() ) 861 { 878 { 862 visAtt->SetVisibility(GetVisibility()); << 879 visAtt->SetVisibility( GetVisibility() ); 863 } 880 } 864 else if(GetColour()[0] != -1) << 881 else if( GetColour()[0] != -1 ) 865 { 882 { 866 // this else should not be necessary, be 883 // this else should not be necessary, because if the visibility 867 // is set to off, colour should have no 884 // is set to off, colour should have no effect. But it does not 868 // work: if you set colour and vis off, 885 // work: if you set colour and vis off, it is visualized!?!?!? 869 886 870 const G4double* col = GetColour(); 887 const G4double* col = GetColour(); 871 if(col[3] == -1.) << 888 if( col[3] == -1. ) 872 { 889 { 873 visAtt->SetColour(G4Colour(col[0], col << 890 visAtt->SetColour( G4Colour(col[0],col[1],col[2])); 874 } 891 } 875 else 892 else 876 { 893 { 877 visAtt->SetColour(G4Colour(col[0], col << 894 visAtt->SetColour( G4Colour(col[0],col[1],col[2],col[3])); 878 } 895 } 879 } 896 } 880 logvol->SetVisAttributes(visAtt); 897 logvol->SetVisAttributes(visAtt); 881 } 898 } 882 899 883 #ifdef G4VERBOSE 900 #ifdef G4VERBOSE 884 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 901 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 885 { 902 { 886 G4cout << " G4tgbVolume::ConstructG4LogVol 903 G4cout << " G4tgbVolume::ConstructG4LogVol() -" 887 << " Created logical volume: " << G 904 << " Created logical volume: " << GetName() << G4endl; 888 } 905 } 889 #endif 906 #endif 890 907 891 return logvol; 908 return logvol; 892 } 909 } 893 910 894 // ------------------------------------------- << 911 >> 912 //------------------------------------------------------------------- 895 G4VPhysicalVolume* 913 G4VPhysicalVolume* 896 G4tgbVolume::ConstructG4PhysVol(const G4tgrPla << 914 G4tgbVolume::ConstructG4PhysVol( const G4tgrPlace* place, 897 const G4Logica << 915 const G4LogicalVolume* currentLV, 898 const G4Logica << 916 const G4LogicalVolume* parentLV ) 899 { 917 { 900 G4VPhysicalVolume* physvol = nullptr; << 918 G4VPhysicalVolume* physvol = 0; 901 G4int copyNo; 919 G4int copyNo; 902 << 920 903 //----- Case of placement of top volume 921 //----- Case of placement of top volume 904 if(place == nullptr) << 922 if( place == 0 ) 905 { 923 { 906 #ifdef G4VERBOSE 924 #ifdef G4VERBOSE 907 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 925 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 908 { 926 { 909 G4cout << " G4tgbVolume::ConstructG4Phys << 927 G4cout << " G4tgbVolume::ConstructG4PhysVol() - World: " 910 << G4endl; << 928 << GetName() << G4endl; 911 } 929 } 912 #endif 930 #endif 913 physvol = new G4PVPlacement( << 931 physvol = new G4PVPlacement(0, G4ThreeVector(), 914 nullptr, G4ThreeVector(), const_cast<G4L << 932 const_cast<G4LogicalVolume*>(currentLV), 915 GetName(), 0, false, 0, theTgrVolume->Ge << 933 GetName(), 0, false, 0, >> 934 theTgrVolume->GetCheckOverlaps()); 916 #ifdef G4VERBOSE 935 #ifdef G4VERBOSE 917 if(G4tgrMessenger::GetVerboseLevel() >= 1) << 936 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 918 { 937 { 919 G4cout << " Constructing new : G4PVPlace << 938 G4cout << " Constructing new : G4PVPlacement " 920 << G4endl; << 939 << physvol->GetName() << G4endl; 921 } 940 } 922 #endif 941 #endif 923 } 942 } 924 else 943 else 925 { << 944 { 926 copyNo = place->GetCopyNo(); 945 copyNo = place->GetCopyNo(); 927 946 928 #ifdef G4VERBOSE 947 #ifdef G4VERBOSE 929 if(G4tgrMessenger::GetVerboseLevel() >= 2) << 948 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 930 { 949 { 931 G4cout << " G4tgbVolume::ConstructG4Phys 950 G4cout << " G4tgbVolume::ConstructG4PhysVol() - " << GetName() << G4endl 932 << " inside " << parentLV->GetN 951 << " inside " << parentLV->GetName() << " copy No: " << copyNo 933 << " of type= " << theTgrVolume-> 952 << " of type= " << theTgrVolume->GetType() << G4endl 934 << " placement type= " << place 953 << " placement type= " << place->GetType() << G4endl; 935 } 954 } 936 #endif 955 #endif 937 << 956 938 if(theTgrVolume->GetType() == "VOLSimple") << 957 if( theTgrVolume->GetType() == "VOLSimple" ) 939 { 958 { 940 //----- Get placement 959 //----- Get placement 941 #ifdef G4VERBOSE 960 #ifdef G4VERBOSE 942 if(G4tgrMessenger::GetVerboseLevel() >= << 961 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 943 { 962 { 944 G4cout << " G4tgbVolume::ConstructG4Ph 963 G4cout << " G4tgbVolume::ConstructG4PhysVol() - Placement type = " 945 << place->GetType() << G4endl; 964 << place->GetType() << G4endl; 946 } 965 } 947 #endif 966 #endif 948 << 967 949 //--------------- If it is G4tgrPlaceSi 968 //--------------- If it is G4tgrPlaceSimple 950 if(place->GetType() == "PlaceSimple") << 969 if( place->GetType() == "PlaceSimple" ) 951 { 970 { 952 //----- Get rotation matrix 971 //----- Get rotation matrix 953 G4tgrPlaceSimple* placeSimple = (G4tgr << 972 G4tgrPlaceSimple* placeSimple = (G4tgrPlaceSimple*)place; 954 G4String rmName = placeS << 973 G4String rmName = placeSimple->GetRotMatName(); 955 974 956 G4RotationMatrix* rotmat = << 975 G4RotationMatrix* rotmat = G4tgbRotationMatrixMgr::GetInstance() 957 G4tgbRotationMatrixMgr::GetInstance( << 976 ->FindOrBuildG4RotMatrix( rmName ); 958 //----- Place volume in mother 977 //----- Place volume in mother 959 G4double check = << 978 G4double check = (rotmat->colX().cross(rotmat->colY()))*rotmat->colZ(); 960 (rotmat->colX().cross(rotmat->colY() << 961 G4double tol = 1.0e-3; 979 G4double tol = 1.0e-3; 962 //---- Check that matrix is ortogonal 980 //---- Check that matrix is ortogonal 963 if(1 - std::abs(check) > tol) << 981 if (1-std::abs(check)>tol) 964 { 982 { 965 G4cerr << " Matrix : " << rmName << << 983 G4cerr << " Matrix : " << rmName << " " << rotmat->colX() 966 << rotmat->colY() << " " << r << 984 << " " << rotmat->colY() << " " << rotmat->colZ() << G4endl 967 << " product x X y * z = " << 985 << " product x X y * z = " << check << " x X y " 968 << rotmat->colX().cross(rotma 986 << rotmat->colX().cross(rotmat->colY()) << G4endl; 969 G4String ErrMessage = "Rotation is n 987 G4String ErrMessage = "Rotation is not ortogonal " + rmName + " !"; 970 G4Exception("G4tgbVolume::ConstructG << 988 G4Exception("G4tgbVolume::ConstructG4PhysVol()", 971 FatalException, ErrMessa << 989 "InvalidSetup", FatalException, ErrMessage); 972 //---- Check if it is reflection 990 //---- Check if it is reflection 973 } 991 } 974 else if(1 + check <= tol) << 992 else if (1+check<=tol) 975 { 993 { 976 G4Translate3D transl = place->GetPla 994 G4Translate3D transl = place->GetPlacement(); 977 G4Transform3D trfrm = transl * G4Ro 995 G4Transform3D trfrm = transl * G4Rotate3D(*rotmat); 978 physvol = << 996 physvol = (G4ReflectionFactory::Instance()->Place(trfrm, GetName(), 979 (G4ReflectionFactory::Instance()-> << 997 const_cast<G4LogicalVolume*>(currentLV), 980 trfrm, GetName(), const_cast<G4 << 998 const_cast<G4LogicalVolume*>(parentLV), 981 const_cast<G4LogicalVolume*>(pa << 999 false, copyNo, false )).first; 982 .first; << 983 } 1000 } 984 else 1001 else 985 { 1002 { 986 #ifdef G4VERBOSE 1003 #ifdef G4VERBOSE 987 if(G4tgrMessenger::GetVerboseLevel() << 1004 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 988 { 1005 { 989 G4cout << "Construction new G4VPhy 1006 G4cout << "Construction new G4VPhysicalVolume" 990 << " through G4ReflectionFa << 1007 << " through G4ReflectionFactory " << GetName() 991 << " in volume " << parentL << 1008 << " in volume " << parentLV->GetName() 992 << copyNo << " position " < << 1009 << " copyNo " << copyNo 993 << rotmat->colX() << " " << << 1010 << " position " << place->GetPlacement() 994 << rotmat->colZ() << G4endl << 1011 << " ROT " << rotmat->colX() >> 1012 << " " << rotmat->colY() >> 1013 << " " << rotmat->colZ() << G4endl; 995 } 1014 } 996 #endif 1015 #endif 997 physvol = << 1016 physvol = new G4PVPlacement( rotmat, place->GetPlacement(), 998 new G4PVPlacement(rotmat, place->G << 1017 const_cast<G4LogicalVolume*>(currentLV), 999 const_cast<G4Log << 1018 GetName(), 1000 GetName(), cons << 1019 const_cast<G4LogicalVolume*>(parentLV), 1001 false, copyNo, << 1020 false, copyNo, >> 1021 theTgrVolume->GetCheckOverlaps()); 1002 } 1022 } 1003 << 1023 1004 //--------------- If it is G4tgrPlace 1024 //--------------- If it is G4tgrPlaceParam 1005 } 1025 } 1006 else if(place->GetType() == "PlaceParam << 1026 else if( place->GetType() == "PlaceParam" ) 1007 { 1027 { 1008 G4tgrPlaceParameterisation* dp = (G4t << 1028 G4tgrPlaceParameterisation* dp = (G4tgrPlaceParameterisation*)(place); 1009 1029 1010 //----- See what parameterisation typ 1030 //----- See what parameterisation type 1011 #ifdef G4VERBOSE 1031 #ifdef G4VERBOSE 1012 if(G4tgrMessenger::GetVerboseLevel() << 1032 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 1013 { 1033 { 1014 G4cout << " G4tgbVolume::ConstructG 1034 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl 1015 << " param: " << GetName() << 1035 << " param: " << GetName() << " in " << parentLV->GetName() 1016 << " param type= " << dp->Ge 1036 << " param type= " << dp->GetParamType() << G4endl; 1017 } 1037 } 1018 #endif 1038 #endif 1019 << 1039 1020 G4tgbPlaceParameterisation* param = n << 1040 G4tgbPlaceParameterisation * param=0; 1021 << 1041 1022 if((dp->GetParamType() == "CIRCLE") | << 1042 if( (dp->GetParamType() == "CIRCLE") 1023 (dp->GetParamType() == "CIRCLE_XY" << 1043 || (dp->GetParamType() == "CIRCLE_XY") 1024 (dp->GetParamType() == "CIRCLE_XZ" << 1044 || (dp->GetParamType() == "CIRCLE_XZ") 1025 (dp->GetParamType() == "CIRCLE_YZ" << 1045 || (dp->GetParamType() == "CIRCLE_YZ") ) 1026 { << 1046 { 1027 param = new G4tgbPlaceParamCircle(d 1047 param = new G4tgbPlaceParamCircle(dp); 1028 } << 1048 1029 else if((dp->GetParamType() == "LINEA << 1049 } 1030 (dp->GetParamType() == "LINEA << 1050 else if( (dp->GetParamType() == "LINEAR") 1031 (dp->GetParamType() == "LINEA << 1051 || (dp->GetParamType() == "LINEAR_X") 1032 (dp->GetParamType() == "LINEA << 1052 || (dp->GetParamType() == "LINEAR_Y") 1033 { << 1053 || (dp->GetParamType() == "LINEAR_Z") ) >> 1054 { 1034 param = new G4tgbPlaceParamLinear(d 1055 param = new G4tgbPlaceParamLinear(dp); 1035 } << 1056 1036 else if((dp->GetParamType() == "SQUAR << 1057 } 1037 (dp->GetParamType() == "SQUAR << 1058 else if( (dp->GetParamType() == "SQUARE") 1038 (dp->GetParamType() == "SQUAR << 1059 || (dp->GetParamType() == "SQUARE_XY") 1039 (dp->GetParamType() == "SQUAR << 1060 || (dp->GetParamType() == "SQUARE_XZ") >> 1061 || (dp->GetParamType() == "SQUARE_YZ") ) 1040 { 1062 { 1041 param = new G4tgbPlaceParamSquare(d 1063 param = new G4tgbPlaceParamSquare(dp); 1042 } 1064 } 1043 else 1065 else 1044 { 1066 { 1045 G4String ErrMessage = "Parameterisa << 1067 G4String ErrMessage = "Parameterisation has wrong type, TYPE: " 1046 G4String(dp-> << 1068 + G4String(dp->GetParamType()) + " !"; 1047 G4Exception("G4tgbVolume::Construct 1069 G4Exception("G4tgbVolume::ConstructG4PhysVol", "WrongArgument", 1048 FatalException, ErrMess 1070 FatalException, ErrMessage); 1049 return nullptr; << 1050 } 1071 } 1051 #ifdef G4VERBOSE 1072 #ifdef G4VERBOSE 1052 if(G4tgrMessenger::GetVerboseLevel() << 1073 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1053 { 1074 { 1054 G4cout << " G4tgbVolume::ConstructG 1075 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl 1055 << " New G4PVParameterised 1076 << " New G4PVParameterised: " << GetName() << " vol " 1056 << currentLV->GetName() << " 1077 << currentLV->GetName() << " in vol " << parentLV->GetName() 1057 << " axis " << param->GetAxi 1078 << " axis " << param->GetAxis() << " nCopies " 1058 << param->GetNCopies() << G4 1079 << param->GetNCopies() << G4endl; 1059 } 1080 } 1060 #endif 1081 #endif 1061 physvol = new G4PVParameterised( << 1082 physvol = new G4PVParameterised(GetName(), 1062 GetName(), const_cast<G4LogicalVolu << 1083 const_cast<G4LogicalVolume*>(currentLV), 1063 const_cast<G4LogicalVolume*>(parent << 1084 const_cast<G4LogicalVolume*>(parentLV), 1064 param->GetNCopies(), param); << 1085 EAxis(param->GetAxis()), >> 1086 param->GetNCopies(), param); 1065 #ifdef G4VERBOSE 1087 #ifdef G4VERBOSE 1066 if(G4tgrMessenger::GetVerboseLevel() << 1088 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1067 { << 1089 { 1068 G4cout << " Constructing new G4PVPa << 1090 G4cout << " Constructing new G4PVParameterised: " 1069 << physvol->GetName() << " i << 1091 << physvol->GetName() << " in volume " << parentLV->GetName() 1070 << " N copies " << param->Ge << 1092 << " N copies " << param->GetNCopies() 1071 << param->GetAxis() << G4end << 1093 << " axis " << param->GetAxis() << G4endl; 1072 } << 1094 } 1073 #endif 1095 #endif >> 1096 1074 } 1097 } 1075 else if(place->GetType() == "PlaceRepli << 1098 else if( place->GetType() == "PlaceReplica" ) 1076 { 1099 { 1077 //--------------- If it is PlaceRepl << 1100 //--------------- If it is PlaceReplica 1078 G4tgrPlaceDivRep* dpr = (G4tgrPlaceDi << 1101 G4tgrPlaceDivRep* dpr = (G4tgrPlaceDivRep*)place; 1079 1102 1080 #ifdef G4VERBOSE 1103 #ifdef G4VERBOSE 1081 if(G4tgrMessenger::GetVerboseLevel() << 1104 if( G4tgrMessenger::GetVerboseLevel() >= 2 ) 1082 { 1105 { 1083 G4cout << " G4tgbVolume::ConstructG << 1106 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl 1084 << " replica" << 1107 << " replica" << " " << currentLV->GetName() 1085 << " " << currentLV->GetName << 1108 << " in " << parentLV->GetName() 1086 << " NDiv " << dpr->GetNDiv( << 1109 << " NDiv " << dpr->GetNDiv() << " Width " << dpr->GetWidth() 1087 << " offset " << dpr->GetOff << 1110 << " offset " << dpr->GetOffset() << G4endl; 1088 } << 1111 } 1089 #endif 1112 #endif 1090 physvol = new G4PVReplica( << 1113 physvol = new G4PVReplica(GetName(), 1091 GetName(), const_cast<G4LogicalVolu << 1114 const_cast<G4LogicalVolume*>(currentLV), 1092 const_cast<G4LogicalVolume*>(parent << 1115 const_cast<G4LogicalVolume*>(parentLV), 1093 dpr->GetNDiv(), dpr->GetWidth(), dp << 1116 EAxis(dpr->GetAxis()), dpr->GetNDiv(), >> 1117 dpr->GetWidth(), dpr->GetOffset()); 1094 #ifdef G4VERBOSE 1118 #ifdef G4VERBOSE 1095 if(G4tgrMessenger::GetVerboseLevel() << 1119 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1096 { << 1120 { 1097 G4cout << " Constructing new G4PVRe << 1121 G4cout << " Constructing new G4PVReplica: " 1098 << " in " << parentLV->GetNa << 1122 << currentLV->GetName() 1099 << " Width " << dpr->GetWidt << 1123 << " in " << parentLV->GetName() 1100 << dpr->GetOffset() << G4end << 1124 << " NDiv " << dpr->GetNDiv() << " Width " << dpr->GetWidth() 1101 } << 1125 << " offset " << dpr->GetOffset() << G4endl; >> 1126 } 1102 #endif 1127 #endif 1103 } 1128 } 1104 } 1129 } 1105 else if(theTgrVolume->GetType() == "VOLDi << 1130 else if( theTgrVolume->GetType() == "VOLDivision" ) 1106 { 1131 { 1107 G4tgrVolumeDivision* volr = (G4tgrVolu << 1132 G4tgrVolumeDivision* volr = (G4tgrVolumeDivision*)theTgrVolume; 1108 G4tgrPlaceDivRep* placeDiv = volr->GetP << 1133 G4tgrPlaceDivRep* placeDiv = volr->GetPlaceDivision() ; 1109 G4VSolid* solid = << 1134 G4VSolid* solid = BuildSolidForDivision( parentLV->GetSolid(), placeDiv->GetAxis() ); 1110 BuildSolidForDivision(parentLV->GetSo << 1135 G4Material* mate = G4tgbMaterialMgr::GetInstance() 1111 G4Material* mate = G4tgbMaterialMgr::Ge << 1136 ->FindOrBuildG4Material( theTgrVolume->GetMaterialName() ); 1112 theTgrVolume->GetMaterialName()); << 1137 G4LogicalVolume* divLV = new G4LogicalVolume(solid, 1113 G4LogicalVolume* divLV = << 1138 const_cast<G4Material*>(mate), 1114 new G4LogicalVolume(solid, const_cast << 1139 GetName() ); 1115 #ifdef G4VERBOSE 1140 #ifdef G4VERBOSE 1116 if(G4tgrMessenger::GetVerboseLevel() >= << 1141 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1117 { 1142 { 1118 G4cout << " Constructed new G4Logical << 1143 G4cout << " Constructed new G4LogicalVolume for division: " 1119 << divLV->GetName() << " mate << 1144 << divLV->GetName() << " mate " << mate->GetName() << G4endl; 1120 } 1145 } 1121 #endif 1146 #endif 1122 << 1147 1123 G4DivType divType = placeDiv->GetDivTyp 1148 G4DivType divType = placeDiv->GetDivType(); 1124 switch(divType) << 1149 switch (divType) 1125 { 1150 { 1126 case DivByNdiv: << 1151 case DivByNdiv: 1127 physvol = new G4PVDivision(GetName( << 1152 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV, 1128 const_ca << 1153 const_cast<G4LogicalVolume*>(parentLV), 1129 placeDiv << 1154 placeDiv->GetAxis(), placeDiv->GetNDiv(), 1130 placeDiv << 1155 placeDiv->GetOffset()); 1131 #ifdef G4VERBOSE << 1132 if(G4tgrMessenger::GetVerboseLevel( << 1133 { << 1134 G4cout << " Constructing new G4PV << 1135 << GetName() << " in " << << 1136 << placeDiv->GetAxis() << << 1137 << " offset " << placeDiv- << 1138 } << 1139 #endif << 1140 break; << 1141 case DivByWidth: << 1142 physvol = new G4PVDivision(GetName( << 1143 const_ca << 1144 placeDiv << 1145 placeDiv << 1146 #ifdef G4VERBOSE 1156 #ifdef G4VERBOSE 1147 if(G4tgrMessenger::GetVerboseLevel( << 1157 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1148 { << 1158 { 1149 G4cout << " Constructing new G4PV << 1159 G4cout << " Constructing new G4PVDivision by number of divisions: " 1150 << " in " << parentLV->Get << 1160 << GetName() << " in " << parentLV->GetName() 1151 << placeDiv->GetAxis() << << 1161 << " axis " << placeDiv->GetAxis() 1152 << " offset " << placeDiv- << 1162 << " Ndiv " << placeDiv->GetNDiv() 1153 } << 1163 << " offset " << placeDiv->GetOffset() << G4endl; 1154 #endif << 1164 } 1155 break; << 1165 #endif 1156 case DivByNdivAndWidth: << 1166 break; 1157 physvol = new G4PVDivision( << 1167 case DivByWidth: 1158 GetName(), (G4LogicalVolume*) div << 1168 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV, 1159 const_cast<G4LogicalVolume*>(pare << 1169 const_cast<G4LogicalVolume*>(parentLV), 1160 placeDiv->GetNDiv(), placeDiv->Ge << 1170 placeDiv->GetAxis(), placeDiv->GetWidth(), 1161 #ifdef G4VERBOSE << 1171 placeDiv->GetOffset()); 1162 if(G4tgrMessenger::GetVerboseLevel( << 1172 #ifdef G4VERBOSE 1163 { << 1173 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1164 G4cout << " Constructing new G4PV << 1174 { 1165 << " and number of divisio << 1175 G4cout << " Constructing new G4PVDivision by width: " 1166 << parentLV->GetName() << << 1176 << GetName() << " in " << parentLV->GetName() 1167 << " Ndiv " << placeDiv->G << 1177 << " axis " << placeDiv->GetAxis() 1168 << placeDiv->GetWidth() << << 1178 << " width " << placeDiv->GetWidth() 1169 << placeDiv->GetOffset() < << 1179 << " offset " << placeDiv->GetOffset() << G4endl; 1170 } << 1180 } >> 1181 #endif >> 1182 break; >> 1183 case DivByNdivAndWidth: >> 1184 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV, >> 1185 const_cast<G4LogicalVolume*>(parentLV), >> 1186 placeDiv->GetAxis(), placeDiv->GetNDiv(), >> 1187 placeDiv->GetWidth(), >> 1188 placeDiv->GetOffset()); >> 1189 #ifdef G4VERBOSE >> 1190 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) >> 1191 { >> 1192 G4cout << " Constructing new G4PVDivision by width" >> 1193 << " and number of divisions: " >> 1194 << GetName() << " in " << parentLV->GetName() >> 1195 << " axis " << placeDiv->GetAxis() >> 1196 << " Ndiv " << placeDiv->GetNDiv() >> 1197 << " width " << placeDiv->GetWidth() >> 1198 << " offset " << placeDiv->GetOffset() << G4endl; >> 1199 } 1171 #endif 1200 #endif 1172 break; << 1201 break; 1173 } 1202 } 1174 } 1203 } 1175 else if(theTgrVolume->GetType() == "VOLAs << 1204 else if( theTgrVolume->GetType() == "VOLAssembly" ) 1176 { 1205 { 1177 // Define one layer as one assembly vol 1206 // Define one layer as one assembly volume 1178 G4tgrVolumeAssembly* tgrAssembly = (G4t << 1207 G4tgrVolumeAssembly * tgrAssembly = (G4tgrVolumeAssembly *)theTgrVolume; 1179 1208 1180 if(!theG4AssemblyVolume) << 1209 if( !theG4AssemblyVolume ) 1181 { 1210 { 1182 theG4AssemblyVolume = new G4AssemblyV 1211 theG4AssemblyVolume = new G4AssemblyVolume; 1183 #ifdef G4VERBOSE 1212 #ifdef G4VERBOSE 1184 if(G4tgrMessenger::GetVerboseLevel() << 1213 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1185 { << 1214 { 1186 G4cout << " Constructing new G4Asse << 1215 G4cout << " Constructing new G4AssemblyVolume: " 1187 << " number of assembly comp << 1216 << " number of assembly components " 1188 << tgrAssembly->GetNoCompone << 1217 << tgrAssembly->GetNoComponents() << G4endl; 1189 } << 1218 } 1190 #endif << 1219 #endif 1191 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeM 1220 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeMgr::GetInstance(); 1192 for(G4int ii = 0; ii < tgrAssembly->G << 1221 for( G4int ii = 0; ii < tgrAssembly->GetNoComponents(); ii++ ) 1193 { 1222 { 1194 // Rotation and translation of a pl 1223 // Rotation and translation of a plate inside the assembly 1195 1224 1196 G4ThreeVector transl = tgrAssembly- << 1225 G4ThreeVector transl = tgrAssembly->GetComponentPos(ii); 1197 G4String rmName = tgrAssembly- << 1226 G4String rmName = tgrAssembly->GetComponentRM(ii); 1198 G4RotationMatrix* rotmat = << 1227 G4RotationMatrix* rotmat = G4tgbRotationMatrixMgr::GetInstance() 1199 G4tgbRotationMatrixMgr::GetInstan << 1228 ->FindOrBuildG4RotMatrix( rmName ); 1200 rmName); << 1229 1201 << 1202 //----- Get G4LogicalVolume of comp 1230 //----- Get G4LogicalVolume of component 1203 G4String lvname = tgrAssemb << 1231 G4String lvname = tgrAssembly->GetComponentName(ii); 1204 G4LogicalVolume* logvol = g4vmgr->F << 1232 G4LogicalVolume* logvol = g4vmgr->FindG4LogVol( lvname); 1205 if(logvol == nullptr) << 1233 if( logvol == 0 ) 1206 { 1234 { 1207 g4vmgr->FindVolume(lvname)->Const << 1235 g4vmgr->FindVolume( lvname )->ConstructG4Volumes( 0, 0); 1208 logvol = g4vmgr->FindG4LogVol(lvn << 1236 logvol = g4vmgr->FindG4LogVol( lvname, true ); 1209 } 1237 } 1210 // Fill the assembly by the plates 1238 // Fill the assembly by the plates 1211 theG4AssemblyVolume->AddPlacedVolum << 1239 theG4AssemblyVolume->AddPlacedVolume( logvol, transl, rotmat ); 1212 #ifdef G4VERBOSE 1240 #ifdef G4VERBOSE 1213 if(G4tgrMessenger::GetVerboseLevel( << 1241 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1214 { << 1242 { 1215 G4cout << " G4AssemblyVolume->Add << 1243 G4cout << " G4AssemblyVolume->AddPlacedVolume " << ii 1216 << logvol->GetName() << " << 1244 << " " << logvol->GetName() 1217 << " rotmat " << rotmat->c << 1245 << " translation " << transl 1218 << " " << rotmat->colZ() < << 1246 << " rotmat " << rotmat->colX() 1219 } << 1247 << " " << rotmat->colY() >> 1248 << " " << rotmat->colZ() << G4endl; >> 1249 } 1220 #endif 1250 #endif >> 1251 1221 } 1252 } 1222 } 1253 } 1223 1254 1224 // Rotation and Translation of the asse 1255 // Rotation and Translation of the assembly inside the world 1225 1256 1226 G4tgrPlaceSimple* placeSimple = (G4tgrP << 1257 G4tgrPlaceSimple* placeSimple = (G4tgrPlaceSimple*)place; 1227 G4String rmName = placeSi << 1258 G4String rmName = placeSimple->GetRotMatName(); 1228 G4RotationMatrix* rotmat = << 1259 G4RotationMatrix* rotmat = G4tgbRotationMatrixMgr::GetInstance() 1229 G4tgbRotationMatrixMgr::GetInstance() << 1260 ->FindOrBuildG4RotMatrix( rmName ); 1230 G4ThreeVector transl = place->GetPlacem 1261 G4ThreeVector transl = place->GetPlacement(); 1231 1262 1232 G4LogicalVolume* parentLV_nonconst = 1263 G4LogicalVolume* parentLV_nonconst = 1233 const_cast<G4LogicalVolume*>(parentLV << 1264 const_cast<G4LogicalVolume*>(parentLV); 1234 theG4AssemblyVolume->MakeImprint(parent << 1265 theG4AssemblyVolume->MakeImprint( parentLV_nonconst, transl, rotmat ); >> 1266 1235 } 1267 } 1236 else // If it is G4tgrVolumeAssembly << 1268 else // If it is G4tgrVolumeAssembly 1237 { 1269 { 1238 G4String ErrMessage = << 1270 G4String ErrMessage = "Volume type not supported: " 1239 "Volume type not supported: " + theTg << 1271 + theTgrVolume->GetType() + ", sorry..."; 1240 G4Exception("G4tgbVolume::ConstructG4Ph 1272 G4Exception("G4tgbVolume::ConstructG4PhysVol()", "NotImplemented", 1241 FatalException, ErrMessage) 1273 FatalException, ErrMessage); 1242 } << 1274 } 1243 } << 1275 } 1244 1276 1245 return physvol; 1277 return physvol; 1246 } 1278 } 1247 1279 1248 // ------------------------------------------ << 1280 1249 G4VSolid* G4tgbVolume::BuildSolidForDivision( << 1281 //------------------------------------------------------------------- >> 1282 G4VSolid* G4tgbVolume::BuildSolidForDivision( G4VSolid* parentSolid, EAxis axis ) 1250 { 1283 { 1251 G4VSolid* solid = nullptr; << 1284 G4VSolid* solid=0; 1252 G4double redf = << 1285 G4double redf = (parentSolid->GetExtent().GetXmax()-parentSolid->GetExtent().GetXmin()); 1253 (parentSolid->GetExtent().GetXmax() - par << 1286 redf = std::min(redf,parentSolid->GetExtent().GetYmax()-parentSolid->GetExtent().GetYmin()); 1254 redf = std::min(redf, parentSolid->GetExten << 1287 redf = std::min(redf,parentSolid->GetExtent().GetZmax()-parentSolid->GetExtent().GetZmin()); 1255 parentSolid->GetExt << 1288 redf *= 0.001; //make daugther much smaller, to fit in parent 1256 redf = std::min(redf, parentSolid->GetExten << 1289 1257 parentSolid->GetExt << 1290 if( parentSolid->GetEntityType() == "G4Box" ) 1258 redf *= 0.001; // make daugther much small << 1291 { 1259 << 1292 G4Box* psolid = (G4Box*)(parentSolid); 1260 if(parentSolid->GetEntityType() == "G4Box") << 1293 solid = new G4Box(GetName(), psolid->GetXHalfLength()*redf, 1261 { << 1294 psolid->GetZHalfLength()*redf, 1262 G4Box* psolid = (G4Box*) (parentSolid); << 1295 psolid->GetZHalfLength()*redf); 1263 solid = new G4Box(GetName(), psol << 1296 } 1264 psolid->GetZHalfLength( << 1297 else if ( parentSolid->GetEntityType() == "G4Tubs" ) 1265 psolid->GetZHalfLength( << 1298 { 1266 } << 1299 G4Tubs* psolid = (G4Tubs*)(parentSolid); 1267 else if(parentSolid->GetEntityType() == "G4 << 1300 solid = new G4Tubs( GetName(), psolid->GetInnerRadius()*redf, 1268 { << 1301 psolid->GetOuterRadius()*redf, 1269 G4Tubs* psolid = (G4Tubs*) (parentSolid); << 1302 psolid->GetZHalfLength()*redf, 1270 solid = new G4Tubs(GetName(), ps << 1303 psolid->GetSPhi(), psolid->GetDPhi()); 1271 psolid->GetOuterRadius << 1304 } 1272 psolid->GetZHalfLength << 1305 else if ( parentSolid->GetEntityType() == "G4Cons" ) 1273 psolid->GetStartPhiAng << 1306 { 1274 } << 1307 G4Cons* psolid = (G4Cons*)(parentSolid); 1275 else if(parentSolid->GetEntityType() == "G4 << 1308 solid = new G4Cons( GetName(), psolid->GetInnerRadiusMinusZ()*redf, 1276 { << 1309 psolid->GetOuterRadiusMinusZ()*redf, 1277 G4Cons* psolid = (G4Cons*) (parentSolid); << 1310 psolid->GetInnerRadiusPlusZ()*redf, 1278 solid = new G4Cons(GetName(), psolid->Get << 1311 psolid->GetOuterRadiusPlusZ()*redf, 1279 psolid->GetOuterRadius << 1312 psolid->GetZHalfLength()*redf, 1280 psolid->GetInnerRadius << 1313 psolid->GetSPhi(), psolid->GetDPhi()); 1281 psolid->GetOuterRadius << 1314 } 1282 psolid->GetZHalfLength << 1315 else if ( parentSolid->GetEntityType() == "G4Trd" ) 1283 psolid->GetStartPhiAng << 1284 } << 1285 else if(parentSolid->GetEntityType() == "G4 << 1286 { 1316 { 1287 G4Trd* psolid = (G4Trd*) (parentSolid); << 1317 G4Trd* psolid = (G4Trd*)(parentSolid); 1288 G4double mpDx1 = psolid->GetXHalfLength1( 1318 G4double mpDx1 = psolid->GetXHalfLength1(); 1289 G4double mpDx2 = psolid->GetXHalfLength2( 1319 G4double mpDx2 = psolid->GetXHalfLength2(); 1290 1320 1291 if(axis == kXAxis && << 1321 if( axis == kXAxis && std::fabs(mpDx1 - mpDx2) > G4GeometryTolerance::GetInstance()->GetSurfaceTolerance() ) 1292 std::fabs(mpDx1 - mpDx2) > << 1322 { 1293 G4GeometryTolerance::GetInstance()-> << 1323 solid = new G4Trap( GetName(), psolid->GetZHalfLength()*redf, 1294 { << 1324 psolid->GetYHalfLength1()*redf, 1295 solid = new G4Trap(GetName(), psolid->G << 1325 psolid->GetXHalfLength2()*redf, 1296 psolid->GetYHalfLeng << 1326 psolid->GetXHalfLength1()*redf ); 1297 psolid->GetXHalfLeng << 1327 } 1298 psolid->GetXHalfLeng << 1299 } << 1300 else 1328 else 1301 { 1329 { 1302 solid = new G4Trd( << 1330 solid = new G4Trd( GetName(), psolid->GetXHalfLength1()*redf, 1303 GetName(), psolid->GetXHalfLength1() << 1331 psolid->GetXHalfLength2()*redf, 1304 psolid->GetXHalfLength2() * redf, pso << 1332 psolid->GetYHalfLength1()*redf, 1305 psolid->GetYHalfLength2() * redf, pso << 1333 psolid->GetYHalfLength2()*redf, 1306 } << 1334 psolid->GetZHalfLength()*redf); 1307 } << 1335 } 1308 else if(parentSolid->GetEntityType() == "G4 << 1336 1309 { << 1337 } 1310 G4Para* psolid = (G4Para*) (parentSolid); << 1338 else if ( parentSolid->GetEntityType() == "G4Para" ) 1311 solid = new G4Para( << 1339 { 1312 GetName(), psolid->GetXHalfLength() * r << 1340 G4Para* psolid = (G4Para*)(parentSolid); 1313 psolid->GetYHalfLength() * redf, psolid << 1341 solid = new G4Para( GetName(), psolid->GetXHalfLength()*redf, 1314 std::atan(psolid->GetTanAlpha()), psoli << 1342 psolid->GetYHalfLength()*redf, 1315 psolid->GetSymAxis().phi()); << 1343 psolid->GetZHalfLength()*redf, 1316 } << 1344 std::atan(psolid->GetTanAlpha()), 1317 else if(parentSolid->GetEntityType() == "G4 << 1345 psolid->GetSymAxis().theta(), >> 1346 psolid->GetSymAxis().phi() ); >> 1347 } >> 1348 else if ( parentSolid->GetEntityType() == "G4Polycone" ) 1318 { 1349 { 1319 G4Polycone* psolid = (G4Polyc << 1350 G4Polycone* psolid = (G4Polycone*)(parentSolid); 1320 G4PolyconeHistorical origParam = *(psolid 1351 G4PolyconeHistorical origParam = *(psolid->GetOriginalParameters()); 1321 for(G4int ii = 0; ii < origParam.Num_z_pl << 1352 for( G4int ii = 0; ii < origParam.Num_z_planes; ii++ ) 1322 { << 1323 origParam.Rmin[ii] = origParam.Rmin[ii] << 1324 origParam.Rmax[ii] = origParam.Rmax[ii] << 1325 } << 1326 solid = new G4Polycone(GetName(), psolid- << 1327 psolid->GetEndPhi( << 1328 origParam.Z_values << 1329 } << 1330 else if(parentSolid->GetEntityType() == "G4 << 1331 { << 1332 G4GenericPolycone* psolid = (G4GenericPol << 1333 const G4int numRZ = psolid->GetNu << 1334 G4double* r = new G4double[ << 1335 G4double* z = new G4double[ << 1336 for(G4int ii = 0; ii < numRZ; ++ii) << 1337 { 1353 { 1338 r[ii] = psolid->GetCorner(ii).r; << 1354 origParam.Rmin[ii] = origParam.Rmin[ii]*redf; 1339 z[ii] = psolid->GetCorner(ii).z; << 1355 origParam.Rmax[ii] = origParam.Rmax[ii]*redf; 1340 } 1356 } 1341 solid = new G4GenericPolycone(GetName(), << 1357 solid = new G4Polycone( GetName(), psolid->GetStartPhi(), 1342 psolid->Get << 1358 psolid->GetEndPhi(), 1343 numRZ, r, z << 1359 origParam.Num_z_planes, origParam.Z_values, 1344 delete[] r; << 1360 origParam.Rmin, origParam.Rmax); 1345 delete[] z; << 1361 1346 } << 1362 } 1347 else if(parentSolid->GetEntityType() == "G4 << 1363 else if ( parentSolid->GetEntityType() == "G4Polyhedra" ) 1348 { 1364 { 1349 G4Polyhedra* psolid = (G4Poly << 1365 G4Polyhedra* psolid = (G4Polyhedra*)(parentSolid); 1350 G4PolyhedraHistorical origParam = *(psoli 1366 G4PolyhedraHistorical origParam = *(psolid->GetOriginalParameters()); 1351 for(G4int ii = 0; ii < origParam.Num_z_pl << 1367 for( G4int ii = 0; ii < origParam.Num_z_planes; ii++ ) 1352 { 1368 { 1353 origParam.Rmin[ii] = origParam.Rmin[ii] << 1369 origParam.Rmin[ii] = origParam.Rmin[ii]*redf; 1354 origParam.Rmax[ii] = origParam.Rmax[ii] << 1370 origParam.Rmax[ii] = origParam.Rmax[ii]*redf; 1355 } 1371 } 1356 solid = << 1372 solid = new G4Polyhedra( GetName(), psolid->GetStartPhi(), 1357 new G4Polyhedra(GetName(), psolid->GetS << 1373 psolid->GetEndPhi(), 1358 psolid->GetNumSide(), o << 1374 psolid->GetNumSide(), 1359 origParam.Z_values, ori << 1375 origParam.Num_z_planes, origParam.Z_values, >> 1376 origParam.Rmin, origParam.Rmax); 1360 } 1377 } 1361 else 1378 else 1362 { << 1379 { 1363 G4String ErrMessage = "Solid type not sup << 1380 G4String ErrMessage = "Solid type not supported. VOLUME= " + GetName() 1364 " Solid type= " + p << 1381 + " Solid type= " + parentSolid->GetEntityType() + "\n" 1365 "\n" + << 1382 + "Only supported types are: G4Box, G4Tubs, G4Cons," 1366 "Only supported typ << 1383 + " G4Trd, G4Para, G4Polycone, G4Polyhedra."; 1367 " G4Trd, G4Para, G4 << 1368 G4Exception("G4tgbVolume::BuildSolidForDi 1384 G4Exception("G4tgbVolume::BuildSolidForDivision()", "NotImplemented", 1369 FatalException, ErrMessage); 1385 FatalException, ErrMessage); 1370 return nullptr; << 1371 } 1386 } 1372 1387 1373 #ifdef G4VERBOSE 1388 #ifdef G4VERBOSE 1374 if(G4tgrMessenger::GetVerboseLevel() >= 1) << 1389 if( G4tgrMessenger::GetVerboseLevel() >= 1 ) 1375 { << 1390 { 1376 G4cout << " Constructing new G4Solid for << 1391 G4cout << " Constructing new G4Solid for division: " 1377 } << 1392 << *solid << G4endl; >> 1393 } 1378 #endif 1394 #endif 1379 return solid; 1395 return solid; 1380 } 1396 } >> 1397 1381 1398