Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // Implementation of G4UGenericTrap wrapper cl 27 // 28 // 30.10.13 G.Cosmo, CERN 29 // ------------------------------------------- 30 31 #include "G4GenericTrap.hh" 32 #include "G4UGenericTrap.hh" 33 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 35 36 #include "G4AffineTransform.hh" 37 #include "G4VPVParameterisation.hh" 38 #include "G4BoundingEnvelope.hh" 39 40 #include "G4Polyhedron.hh" 41 42 using namespace CLHEP; 43 44 ////////////////////////////////////////////// 45 // 46 // Constructor (generic parameters) 47 // 48 G4UGenericTrap::G4UGenericTrap(const G4String& 49 const std::vect 50 : Base_t(name), fVisSubdivisions(0) 51 { 52 SetZHalfLength(halfZ); 53 Initialise(vertices); 54 } 55 56 57 ////////////////////////////////////////////// 58 // 59 // Fake default constructor - sets only member 60 // for usage restri 61 // 62 G4UGenericTrap::G4UGenericTrap(__void__& a) 63 : Base_t(a), fVisSubdivisions(0) 64 { 65 } 66 67 68 ////////////////////////////////////////////// 69 // 70 // Destructor 71 // 72 G4UGenericTrap::~G4UGenericTrap() = default; 73 74 75 ////////////////////////////////////////////// 76 // 77 // Copy constructor 78 // 79 G4UGenericTrap::G4UGenericTrap(const G4UGeneri 80 : Base_t(source), fVisSubdivisions(source.fV 81 fVertices(source.fVertices) 82 { 83 } 84 85 86 ////////////////////////////////////////////// 87 // 88 // Assignment operator 89 // 90 G4UGenericTrap& 91 G4UGenericTrap::operator=(const G4UGenericTrap 92 { 93 if (this == &source) return *this; 94 95 Base_t::operator=( source ); 96 fVertices = source.fVertices; 97 fVisSubdivisions = source.fVisSubdivisions; 98 99 return *this; 100 } 101 102 ////////////////////////////////////////////// 103 // 104 // Accessors & modifiers 105 // 106 G4double G4UGenericTrap::GetZHalfLength() cons 107 { 108 return GetDZ(); 109 } 110 G4int G4UGenericTrap::GetNofVertices() const 111 { 112 return fVertices.size(); 113 } 114 G4TwoVector G4UGenericTrap::GetVertex(G4int in 115 { 116 return { GetVerticesX()[index], GetVerticesY 117 } 118 const std::vector<G4TwoVector>& G4UGenericTrap 119 { 120 return fVertices; 121 } 122 G4double G4UGenericTrap::GetTwistAngle(G4int i 123 { 124 return GetTwist(index); 125 } 126 G4bool G4UGenericTrap::IsTwisted() const 127 { 128 return !IsPlanar(); 129 } 130 G4int G4UGenericTrap::GetVisSubdivisions() con 131 { 132 return fVisSubdivisions; 133 } 134 135 void G4UGenericTrap::SetVisSubdivisions(G4int 136 { 137 fVisSubdivisions = subdiv; 138 } 139 140 void G4UGenericTrap::SetZHalfLength(G4double h 141 { 142 SetDZ(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 } 156 157 ////////////////////////////////////////////// 158 // 159 // Get bounding box 160 161 void G4UGenericTrap::BoundingLimits(G4ThreeVec 162 G4ThreeVec 163 { 164 U3Vector vmin, vmax; 165 Extent(vmin,vmax); 166 pMin.set(vmin.x(),vmin.y(),vmin.z()); 167 pMax.set(vmax.x(),vmax.y(),vmax.z()); 168 169 // Check correctness of the bounding box 170 // 171 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 172 { 173 std::ostringstream message; 174 message << "Bad bounding box (min >= max) 175 << GetName() << " !" 176 << "\npMin = " << pMin 177 << "\npMax = " << pMax; 178 G4Exception("G4UGenericTrap::BoundingLimit 179 JustWarning, message); 180 StreamInfo(G4cout); 181 } 182 } 183 184 ////////////////////////////////////////////// 185 // 186 // Calculate extent under transform and specif 187 188 G4bool 189 G4UGenericTrap::CalculateExtent(const EAxis pA 190 const G4VoxelL 191 const G4Affine 192 G4double 193 { 194 G4ThreeVector bmin, bmax; 195 G4bool exist; 196 197 // Check bounding box (bbox) 198 // 199 BoundingLimits(bmin,bmax); 200 G4BoundingEnvelope bbox(bmin,bmax); 201 #ifdef G4BBOX_EXTENT 202 return bbox.CalculateExtent(pAxis,pVoxelLimi 203 #endif 204 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox 205 { 206 return exist = pMin < pMax; 207 } 208 209 // Set bounding envelope (benv) and calculat 210 // 211 // To build the bounding envelope with plane 212 // the trapezoid is subdivided in triangles. 213 // duplication of vertices in the bases in a 214 // a convex polyhedron (some faces of the en 215 // 216 G4double dz = GetZHalfLength(); 217 G4ThreeVectorList baseA(8), baseB(8); 218 for (G4int i=0; i<4; ++i) 219 { 220 G4TwoVector va = GetVertex(i); 221 G4TwoVector vb = GetVertex(i+4); 222 baseA[2*i].set(va.x(),va.y(),-dz); 223 baseB[2*i].set(vb.x(),vb.y(), dz); 224 } 225 for (G4int i=0; i<4; ++i) 226 { 227 G4int k1=2*i, k2=(2*i+2)%8; 228 G4double ax = (baseA[k2].x()-baseA[k1].x() 229 G4double ay = (baseA[k2].y()-baseA[k1].y() 230 G4double bx = (baseB[k2].x()-baseB[k1].x() 231 G4double by = (baseB[k2].y()-baseB[k1].y() 232 G4double znorm = ax*by - ay*bx; 233 baseA[k1+1] = (znorm < 0.0) ? baseA[k2] : 234 baseB[k1+1] = (znorm < 0.0) ? baseB[k1] : 235 } 236 237 std::vector<const G4ThreeVectorList *> polyg 238 polygons[0] = &baseA; 239 polygons[1] = &baseB; 240 241 G4BoundingEnvelope benv(bmin,bmax,polygons); 242 exist = benv.CalculateExtent(pAxis,pVoxelLim 243 return exist; 244 } 245 246 ////////////////////////////////////////////// 247 // 248 // CreatePolyhedron() 249 // 250 G4Polyhedron* G4UGenericTrap::CreatePolyhedron 251 { 252 // Approximation of Twisted Side 253 // Construct extra Points, if Twisted Side 254 // 255 G4Polyhedron* polyhedron; 256 G4int nVertices, nFacets; 257 G4double fDz = GetZHalfLength(); 258 259 G4int subdivisions = 0; 260 if (IsTwisted()) 261 { 262 if (GetVisSubdivisions() != 0) 263 { 264 subdivisions = GetVisSubdivisions(); 265 } 266 else 267 { 268 // Estimation of Number of Subdivisions 269 // 270 G4double maxTwist = 0.; 271 for(G4int i = 0; i < 4; ++i) 272 { 273 if (GetTwistAngle(i) > maxTwist) { max 274 } 275 276 // Computes bounding vectors for the sha 277 // 278 G4double Dx, Dy; 279 G4ThreeVector minVec, maxVec; 280 BoundingLimits(minVec, maxVec); 281 Dx = 0.5*(maxVec.x() - minVec.y()); 282 Dy = 0.5*(maxVec.y() - minVec.y()); 283 if (Dy > Dx) { Dx = Dy; } 284 285 subdivisions = 8*G4int(maxTwist/(Dx*Dx*D 286 if (subdivisions < 4) { subdivisions = 287 if (subdivisions > 30) { subdivisions = 288 } 289 } 290 G4int sub4 = 4*subdivisions; 291 nVertices = 8 + subdivisions*4; 292 nFacets = 6 + subdivisions*4; 293 G4double cf = 1./(subdivisions + 1); 294 polyhedron = new G4Polyhedron(nVertices, nFa 295 296 // Set vertices 297 // 298 G4int icur = 0; 299 for (G4int i = 0; i < 4; ++i) 300 { 301 G4ThreeVector v(GetVertex(i).x(),GetVertex 302 polyhedron->SetVertex(++icur, v); 303 } 304 for (G4int i = 0; i < subdivisions; ++i) 305 { 306 for (G4int j = 0; j < 4; ++j) 307 { 308 G4TwoVector u = GetVertex(j)+cf*(i+1)*( 309 G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fD 310 polyhedron->SetVertex(++icur, v); 311 } 312 } 313 for (G4int i = 4; i < 8; ++i) 314 { 315 G4ThreeVector v(GetVertex(i).x(),GetVertex 316 polyhedron->SetVertex(++icur, v); 317 } 318 319 // Set facets 320 // 321 icur = 0; 322 polyhedron->SetFacet(++icur, 1, 4, 3, 2); // 323 for (G4int i = 0; i < subdivisions + 1; ++i) 324 { 325 G4int is = i*4; 326 polyhedron->SetFacet(++icur, 5+is, 8+is, 4 327 polyhedron->SetFacet(++icur, 8+is, 7+is, 3 328 polyhedron->SetFacet(++icur, 7+is, 6+is, 2 329 polyhedron->SetFacet(++icur, 6+is, 5+is, 1 330 } 331 polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, 332 333 polyhedron->SetReferences(); 334 polyhedron->InvertFacets(); 335 336 return polyhedron; 337 } 338 339 #endif // G4GEOM_USE_USOLIDS 340