84 auto data = std::make_unique<OwnedThreadData_t>(
fNedges + 10);
85 Int_t *intBuffer =
data->fIntBuffer.get();
102 fGeneration.fetch_add(1, std::memory_order_release);
165 Double_t rmin1, rmax1, rmin2, rmax2, dphi, dz;
169 for (ipl = 0; ipl <
fNz - 1; ipl++) {
170 dz =
fZ[ipl + 1] -
fZ[ipl];
175 rmin2 =
fRmin[ipl + 1];
176 rmax2 =
fRmax[ipl + 1];
178 (rmax1 * rmax1 + rmax1 * rmax2 + rmax2 * rmax2 - rmin1 * rmin1 - rmin1 * rmin2 - rmin2 * rmin2);
189 for (
Int_t isec = 0; isec <
fNz - 1; isec++) {
190 if (
fZ[isec] >
fZ[isec + 1]) {
192 Fatal(
"ComputeBBox",
"Wrong section order");
199 Fatal(
"ComputeBBox",
"Shape %s at index %d: Not allowed first two or last two sections at same Z",
GetName(),
252 fOrigin[2] = 0.5 * (zmax + zmin);
255 fDZ = 0.5 * (zmax - zmin);
264 memset(norm, 0, 3 *
sizeof(
Double_t));
282 if (point[2] >=
fZ[
fNz - 1] || ipl < 0) {
287 Int_t iplclose = ipl;
288 if ((
fZ[ipl + 1] - point[2]) < (point[2] -
fZ[ipl]))
306 if (iplclose == 0 || iplclose == (
fNz - 1)) {
317 while (ipl <
fNz - 2 &&
fZ[ipl] ==
fZ[ipl + 1])
319 dz =
fZ[ipl + 1] -
fZ[ipl];
321 rmin2 =
fRmin[ipl + 1];
322 rsum = rmin1 + rmin2;
325 ta = (rmin2 - rmin1) / dz;
327 rpgon = rmin1 + (point[2] -
fZ[ipl]) * ta;
331 norm[2] = -calf * ta;
335 rpgon =
fRmax[ipl] + (point[2] -
fZ[ipl]) * ta;
341 norm[2] = -calf * ta;
346 norm[0] = norm[1] = 0.;
353 if (norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2] < 0) {
366 if (point[2] <
fZ[0])
368 if (point[2] >
fZ[
fNz - 1])
424 if (iact < 3 && safe) {
428 if (iact == 1 && step < *safe)
434 if (ipl ==
fNz - 1) {
455 if ((point[0] * dir[1] - point[1] * dir[0]) > 0) {
496 Double_t rproj = point[0] * cphi + point[1] * sphi;
499 if (rproj >
fRmin[ipln] && rproj <
fRmin[ipln + 1])
501 if (rproj <
fRmax[ipln] && rproj >
fRmax[ipln + 1])
505 if (rproj <
fRmin[ipln] && rproj >
fRmin[ipln + 1])
507 if (rproj >
fRmax[ipln] && rproj <
fRmax[ipln + 1])
522 if (
SliceCrossingIn(point, dir, ipl, icrossed, iph, sph, snext, stepmax))
559 Double_t rdotn = point[0] * dir[0] + point[1] * dir[1];
565 sphi[0] =
TMath::Sqrt((point[0] * point[0] + point[1] * point[1]) / (1. - dir[2] * dir[2]));
567 if (sphi[0] > stepmax) {
584 ist = (incsec > 0) ? 0 :
fNedges;
586 ist = (incsec > 0) ? (istart + 1) : istart;
594 phi = phi1 + ist * divphi;
599 sphi[icrossed] = stepmax;
600 iphi[icrossed++] = istart;
602 if (sphi[icrossed - 1] > stepmax) {
603 sphi[icrossed - 1] = stepmax;
607 istart = (incsec > 0) ? 0 : (
fNedges - 1);
611 istart = (
fDphi < 360.) ? (-1) : 0;
618 ist = (incsec > 0) ? 0 :
fNedges;
620 ist = (incsec > 0) ? (istart + 1) : istart;
640 if (iphi[0] < 0 && nphi == 1)
644 if (ipl < 0 || ipl ==
fNz - 1)
658 rmin =
Rpg(point[2], ipl,
kTRUE, apg, bpg);
659 rmax =
Rpg(point[2], ipl,
kFALSE, apg, bpg);
670 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
671 if (step > stepmax) {
675 if (iphi[iphcrt] < 0) {
680 snextphi = stepphi[iphcrt];
681 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
684 rproj =
pt[0] * cosph +
pt[1] * sinph;
686 ndot = dir[0] * cosph + dir[1] * sinph;
688 dist = (ndot > 0) ? ((rmax - rproj) / ndot) : ((rmin - rproj) / ndot);
692 if (dist < (snextphi - step)) {
699 for (i = 0; i < 3; i++)
700 pt[i] = point[i] + step * dir[i];
718 if (iphi[0] < 0 && nphi == 1)
722 if (ipl < 0 || ipl ==
fNz - 1)
736 rmin =
Rpg(point[2], ipl,
kTRUE, apg, bpg);
737 rmax =
Rpg(point[2], ipl,
kFALSE, apg, bpg);
748 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
751 snextphi = stepphi[iphcrt];
752 if (iphi[iphcrt] < 0) {
753 if (iphcrt == nphi - 1)
755 if (snextphi > stepmax)
757 for (i = 0; i < 3; i++)
758 pt[i] = point[i] + snextphi * dir[i];
759 phi = phi1 + (iphi[iphcrt + 1] + 0.5) * divphi;
762 rproj =
pt[0] * cosph +
pt[1] * sinph;
763 if (rproj < rmin || rproj > rmax) {
771 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
774 rproj =
pt[0] * cosph +
pt[1] * sinph;
776 ndot = dir[0] * cosph + dir[1] * sinph;
788 for (i = 0; i < 3; i++)
789 pt[i] = point[i] + step * dir[i];
820 Int_t incseg = (dir[2] > 0) ? 1 : -1;
822 Int_t iplstart = ipl;
825 Double_t rpg = 0, rnew = 0, znew = 0;
826 Double_t rpgin = 0, rpgout = 0, apgin = 0, apgout = 0, bpgin = 0, bpgout = 0;
831 Double_t distz = 0, distr = 0, din = 0, dout = 0;
834 for (iphcrt = iphstart; iphcrt < nphi; iphcrt++) {
836 if (step > stepmax) {
840 if (iphi[iphcrt] < 0) {
844 snextphi = stepphi[iphcrt];
845 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
850 while (ipl >= 0 && ipl <
fNz - 1) {
853 distz = (
fZ[ipl + ((1 + incseg) >> 1)] -
pt[2]) * invdir;
855 dz =
fZ[ipl + 1] -
fZ[ipl];
857 rnew = apr + bpr *
fZ[ipl];
858 rpg = (rnew -
fRmin[ipl]) * (rnew -
fRmin[ipl + 1]);
861 rpg = (rnew -
fRmax[ipl]) * (rnew -
fRmax[ipl + 1]);
869 znew = (apr - apgin) / db;
870 din = (znew -
pt[2]) * invdir;
875 znew = (apr - apgout) / db;
876 dout = (znew -
pt[2]) * invdir;
882 if (iphcrt == iphstart && ipl == iplstart) {
883 if (rproj < rpgin + 1.E-8) {
884 Double_t ndotd = dir[0] * cosph + dir[1] * sinph + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) / dz;
886 snext = (din < 0) ? step : (step + din);
895 }
else if (rproj > rpgout - 1.E-8) {
896 Double_t ndotd = dir[0] * cosph + dir[1] * sinph + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) / dz;
898 snext = (dout < 0) ? step : (step + dout);
912 if (snextphi < step +
TMath::Min(distz, distr)) {
913 for (i = 0; i < 3; i++)
914 pt[i] = point[i] + snextphi * dir[i];
926 if ((ipl + incseg < 0) || (ipl + incseg >
fNz - 2)) {
950 if (iphi[0] < 0 && nphi == 1)
956 Int_t incseg = (dir[2] > 0) ? 1 : -1;
963 if (ipl ==
fNz - 1) {
970 if ((ipl + incseg) < 0 || (ipl + incseg) >
fNz - 1)
993 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
998 snextphi = stepphi[iphcrt];
999 if (iphi[iphcrt] < 0) {
1000 if (iphcrt == nphi - 1)
1002 if (snextphi > stepmax)
1004 for (i = 0; i < 3; i++)
1005 pt[i] = point[i] + snextphi * dir[i];
1009 while (
pt[2] >
fZ[ipl + 1]) {
1015 while (
pt[2] <
fZ[ipl]) {
1024 phi = phi1 + (iphi[iphcrt + 1] + 0.5) * divphi;
1028 rproj =
pt[0] * cosph +
pt[1] * sinph;
1029 if (rproj < rpgin || rproj > rpgout) {
1049 if (ipl < 0 || ipl >
fNz - 2)
1051 if (sstart > stepmax)
1056 for (
Int_t i = 0; i < 3; i++)
1057 pt[i] += sstart * dir[i];
1060 Int_t incseg = (dir[2] > 0) ? 1 : -1;
1068 Rproj(
pt[2], point, dir, cphi, sphi, apr, bpr);
1071 Int_t icrtseg = ipl;
1072 Int_t isegstart = ipl;
1073 Int_t iseglast = (incseg > 0) ? (
fNz - 1) : -1;
1074 Double_t din, dout, rdot, rnew, apg, bpg, db, znew;
1076 for (ipl = isegstart; ipl != iseglast; ipl += incseg) {
1077 step = (
fZ[ipl + 1 - ((1 + incseg) >> 1)] -
pt[2]) * invdir;
1079 if (step > stepmax) {
1086 dz =
fZ[ipl + 1] -
fZ[ipl];
1092 rdot = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) / dz;
1097 rnew = apr + bpr *
fZ[ipl];
1100 din = (
fZ[ipl] -
pt[2]) * invdir;
1105 znew = (apr - apg) / db;
1106 if (znew >
fZ[ipl] && znew <
fZ[ipl + 1]) {
1107 din = (znew -
pt[2]) * invdir;
1119 rdot = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) / dz;
1124 rnew = apr + bpr *
fZ[ipl];
1127 dout = (
fZ[ipl] -
pt[2]) * invdir;
1132 znew = (apr - apg) / db;
1133 if (znew >
fZ[ipl] && znew <
fZ[ipl + 1])
1134 dout = (znew -
pt[2]) * invdir;
1144 if (step > stepmax) {
1148 snext = sstart + step;
1162 if (iact < 3 && safe) {
1166 if (iact == 1 && step < *safe)
1195 if (r2 > (radmax * radmax) ||
pt[2] <
fZ[0] ||
pt[2] >
fZ[
fNz - 1]) {
1200 if (snext > stepmax)
1204 for (i = 0; i < 3; i++)
1205 pt[i] += snext * dir[i];
1223 ipsec =
Int_t(ddp / divphi);
1226 if (rpr >= rmin && rpr <= rmax)
1241 return (snext + snewcross);
1255 if (
fDphi < 360.0) {
1277 if (rproj <
fRmin[ipl] && rproj >
fRmin[ipl + 1] && dir[2] > 0)
1279 if (rproj >
fRmin[ipl] && rproj <
fRmin[ipl + 1] && dir[2] < 0)
1281 if (rproj >
fRmax[ipl] && rproj <
fRmax[ipl + 1] && dir[2] > 0)
1283 if (rproj <
fRmax[ipl] && rproj >
fRmax[ipl + 1] && dir[2] < 0)
1290 if (rproj < rpgout + 1.E-8) {
1293 if (rproj > rpgin - 1.E-8) {
1305 if (safrmin < safz && safrmin < safrmax && safrmin < safphi) {
1307 Double_t ndotd = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) * dzinv;
1313 if (!done && safrmax < safz && safrmax < safphi) {
1314 Double_t ndotd = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) * dzinv;
1320 if (!done && safz < safphi) {
1325 if (iplc == 0 || iplc ==
fNz - 1) {
1326 if (
pt[2] * dir[2] < 0)
1332 if (rproj <
fRmin[iplc] && rproj >
fRmin[iplc + 1])
1334 if (rproj >
fRmax[iplc] && rproj <
fRmax[iplc + 1])
1337 if (rproj >
fRmin[iplc] && rproj <
fRmin[iplc + 1])
1339 if (rproj <
fRmax[iplc] && rproj >
fRmax[iplc + 1])
1344 if (rproj <
fRmin[iplc - 1] && rproj >
fRmin[iplc])
1346 if (rproj >
fRmax[iplc - 1] && rproj <
fRmax[iplc])
1349 if (rproj >
fRmin[iplc - 1] && rproj <
fRmin[iplc])
1351 if (rproj <
fRmax[iplc - 1] && rproj >
fRmax[iplc])
1370 return (snext + sph[0]);
1371 if (iph[0] >= 0 && sph[0] > 1.E-8)
1412 Double_t zmax = start + ndiv * step;
1417 Error(
"Divide",
"makes no sense dividing a pgon on radius");
1421 Error(
"Divide",
"ndiv should divide number of pgon edges");
1429 shape =
new TGeoPgon(-step / 2, step, nedges,
fNz);
1432 for (is = 0; is <
fNz; is++)
1435 for (
id = 0;
id < ndiv;
id++) {
1442 for (ipl = 0; ipl <
fNz - 1; ipl++) {
1443 if (start <
fZ[ipl])
1446 if ((start + ndiv * step) >
fZ[ipl + 1])
1451 zmax =
fZ[isect + 1];
1455 Error(
"Divide",
"cannot divide pcon on Z if divided region is not between 2 consecutive planes");
1458 finder =
new TGeoPatternZ(voldiv, ndiv, start, start + ndiv * step);
1463 for (
id = 0;
id < ndiv;
id++) {
1465 Double_t z2 = start + (
id + 1) * step;
1466 Double_t rmin1 = (
fRmin[isect] * (zmax - z1) -
fRmin[isect + 1] * (zmin - z1)) / (zmax - zmin);
1467 Double_t rmax1 = (
fRmax[isect] * (zmax - z1) -
fRmax[isect + 1] * (zmin - z1)) / (zmax - zmin);
1468 Double_t rmin2 = (
fRmin[isect] * (zmax - z2) -
fRmin[isect + 1] * (zmin - z2)) / (zmax - zmin);
1469 Double_t rmax2 = (
fRmax[isect] * (zmax - z2) -
fRmax[isect + 1] * (zmin - z2)) / (zmax - zmin);
1471 ((
TGeoPgon *)shape)->DefineSection(0, -step / 2, rmin1, rmax1);
1472 ((
TGeoPgon *)shape)->DefineSection(1, step / 2, rmin2, rmax2);
1479 default:
Error(
"Divide",
"Wrong axis type for division");
return nullptr;
1489 param[0] =
fRmin[0];
1490 param[1] =
fRmax[0];
1492 if (
fRmin[i] < param[0])
1493 param[0] =
fRmin[i];
1494 if (
fRmax[i] > param[1])
1495 param[1] =
fRmax[i];
1499 param[0] *= param[0];
1500 param[1] *= param[1];
1507 param[3] = param[2] +
fDphi;
1515 printf(
"*** Shape %s: TGeoPgon ***\n",
GetName());
1516 printf(
" Nedges = %i\n",
fNedges);
1526 Int_t nbPnts, nbSegs, nbPols;
1557 Int_t nbPnts = nz * 2 *
n;
1565 Int_t indx = 0, indx2, k;
1569 for (i = 0; i < nz * 2; i++) {
1571 for (j = 1; j <
n; j++) {
1573 buff.
fSegs[indx++] = indx2 + j - 1;
1574 buff.
fSegs[indx++] = indx2 + j;
1578 buff.
fSegs[indx++] = indx2 + j - 1;
1579 buff.
fSegs[indx++] = indx2;
1584 for (i = 0; i < 2; i++) {
1585 indx2 = i * (nz - 1) * 2 *
n;
1586 for (j = 0; j <
n; j++) {
1588 buff.
fSegs[indx++] = indx2 + j;
1589 buff.
fSegs[indx++] = indx2 +
n + j;
1594 for (i = 0; i < (nz - 1); i++) {
1597 for (j = 0; j <
n; j++) {
1598 buff.
fSegs[indx++] =
c + 2;
1599 buff.
fSegs[indx++] = indx2 + j;
1600 buff.
fSegs[indx++] = indx2 +
n * 2 + j;
1603 indx2 = i *
n * 2 +
n;
1604 for (j = 0; j <
n; j++) {
1605 buff.
fSegs[indx++] =
c + 3;
1606 buff.
fSegs[indx++] = indx2 + j;
1607 buff.
fSegs[indx++] = indx2 +
n * 2 + j;
1614 for (i = 1; i < (nz - 1); i++) {
1615 for (j = 0; j < 2; j++) {
1617 buff.
fSegs[indx++] = 2 * i *
n + j * (
n - 1);
1618 buff.
fSegs[indx++] = (2 * i + 1) *
n + j * (
n - 1);
1623 Int_t m =
n - 1 + (specialCase ? 1 : 0);
1629 for (j = 0; j <
n - 1; j++) {
1630 buff.
fPols[indx++] =
c + 3;
1631 buff.
fPols[indx++] = 4;
1632 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1633 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1634 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j + 1;
1635 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1638 buff.
fPols[indx++] =
c + 3;
1639 buff.
fPols[indx++] = 4;
1640 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1641 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1642 buff.
fPols[indx++] = 2 * nz *
m + i *
n;
1643 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1646 for (j = 0; j <
n - 1; j++) {
1647 buff.
fPols[indx++] =
c + 3;
1648 buff.
fPols[indx++] = 4;
1649 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1650 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j + 1;
1651 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1652 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1655 buff.
fPols[indx++] =
c + 3;
1656 buff.
fPols[indx++] = 4;
1657 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1658 buff.
fPols[indx++] = 2 * nz *
m + i *
n;
1659 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1660 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1664 for (k = 0; k < (nz - 1); k++) {
1666 for (j = 0; j <
n - 1; j++) {
1667 buff.
fPols[indx++] =
c + i;
1668 buff.
fPols[indx++] = 4;
1669 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j + 1;
1670 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1671 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1672 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1675 buff.
fPols[indx++] =
c + i;
1676 buff.
fPols[indx++] = 4;
1677 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n;
1678 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1679 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1680 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1683 for (j = 0; j <
n - 1; j++) {
1684 buff.
fPols[indx++] =
c + i;
1685 buff.
fPols[indx++] = 4;
1686 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1687 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1688 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1689 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j + 1;
1692 buff.
fPols[indx++] =
c + i;
1693 buff.
fPols[indx++] = 4;
1694 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1695 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1696 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1697 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n;
1704 indx2 = nz * 2 * (
n - 1);
1705 for (k = 0; k < (nz - 1); k++) {
1706 buff.
fPols[indx++] =
c + 2;
1707 buff.
fPols[indx++] = 4;
1708 buff.
fPols[indx++] = k == 0 ? indx2 : indx2 + 2 * nz *
n + 2 * (k - 1);
1709 buff.
fPols[indx++] = indx2 + 2 * (k + 1) *
n;
1710 buff.
fPols[indx++] = indx2 + 2 * nz *
n + 2 * k;
1711 buff.
fPols[indx++] = indx2 + (2 * k + 3) *
n;
1713 buff.
fPols[indx++] =
c + 2;
1714 buff.
fPols[indx++] = 4;
1715 buff.
fPols[indx++] = k == 0 ? indx2 +
n - 1 : indx2 + 2 * nz *
n + 2 * (k - 1) + 1;
1716 buff.
fPols[indx++] = indx2 + (2 * k + 3) *
n +
n - 1;
1717 buff.
fPols[indx++] = indx2 + 2 * nz *
n + 2 * k + 1;
1718 buff.
fPols[indx++] = indx2 + 2 * (k + 1) *
n +
n - 1;
1720 buff.
fPols[indx - 8] = indx2 +
n;
1721 buff.
fPols[indx - 2] = indx2 + 2 *
n - 1;
1732 const Int_t nbPnts = nz *
n + 2;
1734 if ((nz < 2) || (nbPnts <= 0) || (
n < 2))
1739 Int_t indx = 0, indx1 = 0, indx2 = 0, i, j;
1742 for (i = 0; i < nz; i++) {
1744 for (j = 1; j <
n; j++) {
1746 buff.
fSegs[indx++] = indx2 + j - 1;
1747 buff.
fSegs[indx++] = indx2 + j % (
n - 1);
1753 for (j = 0; j <
n; j++) {
1755 buff.
fSegs[indx++] = indx2 + j % (
n - 1);
1756 buff.
fSegs[indx++] = nbPnts - 2;
1759 indx2 = (nz - 1) *
n;
1761 for (j = 0; j <
n; j++) {
1763 buff.
fSegs[indx++] = indx2 + j % (
n - 1);
1764 buff.
fSegs[indx++] = nbPnts - 1;
1768 for (i = 0; i < (nz - 1); i++) {
1771 for (j = 0; j <
n; j++) {
1773 buff.
fSegs[indx++] = indx2 + j % (
n - 1);
1774 buff.
fSegs[indx++] = indx2 +
n + j % (
n - 1);
1782 indx2 = nz * (
n - 1);
1783 for (j = 0; j <
n - 1; j++) {
1785 buff.
fPols[indx++] = 3;
1786 buff.
fPols[indx++] = indx1 + j;
1787 buff.
fPols[indx++] = indx2 + (j + 1) % (
n - 1);
1788 buff.
fPols[indx++] = indx2 + j;
1792 indx1 = (nz - 1) * (
n - 1);
1793 indx2 = nz * (
n - 1) +
n;
1794 for (j = 0; j <
n - 1; j++) {
1796 buff.
fPols[indx++] = 3;
1797 buff.
fPols[indx++] = indx1 + j;
1798 buff.
fPols[indx++] = indx2 + j;
1799 buff.
fPols[indx++] = indx2 + (j + 1) % (
n - 1);
1803 for (
Int_t k = 0; k < (nz - 1); k++) {
1804 indx1 = k * (
n - 1);
1805 indx2 = nz * (
n - 1) +
n * 2 + k *
n;
1806 for (j = 0; j <
n - 1; j++) {
1808 buff.
fPols[indx++] = 4;
1809 buff.
fPols[indx++] = indx1 + j;
1810 buff.
fPols[indx++] = indx2 + j;
1811 buff.
fPols[indx++] = indx1 + j + (
n - 1);
1812 buff.
fPols[indx++] = indx2 + (j + 1) % (
n - 1);
1827 if (ipl < 0 || ipl >
fNz - 2) {
1828 Fatal(
"Rpg",
"Plane index parameter ipl=%i out of range\n", ipl);
1842 r2 =
fRmin[ipl + 1];
1845 r2 =
fRmax[ipl + 1];
1848 a = (r1 *
fZ[ipl + 1] - r2 *
fZ[ipl]) * dzinv;
1849 b = (r2 - r1) * dzinv;
1866 a = ((point[0] * dir[2] - point[2] * dir[0]) * cphi + (point[1] * dir[2] - point[2] * dir[1]) * sphi) * invdirz;
1867 b = (dir[0] * cphi + dir[1] * sphi) * invdirz;
1881 if (ipl < 0 || ipl >
fNz - 2)
1882 return (safmin + 1.);
1887 Double_t znew = point[2] - 0.5 * (
fZ[ipl] +
fZ[ipl + 1]);
1889 if (-saf[0] > safmin)
1900 r =
TMath::Sqrt(point[0] * point[0] + point[1] * point[1]);
1901 Double_t ro1 = 0.5 * (rmin1 + rmin2);
1902 Double_t tg1 = (rmin2 - rmin1) / dz;
1904 Double_t ro2 = 0.5 * (rmax1 + rmax2);
1905 Double_t tg2 = (rmax2 - rmax1) / dz;
1910 saf[2] = (rout -
r) * cr2;
1911 for (i = 0; i < 3; i++)
1921 if (rmin1 + rmin2 > 1E-10) {
1922 ta = (rmin2 - rmin1) / dz;
1924 rpgon = rmin1 + (point[2] -
fZ[ipl]) * ta;
1925 saf[1] = (
r - rpgon) * calf;
1929 ta = (rmax2 - rmax1) / dz;
1931 rpgon = rmax1 + (point[2] -
fZ[ipl]) * ta;
1932 saf[2] = (rpgon -
r) * calf;
1937 for (i = 0; i < 3; i++)
1955 Int_t ipl, iplane, iphi;
1961 if (ipl == (
fNz - 1))
1965 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1970 if (safmin > 1E10) {
1979 while ((iplane <
fNz - 1) && saftmp < 1E10) {
1981 if (saftmp < safmin)
1988 while ((iplane >= 0) && saftmp < 1E10) {
1990 if (saftmp < safmin)
2000 else if (ipl ==
fNz - 1)
2002 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
2007 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
2016 while ((iplane <
fNz - 1) && saftmp < 1E10) {
2018 if (saftmp < safmin)
2025 while ((iplane >= 0) && saftmp < 1E10) {
2027 if (saftmp < safmin)
2041 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
2042 out <<
" phi1 = " <<
fPhi1 <<
";" << std::endl;
2043 out <<
" dphi = " <<
fDphi <<
";" << std::endl;
2044 out <<
" nedges = " <<
fNedges <<
";" << std::endl;
2045 out <<
" nz = " <<
fNz <<
";" << std::endl;
2046 out <<
" auto " <<
GetPointerName() <<
" = new TGeoPgon(\"" <<
GetName() <<
"\", phi1, dphi, nedges, nz);"
2049 out <<
" z = " <<
fZ[i] <<
";" << std::endl;
2050 out <<
" rmin = " <<
fRmin[i] <<
";" << std::endl;
2051 out <<
" rmax = " <<
fRmax[i] <<
";" << std::endl;
2052 out <<
" " <<
GetPointerName() <<
"->DefineSection(" << i <<
", z, rmin, rmax);" << std::endl;
2067 Error(
"SetDimensions",
"Pgon %s: Number of Z sections must be > 2",
GetName());
2083 DefineSection(i, param[4 + 3 * i], param[5 + 3 * i], param[6 + 3 * i]);
2101 for (i = 0; i <
GetNz(); i++) {
2103 for (j = 0; j <
n; j++) {
2109 for (j = 0; j <
n; j++) {
2144 for (i = 0; i <
fNz; i++) {
2146 for (j = 0; j <
n; j++) {
2152 for (j = 0; j <
n; j++) {
2177 nvert = nsegs = npols = 0;
2188 nsegs = 4 * (nz *
n - 1 + (specialCase ? 1 : 0));
2189 npols = 2 * (nz *
n - 1 + (specialCase ? 1 : 0));
2192 nsegs = nz * (
n - 1) +
n * 2 + (nz - 1) *
n;
2193 npols = 2 * (
n - 1) + (nz - 1) * (
n - 1);
2202 Int_t nvert, nsegs, npols;
2224 Int_t nbPnts, nbSegs, nbPols;
2227 if (buffer.
SetRawSizes(nbPnts, 3 * nbPnts, nbSegs, 3 * nbSegs, nbPols, 6 * nbPols)) {
2254 for (
Int_t i = 0; i < vecsize; i++)
2265 for (
Int_t i = 0; i < vecsize; i++)
2275 for (
Int_t i = 0; i < vecsize; i++)
2285 for (
Int_t i = 0; i < vecsize; i++)
2296 for (
Int_t i = 0; i < vecsize; i++)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
float Float_t
Float 4 bytes (float)
double Double_t
Double 8 bytes.
const char Option_t
Option string (const char)
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
R__EXTERN TGeoManager * gGeoManager
Generic 3D primitive description class.
Bool_t SectionsValid(UInt_t mask) const
void SetSectionsValid(UInt_t mask)
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const override
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
Compute distance from outside point to surface of the box.
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
TObjArray * GetListOfShapes() const
Node containing an offset.
a cylindrical phi divison pattern
base finder class for patterns. A pattern is specifying a division type
void SetDivIndex(Int_t index)
A polycone is represented by a sequence of tubes/cones, glued together at defined Z planes.
virtual void DefineSection(Int_t snum, Double_t z, Double_t rmin, Double_t rmax)
Defines z position of a section plane, rmin and rmax at this z.
void InspectShape() const override
print shape parameters
Bool_t HasInsideSurface() const
Returns true when pgon has internal surface It will be only disabled when all Rmin values are 0.
Polygons are defined in the same way as polycones, the difference being just that the segments betwee...
void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const override
Compute safe distance from each of the points in the input array.
TBuffer3D * MakeBuffer3D() const override
Creates a TBuffer3D describing this shape.
static std::atomic< UInt_t > fgInstanceCount
void SetPoints(Double_t *points) const override
create polygone mesh points
Bool_t Contains(const Double_t *point) const override
test if point is inside this shape check total z range
std::mutex fOwnedDataMutex
! Protects cold allocation and cleanup
Bool_t SliceCrossingInZ(const Double_t *point, const Double_t *dir, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Performs ray propagation between Z segments.
std::vector< std::unique_ptr< OwnedThreadData_t > > fOwnedData
! Object-owned per-thread buffers
~TGeoPgon() override
destructor
Bool_t SliceCrossing(const Double_t *point, const Double_t *dir, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Check boundary crossing inside phi slices.
void Sizeof3D() const override
fill size of this 3-D object
Int_t GetNmeshVertices() const override
Return number of vertices of the mesh representation.
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Compute normal to closest surface from POINT.
void GetBoundingCylinder(Double_t *param) const override
Fill vector param[4] with the bounding cylinder parameters.
void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Bool_t SliceCrossingZ(const Double_t *point, const Double_t *dir, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Performs ray propagation between Z segments.
void InspectShape() const override
Inspect the PGON parameters.
void LocatePhi(const Double_t *point, Int_t &ipsec) const
Locates index IPSEC of the phi sector containing POINT.
TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step) override
Divide this polygone shape belonging to volume "voldiv" into ndiv volumes called divname,...
void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const override
Returns numbers of vertices, segments and polygons composing the shape mesh.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
computes the closest distance from given point to this shape, according to option.
void ClearThreadData() const override
Release object-owned scratch buffers and invalidate the non-owning TLS slots.
Double_t SafetyToSegment(const Double_t *point, Int_t ipl, Int_t iphi, Bool_t in, Double_t safphi, Double_t safmin=TGeoShape::Big()) const
Compute safety from POINT to segment between planes ipl, ipl+1 within safmin.
Double_t Capacity() const override
Computes capacity of the shape in [length^3].
Double_t Rpg(Double_t z, Int_t ipl, Bool_t inner, Double_t &a, Double_t &b) const
Computes projected pgon radius (inner or outer) corresponding to a given Z value.
void SetDimensions(Double_t *param) override
Set PGON dimensions starting from an array.
void SetSegsAndPolsNoInside(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons, when no inner surface exists.
Bool_t SliceCrossingIn(const Double_t *point, const Double_t *dir, Int_t ipl, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Check boundary crossing inside phi slices.
void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const override
Check the inside status for each of the points in the array.
void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const override
Fills a static 3D buffer and returns a reference.
void InitThreadSlot(ThreadData_t &td) const
(Re)build the per-thread scratch buffers for this shape into the given slot.
ThreadData_t & GetThreadData() const
Per-thread non-owning cache of scratch buffers indexed by this shape.
void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize) override
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
void ComputeBBox() override
compute bounding box for a polygone Check if the sections are in increasing Z order
Double_t Rproj(Double_t z, const Double_t *point, const Double_t *dir, Double_t cphi, Double_t sphi, Double_t &a, Double_t &b) const
Computes projected distance at a given Z for a given ray inside a given sector and fills coefficients...
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
compute distance from inside point to surface of the polygone first find out in which Z section the p...
Bool_t IsCrossingSlice(const Double_t *point, const Double_t *dir, Int_t iphi, Double_t sstart, Int_t &ipl, Double_t &snext, Double_t stepmax) const
Check crossing of a given pgon slice, from a starting point inside the slice.
Int_t GetPhiCrossList(const Double_t *point, const Double_t *dir, Int_t istart, Double_t *sphi, Int_t *iphi, Double_t stepmax=TGeoShape::Big()) const
Returns lists of PGON phi crossings for a ray starting from POINT.
void SetSegsAndPols(TBuffer3D &buff) const override
Fill TBuffer3D structure for segments and polygons.
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
Compute distance from outside point to surface of the polygone.
std::atomic< Int_t > fGeneration
non-reused index of this shape into the per-thread vector
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
compute closest distance from point px,py to each corner
Base abstract class for all shapes.
Int_t GetBasicColor() const
Get the basic color (0-7).
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
static Double_t SafetyPhi(const Double_t *point, Bool_t in, Double_t phi1, Double_t phi2)
Static method to compute safety w.r.t a phi corner defined by cosines/sines of the angles phi1,...
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
const char * GetPointerName() const
Provide a pointer name containing uid.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
static void NormalPhi(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
Static method to compute normal to phi planes.
static Bool_t IsCrossingSemiplane(const Double_t *point, const Double_t *dir, Double_t cphi, Double_t sphi, Double_t &snext, Double_t &rxy)
Compute distance from POINT to semiplane defined by PHI angle along DIR.
const char * GetName() const override
Get the shape name.
static Double_t Tolerance()
static Bool_t IsCloseToPhi(Double_t epsil, const Double_t *point, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
True if point is closer than epsil to one of the phi planes defined by c1,s1 or c2,...
static Double_t DistFromOutsideS(const Double_t *point, const Double_t *dir, Double_t rmin, Double_t rmax, Double_t dz)
Static method to compute distance from outside point to a tube with given parameters Boundary safe al...
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
TGeoMedium * GetMedium() const
void SetFinder(TGeoPatternFinder *finder)
Int_t GetNdaughters() const
Int_t IndexOf(const TObject *obj) const override
TObject * At(Int_t idx) const override
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual const char * ClassName() const
Returns name of class to which the object belongs.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
const char * Data() const
Long64_t LocMin(Long64_t n, const T *a)
Returns index of array with the minimum element.
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
T1 Sign(T1 a, T2 b)
Returns a value with the magnitude of a and the sign of b.
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Long64_t LocMax(Long64_t n, const T *a)
Returns index of array with the maximum element.
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Double_t Sqrt(Double_t x)
Returns the square root of x.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
std::unique_ptr< Int_t[]> fIntBuffer
OwnedThreadData_t(std::size_t size)
std::unique_ptr< Double_t[]> fDblBuffer
bumped whenever the per-thread state must be rebuilt
Int_t fInitGen
[fNedges+4] temporary double buffer array
Double_t * fDblBuffer
[fNedges+4] temporary int buffer array