54 #ifndef EGS_ND_GEOMETRY_
55 #define EGS_ND_GEOMETRY_
60 #define EGS_VHP_EXPORT __declspec(dllexport)
62 #define EGS_VHP_EXPORT __declspec(dllimport)
68 #ifdef HAVE_VISIBILITY
69 #define EGS_VHP_EXPORT __attribute__ ((visibility ("default")))
70 #define EGS_VHP_LOCAL __attribute__ ((visibility ("hidden")))
72 #define EGS_VHP_EXPORT
92 struct EGS_VHP_LOCAL VHP_RowInfo {
96 VHP_RowInfo() : nbin(0) {};
103 int getBin(
int i)
const {
105 while (mu - ml > 1) {
116 int getOrgan(
int pixel)
const {
117 return pixel < pix[0] || pixel >= pix[nbin] ? 0 : org[getBin(pixel)];
119 int getSize()
const {
120 int result =
sizeof(nbin) +
sizeof(
unsigned short *) +
121 sizeof(
unsigned char *);
122 if (nbin > 0) result += nbin*
sizeof(
unsigned char) +
123 (nbin+1)*
sizeof(
unsigned short);
126 void readData(istream &in);
135 struct EGS_VHP_LOCAL VHP_SliceInfo {
136 unsigned short firstr;
137 unsigned short lastr;
139 VHP_SliceInfo() : rinfo(0) {};
145 void getSliceDimensions(
int &nx,
int &ny) {
148 int nrow = lastr - firstr + 1;
149 for (
int j=0; j<nrow; ++j) {
150 int ni = rinfo[j].pix[rinfo[j].nbin];
156 int getOrgan(
int row,
int pixel)
const {
157 return rinfo && row >= firstr && row <= lastr ?
158 rinfo[row-firstr].getOrgan(pixel) : 0;
160 int getSize()
const {
161 int result =
sizeof(firstr) +
sizeof(lastr) +
162 sizeof(VHP_RowInfo *);
164 int nrow = lastr-firstr+1;
165 for (
int j=0; j<nrow; ++j) {
166 result += rinfo[j].getSize();
171 void readData(istream &in);
180 class EGS_VHP_LOCAL VHP_OrganData {
182 VHP_OrganData(
const char *fname,
int slice_min=0,
int slice_max=1000000);
188 int getOrgan(
int islice,
int i,
int j)
const {
189 return islice >= 0 && islice < nslice ?
190 slices[islice].getOrgan(i,j) : 0;
192 const VHP_SliceInfo &getVHP_SliceInfo(
int j)
const {
195 const VHP_SliceInfo &operator[](
int j)
const {
198 int getSize()
const {
199 int result =
sizeof(nslice) +
sizeof(VHP_SliceInfo *);
201 for (
int j=0; j<nslice; ++j) {
202 result += slices[j].getSize();
207 void getPhantomDimensions(
int &Nx,
int &Ny,
int &Nz) {
212 void getVoxelSizes(EGS_Float &Dx, EGS_Float &Dy, EGS_Float &Dz) {
217 int getOrgan(
int ireg)
const {
219 if (k < 0 || k >= nslice) {
222 int jj = ireg - k*nx*ny;
225 return getOrgan(k,j,i);
234 VHP_SliceInfo *slices;
235 unsigned short nslice;
246 struct EGS_VHP_LOCAL EGS_VoxelInfo {
247 unsigned short ix, iy, iz;
256 class EGS_VHP_LOCAL EGS_VoxelGeometry {
260 EGS_Float dx, dxi, xmin, xmax;
261 EGS_Float dy, dyi, ymin, ymax;
262 EGS_Float dz, dzi, zmin, zmax;
266 static EGS_VoxelInfo *v;
269 EGS_VoxelGeometry(
int Nx,
int Ny,
int Nz,
270 EGS_Float Dx, EGS_Float Dy, EGS_Float Dz) :
271 dx(Dx), dxi(1/Dx), xmin(0), xmax(Dx*Nx),
272 dy(Dy), dyi(1/Dy), ymin(0), ymax(Dy*Ny),
273 dz(Dz), dzi(1/Dz), zmin(0), zmax(Dz*Nz),
274 nx(Nx), ny(Ny), nz(Nz), nxy(nx*ny) {};
276 ~EGS_VoxelGeometry() {
285 return (x.
x >= xmin && x.
x <= xmax &&
286 x.
y >= ymin && x.
y <= ymax &&
287 x.
z >= zmin && x.
z <= zmax) ?
true :
false;
310 return ix + iy*nx + iz*nxy;
315 return ix + iy*nx + iz*nxy;
318 int computeIntersections(
int ireg,
int n,
const EGS_Vector &X,
327 v =
new EGS_VoxelInfo [n];
335 ireg = howfar(ireg,x,u,t);
340 isections[0].
rhof = 1;
341 isections[0].
ireg = -1;
342 isections[0].
imed = -1;
347 int ir = ireg - iz*nxy;
350 EGS_Float uxi, uyi, uzi, nextx, nexty, nextz, sx, sy, sz;
351 int dirx, diry, dirz;
355 nextx = (dx*(ix+1)-x.
x)*uxi;
361 nextx = (dx*ix-x.
x)*uxi;
372 nexty = (dy*(iy+1)-x.
y)*uyi;
378 nexty = (dy*iy-x.
y)*uyi;
389 nextz = (dz*(iz+1)-x.
z)*uzi;
395 nextz = (dz*iz-x.
z)*uzi;
403 for (
int j=ifirst; j<n; j++) {
404 isections[j].
ireg = ireg;
409 if (nextx < nexty && nextx < nextz) {
412 if (ix < 0 || ix >= nx) {
420 else if (nexty < nextz) {
423 if (iy < 0 || iy >= ny) {
427 inew = ireg + nx*diry;
434 if (iz < 0 || iz >= nz) {
438 inew = ireg + nxy*dirz;
447 return ireg >= 0 ? -1 : n;
450 EGS_Float howfarToOutside(
int ireg,
const EGS_Vector &x,
455 EGS_Float tx = u.
x > 0 ? (xmax-x.
x)/u.
x :
457 EGS_Float ty = u.
y > 0 ? (ymax-x.
y)/u.
y :
459 EGS_Float tz = u.
z > 0 ? (zmax-x.
z)/u.
z :
461 return tx < ty && tx < tz ? tx : ty < tz ? ty : tz;
464 void setIndeces(
int ireg) {
466 int ir = ireg - iz*nxy;
476 int howfarIn(
int ireg,
int Ix,
int Iy,
int Iz,
const EGS_Vector &x,
481 return howfarIn(ireg,x,u,t,normal);
486 int ixs = ix, iys = iy;
489 EGS_Float d = (dx*(ix+1)-x.
x)/u.
x;
504 EGS_Float d = (dx*ix-x.
x)/u.
x;
519 EGS_Float d = (dy*(iy+1)-x.
y)/u.
y;
535 EGS_Float d = (dy*iy-x.
y)/u.
y;
551 EGS_Float d = (dz*(iz+1)-x.
z)/u.
z;
568 EGS_Float d = (dz*iz-x.
z)/u.
z;
589 EGS_Float tlong = 2*t, d;
590 if (x.
x <= xmin && u.
x > 0) {
594 else if (x.
x >= xmax && u.
x < 0) {
602 EGS_Float yy = x.
y + u.
y*d, zz = x.
z + u.
z*d;
603 if (yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax) {
613 if (normal) *normal = ix == 0 ?
EGS_Vector(-1,0,0) :
615 return ix + iy*nx + iz*nxy;
618 if (x.
y <= ymin && u.
y > 0) {
622 else if (x.
y >= ymax && u.
y < 0) {
630 EGS_Float xx = x.
x + u.
x*d, zz = x.
z + u.
z*d;
631 if (xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax) {
641 if (normal) *normal = iy == 0 ?
EGS_Vector(0,-1,0) :
643 return ix + iy*nx + iz*nxy;
646 if (x.
z <= zmin && u.
z > 0) {
650 else if (x.
z >= zmax && u.
z < 0) {
658 EGS_Float xx = x.
x + u.
x*d, yy = x.
y + u.
y*d;
659 if (xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax) {
669 if (normal) *normal = iz == 0 ?
EGS_Vector(0,0,-1) :
671 return ix + iy*nx + iz*nxy;
681 return howfarIn(ireg,x,u,t,normal);
683 return howfarOut(x,u,t,normal);
686 EGS_Float hownearIn(
int Ix,
int Iy,
int Iz,
const EGS_Vector &x) {
694 EGS_Float t1,t2,tx,ty,tz;
697 tx = t1 < t2 ? t1 : t2;
700 ty = t1 < t2 ? t1 : t2;
703 tz = t1 < t2 ? t1 : t2;
704 return tx < ty && tx < tz ? tx : ty < tz ? ty : tz;
707 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
713 EGS_Float s1=0, s2=0;
714 if (x.
x < xmin || x.
x > xmax) {
715 EGS_Float t = x.
x < xmin ? xmin-x.
x : x.
x-xmax;
720 if (x.
y < ymin || x.
y > ymax) {
721 EGS_Float t = x.
y < ymin ? ymin-x.
y : x.
y-ymax;
726 if (x.
z < zmin || x.
z > zmax) {
727 EGS_Float t = x.
z < zmin ? zmin-x.
z : x.
z-zmax;
732 return nc == 1 ? s1 : sqrt(s2);
743 EGS_Float xmin, xmax;
744 EGS_Float ymin, ymax;
745 EGS_Float zmin, zmax;
748 (x.
x>=xmin&&x.
x<=xmax&&x.
y>=ymin&&ymax<=ymin&&x.z>=zmin&&x.
z<=zmax);
751 EGS_Float tlong = 2*t, d;
752 if (x.
x <= xmin && u.
x > 0) {
755 else if (x.
x >= xmax && u.
x < 0) {
762 EGS_Float yy = x.
y + u.
y*d, zz = x.
z + u.
z*d;
763 if (yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax) {
768 if (x.
y <= ymin && u.
y > 0) {
771 else if (x.
y >= ymax && u.
y < 0) {
778 EGS_Float xx = x.
x + u.
x*d, zz = x.
z + u.
z*d;
779 if (xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax) {
784 if (x.
z <= zmin && u.
z > 0) {
787 else if (x.
z >= zmax && u.
z < 0) {
794 EGS_Float xx = x.
x + u.
x*d, yy = x.
y + u.
y*d;
795 if (xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax) {
850 class EGS_VHP_LOCAL EGS_MicroMatrixCluster {
854 EGS_MicroMatrixCluster(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz,
855 EGS_Float bsc_thickness,
int tb_med,
int bm_med,
856 const char *micro_file);
858 ~EGS_MicroMatrixCluster();
861 int howfar(
int imic,
int ireg,
int &lax,
int &lay,
int &laz,
int &newmic,
863 EGS_Float &t,
int *newmed=0,
EGS_Vector *normal=0) {
864 int inew = vg->howfar(ireg,x,u,t,normal);
867 int iz = imic/(mx*my);
868 int itmp = imic - iz*mx*my;
870 int ix = itmp - mx*iy;
877 else if (vg->ix >= vg->nx) {
883 else if (vg->iy < 0) {
889 else if (vg->iy >= vg->ny) {
895 else if (vg->iz < 0) {
901 else if (vg->iz >= vg->nz) {
907 newmic = ix + iy*mx + iz*mx*my;
910 *newmed = micros[newmic][inew] ? med_bm : med_tb;
915 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
916 return vg->hownear(ireg,x);
919 int medium(
int imic,
int ireg)
const {
920 return micros[imic][ireg] ? med_bm : med_tb;
923 int medium(
int ireg)
const {
924 int imic = ireg/nreg;
926 return medium(imic,ireg);
930 int ix = (int)(x.
x*dxi), iy = (int)(x.
y*dyi), iz = (int)(x.
z*dzi);
935 imic = ix + iy*mx + iz*mz;
936 return vg->isWhere(x1);
939 void getIndeces(
int ireg,
int &imic,
int &ix,
int &iy,
int &iz) {
943 iy = (ireg - iz*nxy)/nx;
944 ix = ireg - iz*nxy - iy*nx;
947 int isWhere(
int jx,
int jy,
int jz,
const EGS_Vector &x1,
int *newmed=0) {
948 int ix = jx%mx, iy = jy%my, iz = jz%mz;
949 int imic = ix + iy*mx + iz*mz;
950 int iloc = vg->isWhereFast(x1);
952 *newmed = medium(imic,iloc);
954 return imic*nreg + iloc;
957 bool isValid()
const {
958 return (vg && micros);
961 void getStepFractions(
int imic,
int ireg,
963 EGS_Float &bsc_step, EGS_Float &bm_step) {
966 int mict = micros[imic][ireg];
972 else if (mict == 2) {
979 int jy = (ireg-jz*nxy)/nx;
980 int jx = ireg-jz*nxy-jy*nx;
981 EGS_Vector xcorner(vg->dx*jx,vg->dy*jy,vg->dz*jz);
983 bool i_inside = bm_boxes[mict].isInside(Xi),
984 f_inside = bm_boxes[mict].isInside(Xf);
987 if (i_inside && f_inside) {
993 EGS_Float t = u.length();
999 if (!bm_boxes[mict].willEnter(Xi,u,tt)) {
1013 bm_step = 1 - bsc_step;
1019 bm_step = ti*bm_boxes[mict].howfarToOut(Xi,u);
1020 bsc_step = 1 - bm_step;
1026 void getVolumes(
int imic, EGS_Float &tb, EGS_Float &bm, EGS_Float &bsc) {
1035 int nx, ny, nz, nxy, nreg;
1038 EGS_Float dx, dy, dz;
1039 EGS_Float dxi, dyi, dzi;
1052 unsigned char **micros;
1053 EGS_VoxelGeometry *vg;
1058 static VHPBox bm_boxes[64];
1059 static bool bm_boxes_initialized;
1068 EGS_TestMicro(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, EGS_Float bsc_t,
1069 int tb_med,
int bm_med,
const char *micro_file,
const string &Name=
"");
1077 return vg->isInside(x);
1080 int ireg = vg->isWhere(x);
1085 int ix = vg->ix%micro->mx,
1086 iy = vg->iy%micro->my,
1087 iz = vg->iz%micro->mz;
1088 int imic = ix + iy*micro->mx + iz*micro->mxy;
1089 int iloc = micro->vg->isWhere(x1);
1090 return imic*nr + iloc;
1094 EGS_Float &t,
int *newmed=0,
EGS_Vector *normal=0) {
1096 int voxel = ireg/nr;
1097 int ilocal = ireg - voxel*nr;
1098 vg->setIndeces(voxel);
1100 int inew = micro->vg->howfar(ilocal,x1,u,t,normal);
1101 if (inew == ilocal) {
1105 if (micro->vg->ix < 0) {
1106 if ((--vg->ix) < 0) {
1109 micro->vg->ix = micro->vg->nx-1;
1111 else if (micro->vg->ix >= micro->vg->nx) {
1112 if ((++vg->ix) >= vg->nx) {
1117 else if (micro->vg->iy < 0) {
1118 if ((--vg->iy) < 0) {
1121 micro->vg->iy = micro->vg->ny-1;
1123 else if (micro->vg->iy >= micro->vg->ny) {
1124 if ((++vg->iy) >= vg->ny) {
1129 else if (micro->vg->iz < 0) {
1130 if ((--vg->iz) < 0) {
1133 micro->vg->iz = micro->vg->nz-1;
1135 else if (micro->vg->iz >= micro->vg->nz) {
1136 if ((++vg->iz) >= vg->nz) {
1141 inew = micro->vg->ix + micro->vg->iy*micro->vg->nx +
1142 micro->vg->iz*micro->vg->nxy;
1144 voxel = vg->ix + vg->iy*vg->nx + vg->iz*vg->nxy;
1146 *newmed = micro->medium(voxel,inew);
1148 return voxel*nr + inew;
1150 int voxel = vg->howfar(ireg,x,u,t,normal);
1155 x1 -=
EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz);
1156 int ilocal = micro->vg->isWhereFast(x1);
1158 egsFatal(
"x=(%g,%g,%g) x+u*t=(%g,%g,%g) x1=(%g,%g,%g)\n",x.
x,x.
y,x.
z,(x+u*t).x,(x+u*t).y,(x+u*t).z,x1.
x,x1.
y,x1.
z);
1161 *newmed = micro->medium(voxel,ilocal);
1163 return voxel*nr + ilocal;
1166 EGS_Float howfarToOutside(
int ireg,
const EGS_Vector &x,
1168 return vg->howfarToOutside(ireg,x,u);
1171 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
1173 return vg->hownear(ireg,x);
1175 int voxel = ireg/nr;
1176 int ilocal = ireg - voxel*nr;
1177 vg->setIndeces(voxel);
1179 return micro->vg->hownear(ilocal,x1);
1182 int medium(
int ireg)
const {
1183 int voxel = ireg/nr;
1184 int ilocal = ireg - voxel*nr;
1185 return micro->medium(voxel,ilocal);
1188 int getMaxStep()
const {
1189 return micro->mx*micro->nx + micro->my*micro->ny +
1190 micro->mz*micro->nz + 1;
1193 const string &getType()
const {
1199 EGS_VoxelGeometry *vg;
1200 EGS_MicroMatrixCluster *micro;
1203 void setMedia(
EGS_Input *inp,
int nmed,
const int *med_ind);
1308 int slice_min=0,
int slice_max=1000000,
const string &Name=
"");
1313 return vg->isInside(x);
1317 int ireg = vg->isWhere(x);
1321 int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix);
1322 int mict = organ_micro[iorg];
1327 int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1);
1328 return nmax*mict + micr + nmacro;
1335 int medium(
int ireg)
const {
1336 if (ireg < nmacro) {
1337 return organ_media[organs->getOrgan(ireg)];
1340 int mict = ireg/nmax;
1341 int iloc = ireg - mict*nmax;
1342 return micros[mict]->medium(iloc);
1345 int computeIntersections(
int ireg,
int n,
const EGS_Vector &X,
1353 int result = vg->computeIntersections(ireg,n,X,u,isections);
1357 int nloop = result > 0 ? result : n;
1358 int first = isections[0].
ireg >= 0 ? 0 : 1;
1359 EGS_VoxelInfo *v = vg->v;
1360 for (
int j=first; j<nloop; ++j) isections[j].imed =
1361 organ_media[organs->getOrgan(v[j].iz,v[j].iy,v[j].ix)];
1365 EGS_Float howfarToOutside(
int ireg,
const EGS_Vector &x,
1367 return vg->howfarToOutside(ireg,x,u);
1371 EGS_Float &t,
int *newmed=0,
EGS_Vector *normal=0) {
1373 int inew = vg->howfar(ireg,x,u,t,normal);
1374 if (newmed && inew >= 0 && inew != ireg) {
1375 *newmed = organ_media[organs->getOrgan(vg->iz,vg->iy,vg->ix)];
1379 if (ireg >= 0 && ireg < nmacro) {
1381 int inew = vg->howfar(ireg,x,u,t,normal);
1383 if (t < -boundaryTolerance) {
1384 egsWarning(
"negative step %g in macro voxel\n",t);
1387 egsWarning(
"ix=%d iy=%d iz=%d\n",vg->ix,vg->iy,vg->iz);
1390 t = boundaryTolerance;
1392 if (inew < 0 || inew == ireg) {
1396 int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix);
1397 int mict = organ_micro[iorg];
1400 *newmed = organ_media[iorg];
1406 EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz));
1407 int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1,newmed);
1408 return nmax*mict + micr + nmacro;
1412 int ireg1 = ireg - nmacro;
1413 int mict = ireg1/nmax;
1414 int iloc = ireg1 - mict*nmax;
1416 int imic, ix, iy, iz;
1417 EGS_MicroMatrixCluster *micro = micros[mict];
1418 micro->getIndeces(iloc,imic,ix,iy,iz);
1419 int ilocal = iloc - imic*micros[mict]->nreg;
1426 EGS_Float aux = x.
x*vg->dxi;
1427 if (ix > 0 && ix < micros[mict]->vg->nx-1) {
1431 lax = (int)(aux+0.5);
1434 lax = (int)(aux-0.5);
1437 if (iy > 0 && iy < micros[mict]->vg->ny-1) {
1441 lay = (int)(aux+0.5);
1444 lay = (int)(aux-0.5);
1447 if (iz > 0 && iz < micros[mict]->vg->nz-1) {
1451 laz = (int)(aux+0.5);
1454 laz = (int)(aux-0.5);
1457 int inew = micro->vg->howfarIn(ilocal,ix,iy,iz,x1,u,t,normal);
1459 if (t < -boundaryTolerance) {
1460 egsWarning(
"negative step %g in micro matrix\n",t);
1464 egsWarning(
"lax=%d lay=%d laz=%d\n",lax,lay,laz);
1470 if (inew == ilocal) {
1477 if (micro->vg->ix < 0) {
1481 micro->vg->ix = micro->vg->nx-1;
1483 else if (micro->vg->ix >= micro->vg->nx) {
1484 if ((++lax) >= vg->nx) {
1489 else if (micro->vg->iy < 0) {
1493 micro->vg->iy = micro->vg->ny-1;
1495 else if (micro->vg->iy >= micro->vg->ny) {
1496 if ((++lay) >= vg->ny) {
1501 else if (micro->vg->iz < 0) {
1505 micro->vg->iz = micro->vg->nz-1;
1507 else if (micro->vg->iz >= micro->vg->nz) {
1508 if ((++laz) >= vg->nz) {
1514 int iorg = organs->getOrgan(laz,lay,lax);
1515 mict = organ_micro[iorg];
1518 *newmed = organ_media[iorg];
1520 return lax + lay*vg->nx + laz*vg->nxy;
1522 inew = micro->vg->ix + micro->vg->iy*micro->vg->nx +
1523 micro->vg->iz*micro->vg->nxy;
1524 int lix = lax%micros[mict]->mx;
1525 int liy = lay%micros[mict]->my;
1526 int liz = laz%micros[mict]->mz;
1527 imic = lix + micros[mict]->mx*liy + micros[mict]->mxy*liz;
1530 *newmed = micros[mict]->medium(imic,inew);
1532 return nmax*mict + inew + nmacro;
1535 int imac = vg->howfarOut(x,u,t,normal);
1539 int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix);
1540 int mict = organ_micro[iorg];
1543 *newmed = organ_media[iorg];
1548 x1 -=
EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz);
1549 int ilocal = micros[mict]->vg->isWhereFast(x1);
1550 int ix=vg->ix%micros[mict]->mx,
1551 iy=vg->iy%micros[mict]->my,
1552 iz=vg->iz%micros[mict]->mz;
1553 int imic = ix + iy*micros[mict]->mx + iz*micros[mict]->mxy;
1555 *newmed = micros[mict]->medium(imic,ilocal);
1557 return nmax*mict + imic*micros[mict]->nreg + ilocal + nmacro;
1560 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
1561 if (ireg < nmacro) {
1562 return vg->hownear(ireg,x);
1565 int mict = ireg/nmax;
1566 int iloc = ireg - mict*nmax;
1567 int imic, ix, iy, iz;
1568 EGS_MicroMatrixCluster *micro = micros[mict];
1569 micro->getIndeces(iloc,imic,ix,iy,iz);
1576 EGS_Float aux = x.
x*vg->dxi;
1577 if (ix > 0 && ix < micro->vg->nx-1) {
1581 lax = (int)(aux+0.5);
1584 lax = (int)(aux-0.5);
1587 if (iy > 0 && iy < micro->vg->ny-1) {
1591 lay = (int)(aux+0.5);
1594 lay = (int)(aux-0.5);
1597 if (iz > 0 && iz < micro->vg->nz-1) {
1601 laz = (int)(aux+0.5);
1604 laz = (int)(aux-0.5);
1607 return micro->vg->hownearIn(ix,iy,iz,x1);
1610 int getMaxStep()
const {
1612 return vg->nx+vg->ny+vg->nz+1;
1614 int nmx=0, nmy=0, nmz=0;
1615 for (
int mict=0; mict<nmicro; ++mict) {
1616 if (micros[mict]->nx > nmx) {
1617 nmx = micros[mict]->nx;
1619 if (micros[mict]->ny > nmy) {
1620 nmy = micros[mict]->ny;
1622 if (micros[mict]->nx > nmz) {
1623 nmx = micros[mict]->nz;
1626 return vg->nx*nmx+vg->ny*nmy+vg->nz*nmz+1;
1630 return (vg && organs);
1643 const string &getType()
const {
1647 void printInfo()
const;
1654 EGS_VoxelGeometry *vg;
1655 VHP_OrganData *organs;
1657 int organ_media[256];
1658 int organ_micro[256];
1659 string organ_names[256];
1660 EGS_MicroMatrixCluster **micros;
1668 void setMedia(
EGS_Input *inp,
int nmed,
const int *med_ind);
EGS_Float t
distance to next region boundary
EGS_Float rhof
relative mass density in that region
A class representing 3D vectors.
Global egspp functions header file.
const EGS_Float veryFar
A very large float.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
A Voxelized Human Phantom (VHP) geometry.
virtual int computeIntersections(int ireg, int n, const EGS_Vector &x, const EGS_Vector &u, EGS_GeometryIntersections *isections)
Calculates intersection distances to region boundaries.
int nr
number of voxels in a micro-matrix
EGS_BaseGeometry class header file.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.