162 if (&ts ==
this)
return *
this;
216 for (
G4int i = 0; i <
n; ++i)
235 G4Exception(
"G4TessellatedSolid::AddFacet()",
"GeomSolids1002",
236 JustWarning,
"Attempt to add facets when solid is closed.");
241 set<G4VertexInfo,G4VertexComparator>::iterator begin
246 value.
mag2 = p.x() + p.y() + p.z();
255 while (!found && it != end)
260 if ((found = (facet == aFacet)))
break;
262 if (dif > kCarTolerance3)
break;
269 while (!found && it != begin)
275 found = (facet == aFacet);
278 if (dif > kCarTolerance3)
break;
293 G4Exception(
"G4TessellatedSolid::AddFacet()",
"GeomSolids1002",
294 JustWarning,
"Attempt to add facet not properly defined.");
303 const std::vector<G4int> &
max,
306 vector<G4int> xyz = voxel;
307 stack<vector<G4int> >
pos;
310 G4int cc = 0, nz = 0;
312 vector<G4int> candidates;
330 for (
G4int i = 0; i <= 2; ++i)
332 if (xyz[i] < max[i] - 1)
360 vector<G4int> voxel(3), maxVoxels(3);
362 G4int size = maxVoxels[0] * maxVoxels[1] * maxVoxels[2];
369 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
371 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
373 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
421 for (
G4int j = 0; j < size; ++j)
427 for (
G4int i=0; i < vsize; ++i)
453 set<G4VertexInfo,G4VertexComparator> vertexListSorted;
454 set<G4VertexInfo,G4VertexComparator>::iterator begin
455 = vertexListSorted.begin(), end = vertexListSorted.end(),
pos, it;
464 vector<G4int> newIndex(100);
466 for (
G4int k = 0; k < size; ++k)
475 value.
mag2 = p.x() + p.y() + p.z();
481 pos = vertexListSorted.lower_bound(value);
488 found = (dif < kCarTolerance24);
490 dif = q.x() + q.y() + q.z() - value.
mag2;
491 if (dif > kCarTolerance3)
break;
504 found = (dif < kCarTolerance24);
506 dif = value.
mag2 - (q.x() + q.y() + q.z());
507 if (dif > kCarTolerance3)
break;
515 G4cout << p.x() <<
":" << p.y() <<
":" << p.z() <<
G4endl;
516 G4cout <<
"Adding new vertex #" << i <<
" of facet " << k
521 vertexListSorted.insert(value);
522 begin = vertexListSorted.begin();
523 end = vertexListSorted.end();
524 newIndex[i] = value.
id;
542 G4cout << p.x() <<
":" << p.y() <<
":" << p.z() <<
G4endl;
543 G4cout <<
"Vertex #" << i <<
" of facet " << k
544 <<
" found, redirecting to " <<
id <<
G4endl;
560 for (set<G4VertexInfo,G4VertexComparator>::iterator res=
561 vertexListSorted.begin(); res!=vertexListSorted.end(); ++res)
563 G4int id = (*res).id;
565 G4double mvalue = vec.x() + vec.y() + vec.z();
566 if (previousValue && (previousValue - 1e-9 > mvalue))
567 G4cout <<
"Error in CreateVertexList: previousValue " << previousValue
568 <<
" is smaller than mvalue " << mvalue <<
G4endl;
569 previousValue = mvalue;
581 G4cout <<
"G4TessellatedSolid - Allocated memory without voxel overhead "
582 << without <<
"; with " << with <<
"; ratio: " << ratio <<
G4endl;
638 for (
G4int i = 0; i < size; ++i)
664 vector<G4int> startingVoxel(3);
667 const G4double dirTolerance = 1.0E-14;
669 const vector<G4int> &startingCandidates =
671 G4int limit = startingCandidates.size();
681 for(
G4int i = 0; i < limit; ++i)
683 G4int candidate = startingCandidates[i];
686 if (dist < minDist) minDist = dist;
713 G4bool nearParallel =
false;
733 vector<G4int> curVoxel(3);
734 curVoxel = startingVoxel;
742 const vector<G4int> &candidates =
745 if (
G4int candidatesCount = candidates.size())
747 for (
G4int i = 0 ; i < candidatesCount; ++i)
749 G4int candidate = candidates[i];
753 crossingO = facet.
Intersect(p,v,
true,distO,distFromSurfaceO,normalO);
754 crossingI = facet.
Intersect(p,v,
false,distI,distFromSurfaceI,normalI);
756 if (crossingO || crossingI)
760 nearParallel = (crossingO
761 && std::fabs(normalO.dot(v))<dirTolerance)
762 || (crossingI && std::fabs(normalI.dot(v))<dirTolerance);
765 if (crossingO && distO > 0.0 && distO < distOut)
767 if (crossingI && distI > 0.0 && distI < distIn)
773 if (nearParallel)
break;
789 currentPoint += direction * (shift + shiftBonus);
808 std::ostringstream message;
809 G4int oldprc = message.precision(16);
810 message <<
"Cannot determine whether point is inside or outside volume!"
816 <<
"p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
817 <<
"p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
818 <<
"p.z() = " << p.z()/
mm <<
" mm";
819 message.precision(oldprc);
855 const G4double dirTolerance = 1.0E-14;
862 for (
G4int i = 0; i < size; ++i)
866 if (dist < minDist) minDist = dist;
902 for (
G4int i=0; i<nTry; ++i)
904 G4bool nearParallel =
false;
916 vector<G4VFacet*>::const_iterator f =
fFacets.begin();
925 crossingO = ((*f)->Intersect(p,v,
true,distO,distFromSurfaceO,normalO));
926 crossingI = ((*f)->Intersect(p,v,
false,distI,distFromSurfaceI,normalI));
927 if (crossingO || crossingI)
929 nearParallel = (crossingO && std::fabs(normalO.dot(v))<dirTolerance)
930 || (crossingI && std::fabs(normalI.dot(v))<dirTolerance);
933 if (crossingO && distO > 0.0 && distO < distOut) distOut = distO;
934 if (crossingI && distI > 0.0 && distI < distIn) distIn = distI;
937 }
while (!nearParallel && ++f!=
fFacets.end());
948 std::ostringstream message;
949 G4int oldprc = message.precision(16);
950 message <<
"Cannot determine whether point is inside or outside volume!"
956 <<
"p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
957 <<
"p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
958 <<
"p.z() = " << p.z()/
mm <<
" mm";
959 message.precision(oldprc);
981 if (i == 0) location = locationprime;
1000 vector<G4int> curVoxel(3);
1005 if (
G4int limit = candidates.size())
1008 for(
G4int i = 0 ; i < limit ; ++i)
1010 G4int candidate = candidates[i];
1013 if (dist < minDist) minDist = dist;
1027 for (
G4int i = 0; i < size; ++i)
1047 std::ostringstream message;
1048 message <<
"Point p is not on surface !?" <<
G4endl
1049 <<
" No facets found for point: " << p <<
" !" <<
G4endl
1050 <<
" Returning approximated value for normal.";
1052 G4Exception(
"G4TessellatedSolid::SurfaceNormal(p)",
1083 std::ostringstream message;
1084 G4int oldprc = message.precision(16) ;
1085 message <<
"Point p is already inside!?" <<
G4endl
1087 <<
" p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
1088 <<
" p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
1089 <<
" p.z() = " << p.z()/
mm <<
" mm" <<
G4endl
1091 message.precision(oldprc) ;
1092 G4Exception(
"G4TriangularFacet::DistanceToIn(p,v)",
1098 for (
G4int i = 0; i < size; ++i)
1101 if (facet.
Intersect(p,v,
false,dist,distFromSurface,normal))
1151 std::ostringstream message;
1152 G4int oldprc = message.precision(16) ;
1153 message <<
"Point p is already outside!?" <<
G4endl
1155 <<
" p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
1156 <<
" p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
1157 <<
" p.z() = " << p.z()/
mm <<
" mm" <<
G4endl
1159 message.precision(oldprc) ;
1160 G4Exception(
"G4TriangularFacet::DistanceToOut(p)",
1165 G4bool isExtreme =
false;
1167 for (
G4int i = 0; i < size; ++i)
1170 if (facet.
Intersect(p,v,
true,dist,distFromSurface,normal))
1182 if (dist >= 0.0 && dist < minDist)
1192 aNormalVector = minNormal;
1193 aConvex = isExtreme;
1200 Normal(p, aNormalVector);
1212 G4int &minCandidate )
const
1214 G4int candidatesCount = candidates.size();
1219 for (
G4int i = 0 ; i < candidatesCount; ++i)
1221 G4int candidate = candidates[i];
1223 if (facet.
Intersect(aPoint,direction,
true,dist,distFromSurface,normal))
1232 minCandidate = candidate;
1235 if (dist >= 0.0 && dist < minDist)
1239 minCandidate = candidate;
1263 vector<G4int> curVoxel(3);
1270 const vector<G4int> *old = 0;
1272 G4int minCandidate = -1;
1276 if (old == &candidates)
1278 if (old != &candidates && candidates.size())
1281 aNormalVector, minCandidate);
1282 if (minDistance <= totalShift)
break;
1288 totalShift += shift;
1289 if (minDistance <= totalShift)
break;
1291 currentPoint += direction * (shift + shiftBonus);
1297 if (minCandidate < 0)
1302 Normal(aPoint, aNormalVector);
1325 G4int candidatesCount = candidates.size();
1331 for (
G4int i = 0 ; i < candidatesCount; ++i)
1333 G4int candidate = candidates[i];
1335 if (facet.
Intersect(aPoint,direction,
false,dist,distFromSurface,normal))
1345 && (dist >= 0.0) && (dist < minDistance))
1384 currentPoint += direction * (shift + shiftBonus);
1389 vector<G4int> curVoxel(3);
1395 if (candidates.size())
1398 if (minDistance > distance) minDistance = distance;
1399 if (distance < totalShift)
break;
1405 totalShift += shift;
1406 if (minDistance < totalShift)
break;
1408 currentPoint += direction * (shift + shiftBonus);
1424 const std::pair<G4int, G4double> &r)
1426 return l.second < r.second;
1439 vector<pair<G4int, G4double> > voxelsSorted(size);
1441 pair<G4int, G4double> info;
1443 for (
G4int i = 0; i < size; ++i)
1450 info.second = safety;
1451 voxelsSorted[i] = info;
1454 std::sort(voxelsSorted.begin(), voxelsSorted.end(),
1457 for (
G4int i = 0; i < size; ++i)
1459 const pair<G4int,G4double> &inf = voxelsSorted[i];
1461 if (dist > minDist)
break;
1464 G4int csize = candidates.size();
1465 for (
G4int j = 0; j < csize; ++j)
1467 G4int candidate = candidates[j];
1469 dist = simple ? facet.
Distance(p,minDist)
1489 std::ostringstream message;
1490 G4int oldprc = message.precision(16) ;
1491 message <<
"Point p is already inside!?" <<
G4endl
1493 <<
"p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
1494 <<
"p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
1495 <<
"p.z() = " << p.z()/
mm <<
" mm" <<
G4endl
1497 message.precision(oldprc) ;
1512 vector<G4int> startingVoxel(3);
1529 for (
G4int i = 0; i < size; ++i)
1533 if (dist < minDist) minDist = dist;
1547 std::ostringstream message;
1548 G4int oldprc = message.precision(16) ;
1549 message <<
"Point p is already outside!?" <<
G4endl
1551 <<
"p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
1552 <<
"p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
1553 <<
"p.z() = " << p.z()/
mm <<
" mm" <<
G4endl
1555 message.precision(oldprc) ;
1556 G4Exception(
"G4TriangularFacet::DistanceToOut(p)",
1575 for (
G4int i = 0; i < size; ++i)
1579 if (dist < minDist) minDist = dist;
1605 for (
G4int i = 0; i < size; ++i)
1607 os <<
"FACET # = " << i + 1 <<
G4endl;
1742 for (G4ThreeVectorList::const_iterator v=
fVertexList.begin();
1749 for (
G4int i = 0; i < size; ++i)
1755 else if (n == 3) v[3] = 0;
1756 for (
G4int j=0; j<
n; ++j)
1761 polyhedron->
AddFacet(v[0],v[1],v[2],v[3]);
1804 for (
G4int i=0; i < size; ++i)
1813 size = transVertexList.size();
1814 for (
G4int i=0; i< size; ++i)
1816 for (
G4int axis=G4ThreeVector::X; axis < G4ThreeVector::SIZE; ++axis)
1818 G4double coordinate = transVertexList[i][axis];
1819 if (coordinate < minExtent[axis])
1820 { minExtent[axis] = coordinate; }
1821 if (coordinate > maxExtent[axis])
1822 { maxExtent[axis] = coordinate; }
1827 for (
G4int axis=G4ThreeVector::X; axis < G4ThreeVector::SIZE; ++axis)
1832 case G4ThreeVector::X: geomAxis =
kXAxis;
break;
1833 case G4ThreeVector::Y: geomAxis =
kYAxis;
break;
1834 case G4ThreeVector::Z: geomAxis =
kZAxis;
break;
1849 if (minExtent[axis] < voxelMinExtent)
1851 minExtent[axis] = voxelMinExtent ;
1853 if (maxExtent[axis] > voxelMaxExtent)
1855 maxExtent[axis] = voxelMaxExtent;
1865 case kXAxis: vecAxis = G4ThreeVector::X;
break;
1866 case kYAxis: vecAxis = G4ThreeVector::Y;
break;
1867 case kZAxis: vecAxis = G4ThreeVector::Z;
break;
1942 for (
G4int i = 0; i < size; ++i)
1957 return fFacets[i]->GetPointOnFace();
1973 G4ThreeVector(-0.9577428892113370, 0.2732676269591740, 0.0897405271949221);
1975 G4ThreeVector(-0.8331264504940770,-0.5162067214954600,-0.1985722492445700);
1977 G4ThreeVector(-0.1516671651108820, 0.9666292616127460, 0.2064580868390110);
1979 G4ThreeVector( 0.6570250350323190,-0.6944539025883300, 0.2933460081893360);
1981 G4ThreeVector(-0.4820456281280320,-0.6331060000098690,-0.6056474264406270);
1983 G4ThreeVector( 0.7629032554236800 , 0.1016854697539910,-0.6384658864065180);
1985 G4ThreeVector( 0.7689540409061150, 0.5034929891988220, 0.3939600142169160);
1987 G4ThreeVector( 0.5765188359255740, 0.5997271636278330,-0.5549354566343150);
1989 G4ThreeVector( 0.6660632777862070,-0.6362809868288380, 0.3892379937580790);
1991 G4ThreeVector( 0.3824415020414780, 0.6541792713761380,-0.6525243125110690);
1993 G4ThreeVector(-0.5107726564526760, 0.6020905056811610, 0.6136760679616570);
1995 G4ThreeVector( 0.7459135439578050, 0.6618796061649330, 0.0743530220183488);
1997 G4ThreeVector( 0.1536405855311580, 0.8117477913978260,-0.5634359711967240);
1999 G4ThreeVector( 0.0744395301705579,-0.8707110101772920,-0.4861286795736560);
2001 G4ThreeVector(-0.1665874645185400, 0.6018553940549240,-0.7810369397872780);
2003 G4ThreeVector( 0.7766902003633100, 0.6014617505959970,-0.1870724331097450);
2005 G4ThreeVector(-0.8710128685847430,-0.1434320216603030,-0.4698551243971010);
2007 G4ThreeVector( 0.8901082092766820,-0.4388411398893870, 0.1229871120030100);
2009 G4ThreeVector(-0.6430417431544370,-0.3295938228697690, 0.6912779675984150);
2011 G4ThreeVector( 0.6331124368380410, 0.6306211461665000, 0.4488714875425340);
2020 G4int base =
sizeof(*this);
2025 for (
G4int i = 0; i < limit; i++)
2031 std::set<G4VFacet *>::const_iterator beg, end, it;
2034 for (it = beg; it != end; it++)
2049 size += sizeInsides + sizeVoxels;
G4bool Contains(const G4ThreeVector &point) const
void ResetBitNumber(unsigned int bitnumber)
unsigned int GetNbits() const
ThreeVector shoot(const G4int Ap, const G4int Af)
void SetSolidClosed(const G4bool t)
EInside InsideVoxels(const G4ThreeVector &aPoint) const
G4double DistanceToInCore(const G4ThreeVector &p, const G4ThreeVector &v, G4double aPstep=kInfinity) const
static const G4double kInfinity
G4double DistanceToInNoVoxels(const G4ThreeVector &p, const G4ThreeVector &v, G4double aPstep=kInfinity) const
void Voxelize(std::vector< G4VFacet * > &facets)
virtual G4double GetArea()=0
CLHEP::Hep3Vector G4ThreeVector
void DistanceToOutCandidates(const std::vector< G4int > &candidates, const G4ThreeVector &aPoint, const G4ThreeVector &direction, G4double &minDist, G4ThreeVector &minNormal, G4int &minCandidate) const
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const
void PrecalculateInsides()
void CopyObjects(const G4TessellatedSolid &s)
std::vector< G4ThreeVector > fVertexList
G4int GetCandidates(std::vector< G4int > &curVoxel, std::vector< G4int > *&candidates, std::vector< G4int > &space) const
virtual G4bool Intersect(const G4ThreeVector &, const G4ThreeVector &, const G4bool, G4double &, G4double &, G4ThreeVector &)=0
virtual G4VisExtent GetExtent() const
G4double DistanceToFirst(const G4ThreeVector &point, const G4ThreeVector &direction) const
G4double DistanceToBoundingBox(const G4ThreeVector &point) const
virtual G4double GetCubicVolume()
G4double GetMaxXExtent() const
virtual G4int GetNumberOfVertices() const =0
virtual G4ThreeVector GetCircumcentre() const =0
virtual G4double GetCubicVolume()
virtual G4double Distance(const G4ThreeVector &, G4double)=0
G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const
G4double GetMinXExtent() const
std::vector< G4ThreeVector > fRandir
virtual G4double GetSurfaceArea()
static G4double MinDistanceToBox(const G4ThreeVector &aPoint, const G4ThreeVector &f)
virtual void SetVertexIndex(G4int i, G4int j)=0
G4bool UpdateCurrentVoxel(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
G4double GetMaxZExtent() const
static G4bool CompareSortedVoxel(const std::pair< G4int, G4double > &l, const std::pair< G4int, G4double > &r)
virtual void AddSolid(const G4Box &)=0
#define G4MUTEX_INITIALIZER
G4int GetPointIndex(const G4ThreeVector &p) const
void SetBitNumber(unsigned int bitnumber, G4bool value=true)
G4VFacet * GetFacet(G4int i) const
static double normal(HepRandomEngine *eptr)
G4double kCarToleranceHalf
G4bool IsEmpty(G4int index) const
virtual G4ThreeVector GetSurfaceNormal() const =0
G4double DistanceToInCandidates(const std::vector< G4int > &candidates, const G4ThreeVector &aPoint, const G4ThreeVector &aDirection) const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
virtual G4double DistanceToOut(const G4ThreeVector &p) const
virtual G4Polyhedron * CreatePolyhedron() const
void GetVoxel(std::vector< G4int > &curVoxel, const G4ThreeVector &point) const
virtual void SetVertices(std::vector< G4ThreeVector > *vertices)=0
G4int SetAllUsingStack(const std::vector< G4int > &voxel, const std::vector< G4int > &max, G4bool status, G4SurfBits &checked)
virtual EInside Inside(const G4ThreeVector &p) const
G4bool fRebuildPolyhedron
G4bool OutsideOfExtent(const G4ThreeVector &p, G4double tolerance=0) const
G4bool AddFacet(G4VFacet *aFacet)
G4double DistanceToNext(const G4ThreeVector &point, const G4ThreeVector &direction, const std::vector< G4int > &curVoxel) const
std::vector< G4ThreeVector > G4ThreeVectorList
void SetMaxVoxels(G4int max)
EInside InsideNoVoxels(const G4ThreeVector &p) const
G4TessellatedSolid & operator+=(const G4TessellatedSolid &right)
G4SurfaceVoxelizer fVoxels
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
void AddVertex(const G4ThreeVector &v)
virtual G4VSolid * Clone() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
std::set< G4VertexInfo, G4VertexComparator > fFacetList
G4int AllocatedMemoryWithoutVoxels()
virtual G4Polyhedron * GetPolyhedron() const
G4int GetNumberOfFacets() const
G4bool IsInside(const G4ThreeVector &p) const
virtual std::ostream & StreamInfo(std::ostream &os) const
virtual G4int GetVertexIndex(G4int i) const =0
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4double MinDistanceFacet(const G4ThreeVector &p, G4bool simple, G4VFacet *&facet) const
G4Polyhedron * fpPolyhedron
G4double DistanceToOutNoVoxels(const G4ThreeVector &p, const G4ThreeVector &v, G4ThreeVector &aNormalVector, G4bool &aConvex, G4double aPstep=kInfinity) const
virtual G4double SafetyFromInside(const G4ThreeVector &p, G4bool aAccurate=false) const
std::ostream & StreamInfo(std::ostream &os) const
void AddFacet(const G4int iv1, const G4int iv2, const G4int iv3, const G4int iv4=0)
virtual ~G4TessellatedSolid()
G4GeometryType fGeometryType
std::set< G4VFacet * > fExtremeFacets
std::vector< G4VFacet * > fFacets
long long GetCountOfVoxels() const
virtual G4GeometryType GetEntityType() const
const std::vector< G4double > & GetBoundary(G4int index) const
G4VSolid & operator=(const G4VSolid &rhs)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
const G4SurfBits & Empty() const
G4int GetMaxVoxels(G4ThreeVector &ratioOfReduction)
const std::vector< G4int > & GetVoxelBoxCandidates(G4int i) const
void DisplayAllocatedMemory()
virtual G4VFacet * GetClone()=0
virtual G4bool Normal(const G4ThreeVector &p, G4ThreeVector &n) const
G4int GetVoxelBoxesSize() const
G4double GetMaxExtent(const EAxis pAxis) const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
virtual G4ThreeVector GetVertex(G4int i) const =0
const G4VoxelBox & GetVoxelBox(G4int i) const
G4double GetMaxYExtent() const
virtual G4ThreeVector GetPointOnSurface() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double DistanceToOutCore(const G4ThreeVector &p, const G4ThreeVector &v, G4ThreeVector &aNormalVector, G4bool &aConvex, G4double aPstep=kInfinity) const
static const G4double pos
G4double GetMinExtent(const EAxis pAxis) const
virtual G4int AllocatedMemory()=0
virtual G4double SafetyFromOutside(const G4ThreeVector &p, G4bool aAccurate=false) const
G4double GetMinYExtent() const
unsigned int GetNbytes() const
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)
G4bool GetSolidClosed() const
virtual G4bool IsDefined() const =0