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