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