55 #ifndef EGS_ND_GEOMETRY_
56 #define EGS_ND_GEOMETRY_
61 #define EGS_VHP_EXPORT __declspec(dllexport)
63 #define EGS_VHP_EXPORT __declspec(dllimport)
69 #ifdef HAVE_VISIBILITY
70 #define EGS_VHP_EXPORT __attribute__ ((visibility ("default")))
71 #define EGS_VHP_LOCAL __attribute__ ((visibility ("hidden")))
73 #define EGS_VHP_EXPORT
93 struct EGS_VHP_LOCAL VHP_RowInfo {
97 VHP_RowInfo() : nbin(0) {};
104 int getBin(
int i)
const {
106 while (mu - ml > 1) {
117 int getOrgan(
int pixel)
const {
118 return pixel < pix[0] || pixel >= pix[nbin] ? 0 : org[getBin(pixel)];
120 int getSize()
const {
121 int result =
sizeof(nbin) +
sizeof(
unsigned short *) +
122 sizeof(
unsigned char *);
123 if (nbin > 0) result += nbin*
sizeof(
unsigned char) +
124 (nbin+1)*
sizeof(
unsigned short);
127 void readData(istream &in);
136 struct EGS_VHP_LOCAL VHP_SliceInfo {
137 unsigned short firstr;
138 unsigned short lastr;
140 VHP_SliceInfo() : rinfo(0) {};
146 void getSliceDimensions(
int &nx,
int &ny) {
149 int nrow = lastr - firstr + 1;
150 for (
int j=0; j<nrow; ++j) {
151 int ni = rinfo[j].pix[rinfo[j].nbin];
157 int getOrgan(
int row,
int pixel)
const {
158 return rinfo && row >= firstr && row <= lastr ?
159 rinfo[row-firstr].getOrgan(pixel) : 0;
161 int getSize()
const {
162 int result =
sizeof(firstr) +
sizeof(lastr) +
163 sizeof(VHP_RowInfo *);
165 int nrow = lastr-firstr+1;
166 for (
int j=0; j<nrow; ++j) {
167 result += rinfo[j].getSize();
172 void readData(istream &in);
181 class EGS_VHP_LOCAL VHP_OrganData {
183 VHP_OrganData(
const char *fname,
int slice_min=0,
int slice_max=1000000);
189 int getOrgan(
int islice,
int i,
int j)
const {
190 return islice >= 0 && islice < nslice ?
191 slices[islice].getOrgan(i,j) : 0;
193 const VHP_SliceInfo &getVHP_SliceInfo(
int j)
const {
196 const VHP_SliceInfo &operator[](
int j)
const {
199 int getSize()
const {
200 int result =
sizeof(nslice) +
sizeof(VHP_SliceInfo *);
202 for (
int j=0; j<nslice; ++j) {
203 result += slices[j].getSize();
208 void getPhantomDimensions(
int &Nx,
int &Ny,
int &Nz) {
213 void getVoxelSizes(EGS_Float &Dx, EGS_Float &Dy, EGS_Float &Dz) {
218 int getOrgan(
int ireg)
const {
220 if (k < 0 || k >= nslice) {
223 int jj = ireg - k*nx*ny;
226 return getOrgan(k,j,i);
235 VHP_SliceInfo *slices;
236 unsigned short nslice;
247 struct EGS_VHP_LOCAL EGS_VoxelInfo {
248 unsigned short ix, iy, iz;
257 class EGS_VHP_LOCAL EGS_VoxelGeometry {
261 EGS_Float dx, dxi, xmin, xmax;
262 EGS_Float dy, dyi, ymin, ymax;
263 EGS_Float dz, dzi, zmin, zmax;
267 static EGS_VoxelInfo *v;
270 EGS_VoxelGeometry(
int Nx,
int Ny,
int Nz,
271 EGS_Float Dx, EGS_Float Dy, EGS_Float Dz) :
272 dx(Dx), dxi(1/Dx), xmin(0), xmax(Dx*Nx),
273 dy(Dy), dyi(1/Dy), ymin(0), ymax(Dy*Ny),
274 dz(Dz), dzi(1/Dz), zmin(0), zmax(Dz*Nz),
275 nx(Nx), ny(Ny), nz(Nz), nxy(nx*ny) {};
277 ~EGS_VoxelGeometry() {
286 return (x.
x >= xmin && x.
x <= xmax &&
287 x.
y >= ymin && x.
y <= ymax &&
288 x.
z >= zmin && x.
z <= zmax) ? true :
false;
311 return ix + iy*nx + iz*nxy;
316 return ix + iy*nx + iz*nxy;
319 int computeIntersections(
int ireg,
int n,
const EGS_Vector &X,
328 v =
new EGS_VoxelInfo [n];
336 ireg = howfar(ireg,x,u,t);
341 isections[0].
rhof = 1;
342 isections[0].
ireg = -1;
343 isections[0].
imed = -1;
348 int ir = ireg - iz*nxy;
351 EGS_Float uxi, uyi, uzi, nextx, nexty, nextz, sx, sy, sz;
352 int dirx, diry, dirz;
356 nextx = (dx*(ix+1)-x.
x)*uxi;
362 nextx = (dx*ix-x.
x)*uxi;
373 nexty = (dy*(iy+1)-x.
y)*uyi;
379 nexty = (dy*iy-x.
y)*uyi;
390 nextz = (dz*(iz+1)-x.
z)*uzi;
396 nextz = (dz*iz-x.
z)*uzi;
404 for (
int j=ifirst; j<n; j++) {
405 isections[j].
ireg = ireg;
410 if (nextx < nexty && nextx < nextz) {
413 if (ix < 0 || ix >= nx) {
421 else if (nexty < nextz) {
424 if (iy < 0 || iy >= ny) {
428 inew = ireg + nx*diry;
435 if (iz < 0 || iz >= nz) {
439 inew = ireg + nxy*dirz;
448 return ireg >= 0 ? -1 : n;
451 EGS_Float howfarToOutside(
int ireg,
const EGS_Vector &x,
456 EGS_Float tx = u.
x > 0 ? (xmax-x.
x)/u.
x :
458 EGS_Float ty = u.
y > 0 ? (ymax-x.
y)/u.
y :
460 EGS_Float tz = u.
z > 0 ? (zmax-x.
z)/u.
z :
462 return tx < ty && tx < tz ? tx : ty < tz ? ty : tz;
465 void setIndeces(
int ireg) {
467 int ir = ireg - iz*nxy;
477 int howfarIn(
int ireg,
int Ix,
int Iy,
int Iz,
const EGS_Vector &x,
482 return howfarIn(ireg,x,u,t,normal);
487 int ixs = ix, iys = iy;
490 EGS_Float d = (dx*(ix+1)-x.
x)/u.
x;
505 EGS_Float d = (dx*ix-x.
x)/u.
x;
520 EGS_Float d = (dy*(iy+1)-x.
y)/u.
y;
536 EGS_Float d = (dy*iy-x.
y)/u.
y;
552 EGS_Float d = (dz*(iz+1)-x.
z)/u.
z;
569 EGS_Float d = (dz*iz-x.
z)/u.
z;
590 EGS_Float tlong = 2*t, d;
591 if (x.
x <= xmin && u.
x > 0) {
595 else if (x.
x >= xmax && u.
x < 0) {
603 EGS_Float yy = x.
y + u.
y*d, zz = x.
z + u.
z*d;
604 if (yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax) {
614 if (normal) *normal = ix == 0 ?
EGS_Vector(-1,0,0) :
616 return ix + iy*nx + iz*nxy;
619 if (x.
y <= ymin && u.
y > 0) {
623 else if (x.
y >= ymax && u.
y < 0) {
631 EGS_Float xx = x.
x + u.
x*d, zz = x.
z + u.
z*d;
632 if (xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax) {
642 if (normal) *normal = iy == 0 ?
EGS_Vector(0,-1,0) :
644 return ix + iy*nx + iz*nxy;
647 if (x.
z <= zmin && u.
z > 0) {
651 else if (x.
z >= zmax && u.
z < 0) {
659 EGS_Float xx = x.
x + u.
x*d, yy = x.
y + u.
y*d;
660 if (xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax) {
670 if (normal) *normal = iz == 0 ?
EGS_Vector(0,0,-1) :
672 return ix + iy*nx + iz*nxy;
682 return howfarIn(ireg,x,u,t,normal);
684 return howfarOut(x,u,t,normal);
687 EGS_Float hownearIn(
int Ix,
int Iy,
int Iz,
const EGS_Vector &x) {
695 EGS_Float t1,t2,tx,ty,tz;
698 tx = t1 < t2 ? t1 : t2;
701 ty = t1 < t2 ? t1 : t2;
704 tz = t1 < t2 ? t1 : t2;
705 return tx < ty && tx < tz ? tx : ty < tz ? ty : tz;
708 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
714 EGS_Float s1=0, s2=0;
715 if (x.
x < xmin || x.
x > xmax) {
716 EGS_Float t = x.
x < xmin ? xmin-x.
x : x.
x-xmax;
721 if (x.
y < ymin || x.
y > ymax) {
722 EGS_Float t = x.
y < ymin ? ymin-x.
y : x.
y-ymax;
727 if (x.
z < zmin || x.
z > zmax) {
728 EGS_Float t = x.
z < zmin ? zmin-x.
z : x.
z-zmax;
733 return nc == 1 ? s1 : sqrt(s2);
744 EGS_Float xmin, xmax;
745 EGS_Float ymin, ymax;
746 EGS_Float zmin, zmax;
749 (x.
x>=xmin&&x.
x<=xmax&&x.
y>=ymin&&ymax<=ymin&&x.z>=zmin&&x.
z<=zmax);
752 EGS_Float tlong = 2*t, d;
753 if (x.
x <= xmin && u.
x > 0) {
756 else if (x.
x >= xmax && u.
x < 0) {
763 EGS_Float yy = x.
y + u.
y*d, zz = x.
z + u.
z*d;
764 if (yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax) {
769 if (x.
y <= ymin && u.
y > 0) {
772 else if (x.
y >= ymax && u.
y < 0) {
779 EGS_Float xx = x.
x + u.
x*d, zz = x.
z + u.
z*d;
780 if (xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax) {
785 if (x.
z <= zmin && u.
z > 0) {
788 else if (x.
z >= zmax && u.
z < 0) {
795 EGS_Float xx = x.
x + u.
x*d, yy = x.
y + u.
y*d;
796 if (xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax) {
851 class EGS_VHP_LOCAL EGS_MicroMatrixCluster {
855 EGS_MicroMatrixCluster(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz,
856 EGS_Float bsc_thickness,
int tb_med,
int bm_med,
857 const char *micro_file);
859 ~EGS_MicroMatrixCluster();
862 int howfar(
int imic,
int ireg,
int &lax,
int &lay,
int &laz,
int &newmic,
864 EGS_Float &t,
int *newmed=0,
EGS_Vector *normal=0) {
865 int inew = vg->howfar(ireg,x,u,t,normal);
868 int iz = imic/(mx*my);
869 int itmp = imic - iz*mx*my;
871 int ix = itmp - mx*iy;
878 else if (vg->ix >= vg->nx) {
884 else if (vg->iy < 0) {
890 else if (vg->iy >= vg->ny) {
896 else if (vg->iz < 0) {
902 else if (vg->iz >= vg->nz) {
908 newmic = ix + iy*mx + iz*mx*my;
911 *newmed = micros[newmic][inew] ? med_bm : med_tb;
916 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
917 return vg->hownear(ireg,x);
920 int medium(
int imic,
int ireg)
const {
921 return micros[imic][ireg] ? med_bm : med_tb;
924 int medium(
int ireg)
const {
925 int imic = ireg/nreg;
927 return medium(imic,ireg);
931 int ix = (int)(x.
x*dxi), iy = (int)(x.
y*dyi), iz = (int)(x.
z*dzi);
936 imic = ix + iy*mx + iz*mz;
937 return vg->isWhere(x1);
940 void getIndeces(
int ireg,
int &imic,
int &ix,
int &iy,
int &iz) {
944 iy = (ireg - iz*nxy)/nx;
945 ix = ireg - iz*nxy - iy*nx;
948 int isWhere(
int jx,
int jy,
int jz,
const EGS_Vector &x1,
int *newmed=0) {
949 int ix = jx%mx, iy = jy%my, iz = jz%mz;
950 int imic = ix + iy*mx + iz*mz;
951 int iloc = vg->isWhereFast(x1);
953 *newmed = medium(imic,iloc);
955 return imic*nreg + iloc;
958 bool isValid()
const {
959 return (vg && micros);
962 void getStepFractions(
int imic,
int ireg,
964 EGS_Float &bsc_step, EGS_Float &bm_step) {
967 int mict = micros[imic][ireg];
973 else if (mict == 2) {
980 int jy = (ireg-jz*nxy)/nx;
981 int jx = ireg-jz*nxy-jy*nx;
982 EGS_Vector xcorner(vg->dx*jx,vg->dy*jy,vg->dz*jz);
984 bool i_inside = bm_boxes[mict].isInside(Xi),
985 f_inside = bm_boxes[mict].isInside(Xf);
988 if (i_inside && f_inside) {
994 EGS_Float t = u.length();
1000 if (!bm_boxes[mict].willEnter(Xi,u,tt)) {
1014 bm_step = 1 - bsc_step;
1020 bm_step = ti*bm_boxes[mict].howfarToOut(Xi,u);
1021 bsc_step = 1 - bm_step;
1027 void getVolumes(
int imic, EGS_Float &tb, EGS_Float &bm, EGS_Float &bsc) {
1036 int nx, ny, nz, nxy, nreg;
1039 EGS_Float dx, dy, dz;
1040 EGS_Float dxi, dyi, dzi;
1053 unsigned char **micros;
1054 EGS_VoxelGeometry *vg;
1059 static VHPBox bm_boxes[64];
1060 static bool bm_boxes_initialized;
1069 EGS_TestMicro(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, EGS_Float bsc_t,
1070 int tb_med,
int bm_med,
const char *micro_file,
const string &Name=
"");
1078 return vg->isInside(x);
1081 int ireg = vg->isWhere(x);
1086 int ix = vg->ix%micro->mx,
1087 iy = vg->iy%micro->my,
1088 iz = vg->iz%micro->mz;
1089 int imic = ix + iy*micro->mx + iz*micro->mxy;
1090 int iloc = micro->vg->isWhere(x1);
1091 return imic*nr + iloc;
1095 EGS_Float &t,
int *newmed=0,
EGS_Vector *normal=0) {
1097 int voxel = ireg/nr;
1098 int ilocal = ireg - voxel*nr;
1099 vg->setIndeces(voxel);
1101 int inew = micro->vg->howfar(ilocal,x1,u,t,normal);
1102 if (inew == ilocal) {
1106 if (micro->vg->ix < 0) {
1107 if ((--vg->ix) < 0) {
1110 micro->vg->ix = micro->vg->nx-1;
1112 else if (micro->vg->ix >= micro->vg->nx) {
1113 if ((++vg->ix) >= vg->nx) {
1118 else if (micro->vg->iy < 0) {
1119 if ((--vg->iy) < 0) {
1122 micro->vg->iy = micro->vg->ny-1;
1124 else if (micro->vg->iy >= micro->vg->ny) {
1125 if ((++vg->iy) >= vg->ny) {
1130 else if (micro->vg->iz < 0) {
1131 if ((--vg->iz) < 0) {
1134 micro->vg->iz = micro->vg->nz-1;
1136 else if (micro->vg->iz >= micro->vg->nz) {
1137 if ((++vg->iz) >= vg->nz) {
1142 inew = micro->vg->ix + micro->vg->iy*micro->vg->nx +
1143 micro->vg->iz*micro->vg->nxy;
1145 voxel = vg->ix + vg->iy*vg->nx + vg->iz*vg->nxy;
1147 *newmed = micro->medium(voxel,inew);
1149 return voxel*nr + inew;
1151 int voxel = vg->howfar(ireg,x,u,t,normal);
1156 x1 -=
EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz);
1157 int ilocal = micro->vg->isWhereFast(x1);
1159 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);
1162 *newmed = micro->medium(voxel,ilocal);
1164 return voxel*nr + ilocal;
1167 EGS_Float howfarToOutside(
int ireg,
const EGS_Vector &x,
1169 return vg->howfarToOutside(ireg,x,u);
1172 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
1174 return vg->hownear(ireg,x);
1176 int voxel = ireg/nr;
1177 int ilocal = ireg - voxel*nr;
1178 vg->setIndeces(voxel);
1180 return micro->vg->hownear(ilocal,x1);
1183 int medium(
int ireg)
const {
1184 int voxel = ireg/nr;
1185 int ilocal = ireg - voxel*nr;
1186 return micro->medium(voxel,ilocal);
1189 int getMaxStep()
const {
1190 return micro->mx*micro->nx + micro->my*micro->ny +
1191 micro->mz*micro->nz + 1;
1194 const string &getType()
const {
1200 EGS_VoxelGeometry *vg;
1201 EGS_MicroMatrixCluster *micro;
1204 void setMedia(
EGS_Input *inp,
int nmed,
const int *med_ind);
1309 int slice_min=0,
int slice_max=1000000,
const string &Name=
"");
1314 return vg->isInside(x);
1318 int ireg = vg->isWhere(x);
1322 int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix);
1323 int mict = organ_micro[iorg];
1328 int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1);
1329 return nmax*mict + micr + nmacro;
1336 int medium(
int ireg)
const {
1337 if (ireg < nmacro) {
1338 return organ_media[organs->getOrgan(ireg)];
1341 int mict = ireg/nmax;
1342 int iloc = ireg - mict*nmax;
1343 return micros[mict]->medium(iloc);
1346 int computeIntersections(
int ireg,
int n,
const EGS_Vector &X,
1354 int result = vg->computeIntersections(ireg,n,X,u,isections);
1358 int nloop = result > 0 ? result : n;
1359 int first = isections[0].
ireg >= 0 ? 0 : 1;
1360 EGS_VoxelInfo *v = vg->v;
1361 for (
int j=first; j<nloop; ++j) isections[j].imed =
1362 organ_media[organs->getOrgan(v[j].iz,v[j].iy,v[j].ix)];
1366 EGS_Float howfarToOutside(
int ireg,
const EGS_Vector &x,
1368 return vg->howfarToOutside(ireg,x,u);
1372 EGS_Float &t,
int *newmed=0,
EGS_Vector *normal=0) {
1374 int inew = vg->howfar(ireg,x,u,t,normal);
1375 if (newmed && inew >= 0 && inew != ireg) {
1376 *newmed = organ_media[organs->getOrgan(vg->iz,vg->iy,vg->ix)];
1380 if (ireg >= 0 && ireg < nmacro) {
1382 int inew = vg->howfar(ireg,x,u,t,normal);
1384 if (t < -boundaryTolerance) {
1385 egsWarning(
"negative step %g in macro voxel\n",t);
1388 egsWarning(
"ix=%d iy=%d iz=%d\n",vg->ix,vg->iy,vg->iz);
1391 t = boundaryTolerance;
1393 if (inew < 0 || inew == ireg) {
1397 int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix);
1398 int mict = organ_micro[iorg];
1401 *newmed = organ_media[iorg];
1407 EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz));
1408 int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1,newmed);
1409 return nmax*mict + micr + nmacro;
1413 int ireg1 = ireg - nmacro;
1414 int mict = ireg1/nmax;
1415 int iloc = ireg1 - mict*nmax;
1417 int imic, ix, iy, iz;
1418 EGS_MicroMatrixCluster *micro = micros[mict];
1419 micro->getIndeces(iloc,imic,ix,iy,iz);
1420 int ilocal = iloc - imic*micros[mict]->nreg;
1427 EGS_Float aux = x.
x*vg->dxi;
1428 if (ix > 0 && ix < micros[mict]->vg->nx-1) {
1432 lax = (int)(aux+0.5);
1435 lax = (int)(aux-0.5);
1438 if (iy > 0 && iy < micros[mict]->vg->ny-1) {
1442 lay = (int)(aux+0.5);
1445 lay = (int)(aux-0.5);
1448 if (iz > 0 && iz < micros[mict]->vg->nz-1) {
1452 laz = (int)(aux+0.5);
1455 laz = (int)(aux-0.5);
1458 int inew = micro->vg->howfarIn(ilocal,ix,iy,iz,x1,u,t,normal);
1460 if (t < -boundaryTolerance) {
1461 egsWarning(
"negative step %g in micro matrix\n",t);
1465 egsWarning(
"lax=%d lay=%d laz=%d\n",lax,lay,laz);
1471 if (inew == ilocal) {
1478 if (micro->vg->ix < 0) {
1482 micro->vg->ix = micro->vg->nx-1;
1484 else if (micro->vg->ix >= micro->vg->nx) {
1485 if ((++lax) >= vg->nx) {
1490 else if (micro->vg->iy < 0) {
1494 micro->vg->iy = micro->vg->ny-1;
1496 else if (micro->vg->iy >= micro->vg->ny) {
1497 if ((++lay) >= vg->ny) {
1502 else if (micro->vg->iz < 0) {
1506 micro->vg->iz = micro->vg->nz-1;
1508 else if (micro->vg->iz >= micro->vg->nz) {
1509 if ((++laz) >= vg->nz) {
1515 int iorg = organs->getOrgan(laz,lay,lax);
1516 mict = organ_micro[iorg];
1519 *newmed = organ_media[iorg];
1521 return lax + lay*vg->nx + laz*vg->nxy;
1523 inew = micro->vg->ix + micro->vg->iy*micro->vg->nx +
1524 micro->vg->iz*micro->vg->nxy;
1525 int lix = lax%micros[mict]->mx;
1526 int liy = lay%micros[mict]->my;
1527 int liz = laz%micros[mict]->mz;
1528 imic = lix + micros[mict]->mx*liy + micros[mict]->mxy*liz;
1531 *newmed = micros[mict]->medium(imic,inew);
1533 return nmax*mict + inew + nmacro;
1536 int imac = vg->howfarOut(x,u,t,normal);
1540 int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix);
1541 int mict = organ_micro[iorg];
1544 *newmed = organ_media[iorg];
1549 x1 -=
EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz);
1550 int ilocal = micros[mict]->vg->isWhereFast(x1);
1551 int ix=vg->ix%micros[mict]->mx,
1552 iy=vg->iy%micros[mict]->my,
1553 iz=vg->iz%micros[mict]->mz;
1554 int imic = ix + iy*micros[mict]->mx + iz*micros[mict]->mxy;
1556 *newmed = micros[mict]->medium(imic,ilocal);
1558 return nmax*mict + imic*micros[mict]->nreg + ilocal + nmacro;
1561 EGS_Float hownear(
int ireg,
const EGS_Vector &x) {
1562 if (ireg < nmacro) {
1563 return vg->hownear(ireg,x);
1566 int mict = ireg/nmax;
1567 int iloc = ireg - mict*nmax;
1568 int imic, ix, iy, iz;
1569 EGS_MicroMatrixCluster *micro = micros[mict];
1570 micro->getIndeces(iloc,imic,ix,iy,iz);
1577 EGS_Float aux = x.
x*vg->dxi;
1578 if (ix > 0 && ix < micro->vg->nx-1) {
1582 lax = (int)(aux+0.5);
1585 lax = (int)(aux-0.5);
1588 if (iy > 0 && iy < micro->vg->ny-1) {
1592 lay = (int)(aux+0.5);
1595 lay = (int)(aux-0.5);
1598 if (iz > 0 && iz < micro->vg->nz-1) {
1602 laz = (int)(aux+0.5);
1605 laz = (int)(aux-0.5);
1608 return micro->vg->hownearIn(ix,iy,iz,x1);
1611 int getMaxStep()
const {
1613 return vg->nx+vg->ny+vg->nz+1;
1615 int nmx=0, nmy=0, nmz=0;
1616 for (
int mict=0; mict<nmicro; ++mict) {
1617 if (micros[mict]->nx > nmx) {
1618 nmx = micros[mict]->nx;
1620 if (micros[mict]->ny > nmy) {
1621 nmy = micros[mict]->ny;
1623 if (micros[mict]->nx > nmz) {
1624 nmx = micros[mict]->nz;
1627 return vg->nx*nmx+vg->ny*nmy+vg->nz*nmz+1;
1631 return (vg && organs);
1644 const string &getType()
const {
1648 void printInfo()
const;
1655 EGS_VoxelGeometry *vg;
1656 VHP_OrganData *organs;
1658 int organ_media[256];
1659 int organ_micro[256];
1660 string organ_names[256];
1661 EGS_MicroMatrixCluster **micros;
1669 void setMedia(
EGS_Input *inp,
int nmed,
const int *med_ind);
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
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
A Voxelized Human Phantom (VHP) geometry.
A class representing 3D vectors.
EGS_BaseGeometry class header file.
Global egspp functions header file.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
const EGS_Float veryFar
A very large float.
EGS_Float t
distance to next region boundary
EGS_Float rhof
relative mass density in that region