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