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