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 26 // Implementation of G4UGenericTrap wrapper class 27 // 27 // 28 // 30.10.13 G.Cosmo, CERN 28 // 30.10.13 G.Cosmo, CERN 29 // ------------------------------------------- 29 // -------------------------------------------------------------------- 30 30 31 #include "G4GenericTrap.hh" 31 #include "G4GenericTrap.hh" 32 #include "G4UGenericTrap.hh" 32 #include "G4UGenericTrap.hh" 33 33 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) ) 35 35 36 #include "G4AffineTransform.hh" 36 #include "G4AffineTransform.hh" 37 #include "G4VPVParameterisation.hh" 37 #include "G4VPVParameterisation.hh" 38 #include "G4BoundingEnvelope.hh" 38 #include "G4BoundingEnvelope.hh" 39 39 40 #include "G4Polyhedron.hh" 40 #include "G4Polyhedron.hh" >> 41 #include "G4PolyhedronArbitrary.hh" 41 42 42 using namespace CLHEP; 43 using namespace CLHEP; 43 44 44 ////////////////////////////////////////////// 45 //////////////////////////////////////////////////////////////////////// 45 // 46 // 46 // Constructor (generic parameters) 47 // Constructor (generic parameters) 47 // 48 // 48 G4UGenericTrap::G4UGenericTrap(const G4String& 49 G4UGenericTrap::G4UGenericTrap(const G4String& name, G4double halfZ, 49 const std::vect 50 const std::vector<G4TwoVector>& vertices) 50 : Base_t(name), fVisSubdivisions(0) 51 : Base_t(name), fVisSubdivisions(0) 51 { 52 { 52 SetZHalfLength(halfZ); 53 SetZHalfLength(halfZ); 53 Initialise(vertices); 54 Initialise(vertices); 54 } 55 } 55 56 56 57 57 ////////////////////////////////////////////// 58 //////////////////////////////////////////////////////////////////////// 58 // 59 // 59 // Fake default constructor - sets only member 60 // Fake default constructor - sets only member data and allocates memory 60 // for usage restri 61 // for usage restricted to object persistency. 61 // 62 // 62 G4UGenericTrap::G4UGenericTrap(__void__& a) 63 G4UGenericTrap::G4UGenericTrap(__void__& a) 63 : Base_t(a), fVisSubdivisions(0) << 64 : Base_t(a), fVisSubdivisions(0), fVertices() 64 { 65 { 65 } 66 } 66 67 67 68 68 ////////////////////////////////////////////// 69 ////////////////////////////////////////////////////////////////////////// 69 // 70 // 70 // Destructor 71 // Destructor 71 // 72 // 72 G4UGenericTrap::~G4UGenericTrap() = default; << 73 G4UGenericTrap::~G4UGenericTrap() >> 74 { >> 75 } 73 76 74 77 75 ////////////////////////////////////////////// 78 ////////////////////////////////////////////////////////////////////////// 76 // 79 // 77 // Copy constructor 80 // Copy constructor 78 // 81 // 79 G4UGenericTrap::G4UGenericTrap(const G4UGeneri 82 G4UGenericTrap::G4UGenericTrap(const G4UGenericTrap& source) 80 : Base_t(source), fVisSubdivisions(source.fV 83 : Base_t(source), fVisSubdivisions(source.fVisSubdivisions), 81 fVertices(source.fVertices) 84 fVertices(source.fVertices) >> 85 82 { 86 { 83 } 87 } 84 88 85 89 86 ////////////////////////////////////////////// 90 ////////////////////////////////////////////////////////////////////////// 87 // 91 // 88 // Assignment operator 92 // Assignment operator 89 // 93 // 90 G4UGenericTrap& 94 G4UGenericTrap& 91 G4UGenericTrap::operator=(const G4UGenericTrap 95 G4UGenericTrap::operator=(const G4UGenericTrap& source) 92 { 96 { 93 if (this == &source) return *this; 97 if (this == &source) return *this; 94 98 95 Base_t::operator=( source ); 99 Base_t::operator=( source ); 96 fVertices = source.fVertices; 100 fVertices = source.fVertices; 97 fVisSubdivisions = source.fVisSubdivisions; 101 fVisSubdivisions = source.fVisSubdivisions; 98 102 99 return *this; 103 return *this; 100 } 104 } 101 105 102 ////////////////////////////////////////////// 106 ////////////////////////////////////////////////////////////////////////// 103 // 107 // 104 // Accessors & modifiers 108 // Accessors & modifiers 105 // 109 // 106 G4double G4UGenericTrap::GetZHalfLength() cons 110 G4double G4UGenericTrap::GetZHalfLength() const 107 { 111 { 108 return GetDZ(); 112 return GetDZ(); 109 } 113 } 110 G4int G4UGenericTrap::GetNofVertices() const 114 G4int G4UGenericTrap::GetNofVertices() const 111 { 115 { 112 return fVertices.size(); 116 return fVertices.size(); 113 } 117 } 114 G4TwoVector G4UGenericTrap::GetVertex(G4int in 118 G4TwoVector G4UGenericTrap::GetVertex(G4int index) const 115 { 119 { 116 return { GetVerticesX()[index], GetVerticesY << 120 return G4TwoVector(GetVerticesX()[index], GetVerticesY()[index]); 117 } 121 } 118 const std::vector<G4TwoVector>& G4UGenericTrap 122 const std::vector<G4TwoVector>& G4UGenericTrap::GetVertices() const 119 { 123 { 120 return fVertices; 124 return fVertices; 121 } 125 } 122 G4double G4UGenericTrap::GetTwistAngle(G4int i 126 G4double G4UGenericTrap::GetTwistAngle(G4int index) const 123 { 127 { 124 return GetTwist(index); 128 return GetTwist(index); 125 } 129 } 126 G4bool G4UGenericTrap::IsTwisted() const 130 G4bool G4UGenericTrap::IsTwisted() const 127 { 131 { 128 return !IsPlanar(); 132 return !IsPlanar(); 129 } 133 } 130 G4int G4UGenericTrap::GetVisSubdivisions() con 134 G4int G4UGenericTrap::GetVisSubdivisions() const 131 { 135 { 132 return fVisSubdivisions; 136 return fVisSubdivisions; 133 } 137 } 134 138 135 void G4UGenericTrap::SetVisSubdivisions(G4int 139 void G4UGenericTrap::SetVisSubdivisions(G4int subdiv) 136 { 140 { 137 fVisSubdivisions = subdiv; 141 fVisSubdivisions = subdiv; 138 } 142 } 139 143 140 void G4UGenericTrap::SetZHalfLength(G4double h 144 void G4UGenericTrap::SetZHalfLength(G4double halfZ) 141 { 145 { 142 SetDZ(halfZ); 146 SetDZ(halfZ); 143 } 147 } 144 148 145 void G4UGenericTrap::Initialise(const std::vec 149 void G4UGenericTrap::Initialise(const std::vector<G4TwoVector>& v) 146 { 150 { 147 G4double verticesx[8], verticesy[8]; 151 G4double verticesx[8], verticesy[8]; 148 for (G4int i=0; i<8; ++i) 152 for (G4int i=0; i<8; ++i) 149 { 153 { 150 fVertices.push_back(v[i]); 154 fVertices.push_back(v[i]); 151 verticesx[i] = v[i].x(); 155 verticesx[i] = v[i].x(); 152 verticesy[i] = v[i].y(); 156 verticesy[i] = v[i].y(); 153 } 157 } 154 Initialize(verticesx, verticesy, GetZHalfLen 158 Initialize(verticesx, verticesy, GetZHalfLength()); 155 } 159 } 156 160 157 ////////////////////////////////////////////// 161 ///////////////////////////////////////////////////////////////////////// 158 // 162 // 159 // Get bounding box 163 // Get bounding box 160 164 161 void G4UGenericTrap::BoundingLimits(G4ThreeVec 165 void G4UGenericTrap::BoundingLimits(G4ThreeVector& pMin, 162 G4ThreeVec 166 G4ThreeVector& pMax) const 163 { 167 { 164 U3Vector vmin, vmax; 168 U3Vector vmin, vmax; 165 Extent(vmin,vmax); 169 Extent(vmin,vmax); 166 pMin.set(vmin.x(),vmin.y(),vmin.z()); 170 pMin.set(vmin.x(),vmin.y(),vmin.z()); 167 pMax.set(vmax.x(),vmax.y(),vmax.z()); 171 pMax.set(vmax.x(),vmax.y(),vmax.z()); 168 172 169 // Check correctness of the bounding box 173 // Check correctness of the bounding box 170 // 174 // 171 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 175 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) 172 { 176 { 173 std::ostringstream message; 177 std::ostringstream message; 174 message << "Bad bounding box (min >= max) 178 message << "Bad bounding box (min >= max) for solid: " 175 << GetName() << " !" 179 << GetName() << " !" 176 << "\npMin = " << pMin 180 << "\npMin = " << pMin 177 << "\npMax = " << pMax; 181 << "\npMax = " << pMax; 178 G4Exception("G4UGenericTrap::BoundingLimit 182 G4Exception("G4UGenericTrap::BoundingLimits()", "GeomMgt0001", 179 JustWarning, message); 183 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 BoundingLimits(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 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 G4ThreeVector minVec, maxVec; 280 BoundingLimits(minVec, maxVec); << 285 BoundingLimits(minVec,maxVec); 281 Dx = 0.5*(maxVec.x() - minVec.y()); << 286 Dx = 0.5*(maxVec.x()- minVec.y()); 282 Dy = 0.5*(maxVec.y() - minVec.y()); << 287 Dy = 0.5*(maxVec.y()- minVec.y()); 283 if (Dy > Dx) { Dx = Dy; } << 288 if (Dy > Dx) { Dx=Dy; } 284 << 289 285 subdivisions = 8*G4int(maxTwist/(Dx*Dx*D << 290 subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz); 286 if (subdivisions < 4) { subdivisions = << 291 if (subdivisions<4) { subdivisions=4; } 287 if (subdivisions > 30) { subdivisions = << 292 if (subdivisions>30) { subdivisions=30; } 288 } 293 } 289 } 294 } 290 G4int sub4 = 4*subdivisions; << 295 G4int sub4=4*subdivisions; 291 nVertices = 8 + subdivisions*4; << 296 nVertices = 8+subdivisions*4; 292 nFacets = 6 + subdivisions*4; << 297 nFacets = 6+subdivisions*4; 293 G4double cf = 1./(subdivisions + 1); << 298 G4double cf=1./(subdivisions+1); 294 polyhedron = new G4Polyhedron(nVertices, nFa << 299 polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets); 295 300 296 // Set vertices << 301 // Add Vertex 297 // 302 // 298 G4int icur = 0; << 303 for (i=0; i<4; ++i) 299 for (G4int i = 0; i < 4; ++i) << 300 { 304 { 301 G4ThreeVector v(GetVertex(i).x(),GetVertex << 305 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(), 302 polyhedron->SetVertex(++icur, v); << 306 GetVertex(i).y(),-fDz)); 303 } 307 } 304 for (G4int i = 0; i < subdivisions; ++i) << 308 for(i=0; i<subdivisions; ++i) 305 { 309 { 306 for (G4int j = 0; j < 4; ++j) << 310 for(G4int j=0; j<4 ; ++j) 307 { 311 { 308 G4TwoVector u = GetVertex(j)+cf*(i+1)*( << 312 G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j)); 309 G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fD << 313 polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1))); 310 polyhedron->SetVertex(++icur, v); << 314 } 311 } << 312 } 315 } 313 for (G4int i = 4; i < 8; ++i) << 316 for (i=4; i<8; ++i) 314 { 317 { 315 G4ThreeVector v(GetVertex(i).x(),GetVertex << 318 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(), 316 polyhedron->SetVertex(++icur, v); << 319 GetVertex(i).y(),fDz)); 317 } 320 } 318 321 319 // Set facets << 322 // Add Facets 320 // 323 // 321 icur = 0; << 324 polyhedron->AddFacet(1,4,3,2); //Z-plane 322 polyhedron->SetFacet(++icur, 1, 4, 3, 2); // << 325 for (i=0; i<subdivisions+1; ++i) 323 for (G4int i = 0; i < subdivisions + 1; ++i) << 324 { 326 { 325 G4int is = i*4; << 327 G4int is=i*4; 326 polyhedron->SetFacet(++icur, 5+is, 8+is, 4 << 328 polyhedron->AddFacet(5+is,8+is,4+is,1+is); 327 polyhedron->SetFacet(++icur, 8+is, 7+is, 3 << 329 polyhedron->AddFacet(8+is,7+is,3+is,4+is); 328 polyhedron->SetFacet(++icur, 7+is, 6+is, 2 << 330 polyhedron->AddFacet(7+is,6+is,2+is,3+is); 329 polyhedron->SetFacet(++icur, 6+is, 5+is, 1 << 331 polyhedron->AddFacet(6+is,5+is,1+is,2+is); 330 } 332 } 331 polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, << 333 polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane 332 334 333 polyhedron->SetReferences(); 335 polyhedron->SetReferences(); 334 polyhedron->InvertFacets(); 336 polyhedron->InvertFacets(); 335 337 336 return polyhedron; << 338 return (G4Polyhedron*) polyhedron; 337 } 339 } 338 340 339 #endif // G4GEOM_USE_USOLIDS 341 #endif // G4GEOM_USE_USOLIDS 340 342