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) 35 << 36 #include "G4AffineTransform.hh" << 37 #include "G4VPVParameterisation.hh" << 38 #include "G4BoundingEnvelope.hh" << 39 37 40 #include "G4Polyhedron.hh" 38 #include "G4Polyhedron.hh" 41 << 39 #include "G4PolyhedronArbitrary.hh" 42 using namespace CLHEP; << 43 40 44 ////////////////////////////////////////////// 41 //////////////////////////////////////////////////////////////////////// 45 // 42 // 46 // Constructor (generic parameters) 43 // Constructor (generic parameters) 47 // 44 // 48 G4UGenericTrap::G4UGenericTrap(const G4String& 45 G4UGenericTrap::G4UGenericTrap(const G4String& name, G4double halfZ, 49 const std::vect 46 const std::vector<G4TwoVector>& vertices) 50 : Base_t(name), fVisSubdivisions(0) << 47 : G4USolid(name, new UGenericTrap()) 51 { 48 { 52 SetZHalfLength(halfZ); 49 SetZHalfLength(halfZ); 53 Initialise(vertices); << 50 std::vector<UVector2> v; >> 51 for (size_t n=0; n<vertices.size(); ++n) >> 52 { >> 53 v.push_back(UVector2(vertices[n].x(),vertices[n].y())); >> 54 } >> 55 GetShape()->SetName(name); >> 56 GetShape()->Initialise(v); 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 : G4USolid(a) 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 : G4USolid(source) 81 fVertices(source.fVertices) << 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 G4USolid::operator=( source ); 96 fVertices = source.fVertices; << 97 fVisSubdivisions = source.fVisSubdivisions; << 98 100 99 return *this; 101 return *this; 100 } 102 } 101 103 102 ////////////////////////////////////////////// 104 ////////////////////////////////////////////////////////////////////////// 103 // 105 // 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() 106 // CreatePolyhedron() 249 // 107 // 250 G4Polyhedron* G4UGenericTrap::CreatePolyhedron 108 G4Polyhedron* G4UGenericTrap::CreatePolyhedron() const 251 { 109 { 252 // Approximation of Twisted Side 110 // Approximation of Twisted Side 253 // Construct extra Points, if Twisted Side 111 // Construct extra Points, if Twisted Side 254 // 112 // 255 G4Polyhedron* polyhedron; << 113 G4PolyhedronArbitrary* polyhedron; 256 G4int nVertices, nFacets; << 114 size_t nVertices, nFacets; 257 G4double fDz = GetZHalfLength(); 115 G4double fDz = GetZHalfLength(); 258 116 259 G4int subdivisions = 0; << 117 G4int subdivisions=0; 260 if (IsTwisted()) << 118 G4int i; >> 119 if(IsTwisted()) 261 { 120 { 262 if (GetVisSubdivisions() != 0) << 121 if ( GetVisSubdivisions()!= 0 ) 263 { 122 { 264 subdivisions = GetVisSubdivisions(); << 123 subdivisions=GetVisSubdivisions(); 265 } 124 } 266 else 125 else 267 { 126 { 268 // Estimation of Number of Subdivisions 127 // Estimation of Number of Subdivisions for smooth visualisation 269 // 128 // 270 G4double maxTwist = 0.; << 129 G4double maxTwist=0.; 271 for(G4int i = 0; i < 4; ++i) << 130 for(i=0; i<4; i++) 272 { 131 { 273 if (GetTwistAngle(i) > maxTwist) { max << 132 if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); } 274 } 133 } 275 134 276 // Computes bounding vectors for the sha 135 // Computes bounding vectors for the shape 277 // 136 // 278 G4double Dx, Dy; << 137 G4double Dx,Dy; 279 G4ThreeVector minVec, maxVec; << 138 UVector3 minBox = GetShape()->GetMinimumBBox(); 280 BoundingLimits(minVec, maxVec); << 139 UVector3 maxBox = GetShape()->GetMaximumBBox(); 281 Dx = 0.5*(maxVec.x() - minVec.y()); << 140 G4ThreeVector minVec(minBox.x(), minBox.y(), minBox.z()); 282 Dy = 0.5*(maxVec.y() - minVec.y()); << 141 G4ThreeVector maxVec(maxBox.x(), maxBox.y(), maxBox.z()); 283 if (Dy > Dx) { Dx = Dy; } << 142 Dx = 0.5*(maxVec.x()- minVec.y()); 284 << 143 Dy = 0.5*(maxVec.y()- minVec.y()); 285 subdivisions = 8*G4int(maxTwist/(Dx*Dx*D << 144 if (Dy > Dx) { Dx=Dy; } 286 if (subdivisions < 4) { subdivisions = << 145 287 if (subdivisions > 30) { subdivisions = << 146 subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz); >> 147 if (subdivisions<4) { subdivisions=4; } >> 148 if (subdivisions>30) { subdivisions=30; } 288 } 149 } 289 } 150 } 290 G4int sub4 = 4*subdivisions; << 151 G4int sub4=4*subdivisions; 291 nVertices = 8 + subdivisions*4; << 152 nVertices = 8+subdivisions*4; 292 nFacets = 6 + subdivisions*4; << 153 nFacets = 6+subdivisions*4; 293 G4double cf = 1./(subdivisions + 1); << 154 G4double cf=1./(subdivisions+1); 294 polyhedron = new G4Polyhedron(nVertices, nFa << 155 polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets); 295 156 296 // Set vertices << 157 // Add Vertex 297 // 158 // 298 G4int icur = 0; << 159 for (i=0;i<4;i++) 299 for (G4int i = 0; i < 4; ++i) << 300 { 160 { 301 G4ThreeVector v(GetVertex(i).x(),GetVertex << 161 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(), 302 polyhedron->SetVertex(++icur, v); << 162 GetVertex(i).y(),-fDz)); 303 } 163 } 304 for (G4int i = 0; i < subdivisions; ++i) << 164 for( i=0;i<subdivisions;i++) 305 { 165 { 306 for (G4int j = 0; j < 4; ++j) << 166 for(G4int j=0;j<4;j++) 307 { 167 { 308 G4TwoVector u = GetVertex(j)+cf*(i+1)*( << 168 G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j)); 309 G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fD << 169 polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1))); 310 polyhedron->SetVertex(++icur, v); << 170 } 311 } << 312 } 171 } 313 for (G4int i = 4; i < 8; ++i) << 172 for (i=4;i<8;i++) 314 { 173 { 315 G4ThreeVector v(GetVertex(i).x(),GetVertex << 174 polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(), 316 polyhedron->SetVertex(++icur, v); << 175 GetVertex(i).y(),fDz)); 317 } 176 } 318 177 319 // Set facets << 178 // Add Facets 320 // 179 // 321 icur = 0; << 180 polyhedron->AddFacet(1,4,3,2); //Z-plane 322 polyhedron->SetFacet(++icur, 1, 4, 3, 2); // << 181 for (i=0;i<subdivisions+1;i++) 323 for (G4int i = 0; i < subdivisions + 1; ++i) << 324 { 182 { 325 G4int is = i*4; << 183 G4int is=i*4; 326 polyhedron->SetFacet(++icur, 5+is, 8+is, 4 << 184 polyhedron->AddFacet(5+is,8+is,4+is,1+is); 327 polyhedron->SetFacet(++icur, 8+is, 7+is, 3 << 185 polyhedron->AddFacet(8+is,7+is,3+is,4+is); 328 polyhedron->SetFacet(++icur, 7+is, 6+is, 2 << 186 polyhedron->AddFacet(7+is,6+is,2+is,3+is); 329 polyhedron->SetFacet(++icur, 6+is, 5+is, 1 << 187 polyhedron->AddFacet(6+is,5+is,1+is,2+is); 330 } 188 } 331 polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, << 189 polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane 332 190 333 polyhedron->SetReferences(); 191 polyhedron->SetReferences(); 334 polyhedron->InvertFacets(); 192 polyhedron->InvertFacets(); 335 193 336 return polyhedron; << 194 return (G4Polyhedron*) polyhedron; 337 } 195 } 338 196 339 #endif // G4GEOM_USE_USOLIDS 197 #endif // G4GEOM_USE_USOLIDS 340 198