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 G4UGenericTrap wrapper cl << 27 // 26 // 28 // 30.10.13 G.Cosmo, CERN << 27 // $Id:$ >> 28 // >> 29 // >> 30 // Implementation of G4UGenericTrap wrapper class 29 // ------------------------------------------- 31 // -------------------------------------------------------------------- 30 32 31 #include "G4GenericTrap.hh" 33 #include "G4GenericTrap.hh" 32 #include "G4UGenericTrap.hh" 34 #include "G4UGenericTrap.hh" 33 35 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 36 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) ) 35 37 36 #include "G4AffineTransform.hh" 38 #include "G4AffineTransform.hh" 37 #include "G4VPVParameterisation.hh" 39 #include "G4VPVParameterisation.hh" 38 #include "G4BoundingEnvelope.hh" 40 #include "G4BoundingEnvelope.hh" 39 41 40 #include "G4Polyhedron.hh" 42 #include "G4Polyhedron.hh" >> 43 #include "G4PolyhedronArbitrary.hh" 41 44 >> 45 #include "G4AutoLock.hh" >> 46 namespace { G4Mutex UGenericTrapMutex = G4MUTEX_INITIALIZER; } 42 using namespace CLHEP; 47 using namespace CLHEP; 43 48 44 ////////////////////////////////////////////// 49 //////////////////////////////////////////////////////////////////////// 45 // 50 // 46 // Constructor (generic parameters) 51 // Constructor (generic parameters) 47 // 52 // 48 G4UGenericTrap::G4UGenericTrap(const G4String& 53 G4UGenericTrap::G4UGenericTrap(const G4String& name, G4double halfZ, 49 const std::vect 54 const std::vector<G4TwoVector>& vertices) 50 : Base_t(name), fVisSubdivisions(0) << 55 : G4USolid(name, new UGenericTrap()) 51 { 56 { 52 SetZHalfLength(halfZ); 57 SetZHalfLength(halfZ); 53 Initialise(vertices); << 58 std::vector<UVector2> v; >> 59 for (size_t n=0; n<vertices.size(); ++n) >> 60 { >> 61 v.push_back(UVector2(vertices[n].x(),vertices[n].y())); >> 62 } >> 63 GetShape()->SetName(name); >> 64 GetShape()->Initialise(v); 54 } 65 } 55 66 56 67 57 ////////////////////////////////////////////// 68 //////////////////////////////////////////////////////////////////////// 58 // 69 // 59 // Fake default constructor - sets only member 70 // Fake default constructor - sets only member data and allocates memory 60 // for usage restri 71 // for usage restricted to object persistency. 61 // 72 // 62 G4UGenericTrap::G4UGenericTrap(__void__& a) 73 G4UGenericTrap::G4UGenericTrap(__void__& a) 63 : Base_t(a), fVisSubdivisions(0) << 74 : G4USolid(a) 64 { 75 { 65 } 76 } 66 77 67 78 68 ////////////////////////////////////////////// 79 ////////////////////////////////////////////////////////////////////////// 69 // 80 // 70 // Destructor 81 // Destructor 71 // 82 // 72 G4UGenericTrap::~G4UGenericTrap() = default; << 83 G4UGenericTrap::~G4UGenericTrap() >> 84 { >> 85 } 73 86 74 87 75 ////////////////////////////////////////////// 88 ////////////////////////////////////////////////////////////////////////// 76 // 89 // 77 // Copy constructor 90 // Copy constructor 78 // 91 // 79 G4UGenericTrap::G4UGenericTrap(const G4UGeneri << 92 G4UGenericTrap::G4UGenericTrap(const G4UGenericTrap &source) 80 : Base_t(source), fVisSubdivisions(source.fV << 93 : G4USolid(source) 81 fVertices(source.fVertices) << 82 { 94 { 83 } 95 } 84 96 85 97 86 ////////////////////////////////////////////// 98 ////////////////////////////////////////////////////////////////////////// 87 // 99 // 88 // Assignment operator 100 // Assignment operator 89 // 101 // 90 G4UGenericTrap& 102 G4UGenericTrap& 91 G4UGenericTrap::operator=(const G4UGenericTrap << 103 G4UGenericTrap::operator=(const G4UGenericTrap &source) 92 { 104 { 93 if (this == &source) return *this; 105 if (this == &source) return *this; 94 106 95 Base_t::operator=( source ); << 107 G4USolid::operator=( source ); 96 fVertices = source.fVertices; << 97 fVisSubdivisions = source.fVisSubdivisions; << 98 108 99 return *this; 109 return *this; 100 } 110 } 101 111 102 ////////////////////////////////////////////// 112 ////////////////////////////////////////////////////////////////////////// 103 // 113 // 104 // Accessors & modifiers 114 // Accessors & modifiers 105 // 115 // 106 G4double G4UGenericTrap::GetZHalfLength() cons 116 G4double G4UGenericTrap::GetZHalfLength() const 107 { 117 { 108 return GetDZ(); << 118 return GetShape()->GetZHalfLength(); 109 } 119 } 110 G4int G4UGenericTrap::GetNofVertices() const 120 G4int G4UGenericTrap::GetNofVertices() const 111 { 121 { 112 return fVertices.size(); << 122 return GetShape()->GetNofVertices(); 113 } 123 } 114 G4TwoVector G4UGenericTrap::GetVertex(G4int in 124 G4TwoVector G4UGenericTrap::GetVertex(G4int index) const 115 { 125 { 116 return { GetVerticesX()[index], GetVerticesY << 126 UVector2 v = GetShape()->GetVertex(index); >> 127 return G4TwoVector(v.x,v.y); 117 } 128 } 118 const std::vector<G4TwoVector>& G4UGenericTrap 129 const std::vector<G4TwoVector>& G4UGenericTrap::GetVertices() const 119 { 130 { 120 return fVertices; << 131 G4AutoLock l(&UGenericTrapMutex); >> 132 std::vector<UVector2> v = GetShape()->GetVertices(); >> 133 static std::vector<G4TwoVector> vertices; vertices.clear(); >> 134 for (size_t n=0; n<v.size(); ++n) >> 135 { >> 136 vertices.push_back(G4TwoVector(v[n].x,v[n].y)); >> 137 } >> 138 return vertices; 121 } 139 } 122 G4double G4UGenericTrap::GetTwistAngle(G4int i 140 G4double G4UGenericTrap::GetTwistAngle(G4int index) const 123 { 141 { 124 return GetTwist(index); << 142 return GetShape()->GetTwistAngle(index); 125 } 143 } 126 G4bool G4UGenericTrap::IsTwisted() const 144 G4bool G4UGenericTrap::IsTwisted() const 127 { 145 { 128 return !IsPlanar(); << 146 return GetShape()->IsTwisted(); 129 } 147 } 130 G4int G4UGenericTrap::GetVisSubdivisions() con 148 G4int G4UGenericTrap::GetVisSubdivisions() const 131 { 149 { 132 return fVisSubdivisions; << 150 return GetShape()->GetVisSubdivisions(); 133 } 151 } 134 152 135 void G4UGenericTrap::SetVisSubdivisions(G4int 153 void G4UGenericTrap::SetVisSubdivisions(G4int subdiv) 136 { 154 { 137 fVisSubdivisions = subdiv; << 155 GetShape()->SetVisSubdivisions(subdiv); 138 } 156 } 139 157 140 void G4UGenericTrap::SetZHalfLength(G4double h 158 void G4UGenericTrap::SetZHalfLength(G4double halfZ) 141 { 159 { 142 SetDZ(halfZ); << 160 GetShape()->SetZHalfLength(halfZ); 143 } << 144 << 145 void G4UGenericTrap::Initialise(const std::vec << 146 { << 147 G4double verticesx[8], verticesy[8]; << 148 for (G4int i=0; i<8; ++i) << 149 { << 150 fVertices.push_back(v[i]); << 151 verticesx[i] = v[i].x(); << 152 verticesy[i] = v[i].y(); << 153 } << 154 Initialize(verticesx, verticesy, GetZHalfLen << 155 } 161 } 156 162 157 ////////////////////////////////////////////// 163 ///////////////////////////////////////////////////////////////////////// 158 // 164 // 159 // Get bounding box 165 // Get bounding box 160 166 161 void G4UGenericTrap::BoundingLimits(G4ThreeVec << 167 void G4UGenericTrap::Extent(G4ThreeVector& pMin, G4ThreeVector& pMax) const 162 G4ThreeVec << 163 { 168 { 164 U3Vector vmin, vmax; << 169 UVector3 vmin, vmax; 165 Extent(vmin,vmax); << 170 GetShape()->Extent(vmin,vmax); 166 pMin.set(vmin.x(),vmin.y(),vmin.z()); 171 pMin.set(vmin.x(),vmin.y(),vmin.z()); 167 pMax.set(vmax.x(),vmax.y(),vmax.z()); 172 pMax.set(vmax.x(),vmax.y(),vmax.z()); 168 173 169 // Check correctness of the bounding box 174 // Check correctness of the bounding box 170 // 175 // 171 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 176 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) 172 { 177 { 173 std::ostringstream message; 178 std::ostringstream message; 174 message << "Bad bounding box (min >= max) 179 message << "Bad bounding box (min >= max) for solid: " 175 << GetName() << " !" 180 << GetName() << " !" 176 << "\npMin = " << pMin 181 << "\npMin = " << pMin 177 << "\npMax = " << pMax; 182 << "\npMax = " << pMax; 178 G4Exception("G4UGenericTrap::BoundingLimit << 183 G4Exception("G4UGenericTrap::Extent()", "GeomMgt0001", JustWarning, message); 179 JustWarning, message); << 180 StreamInfo(G4cout); 184 StreamInfo(G4cout); 181 } 185 } 182 } 186 } 183 187 184 ////////////////////////////////////////////// 188 ////////////////////////////////////////////////////////////////////////// 185 // 189 // 186 // Calculate extent under transform and specif 190 // Calculate extent under transform and specified limit 187 191 188 G4bool 192 G4bool 189 G4UGenericTrap::CalculateExtent(const EAxis pA 193 G4UGenericTrap::CalculateExtent(const EAxis pAxis, 190 const G4VoxelL 194 const G4VoxelLimits& pVoxelLimit, 191 const G4Affine 195 const G4AffineTransform& pTransform, 192 G4double 196 G4double& pMin, G4double& pMax) const 193 { 197 { 194 G4ThreeVector bmin, bmax; 198 G4ThreeVector bmin, bmax; 195 G4bool exist; 199 G4bool exist; 196 200 197 // Check bounding box (bbox) 201 // Check bounding box (bbox) 198 // 202 // 199 BoundingLimits(bmin,bmax); << 203 Extent(bmin,bmax); 200 G4BoundingEnvelope bbox(bmin,bmax); 204 G4BoundingEnvelope bbox(bmin,bmax); 201 #ifdef G4BBOX_EXTENT 205 #ifdef G4BBOX_EXTENT 202 return bbox.CalculateExtent(pAxis,pVoxelLimi << 206 if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 203 #endif 207 #endif 204 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox 208 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax)) 205 { 209 { 206 return exist = pMin < pMax; << 210 return exist = (pMin < pMax) ? true : false; 207 } 211 } 208 212 209 // Set bounding envelope (benv) and calculat 213 // Set bounding envelope (benv) and calculate extent 210 // 214 // 211 // To build the bounding envelope with plane 215 // To build the bounding envelope with plane faces each side face of 212 // the trapezoid is subdivided in triangles. 216 // the trapezoid is subdivided in triangles. Subdivision is done by 213 // duplication of vertices in the bases in a 217 // duplication of vertices in the bases in a way that the envelope be 214 // a convex polyhedron (some faces of the en 218 // a convex polyhedron (some faces of the envelope can be degenerate) 215 // 219 // 216 G4double dz = GetZHalfLength(); 220 G4double dz = GetZHalfLength(); 217 G4ThreeVectorList baseA(8), baseB(8); 221 G4ThreeVectorList baseA(8), baseB(8); 218 for (G4int i=0; i<4; ++i) 222 for (G4int i=0; i<4; ++i) 219 { 223 { 220 G4TwoVector va = GetVertex(i); 224 G4TwoVector va = GetVertex(i); 221 G4TwoVector vb = GetVertex(i+4); 225 G4TwoVector vb = GetVertex(i+4); 222 baseA[2*i].set(va.x(),va.y(),-dz); 226 baseA[2*i].set(va.x(),va.y(),-dz); 223 baseB[2*i].set(vb.x(),vb.y(), dz); 227 baseB[2*i].set(vb.x(),vb.y(), dz); 224 } 228 } 225 for (G4int i=0; i<4; ++i) 229 for (G4int i=0; i<4; ++i) 226 { 230 { 227 G4int k1=2*i, k2=(2*i+2)%8; 231 G4int k1=2*i, k2=(2*i+2)%8; 228 G4double ax = (baseA[k2].x()-baseA[k1].x() 232 G4double ax = (baseA[k2].x()-baseA[k1].x()); 229 G4double ay = (baseA[k2].y()-baseA[k1].y() 233 G4double ay = (baseA[k2].y()-baseA[k1].y()); 230 G4double bx = (baseB[k2].x()-baseB[k1].x() 234 G4double bx = (baseB[k2].x()-baseB[k1].x()); 231 G4double by = (baseB[k2].y()-baseB[k1].y() 235 G4double by = (baseB[k2].y()-baseB[k1].y()); 232 G4double znorm = ax*by - ay*bx; 236 G4double znorm = ax*by - ay*bx; 233 baseA[k1+1] = (znorm < 0.0) ? baseA[k2] : 237 baseA[k1+1] = (znorm < 0.0) ? baseA[k2] : baseA[k1]; 234 baseB[k1+1] = (znorm < 0.0) ? baseB[k1] : 238 baseB[k1+1] = (znorm < 0.0) ? baseB[k1] : baseB[k2]; 235 } 239 } 236 240 237 std::vector<const G4ThreeVectorList *> polyg 241 std::vector<const G4ThreeVectorList *> polygons(2); 238 polygons[0] = &baseA; 242 polygons[0] = &baseA; 239 polygons[1] = &baseB; 243 polygons[1] = &baseB; 240 244 241 G4BoundingEnvelope benv(bmin,bmax,polygons); 245 G4BoundingEnvelope benv(bmin,bmax,polygons); 242 exist = benv.CalculateExtent(pAxis,pVoxelLim 246 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 243 return exist; 247 return exist; 244 } 248 } 245 249 246 ////////////////////////////////////////////// 250 ////////////////////////////////////////////////////////////////////////// 247 // 251 // 248 // CreatePolyhedron() 252 // CreatePolyhedron() 249 // 253 // 250 G4Polyhedron* G4UGenericTrap::CreatePolyhedron 254 G4Polyhedron* G4UGenericTrap::CreatePolyhedron() const 251 { 255 { 252 // Approximation of Twisted Side 256 // Approximation of Twisted Side 253 // Construct extra Points, if Twisted Side 257 // Construct extra Points, if Twisted Side 254 // 258 // 255 G4Polyhedron* polyhedron; << 259 G4PolyhedronArbitrary* polyhedron; 256 G4int nVertices, nFacets; << 260 size_t nVertices, nFacets; 257 G4double fDz = GetZHalfLength(); 261 G4double fDz = GetZHalfLength(); 258 262 259 G4int subdivisions = 0; << 263 G4int subdivisions=0; 260 if (IsTwisted()) << 264 G4int i; >> 265 if(IsTwisted()) 261 { 266 { 262 if (GetVisSubdivisions() != 0) << 267 if ( GetVisSubdivisions()!= 0 ) 263 { 268 { 264 subdivisions = GetVisSubdivisions(); << 269 subdivisions=GetVisSubdivisions(); 265 } 270 } 266 else 271 else 267 { 272 { 268 // Estimation of Number of Subdivisions 273 // Estimation of Number of Subdivisions for smooth visualisation 269 // 274 // 270 G4double maxTwist = 0.; << 275 G4double maxTwist=0.; 271 for(G4int i = 0; i < 4; ++i) << 276 for(i=0; i<4; i++) 272 { 277 { 273 if (GetTwistAngle(i) > maxTwist) { max << 278 if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); } 274 } 279 } 275 280 276 // Computes bounding vectors for the sha 281 // Computes bounding vectors for the shape 277 // 282 // 278 G4double Dx, Dy; << 283 G4double Dx,Dy; 279 G4ThreeVector minVec, maxVec; << 284 UVector3 minBox = GetShape()->GetMinimumBBox(); 280 BoundingLimits(minVec, maxVec); << 285 UVector3 maxBox = GetShape()->GetMaximumBBox(); 281 Dx = 0.5*(maxVec.x() - minVec.y()); << 286 G4ThreeVector minVec(minBox.x(), minBox.y(), minBox.z()); 282 Dy = 0.5*(maxVec.y() - minVec.y()); << 287 G4ThreeVector maxVec(maxBox.x(), maxBox.y(), maxBox.z()); 283 if (Dy > Dx) { Dx = Dy; } << 288 Dx = 0.5*(maxVec.x()- minVec.y()); 284 << 289 Dy = 0.5*(maxVec.y()- minVec.y()); 285 subdivisions = 8*G4int(maxTwist/(Dx*Dx*D << 290 if (Dy > Dx) { Dx=Dy; } 286 if (subdivisions < 4) { subdivisions = << 291 287 if (subdivisions > 30) { subdivisions = << 292 subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz); >> 293 if (subdivisions<4) { subdivisions=4; } >> 294 if (subdivisions>30) { subdivisions=30; } 288 } 295 } 289 } 296 } 290 G4int sub4 = 4*subdivisions; << 297 G4int sub4=4*subdivisions; 291 nVertices = 8 + subdivisions*4; << 298 nVertices = 8+subdivisions*4; 292 nFacets = 6 + subdivisions*4; << 299 nFacets = 6+subdivisions*4; 293 G4double cf = 1./(subdivisions + 1); << 300 G4double cf=1./(subdivisions+1); 294 polyhedron = new G4Polyhedron(nVertices, nFa << 301 polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets); 295 302 296 // Set vertices << 303 // Add Vertex 297 // 304 // 298 G4int icur = 0; << 305 for (i=0;i<4;i++) 299 for (G4int i = 0; i < 4; ++i) << 300 { 306 { 301 G4ThreeVector v(GetVertex(i).x(),GetVertex << 307 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(), 302 polyhedron->SetVertex(++icur, v); << 308 GetVertex(i).y(),-fDz)); 303 } 309 } 304 for (G4int i = 0; i < subdivisions; ++i) << 310 for( i=0;i<subdivisions;i++) 305 { 311 { 306 for (G4int j = 0; j < 4; ++j) << 312 for(G4int j=0;j<4;j++) 307 { 313 { 308 G4TwoVector u = GetVertex(j)+cf*(i+1)*( << 314 G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j)); 309 G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fD << 315 polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1))); 310 polyhedron->SetVertex(++icur, v); << 316 } 311 } << 312 } 317 } 313 for (G4int i = 4; i < 8; ++i) << 318 for (i=4;i<8;i++) 314 { 319 { 315 G4ThreeVector v(GetVertex(i).x(),GetVertex << 320 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(), 316 polyhedron->SetVertex(++icur, v); << 321 GetVertex(i).y(),fDz)); 317 } 322 } 318 323 319 // Set facets << 324 // Add Facets 320 // 325 // 321 icur = 0; << 326 polyhedron->AddFacet(1,4,3,2); //Z-plane 322 polyhedron->SetFacet(++icur, 1, 4, 3, 2); // << 327 for (i=0;i<subdivisions+1;i++) 323 for (G4int i = 0; i < subdivisions + 1; ++i) << 328 { 324 { << 329 G4int is=i*4; 325 G4int is = i*4; << 330 polyhedron->AddFacet(5+is,8+is,4+is,1+is); 326 polyhedron->SetFacet(++icur, 5+is, 8+is, 4 << 331 polyhedron->AddFacet(8+is,7+is,3+is,4+is); 327 polyhedron->SetFacet(++icur, 8+is, 7+is, 3 << 332 polyhedron->AddFacet(7+is,6+is,2+is,3+is); 328 polyhedron->SetFacet(++icur, 7+is, 6+is, 2 << 333 polyhedron->AddFacet(6+is,5+is,1+is,2+is); 329 polyhedron->SetFacet(++icur, 6+is, 5+is, 1 << 330 } 334 } 331 polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, << 335 polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane 332 336 333 polyhedron->SetReferences(); 337 polyhedron->SetReferences(); 334 polyhedron->InvertFacets(); 338 polyhedron->InvertFacets(); 335 339 336 return polyhedron; << 340 return (G4Polyhedron*) polyhedron; 337 } 341 } 338 342 339 #endif // G4GEOM_USE_USOLIDS 343 #endif // G4GEOM_USE_USOLIDS 340 344