41 #ifndef EGS_ENVELOPE_GEOMETRY_
42 #define EGS_ENVELOPE_GEOMETRY_
46 #ifdef BUILD_ENVELOPEG_DLL
47 #define EGS_ENVELOPEG_EXPORT __declspec(dllexport)
49 #define EGS_ENVELOPEG_EXPORT __declspec(dllimport)
51 #define EGS_ENVELOPEG_LOCAL
55 #ifdef HAVE_VISIBILITY
56 #define EGS_ENVELOPEG_EXPORT __attribute__ ((visibility ("default")))
57 #define EGS_ENVELOPEG_LOCAL __attribute__ ((visibility ("hidden")))
59 #define EGS_ENVELOPEG_EXPORT
60 #define EGS_ENVELOPEG_LOCAL
235 const vector<EGS_BaseGeometry *> &geoms,
const string &Name =
"",
236 bool newindexing=
false);
241 if (ireg < 0 || ireg >= nreg) {
245 return g->isRealRegion(ireg);
249 jg = reg_to_inscr[ireg-nbase];
250 ilocal = ireg - local_start[jg];
253 jg = (ireg - nbase)/nmax;
254 ilocal = ireg - nbase - jg*nmax;
256 return geometries[jg]->isRealRegion(ilocal);
260 return g->isInside(x);
264 int ireg = g->isWhere(x);
268 for (
int j=0; j<n_in; j++) {
269 int i = geometries[j]->isWhere(x);
270 if (i >= 0)
return new_indexing ? local_start[j] + i :
280 int medium(
int ireg)
const {
282 return g->medium(ireg);
286 jg = reg_to_inscr[ireg-nbase];
287 ilocal = ireg - local_start[jg];
290 jg = (ireg - nbase)/nmax;
291 ilocal = ireg - nbase - jg*nmax;
293 return geometries[jg]->medium(ilocal);
302 EGS_Float t, ttot = 0;
307 ireg =
howfar(ireg,x,u,t,&imed);
312 isections[0].
rhof = 1;
313 isections[0].
ireg = -1;
314 isections[0].
imed = -1;
326 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
328 egsFatal(
"EGS_EnvelopeGeometry::computeIntersections: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
333 ig = reg_to_inscr[ireg-nbase];
334 ij = ireg - local_start[ig];
337 ig = (ireg - nbase)/nmax;
338 ij = ireg - nbase - ig*nmax;
341 isections[j].
imed = imed;
342 isections[j].
ireg = ireg;
346 int ibase = g->howfar(ireg,x,u,t,&imed);
348 for (
int i=0; i<n_in; i++) {
349 int ireg_i = geometries[i]->howfar(-1,x,u,t,&imed);
356 isections[j++].
t = ttot;
360 else ireg = new_indexing ? local_start[ig] + ij :
361 nbase + ig*nmax + ij;
371 int iadd = new_indexing ? local_start[ig] : nbase + ig*nmax;
372 int nsec = geometries[ig]->computeIntersections(ij,n-j,
374 int nm = nsec >= 0 ? nsec+j : n;
375 for (
int i=j; i<nm; i++) {
376 isections[i].
ireg += iadd;
377 isections[i].
t += ttot;
386 t = isections[j-1].
t - ttot;
388 ttot = isections[j-1].
t;
389 ireg = g->isWhere(x);
393 imed = g->medium(ireg);
406 d = g->howfarToOutside(ireg,x,u);
408 else if (g->regions() == 1) {
409 d = g->howfarToOutside(0,x,u);
412 int ir = g->isWhere(x);
413 d = g->howfarToOutside(ir,x,u);
419 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
427 int ibase = g->howfar(ireg,x,u,t,newmed,normal);
431 for (
int j=0; j<n_in; j++) {
433 geometries[j]->howfar(-1,x,u,t,newmed,normal);
448 return new_indexing ? local_start[jg] + ij : nbase + jg*nmax + ij;
454 jg = reg_to_inscr[ireg-nbase];
455 ilocal = ireg-local_start[jg];
458 jg = (ireg - nbase)/nmax;
459 ilocal = ireg - nbase - jg*nmax;
462 int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal);
464 return new_indexing ? local_start[jg] + inew : nbase + jg*nmax + inew;
471 inew = g->isWhere(x+u*t);
472 if (inew >= 0 && newmed) {
473 *newmed = g->medium(inew);
479 int ienter = g->howfar(ireg,x,u,t,newmed,normal);
483 for (
int j=0; j<n_in; j++) {
484 int i = geometries[j]->isWhere(x+u*t);
488 *newmed = geometries[j]->medium(i);
490 return new_indexing ? local_start[j] + i : nbase + nmax*j + i;
501 tmin = g->hownear(ireg,x);
502 for (
int j=0; j<n_in; j++) {
503 EGS_Float tj = geometries[j]->hownear(-1,x);
515 jg = reg_to_inscr[ireg-nbase];
516 ilocal = ireg-local_start[jg];
519 jg = (ireg - nbase)/nmax;
520 ilocal = ireg - nbase - jg*nmax;
522 return geometries[jg]->hownear(ilocal,x);
524 return g->hownear(ireg,x);
531 for (
int j=0; j<n_in; j++) {
533 geometries[j]->getNextGeom(rndm);
537 g->getNextGeom(rndm);
541 void updatePosition(EGS_Float time) {
544 for (
int j=0; j<n_in; j++) {
546 geometries[j]->updatePosition(time);
550 g->updatePosition(time);
554 void containsDynamic(
bool &hasdynamic) {
557 for (
int j=0; j<n_in; j++) {
558 if (!hasdynamic && geometries[j]) {
559 geometries[j]->containsDynamic(hasdynamic);
562 if (!hasdynamic && g) {
563 g->containsDynamic(hasdynamic);
568 if (has_rho_scaling) {
572 for (
int j=0; j<n_in; j++) {
573 bool hasRS = geometries[j]->hasRhoScaling();
575 has_rho_scaling = hasRS;
580 return g->hasRhoScaling();
583 void finishInitialization() {
584 for (
int j=0; j<n_in; j++) {
585 geometries[j]->finishInitialization();
587 g->finishInitialization();
591 int nstep = g->getMaxStep();
592 for (
int j=0; j<n_in; ++j) {
593 nstep += geometries[j]->getMaxStep();
599 if (ireg >= 0 && ireg < nreg) {
601 return g->hasBooleanProperty(ireg,prop);
603 int jg = (ireg - nbase)/nmax;
604 int ilocal = ireg - nbase - jg*nmax;
605 return geometries[jg]->hasBooleanProperty(ilocal,prop);
610 setPropertyError(
"setBooleanProperty()");
613 setPropertyError(
"addBooleanProperty()");
616 setPropertyError(
"setBooleanProperty()");
619 setPropertyError(
"addBooleanProperty()");
622 const string &
getType()
const {
636 if (ireg < 0 || ireg >= nreg) {
640 return g->getRelativeRho(ireg);
642 int jg = (ireg - nbase)/nmax;
643 return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax);
646 void setBScaling(
int start,
int end, EGS_Float bf);
649 if (ireg < 0 || ireg >= nreg) {
653 return g->getBScaling(ireg);
655 int jg = (ireg - nbase)/nmax;
656 return geometries[jg]->getBScaling(ireg - nbase - jg*nmax);
660 virtual void getLabelRegions(
const string &str, vector<int> ®s,
bool sanitize=
true);
686 void setPropertyError(
const char *funcname) {
687 egsFatal(
"EGS_EnvelopeGeometry::%s: don't use this method\n Define "
688 "properties in the constituent geometries instead\n",
710 const vector<EnvelopeAux *> &fgeoms,
const string &Name =
"",
711 int newindexing=
false);
716 if (ireg < 0 || ireg >= nreg) {
720 return g->isRealRegion(ireg);
724 jg = reg_to_inscr[ireg-nbase];
725 ilocal = ireg - local_start[jg];
728 jg = (ireg - nbase)/nmax;
729 ilocal = ireg - nbase - jg*nmax;
731 return geometries[jg]->isRealRegion(ilocal);
735 return g->isInside(x);
739 int ireg = g->isWhere(x);
740 if (ireg < 0 || n_start[ireg] < 0) {
743 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
745 int i = geometries[j]->isWhere(x);
747 return nbase + nmax*j + i;
756 for (
int j=0; j<n_in; j++) {
757 geometries[j]->getNextGeom(rndm);
759 g->getNextGeom(rndm);
762 void updatePosition(EGS_Float time) {
765 for (
int j=0; j<n_in; j++) {
766 geometries[j]->updatePosition(time);
768 g->updatePosition(time);
771 void containsDynamic(
bool &hasdynamic) {
774 for (
int j=0; j<n_in; j++) {
776 geometries[j]->containsDynamic(hasdynamic);
780 g->containsDynamic(hasdynamic);
785 if (has_rho_scaling) {
789 for (
int j=0; j<n_in; j++) {
790 bool hasRS = geometries[j]->hasRhoScaling();
792 has_rho_scaling = hasRS;
797 return g->hasRhoScaling();
800 void finishInitialization()
override {
801 for (
int j=0; j<n_in; j++) {
802 geometries[j]->finishInitialization();
804 g->finishInitialization();
812 int medium(
int ireg)
const {
814 return g->medium(ireg);
816 int jg = (ireg - nbase)/nmax;
817 int ilocal = ireg - nbase - jg*nmax;
818 return geometries[jg]->medium(ilocal);
827 EGS_Float t, ttot = 0;
834 ireg =
howfar(ireg,x,u,t,&imed);
839 isections[0].
rhof = 1;
840 isections[0].
ireg = -1;
841 isections[0].
imed = -1;
855 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
857 egsFatal(
"EGS_FastEnvelope::computeIntersections: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
863 ig = (ireg - nbase)/nmax;
864 ij = ireg - nbase - ig*nmax;
866 isections[j].
imed = imed;
867 isections[j].
ireg = ireg;
871 int ibase = g->howfar(ireg,x,u,t,&imed);
874 for (
int ii=n_start[ireg]; ii<n_start[ireg+1]; ii++) {
876 int ireg_i = geometries[i]->howfar(-1,x,u,t,&imed);
883 isections[j++].
t = ttot;
890 ireg = nbase + ig*nmax + ij;
901 int iadd = nbase + ig*nmax;
902 int nsec = geometries[ig]->computeIntersections(ij,n-j,
906 int nm = nsec >= 0 ? nsec+j : n;
907 for (
int i=j; i<nm; i++) {
908 isections[i].
ireg += iadd;
909 isections[i].
t += ttot;
919 t = isections[j-1].
t - ttot;
921 ttot = isections[j-1].
t;
922 ireg = g->isWhere(x);
927 imed = g->medium(ireg);
940 d = g->howfarToOutside(ireg,x,u);
942 else if (g->regions() == 1) {
943 d = g->howfarToOutside(0,x,u);
946 int ir = g->isWhere(x);
947 d = g->howfarToOutside(ir,x,u);
953 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
960 int ibase = g->howfar(ireg,x,u,t,newmed,normal);
964 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
967 geometries[j]->howfar(-1,x,u,t,newmed,normal);
982 return nbase + jg*nmax + ij;
986 int jg = (ireg - nbase)/nmax;
987 int ilocal = ireg - nbase - jg*nmax;
989 int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal);
991 return nbase + jg*nmax + inew;
998 inew = g->isWhere(x+u*t);
999 if (inew >= 0 && newmed) {
1000 *newmed = g->medium(inew);
1006 int ienter = g->howfar(ireg,x,u,t,newmed,normal);
1011 for (
int jj=n_start[ienter]; jj<n_start[ienter+1]; jj++) {
1013 int i = geometries[j]->isWhere(x+u*t);
1017 *newmed = geometries[j]->medium(i);
1019 return nbase + nmax*j + i;
1030 tmin = g->hownear(ireg,x);
1034 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
1036 EGS_Float tj = geometries[j]->hownear(-1,x);
1046 int jg = (ireg - nbase)/nmax;
1047 int ilocal = ireg - nbase - jg*nmax;
1048 return geometries[jg]->hownear(ilocal,x);
1050 return g->hownear(ireg,x);
1054 if (ireg >= 0 && ireg < nreg) {
1056 return g->hasBooleanProperty(ireg,prop);
1058 int jg = (ireg - nbase)/nmax;
1059 int ilocal = ireg - nbase - jg*nmax;
1060 return geometries[jg]->hasBooleanProperty(ilocal,prop);
1065 setPropertyError(
"setBooleanProperty()");
1068 setPropertyError(
"addBooleanProperty()");
1071 setPropertyError(
"setBooleanProperty()");
1074 setPropertyError(
"addBooleanProperty()");
1078 int nstep = g->getMaxStep();
1079 for (
int j=0; j<n_in; ++j) {
1080 nstep += geometries[j]->getMaxStep();
1085 const string &
getType()
const {
1094 if (ireg < 0 || ireg >= nreg) {
1098 return g->getRelativeRho(ireg);
1100 int jg = (ireg - nbase)/nmax;
1101 return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax);
1104 void setBScaling(
int start,
int end, EGS_Float bf);
1107 if (ireg < 0 || ireg >= nreg) {
1111 return g->getBScaling(ireg);
1113 int jg = (ireg - nbase)/nmax;
1114 return geometries[jg]->getBScaling(ireg - nbase - jg*nmax);
1118 virtual void getLabelRegions(
const string &str, vector<int> ®s,
bool sanitize=
true);
1146 void setPropertyError(
const char *funcname) {
1147 egsFatal(
"EGS_FastEnvelope::%s: don't use this method\n Define "
1148 "properties in the constituent geometries instead\n",
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual int getGlobalRegionOffset(const string geomName)
Get the global region number for the first region in the 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.
virtual EGS_Float hownear(int ireg, const EGS_Vector &x)=0
Calculate the distance to a boundary for position x in any direction.
virtual int inside(const EGS_Vector &x)=0
Returns the region index, if inside, or -1 if outside (obsolete)
virtual bool hasBooleanProperty(int ireg, EGS_BPType prop) const
Is the boolean property prop set for region ireg ?
virtual EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, const EGS_Vector &u)
virtual EGS_Float getBScaling(int ireg) const
Get the B field scaling factor in region ireg.
virtual void setBScaling(int start, int end, EGS_Float bf)
Set the B field scaling factor in regions.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
virtual const string & getType() const =0
Get the geometry type.
virtual int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0)=0
Calculate the distance to a boundary from x along the direction u.
bool has_rho_scaling
Does this geometry have relative mass density scvaling?
virtual bool hasRhoScaling()
Does this geometry object have a mass density scaling feature?
virtual bool isRealRegion(int ireg) const
Returnes true if ireg is a real region, false otherwise.
virtual bool isInside(const EGS_Vector &x)=0
Is the position x inside the geometry?
virtual EGS_Float getRelativeRho(int ireg) const
Get the relative mass density in region ireg.
virtual void setBooleanProperty(EGS_BPType prop)
Set the boolean properties of the entire geometry to prop.
virtual int getMaxStep() const
Returns the maximum number of steps through the geometry.
virtual int medium(int ireg) const
Returns the medium index in region ireg.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
virtual void printInfo() const
Print information about this geometry.
virtual void addBooleanProperty(int bit)
Add a boolean property for the entire geometry by setting the bit'th bit.
virtual void getLabelRegions(const string &str, vector< int > ®s, bool sanitize=true)
Get the list of all regions labeled with str.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
An envelope geometry class.
EGS_BaseGeometry * g
The envelope geometry.
int n_in
Number of inscribed geometries.
static string type
Geometry type.
int * local_start
First region for each inscribed geometry.
int nbase
Number of regions in the base geometry.
bool new_indexing
If true, use new indexing style.
EGS_BaseGeometry ** geometries
The inscribed geometries.
int * reg_to_inscr
Region to inscribed geometry conversion.
An envelope geometry class.
int nbase
Number of regions in the base geometry.
EGS_BaseGeometry ** geometries
The inscribed geometries.
int * local_start
First region for each inscribed geometry.
int n_in
Number of inscribed geometries.
int * reg_to_inscr
Region to inscribed geometry conversion.
EGS_BaseGeometry * g
The envelope geometry.
static string type
Geometry type.
bool new_indexing
If true, use new indexing style.
Base random number generator class. All random number generators should be derived from this class.
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.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
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