83using CLHEP::perMillion;
99 for (
const auto& edge : facet.edge) {
100 ostr <<
" " << edge.v <<
"/" << edge.f;
107 ostr <<
"Nvertices=" << ph.
nvert <<
", Nfacets=" << ph.
nface << std::endl;
109 for (i=1; i<=ph.
nvert; i++) {
110 ostr <<
"xyz(" << i <<
")="
111 << ph.
pV[i].
x() <<
' ' << ph.
pV[i].
y() <<
' ' << ph.
pV[i].
z()
114 for (i=1; i<=ph.
nface; i++) {
115 ostr <<
"face(" << i <<
")=" << ph.
pF[i] << std::endl;
128: nvert(0), nface(0), pV(nullptr), pF(nullptr)
140: nvert(0), nface(0), pV(nullptr), pF(nullptr)
154: nvert(0), nface(0), pV(nullptr), pF(nullptr)
225 for (i=0; i<4; i++) {
226 if (iNode == std::abs(pF[iFace].edge[i].v))
break;
230 <<
"HepPolyhedron::FindNeighbour: face " << iFace
231 <<
" has no node " << iNode
237 if (pF[iFace].edge[i].v == 0) i = 2;
239 return (pF[iFace].edge[i].v > 0) ? 0 : pF[iFace].edge[i].f;
253 G4int k = iFace, iOrder = 1;
256 k = FindNeighbour(k, iNode, iOrder);
257 if (k == iFace)
break;
259 normal += GetUnitNormal(k);
261 if (iOrder < 0)
break;
266 return normal.
unit();
292 if (index < 1 || index >
nvert)
295 <<
"HepPolyhedron::SetVertex: vertex index = " << index
296 <<
" is out of range\n"
297 <<
" N. of vertices = " <<
nvert <<
"\n"
298 <<
" N. of facets = " <<
nface << std::endl;
315 if (index < 1 || index >
nface)
318 <<
"HepPolyhedron::SetFacet: facet index = " << index
319 <<
" is out of range\n"
320 <<
" N. of vertices = " <<
nvert <<
"\n"
321 <<
" N. of facets = " <<
nface << std::endl;
324 if (iv1 < 1 || iv1 >
nvert ||
325 iv2 < 1 || iv2 >
nvert ||
326 iv3 < 1 || iv3 >
nvert ||
327 iv4 < 0 || iv4 >
nvert)
330 <<
"HepPolyhedron::SetFacet: incorrectly specified facet"
331 <<
" (" << iv1 <<
", " << iv2 <<
", " << iv3 <<
", " << iv4 <<
")\n"
332 <<
" N. of vertices = " <<
nvert <<
"\n"
333 <<
" N. of facets = " <<
nface << std::endl;
336 pF[index] =
G4Facet(iv1, 0, iv2, 0, iv3, 0, iv4, 0);
349 const G4int nMin = 3;
352 <<
"HepPolyhedron::SetNumberOfRotationSteps: attempt to set the\n"
353 <<
"number of steps per circle < " << nMin <<
"; forced to " << nMin
390 if (Nvert > 0 && Nface > 0) {
410 enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
412 pF[1] =
G4Facet(1,LEFT, 4,BACK, 3,RIGHT, 2,FRONT);
413 pF[2] =
G4Facet(5,TOP, 8,BACK, 4,BOTTOM, 1,FRONT);
414 pF[3] =
G4Facet(8,TOP, 7,RIGHT, 3,BOTTOM, 4,LEFT);
415 pF[4] =
G4Facet(7,TOP, 6,FRONT, 2,BOTTOM, 3,BACK);
416 pF[5] =
G4Facet(6,TOP, 5,LEFT, 1,BOTTOM, 2,RIGHT);
417 pF[6] =
G4Facet(5,FRONT, 6,RIGHT, 7,BACK, 8,LEFT);
442 if (r1 == 0. && r2 == 0.)
return;
447 G4int ii1 = ifWholeCircle ? i1 : i1+nds;
448 G4int ii2 = ifWholeCircle ? i2 : i2+nds;
449 G4int vv = ifWholeCircle ? vEdge : 1;
453 pF[kface++] =
G4Facet(i1,0, v2*i2,0, (i2+1),0);
454 }
else if (r2 == 0.) {
455 pF[kface++] =
G4Facet(i1,0, i2,0, v1*(i1+1),0);
457 pF[kface++] =
G4Facet(i1,0, v2*i2,0, (i2+1),0, v1*(i1+1),0);
461 pF[kface++] =
G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0);
462 for (i2++,i=1; i<nds-1; i2++,i++) {
463 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0);
465 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0);
466 }
else if (r2 == 0.) {
467 pF[kface++] =
G4Facet(vv*i1,0, vEdge*i2,0, v1*(i1+1),0);
468 for (i1++,i=1; i<nds-1; i1++,i++) {
469 pF[kface++] =
G4Facet(vEdge*i1,0, vEdge*i2,0, v1*(i1+1),0);
471 pF[kface++] =
G4Facet(vEdge*i1,0, vv*i2,0, v1*ii1,0);
473 pF[kface++] =
G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
474 for (i1++,i2++,i=1; i<nds-1; i1++,i2++,i++) {
475 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
477 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0, v1*ii1,0);
502 G4int k1, k2, k3, k4;
504 if (std::abs(dphi-pi) < perMillion) {
505 for (
G4int i=0; i<4; i++) {
508 if (r[k1] == 0. && r[k2] == 0.) vv[i] = -1;
512 if (ii[1] == ii[2]) {
516 pF[kface++] =
G4Facet(vv[0]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
517 if (r[ii[0]] != 0.) k1 += nds;
518 if (r[ii[2]] != 0.) k2 += nds;
519 if (r[ii[3]] != 0.) k3 += nds;
520 pF[kface++] =
G4Facet(vv[2]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
521 }
else if (kk[ii[0]] == kk[ii[1]]) {
525 pF[kface++] =
G4Facet(vv[1]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
526 if (r[ii[0]] != 0.) k1 += nds;
527 if (r[ii[2]] != 0.) k2 += nds;
528 if (r[ii[3]] != 0.) k3 += nds;
529 pF[kface++] =
G4Facet(vv[2]*k3,0, vv[1]*k2,0, vv[3]*k1,0);
530 }
else if (kk[ii[2]] == kk[ii[3]]) {
534 pF[kface++] =
G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[3]*k3,0);
535 if (r[ii[0]] != 0.) k1 += nds;
536 if (r[ii[1]] != 0.) k2 += nds;
537 if (r[ii[2]] != 0.) k3 += nds;
538 pF[kface++] =
G4Facet(vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
544 pF[kface++] =
G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[2]*k3,0, vv[3]*k4,0);
545 if (r[ii[0]] != 0.) k1 += nds;
546 if (r[ii[1]] != 0.) k2 += nds;
547 if (r[ii[2]] != 0.) k3 += nds;
548 if (r[ii[3]] != 0.) k4 += nds;
549 pF[kface++] =
G4Facet(vv[2]*k4,0, vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
579 static const G4double wholeCircle = twopi;
583 G4bool ifWholeCircle = std::abs(dphi-wholeCircle) < perMillion;
584 G4double delPhi = ifWholeCircle ? wholeCircle : dphi;
587 if (nSphi == 0) nSphi = 1;
588 G4int nVphi = ifWholeCircle ? nSphi : nSphi + 1;
589 G4bool ifClosed = np1 <= 0;
593 G4int absNp1 = std::abs(np1);
594 G4int absNp2 = std::abs(np2);
596 G4int i1end = absNp1-1;
597 G4int i2beg = absNp1;
598 G4int i2end = absNp1+absNp2-1;
601 for(i=i1beg; i<=i2end; i++) {
608 for (i=i1beg; i<=i1end; i++) {
609 Nverts += (r[i] == 0.) ? 1 : nVphi;
617 if (r[i2beg] != r[i1beg] || z[i2beg] != z[i1beg]) {
618 Nverts += (r[i2beg] == 0.) ? 1 : nVphi;
622 for(i=i2beg+1; i<i2end; i++) {
623 Nverts += (r[i] == 0.) ? 1 : nVphi;
626 if (r[i2end] != r[i1end] || z[i2end] != z[i1end]) {
627 if (absNp2 > 1) Nverts += (r[i2end] == 0.) ? 1 : nVphi;
635 G4int Nfaces = ifClosed ? absNp1*nSphi : (absNp1-1)*nSphi;
640 for(i=i2beg; i<i2end; i++) {
641 if (r[i] > 0. || r[i+1] > 0.) Nfaces += nSphi;
645 if (r[i2end] > 0. || r[i2beg] > 0.) Nfaces += nSphi;
652 if (ifSide1 && (r[i1beg] > 0. || r[i2beg] > 0.)) Nfaces += nSphi;
653 if (ifSide2 && (r[i1end] > 0. || r[i2end] > 0.)) Nfaces += nSphi;
658 if (!ifWholeCircle) {
659 Nfaces += ifClosed ? 2*absNp1 : 2*(absNp1-1);
665 if (
pV ==
nullptr ||
pF ==
nullptr)
return;
670 kk =
new G4int[absNp1+absNp2];
675 for(i=i1beg; i<=i1end; i++) {
678 {
pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
687 {
pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
694 for(i=i2beg+1; i<i2end; i++) {
697 {
pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
716 for(j=0; j<nVphi; j++) {
717 cosPhi = std::cos(phi+j*delPhi/nSphi);
718 sinPhi = std::sin(phi+j*delPhi/nSphi);
719 for(i=i1beg; i<=i2end; i++) {
721 pV[kk[i]+j] =
G4Point3D(r[i]*cosPhi,r[i]*sinPhi,z[i]);
732 v2 = ifClosed ? nodeVis : 1;
733 for(i=i1beg; i<i1end; i++) {
735 if (!ifClosed && i == i1end-1) {
738 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
740 RotateEdge(kk[i], kk[i+1], r[i], r[i+1], v1, v2,
741 edgeVis, ifWholeCircle, nSphi, k);
744 RotateEdge(kk[i1end], kk[i1beg], r[i1end],r[i1beg], nodeVis, nodeVis,
745 edgeVis, ifWholeCircle, nSphi, k);
751 v2 = ifClosed ? nodeVis : 1;
752 for(i=i2beg; i<i2end; i++) {
754 if (!ifClosed && i==i2end-1) {
757 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
759 RotateEdge(kk[i+1], kk[i], r[i+1], r[i], v2, v1,
760 edgeVis, ifWholeCircle, nSphi, k);
763 RotateEdge(kk[i2beg], kk[i2end], r[i2beg], r[i2end], nodeVis, nodeVis,
764 edgeVis, ifWholeCircle, nSphi, k);
772 RotateEdge(kk[i2beg], kk[i1beg], r[i2beg], r[i1beg], 1, 1,
773 -1, ifWholeCircle, nSphi, k);
776 RotateEdge(kk[i1end], kk[i2end], r[i1end], r[i2end], 1, 1,
777 -1, ifWholeCircle, nSphi, k);
783 if (!ifWholeCircle) {
788 for (i=i1beg; i<=i1end; i++) {
790 ii[3] = (i == i1end) ? i1beg : i+1;
791 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
792 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
800 for (i=i1beg; i<i1end; i++) {
803 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
804 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
805 vv[0] = (i == i1beg) ? 1 : -1;
807 vv[2] = (i == i1end-1) ? 1 : -1;
820 <<
"HepPolyhedron::RotateAroundZ: number of generated faces ("
821 << k-1 <<
") is not equal to the number of allocated faces ("
831 const std::vector<G4TwoVector> &rz,
854 G4bool ifWholeCircle = std::abs(dphi - twopi) < perMillion;
855 G4double delPhi = (ifWholeCircle) ? twopi : dphi;
858 if (nSphi == 0) nSphi = 1;
859 G4int nVphi = (ifWholeCircle) ? nSphi : nSphi + 1;
865 for (
G4int i = 0; i < Nrz; ++i)
867 G4int k = (i == 0) ? Nrz - 1 : i - 1;
868 area += rz[k].x()*rz[i].y() - rz[i].x()*rz[k].y();
875 for (
G4int i = 0; i < Nrz; ++i)
885 for(
G4int i = 0; i < Nrz; ++i) Nverts += (r[i] == 0.) ? 1 : nVphi;
888 for (
G4int i = 0; i < Nrz; ++i)
890 G4int k = (i == 0) ? Nrz - 1 : i - 1;
891 Nedges -=
static_cast<int>(r[k] == 0 && r[i] == 0);
894 G4int Nfaces = Nedges*nSphi;
895 if (!ifWholeCircle) Nfaces += 2*(Nrz - 2);
900 if (
pV ==
nullptr ||
pF ==
nullptr)
909 auto kk =
new G4int[Nrz];
913 for(
G4int i = 0; i < Nrz; ++i)
916 if (r[i] == 0.)
pV[kfree++] =
G4Point3D(0, 0, z[i]);
917 if (r[i] != 0.) kfree += nVphi;
921 for(
G4int j = 0; j < nVphi; ++j)
923 G4double cosPhi = std::cos(phi + j*delPhi/nSphi);
924 G4double sinPhi = std::sin(phi + j*delPhi/nSphi);
925 for(
G4int i = 0; i < Nrz; ++i)
928 pV[kk[i] + j] =
G4Point3D(r[i]*cosPhi, r[i]*sinPhi, z[i]);
935 for(
G4int i = 0; i < Nrz; ++i)
937 G4int i1 = (i < Nrz - 1) ? i + 1 : 0;
939 if (area < 0.) std::swap(i1, i2);
940 RotateEdge(kk[i1], kk[i2], r[i1], r[i2], nodeVis, nodeVis,
941 edgeVis, ifWholeCircle, nSphi, kfree);
948 std::vector<G4int> triangles;
953 for (
G4int i = 0; i < ntria; ++i)
955 G4int i1 = triangles[0 + i*3];
956 G4int i2 = triangles[1 + i*3];
957 G4int i3 = triangles[2 + i*3];
958 if (area < 0.) std::swap(i1, i3);
959 G4int v1 = (std::abs(i2-i1) == 1 || std::abs(i2-i1) == Nrz-1) ? 1 : -1;
960 G4int v2 = (std::abs(i3-i2) == 1 || std::abs(i3-i2) == Nrz-1) ? 1 : -1;
961 G4int v3 = (std::abs(i1-i3) == 1 || std::abs(i1-i3) == Nrz-1) ? 1 : -1;
962 ii[0] = i1; ii[1] = i2; ii[2] = i2; ii[3] = i3;
963 vv[0] = v1; vv[1] = -1; vv[2] = v2; vv[3] = v3;
974 if (kfree - 1 !=
nface)
977 <<
"HepPolyhedron::RotateContourAroundZ: number of generated faces ("
978 << kfree-1 <<
") is not equal to the number of allocated faces ("
986 std::vector<G4int> &result)
1005 if (n < 3)
return false;
1010 for(
G4int i = 0; i < n; ++i)
1012 G4int k = (i == 0) ? n - 1 : i - 1;
1013 area += polygon[k].x()*polygon[i].y() - polygon[i].x()*polygon[k].y();
1019 auto V =
new G4int[n];
1021 for (
G4int i = 0; i < n; ++i) V[i] = i;
1023 for (
G4int i = 0; i < n; ++i) V[i] = (n - 1) - i;
1029 for(
G4int b = nv - 1; nv > 2; )
1035 if (area < 0.) std::reverse(result.begin(),result.end());
1040 G4int a = (b < nv) ? b : 0;
1041 b = (a+1 < nv) ? a+1 : 0;
1042 G4int c = (b+1 < nv) ? b+1 : 0;
1047 result.push_back(V[a]);
1048 result.push_back(V[b]);
1049 result.push_back(V[c]);
1053 for(
G4int i = b; i < nv; ++i) V[i] = V[i+1];
1059 if (area < 0.) std::reverse(result.begin(),result.end());
1079 G4double Ax = contour[V[a]].x(), Ay = contour[V[a]].y();
1080 G4double Bx = contour[V[b]].x(), By = contour[V[b]].y();
1081 G4double Cx = contour[V[c]].x(), Cy = contour[V[c]].y();
1082 if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) <
kCarTolerance)
return false;
1085 G4double xmin = std::min(std::min(Ax,Bx),Cx);
1086 G4double xmax = std::max(std::max(Ax,Bx),Cx);
1087 G4double ymin = std::min(std::min(Ay,By),Cy);
1088 G4double ymax = std::max(std::max(Ay,By),Cy);
1090 for (
G4int i=0; i<n; ++i)
1092 if((i == a) || (i == b) || (i == c))
continue;
1094 if (Px < xmin || Px > xmax)
continue;
1096 if (Py < ymin || Py > ymax)
continue;
1098 if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) > 0.)
1100 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.)
continue;
1101 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.)
continue;
1102 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.)
continue;
1106 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.)
continue;
1107 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.)
continue;
1108 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.)
continue;
1125 if (
nface <= 0)
return;
1127 struct edgeListMember {
1128 edgeListMember *next;
1132 } *edgeList, *freeList, **headList;
1137 edgeList =
new edgeListMember[2*
nface];
1138 headList =
new edgeListMember*[
nvert];
1141 for (i=0; i<
nvert; i++) {
1142 headList[i] =
nullptr;
1144 freeList = edgeList;
1145 for (i=0; i<2*
nface-1; i++) {
1146 edgeList[i].next = &edgeList[i+1];
1148 edgeList[2*
nface-1].next =
nullptr;
1152 G4int iface, iedge, nedge, i1, i2, k1, k2;
1153 edgeListMember *prev, *cur;
1155 for(iface=1; iface<=
nface; iface++) {
1156 nedge = (
pF[iface].edge[3].v == 0) ? 3 : 4;
1157 for (iedge=0; iedge<nedge; iedge++) {
1159 i2 = (iedge < nedge-1) ? iedge+1 : 0;
1160 i1 = std::abs(
pF[iface].edge[i1].v);
1161 i2 = std::abs(
pF[iface].edge[i2].v);
1162 k1 = (i1 < i2) ? i1 : i2;
1163 k2 = (i1 > i2) ? i1 : i2;
1167 if (cur ==
nullptr) {
1168 headList[k1] = freeList;
1169 if (freeList ==
nullptr) {
1171 <<
"Polyhedron::SetReferences: bad link "
1175 freeList = freeList->next;
1177 cur->next =
nullptr;
1184 if (cur->v2 == k2) {
1185 headList[k1] = cur->next;
1186 cur->next = freeList;
1188 pF[iface].edge[iedge].f = cur->iface;
1189 pF[cur->iface].edge[cur->iedge].f = iface;
1190 i1 = (
pF[iface].edge[iedge].v < 0) ? -1 : 1;
1191 i2 = (
pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
1194 <<
"Polyhedron::SetReferences: different edge visibility "
1195 << iface <<
"/" << iedge <<
"/"
1196 <<
pF[iface].edge[iedge].v <<
" and "
1197 << cur->iface <<
"/" << cur->iedge <<
"/"
1198 <<
pF[cur->iface].edge[cur->iedge].v
1208 if (cur ==
nullptr) {
1209 prev->next = freeList;
1210 if (freeList ==
nullptr) {
1212 <<
"Polyhedron::SetReferences: bad link "
1216 freeList = freeList->next;
1218 cur->next =
nullptr;
1225 if (cur->v2 == k2) {
1226 prev->next = cur->next;
1227 cur->next = freeList;
1229 pF[iface].edge[iedge].f = cur->iface;
1230 pF[cur->iface].edge[cur->iedge].f = iface;
1231 i1 = (
pF[iface].edge[iedge].v < 0) ? -1 : 1;
1232 i2 = (
pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
1235 <<
"Polyhedron::SetReferences: different edge visibility "
1236 << iface <<
"/" << iedge <<
"/"
1237 <<
pF[iface].edge[iedge].v <<
" and "
1238 << cur->iface <<
"/" << cur->iedge <<
"/"
1239 <<
pF[cur->iface].edge[cur->iedge].v
1250 for (i=0; i<
nvert; i++) {
1251 if (headList[i] !=
nullptr) {
1253 <<
"Polyhedron::SetReferences: List " << i <<
" is not empty"
1279 if (
pF[icur].edge[0].v == 0)
continue;
1280 if (
pF[icur].edge[3].v != 0)
continue;
1282 if (
pF[icur].edge[0].f < icur &&
1283 pF[icur].edge[1].f < icur &&
1284 pF[icur].edge[2].f < icur)
continue;
1288 G4int vcur0 = std::abs(
pF[icur].edge[0].v);
1289 G4int vcur1 = std::abs(
pF[icur].edge[1].v);
1290 G4int vcur2 = std::abs(
pF[icur].edge[2].v);
1292 G4int kcheck = 0, icheck = 0, vcheck = 0;
1294 for (
G4int k = 0; k < 3; ++k)
1296 G4int itmp =
pF[icur].edge[k].f;
1298 if (itmp < icur)
continue;
1299 if (
pF[itmp].edge[0].v == 0 ||
1300 pF[itmp].edge[3].v != 0)
continue;
1303 for (
G4int j = 0; j < 3; ++j)
1305 vtmp = std::abs(
pF[itmp].edge[j].v);
1306 if (vtmp != vcur0 && vtmp != vcur1 && vtmp != vcur2)
break;
1310 if (dtmp > tolerance || dtmp >= dist)
continue;
1316 if (icheck == 0)
continue;
1319 pF[icheck].edge[0].v = 0;
1322 pF[icur].edge[3].v =
pF[icur].edge[2].v;
1323 pF[icur].edge[2].v =
pF[icur].edge[1].v;
1324 pF[icur].edge[1].v = vcheck;
1326 else if (kcheck == 1)
1328 pF[icur].edge[3].v =
pF[icur].edge[2].v;
1329 pF[icur].edge[2].v = vcheck;
1333 pF[icur].edge[3].v = vcheck;
1336 if (njoin == 0)
return;
1342 if (
pF[icur].edge[0].v == 0)
continue;
1344 pF[nnew].edge[0].v =
pF[icur].edge[0].v;
1345 pF[nnew].edge[1].v =
pF[icur].edge[1].v;
1346 pF[nnew].edge[2].v =
pF[icur].edge[2].v;
1347 pF[nnew].edge[3].v =
pF[icur].edge[3].v;
1363 if (
nface <= 0)
return;
1364 G4int i, k, nnode, v[4],f[4];
1365 for (i=1; i<=
nface; i++) {
1366 nnode = (
pF[i].edge[3].v == 0) ? 3 : 4;
1367 for (k=0; k<nnode; k++) {
1368 v[k] = (k+1 == nnode) ?
pF[i].edge[0].v :
pF[i].edge[k+1].v;
1369 if (v[k] *
pF[i].edge[k].v < 0) v[k] = -v[k];
1370 f[k] =
pF[i].edge[k].f;
1372 for (k=0; k<nnode; k++) {
1373 pF[i].edge[nnode-1-k].v = v[k];
1374 pF[i].edge[nnode-1-k].f = f[k];
1416 G4int vIndex = pF[iFace].edge[iQVertex].v;
1418 edgeFlag = (vIndex > 0) ? 1 : 0;
1419 index = std::abs(vIndex);
1421 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
1423 if (++iFace > nface) iFace = 1;
1441 if (index <= 0 || index > nvert) {
1443 <<
"HepPolyhedron::GetVertex: irrelevant index " << index
1464 G4bool rep = GetNextVertexIndex(index, edgeFlag);
1485 if (nface == 0)
return false;
1487 G4int k = pF[iFace].edge[iNode].v;
1488 if (k > 0) { edgeFlag = 1; }
else { edgeFlag = -1; k = -k; }
1490 normal = FindNodeNormal(iFace,k);
1491 if (iNode >= 3 || pF[iFace].edge[iNode+1].v == 0) {
1493 if (++iFace > nface) iFace = 1;
1516 G4int k1, k2, kflag, kface1, kface2;
1518 if (iFace == 1 && iQVertex == 0) {
1519 k2 = pF[nface].edge[0].v;
1520 k1 = pF[nface].edge[3].v;
1521 if (k1 == 0) k1 = pF[nface].edge[2].v;
1522 if (std::abs(k1) > std::abs(k2)) iOrder = -1;
1526 k1 = pF[iFace].edge[iQVertex].v;
1530 kface2 = pF[iFace].edge[iQVertex].f;
1531 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
1533 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1537 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1539 }
while (iOrder*k1 > iOrder*k2);
1541 i1 = k1; i2 = k2; edgeFlag = (kflag > 0) ? 1 : 0;
1542 iface1 = kface1; iface2 = kface2;
1544 if (iFace > nface) {
1545 iFace = 1; iOrder = 1;
1564 G4int kface1, kface2;
1565 return GetNextEdgeIndices(i1, i2, edgeFlag, kface1, kface2);
1571 G4int &edgeFlag)
const
1583 G4bool rep = GetNextEdgeIndices(i1,i2,edgeFlag);
1604 G4bool rep = GetNextEdgeIndices(i1,i2,edgeFlag,iface1,iface2);
1621 if (iFace < 1 || iFace > nface) {
1623 <<
"HepPolyhedron::GetFacet: irrelevant index " << iFace
1628 for (i=0; i<4; i++) {
1629 k = pF[iFace].edge[i].v;
1631 if (iFaces !=
nullptr) iFaces[i] = pF[iFace].edge[i].f;
1634 if (edgeFlags !=
nullptr) edgeFlags[i] = 1;
1637 if (edgeFlags !=
nullptr) edgeFlags[i] = -1;
1656 GetFacet(index, n, iNodes, edgeFlags);
1658 for (
G4int i=0; i<n; i++) {
1659 nodes[i] = pV[iNodes[i]];
1660 if (normals !=
nullptr) normals[i] = FindNodeNormal(index,iNodes[i]);
1680 if (edgeFlags ==
nullptr) {
1681 GetFacet(iFace, n, nodes);
1682 }
else if (normals ==
nullptr) {
1683 GetFacet(iFace, n, nodes, edgeFlags);
1685 GetFacet(iFace, n, nodes, edgeFlags, normals);
1688 if (++iFace > nface) {
1706 if (iFace < 1 || iFace > nface) {
1708 <<
"HepPolyhedron::GetNormal: irrelevant index " << iFace
1713 G4int i0 = std::abs(pF[iFace].edge[0].v);
1714 G4int i1 = std::abs(pF[iFace].edge[1].v);
1715 G4int i2 = std::abs(pF[iFace].edge[2].v);
1716 G4int i3 = std::abs(pF[iFace].edge[3].v);
1717 if (i3 == 0) i3 = i0;
1718 return (pV[i2] - pV[i0]).cross(pV[i3] - pV[i1]);
1731 if (iFace < 1 || iFace > nface) {
1733 <<
"HepPolyhedron::GetUnitNormal: irrelevant index " << iFace
1738 G4int i0 = std::abs(pF[iFace].edge[0].v);
1739 G4int i1 = std::abs(pF[iFace].edge[1].v);
1740 G4int i2 = std::abs(pF[iFace].edge[2].v);
1741 G4int i3 = std::abs(pF[iFace].edge[3].v);
1742 if (i3 == 0) i3 = i0;
1743 return ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).unit();
1758 normal = GetNormal(iFace);
1759 if (++iFace > nface) {
1777 G4bool rep = GetNextNormal(normal);
1778 normal = normal.unit();
1794 G4int i0 = std::abs(
pF[iFace].edge[0].v);
1795 G4int i1 = std::abs(
pF[iFace].edge[1].v);
1796 G4int i2 = std::abs(
pF[iFace].edge[2].v);
1797 G4int i3 = std::abs(
pF[iFace].edge[3].v);
1798 if (i3 == 0) i3 = i0;
1799 srf += ((
pV[i2] -
pV[i0]).cross(
pV[i3] -
pV[i1])).mag();
1816 G4int i0 = std::abs(
pF[iFace].edge[0].v);
1817 G4int i1 = std::abs(
pF[iFace].edge[1].v);
1818 G4int i2 = std::abs(
pF[iFace].edge[2].v);
1819 G4int i3 = std::abs(
pF[iFace].edge[3].v);
1823 pt = (
pV[i0]+
pV[i1]+
pV[i2]) * (1./3.);
1825 pt = (
pV[i0]+
pV[i1]+
pV[i2]+
pV[i3]) * 0.25;
1827 v += ((
pV[i2] -
pV[i0]).cross(
pV[i3] -
pV[i1])).
dot(pt);
1867 enum {DUMMY, BOTTOM,
1868 LEFT_BOTTOM, LEFT_FRONT, LEFT_TOP, LEFT_BACK,
1869 BACK_BOTTOM, BACK_LEFT, BACK_TOP, BACK_RIGHT,
1870 RIGHT_BOTTOM, RIGHT_BACK, RIGHT_TOP, RIGHT_FRONT,
1871 FRONT_BOTTOM, FRONT_RIGHT, FRONT_TOP, FRONT_LEFT,
1874 pF[ 1]=
G4Facet(1,LEFT_BOTTOM, 4,BACK_BOTTOM, 3,RIGHT_BOTTOM, 2,FRONT_BOTTOM);
1876 pF[ 2]=
G4Facet(4,BOTTOM, -1,LEFT_FRONT, -12,LEFT_BACK, 0,0);
1877 pF[ 3]=
G4Facet(1,FRONT_LEFT, -5,LEFT_TOP, -12,LEFT_BOTTOM, 0,0);
1878 pF[ 4]=
G4Facet(5,TOP, -8,LEFT_BACK, -12,LEFT_FRONT, 0,0);
1879 pF[ 5]=
G4Facet(8,BACK_LEFT, -4,LEFT_BOTTOM, -12,LEFT_TOP, 0,0);
1881 pF[ 6]=
G4Facet(3,BOTTOM, -4,BACK_LEFT, -11,BACK_RIGHT, 0,0);
1882 pF[ 7]=
G4Facet(4,LEFT_BACK, -8,BACK_TOP, -11,BACK_BOTTOM, 0,0);
1883 pF[ 8]=
G4Facet(8,TOP, -7,BACK_RIGHT, -11,BACK_LEFT, 0,0);
1884 pF[ 9]=
G4Facet(7,RIGHT_BACK, -3,BACK_BOTTOM, -11,BACK_TOP, 0,0);
1886 pF[10]=
G4Facet(2,BOTTOM, -3,RIGHT_BACK, -10,RIGHT_FRONT, 0,0);
1887 pF[11]=
G4Facet(3,BACK_RIGHT, -7,RIGHT_TOP, -10,RIGHT_BOTTOM, 0,0);
1888 pF[12]=
G4Facet(7,TOP, -6,RIGHT_FRONT, -10,RIGHT_BACK, 0,0);
1889 pF[13]=
G4Facet(6,FRONT_RIGHT,-2,RIGHT_BOTTOM,-10,RIGHT_TOP, 0,0);
1891 pF[14]=
G4Facet(1,BOTTOM, -2,FRONT_RIGHT, -9,FRONT_LEFT, 0,0);
1892 pF[15]=
G4Facet(2,RIGHT_FRONT,-6,FRONT_TOP, -9,FRONT_BOTTOM, 0,0);
1893 pF[16]=
G4Facet(6,TOP, -5,FRONT_LEFT, -9,FRONT_RIGHT, 0,0);
1894 pF[17]=
G4Facet(5,LEFT_FRONT, -1,FRONT_BOTTOM, -9,FRONT_TOP, 0,0);
1896 pF[18]=
G4Facet(5,FRONT_TOP, 6,RIGHT_TOP, 7,BACK_TOP, 8,LEFT_TOP);
1904 const G4int faces[][4])
1920 if (
nvert == 0)
return 1;
1922 for (
G4int i=0; i<Nnodes; i++) {
1923 pV[i+1] =
G4Point3D(xyz[i][0], xyz[i][1], xyz[i][2]);
1925 for (
G4int k=0; k<Nfaces; k++) {
1926 pF[k+1] =
G4Facet(faces[k][0],0,faces[k][1],0,faces[k][2],0,faces[k][3],0);
1944 for(
int i=1;i<=
nvert;i++) {
1947 centre = centre/
nvert;
2030 G4double DzTthetaCphi = Dz*std::tan(Theta)*std::cos(Phi);
2031 G4double DzTthetaSphi = Dz*std::tan(Theta)*std::sin(Phi);
2032 G4double Dy1Talp1 = Dy1*std::tan(Alp1);
2033 G4double Dy2Talp2 = Dy2*std::tan(Alp2);
2037 pV[1] =
G4Point3D(-DzTthetaCphi-Dy1Talp1-Dx1,-DzTthetaSphi-Dy1,-Dz);
2038 pV[2] =
G4Point3D(-DzTthetaCphi-Dy1Talp1+Dx1,-DzTthetaSphi-Dy1,-Dz);
2039 pV[3] =
G4Point3D(-DzTthetaCphi+Dy1Talp1+Dx2,-DzTthetaSphi+Dy1,-Dz);
2040 pV[4] =
G4Point3D(-DzTthetaCphi+Dy1Talp1-Dx2,-DzTthetaSphi+Dy1,-Dz);
2041 pV[5] =
G4Point3D( DzTthetaCphi-Dy2Talp2-Dx3, DzTthetaSphi-Dy2, Dz);
2042 pV[6] =
G4Point3D( DzTthetaCphi-Dy2Talp2+Dx3, DzTthetaSphi-Dy2, Dz);
2043 pV[7] =
G4Point3D( DzTthetaCphi+Dy2Talp2+Dx4, DzTthetaSphi+Dy2, Dz);
2044 pV[8] =
G4Point3D( DzTthetaCphi+Dy2Talp2-Dx4, DzTthetaSphi+Dy2, Dz);
2054 :
HepPolyhedronTrap(Dz, Theta, Phi, Dy, Dx, Dx,
Alpha, Dy, Dx, Dx,
Alpha) {}
2078 static const G4double wholeCircle=twopi;
2083 if (r1 < 0. || r2 <= 0.) k = 1;
2085 if (dz <= 0.) k += 2;
2091 phi2 = sPhi; phi1 = phi2 + dPhi;
2095 phi1 = sPhi; phi2 = phi1 + wholeCircle;
2099 phi1 = sPhi; phi2 = phi1 + dPhi;
2103 if (std::abs(dphi-wholeCircle) < perMillion) dphi = wholeCircle;
2104 if (dphi > wholeCircle) k += 4;
2107 std::cerr <<
"HepPolyhedronParaboloid: error in input parameters";
2108 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
2109 if ((k & 2) != 0) std::cerr <<
" (half-length)";
2110 if ((k & 4) != 0) std::cerr <<
" (angles)";
2111 std::cerr << std::endl;
2112 std::cerr <<
" r1=" << r1;
2113 std::cerr <<
" r2=" << r2;
2114 std::cerr <<
" dz=" << dz <<
" sPhi=" << sPhi <<
" dPhi=" << dPhi
2123 G4double k1 = (r2*r2 - r1*r1) / 2 / dz;
2131 for(
G4int i = 1; i < n - 1; i++)
2133 rr[i] = rr[i-1] - dl;
2134 zz[i] = (rr[i]*rr[i] - k2) / k1;
2183 static const G4double wholeCircle = twopi;
2188 if (r1 < 0. || r2 < 0. || r1 >= r2) k = 1;
2189 if (halfZ <= 0.) k += 2;
2190 if (sqrtan1 < 0.|| sqrtan2 < 0.) k += 4;
2194 std::cerr <<
"HepPolyhedronHype: error in input parameters";
2195 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
2196 if ((k & 2) != 0) std::cerr <<
" (half-length)";
2197 if ((k & 4) != 0) std::cerr <<
" (angles)";
2198 std::cerr << std::endl;
2199 std::cerr <<
" r1=" << r1 <<
" r2=" << r2;
2200 std::cerr <<
" halfZ=" << halfZ <<
" sqrTan1=" << sqrtan1
2201 <<
" sqrTan2=" << sqrtan2
2209 G4int nz1 = (sqrtan1 == 0.) ? 2 : ns + 1;
2210 G4int nz2 = (sqrtan2 == 0.) ? 2 : ns + 1;
2216 for(
G4int i = 0; i < nz2; ++i)
2218 zz[i] = halfZ - dz2*i;
2219 rr[i] = std::sqrt(sqrtan2*zz[i]*zz[i] + r2*r2);
2224 for(
G4int i = 0; i < nz1; ++i)
2227 zz[j] = halfZ - dz1*i;
2228 rr[j] = std::sqrt(sqrtan1*zz[j]*zz[j] + r1*r1);
2233 RotateAroundZ(0, 0., wholeCircle, nz2, nz1, zz, rr, -1, -1);
2264 static const G4double wholeCircle=twopi;
2269 if (Rmn1 < 0. || Rmx1 < 0. || Rmn2 < 0. || Rmx2 < 0.) k = 1;
2270 if (Rmn1 > Rmx1 || Rmn2 > Rmx2) k = 1;
2271 if (Rmn1 == Rmx1 && Rmn2 == Rmx2) k = 1;
2273 if (Dz <= 0.) k += 2;
2277 phi2 = Phi1; phi1 = phi2 - Dphi;
2278 }
else if (Dphi == 0.) {
2279 phi1 = Phi1; phi2 = phi1 + wholeCircle;
2281 phi1 = Phi1; phi2 = phi1 + Dphi;
2284 if (std::abs(dphi-wholeCircle) < perMillion) dphi = wholeCircle;
2285 if (dphi > wholeCircle) k += 4;
2288 std::cerr <<
"HepPolyhedronCone(s)/Tube(s): error in input parameters";
2289 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
2290 if ((k & 2) != 0) std::cerr <<
" (half-length)";
2291 if ((k & 4) != 0) std::cerr <<
" (angles)";
2292 std::cerr << std::endl;
2293 std::cerr <<
" Rmn1=" << Rmn1 <<
" Rmx1=" << Rmx1;
2294 std::cerr <<
" Rmn2=" << Rmn2 <<
" Rmx2=" << Rmx2;
2295 std::cerr <<
" Dz=" << Dz <<
" Phi1=" << Phi1 <<
" Dphi=" << Dphi
2366 if (dphi <= 0. || dphi > twopi) {
2368 <<
"HepPolyhedronPgon/Pcon: wrong delta phi = " << dphi
2375 <<
"HepPolyhedronPgon/Pcon: number of z-planes less than two = " << nz
2382 <<
"HepPolyhedronPgon/Pcon: error in number of phi-steps =" << npdv
2388 for (i=0; i<nz; i++) {
2389 if (rmin[i] < 0. || rmax[i] < 0. || rmin[i] > rmax[i]) {
2391 <<
"HepPolyhedronPgon: error in radiuses rmin[" << i <<
"]="
2392 << rmin[i] <<
" rmax[" << i <<
"]=" << rmax[i]
2404 if (z[0] > z[nz-1]) {
2405 for (i=0; i<nz; i++) {
2412 for (i=0; i<nz; i++) {
2414 rr[i] = rmax[nz-i-1];
2415 zz[i+nz] = z[nz-i-1];
2416 rr[i+nz] = rmin[nz-i-1];
2423 G4int edgeVis = (npdv == 0) ? -1 : 1;
2424 RotateAroundZ(npdv, phi, dphi, nz, nz, zz, rr, nodeVis, edgeVis);
2434 const std::vector<G4TwoVector> &rz)
2451 if (dphi <= 0. || dphi > twopi) {
2453 <<
"HepPolyhedronPgon/Pcon: wrong delta phi = " << dphi
2460 <<
"HepPolyhedronPgon/Pcon: error in number of phi-steps = " << npdv
2468 <<
"HepPolyhedronPgon/Pcon: invalid number of nodes in rz-contour = " << nrz
2476 G4int edgeVis = (npdv == 0) ? -1 : 1;
2490 const std::vector<G4TwoVector> &rz)
2516 if (dphi <= 0. || dphi > twopi) {
2518 <<
"HepPolyhedronSphere: wrong delta phi = " << dphi
2523 if (the < 0. || the > pi) {
2525 <<
"HepPolyhedronSphere: wrong theta = " << the
2530 if (dthe <= 0. || dthe > pi) {
2532 <<
"HepPolyhedronSphere: wrong delta theta = " << dthe
2537 if (the+dthe > pi) {
2539 <<
"HepPolyhedronSphere: wrong theta + delta theta = "
2540 << the <<
" " << dthe
2545 if (rmin < 0. || rmin >= rmax) {
2547 <<
"HepPolyhedronSphere: error in radiuses"
2548 <<
" rmin=" << rmin <<
" rmax=" << rmax
2557 if (np1 <= 1) np1 = 2;
2566 for (
G4int i=0; i<np1; i++) {
2567 cosa = std::cos(the+i*a);
2568 sina = std::sin(the+i*a);
2572 zz[i+np1] = rmin*cosa;
2573 rr[i+np1] = rmin*sina;
2614 if (dphi <= 0. || dphi > twopi) {
2616 <<
"HepPolyhedronTorus: wrong delta phi = " << dphi
2621 if (rmin < 0. || rmin >= rmax || rmax >= rtor) {
2623 <<
"HepPolyhedronTorus: error in radiuses"
2624 <<
" rmin=" << rmin <<
" rmax=" << rmax <<
" rtorus=" << rtor
2640 for (
G4int i=0; i<np1; i++) {
2641 cosa = std::cos(i*a);
2642 sina = std::sin(i*a);
2644 rr[i] = rtor+rmax*sina;
2646 zz[i+np1] = rmin*cosa;
2647 rr[i+np1] = rtor+rmin*sina;
2684 pV[1].
set(p0[0], p0[1], p0[2]);
2685 pV[2].
set(p1[0], p1[1], p1[2]);
2686 pV[3].
set(p2[0], p2[1], p2[2]);
2687 pV[4].
set(p3[0], p3[1], p3[2]);
2695 pV[3].
set(p3[0], p3[1], p3[2]);
2696 pV[4].
set(p2[0], p2[1], p2[2]);
2728 if (zCut1 >= cz || zCut2 <= -cz || zCut1 > zCut2) {
2729 std::cerr <<
"HepPolyhedronEllipsoid: wrong zCut1 = " << zCut1
2730 <<
" zCut2 = " << zCut2
2731 <<
" for given cz = " << cz << std::endl;
2735 std::cerr <<
"HepPolyhedronEllipsoid: bad z semi-axis: cz = " << cz
2743 G4double sthe = std::acos(zCut2/cz);
2744 G4double dthe = std::acos(zCut1/cz) - sthe;
2747 if (np1 <= 1) np1 = 2;
2753 if ((zz ==
nullptr) || (rr ==
nullptr))
2755 G4Exception(
"HepPolyhedronEllipsoid::HepPolyhedronEllipsoid",
2761 for (
G4int i = 0; i < np1; ++i)
2763 cosa = std::cos(sthe + i*a);
2764 sina = std::sin(sthe + i*a);
2768 zz[np1 + 0] = zCut2;
2770 zz[np1 + 1] = zCut1;
2814 if ( (ax <= 0.) || (ay <= 0.) || (h <= 0.) || (zTopCut <= 0.) ) { k = 1; }
2817 std::cerr <<
"HepPolyhedronCone: error in input parameters";
2818 std::cerr << std::endl;
2824 zTopCut = (h >= zTopCut ? zTopCut : h);
2833 rr[0] = (h-zTopCut);
2834 rr[1] = (h+zTopCut);
2850 p->
setX( p->
x() * ax );
2851 p->
setY( p->
y() * ay );
2883 G4double maxAng = (
A == 0.) ? 0. : std::acosh(1. + H/
A);
2884 G4double delAng = maxAng/(np1 - 1);
2892 for (
G4int iz = 1; iz < np1 - 1; ++iz)
2895 zz[iz] =
A*std::cosh(ang) -
A;
2896 rr[iz] =
B*std::sinh(ang);
2939 <<
"HepPolyhedronTetMesh: Empty tetrahedron mesh" << std::endl;
2942 G4int ntet = nnodes/4;
2943 if (nnodes != ntet*4)
2945 std::cerr <<
"HepPolyhedronTetMesh: Number of nodes = " << nnodes
2946 <<
" in tetrahedron mesh is NOT multiple of 4"
2954 std::vector<G4int> iheads(nnodes, -1);
2955 std::vector<std::pair<G4int,G4int>> ipairs(nnodes,std::pair(-1,-1));
2956 for (
G4int i = 0; i < nnodes; ++i)
2960 auto key = std::hash<G4double>()(point.
x());
2961 key ^= std::hash<G4double>()(point.
y());
2962 key ^= std::hash<G4double>()(point.
z());
2965 if (iheads[key] < 0)
2968 ipairs[i].first = i;
2972 for (
G4int icur = iheads[key], iprev = 0;;)
2974 G4int icheck = ipairs[icur].first;
2975 if (tetrahedra[icheck] == point)
2977 ipairs[i].first = icheck;
2981 icur = ipairs[icur].second;
2985 ipairs[i].first = i;
2986 ipairs[iprev].second = i;
2996 facet() : i1(0), i2(0), i3(0) {};
2999 G4int nfacets = nnodes;
3000 std::vector<facet> ifacets(nfacets);
3001 for (
G4int i = 0; i < nfacets; i += 4)
3003 G4int i0 = ipairs[i + 0].first;
3004 G4int i1 = ipairs[i + 1].first;
3005 G4int i2 = ipairs[i + 2].first;
3006 G4int i3 = ipairs[i + 3].first;
3007 if (i0 > i1) std::swap(i0, i1);
3008 if (i0 > i2) std::swap(i0, i2);
3009 if (i0 > i3) std::swap(i0, i3);
3010 if (i1 > i2) std::swap(i1, i2);
3011 if (i1 > i3) std::swap(i1, i3);
3016 if (volume > 0.) std::swap(i2, i3);
3017 ifacets[i + 0] = facet(i0, i1, i2);
3018 ifacets[i + 1] = facet(i0, i2, i3);
3019 ifacets[i + 2] = facet(i0, i3, i1);
3020 ifacets[i + 3] = facet(i1, i3, i2);
3024 std::fill(iheads.begin(), iheads.end(), -1);
3025 std::fill(ipairs.begin(), ipairs.end(), std::pair(-1,-1));
3026 for (
G4int i = 0; i < nfacets; ++i)
3029 G4int key = ifacets[i].i1;
3030 if (iheads[key] < 0)
3033 ipairs[i].first = i;
3037 G4int i2 = ifacets[i].i2, i3 = ifacets[i].i3;
3038 for (
G4int icur = iheads[key], iprev = -1;;)
3040 G4int icheck = ipairs[icur].first;
3041 if (ifacets[icheck].i2 == i3 && ifacets[icheck].i3 == i2)
3045 iheads[key] = ipairs[icur].second;
3049 ipairs[iprev].second = ipairs[icur].second;
3051 ipairs[icur].first = -1;
3052 ipairs[icur].second = -1;
3056 icur = ipairs[icur].second;
3060 ipairs[i].first = i;
3061 ipairs[iprev].second = i;
3068 std::fill(iheads.begin(), iheads.end(), -1);
3069 G4int nver = 0, nfac = 0;
3070 for (
G4int i = 0; i < nfacets; ++i)
3072 if (ipairs[i].first < 0)
continue;
3073 G4int i1 = ifacets[i].i1;
3074 G4int i2 = ifacets[i].i2;
3075 G4int i3 = ifacets[i].i3;
3076 if (iheads[i1] < 0) iheads[i1] = nver++;
3077 if (iheads[i2] < 0) iheads[i2] = nver++;
3078 if (iheads[i3] < 0) iheads[i3] = nver++;
3084 for (
G4int i = 0; i < nnodes; ++i)
3086 G4int k = iheads[i];
3087 if (k >= 0)
SetVertex(k + 1, tetrahedra[i]);
3089 for (
G4int i = 0, k = 0; i < nfacets; ++i)
3091 if (ipairs[i].first < 0)
continue;
3092 G4int i1 = iheads[ifacets[i].i1] + 1;
3093 G4int i2 = iheads[ifacets[i].i2] + 1;
3094 G4int i3 = iheads[ifacets[i].i3] + 1;
3104 const std::vector<G4ThreeVector>& positions)
3120 std::cerr <<
"HepPolyhedronBoxMesh: Empty box mesh" << std::endl;
3124 G4double invx = 1./sizeX, invy = 1./sizeY, invz = 1./sizeZ;
3127 for (
const auto& p: positions)
3129 if (pmin.
x() > p.x()) pmin.
setX(p.x());
3130 if (pmin.
y() > p.y()) pmin.
setY(p.y());
3131 if (pmin.
z() > p.z()) pmin.
setZ(p.z());
3132 if (pmax.x() < p.x()) pmax.setX(p.x());
3133 if (pmax.y() < p.y()) pmax.setY(p.y());
3134 if (pmax.z() < p.z()) pmax.setZ(p.z());
3137 G4int nx = (pmax.x() - pmin.
x())*invx + 1.5;
3138 G4int ny = (pmax.y() - pmin.
y())*invy + 1.5;
3139 G4int nz = (pmax.z() - pmin.
z())*invz + 1.5;
3141 std::vector<char> voxels(nx*ny*nz, 0);
3142 std::vector<G4int> indices((nx+1)*(ny+1)*(nz+1), 0);
3144 G4int kx = ny*nz, ky = nz;
3145 for (
const auto& p: positions)
3147 G4int ix = (p.x() - pmin.
x())*invx + 0.5;
3148 G4int iy = (p.y() - pmin.
y())*invy + 0.5;
3149 G4int iz = (p.z() - pmin.
z())*invz + 0.5;
3150 G4int i = ix*kx + iy*ky + iz;
3155 G4int kvx = (ny + 1)*(nz + 1), kvy = nz + 1;
3156 G4int nver = 0, nfac = 0;
3157 for (
const auto& p: positions)
3159 G4int ix = (p.x() - pmin.
x())*invx + 0.5;
3160 G4int iy = (p.y() - pmin.
y())*invy + 0.5;
3161 G4int iz = (p.z() - pmin.
z())*invz + 0.5;
3175 vcheck = (ix == 0) ? 0 : voxels[(ix-1)*kx + iy*ky + iz];
3179 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0);
3180 G4int i2 = (ix+0)*kvx + (iy+0)*kvy + (iz+1);
3181 G4int i3 = (ix+0)*kvx + (iy+1)*kvy + (iz+1);
3182 G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+0);
3183 if (indices[i1] == 0) indices[i1] = ++nver;
3184 if (indices[i2] == 0) indices[i2] = ++nver;
3185 if (indices[i3] == 0) indices[i3] = ++nver;
3186 if (indices[i4] == 0) indices[i4] = ++nver;
3189 vcheck = (ix == nx - 1) ? 0 : voxels[(ix+1)*kx + iy*ky + iz];
3193 G4int i1 = (ix+1)*kvx + (iy+1)*kvy + (iz+0);
3194 G4int i2 = (ix+1)*kvx + (iy+1)*kvy + (iz+1);
3195 G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1);
3196 G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0);
3197 if (indices[i1] == 0) indices[i1] = ++nver;
3198 if (indices[i2] == 0) indices[i2] = ++nver;
3199 if (indices[i3] == 0) indices[i3] = ++nver;
3200 if (indices[i4] == 0) indices[i4] = ++nver;
3203 vcheck = (iy == 0) ? 0 : voxels[ix*kx + (iy-1)*ky + iz];
3207 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0);
3208 G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+0);
3209 G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1);
3210 G4int i4 = (ix+0)*kvx + (iy+0)*kvy + (iz+1);
3211 if (indices[i1] == 0) indices[i1] = ++nver;
3212 if (indices[i2] == 0) indices[i2] = ++nver;
3213 if (indices[i3] == 0) indices[i3] = ++nver;
3214 if (indices[i4] == 0) indices[i4] = ++nver;
3217 vcheck = (iy == ny - 1) ? 0 : voxels[ix*kx + (iy+1)*ky + iz];
3221 G4int i1 = (ix+0)*kvx + (iy+1)*kvy + (iz+0);
3222 G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+1);
3223 G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1);
3224 G4int i4 = (ix+1)*kvx + (iy+1)*kvy + (iz+0);
3225 if (indices[i1] == 0) indices[i1] = ++nver;
3226 if (indices[i2] == 0) indices[i2] = ++nver;
3227 if (indices[i3] == 0) indices[i3] = ++nver;
3228 if (indices[i4] == 0) indices[i4] = ++nver;
3231 vcheck = (iz == 0) ? 0 : voxels[ix*kx + iy*ky + (iz-1)];
3235 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0);
3236 G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+0);
3237 G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+0);
3238 G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0);
3239 if (indices[i1] == 0) indices[i1] = ++nver;
3240 if (indices[i2] == 0) indices[i2] = ++nver;
3241 if (indices[i3] == 0) indices[i3] = ++nver;
3242 if (indices[i4] == 0) indices[i4] = ++nver;
3245 vcheck = (iz == nz - 1) ? 0 : voxels[ix*kx + iy*ky + (iz+1)];
3249 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+1);
3250 G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+1);
3251 G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1);
3252 G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+1);
3253 if (indices[i1] == 0) indices[i1] = ++nver;
3254 if (indices[i2] == 0) indices[i2] = ++nver;
3255 if (indices[i3] == 0) indices[i3] = ++nver;
3256 if (indices[i4] == 0) indices[i4] = ++nver;
3261 G4ThreeVector p0(pmin.
x() - 0.5*sizeX, pmin.
y() - 0.5*sizeY, pmin.
z() - 0.5*sizeZ);
3262 for (
G4int ix = 0; ix <= nx; ++ix)
3264 for (
G4int iy = 0; iy <= ny; ++iy)
3266 for (
G4int iz = 0; iz <= nz; ++iz)
3268 G4int i = ix*kvx + iy*kvy + iz;
3269 if (indices[i] == 0)
continue;
3275 for (
const auto& p: positions)
3277 G4int ix = (p.x() - pmin.
x())*invx + 0.5;
3278 G4int iy = (p.y() - pmin.
y())*invy + 0.5;
3279 G4int iz = (p.z() - pmin.
z())*invz + 0.5;
3282 vcheck = (ix == 0) ? 0 : voxels[(ix-1)*kx + iy*ky + iz];
3285 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0);
3286 G4int i2 = (ix+0)*kvx + (iy+0)*kvy + (iz+1);
3287 G4int i3 = (ix+0)*kvx + (iy+1)*kvy + (iz+1);
3288 G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+0);
3289 SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
3292 vcheck = (ix == nx - 1) ? 0 : voxels[(ix+1)*kx + iy*ky + iz];
3295 G4int i1 = (ix+1)*kvx + (iy+1)*kvy + (iz+0);
3296 G4int i2 = (ix+1)*kvx + (iy+1)*kvy + (iz+1);
3297 G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1);
3298 G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0);
3299 SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
3303 vcheck = (iy == 0) ? 0 : voxels[ix*kx + (iy-1)*ky + iz];
3306 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0);
3307 G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+0);
3308 G4int i3 = (ix+1)*kvx + (iy+0)*kvy + (iz+1);
3309 G4int i4 = (ix+0)*kvx + (iy+0)*kvy + (iz+1);
3310 SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
3313 vcheck = (iy == ny - 1) ? 0 : voxels[ix*kx + (iy+1)*ky + iz];
3316 G4int i1 = (ix+0)*kvx + (iy+1)*kvy + (iz+0);
3317 G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+1);
3318 G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1);
3319 G4int i4 = (ix+1)*kvx + (iy+1)*kvy + (iz+0);
3320 SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
3323 vcheck = (iz == 0) ? 0 : voxels[ix*kx + iy*ky + (iz-1)];
3326 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+0);
3327 G4int i2 = (ix+0)*kvx + (iy+1)*kvy + (iz+0);
3328 G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+0);
3329 G4int i4 = (ix+1)*kvx + (iy+0)*kvy + (iz+0);
3330 SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
3333 vcheck = (iz == nz - 1) ? 0 : voxels[ix*kx + iy*ky + (iz+1)];
3336 G4int i1 = (ix+0)*kvx + (iy+0)*kvy + (iz+1);
3337 G4int i2 = (ix+1)*kvx + (iy+0)*kvy + (iz+1);
3338 G4int i3 = (ix+1)*kvx + (iy+1)*kvy + (iz+1);
3339 G4int i4 = (ix+0)*kvx + (iy+1)*kvy + (iz+1);
3340 SetFacet(++nfac, indices[i1], indices[i2], indices[i3], indices[i4]);
3359#include "BooleanProcessor.src"
3372 BooleanProcessor processor;
3373 return processor.execute(OP_UNION, *
this, p,ierr);
3387 BooleanProcessor processor;
3388 return processor.execute(OP_INTERSECTION, *
this, p,ierr);
3402 BooleanProcessor processor;
3403 return processor.execute(OP_SUBTRACTION, *
this, p,ierr);
3411#include "HepPolyhedronProcessor.src"
const G4double kCarTolerance
G4double B(G4double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
HepGeom::Normal3D< G4double > G4Normal3D
HepGeom::Point3D< G4double > G4Point3D
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Vector3D< G4double > G4Vector3D
std::ostream & operator<<(std::ostream &ostr, const G4Facet &facet)
const G4double spatialTolerance
#define DEFAULT_NUMBER_OF_STEPS
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
BasicVector3D< T > cross(const BasicVector3D< T > &v) const
BasicVector3D< T > unit() const
void set(T x1, T y1, T z1)
T dot(const BasicVector3D< T > &v) const
~HepPolyhedronBoxMesh() override
HepPolyhedronBoxMesh(G4double sizeX, G4double sizeY, G4double sizeZ, const std::vector< G4ThreeVector > &positions)
HepPolyhedronBox(G4double Dx, G4double Dy, G4double Dz)
~HepPolyhedronBox() override
~HepPolyhedronCone() override
HepPolyhedronCone(G4double Rmn1, G4double Rmx1, G4double Rmn2, G4double Rmx2, G4double Dz)
~HepPolyhedronCons() override
HepPolyhedronCons(G4double Rmn1, G4double Rmx1, G4double Rmn2, G4double Rmx2, G4double Dz, G4double Phi1, G4double Dphi)
~HepPolyhedronEllipsoid() override
HepPolyhedronEllipsoid(G4double dx, G4double dy, G4double dz, G4double zcut1, G4double zcut2)
HepPolyhedronEllipticalCone(G4double dx, G4double dy, G4double z, G4double zcut1)
~HepPolyhedronEllipticalCone() override
HepPolyhedronHype(G4double r1, G4double r2, G4double tan1, G4double tan2, G4double halfZ)
~HepPolyhedronHype() override
~HepPolyhedronHyperbolicMirror() override
HepPolyhedronHyperbolicMirror(G4double a, G4double h, G4double r)
~HepPolyhedronPara() override
HepPolyhedronPara(G4double Dx, G4double Dy, G4double Dz, G4double Alpha, G4double Theta, G4double Phi)
~HepPolyhedronParaboloid() override
HepPolyhedronParaboloid(G4double r1, G4double r2, G4double dz, G4double Phi1, G4double Dphi)
~HepPolyhedronPcon() override
HepPolyhedronPcon(G4double phi, G4double dphi, G4int nz, const G4double *z, const G4double *rmin, const G4double *rmax)
~HepPolyhedronPgon() override
HepPolyhedronPgon(G4double phi, G4double dphi, G4int npdv, G4int nz, const G4double *z, const G4double *rmin, const G4double *rmax)
~HepPolyhedronSphere() override
HepPolyhedronSphere(G4double rmin, G4double rmax, G4double phi, G4double dphi, G4double the, G4double dthe)
~HepPolyhedronTetMesh() override
HepPolyhedronTetMesh(const std::vector< G4ThreeVector > &tetrahedra)
HepPolyhedronTet(const G4double p0[3], const G4double p1[3], const G4double p2[3], const G4double p3[3])
~HepPolyhedronTet() override
HepPolyhedronTorus(G4double rmin, G4double rmax, G4double rtor, G4double phi, G4double dphi)
~HepPolyhedronTorus() override
~HepPolyhedronTrap() override
HepPolyhedronTrap(G4double Dz, G4double Theta, G4double Phi, G4double Dy1, G4double Dx1, G4double Dx2, G4double Alp1, G4double Dy2, G4double Dx3, G4double Dx4, G4double Alp2)
HepPolyhedronTrd1(G4double Dx1, G4double Dx2, G4double Dy, G4double Dz)
~HepPolyhedronTrd1() override
HepPolyhedronTrd2(G4double Dx1, G4double Dx2, G4double Dy1, G4double Dy2, G4double Dz)
~HepPolyhedronTrd2() override
~HepPolyhedronTube() override
HepPolyhedronTube(G4double Rmin, G4double Rmax, G4double Dz)
HepPolyhedronTubs(G4double Rmin, G4double Rmax, G4double Dz, G4double Phi1, G4double Dphi)
~HepPolyhedronTubs() override
static void SetNumberOfRotationSteps(G4int n)
void RotateAroundZ(G4int nstep, G4double phi, G4double dphi, G4int np1, G4int np2, const G4double *z, G4double *r, G4int nodeVis, G4int edgeVis)
G4bool GetNextEdgeIndices(G4int &i1, G4int &i2, G4int &edgeFlag, G4int &iface1, G4int &iface2) const
G4Normal3D GetUnitNormal(G4int iFace) const
G4int createTwistedTrap(G4double Dz, const G4double xy1[][2], const G4double xy2[][2])
G4bool GetNextNormal(G4Normal3D &normal) const
HepPolyhedron & operator=(const HepPolyhedron &from)
G4Normal3D FindNodeNormal(G4int iFace, G4int iNode) const
static G4int GetNumberOfRotationSteps()
G4Normal3D GetNormal(G4int iFace) const
G4Point3D vertexUnweightedMean() const
G4int FindNeighbour(G4int iFace, G4int iNode, G4int iOrder) const
G4bool TriangulatePolygon(const std::vector< G4TwoVector > &polygon, std::vector< G4int > &result)
void SetVertex(G4int index, const G4Point3D &v)
void RotateContourAroundZ(G4int nstep, G4double phi, G4double dphi, const std::vector< G4TwoVector > &rz, G4int nodeVis, G4int edgeVis)
void SetFacet(G4int index, G4int iv1, G4int iv2, G4int iv3, G4int iv4=0)
G4Point3D GetVertex(G4int index) const
G4double GetSurfaceArea() const
HepPolyhedron subtract(const HepPolyhedron &p) const
G4bool GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const
void GetFacet(G4int iFace, G4int &n, G4int *iNodes, G4int *edgeFlags=nullptr, G4int *iFaces=nullptr) const
G4double GetVolume() const
HepPolyhedron intersect(const HepPolyhedron &p) const
HepPolyhedron & Transform(const G4Transform3D &t)
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
void AllocateMemory(G4int Nvert, G4int Nface)
G4bool GetNextUnitNormal(G4Normal3D &normal) const
static void ResetNumberOfRotationSteps()
G4bool CheckSnip(const std::vector< G4TwoVector > &contour, G4int a, G4int b, G4int c, G4int n, const G4int *V)
void RotateEdge(G4int k1, G4int k2, G4double r1, G4double r2, G4int v1, G4int v2, G4int vEdge, G4bool ifWholeCircle, G4int ns, G4int &kface)
static G4ThreadLocal G4int fNumberOfRotationSteps
G4bool GetNextVertexIndex(G4int &index, G4int &edgeFlag) const
G4bool GetNextFacet(G4int &n, G4Point3D *nodes, G4int *edgeFlags=nullptr, G4Normal3D *normals=nullptr) const
void JoinCoplanarFacets(G4double tolerance)
HepPolyhedron add(const HepPolyhedron &p) const
G4bool GetNextEdge(G4Point3D &p1, G4Point3D &p2, G4int &edgeFlag) const
void SetSideFacets(G4int ii[4], G4int vv[4], G4int *kk, G4double *r, G4double dphi, G4int ns, G4int &kface)