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) {
 
  426                 int ibase = g->howfar(ireg,x,u,t,newmed,normal);
 
  430                 for (
int j=0; j<n_in; j++) {
 
  432                         geometries[j]->howfar(-1,x,u,t,newmed,normal);
 
  447                 return new_indexing ? local_start[jg] + ij :
 
  448                        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);
 
  463             if (inew >= 0) 
return new_indexing ? local_start[jg] + inew :
 
  464                                       nbase + jg*nmax + inew;
 
  470             inew = g->isWhere(x+u*t);
 
  471             if (inew >= 0 && newmed) {
 
  472                 *newmed = g->medium(inew);
 
  478         int ienter = g->howfar(ireg,x,u,t,newmed,normal);
 
  482             for (
int j=0; j<n_in; j++) {
 
  483                 int i = geometries[j]->isWhere(x+u*t);
 
  487                         *newmed = geometries[j]->medium(i);
 
  489                     return new_indexing ? local_start[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++) {
 
  532             geometries[j]->getNextGeom(rndm);
 
  534         g->getNextGeom(rndm);
 
  537     void updatePosition(EGS_Float time) {
 
  540         for (
int j=0; j<n_in; j++) {
 
  541             geometries[j]->updatePosition(time);
 
  543         g->updatePosition(time);
 
  546     void containsDynamic(
bool &hasdynamic) {
 
  549         for (
int j=0; j<n_in; j++) {
 
  551                 geometries[j]->containsDynamic(hasdynamic);
 
  555             g->containsDynamic(hasdynamic);
 
  562         int nstep = g->getMaxStep();
 
  563         for (
int j=0; j<n_in; ++j) {
 
  564             nstep += geometries[j]->getMaxStep();
 
  570         if (ireg >= 0 && ireg < nreg) {
 
  572                 return g->hasBooleanProperty(ireg,prop);
 
  574             int jg = (ireg - nbase)/nmax;
 
  575             int ilocal = ireg - nbase - jg*nmax;
 
  576             return geometries[jg]->hasBooleanProperty(ilocal,prop);
 
  581         setPropertyError(
"setBooleanProperty()");
 
  584         setPropertyError(
"addBooleanProperty()");
 
  587         setPropertyError(
"setBooleanProperty()");
 
  590         setPropertyError(
"addBooleanProperty()");
 
  593     const string &
getType()
 const {
 
  607         if (ireg < 0 || ireg >= nreg) {
 
  611             return g->getRelativeRho(ireg);
 
  613         int jg = (ireg - nbase)/nmax;
 
  614         return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax);
 
  617     void setBScaling(
int start, 
int end, EGS_Float bf);
 
  620         if (ireg < 0 || ireg >= nreg) {
 
  624             return g->getBScaling(ireg);
 
  626         int jg = (ireg - nbase)/nmax;
 
  627         return geometries[jg]->getBScaling(ireg - nbase - jg*nmax);
 
  656     void setPropertyError(
const char *funcname) {
 
  657         egsFatal(
"EGS_EnvelopeGeometry::%s: don't use this method\n  Define " 
  658                  "properties in the constituent geometries instead\n",
 
  680                      const vector<EnvelopeAux *> &fgeoms, 
const string &Name = 
"",
 
  681                      int newindexing=
false);
 
  686         if (ireg < 0 || ireg >= nreg) {
 
  690             return g->isRealRegion(ireg);
 
  694             jg = reg_to_inscr[ireg-nbase];
 
  695             ilocal = ireg - local_start[jg];
 
  698             jg = (ireg - nbase)/nmax;
 
  699             ilocal = ireg - nbase - jg*nmax;
 
  701         return geometries[jg]->isRealRegion(ilocal);
 
  705         return g->isInside(x);
 
  709         int ireg = g->isWhere(x);
 
  710         if (ireg < 0 || n_start[ireg] < 0) {
 
  713         for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
 
  715             int i = geometries[j]->isWhere(x);
 
  717                 return nbase + nmax*j + i;
 
  726         for (
int j=0; j<n_in; j++) {
 
  727             geometries[j]->getNextGeom(rndm);
 
  729         g->getNextGeom(rndm);
 
  732     void updatePosition(EGS_Float time) {
 
  735         for (
int j=0; j<n_in; j++) {
 
  736             geometries[j]->updatePosition(time);
 
  738         g->updatePosition(time);
 
  741     void containsDynamic(
bool &hasdynamic) {
 
  744         for (
int j=0; j<n_in; j++) {
 
  746                 geometries[j]->containsDynamic(hasdynamic);
 
  750             g->containsDynamic(hasdynamic);
 
  759     int medium(
int ireg)
 const {
 
  761             return g->medium(ireg);
 
  763         int jg = (ireg - nbase)/nmax;
 
  764         int ilocal = ireg - nbase - jg*nmax;
 
  765         return geometries[jg]->medium(ilocal);
 
  774         EGS_Float t, ttot = 0;
 
  781             ireg = 
howfar(ireg,x,u,t,&imed);
 
  786             isections[0].
rhof = 1;
 
  787             isections[0].
ireg = -1;
 
  788             isections[0].
imed = -1;
 
  802         for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
 
  804                 egsFatal(
"EGS_FastEnvelope::computeIntersections: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
 
  810                 ig = (ireg - nbase)/nmax;
 
  811                 ij = ireg - nbase - ig*nmax;
 
  813             isections[j].
imed = imed;
 
  814             isections[j].
ireg = ireg;
 
  818                 int ibase = g->howfar(ireg,x,u,t,&imed);
 
  821                 for (
int ii=n_start[ireg]; ii<n_start[ireg+1]; ii++) {
 
  823                     int ireg_i = geometries[i]->howfar(-1,x,u,t,&imed);
 
  830                 isections[j++].
t = ttot;
 
  837                     ireg = nbase + ig*nmax + ij;
 
  848                 int iadd = nbase + ig*nmax;
 
  849                 int nsec = geometries[ig]->computeIntersections(ij,n-j,
 
  853                 int nm = nsec >= 0 ? nsec+j : n;
 
  854                 for (
int i=j; i<nm; i++) {
 
  855                     isections[i].
ireg += iadd;
 
  856                     isections[i].
t += ttot;
 
  866                 t = isections[j-1].
t - ttot;
 
  868                 ttot = isections[j-1].
t;
 
  869                 ireg = g->isWhere(x);
 
  874                 imed = g->medium(ireg);
 
  887             d = g->howfarToOutside(ireg,x,u);
 
  889         else if (g->regions() == 1) {
 
  890             d = g->howfarToOutside(0,x,u);
 
  893             int ir = g->isWhere(x);
 
  894             d = g->howfarToOutside(ir,x,u);
 
  900                EGS_Float &t, 
int *newmed = 0, 
EGS_Vector *normal = 0) {
 
  907                 int ibase = g->howfar(ireg,x,u,t,newmed,normal);
 
  911                 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
 
  914                         geometries[j]->howfar(-1,x,u,t,newmed,normal);
 
  929                 return nbase + jg*nmax + ij;
 
  933             int jg = (ireg - nbase)/nmax;
 
  934             int ilocal = ireg - nbase - jg*nmax;
 
  936             int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal);
 
  938                 return nbase + jg*nmax + inew;
 
  945             inew = g->isWhere(x+u*t);
 
  946             if (inew >= 0 && newmed) {
 
  947                 *newmed = g->medium(inew);
 
  953         int ienter = g->howfar(ireg,x,u,t,newmed,normal);
 
  958             for (
int jj=n_start[ienter]; jj<n_start[ienter+1]; jj++) {
 
  960                 int i = geometries[j]->isWhere(x+u*t);
 
  964                         *newmed = geometries[j]->medium(i);
 
  966                     return nbase + nmax*j + i;
 
  977                 tmin = g->hownear(ireg,x);
 
  981                 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
 
  983                     EGS_Float tj = geometries[j]->hownear(-1,x);
 
  993             int jg = (ireg - nbase)/nmax;
 
  994             int ilocal = ireg - nbase - jg*nmax;
 
  995             return geometries[jg]->hownear(ilocal,x);
 
  997         return g->hownear(ireg,x);
 
 1001         if (ireg >= 0 && ireg < nreg) {
 
 1003                 return g->hasBooleanProperty(ireg,prop);
 
 1005             int jg = (ireg - nbase)/nmax;
 
 1006             int ilocal = ireg - nbase - jg*nmax;
 
 1007             return geometries[jg]->hasBooleanProperty(ilocal,prop);
 
 1012         setPropertyError(
"setBooleanProperty()");
 
 1015         setPropertyError(
"addBooleanProperty()");
 
 1018         setPropertyError(
"setBooleanProperty()");
 
 1021         setPropertyError(
"addBooleanProperty()");
 
 1025         int nstep = g->getMaxStep();
 
 1026         for (
int j=0; j<n_in; ++j) {
 
 1027             nstep += geometries[j]->getMaxStep();
 
 1032     const string &
getType()
 const {
 
 1041         if (ireg < 0 || ireg >= nreg) {
 
 1045             return g->getRelativeRho(ireg);
 
 1047         int jg = (ireg - nbase)/nmax;
 
 1048         return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax);
 
 1051     void setBScaling(
int start, 
int end, EGS_Float bf);
 
 1054         if (ireg < 0 || ireg >= nreg) {
 
 1058             return g->getBScaling(ireg);
 
 1060         int jg = (ireg - nbase)/nmax;
 
 1061         return geometries[jg]->getBScaling(ireg - nbase - jg*nmax);
 
 1092     void setPropertyError(
const char *funcname) {
 
 1093         egsFatal(
"EGS_FastEnvelope::%s: don't use this method\n  Define " 
 1094                  "properties in the constituent geometries instead\n",
 
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.
 
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 void getLabelRegions(const string &str, vector< int > ®s)
Get the list of all regions labeled with str.
 
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.
 
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 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