// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4VSolid.cc,v 1.40 2010/10/19 15:19:37 gcosmo Exp $ // GEANT4 tag $Name: geommng-V09-03-05 $ // // class G4VSolid // // Implementation for solid base class // // History: // // 06.12.02 V.Grichine, restored original conditions in ClipPolygon() // 10.05.02 V.Grichine, ClipPolygon(): clip only other axis and limited voxels // 15.04.02 V.Grichine, bug fixed in ClipPolygon(): clip only one axis // 13.03.02 V.Grichine, cosmetics of voxel limit functions // 15.11.00 D.Williams, V.Grichine, fix in CalculateClippedPolygonExtent() // 10.07.95 P.Kent, Added == operator, solid Store entry // 30.06.95 P.Kent, Created. // -------------------------------------------------------------------- #include "G4VSolid.hh" #include "G4SolidStore.hh" #include "globals.hh" #include "Randomize.hh" #include "G4GeometryTolerance.hh" #include "G4VoxelLimits.hh" #include "G4AffineTransform.hh" #include "G4VisExtent.hh" ////////////////////////////////////////////////////////////////////////// // // Constructor // - Copies name // - Add ourselves to solid Store G4VSolid::G4VSolid(const G4String& name) : fshapeName(name) { kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); // Register to store // G4SolidStore::GetInstance()->Register(this); } ////////////////////////////////////////////////////////////////////////// // // Copy constructor // G4VSolid::G4VSolid(const G4VSolid& rhs) : kCarTolerance(rhs.kCarTolerance), fshapeName(rhs.fshapeName) { // Register to store // G4SolidStore::GetInstance()->Register(this); } ////////////////////////////////////////////////////////////////////////// // // Fake default constructor - sets only member data and allocates memory // for usage restricted to object persistency. // G4VSolid::G4VSolid( __void__& ) : fshapeName("") { // Register to store // G4SolidStore::GetInstance()->Register(this); } ////////////////////////////////////////////////////////////////////////// // // Destructor (virtual) // - Remove ourselves from solid Store G4VSolid::~G4VSolid() { G4SolidStore::GetInstance()->DeRegister(this); } ////////////////////////////////////////////////////////////////////////// // // Assignment operator G4VSolid& G4VSolid::operator = (const G4VSolid& rhs) { // Check assignment to self // if (this == &rhs) { return *this; } // Copy data // kCarTolerance = rhs.kCarTolerance; fshapeName = rhs.fshapeName; return *this; } ////////////////////////////////////////////////////////////////////////// // // Streaming operator dumping solid contents std::ostream& operator<< ( std::ostream& os, const G4VSolid& e ) { return e.StreamInfo(os); } ////////////////////////////////////////////////////////////////////////// // // Throw exception if ComputeDimensions called for illegal derived class void G4VSolid::ComputeDimensions(G4VPVParameterisation*, const G4int, const G4VPhysicalVolume*) { G4cerr << "ERROR - Illegal call to G4VSolid::ComputeDimensions()" << G4endl << " Method not overloaded by derived class !" << G4endl; G4Exception("G4VSolid::ComputeDimensions()", "NotApplicable", FatalException, "Illegal call to case class."); } ////////////////////////////////////////////////////////////////////////// // // Throw exception (warning) for solids not implementing the method G4ThreeVector G4VSolid::GetPointOnSurface() const { G4cerr << "WARNING - G4VSolid::GetPointOnSurface()" << G4endl << " Not implemented for solid: " << this->GetEntityType() << " !" << G4endl; G4Exception("G4VSolid::GetPointOnSurface()", "NotImplemented", JustWarning, "Not implemented for this solid ! Returning origin."); return G4ThreeVector(0,0,0); } ////////////////////////////////////////////////////////////////////////// // // Dummy implementations ... const G4VSolid* G4VSolid::GetConstituentSolid(G4int) const { return 0; } G4VSolid* G4VSolid::GetConstituentSolid(G4int) { return 0; } const G4DisplacedSolid* G4VSolid::GetDisplacedSolidPtr() const { return 0; } G4DisplacedSolid* G4VSolid::GetDisplacedSolidPtr() { return 0; } //////////////////////////////////////////////////////////////// // // Returns an estimation of the solid volume in internal units. // The number of statistics and error accuracy is fixed. // This method may be overloaded by derived classes to compute the // exact geometrical quantity for solids where this is possible. // or anyway to cache the computed value. // This implementation does NOT cache the computed value. G4double G4VSolid::GetCubicVolume() { G4int cubVolStatistics = 1000000; G4double cubVolEpsilon = 0.001; return EstimateCubicVolume(cubVolStatistics, cubVolEpsilon); } //////////////////////////////////////////////////////////////// // // Calculate cubic volume based on Inside() method. // Accuracy is limited by the second argument or the statistics // expressed by the first argument. // Implementation is courtesy of Vasiliki Despoina Mitsou, // University of Athens. G4double G4VSolid::EstimateCubicVolume(G4int nStat, G4double epsilon) const { G4int iInside=0; G4double px,py,pz,minX,maxX,minY,maxY,minZ,maxZ,volume; G4bool yesno; G4ThreeVector p; EInside in; // values needed for CalculateExtent signature G4VoxelLimits limit; // Unlimited G4AffineTransform origin; // min max extents of pSolid along X,Y,Z yesno = this->CalculateExtent(kXAxis,limit,origin,minX,maxX); yesno = this->CalculateExtent(kYAxis,limit,origin,minY,maxY); yesno = this->CalculateExtent(kZAxis,limit,origin,minZ,maxZ); // limits if(nStat < 100) nStat = 100; if(epsilon > 0.01) epsilon = 0.01; for(G4int i = 0; i < nStat; i++ ) { px = minX+(maxX-minX)*G4UniformRand(); py = minY+(maxY-minY)*G4UniformRand(); pz = minZ+(maxZ-minZ)*G4UniformRand(); p = G4ThreeVector(px,py,pz); in = this->Inside(p); if(in != kOutside) iInside++; } volume = (maxX-minX)*(maxY-minY)*(maxZ-minZ)*iInside/nStat; return volume; } //////////////////////////////////////////////////////////////// // // Returns an estimation of the solid surface area in internal units. // The number of statistics and error accuracy is fixed. // This method may be overloaded by derived classes to compute the // exact geometrical quantity for solids where this is possible. // or anyway to cache the computed value. // This implementation does NOT cache the computed value. G4double G4VSolid::GetSurfaceArea() { G4int stat = 1000000; G4double ell = -1.; return EstimateSurfaceArea(stat,ell); } //////////////////////////////////////////////////////////////// // // Estimate surface area based on Inside(), DistanceToIn(), and // DistanceToOut() methods. Accuracy is limited by the statistics // defined by the first argument. Implemented by Mikhail Kosov. G4double G4VSolid::EstimateSurfaceArea(G4int nStat, G4double ell) const { G4int inside=0; G4double px,py,pz,minX,maxX,minY,maxY,minZ,maxZ,surf; G4bool yesno; G4ThreeVector p; EInside in; // values needed for CalculateExtent signature G4VoxelLimits limit; // Unlimited G4AffineTransform origin; // min max extents of pSolid along X,Y,Z yesno = this->CalculateExtent(kXAxis,limit,origin,minX,maxX); yesno = this->CalculateExtent(kYAxis,limit,origin,minY,maxY); yesno = this->CalculateExtent(kZAxis,limit,origin,minZ,maxZ); // limits if(nStat < 100) { nStat = 100; } G4double dX=maxX-minX; G4double dY=maxY-minY; G4double dZ=maxZ-minZ; if(ell<=0.) // Automatic definition of skin thickness { G4double minval=dX; if(dYInside(p); if(in != kOutside) { if (DistanceToOut(p)pSectionIndex+1-> // pSectionIndex+2->pSectionIndex+3->pSectionIndex // in the List pVertices // // If the minimum is pMax pMax is set to the new maximum // // No modifications are made to pVertices // void G4VSolid::ClipCrossSection( G4ThreeVectorList* pVertices, const G4int pSectionIndex, const G4VoxelLimits& pVoxelLimit, const EAxis pAxis, G4double& pMin, G4double& pMax) const { G4ThreeVectorList polygon; polygon.reserve(4); polygon.push_back((*pVertices)[pSectionIndex]); polygon.push_back((*pVertices)[pSectionIndex+1]); polygon.push_back((*pVertices)[pSectionIndex+2]); polygon.push_back((*pVertices)[pSectionIndex+3]); // G4cout<<"ClipCrossSection: 0-1-2-3"<pSectionIndex+3 and // pSectionIndex+4->pSectionIndex7 // // in the List pVertices, within the boundaries of the voxel limits pVoxelLimit // // If the minimum is pMax pMax is set to the new maximum // // No modifications are made to pVertices void G4VSolid::ClipBetweenSections( G4ThreeVectorList* pVertices, const G4int pSectionIndex, const G4VoxelLimits& pVoxelLimit, const EAxis pAxis, G4double& pMin, G4double& pMax) const { G4ThreeVectorList polygon; polygon.reserve(4); polygon.push_back((*pVertices)[pSectionIndex]); polygon.push_back((*pVertices)[pSectionIndex+4]); polygon.push_back((*pVertices)[pSectionIndex+5]); polygon.push_back((*pVertices)[pSectionIndex+1]); // G4cout<<"ClipBetweenSections: 0-4-5-1"< output inside section // // G4cout << "vStart outside, vEnd inside" << G4endl; pVoxelLimit.ClipToLimits(vStart,vEnd); outputPolygon.push_back(vStart); outputPolygon.push_back(vEnd); } else // Both point outside -> no output { // outputPolygon.push_back(vStart); // outputPolygon.push_back(vEnd); } } } } G4VisExtent G4VSolid::GetExtent () const { G4VisExtent extent; G4VoxelLimits voxelLimits; // Defaults to "infinite" limits. G4AffineTransform affineTransform; G4double vmin, vmax; CalculateExtent(kXAxis,voxelLimits,affineTransform,vmin,vmax); extent.SetXmin (vmin); extent.SetXmax (vmax); CalculateExtent(kYAxis,voxelLimits,affineTransform,vmin,vmax); extent.SetYmin (vmin); extent.SetYmax (vmax); CalculateExtent(kZAxis,voxelLimits,affineTransform,vmin,vmax); extent.SetZmin (vmin); extent.SetZmax (vmax); return extent; } G4Polyhedron* G4VSolid::CreatePolyhedron () const { return 0; } G4NURBS* G4VSolid::CreateNURBS () const { return 0; } G4Polyhedron* G4VSolid::GetPolyhedron () const { return 0; }