Import Geant4 10.3.0 source tree
This commit is contained in:
@@ -24,12 +24,15 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4TessellatedSolid.cc 95311 2016-02-04 13:54:13Z gcosmo $
|
||||
// $Id: G4TessellatedSolid.cc 101118 2016-11-07 09:10:59Z gcosmo $
|
||||
//
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// 23 October 2016, E Tcherniaev, reimplemented CalculateExtent() to make
|
||||
// use of G4BoundingEnvelope, added Extent().
|
||||
//
|
||||
// 12 October 2012, M Gayer, CERN, complete rewrite reducing memory
|
||||
// requirements more than 50% and speedup by a factor of
|
||||
// tens or more depending on the number of facets, thanks
|
||||
@@ -87,6 +90,7 @@
|
||||
#include "G4VFacet.hh"
|
||||
#include "G4VoxelLimits.hh"
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
#include "G4VGraphicsScene.hh"
|
||||
@@ -270,7 +274,7 @@ G4bool G4TessellatedSolid::AddFacet (G4VFacet *aFacet)
|
||||
{
|
||||
--it;
|
||||
G4int id = (*it).id;
|
||||
G4VFacet *facet = fFacets[id];
|
||||
G4VFacet *facet = fFacets[id];
|
||||
G4ThreeVector q = facet->GetCircumcentre();
|
||||
found = (facet == aFacet);
|
||||
if (found) break;
|
||||
@@ -375,7 +379,10 @@ void G4TessellatedSolid::PrecalculateInsides()
|
||||
G4int index = fVoxels.GetVoxelsIndex(voxel);
|
||||
if (!checked[index] && fVoxels.IsEmpty(index))
|
||||
{
|
||||
for (G4int i = 0; i <= 2; ++i) point[i] = fVoxels.GetBoundary(i)[voxel[i]];
|
||||
for (G4int i = 0; i <= 2; ++i)
|
||||
{
|
||||
point[i] = fVoxels.GetBoundary(i)[voxel[i]];
|
||||
}
|
||||
G4bool inside = (G4bool) (InsideNoVoxels(point) == kInside);
|
||||
SetAllUsingStack(voxel, maxVoxels, inside, checked);
|
||||
}
|
||||
@@ -511,11 +518,11 @@ void G4TessellatedSolid::CreateVertexList()
|
||||
|
||||
if (!found)
|
||||
{
|
||||
#ifdef G4SPECSDEBUG
|
||||
#ifdef G4SPECSDEBUG
|
||||
G4cout << p.x() << ":" << p.y() << ":" << p.z() << G4endl;
|
||||
G4cout << "Adding new vertex #" << i << " of facet " << k
|
||||
<< " id " << value.id << G4endl;
|
||||
G4cout << "===" << G4endl;
|
||||
G4cout << "===" << G4endl;
|
||||
#endif
|
||||
fVertexList.push_back(p);
|
||||
vertexListSorted.insert(value);
|
||||
@@ -538,7 +545,7 @@ void G4TessellatedSolid::CreateVertexList()
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef G4SPECSDEBUG
|
||||
#ifdef G4SPECSDEBUG
|
||||
G4cout << p.x() << ":" << p.y() << ":" << p.z() << G4endl;
|
||||
G4cout << "Vertex #" << i << " of facet " << k
|
||||
<< " found, redirecting to " << id << G4endl;
|
||||
@@ -579,7 +586,7 @@ void G4TessellatedSolid::DisplayAllocatedMemory()
|
||||
G4int with = AllocatedMemory();
|
||||
G4double ratio = (G4double) with / without;
|
||||
G4cout << "G4TessellatedSolid - Allocated memory without voxel overhead "
|
||||
<< without << "; with " << with << "; ratio: " << ratio << G4endl;
|
||||
<< without << "; with " << with << "; ratio: " << ratio << G4endl;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1114,12 +1121,12 @@ G4TessellatedSolid::DistanceToInNoVoxels (const G4ThreeVector &p,
|
||||
else
|
||||
{
|
||||
if (-kCarToleranceHalf <= dist && dist <= kCarToleranceHalf)
|
||||
{
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (distFromSurface > -kCarToleranceHalf
|
||||
if (distFromSurface > -kCarToleranceHalf
|
||||
&& distFromSurface < kCarToleranceHalf)
|
||||
{
|
||||
minDist = dist;
|
||||
@@ -1816,9 +1823,31 @@ G4Polyhedron* G4TessellatedSolid::GetPolyhedron () const
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CalculateExtent
|
||||
// Get bounding box
|
||||
//
|
||||
// Based on correction provided by Stan Seibert, University of Texas.
|
||||
void G4TessellatedSolid::Extent(G4ThreeVector& pMin, G4ThreeVector& pMax) const
|
||||
{
|
||||
pMin = fMinExtent;
|
||||
pMax = fMaxExtent;
|
||||
|
||||
// Check correctness of the bounding box
|
||||
//
|
||||
if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Bad bounding box (min >= max) for solid: "
|
||||
<< GetName() << " !"
|
||||
<< "\npMin = " << pMin
|
||||
<< "\npMax = " << pMax;
|
||||
G4Exception("G4TessellatedSolid::Extent()",
|
||||
"GeomMgt0001", JustWarning, message);
|
||||
DumpInfo();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate extent under transform and specified limit
|
||||
//
|
||||
G4bool
|
||||
G4TessellatedSolid::CalculateExtent(const EAxis pAxis,
|
||||
@@ -1826,81 +1855,55 @@ G4TessellatedSolid::CalculateExtent(const EAxis pAxis,
|
||||
const G4AffineTransform& pTransform,
|
||||
G4double& pMin, G4double& pMax) const
|
||||
{
|
||||
G4ThreeVectorList transVertexList(fVertexList);
|
||||
G4int size = fVertexList.size();
|
||||
G4ThreeVector bmin, bmax;
|
||||
G4bool exist;
|
||||
|
||||
// Put solid into transformed frame
|
||||
for (G4int i=0; i < size; ++i)
|
||||
// Check bounding box (bbox)
|
||||
//
|
||||
Extent(bmin,bmax);
|
||||
G4BoundingEnvelope bbox(bmin,bmax);
|
||||
#ifdef G4BBOX_EXTENT
|
||||
if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
|
||||
#endif
|
||||
if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
|
||||
{
|
||||
pTransform.ApplyPointTransform(transVertexList[i]);
|
||||
return exist = (pMin < pMax) ? true : false;
|
||||
}
|
||||
|
||||
// Find min and max extent in each dimension
|
||||
G4ThreeVector minExtent(kInfinity, kInfinity, kInfinity);
|
||||
G4ThreeVector maxExtent(-kInfinity, -kInfinity, -kInfinity);
|
||||
// The extent is calculated as cumulative extent of the pyramids
|
||||
// formed by facets and the center of the bounding box.
|
||||
//
|
||||
G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
|
||||
G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
|
||||
|
||||
size = transVertexList.size();
|
||||
for (G4int i=0; i< size; ++i)
|
||||
G4ThreeVectorList base;
|
||||
G4ThreeVectorList apex(1);
|
||||
std::vector<const G4ThreeVectorList *> pyramid(2);
|
||||
pyramid[0] = &base;
|
||||
pyramid[1] = &apex;
|
||||
apex[0] = (bmin+bmax)*0.5;
|
||||
|
||||
// main loop along facets
|
||||
pMin = kInfinity;
|
||||
pMax = -kInfinity;
|
||||
for (G4int i=0; i<GetNumberOfFacets(); ++i)
|
||||
{
|
||||
for (G4int axis=G4ThreeVector::X; axis < G4ThreeVector::SIZE; ++axis)
|
||||
{
|
||||
G4double coordinate = transVertexList[i][axis];
|
||||
if (coordinate < minExtent[axis])
|
||||
{ minExtent[axis] = coordinate; }
|
||||
if (coordinate > maxExtent[axis])
|
||||
{ maxExtent[axis] = coordinate; }
|
||||
}
|
||||
G4VFacet* facet = GetFacet(i);
|
||||
if (std::abs((facet->GetSurfaceNormal()).dot(facet->GetVertex(0)-apex[0]))
|
||||
< kCarToleranceHalf) continue;
|
||||
|
||||
G4int nv = facet->GetNumberOfVertices();
|
||||
base.resize(nv);
|
||||
for (G4int k=0; k<nv; ++k) { base[k] = facet->GetVertex(k); }
|
||||
|
||||
G4double emin,emax;
|
||||
G4BoundingEnvelope benv(pyramid);
|
||||
if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
|
||||
if (emin < pMin) pMin = emin;
|
||||
if (emax > pMax) pMax = emax;
|
||||
if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
|
||||
}
|
||||
|
||||
// Check for containment and clamp to voxel boundaries
|
||||
for (G4int axis=G4ThreeVector::X; axis < G4ThreeVector::SIZE; ++axis)
|
||||
{
|
||||
EAxis geomAxis = kXAxis; // U geom classes use different index type
|
||||
switch(axis)
|
||||
{
|
||||
case G4ThreeVector::X: geomAxis = kXAxis; break;
|
||||
case G4ThreeVector::Y: geomAxis = kYAxis; break;
|
||||
case G4ThreeVector::Z: geomAxis = kZAxis; break;
|
||||
}
|
||||
G4bool isLimited = pVoxelLimit.IsLimited(geomAxis);
|
||||
G4double voxelMinExtent = pVoxelLimit.GetMinExtent(geomAxis);
|
||||
G4double voxelMaxExtent = pVoxelLimit.GetMaxExtent(geomAxis);
|
||||
|
||||
if (isLimited)
|
||||
{
|
||||
if ( minExtent[axis] > voxelMaxExtent+kCarTolerance ||
|
||||
maxExtent[axis] < voxelMinExtent-kCarTolerance )
|
||||
{
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minExtent[axis] < voxelMinExtent)
|
||||
{
|
||||
minExtent[axis] = voxelMinExtent ;
|
||||
}
|
||||
if (maxExtent[axis] > voxelMaxExtent)
|
||||
{
|
||||
maxExtent[axis] = voxelMaxExtent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert pAxis into G4ThreeVector index
|
||||
G4int vecAxis=0;
|
||||
switch(pAxis)
|
||||
{
|
||||
case kXAxis: vecAxis = G4ThreeVector::X; break;
|
||||
case kYAxis: vecAxis = G4ThreeVector::Y; break;
|
||||
case kZAxis: vecAxis = G4ThreeVector::Z; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
pMin = minExtent[vecAxis] - kCarTolerance;
|
||||
pMax = maxExtent[vecAxis] + kCarTolerance;
|
||||
|
||||
return true;
|
||||
return (pMin < pMax);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1949,7 +1952,9 @@ G4double G4TessellatedSolid::GetMaxZExtent () const
|
||||
//
|
||||
G4VisExtent G4TessellatedSolid::GetExtent () const
|
||||
{
|
||||
return G4VisExtent (fMinExtent.x(), fMaxExtent.x(), fMinExtent.y(), fMaxExtent.y(), fMinExtent.z(), fMaxExtent.z());
|
||||
return G4VisExtent (fMinExtent.x(), fMaxExtent.x(),
|
||||
fMinExtent.y(), fMaxExtent.y(),
|
||||
fMinExtent.z(), fMaxExtent.z());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user