17#define perMillion 0.000001
18#define deg (M_PI/180.0)
24 return a < 0 ? -
a :
a;
27 return a < 0.0f ? -
a :
a;
37 setValue(v[0],v[1],v[2]);
41 setValue(v[0],v[1],v[2]);
45 return HVPoint3D(v1[0] + v2[0],v1[1] + v2[1],v1[2] + v2[2]);
120 for (
int k=0; k<4; k++) {
128 ostr <<
"Nverteces=" << ph.
m_nvert <<
", Nfacets=" << ph.
m_nface << std::endl;
130 for (i=1; i<=ph.
m_nvert; i++) {
131 ostr <<
"xyz(" << i <<
")="
132 << ph.
m_pV[i][0] <<
' ' << ph.
m_pV[i][1] <<
' ' << ph.
m_pV[i][2]
135 for (i=1; i<=ph.
m_nface; i++) {
136 ostr <<
"face(" << i <<
")=" << ph.
m_pF[i] << std::endl;
172 if (
this == &from)
return *
this;
201 for (i=0; i<4; i++) {
202 if (iNode ==
iabs(m_pF[iFace].m_edge[i].v))
break;
206 <<
"SbPolyhedron::FindNeighbour: face " << iFace
207 <<
" has no node " << iNode
213 if (m_pF[iFace].m_edge[i].v == 0) i = 2;
215 return (m_pF[iFace].m_edge[i].v > 0) ? 0 : m_pF[iFace].m_edge[i].f;
229 int k = iFace, iOrder = 1;
233 if (k == iFace)
break;
237 if (iOrder < 0)
break;
259 <<
"SbPolyhedron::SetNumberOfRotationSteps: attempt to set the\n"
260 <<
"number of steps per circle < " << nMin <<
"; forced to " << nMin
297 enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
299 m_pF[1] =
SbFacet(1,LEFT, 4,BACK, 3,RIGHT, 2,FRONT);
300 m_pF[2] =
SbFacet(5,TOP, 8,BACK, 4,BOTTOM, 1,FRONT);
301 m_pF[3] =
SbFacet(8,TOP, 7,RIGHT, 3,BOTTOM, 4,LEFT);
302 m_pF[4] =
SbFacet(7,TOP, 6,FRONT, 2,BOTTOM, 3,BACK);
303 m_pF[5] =
SbFacet(6,TOP, 5,LEFT, 1,BOTTOM, 2,RIGHT);
304 m_pF[6] =
SbFacet(5,FRONT, 6,RIGHT, 7,BACK, 8,LEFT);
308 int v1,
int v2,
int vEdge,
309 bool ifWholeCircle,
int ns,
int &kface)
329 if (r1 == 0. && r2 == 0)
return;
334 int ii1 = ifWholeCircle ? i1 : i1+ns;
335 int ii2 = ifWholeCircle ? i2 : i2+ns;
336 int vv = ifWholeCircle ? vEdge : 1;
341 }
else if (r2 == 0.) {
344 m_pF[kface++] =
SbFacet(i1,0, v2*i2,0, (i2+1),0, v1*(i1+1),0);
348 m_pF[kface++] =
SbFacet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0);
349 for (i2++,i=1; i<ns-1; i2++,i++) {
350 m_pF[kface++] =
SbFacet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0);
352 m_pF[kface++] =
SbFacet(vEdge*i1,0, v2*i2,0, vv*ii2,0);
353 }
else if (r2 == 0.) {
354 m_pF[kface++] =
SbFacet(vv*i1,0, vEdge*i2,0, v1*(i1+1),0);
355 for (i1++,i=1; i<ns-1; i1++,i++) {
356 m_pF[kface++] =
SbFacet(vEdge*i1,0, vEdge*i2,0, v1*(i1+1),0);
358 m_pF[kface++] =
SbFacet(vEdge*i1,0, vv*i2,0, v1*ii1,0);
360 m_pF[kface++] =
SbFacet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
361 for (i1++,i2++,i=1; i<ns-1; i1++,i2++,i++) {
362 m_pF[kface++] =
SbFacet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
364 m_pF[kface++] =
SbFacet(vEdge*i1,0, v2*i2,0, vv*ii2,0, v1*ii1,0);
371 double dphi,
int ns,
int &kface)
391 for (
int i=0; i<4; i++) {
393 k2 = (i == 3) ? ii[0] : ii[i+1];
394 if (
r[k1] == 0. &&
r[k2] == 0.) vv[i] = -1;
398 if (ii[1] == ii[2]) {
402 m_pF[kface++] =
SbFacet(vv[0]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
403 if (
r[ii[0]] != 0.) k1 += ns;
404 if (
r[ii[2]] != 0.) k2 += ns;
405 if (
r[ii[3]] != 0.) k3 += ns;
406 m_pF[kface++] =
SbFacet(vv[2]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
407 }
else if (kk[ii[0]] == kk[ii[1]]) {
411 m_pF[kface++] =
SbFacet(vv[1]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
412 if (
r[ii[0]] != 0.) k1 += ns;
413 if (
r[ii[2]] != 0.) k2 += ns;
414 if (
r[ii[3]] != 0.) k3 += ns;
415 m_pF[kface++] =
SbFacet(vv[2]*k3,0, vv[1]*k2,0, vv[3]*k1,0);
416 }
else if (kk[ii[2]] == kk[ii[3]]) {
420 m_pF[kface++] =
SbFacet(vv[0]*k1,0, vv[1]*k2,0, vv[3]*k3,0);
421 if (
r[ii[0]] != 0.) k1 += ns;
422 if (
r[ii[1]] != 0.) k2 += ns;
423 if (
r[ii[2]] != 0.) k3 += ns;
424 m_pF[kface++] =
SbFacet(vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
430 m_pF[kface++] =
SbFacet(vv[0]*k1,0, vv[1]*k2,0, vv[2]*k3,0, vv[3]*k4,0);
431 if (
r[ii[0]] != 0.) k1 += ns;
432 if (
r[ii[1]] != 0.) k2 += ns;
433 if (
r[ii[2]] != 0.) k3 += ns;
434 if (
r[ii[3]] != 0.) k4 += ns;
435 m_pF[kface++] =
SbFacet(vv[2]*k4,0, vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
441 const double *
z,
double *
r,
442 int nodeVis,
int edgeVis)
465 static double wholeCircle = 2*
M_PI;
469 bool ifWholeCircle = (fabs(dphi-wholeCircle) <
perMillion) ?
471 double delPhi = ifWholeCircle ? wholeCircle : dphi;
472 int nSphi = (nstep > 0) ?
474 if (nSphi == 0) nSphi = 1;
475 int nVphi = ifWholeCircle ? nSphi : nSphi+1;
476 bool ifClosed = np1 > 0 ? false :
true;
480 int absNp1 =
iabs(np1);
481 int absNp2 =
iabs(np2);
483 int i1end = absNp1-1;
485 int i2end = absNp1+absNp2-1;
488 for(i=i1beg; i<=i2end; i++) {
493 for (i=i1beg; i<=i1end; i++) {
494 j += (
r[i] == 0.) ? 1 : nVphi;
497 bool ifSide1 =
false;
498 bool ifSide2 =
false;
500 if (
r[i2beg] !=
r[i1beg] ||
z[i2beg] !=
z[i1beg]) {
501 j += (
r[i2beg] == 0.) ? 1 : nVphi;
505 for(i=i2beg+1; i<i2end; i++) {
506 j += (
r[i] == 0.) ? 1 : nVphi;
509 if (
r[i2end] !=
r[i1end] ||
z[i2end] !=
z[i1end]) {
510 if (absNp2 > 1) j += (
r[i2end] == 0.) ? 1 : nVphi;
516 k = ifClosed ? absNp1*nSphi : (absNp1-1)*nSphi;
519 for(i=i2beg; i<i2end; i++) {
520 if (
r[i] > 0. ||
r[i+1] > 0.) k += nSphi;
524 if (
r[i2end] > 0. ||
r[i2beg] > 0.) k += nSphi;
529 if (ifSide1 && (
r[i1beg] > 0. ||
r[i2beg] > 0.)) k += nSphi;
530 if (ifSide2 && (
r[i1end] > 0. ||
r[i2end] > 0.)) k += nSphi;
533 if (!ifWholeCircle) {
534 k += ifClosed ? 2*absNp1 : 2*(absNp1-1);
544 kk =
new int[absNp1+absNp2];
547 for(i=i1beg; i<=i1end; i++) {
549 if (
r[i] == 0.) {
m_pV[k++] =
HVPoint3D(0, 0,
z[i]); }
else { k += nVphi; }
555 if (
r[i] == 0.) {
m_pV[k++] =
HVPoint3D(0, 0,
z[i]); }
else { k += nVphi; }
560 for(i=i2beg+1; i<i2end; i++) {
562 if (
r[i] == 0.) {
m_pV[k++] =
HVPoint3D(0, 0,
z[i]); }
else { k += nVphi; }
575 double cosPhi, sinPhi;
577 for(j=0; j<nVphi; j++) {
578 cosPhi = cos(
phi+j*delPhi/nSphi);
579 sinPhi = sin(
phi+j*delPhi/nSphi);
580 for(i=i1beg; i<=i2end; i++) {
590 v2 = ifClosed ? nodeVis : 1;
591 for(i=i1beg; i<i1end; i++) {
593 if (!ifClosed && i == i1end-1) {
596 v2 = (
r[i] ==
r[i+1] &&
r[i+1] ==
r[i+2]) ? -1 : nodeVis;
599 edgeVis, ifWholeCircle, nSphi, k);
602 RotateEdge(kk[i1end], kk[i1beg],
r[i1end],
r[i1beg], nodeVis, nodeVis,
603 edgeVis, ifWholeCircle, nSphi, k);
609 v2 = ifClosed ? nodeVis : 1;
610 for(i=i2beg; i<i2end; i++) {
612 if (!ifClosed && i==i2end-1) {
615 v2 = (
r[i] ==
r[i+1] &&
r[i+1] ==
r[i+2]) ? -1 : nodeVis;
618 edgeVis, ifWholeCircle, nSphi, k);
621 RotateEdge(kk[i2beg], kk[i2end],
r[i2beg],
r[i2end], nodeVis, nodeVis,
622 edgeVis, ifWholeCircle, nSphi, k);
630 RotateEdge(kk[i2beg], kk[i1beg],
r[i2beg],
r[i1beg], 1, 1,
631 -1, ifWholeCircle, nSphi, k);
634 RotateEdge(kk[i1end], kk[i2end],
r[i1end],
r[i2end], 1, 1,
635 -1, ifWholeCircle, nSphi, k);
641 if (!ifWholeCircle) {
646 for (i=i1beg; i<=i1end; i++) {
648 ii[3] = (i == i1end) ? i1beg : i+1;
649 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
650 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
658 for (i=i1beg; i<i1end; i++) {
661 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
662 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
663 vv[0] = (i == i1beg) ? 1 : -1;
665 vv[2] = (i == i1end-1) ? 1 : -1;
676 <<
"Polyhedron::RotateAroundZ: number of generated faces ("
677 << k-1 <<
") is not equal to the number of allocated faces ("
695 struct edgeListMember {
696 edgeListMember *next;
700 } *edgeList, *freeList, **headList;
705 edgeList =
new edgeListMember[2*
m_nface];
706 headList =
new edgeListMember*[
m_nvert];
713 for (i=0; i<2*
m_nface-1; i++) {
714 edgeList[i].next = &edgeList[i+1];
716 edgeList[2*
m_nface-1].next = 0;
720 int iface, iedge, nedge, i1, i2, k1, k2;
721 edgeListMember *prev, *cur;
723 for(iface=1; iface<=
m_nface; iface++) {
724 nedge = (
m_pF[iface].m_edge[3].v == 0) ? 3 : 4;
725 for (iedge=0; iedge<nedge; iedge++) {
727 i2 = (iedge < nedge-1) ? iedge+1 : 0;
728 i1 =
iabs(
m_pF[iface].m_edge[i1].v);
729 i2 =
iabs(
m_pF[iface].m_edge[i2].v);
730 k1 = (i1 < i2) ? i1 : i2;
731 k2 = (i1 > i2) ? i1 : i2;
736 headList[k1] = freeList;
737 freeList = freeList->next;
747 headList[k1] = cur->next;
748 cur->next = freeList;
750 m_pF[iface].m_edge[iedge].f = cur->iface;
751 m_pF[cur->iface].m_edge[cur->iedge].f = iface;
752 i1 = (
m_pF[iface].m_edge[iedge].v < 0) ? -1 : 1;
753 i2 = (
m_pF[cur->iface].m_edge[cur->iedge].v < 0) ? -1 : 1;
756 <<
"Polyhedron::SetReferences: different edge visibility "
757 << iface <<
"/" << iedge <<
"/"
758 <<
m_pF[iface].m_edge[iedge].v <<
" and "
759 << cur->iface <<
"/" << cur->iedge <<
"/"
760 <<
m_pF[cur->iface].m_edge[cur->iedge].v
771 prev->next = freeList;
772 freeList = freeList->next;
782 prev->next = cur->next;
783 cur->next = freeList;
785 m_pF[iface].m_edge[iedge].f = cur->iface;
786 m_pF[cur->iface].m_edge[cur->iedge].f = iface;
787 i1 = (
m_pF[iface].m_edge[iedge].v < 0) ? -1 : 1;
788 i2 = (
m_pF[cur->iface].m_edge[cur->iedge].v < 0) ? -1 : 1;
791 <<
"Polyhedron::SetReferences: different edge visibility "
792 << iface <<
"/" << iedge <<
"/"
793 <<
m_pF[iface].m_edge[iedge].v <<
" and "
794 << cur->iface <<
"/" << cur->iedge <<
"/"
795 <<
m_pF[cur->iface].m_edge[cur->iedge].v
807 if (headList[i] != 0) {
809 <<
"Polyhedron::SetReferences: List " << i <<
" is not empty"
831 int i, k, nnode, v[4],f[4];
833 nnode = (
m_pF[i].m_edge[3].v == 0) ? 3 : 4;
834 for (k=0; k<nnode; k++) {
835 v[k] = (k+1 == nnode) ?
m_pF[i].m_edge[0].v :
m_pF[i].m_edge[k+1].v;
836 if (v[k] *
m_pF[i].m_edge[k].v < 0) v[k] = -v[k];
837 f[k] =
m_pF[i].m_edge[k].f;
839 for (k=0; k<nnode; k++) {
840 m_pF[i].m_edge[nnode-1-k].v = v[k];
841 m_pF[i].m_edge[nnode-1-k].f = f[k];
881,
const SbVec3d& translation
886 for (
int i=1; i<=
m_nvert; i++) {
887 rotation.multVec(
m_pV[i],tmp);
888 m_pV[i] = tmp+translation;
890 SbVec3d
x; rotation.multVec(SbVec3d(1,0,0),
x);
891 SbVec3d
y; rotation.multVec(SbVec3d(0,1,0),
y);
892 SbVec3d
z; rotation.multVec(SbVec3d(0,0,1),
z);
913 static int iFace = 1;
914 static int iQVertex = 0;
915 int vIndex =
m_pF[iFace].m_edge[iQVertex].v;
917 edgeFlag = (vIndex > 0) ? 1 : 0;
920 if (iQVertex >= 3 ||
m_pF[iFace].m_edge[iQVertex+1].v == 0) {
922 if (++iFace >
m_nface) iFace = 1;
940 if (index <= 0 || index >
m_nvert) {
942 <<
"SbPolyhedron::GetVertex: irrelevant index " <<
index
989 static int iFace = 1;
990 static int iNode = 0;
992 if (
m_nface == 0)
return false;
994 int k =
m_pF[iFace].m_edge[iNode].v;
995 if (k > 0) { edgeFlag = 1; }
else { edgeFlag = -1; k = -k; }
998 if (iNode >= 3 ||
m_pF[iFace].m_edge[iNode+1].v == 0) {
1000 if (++iFace >
m_nface) iFace = 1;
1009 int &iface1,
int &iface2)
const
1021 static int iFace = 1;
1022 static int iQVertex = 0;
1023 static int iOrder = 1;
1024 int k1, k2, kflag, kface1, kface2;
1026 if (iFace == 1 && iQVertex == 0) {
1030 if (
iabs(k1) >
iabs(k2)) iOrder = -1;
1034 k1 =
m_pF[iFace].m_edge[iQVertex].v;
1038 kface2 =
m_pF[iFace].m_edge[iQVertex].f;
1039 if (iQVertex >= 3 ||
m_pF[iFace].m_edge[iQVertex+1].v == 0) {
1041 k2 =
iabs(
m_pF[iFace].m_edge[iQVertex].v);
1045 k2 =
iabs(
m_pF[iFace].m_edge[iQVertex].v);
1047 }
while (iOrder*k1 > iOrder*k2);
1049 i1 = k1; i2 = k2; edgeFlag = (kflag > 0) ? 1 : 0;
1050 iface1 = kface1; iface2 = kface2;
1053 iFace = 1; iOrder = 1;
1079 int &edgeFlag)
const
1099 int &edgeFlag,
int &iface1,
int &iface2)
const
1119 int *edgeFlags,
int *iFaces)
const
1129 if (iFace < 1 || iFace >
m_nface) {
1131 <<
"SbPolyhedron::GetFacet: irrelevant index " << iFace
1136 for (i=0; i<4; i++) {
1137 k =
m_pF[iFace].m_edge[i].v;
1139 if (iFaces != 0) iFaces[i] =
m_pF[iFace].m_edge[i].f;
1142 if (edgeFlags != 0) edgeFlags[i] = 1;
1145 if (edgeFlags != 0) edgeFlags[i] = -1;
1166 for (
int i=0; i<4; i++) {
1167 nodes[i] =
m_pV[iNodes[i]];
1186 static int iFace = 1;
1188 if (edgeFlags == 0) {
1190 }
else if (normals == 0) {
1191 GetFacet(iFace, n, nodes, edgeFlags);
1193 GetFacet(iFace, n, nodes, edgeFlags, normals);
1214 if (iFace < 1 || iFace >
m_nface) {
1216 <<
"SbPolyhedron::GetNormal: irrelevant index " << iFace
1221 int i0 =
iabs(
m_pF[iFace].m_edge[0].v);
1222 int i1 =
iabs(
m_pF[iFace].m_edge[1].v);
1223 int i2 =
iabs(
m_pF[iFace].m_edge[2].v);
1224 int i3 =
iabs(
m_pF[iFace].m_edge[3].v);
1225 if (i3 == 0) i3 = i0;
1239 if (iFace < 1 || iFace >
m_nface) {
1241 <<
"SbPolyhedron::GetUnitNormal: irrelevant index " << iFace
1246 int i0 =
iabs(
m_pF[iFace].m_edge[0].v);
1247 int i1 =
iabs(
m_pF[iFace].m_edge[1].v);
1248 int i2 =
iabs(
m_pF[iFace].m_edge[2].v);
1249 int i3 =
iabs(
m_pF[iFace].m_edge[3].v);
1250 if (i3 == 0) i3 = i0;
1267 static int iFace = 1;
1304 for (
int iFace=1; iFace<=
m_nface; iFace++) {
1305 int i0 =
iabs(
m_pF[iFace].m_edge[0].v);
1306 int i1 =
iabs(
m_pF[iFace].m_edge[1].v);
1307 int i2 =
iabs(
m_pF[iFace].m_edge[2].v);
1308 int i3 =
iabs(
m_pF[iFace].m_edge[3].v);
1309 if (i3 == 0) i3 = i0;
1326 for (
int iFace=1; iFace<=
m_nface; iFace++) {
1327 int i0 =
iabs(
m_pF[iFace].m_edge[0].v);
1328 int i1 =
iabs(
m_pF[iFace].m_edge[1].v);
1329 int i2 =
iabs(
m_pF[iFace].m_edge[2].v);
1330 int i3 =
iabs(
m_pF[iFace].m_edge[3].v);
1344 double Dy1,
double Dy2,
1378 double Dy,
double Dz)
1422 double DzTthetaCphi = Dz*tan(Theta)*cos(Phi);
1423 double DzTthetaSphi = Dz*tan(Theta)*sin(Phi);
1424 double Dy1Talp1 = Dy1*tan(Alp1);
1425 double Dy2Talp2 = Dy2*tan(Alp2);
1429 m_pV[1] =
HVPoint3D(-DzTthetaCphi-Dy1Talp1-Dx1,-DzTthetaSphi-Dy1,-Dz);
1430 m_pV[2] =
HVPoint3D(-DzTthetaCphi-Dy1Talp1+Dx1,-DzTthetaSphi-Dy1,-Dz);
1431 m_pV[3] =
HVPoint3D(-DzTthetaCphi+Dy1Talp1+Dx2,-DzTthetaSphi+Dy1,-Dz);
1432 m_pV[4] =
HVPoint3D(-DzTthetaCphi+Dy1Talp1-Dx2,-DzTthetaSphi+Dy1,-Dz);
1433 m_pV[5] =
HVPoint3D( DzTthetaCphi-Dy2Talp2-Dx3, DzTthetaSphi-Dy2, Dz);
1434 m_pV[6] =
HVPoint3D( DzTthetaCphi-Dy2Talp2+Dx3, DzTthetaSphi-Dy2, Dz);
1435 m_pV[7] =
HVPoint3D( DzTthetaCphi+Dy2Talp2+Dx4, DzTthetaSphi+Dy2, Dz);
1436 m_pV[8] =
HVPoint3D( DzTthetaCphi+Dy2Talp2-Dx4, DzTthetaSphi+Dy2, Dz);
1444 double Alpha,
double Theta,
1446 :
SbPolyhedronTrap(Dz, Theta, Phi, Dy, Dx, Dx, Alpha, Dy, Dx, Dx, Alpha) {}
1472 static double wholeCircle=2*
M_PI;
1477 if (Rmn1 < 0. || Rmx1 < 0. || Rmn2 < 0. || Rmx2 < 0.) k = 1;
1478 if (Rmn1 > Rmx1 || Rmn2 > Rmx2) k = 1;
1479 if (Rmn1 == Rmx1 && Rmn2 == Rmx2) k = 1;
1482 if (Dz == 0)
return;
1484 if (Dz < 0.) k += 2;
1486 double phi1, phi2, dphi;
1488 phi2 = Phi1; phi1 = phi2 - Dphi;
1489 }
else if (Dphi == 0.) {
1490 phi1 = Phi1; phi2 = phi1 + wholeCircle;
1492 phi1 = Phi1; phi2 = phi1 + Dphi;
1495 if (fabs(dphi-wholeCircle) <
perMillion) dphi = wholeCircle;
1496 if (dphi > wholeCircle) k += 4;
1499 std::cerr <<
"SbPolyhedronCone(s)/Tube(s): error in input parameters";
1500 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1501 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1502 if ((k & 4) != 0) std::cerr <<
" (angles)";
1503 std::cerr << std::endl;
1504 std::cerr <<
" Rmn1=" << Rmn1 <<
" Rmx1=" << Rmx1;
1505 std::cerr <<
" Rmn2=" << Rmn2 <<
" Rmx2=" << Rmx2;
1506 std::cerr <<
" Dz=" << Dz <<
" Phi1=" << Phi1 <<
" Dphi=" << Dphi
1513 double zz[4],
rr[4];
1532 double Rmn2,
double Rmx2,
1540 double Phi1,
double Dphi)
1577 if (dphi <= 0. || dphi > 2*
M_PI) {
1579 <<
"SbPolyhedronPgon/Pcon: wrong delta phi = " << dphi
1586 <<
"SbPolyhedronPgon/Pcon: number of z-planes less than two = " << nz
1593 <<
"SbPolyhedronPgon/Pcon: error in number of phi-steps =" << npdv
1599 for (i=0; i<nz; i++) {
1600 if (rmin[i] < 0. || rmax[i] < 0. || rmin[i] > rmax[i]) {
1602 <<
"SbPolyhedronPgon: error in radiuses rmin[" << i <<
"]="
1603 << rmin[i] <<
" rmax[" << i <<
"]=" << rmax[i]
1612 zz =
new double[2*nz];
1613 rr =
new double[2*nz];
1615 if (
z[0] >
z[nz-1]) {
1616 for (i=0; i<nz; i++) {
1623 for (i=0; i<nz; i++) {
1625 rr[i] = rmax[nz-i-1];
1626 zz[i+nz] =
z[nz-i-1];
1627 rr[i+nz] = rmin[nz-i-1];
1651 double phi,
double dphi,
1652 double the,
double dthe)
1671 if (dphi <= 0. || dphi > 2*
M_PI) {
1673 <<
"SbPolyhedronSphere: wrong delta phi = " << dphi
1678 if (the < 0. || the >
M_PI) {
1680 <<
"SbPolyhedronSphere: wrong theta = " << the
1685 if (dthe <= 0. || dthe >
M_PI) {
1687 <<
"SbPolyhedronSphere: wrong delta theta = " << dthe
1692 if ( (the+dthe >=
M_PI) && (the+dthe <
M_PI + 2*DBL_EPSILON) )
1695 if (the+dthe >
M_PI) {
1697 <<
"SbPolyhedronSphere: wrong theta + delta theta = "
1698 << the <<
" " << dthe
1703 if (rmin < 0. || rmin >= rmax) {
1705 <<
"SbPolyhedronSphere: error in radiuses"
1706 <<
" rmin=" << rmin <<
" rmax=" << rmax
1714 int np1 = int(dthe*ns/
M_PI+.5) + 1;
1715 if (np1 <= 1) np1 = 2;
1719 zz =
new double[np1+np2];
1720 rr =
new double[np1+np2];
1722 double a = dthe/(np1-1);
1724 for (
int i=0; i<np1; i++) {
1725 cosa = cos(the+i*
a);
1726 sina = sin(the+i*
a);
1730 zz[i+np1] = rmin*cosa;
1731 rr[i+np1] = rmin*sina;
1772 if (dphi <= 0. || dphi > 2*
M_PI) {
1774 <<
"SbPolyhedronTorus: wrong delta phi = " << dphi
1779 if (rmin < 0. || rmin >= rmax || rmax >= rtor) {
1781 <<
"SbPolyhedronTorus: error in radiuses"
1782 <<
" rmin=" << rmin <<
" rmax=" << rmax <<
" rtorus=" << rtor
1793 const auto totNumPts = np1+np2;
1794 auto zz =
new double[totNumPts]{};
1795 auto rr =
new double[totNumPts]{};
1796 for (
unsigned int i(0);i!=(
unsigned int) totNumPts;++i){
1801 double a = 2*
M_PI/np1;
1803 for (
int i=0; i<np1; i++) {
1807 rr[i] = rtor+rmax*sina;
1809 zz[i+np1] = rmin*cosa;
1810 rr[i+np1] = rtor+rmin*sina;
1919 void setData(
const std::vector<double> * xx,
const std::vector<double>* yy,
const double&
dz);
1927 const std::vector<double> *
x;
1928 const std::vector<double> *
y;
1934 std::unique_ptr<PolygonTriangulator>
poly;
1947 bool isinternaledge(
const Edge& edge,
const std::map<
Edge,std::vector<Triangles::const_iterator> >& edge2triangles_map)
const;
1949 void setupface(
const unsigned& face_id,
const std::vector<unsigned>&v)
const;
1950 void setupExternalFace(
const unsigned& id_extedge,
const unsigned& prev_edgeface,
const unsigned& next_edgeface,
1951 const unsigned& idfirstvertex,
const unsigned& idsecondvertex,
1952 const unsigned& id_triangleface,
const unsigned&
n, std::vector<unsigned>& faceinfo)
const;
1954 void getSurroundingValues(
const std::vector<unsigned>& numbercycle,
const unsigned& centralValue,
1955 unsigned& prevValue,
unsigned& nextValue)
const;
1986 assert (
n==yy->size()&&
n>2);
1996 poly = std::make_unique<PolygonTriangulator>(*
x,*
y);
2006 std::map<Edge,std::vector<PolygonTriangulator::Triangles::const_iterator> > edge2triangles_map;
2007 std::set<Edge> alledges;
2008 Triangles::const_iterator itt=
poly->triangles()->begin();
2009 Triangles::const_iterator ittE=
poly->triangles()->end();
2010 for(; itt!=ittE; ++itt)
2011 for (
unsigned iedge=0;iedge<3;++iedge) {
2013 if (edge2triangles_map.find(eun)==edge2triangles_map.end()) {
2014 alledges.insert(eun);
2016 edge2triangles_map[eun].push_back(itt);
2021 std::set<Edge>::const_iterator itedges = alledges.begin();
2022 std::set<Edge>::const_iterator itedgesE = alledges.end();
2023 for (;itedges!=itedgesE;++itedges) {
2031 itt=
poly->triangles()->begin();
2032 for(; itt!=ittE; ++itt)
2033 for (
unsigned iedge=0;iedge<3;++iedge) {
2036 assert(edge2triangles_map.find(eun)!=edge2triangles_map.end());
2041 assert(edge2triangles_map[eun].size()==2);
2043 const Triangle* triangle1 =
static_cast<const Triangle*
>( &(*(edge2triangles_map[eun].front())) );
2044 const Triangle* triangle2 =
static_cast<const Triangle*
>( &(*(edge2triangles_map[eun].back())) );
2045 neighbourmap[e]=(triangle==triangle1?triangle2:triangle1);
2063 std::set<const Triangle*> triangles_with_extra_vertex;
2066 Triangles::const_iterator itt=
poly->triangles()->begin();
2067 Triangles::const_iterator ittE=
poly->triangles()->end();
2068 for(; itt!=ittE; ++itt) {
2069 unsigned ninternaledges(0);
2070 for (
unsigned iedge=0;iedge<3;++iedge) {
2075 if (ninternaledges<3)
2081 for (;iedge<3;++iedge) {
2084 assert(trneighbour);
2085 if (triangles_with_extra_vertex.insert(trneighbour).second) {
2086 triangles_with_extra_vertex.insert(&(*itt));
2097 itt=
poly->triangles()->begin();
2098 for(; itt!=ittE; ++itt) {
2100 if (triangles_with_extra_vertex.find(triangle)!=triangles_with_extra_vertex.end())
2102 for (
unsigned iedge=0;iedge<3;++iedge) {
2108 triangles_with_extra_vertex.insert(triangle);
2114 assert(
ntriangles==triangles_with_extra_vertex.size());
2130 unsigned ielev = 3*
n-4;
2131 for (;itl!=itlE;++itl) {
2140 for (
unsigned i = 0; i<
n; ++i)
2143 for (
unsigned i = 0; i<
n; ++i)
2148 for (; itlid!=itlidE; ++itlid) {
2149 double xx = 0.5*(
x->at(itlid->first.first-1)+
x->at(itlid->first.second-1));
2150 double yy = 0.5*(
y->at(itlid->first.first-1)+
y->at(itlid->first.second-1));
2155 for (; itlid!=itlidE; ++itlid) {
2156 double xx = 0.5*(
x->at(itlid->first.first-1)+
x->at(itlid->first.second-1));
2157 double yy = 0.5*(
y->at(itlid->first.first-1)+
y->at(itlid->first.second-1));
2165 const std::map<
Edge,std::vector<Triangles::const_iterator> >& edge2triangles_map)
const {
2167 Edge reverse_edge(edge.second,edge.first);
2169 std::map<Edge,std::vector<Triangles::const_iterator> >
::const_iterator it = edge2triangles_map.find(edge);
2170 if (it!=edge2triangles_map.end()) k += it->second.size();
2171 it = edge2triangles_map.find(reverse_edge);
2172 if (it!=edge2triangles_map.end()) k += it->second.size();
2181 return oriented ?
Edge((*tr)[2],(*tr)[0]) :
Edge((*tr)[0],(*tr)[2]);
2183 return Edge((*tr)[i],(*tr)[i+1]);
2188 assert(v.size()==8);
2189 sbpolyhedron->m_pF[face_id] =
SbFacet(v.at(0),v.at(1),v.at(2),v.at(3),v.at(4),v.at(5),v.at(6),v.at(7));
2195 const unsigned& idfirstvertex,
const unsigned& idsecondvertex,
2196 const unsigned& id_triangleface,
const unsigned&
n, std::vector<unsigned>& faceinfo)
const {
2198 faceinfo.push_back(idfirstvertex);
2199 faceinfo.push_back(prev_edgeface);
2201 faceinfo.push_back(id_triangleface+
n-2);
2203 faceinfo.push_back(next_edgeface);
2204 faceinfo.push_back(idsecondvertex);
2205 faceinfo.push_back(id_triangleface);
2212 unsigned& prevValue,
unsigned& nextValue)
const
2216 for ( i=0;i<numbercycle.size();++i)
2217 if (numbercycle.at(i)==centralValue)
2220 assert(i<numbercycle.size());
2221 prevValue = ( i==0 ? numbercycle.back() : numbercycle.at(i-1) );
2222 nextValue = ( i==numbercycle.size()-1 ? numbercycle.front() : numbercycle.at(i+1) );
2247 std::map<const Triangle*,unsigned> triangle_2_id;
2248 Triangles::const_iterator itt=
poly->triangles()->begin();
2249 Triangles::const_iterator ittE=
poly->triangles()->end();
2251 for(; itt!=ittE; ++itt) {
2253 triangle_2_id[triangle]=++itri;
2258 std::vector<unsigned> edgeface_ids;
2259 std::map<Edge,unsigned> edge_2_firstid;
2260 std::map<Edge,unsigned> edge_2_secondid;
2261 for (
unsigned i = 1; i<=
n;++i) {
2262 Edge eun((i==
n?1:i),(i==
n?
n:i+1));
2263 edgeface_ids.push_back(2*
n-4+i);
2264 edge_2_firstid[eun]=edgeface_ids.back();
2265 bool hasextravertex=
2267 if (hasextravertex) {
2269 edge_2_secondid[eun]=edgeface_ids.back();
2273 std::vector<unsigned> faceinfo_top, faceinfo_bottom(8), faceinfo_sides;
2274 itt =
poly->triangles()->begin();
2275 for(; itt!=ittE; ++itt) {
2276 unsigned triangleid = triangle_2_id[&(*itt)];
2279 for (
unsigned iedge=0;iedge<3;++iedge) {
2286 faceinfo_top.push_back(e.first);
2289 assert(triangle_2_id.find(
neighbourmap[e])!=triangle_2_id.end());
2290 faceinfo_top.push_back(triangle_2_id[
neighbourmap[e]]);
2291 if (hasextravertex) {
2293 faceinfo_top.push_back(triangle_2_id[
neighbourmap[e]]);
2298 assert(edge_2_firstid.find(eun)!=edge_2_firstid.end());
2299 unsigned firstsideid = edge_2_firstid[eun];
2300 faceinfo_top.push_back(firstsideid);
2301 if (hasextravertex) {
2303 assert(edge_2_secondid.find(eun)!=edge_2_secondid.end());
2304 faceinfo_top.push_back(edge_2_secondid[eun]);
2307 unsigned prev_edgeface,next_edgeface;
2309 unsigned firstvertexid = e.first;
2311 setupExternalFace(firstsideid,prev_edgeface, next_edgeface,firstvertexid,secondvertexid,
2313 triangleid,
n,faceinfo_sides);
2314 if (hasextravertex) {
2315 firstsideid=next_edgeface;
2317 firstvertexid=secondvertexid;
2318 secondvertexid=e.second;
2322 triangleid,
n,faceinfo_sides);
2329 assert(faceinfo_bottom.size()==8);
2330 assert(faceinfo_top.size()==8);
2343 faceinfo_top.clear();
2368 std::cerr <<
"ERROR in SbPolyhedronArbitrary::AddVertex. Attempt to exceed maximum number of vertices: "
2380 std::cerr <<
"ERROR in SbPolyhedronArbitrary::AddFacet. Attempt to exceed maximum number of facets: "
2390 std::cerr <<
"ERROR in SbPolyhedronArbitrary::AddFacet. Attempt to index vertex number which is out-of-range: ("
2391 << iv1 <<
"," << iv2 <<
"," << iv3 <<
"," << iv4 <<
")" << std::endl;
2397 std::cerr <<
"ERROR in SbPolyhedronArbitrary::AddFacet. Vertex needs to be defined first : ("
2398 << iv1 <<
"," << iv2 <<
"," << iv3 <<
"," << iv4 <<
")" << std::endl;
2415 m_pV[1] =
HVPoint3D(Vertices[0].first,Vertices[0].second,-Dz);
2416 m_pV[2] =
HVPoint3D(Vertices[1].first,Vertices[1].second,-Dz);
2417 m_pV[3] =
HVPoint3D(Vertices[2].first,Vertices[2].second,-Dz);
2418 m_pV[4] =
HVPoint3D(Vertices[3].first,Vertices[3].second,-Dz);
2419 m_pV[5] =
HVPoint3D(Vertices[4].first,Vertices[4].second,Dz);
2420 m_pV[6] =
HVPoint3D(Vertices[5].first,Vertices[5].second,Dz);
2421 m_pV[7] =
HVPoint3D(Vertices[6].first,Vertices[6].second,Dz);
2422 m_pV[8] =
HVPoint3D(Vertices[7].first,Vertices[7].second,Dz);
const boost::regex rr(r_r)
Scalar phi() const
phi method
HVPoint3D operator+(const HVPoint3D &v1, const HVPoint3D &v2)
static HEPVis_BooleanProcessor processor
std::ostream & operator<<(std::ostream &ostr, const SbFacet &facet)
#define DEFAULT_NUMBER_OF_STEPS
HVPoint3D & operator=(const HVPoint3D &v)
std::list< Triangle > Triangles
std::vector< unsigned > Triangle
SbFacet(int v1=0, int f1=0, int v2=0, int f2=0, int v3=0, int f3=0, int v4=0, int f4=0)
struct SbFacet::@146305307241173307306147201343177135163056232201 m_edge[4]
SbPolyhedronArbitrary(const int nVertices, const int nFacets)
void AddFacet(const int iv1, const int iv2, const int iv3, const int iv4=0)
void AddVertex(const double v1, const double v2, const double v3)
virtual ~SbPolyhedronArbitrary()
SbPolyhedronBox(double Dx, double Dy, double Dz)
virtual ~SbPolyhedronBox()
virtual ~SbPolyhedronCone()
SbPolyhedronCone(double Rmn1, double Rmx1, double Rmn2, double Rmx2, double Dz)
SbPolyhedronCons(double Rmn1, double Rmx1, double Rmn2, double Rmx2, double Dz, double Phi1, double Dphi)
virtual ~SbPolyhedronCons()
SbPolyhedronGenericTrap(double Dz, const std::vector< std::pair< double, double > > &Vertices)
virtual ~SbPolyhedronGenericTrap()
virtual ~SbPolyhedronPara()
SbPolyhedronPara(double Dx, double Dy, double Dz, double Alpha, double Theta, double Phi)
SbPolyhedronPcon(double phi, double dphi, int nz, const double *z, const double *rmin, const double *rmax)
virtual ~SbPolyhedronPcon()
virtual ~SbPolyhedronPgon()
SbPolyhedronPgon(double phi, double dphi, int npdv, int nz, const double *z, const double *rmin, const double *rmax)
void setupExternalFace(const unsigned &id_extedge, const unsigned &prev_edgeface, const unsigned &next_edgeface, const unsigned &idfirstvertex, const unsigned &idsecondvertex, const unsigned &id_triangleface, const unsigned &n, std::vector< unsigned > &faceinfo) const
PolygonTriangulator::Triangle Triangle
PolygonTriangulator::Triangles Triangles
const std::vector< double > * y
Internals(SbPolyhedronPolygonXSect *sbp)
unsigned nextraexternalvertices
unsigned nextrainternalvertices
std::pair< int, int > Edge
Edge GetEdge(const Triangle *tr, const unsigned &i, const bool &oriented=false) const
bool isinternaledge(const Edge &edge, const std::map< Edge, std::vector< Triangles::const_iterator > > &edge2triangles_map) const
std::map< Edge, unsigned > externaledgewithextravertex_2_2ndedgeid
std::map< Edge, unsigned > edgewithextravertex_2_id
void getSurroundingValues(const std::vector< unsigned > &numbercycle, const unsigned ¢ralValue, unsigned &prevValue, unsigned &nextValue) const
void setupface(const unsigned &face_id, const std::vector< unsigned > &v) const
unsigned top2bottomfaceid(const unsigned &topid) const
unsigned top2bottomvertexid(const unsigned &topid) const
const std::vector< double > * x
void setData(const std::vector< double > *xx, const std::vector< double > *yy, const double &dz)
std::map< Edge, const Triangle * > neighbourmap
void defineFacesTopology()
SbPolyhedronPolygonXSect * sbpolyhedron
std::set< Edge > edges_external
std::set< Edge > edges_internal
void allocateMemoryAndDefineVertexCoordinates()
std::unique_ptr< PolygonTriangulator > poly
std::set< Edge > edges_with_extra_vertex
void initEdgeClassificationsAndNeighbours()
virtual ~SbPolyhedronPolygonXSect()
SbPolyhedronPolygonXSect(const std::vector< double > &x, const std::vector< double > &y, const double &dz)
virtual ~SbPolyhedronSphere()
SbPolyhedronSphere(double rmin, double rmax, double phi, double dphi, double the, double dthe)
SbPolyhedronTorus(double rmin, double rmax, double rtor, double phi, double dphi)
virtual ~SbPolyhedronTorus()
SbPolyhedronTrap(double Dz, double Theta, double Phi, double Dy1, double Dx1, double Dx2, double Alp1, double Dy2, double Dx3, double Dx4, double Alp2)
virtual ~SbPolyhedronTrap()
virtual ~SbPolyhedronTrd1()
SbPolyhedronTrd1(double Dx1, double Dx2, double Dy, double Dz)
SbPolyhedronTrd2(double Dx1, double Dx2, double Dy1, double Dy2, double Dz)
virtual ~SbPolyhedronTrd2()
SbPolyhedronTube(double Rmin, double Rmax, double Dz)
virtual ~SbPolyhedronTube()
virtual ~SbPolyhedronTubs()
SbPolyhedronTubs(double Rmin, double Rmax, double Dz, double Phi1, double Dphi)
bool GetNextVertex(HVPoint3D &vertex, int &edgeFlag) const
bool GetNextEdge(HVPoint3D &p1, HVPoint3D &p2, int &edgeFlag) const
SbPolyhedron intersect(const SbPolyhedron &p) const
SbPolyhedron add(const SbPolyhedron &p) const
int FindNeighbour(int iFace, int iNode, int iOrder) const
virtual SbPolyhedron & operator=(const SbPolyhedron &from)
bool GetNextNormal(HVNormal3D &normal) const
void RotateAroundZ(int nstep, double phi, double dphi, int np1, int np2, const double *z, double *r, int nodeVis, int edgeVis)
bool GetNextEdgeIndeces(int &i1, int &i2, int &edgeFlag, int &iface1, int &iface2) const
double GetSurfaceArea() const
static int s_numberOfRotationSteps
void AllocateMemory(int Nvert, int Nface)
const HVPoint3D & GetVertexFast(int index) const
HVNormal3D GetUnitNormal(int iFace) const
bool GetNextUnitNormal(HVNormal3D &normal) const
SbPolyhedron subtract(const SbPolyhedron &p) const
void SetSideFacets(int ii[4], int vv[4], int *kk, double *r, double dphi, int ns, int &kface)
bool GetNextVertexIndex(int &index, int &edgeFlag) const
void RotateEdge(int k1, int k2, double r1, double r2, int v1, int v2, int vEdge, bool ifWholeCircle, int ns, int &kface)
HVPoint3D GetVertex(int index) const
SbPolyhedron & Transform(const HEPVis::SbRotation &rot, const SbVec3d &trans)
SbPolyhedron(int Nvert=0, int Nface=0)
static int GetNumberOfRotationSteps()
HVNormal3D FindNodeNormal(int iFace, int iNode) const
void GetFacet(int iFace, int &n, int *iNodes, int *edgeFlags=0, int *iFaces=0) const
bool GetNextFacet(int &n, HVPoint3D *nodes, int *edgeFlags=0, HVNormal3D *normals=0) const
HVNormal3D GetNormal(int iFace) const
static void SetNumberOfRotationSteps(int n)