50#if !defined(G4GEOM_USE_UTESSELLATEDSOLID)
109 fMinExtent.
set(0,0,0);
110 fMaxExtent.
set(0,0,0);
139 if (&ts ==
this)
return *
this;
155void G4TessellatedSolid::Initialize()
159 fRebuildPolyhedron =
false; fpPolyhedron =
nullptr;
160 fCubicVolume = 0.; fSurfaceArea = 0.;
162 fGeometryType =
"G4TessellatedSolid";
163 fSolidClosed =
false;
165 fMinExtent.
set(kInfinity,kInfinity,kInfinity);
166 fMaxExtent.
set(-kInfinity,-kInfinity,-kInfinity);
173void G4TessellatedSolid::DeleteObjects()
175 std::size_t size = fFacets.size();
176 for (std::size_t i = 0; i < size; ++i) {
delete fFacets[i]; }
178 delete fpPolyhedron; fpPolyhedron =
nullptr;
193 for (
G4int i = 0; i <
n; ++i)
212 G4Exception(
"G4TessellatedSolid::AddFacet()",
"GeomSolids1002",
213 JustWarning,
"Attempt to add facets when solid is closed.");
218 set<G4VertexInfo,G4VertexComparator>::iterator begin
219 = fFacetList.begin(), end = fFacetList.end(), pos, it;
222 value.
id = (
G4int)fFacetList.size();
223 value.
mag2 = p.
x() + p.
y() + p.
z();
229 pos = fFacetList.lower_bound(value);
232 while (!found && it != end)
237 if ((found = (facet == aFacet)))
break;
239 if (dif > kCarTolerance3)
break;
243 if (fFacets.size() > 1)
246 while (!found && it != begin)
252 found = (facet == aFacet);
255 if (dif > kCarTolerance3)
break;
262 fFacets.push_back(aFacet);
263 fFacetList.insert(value);
269 G4Exception(
"G4TessellatedSolid::AddFacet()",
"GeomSolids1002",
270 JustWarning,
"Attempt to add facet not properly defined.");
278G4int G4TessellatedSolid::SetAllUsingStack(
const std::vector<G4int>& voxel,
279 const std::vector<G4int>& max,
282 vector<G4int> xyz = voxel;
283 stack<vector<G4int> > pos;
287 vector<G4int> candidates;
304 for (
auto i = 0; i <= 2; ++i)
306 if (xyz[i] < max[i] - 1)
328void G4TessellatedSolid::PrecalculateInsides()
330 vector<G4int> voxel(3), maxVoxels(3);
331 for (
auto i = 0; i <= 2; ++i)
333 G4int size = maxVoxels[0] * maxVoxels[1] * maxVoxels[2];
340 for (voxel[2] = 0; voxel[2] < maxVoxels[2] - 1; ++voxel[2])
342 for (voxel[1] = 0; voxel[1] < maxVoxels[1] - 1; ++voxel[1])
344 for (voxel[0] = 0; voxel[0] < maxVoxels[0] - 1; ++voxel[0])
347 if (!checked[index] && fVoxels.
IsEmpty(index))
349 for (
auto i = 0; i <= 2; ++i)
354 SetAllUsingStack(voxel, maxVoxels, inside, checked);
364void G4TessellatedSolid::Voxelize ()
376 PrecalculateInsides();
392void G4TessellatedSolid::SetExtremeFacets()
395 std::size_t vsize = fVertexList.size();
396 std::vector<G4ThreeVector> vertices(vsize);
397 for (std::size_t i = 0; i < vsize; ++i) { vertices[i] = fVertexList[i]; }
400 std::mt19937 gen(12345678);
401 std::shuffle(vertices.begin(), vertices.end(), gen);
405 for (
auto & point : points) { point = vertices[0]; }
406 for (std::size_t i=1; i < vsize; ++i)
408 if (vertices[i].x() < points[0].x()) points[0] = vertices[i];
409 if (vertices[i].x() > points[1].x()) points[1] = vertices[i];
410 if (vertices[i].y() < points[2].y()) points[2] = vertices[i];
411 if (vertices[i].y() > points[3].y()) points[3] = vertices[i];
412 if (vertices[i].z() < points[4].z()) points[4] = vertices[i];
413 if (vertices[i].z() > points[5].z()) points[5] = vertices[i];
417 std::size_t size = fFacets.size();
418 for (std::size_t j = 0; j < size; ++j)
423 if (!facet.
IsInside(points[0]))
continue;
424 if (!facet.
IsInside(points[1]))
continue;
425 if (!facet.
IsInside(points[2]))
continue;
426 if (!facet.
IsInside(points[3]))
continue;
427 if (!facet.
IsInside(points[4]))
continue;
428 if (!facet.
IsInside(points[5]))
continue;
432 for (std::size_t i=0; i < vsize; ++i)
440 if (isExtreme) fExtremeFacets.insert(&facet);
446void G4TessellatedSolid::CreateVertexList()
458 set<G4VertexInfo,G4VertexComparator> vertexListSorted;
459 set<G4VertexInfo,G4VertexComparator>::iterator begin
460 = vertexListSorted.begin(), end = vertexListSorted.end(),
pos, it;
465 std::size_t size = fFacets.size();
469 vector<G4int> newIndex(100);
471 for (std::size_t k = 0; k < size; ++k)
479 value.
id = (
G4int)fVertexList.size();
480 value.
mag2 = p.
x() + p.
y() + p.
z();
486 pos = vertexListSorted.lower_bound(value);
493 found = (dif < kCarTolerance24);
495 dif = q.
x() + q.
y() + q.
z() - value.
mag2;
496 if (dif > kCarTolerance3)
break;
500 if (!found && (fVertexList.size() > 1))
509 found = (dif < kCarTolerance24);
511 dif = value.
mag2 - (q.
x() + q.
y() + q.
z());
512 if (dif > kCarTolerance3)
break;
521 G4cout <<
"Adding new vertex #" << i <<
" of facet " << k
525 fVertexList.push_back(p);
526 vertexListSorted.insert(value);
527 begin = vertexListSorted.begin();
528 end = vertexListSorted.end();
529 newIndex[i] = value.
id;
533 if (value.
id == 0) fMinExtent = fMaxExtent = p;
536 if (p.
x() > fMaxExtent.
x()) fMaxExtent.
setX(p.
x());
537 else if (p.
x() < fMinExtent.
x()) fMinExtent.
setX(p.
x());
538 if (p.
y() > fMaxExtent.
y()) fMaxExtent.
setY(p.
y());
539 else if (p.
y() < fMinExtent.
y()) fMinExtent.
setY(p.
y());
540 if (p.
z() > fMaxExtent.
z()) fMaxExtent.
setZ(p.
z());
541 else if (p.
z() < fMinExtent.
z()) fMinExtent.
setZ(p.
z());
548 G4cout <<
"Vertex #" << i <<
" of facet " << k
549 <<
" found, redirecting to " <<
id <<
G4endl;
561 vector<G4ThreeVector>(fVertexList).swap(fVertexList);
565 for (
auto res=vertexListSorted.cbegin(); res!=vertexListSorted.cend(); ++res)
567 G4int id = (*res).id;
570 if (previousValue && (previousValue - 1e-9 > mvalue))
571 G4cout <<
"Error in CreateVertexList: previousValue " << previousValue
572 <<
" is smaller than mvalue " << mvalue <<
G4endl;
573 previousValue = mvalue;
585 G4cout <<
"G4TessellatedSolid - Allocated memory without voxel overhead "
586 << without <<
"; with " << with <<
"; ratio: " << ratio <<
G4endl;
622 std::ostringstream message;
623 message <<
"Defects in solid: " <<
GetName()
624 <<
" - negative cubic volume, please check orientation of facets!";
625 G4Exception(
"G4TessellatedSolid::SetSolidClosed()",
630 std::ostringstream message;
631 message <<
"Defects in solid: " <<
GetName()
632 <<
" - some facets have wrong orientation!";
633 G4Exception(
"G4TessellatedSolid::SetSolidClosed()",
638 std::ostringstream message;
639 message <<
"Defects in solid: " <<
GetName()
640 <<
" - there are holes in the surface!";
641 G4Exception(
"G4TessellatedSolid::SetSolidClosed()",
673 std::size_t nface = fFacets.size();
678 for (std::size_t i = 0; i < nface; ++i)
684 G4int ivolume =
static_cast<G4int>(volume <= 0.);
688 std::vector<int64_t> iedge(nedge);
690 for (std::size_t i = 0; i < nface; ++i)
694 for (
G4int k = 0; k < nnode; ++k)
698 int64_t inverse =
static_cast<int64_t
>(i2 > i1);
699 if (inverse != 0) std::swap(i1, i2);
700 iedge[kk++] = i1*1000000000 + i2*2 + inverse;
703 std::sort(iedge.begin(), iedge.end());
711 while (i < nedge - 1)
713 if (iedge[i + 1] - iedge[i] == 1)
717 else if (iedge[i + 1] == iedge[i])
728 return ivolume + iorder + ihole;
744 for (
G4int i = 0; i < size; ++i)
756 return (
G4int)fFacets.size();
770 vector<G4int> startingVoxel(3);
773 const G4double dirTolerance = 1.0E-14;
775 const vector<G4int> &startingCandidates =
777 std::size_t limit = startingCandidates.size();
778 if (limit == 0 && (fInsides.
GetNbits() != 0u))
787 for(std::size_t i = 0; i < limit; ++i)
789 G4int candidate = startingCandidates[i];
790 G4VFacet &facet = *fFacets[candidate];
792 if (dist < minDist) minDist = dist;
819 G4bool nearParallel =
false;
827 distOut = distIn = kInfinity;
839 vector<G4int> curVoxel(3);
840 curVoxel = startingVoxel;
848 const vector<G4int> &candidates =
849 started ? startingCandidates : fVoxels.
GetCandidates(curVoxel);
851 if (
auto candidatesCount = (
G4int)candidates.size())
853 for (
G4int i = 0 ; i < candidatesCount; ++i)
855 G4int candidate = candidates[i];
857 G4VFacet& facet = *fFacets[candidate];
859 crossingO = facet.
Intersect(p,v,
true,distO,distFromSurfaceO,normalO);
860 crossingI = facet.
Intersect(p,v,
false,distI,distFromSurfaceI,normalI);
862 if (crossingO || crossingI)
866 nearParallel = (crossingO
867 && std::fabs(normalO.
dot(v))<dirTolerance)
868 || (crossingI && std::fabs(normalI.
dot(v))<dirTolerance);
871 if (crossingO && distO > 0.0 && distO < distOut)
873 if (crossingI && distI > 0.0 && distI < distIn)
879 if (nearParallel)
break;
886 G4bool inside = fInsides[index];
893 if (shift == kInfinity)
break;
895 currentPoint += direction * (shift + shiftBonus);
900 while (nearParallel && sm != fMaxTries);
914 std::ostringstream message;
915 G4long oldprc = message.precision(16);
916 message <<
"Cannot determine whether point is inside or outside volume!"
919 <<
"Geometry Type = " << fGeometryType <<
G4endl
920 <<
"Number of facets = " << fFacets.size() <<
G4endl
922 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
923 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
924 <<
"p.z() = " << p.
z()/mm <<
" mm";
925 message.precision(oldprc);
940 if (distIn == kInfinity && distOut == kInfinity)
961 const G4double dirTolerance = 1.0E-14;
967 std::size_t size = fFacets.size();
968 for (std::size_t i = 0; i < size; ++i)
972 if (dist < minDist) minDist = dist;
1002 G4bool crossingO =
false;
1003 G4bool crossingI =
false;
1008 for (
G4int i=0; i<nTry; ++i)
1010 G4bool nearParallel =
false;
1019 distOut = distIn = kInfinity;
1022 auto f = fFacets.cbegin();
1031 crossingO = ((*f)->Intersect(p,v,
true,distO,distFromSurfaceO,normalO));
1032 crossingI = ((*f)->Intersect(p,v,
false,distI,distFromSurfaceI,normalI));
1033 if (crossingO || crossingI)
1035 nearParallel = (crossingO && std::fabs(normalO.
dot(v))<dirTolerance)
1036 || (crossingI && std::fabs(normalI.
dot(v))<dirTolerance);
1039 if (crossingO && distO > 0.0 && distO < distOut) distOut = distO;
1040 if (crossingI && distI > 0.0 && distI < distIn) distIn = distI;
1043 }
while (!nearParallel && ++f != fFacets.cend());
1044 }
while (nearParallel && sm != fMaxTries);
1047 if (sm == fMaxTries)
1054 std::ostringstream message;
1055 G4long oldprc = message.precision(16);
1056 message <<
"Cannot determine whether point is inside or outside volume!"
1059 <<
"Geometry Type = " << fGeometryType <<
G4endl
1060 <<
"Number of facets = " << fFacets.size() <<
G4endl
1062 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1063 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1064 <<
"p.z() = " << p.
z()/mm <<
" mm";
1065 message.precision(oldprc);
1080 if (distIn == kInfinity && distOut == kInfinity)
1087 if (i == 0) location = locationprime;
1104 vector<G4int> curVoxel(3);
1106 const vector<G4int> &candidates = fVoxels.
GetCandidates(curVoxel);
1107 if (
auto limit = (
G4int)candidates.size())
1110 for(
G4int i = 0 ; i < limit ; ++i)
1112 G4int candidate = candidates[i];
1113 G4VFacet& facet = *fFacets[candidate];
1127 std::size_t size = fFacets.size();
1128 for (std::size_t i = 0; i < size; ++i)
1155 vector<G4int> curVoxel(3);
1157 const vector<G4int> &candidates = fVoxels.
GetCandidates(curVoxel);
1160 if (
auto limit = (
G4int)candidates.size())
1162 minDist = kInfinity;
1163 for(
G4int i = 0 ; i < limit ; ++i)
1165 G4int candidate = candidates[i];
1166 G4VFacet &fct = *fFacets[candidate];
1168 if (dist < minDist) minDist = dist;
1176 minDist = MinDistanceFacet(p,
true, facet);
1180 minDist = kInfinity;
1181 std::size_t size = fFacets.size();
1182 for (std::size_t i = 0; i < size; ++i)
1194 if (minDist != kInfinity)
1202 std::ostringstream message;
1203 message <<
"Point p is not on surface !?" <<
G4endl
1204 <<
" No facets found for point: " << p <<
" !" <<
G4endl
1205 <<
" Returning approximated value for normal.";
1207 G4Exception(
"G4TessellatedSolid::SurfaceNormal(p)",
1226G4TessellatedSolid::DistanceToInNoVoxels (
const G4ThreeVector& p,
1238 std::ostringstream message;
1239 G4int oldprc = message.precision(16) ;
1240 message <<
"Point p is already inside!?" <<
G4endl
1242 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1243 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1244 <<
" p.z() = " << p.
z()/mm <<
" mm" <<
G4endl
1246 message.precision(oldprc) ;
1247 G4Exception(
"G4TriangularFacet::DistanceToIn(p,v)",
1252 std::size_t size = fFacets.size();
1253 for (std::size_t i = 0; i < size; ++i)
1256 if (facet.
Intersect(p,v,
false,dist,distFromSurface,normal))
1292G4TessellatedSolid::DistanceToOutNoVoxels (
const G4ThreeVector& p,
1306 std::ostringstream message;
1307 G4int oldprc = message.precision(16) ;
1308 message <<
"Point p is already outside!?" <<
G4endl
1310 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1311 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1312 <<
" p.z() = " << p.
z()/mm <<
" mm" <<
G4endl
1314 message.precision(oldprc) ;
1315 G4Exception(
"G4TriangularFacet::DistanceToOut(p)",
1320 G4bool isExtreme =
false;
1321 std::size_t size = fFacets.size();
1322 for (std::size_t i = 0; i < size; ++i)
1325 if (facet.
Intersect(p,v,
true,dist,distFromSurface,normal))
1331 aConvex = (fExtremeFacets.find(&facet) != fExtremeFacets.end());
1334 aNormalVector = normal;
1337 if (dist >= 0.0 && dist < minDist)
1341 isExtreme = (fExtremeFacets.find(&facet) != fExtremeFacets.end());
1345 if (minDist < kInfinity)
1347 aNormalVector = minNormal;
1348 aConvex = isExtreme;
1355 Normal(p, aNormalVector);
1362void G4TessellatedSolid::
1363DistanceToOutCandidates(
const std::vector<G4int>& candidates,
1367 G4int& minCandidate )
const
1369 auto candidatesCount = (
G4int)candidates.size();
1374 for (
G4int i = 0 ; i < candidatesCount; ++i)
1376 G4int candidate = candidates[i];
1377 G4VFacet& facet = *fFacets[candidate];
1378 if (facet.
Intersect(aPoint,direction,
true,dist,distFromSurface,normal))
1387 minCandidate = candidate;
1390 if (dist >= 0.0 && dist < minDist)
1394 minCandidate = candidate;
1403G4TessellatedSolid::DistanceToOutCore(
const G4ThreeVector& aPoint,
1413 minDistance = kInfinity;
1418 vector<G4int> curVoxel(3);
1419 if (!fVoxels.
Contains(aPoint))
return 0.;
1421 fVoxels.
GetVoxel(curVoxel, currentPoint);
1425 const vector<G4int>* old =
nullptr;
1427 G4int minCandidate = -1;
1430 const vector<G4int>& candidates = fVoxels.
GetCandidates(curVoxel);
1431 if (old == &candidates)
1433 if (old != &candidates && !candidates.empty())
1435 DistanceToOutCandidates(candidates, aPoint, direction, minDistance,
1436 aNormalVector, minCandidate);
1437 if (minDistance <= totalShift)
break;
1441 if (shift == kInfinity)
break;
1443 totalShift += shift;
1444 if (minDistance <= totalShift)
break;
1446 currentPoint += direction * (shift + shiftBonus);
1452 if (minCandidate < 0)
1457 Normal(aPoint, aNormalVector);
1461 aConvex = (fExtremeFacets.find(fFacets[minCandidate])
1462 != fExtremeFacets.end());
1467 minDistance = DistanceToOutNoVoxels(aPoint, aDirection, aNormalVector,
1476DistanceToInCandidates(
const std::vector<G4int>& candidates,
1480 auto candidatesCount = (
G4int)candidates.size();
1486 for (
G4int i = 0 ; i < candidatesCount; ++i)
1488 G4int candidate = candidates[i];
1489 G4VFacet& facet = *fFacets[candidate];
1490 if (facet.
Intersect(aPoint,direction,
false,dist,distFromSurface,normal))
1500 && (dist >= 0.0) && (dist < minDistance))
1524G4TessellatedSolid::DistanceToInCore(
const G4ThreeVector& aPoint,
1532 minDistance = kInfinity;
1536 if (shift == kInfinity)
return shift;
1539 currentPoint += direction * (shift + shiftBonus);
1544 vector<G4int> curVoxel(3);
1546 fVoxels.
GetVoxel(curVoxel, currentPoint);
1549 const vector<G4int>& candidates = fVoxels.
GetCandidates(curVoxel);
1550 if (!candidates.empty())
1552 G4double distance=DistanceToInCandidates(candidates, aPoint, direction);
1553 if (minDistance > distance) minDistance = distance;
1554 if (distance < totalShift)
break;
1557 shift = fVoxels.
DistanceToNext(currentPoint, direction, curVoxel);
1558 if (shift == kInfinity )
break;
1560 totalShift += shift;
1561 if (minDistance < totalShift)
break;
1563 currentPoint += direction * (shift + shiftBonus);
1569 minDistance = DistanceToInNoVoxels(aPoint, aDirection, aPstep);
1578G4TessellatedSolid::CompareSortedVoxel(
const std::pair<G4int, G4double>& l,
1579 const std::pair<G4int, G4double>& r)
1581 return l.second < r.second;
1594 vector<pair<G4int, G4double> > voxelsSorted(size);
1596 pair<G4int, G4double> info;
1598 for (
G4int i = 0; i < size; ++i)
1605 info.second = safety;
1606 voxelsSorted[i] = info;
1609 std::sort(voxelsSorted.begin(), voxelsSorted.end(),
1610 &G4TessellatedSolid::CompareSortedVoxel);
1612 for (
G4int i = 0; i < size; ++i)
1614 const pair<G4int,G4double>& inf = voxelsSorted[i];
1616 if (dist > minDist)
break;
1619 auto csize = (
G4int)candidates.size();
1620 for (
G4int j = 0; j < csize; ++j)
1622 G4int candidate = candidates[j];
1623 G4VFacet& facet = *fFacets[candidate];
1624 dist = simple ? facet.
Distance(p,minDist)
1644 std::ostringstream message;
1645 G4int oldprc = message.precision(16) ;
1646 message <<
"Point p is already inside!?" <<
G4endl
1648 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1649 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1650 <<
"p.z() = " << p.
z()/mm <<
" mm" <<
G4endl
1652 message.precision(oldprc) ;
1667 vector<G4int> startingVoxel(3);
1668 fVoxels.
GetVoxel(startingVoxel, p);
1669 const vector<G4int> &candidates = fVoxels.
GetCandidates(startingVoxel);
1670 if (candidates.empty() && (fInsides.
GetNbits() != 0u))
1673 if (fInsides[index])
return 0.;
1678 minDist = MinDistanceFacet(p,
true, facet);
1682 minDist = kInfinity;
1683 std::size_t size = fFacets.size();
1684 for (std::size_t i = 0; i < size; ++i)
1688 if (dist < minDist) minDist = dist;
1702 std::ostringstream message;
1703 G4int oldprc = message.precision(16) ;
1704 message <<
"Point p is already outside!?" <<
G4endl
1706 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1707 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1708 <<
"p.z() = " << p.
z()/mm <<
" mm" <<
G4endl
1710 message.precision(oldprc) ;
1711 G4Exception(
"G4TriangularFacet::DistanceToOut(p)",
1723 minDist = MinDistanceFacet(p,
true, facet);
1727 minDist = kInfinity;
1729 std::size_t size = fFacets.size();
1730 for (std::size_t i = 0; i < size; ++i)
1734 if (dist < minDist) minDist = dist;
1748 return fGeometryType;
1757 os <<
"Geometry Type = " << fGeometryType <<
G4endl;
1758 os <<
"Number of facets = " << fFacets.size() <<
G4endl;
1760 std::size_t size = fFacets.size();
1761 for (std::size_t i = 0; i < size; ++i)
1763 os <<
"FACET # = " << i + 1 <<
G4endl;
1797 location = InsideVoxels(aPoint);
1801 location = InsideNoVoxels(aPoint);
1832 G4double dist = DistanceToInCore(p,v,kInfinity);
1834 if (dist < kInfinity)
1838 std::ostringstream message;
1839 message <<
"Invalid response from facet in solid '" <<
GetName() <<
"',"
1841 <<
"at point: " << p <<
"and direction: " << v;
1842 G4Exception(
"G4TessellatedSolid::DistanceToIn(p,v)",
1889 G4double dist = DistanceToOutCore(p, v, n, valid);
1896 if (dist < kInfinity)
1900 std::ostringstream message;
1901 message <<
"Invalid response from facet in solid '" <<
GetName() <<
"',"
1903 <<
"at point: " << p <<
"and direction: " << v;
1904 G4Exception(
"G4TessellatedSolid::DistanceToOut(p,v,..)",
1923 auto nVertices = (
G4int)fVertexList.size();
1924 auto nFacets = (
G4int)fFacets.size();
1925 auto polyhedron =
new G4Polyhedron(nVertices, nFacets);
1926 for (
auto i = 0; i < nVertices; ++i)
1928 polyhedron->SetVertex(i+1, fVertexList[i]);
1931 for (
auto i = 0; i < nFacets; ++i)
1937 for (
auto j = 0; j < n; ++j)
1941 polyhedron->SetFacet(i+1, v[0], v[1], v[2], v[3]);
1943 polyhedron->SetReferences();
1954 if (fpPolyhedron ==
nullptr ||
1955 fRebuildPolyhedron ||
1960 delete fpPolyhedron;
1962 fRebuildPolyhedron =
false;
1965 return fpPolyhedron;
1980 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
1982 std::ostringstream message;
1983 message <<
"Bad bounding box (min >= max) for solid: "
1985 <<
"\npMin = " << pMin
1986 <<
"\npMax = " << pMax;
1987 G4Exception(
"G4TessellatedSolid::BoundingLimits()",
2019 return (pMin < pMax) ? true :
false;
2030 std::vector<const G4ThreeVectorList *> pyramid(2);
2033 apex[0] = (bmin+bmax)*0.5;
2050 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
2051 if (emin < pMin) pMin = emin;
2052 if (emax > pMax) pMax = emax;
2053 if (eminlim > pMin && emaxlim < pMax)
break;
2055 return (pMin < pMax);
2063 return fMinExtent.
x();
2070 return fMaxExtent.
x();
2077 return fMinExtent.
y();
2084 return fMaxExtent.
y();
2091 return fMinExtent.
z();
2098 return fMaxExtent.
z();
2105 return { fMinExtent.
x(), fMaxExtent.
x(),
2106 fMinExtent.
y(), fMaxExtent.
y(),
2107 fMinExtent.
z(), fMaxExtent.
z() };
2114 if (fCubicVolume != 0.)
return fCubicVolume;
2120 std::size_t size = fFacets.size();
2121 for (std::size_t i = 0; i < size; ++i)
2126 fCubicVolume += area * (facet.
GetVertex(0).dot(unit_normal));
2129 return fCubicVolume;
2136 if (fSurfaceArea != 0.)
return fSurfaceArea;
2138 std::size_t size = fFacets.size();
2139 for (std::size_t i = 0; i < size; ++i)
2142 fSurfaceArea += facet.
GetArea();
2144 return fSurfaceArea;
2153 auto i = (
G4int) G4RandFlat::shoot(0., fFacets.size());
2154 return fFacets[i]->GetPointOnFace();
2166void G4TessellatedSolid::SetRandomVectors ()
2170 G4ThreeVector(-0.9577428892113370, 0.2732676269591740, 0.0897405271949221);
2172 G4ThreeVector(-0.8331264504940770,-0.5162067214954600,-0.1985722492445700);
2174 G4ThreeVector(-0.1516671651108820, 0.9666292616127460, 0.2064580868390110);
2176 G4ThreeVector( 0.6570250350323190,-0.6944539025883300, 0.2933460081893360);
2178 G4ThreeVector(-0.4820456281280320,-0.6331060000098690,-0.6056474264406270);
2180 G4ThreeVector( 0.7629032554236800 , 0.1016854697539910,-0.6384658864065180);
2182 G4ThreeVector( 0.7689540409061150, 0.5034929891988220, 0.3939600142169160);
2184 G4ThreeVector( 0.5765188359255740, 0.5997271636278330,-0.5549354566343150);
2186 G4ThreeVector( 0.6660632777862070,-0.6362809868288380, 0.3892379937580790);
2188 G4ThreeVector( 0.3824415020414780, 0.6541792713761380,-0.6525243125110690);
2190 G4ThreeVector(-0.5107726564526760, 0.6020905056811610, 0.6136760679616570);
2192 G4ThreeVector( 0.7459135439578050, 0.6618796061649330, 0.0743530220183488);
2194 G4ThreeVector( 0.1536405855311580, 0.8117477913978260,-0.5634359711967240);
2196 G4ThreeVector( 0.0744395301705579,-0.8707110101772920,-0.4861286795736560);
2198 G4ThreeVector(-0.1665874645185400, 0.6018553940549240,-0.7810369397872780);
2200 G4ThreeVector( 0.7766902003633100, 0.6014617505959970,-0.1870724331097450);
2202 G4ThreeVector(-0.8710128685847430,-0.1434320216603030,-0.4698551243971010);
2204 G4ThreeVector( 0.8901082092766820,-0.4388411398893870, 0.1229871120030100);
2206 G4ThreeVector(-0.6430417431544370,-0.3295938228697690, 0.6912779675984150);
2208 G4ThreeVector( 0.6331124368380410, 0.6306211461665000, 0.4488714875425340);
2217 G4int base =
sizeof(*this);
2221 std::size_t limit = fFacets.size();
2222 for (std::size_t i = 0; i < limit; ++i)
2228 for (
const auto & fExtremeFacet : fExtremeFacets)
2243 size += sizeInsides + sizeVoxels;
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
void set(double x, double y, double z)
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
unsigned int GetNbits() const
unsigned int GetNbytes() const
void ResetBitNumber(unsigned int bitnumber)
void SetBitNumber(unsigned int bitnumber, G4bool value=true)
virtual G4bool Normal(const G4ThreeVector &p, G4ThreeVector &n) const
G4double GetMinYExtent() const
G4int CheckStructure() const
G4double GetMinZExtent() const
EInside Inside(const G4ThreeVector &p) const override
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)
G4double kCarToleranceHalf
void DescribeYourselfTo(G4VGraphicsScene &scene) const override
G4Polyhedron * GetPolyhedron() const override
G4TessellatedSolid & operator+=(const G4TessellatedSolid &right)
G4bool AddFacet(G4VFacet *aFacet)
void DisplayAllocatedMemory()
G4int GetNumberOfFacets() const
G4double DistanceToOut(const G4ThreeVector &p) const override
G4ThreeVector GetPointOnSurface() const override
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMaxXExtent() const
G4bool GetSolidClosed() const
G4VFacet * GetFacet(G4int i) const
virtual G4double SafetyFromInside(const G4ThreeVector &p, G4bool aAccurate=false) const
G4double GetMinXExtent() const
void SetSolidClosed(const G4bool t)
G4int AllocatedMemoryWithoutVoxels()
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const override
G4VisExtent GetExtent() const override
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4VSolid * Clone() const override
G4double GetSurfaceArea() override
G4int GetFacetIndex(const G4ThreeVector &p) const
virtual G4double SafetyFromOutside(const G4ThreeVector &p, G4bool aAccurate=false) const
G4double GetCubicVolume() override
std::ostream & StreamInfo(std::ostream &os) const override
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const override
~G4TessellatedSolid() override
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
G4Polyhedron * CreatePolyhedron() const override
G4GeometryType GetEntityType() const override
virtual void SetVertexIndex(G4int i, G4int j)=0
virtual G4int AllocatedMemory()=0
virtual G4ThreeVector GetCircumcentre() const =0
std::ostream & StreamInfo(std::ostream &os) const
G4bool IsInside(const G4ThreeVector &p) const
virtual G4ThreeVector GetSurfaceNormal() const =0
virtual G4ThreeVector GetVertex(G4int i) const =0
virtual G4double GetArea() const =0
virtual G4int GetNumberOfVertices() const =0
virtual G4int GetVertexIndex(G4int i) const =0
virtual G4VFacet * GetClone()=0
virtual G4double Distance(const G4ThreeVector &, G4double)=0
virtual void SetVertices(std::vector< G4ThreeVector > *vertices)=0
virtual G4bool IsDefined() const =0
virtual G4bool Intersect(const G4ThreeVector &, const G4ThreeVector &, const G4bool, G4double &, G4double &, G4ThreeVector &)=0
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
const G4SurfBits & Empty() const
G4double DistanceToBoundingBox(const G4ThreeVector &point) const
long long GetCountOfVoxels() const
const std::vector< G4double > & GetBoundary(G4int index) const
G4bool IsEmpty(G4int index) const
G4bool UpdateCurrentVoxel(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void GetVoxel(std::vector< G4int > &curVoxel, const G4ThreeVector &point) const
G4int GetMaxVoxels(G4ThreeVector &ratioOfReduction)
G4double DistanceToFirst(const G4ThreeVector &point, const G4ThreeVector &direction) const
G4int GetVoxelBoxesSize() const
static G4double MinDistanceToBox(const G4ThreeVector &aPoint, const G4ThreeVector &f)
void SetMaxVoxels(G4int max)
const G4VoxelBox & GetVoxelBox(G4int i) const
G4int GetPointIndex(const G4ThreeVector &p) const
G4double DistanceToNext(const G4ThreeVector &point, const G4ThreeVector &direction, std::vector< G4int > &curVoxel) const
void Voxelize(std::vector< G4VSolid * > &solids, std::vector< G4Transform3D > &transforms)
const std::vector< G4int > & GetVoxelBoxCandidates(G4int i) const
G4int GetVoxelsIndex(G4int x, G4int y, G4int z) const
G4bool Contains(const G4ThreeVector &point) const
const std::vector< G4int > & GetCandidates(std::vector< G4int > &curVoxel) const
static G4int GetNumberOfRotationSteps()
T max(const T t1, const T t2)
brief Return the largest of the two arguments