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 // Implementation of G4UPolycone wrapper class << 27 // 26 // 28 // 31.10.13 G.Cosmo, CERN << 27 // $Id:$ >> 28 // >> 29 // Implementation of G4UPolycone wrapper class 29 // ------------------------------------------- 30 // -------------------------------------------------------------------- 30 31 31 #include "G4Polycone.hh" 32 #include "G4Polycone.hh" 32 #include "G4UPolycone.hh" 33 #include "G4UPolycone.hh" 33 34 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 35 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) ) 35 36 36 #include "G4GeomTools.hh" 37 #include "G4GeomTools.hh" 37 #include "G4AffineTransform.hh" 38 #include "G4AffineTransform.hh" 38 #include "G4VPVParameterisation.hh" 39 #include "G4VPVParameterisation.hh" 39 #include "G4BoundingEnvelope.hh" 40 #include "G4BoundingEnvelope.hh" 40 41 41 using namespace CLHEP; 42 using namespace CLHEP; 42 43 43 ////////////////////////////////////////////// 44 //////////////////////////////////////////////////////////////////////// 44 // 45 // 45 // Constructor (GEANT3 style parameters) 46 // Constructor (GEANT3 style parameters) 46 // << 47 // 47 G4UPolycone::G4UPolycone( const G4String& name << 48 G4UPolycone::G4UPolycone( const G4String& name, 48 G4double phiStar 49 G4double phiStart, 49 G4double phiTota 50 G4double phiTotal, 50 G4int numZPlanes 51 G4int numZPlanes, 51 const G4double zPlane[ 52 const G4double zPlane[], 52 const G4double rInner[ 53 const G4double rInner[], 53 const G4double rOuter[ 54 const G4double rOuter[] ) 54 : Base_t(name, phiStart, phiTotal, numZPlane << 55 : G4USolid(name, new UPolycone(name, phiStart, phiTotal, >> 56 numZPlanes, zPlane, rInner, rOuter)) 55 { 57 { 56 fGenericPcon = false; << 58 wrStart = phiStart; while (wrStart < 0) wrStart += twopi; 57 SetOriginalParameters(); << 58 wrStart = phiStart; << 59 while (wrStart < 0) << 60 { << 61 wrStart += twopi; << 62 } << 63 wrDelta = phiTotal; 59 wrDelta = phiTotal; 64 if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_ 60 if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_EPSILON)) 65 { 61 { 66 wrStart = 0; 62 wrStart = 0; 67 wrDelta = twopi; 63 wrDelta = twopi; 68 } 64 } 69 rzcorners.resize(0); 65 rzcorners.resize(0); 70 for (G4int i=0; i<numZPlanes; ++i) 66 for (G4int i=0; i<numZPlanes; ++i) 71 { 67 { 72 G4double z = zPlane[i]; 68 G4double z = zPlane[i]; 73 G4double r = rOuter[i]; 69 G4double r = rOuter[i]; 74 rzcorners.emplace_back(r,z); << 70 rzcorners.push_back(G4TwoVector(r,z)); 75 } 71 } 76 for (G4int i=numZPlanes-1; i>=0; --i) 72 for (G4int i=numZPlanes-1; i>=0; --i) 77 { 73 { 78 G4double z = zPlane[i]; 74 G4double z = zPlane[i]; 79 G4double r = rInner[i]; 75 G4double r = rInner[i]; 80 rzcorners.emplace_back(r,z); << 76 rzcorners.push_back(G4TwoVector(r,z)); 81 } 77 } 82 std::vector<G4int> iout; 78 std::vector<G4int> iout; 83 G4GeomTools::RemoveRedundantVertices(rzcorne 79 G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance); 84 } 80 } 85 81 86 82 87 ////////////////////////////////////////////// 83 //////////////////////////////////////////////////////////////////////// 88 // 84 // 89 // Constructor (generic parameters) 85 // Constructor (generic parameters) 90 // 86 // 91 G4UPolycone::G4UPolycone(const G4String& name, << 87 G4UPolycone::G4UPolycone(const G4String& name, 92 G4double phiSta 88 G4double phiStart, 93 G4double phiTot 89 G4double phiTotal, 94 G4int numRZ, 90 G4int numRZ, 95 const G4double r[], 91 const G4double r[], 96 const G4double z[] 92 const G4double z[] ) 97 : Base_t(name, phiStart, phiTotal, numRZ, r, << 93 : G4USolid(name, new UPolycone(name, phiStart, phiTotal, numRZ, r, z)) 98 { << 94 { 99 fGenericPcon = true; << 100 SetOriginalParameters(); << 101 wrStart = phiStart; while (wrStart < 0) wrSt 95 wrStart = phiStart; while (wrStart < 0) wrStart += twopi; 102 wrDelta = phiTotal; 96 wrDelta = phiTotal; 103 if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_ 97 if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_EPSILON)) 104 { 98 { 105 wrStart = 0; 99 wrStart = 0; 106 wrDelta = twopi; 100 wrDelta = twopi; 107 } 101 } 108 rzcorners.resize(0); 102 rzcorners.resize(0); 109 for (G4int i=0; i<numRZ; ++i) 103 for (G4int i=0; i<numRZ; ++i) 110 { 104 { 111 rzcorners.emplace_back(r[i],z[i]); << 105 rzcorners.push_back(G4TwoVector(r[i],z[i])); 112 } 106 } 113 std::vector<G4int> iout; 107 std::vector<G4int> iout; 114 G4GeomTools::RemoveRedundantVertices(rzcorne 108 G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance); 115 } 109 } 116 110 117 111 118 ////////////////////////////////////////////// 112 //////////////////////////////////////////////////////////////////////// 119 // 113 // 120 // Fake default constructor - sets only member 114 // Fake default constructor - sets only member data and allocates memory 121 // for usage restri 115 // for usage restricted to object persistency. 122 // 116 // 123 G4UPolycone::G4UPolycone( __void__& a ) 117 G4UPolycone::G4UPolycone( __void__& a ) 124 : Base_t(a) << 118 : G4USolid(a) 125 { 119 { 126 } 120 } 127 121 128 122 129 ////////////////////////////////////////////// 123 //////////////////////////////////////////////////////////////////////// 130 // 124 // 131 // Destructor 125 // Destructor 132 // 126 // 133 G4UPolycone::~G4UPolycone() = default; << 127 G4UPolycone::~G4UPolycone() >> 128 { >> 129 } 134 130 135 131 136 ////////////////////////////////////////////// 132 //////////////////////////////////////////////////////////////////////// 137 // 133 // 138 // Copy constructor 134 // Copy constructor 139 // 135 // 140 G4UPolycone::G4UPolycone( const G4UPolycone& s << 136 G4UPolycone::G4UPolycone( const G4UPolycone &source ) 141 : Base_t( source ) << 137 : G4USolid( source ) 142 { 138 { 143 fGenericPcon = source.fGenericPcon; << 144 fOriginalParameters = source.fOriginalParame << 145 wrStart = source.wrStart; 139 wrStart = source.wrStart; 146 wrDelta = source.wrDelta; 140 wrDelta = source.wrDelta; 147 rzcorners = source.rzcorners; 141 rzcorners = source.rzcorners; 148 } 142 } 149 143 150 144 151 ////////////////////////////////////////////// 145 //////////////////////////////////////////////////////////////////////// 152 // 146 // 153 // Assignment operator 147 // Assignment operator 154 // 148 // 155 G4UPolycone& G4UPolycone::operator=( const G4U << 149 G4UPolycone &G4UPolycone::operator=( const G4UPolycone &source ) 156 { 150 { 157 if (this == &source) return *this; 151 if (this == &source) return *this; 158 << 152 159 Base_t::operator=( source ); << 153 G4USolid::operator=( source ); 160 fGenericPcon = source.fGenericPcon; << 161 fOriginalParameters = source.fOriginalParame << 162 wrStart = source.wrStart; 154 wrStart = source.wrStart; 163 wrDelta = source.wrDelta; 155 wrDelta = source.wrDelta; 164 rzcorners = source.rzcorners; 156 rzcorners = source.rzcorners; 165 157 166 return *this; 158 return *this; 167 } 159 } 168 160 169 161 170 ////////////////////////////////////////////// 162 //////////////////////////////////////////////////////////////////////// 171 // 163 // 172 // Accessors & modifiers 164 // Accessors & modifiers 173 // 165 // 174 G4double G4UPolycone::GetStartPhi() const 166 G4double G4UPolycone::GetStartPhi() const 175 { 167 { 176 return wrStart; 168 return wrStart; 177 } 169 } 178 G4double G4UPolycone::GetDeltaPhi() const << 179 { << 180 return wrDelta; << 181 } << 182 G4double G4UPolycone::GetEndPhi() const 170 G4double G4UPolycone::GetEndPhi() const 183 { 171 { 184 return (wrStart + wrDelta); 172 return (wrStart + wrDelta); 185 } 173 } 186 G4double G4UPolycone::GetSinStartPhi() const 174 G4double G4UPolycone::GetSinStartPhi() const 187 { 175 { 188 if (!IsOpen()) return 0.; << 176 if (!IsOpen()) return 0; 189 G4double phi = GetStartPhi(); 177 G4double phi = GetStartPhi(); 190 return std::sin(phi); 178 return std::sin(phi); 191 } 179 } 192 G4double G4UPolycone::GetCosStartPhi() const 180 G4double G4UPolycone::GetCosStartPhi() const 193 { 181 { 194 if (!IsOpen()) return 1.; << 182 if (!IsOpen()) return 1; 195 G4double phi = GetStartPhi(); 183 G4double phi = GetStartPhi(); 196 return std::cos(phi); 184 return std::cos(phi); 197 } 185 } 198 G4double G4UPolycone::GetSinEndPhi() const 186 G4double G4UPolycone::GetSinEndPhi() const 199 { 187 { 200 if (!IsOpen()) return 0.; << 188 if (!IsOpen()) return 0; 201 G4double phi = GetEndPhi(); 189 G4double phi = GetEndPhi(); 202 return std::sin(phi); 190 return std::sin(phi); 203 } 191 } 204 G4double G4UPolycone::GetCosEndPhi() const 192 G4double G4UPolycone::GetCosEndPhi() const 205 { 193 { 206 if (!IsOpen()) return 1.; << 194 if (!IsOpen()) return 1; 207 G4double phi = GetEndPhi(); 195 G4double phi = GetEndPhi(); 208 return std::cos(phi); 196 return std::cos(phi); 209 } 197 } 210 G4bool G4UPolycone::IsOpen() const 198 G4bool G4UPolycone::IsOpen() const 211 { 199 { 212 return (wrDelta < twopi); 200 return (wrDelta < twopi); 213 } 201 } 214 G4int G4UPolycone::GetNumRZCorner() const 202 G4int G4UPolycone::GetNumRZCorner() const 215 { 203 { 216 return rzcorners.size(); 204 return rzcorners.size(); 217 } 205 } 218 G4PolyconeSideRZ G4UPolycone::GetCorner(G4int 206 G4PolyconeSideRZ G4UPolycone::GetCorner(G4int index) const 219 { 207 { 220 G4TwoVector rz = rzcorners.at(index); 208 G4TwoVector rz = rzcorners.at(index); 221 G4PolyconeSideRZ psiderz = { rz.x(), rz.y() 209 G4PolyconeSideRZ psiderz = { rz.x(), rz.y() }; 222 210 223 return psiderz; 211 return psiderz; 224 } 212 } 225 G4PolyconeHistorical* G4UPolycone::GetOriginal 213 G4PolyconeHistorical* G4UPolycone::GetOriginalParameters() const 226 { 214 { 227 return new G4PolyconeHistorical(fOriginalPar << 215 UPolyconeHistorical* pars = GetShape()->GetOriginalParameters(); 228 } << 216 G4PolyconeHistorical* pdata = new G4PolyconeHistorical(pars->fNumZPlanes); 229 void G4UPolycone::SetOriginalParameters() << 217 pdata->Start_angle = pars->fStartAngle; 230 { << 218 pdata->Opening_angle = pars->fOpeningAngle; 231 vecgeom::PolyconeHistorical* original_parame << 219 for (G4int i=0; i<pars->fNumZPlanes; ++i) 232 << 220 { 233 fOriginalParameters.Start_angle = original << 221 pdata->Z_values[i] = pars->fZValues[i]; 234 fOriginalParameters.Opening_angle = original << 222 pdata->Rmin[i] = pars->Rmin[i]; 235 fOriginalParameters.Num_z_planes = original << 223 pdata->Rmax[i] = pars->Rmax[i]; 236 << 237 delete [] fOriginalParameters.Z_values; << 238 delete [] fOriginalParameters.Rmin; << 239 delete [] fOriginalParameters.Rmax; << 240 << 241 G4int numPlanes = fOriginalParameters.Num_z_ << 242 fOriginalParameters.Z_values = new G4double[ << 243 fOriginalParameters.Rmin = new G4double[numP << 244 fOriginalParameters.Rmax = new G4double[numP << 245 for (G4int i=0; i<numPlanes; ++i) << 246 { << 247 fOriginalParameters.Z_values[i] = original << 248 fOriginalParameters.Rmin[i] = original << 249 fOriginalParameters.Rmax[i] = original << 250 } 224 } >> 225 return pdata; 251 } 226 } 252 void G4UPolycone::SetOriginalParameters(G4Poly 227 void G4UPolycone::SetOriginalParameters(G4PolyconeHistorical* pars) 253 { 228 { 254 fOriginalParameters = *pars; << 229 UPolyconeHistorical* pdata = GetShape()->GetOriginalParameters(); 255 fRebuildPolyhedron = true; << 230 pdata->fStartAngle = pars->Start_angle; 256 Reset(); << 231 pdata->fOpeningAngle = pars->Opening_angle; 257 } << 232 pdata->fNumZPlanes = pars->Num_z_planes; 258 << 233 for (G4int i=0; i<pdata->fNumZPlanes; ++i) 259 G4bool G4UPolycone::Reset() << 234 { 260 { << 235 pdata->fZValues[i] = pars->Z_values[i]; 261 if (fGenericPcon) << 236 pdata->Rmin[i] = pars->Rmin[i]; 262 { << 237 pdata->Rmax[i] = pars->Rmax[i]; 263 std::ostringstream message; << 264 message << "Solid " << GetName() << " buil << 265 << G4endl << "Not applicable to th << 266 G4Exception("G4UPolycone::Reset()", "GeomS << 267 JustWarning, message, "Paramet << 268 return true; // error code set << 269 } 238 } >> 239 fRebuildPolyhedron = true; 270 240 271 // << 241 wrStart = pdata->fStartAngle; while (wrStart < 0) wrStart += twopi; 272 // Rebuild polycone based on original parame << 242 wrDelta = pdata->fOpeningAngle; 273 // << 243 if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_EPSILON)) 274 wrStart = fOriginalParameters.Start_angle; << 275 while (wrStart < 0.) << 276 { << 277 wrStart += twopi; << 278 } << 279 wrDelta = fOriginalParameters.Opening_angle; << 280 if (wrDelta <= 0. || wrDelta >= twopi*(1-DBL << 281 { 244 { 282 wrStart = 0.; << 245 wrStart = 0; 283 wrDelta = twopi; 246 wrDelta = twopi; 284 } 247 } 285 rzcorners.resize(0); 248 rzcorners.resize(0); 286 for (G4int i=0; i<fOriginalParameters.Num_z_ << 249 for (G4int i=0; i<pdata->fNumZPlanes; ++i) 287 { 250 { 288 G4double z = fOriginalParameters.Z_value << 251 G4double z = pdata->fZValues[i]; 289 G4double r = fOriginalParameters.Rmax[i] << 252 G4double r = pdata->Rmax[i]; 290 rzcorners.emplace_back(r,z); << 253 rzcorners.push_back(G4TwoVector(r,z)); 291 } 254 } 292 for (G4int i=fOriginalParameters.Num_z_plane << 255 for (G4int i=pdata->fNumZPlanes-1; i>=0; --i) 293 { 256 { 294 G4double z = fOriginalParameters.Z_value << 257 G4double z = pdata->fZValues[i]; 295 G4double r = fOriginalParameters.Rmin[i] << 258 G4double r = pdata->Rmin[i]; 296 rzcorners.emplace_back(r,z); << 259 rzcorners.push_back(G4TwoVector(r,z)); 297 } 260 } 298 std::vector<G4int> iout; 261 std::vector<G4int> iout; 299 G4GeomTools::RemoveRedundantVertices(rzcorne 262 G4GeomTools::RemoveRedundantVertices(rzcorners,iout,2*kCarTolerance); 300 << 263 } 301 return false; // error code unset << 264 G4bool G4UPolycone::Reset() >> 265 { >> 266 GetShape()->Reset(); >> 267 return 0; 302 } 268 } 303 269 304 ////////////////////////////////////////////// 270 //////////////////////////////////////////////////////////////////////// 305 // 271 // 306 // Dispatch to parameterisation for replicatio 272 // Dispatch to parameterisation for replication mechanism dimension 307 // computation & modification. 273 // computation & modification. 308 // 274 // 309 void G4UPolycone::ComputeDimensions(G4VPVParam 275 void G4UPolycone::ComputeDimensions(G4VPVParameterisation* p, 310 const G4in 276 const G4int n, 311 const G4VP 277 const G4VPhysicalVolume* pRep) 312 { 278 { 313 p->ComputeDimensions(*(G4Polycone*)this,n,pR 279 p->ComputeDimensions(*(G4Polycone*)this,n,pRep); 314 } 280 } 315 281 316 282 317 ////////////////////////////////////////////// 283 ////////////////////////////////////////////////////////////////////////// 318 // 284 // 319 // Make a clone of the object 285 // Make a clone of the object 320 286 321 G4VSolid* G4UPolycone::Clone() const 287 G4VSolid* G4UPolycone::Clone() const 322 { 288 { 323 return new G4UPolycone(*this); 289 return new G4UPolycone(*this); 324 } 290 } 325 291 326 ////////////////////////////////////////////// 292 ////////////////////////////////////////////////////////////////////////// 327 // 293 // 328 // Get bounding box 294 // Get bounding box 329 295 330 void G4UPolycone::BoundingLimits(G4ThreeVector << 296 void G4UPolycone::Extent(G4ThreeVector& pMin, G4ThreeVector& pMax) const 331 G4ThreeVector << 332 { 297 { 333 static G4bool checkBBox = true; 298 static G4bool checkBBox = true; 334 static G4bool checkPhi = true; 299 static G4bool checkPhi = true; 335 300 336 G4double rmin = kInfinity, rmax = -kInfinity 301 G4double rmin = kInfinity, rmax = -kInfinity; 337 G4double zmin = kInfinity, zmax = -kInfinity 302 G4double zmin = kInfinity, zmax = -kInfinity; 338 303 339 for (G4int i=0; i<GetNumRZCorner(); ++i) 304 for (G4int i=0; i<GetNumRZCorner(); ++i) 340 { 305 { 341 G4PolyconeSideRZ corner = GetCorner(i); 306 G4PolyconeSideRZ corner = GetCorner(i); 342 if (corner.r < rmin) rmin = corner.r; 307 if (corner.r < rmin) rmin = corner.r; 343 if (corner.r > rmax) rmax = corner.r; 308 if (corner.r > rmax) rmax = corner.r; 344 if (corner.z < zmin) zmin = corner.z; 309 if (corner.z < zmin) zmin = corner.z; 345 if (corner.z > zmax) zmax = corner.z; 310 if (corner.z > zmax) zmax = corner.z; 346 } 311 } 347 312 348 if (IsOpen()) 313 if (IsOpen()) 349 { 314 { 350 G4TwoVector vmin,vmax; 315 G4TwoVector vmin,vmax; 351 G4GeomTools::DiskExtent(rmin,rmax, 316 G4GeomTools::DiskExtent(rmin,rmax, 352 GetSinStartPhi(),G 317 GetSinStartPhi(),GetCosStartPhi(), 353 GetSinEndPhi(),Get 318 GetSinEndPhi(),GetCosEndPhi(), 354 vmin,vmax); 319 vmin,vmax); 355 pMin.set(vmin.x(),vmin.y(),zmin); 320 pMin.set(vmin.x(),vmin.y(),zmin); 356 pMax.set(vmax.x(),vmax.y(),zmax); 321 pMax.set(vmax.x(),vmax.y(),zmax); 357 } 322 } 358 else 323 else 359 { 324 { 360 pMin.set(-rmax,-rmax, zmin); 325 pMin.set(-rmax,-rmax, zmin); 361 pMax.set( rmax, rmax, zmax); 326 pMax.set( rmax, rmax, zmax); 362 } 327 } 363 328 364 // Check correctness of the bounding box 329 // Check correctness of the bounding box 365 // 330 // 366 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 331 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) 367 { 332 { 368 std::ostringstream message; 333 std::ostringstream message; 369 message << "Bad bounding box (min >= max) 334 message << "Bad bounding box (min >= max) for solid: " 370 << GetName() << " !" 335 << GetName() << " !" 371 << "\npMin = " << pMin 336 << "\npMin = " << pMin 372 << "\npMax = " << pMax; 337 << "\npMax = " << pMax; 373 G4Exception("G4UPolycone::BoundingLimits() << 338 G4Exception("G4UPolycone::Extent()", "GeomMgt0001", JustWarning, message); 374 JustWarning, message); << 375 StreamInfo(G4cout); 339 StreamInfo(G4cout); 376 } 340 } 377 341 378 // Check consistency of bounding boxes 342 // Check consistency of bounding boxes 379 // 343 // 380 if (checkBBox) 344 if (checkBBox) 381 { 345 { 382 U3Vector vmin, vmax; << 346 UVector3 vmin, vmax; 383 Extent(vmin,vmax); << 347 GetShape()->Extent(vmin,vmax); 384 if (std::abs(pMin.x()-vmin.x()) > kCarTole 348 if (std::abs(pMin.x()-vmin.x()) > kCarTolerance || 385 std::abs(pMin.y()-vmin.y()) > kCarTole 349 std::abs(pMin.y()-vmin.y()) > kCarTolerance || 386 std::abs(pMin.z()-vmin.z()) > kCarTole 350 std::abs(pMin.z()-vmin.z()) > kCarTolerance || 387 std::abs(pMax.x()-vmax.x()) > kCarTole 351 std::abs(pMax.x()-vmax.x()) > kCarTolerance || 388 std::abs(pMax.y()-vmax.y()) > kCarTole 352 std::abs(pMax.y()-vmax.y()) > kCarTolerance || 389 std::abs(pMax.z()-vmax.z()) > kCarTole 353 std::abs(pMax.z()-vmax.z()) > kCarTolerance) 390 { 354 { 391 std::ostringstream message; 355 std::ostringstream message; 392 message << "Inconsistency in bounding bo 356 message << "Inconsistency in bounding boxes for solid: " 393 << GetName() << " !" 357 << GetName() << " !" 394 << "\nBBox min: wrapper = " << p 358 << "\nBBox min: wrapper = " << pMin << " solid = " << vmin 395 << "\nBBox max: wrapper = " << p 359 << "\nBBox max: wrapper = " << pMax << " solid = " << vmax; 396 G4Exception("G4UPolycone::BoundingLimits << 360 G4Exception("G4UPolycone::Extent()", "GeomMgt0001", JustWarning, message); 397 JustWarning, message); << 398 checkBBox = false; 361 checkBBox = false; 399 } 362 } 400 } 363 } 401 364 402 // Check consistency of angles 365 // Check consistency of angles 403 // 366 // 404 if (checkPhi) 367 if (checkPhi) 405 { 368 { 406 if (GetStartPhi() != Base_t::GetStartPhi() << 369 if (GetStartPhi() != GetShape()->GetStartPhi() || 407 GetEndPhi() != Base_t::GetEndPhi() << 370 GetEndPhi() != GetShape()->GetEndPhi() || 408 IsOpen() != (Base_t::GetDeltaPhi( << 371 IsOpen() != GetShape()->IsOpen()) 409 { 372 { 410 std::ostringstream message; 373 std::ostringstream message; 411 message << "Inconsistency in Phi angles 374 message << "Inconsistency in Phi angles or # of sides for solid: " 412 << GetName() << " !" 375 << GetName() << " !" 413 << "\nPhi start : wrapper = " < 376 << "\nPhi start : wrapper = " << GetStartPhi() 414 << " solid = " << Base_t::Ge << 377 << " solid = " << GetShape()->GetStartPhi() 415 << "\nPhi end : wrapper = " < 378 << "\nPhi end : wrapper = " << GetEndPhi() 416 << " solid = " << Base_t::Ge << 379 << " solid = " << GetShape()->GetEndPhi() 417 << "\nPhi is open: wrapper = " < 380 << "\nPhi is open: wrapper = " << (IsOpen() ? "true" : "false") 418 << " solid = " << 381 << " solid = " << (GetShape()->IsOpen() ? "true" : "false"); 419 << ((Base_t::GetDeltaPhi() < two << 382 G4Exception("G4UPolycone::Extent()", "GeomMgt0001", JustWarning, message); 420 G4Exception("G4UPolycone::BoundingLimits << 421 JustWarning, message); << 422 checkPhi = false; 383 checkPhi = false; 423 } 384 } 424 } 385 } 425 } 386 } 426 387 427 ////////////////////////////////////////////// 388 ////////////////////////////////////////////////////////////////////////// 428 // 389 // 429 // Calculate extent under transform and specif 390 // Calculate extent under transform and specified limit 430 391 431 G4bool G4UPolycone::CalculateExtent(const EAxi 392 G4bool G4UPolycone::CalculateExtent(const EAxis pAxis, 432 const G4Vo 393 const G4VoxelLimits& pVoxelLimit, 433 const G4Af 394 const G4AffineTransform& pTransform, 434 G4do 395 G4double& pMin, G4double& pMax) const 435 { 396 { 436 G4ThreeVector bmin, bmax; 397 G4ThreeVector bmin, bmax; 437 G4bool exist; 398 G4bool exist; 438 399 439 // Check bounding box (bbox) 400 // Check bounding box (bbox) 440 // 401 // 441 BoundingLimits(bmin,bmax); << 402 Extent(bmin,bmax); 442 G4BoundingEnvelope bbox(bmin,bmax); 403 G4BoundingEnvelope bbox(bmin,bmax); 443 #ifdef G4BBOX_EXTENT 404 #ifdef G4BBOX_EXTENT 444 return bbox.CalculateExtent(pAxis,pVoxelLimi << 405 if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 445 #endif 406 #endif 446 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox 407 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax)) 447 { 408 { 448 return exist = pMin < pMax; << 409 return exist = (pMin < pMax) ? true : false; 449 } 410 } 450 411 451 // To find the extent, RZ contour of the pol 412 // To find the extent, RZ contour of the polycone is subdivided 452 // in triangles. The extent is calculated as 413 // in triangles. The extent is calculated as cumulative extent of 453 // all sub-polycones formed by rotation of t 414 // all sub-polycones formed by rotation of triangles around Z 454 // 415 // 455 G4TwoVectorList contourRZ; 416 G4TwoVectorList contourRZ; 456 G4TwoVectorList triangles; 417 G4TwoVectorList triangles; 457 std::vector<G4int> iout; 418 std::vector<G4int> iout; 458 G4double eminlim = pVoxelLimit.GetMinExtent( 419 G4double eminlim = pVoxelLimit.GetMinExtent(pAxis); 459 G4double emaxlim = pVoxelLimit.GetMaxExtent( 420 G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis); 460 421 461 // get RZ contour, ensure anticlockwise orde 422 // get RZ contour, ensure anticlockwise order of corners 462 for (G4int i=0; i<GetNumRZCorner(); ++i) 423 for (G4int i=0; i<GetNumRZCorner(); ++i) 463 { 424 { 464 G4PolyconeSideRZ corner = GetCorner(i); 425 G4PolyconeSideRZ corner = GetCorner(i); 465 contourRZ.emplace_back(corner.r,corner.z); << 426 contourRZ.push_back(G4TwoVector(corner.r,corner.z)); 466 } 427 } 467 G4GeomTools::RemoveRedundantVertices(contour 428 G4GeomTools::RemoveRedundantVertices(contourRZ,iout,2*kCarTolerance); 468 G4double area = G4GeomTools::PolygonArea(con 429 G4double area = G4GeomTools::PolygonArea(contourRZ); 469 if (area < 0.) std::reverse(contourRZ.begin( 430 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end()); 470 431 471 // triangulate RZ countour 432 // triangulate RZ countour 472 if (!G4GeomTools::TriangulatePolygon(contour 433 if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles)) 473 { 434 { 474 std::ostringstream message; 435 std::ostringstream message; 475 message << "Triangulation of RZ contour ha 436 message << "Triangulation of RZ contour has failed for solid: " 476 << GetName() << " !" 437 << GetName() << " !" 477 << "\nExtent has been calculated u 438 << "\nExtent has been calculated using boundary box"; 478 G4Exception("G4UPolycone::CalculateExtent( 439 G4Exception("G4UPolycone::CalculateExtent()", 479 "GeomMgt1002", JustWarning, me 440 "GeomMgt1002", JustWarning, message); 480 return bbox.CalculateExtent(pAxis,pVoxelLi 441 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 481 } 442 } 482 443 483 // set trigonometric values 444 // set trigonometric values 484 const G4int NSTEPS = 24; // numbe 445 const G4int NSTEPS = 24; // number of steps for whole circle 485 G4double astep = twopi/NSTEPS; // max a 446 G4double astep = twopi/NSTEPS; // max angle for one step 486 447 487 G4double sphi = GetStartPhi(); 448 G4double sphi = GetStartPhi(); 488 G4double ephi = GetEndPhi(); 449 G4double ephi = GetEndPhi(); 489 G4double dphi = IsOpen() ? ephi-sphi : two 450 G4double dphi = IsOpen() ? ephi-sphi : twopi; 490 G4int ksteps = (dphi <= astep) ? 1 : (G4i 451 G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1; 491 G4double ang = dphi/ksteps; 452 G4double ang = dphi/ksteps; 492 453 493 G4double sinHalf = std::sin(0.5*ang); 454 G4double sinHalf = std::sin(0.5*ang); 494 G4double cosHalf = std::cos(0.5*ang); 455 G4double cosHalf = std::cos(0.5*ang); 495 G4double sinStep = 2.*sinHalf*cosHalf; 456 G4double sinStep = 2.*sinHalf*cosHalf; 496 G4double cosStep = 1. - 2.*sinHalf*sinHalf; 457 G4double cosStep = 1. - 2.*sinHalf*sinHalf; 497 458 498 G4double sinStart = GetSinStartPhi(); 459 G4double sinStart = GetSinStartPhi(); 499 G4double cosStart = GetCosStartPhi(); 460 G4double cosStart = GetCosStartPhi(); 500 G4double sinEnd = GetSinEndPhi(); 461 G4double sinEnd = GetSinEndPhi(); 501 G4double cosEnd = GetCosEndPhi(); 462 G4double cosEnd = GetCosEndPhi(); 502 463 503 // define vectors and arrays 464 // define vectors and arrays 504 std::vector<const G4ThreeVectorList *> polyg 465 std::vector<const G4ThreeVectorList *> polygons; 505 polygons.resize(ksteps+2); 466 polygons.resize(ksteps+2); 506 G4ThreeVectorList pols[NSTEPS+2]; 467 G4ThreeVectorList pols[NSTEPS+2]; 507 for (G4int k=0; k<ksteps+2; ++k) pols[k].res 468 for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(6); 508 for (G4int k=0; k<ksteps+2; ++k) polygons[k] 469 for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k]; 509 G4double r0[6],z0[6]; // contour with origin 470 G4double r0[6],z0[6]; // contour with original edges of triangle 510 G4double r1[6]; // shifted radii of ex 471 G4double r1[6]; // shifted radii of external edges of triangle 511 472 512 // main loop along triangles 473 // main loop along triangles 513 pMin = kInfinity; 474 pMin = kInfinity; 514 pMax =-kInfinity; 475 pMax =-kInfinity; 515 G4int ntria = triangles.size()/3; 476 G4int ntria = triangles.size()/3; 516 for (G4int i=0; i<ntria; ++i) 477 for (G4int i=0; i<ntria; ++i) 517 { 478 { 518 G4int i3 = i*3; 479 G4int i3 = i*3; 519 for (G4int k=0; k<3; ++k) 480 for (G4int k=0; k<3; ++k) 520 { 481 { 521 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3; 482 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3; 522 G4int k2 = k*2; 483 G4int k2 = k*2; 523 // set contour with original edges of tr 484 // set contour with original edges of triangle 524 r0[k2+0] = triangles[e0].x(); z0[k2+0] = 485 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y(); 525 r0[k2+1] = triangles[e1].x(); z0[k2+1] = 486 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y(); 526 // set shifted radii 487 // set shifted radii 527 r1[k2+0] = r0[k2+0]; 488 r1[k2+0] = r0[k2+0]; 528 r1[k2+1] = r0[k2+1]; 489 r1[k2+1] = r0[k2+1]; 529 if (z0[k2+1] - z0[k2+0] <= 0) continue; 490 if (z0[k2+1] - z0[k2+0] <= 0) continue; 530 r1[k2+0] /= cosHalf; 491 r1[k2+0] /= cosHalf; 531 r1[k2+1] /= cosHalf; 492 r1[k2+1] /= cosHalf; 532 } 493 } 533 494 534 // rotate countour, set sequence of 6-side 495 // rotate countour, set sequence of 6-sided polygons 535 G4double sinCur = sinStart*cosHalf + cosSt 496 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf; 536 G4double cosCur = cosStart*cosHalf - sinSt 497 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf; 537 for (G4int j=0; j<6; ++j) pols[0][j].set(r 498 for (G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]); 538 for (G4int k=1; k<ksteps+1; ++k) 499 for (G4int k=1; k<ksteps+1; ++k) 539 { 500 { 540 for (G4int j=0; j<6; ++j) pols[k][j].set 501 for (G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]); 541 G4double sinTmp = sinCur; 502 G4double sinTmp = sinCur; 542 sinCur = sinCur*cosStep + cosCur*sinStep 503 sinCur = sinCur*cosStep + cosCur*sinStep; 543 cosCur = cosCur*cosStep - sinTmp*sinStep 504 cosCur = cosCur*cosStep - sinTmp*sinStep; 544 } 505 } 545 for (G4int j=0; j<6; ++j) pols[ksteps+1][j 506 for (G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]); 546 507 547 // set sub-envelope and adjust extent 508 // set sub-envelope and adjust extent 548 G4double emin,emax; 509 G4double emin,emax; 549 G4BoundingEnvelope benv(polygons); 510 G4BoundingEnvelope benv(polygons); 550 if (!benv.CalculateExtent(pAxis,pVoxelLimi 511 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue; 551 if (emin < pMin) pMin = emin; 512 if (emin < pMin) pMin = emin; 552 if (emax > pMax) pMax = emax; 513 if (emax > pMax) pMax = emax; 553 if (eminlim > pMin && emaxlim < pMax) retu 514 if (eminlim > pMin && emaxlim < pMax) return true; // max possible extent 554 } 515 } 555 return (pMin < pMax); 516 return (pMin < pMax); 556 } 517 } 557 518 558 ////////////////////////////////////////////// 519 //////////////////////////////////////////////////////////////////////// 559 // 520 // 560 // CreatePolyhedron 521 // CreatePolyhedron 561 // 522 // 562 G4Polyhedron* G4UPolycone::CreatePolyhedron() 523 G4Polyhedron* G4UPolycone::CreatePolyhedron() const 563 { 524 { 564 return new G4PolyhedronPcon(wrStart, wrDelta << 525 G4PolyconeHistorical* original_parameters = GetOriginalParameters(); >> 526 G4PolyhedronPcon* >> 527 polyhedron = new G4PolyhedronPcon( original_parameters->Start_angle, >> 528 original_parameters->Opening_angle, >> 529 original_parameters->Num_z_planes, >> 530 original_parameters->Z_values, >> 531 original_parameters->Rmin, >> 532 original_parameters->Rmax ); >> 533 >> 534 delete original_parameters; // delete local copy >> 535 >> 536 return polyhedron; 565 } 537 } 566 538 567 #endif // G4GEOM_USE_USOLIDS 539 #endif // G4GEOM_USE_USOLIDS 568 540