40 #ifndef EGS_ENVELOPE_GEOMETRY_
41 #define EGS_ENVELOPE_GEOMETRY_
45 #ifdef BUILD_ENVELOPEG_DLL
46 #define EGS_ENVELOPEG_EXPORT __declspec(dllexport)
48 #define EGS_ENVELOPEG_EXPORT __declspec(dllimport)
50 #define EGS_ENVELOPEG_LOCAL
54 #ifdef HAVE_VISIBILITY
55 #define EGS_ENVELOPEG_EXPORT __attribute__ ((visibility ("default")))
56 #define EGS_ENVELOPEG_LOCAL __attribute__ ((visibility ("hidden")))
58 #define EGS_ENVELOPEG_EXPORT
59 #define EGS_ENVELOPEG_LOCAL
234 const vector<EGS_BaseGeometry *> &geoms,
const string &Name =
"",
235 bool newindexing=
false);
240 if (ireg < 0 || ireg >= nreg) {
244 return g->isRealRegion(ireg);
248 jg = reg_to_inscr[ireg-nbase];
249 ilocal = ireg - local_start[jg];
252 jg = (ireg - nbase)/nmax;
253 ilocal = ireg - nbase - jg*nmax;
255 return geometries[jg]->isRealRegion(ilocal);
259 return g->isInside(x);
263 int ireg = g->isWhere(x);
267 for (
int j=0; j<n_in; j++) {
268 int i = geometries[j]->isWhere(x);
269 if (i >= 0)
return new_indexing ? local_start[j] + i :
279 int medium(
int ireg)
const {
281 return g->medium(ireg);
285 jg = reg_to_inscr[ireg-nbase];
286 ilocal = ireg - local_start[jg];
289 jg = (ireg - nbase)/nmax;
290 ilocal = ireg - nbase - jg*nmax;
292 return geometries[jg]->medium(ilocal);
301 EGS_Float t, ttot = 0;
306 ireg =
howfar(ireg,x,u,t,&imed);
311 isections[0].
rhof = 1;
312 isections[0].
ireg = -1;
313 isections[0].
imed = -1;
325 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
327 egsFatal(
"EGS_EnvelopeGeometry::computeIntersections: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
332 ig = reg_to_inscr[ireg-nbase];
333 ij = ireg - local_start[ig];
336 ig = (ireg - nbase)/nmax;
337 ij = ireg - nbase - ig*nmax;
340 isections[j].
imed = imed;
341 isections[j].
ireg = ireg;
345 int ibase = g->howfar(ireg,x,u,t,&imed);
347 for (
int i=0; i<n_in; i++) {
348 int ireg_i = geometries[i]->howfar(-1,x,u,t,&imed);
355 isections[j++].
t = ttot;
359 else ireg = new_indexing ? local_start[ig] + ij :
360 nbase + ig*nmax + ij;
370 int iadd = new_indexing ? local_start[ig] : nbase + ig*nmax;
371 int nsec = geometries[ig]->computeIntersections(ij,n-j,
373 int nm = nsec >= 0 ? nsec+j : n;
374 for (
int i=j; i<nm; i++) {
375 isections[i].
ireg += iadd;
376 isections[i].
t += ttot;
385 t = isections[j-1].
t - ttot;
387 ttot = isections[j-1].
t;
388 ireg = g->isWhere(x);
392 imed = g->medium(ireg);
405 d = g->howfarToOutside(ireg,x,u);
407 else if (g->regions() == 1) {
408 d = g->howfarToOutside(0,x,u);
411 int ir = g->isWhere(x);
412 d = g->howfarToOutside(ir,x,u);
418 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
425 int ibase = g->howfar(ireg,x,u,t,newmed,normal);
429 for (
int j=0; j<n_in; j++) {
431 geometries[j]->howfar(-1,x,u,t,newmed,normal);
446 return new_indexing ? local_start[jg] + ij :
447 nbase + jg*nmax + ij;
453 jg = reg_to_inscr[ireg-nbase];
454 ilocal = ireg-local_start[jg];
457 jg = (ireg - nbase)/nmax;
458 ilocal = ireg - nbase - jg*nmax;
461 int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal);
462 if (inew >= 0)
return new_indexing ? local_start[jg] + inew :
463 nbase + jg*nmax + inew;
469 inew = g->isWhere(x+u*t);
470 if (inew >= 0 && newmed) {
471 *newmed = g->medium(inew);
477 int ienter = g->howfar(ireg,x,u,t,newmed,normal);
481 for (
int j=0; j<n_in; j++) {
482 int i = geometries[j]->isWhere(x+u*t);
486 *newmed = geometries[j]->medium(i);
488 return new_indexing ? local_start[j] + i :
500 tmin = g->hownear(ireg,x);
501 for (
int j=0; j<n_in; j++) {
502 EGS_Float tj = geometries[j]->hownear(-1,x);
514 jg = reg_to_inscr[ireg-nbase];
515 ilocal = ireg-local_start[jg];
518 jg = (ireg - nbase)/nmax;
519 ilocal = ireg - nbase - jg*nmax;
521 return geometries[jg]->hownear(ilocal,x);
523 return g->hownear(ireg,x);
527 int nstep = g->getMaxStep();
528 for (
int j=0; j<n_in; ++j) {
529 nstep += geometries[j]->getMaxStep();
535 if (ireg >= 0 && ireg < nreg) {
537 return g->hasBooleanProperty(ireg,prop);
539 int jg = (ireg - nbase)/nmax;
540 int ilocal = ireg - nbase - jg*nmax;
541 return geometries[jg]->hasBooleanProperty(ilocal,prop);
546 setPropertyError(
"setBooleanProperty()");
549 setPropertyError(
"addBooleanProperty()");
552 setPropertyError(
"setBooleanProperty()");
555 setPropertyError(
"addBooleanProperty()");
558 const string &
getType()
const {
572 if (ireg < 0 || ireg >= nreg) {
576 return g->getRelativeRho(ireg);
578 int jg = (ireg - nbase)/nmax;
579 return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax);
582 void setBScaling(
int start,
int end, EGS_Float bf);
585 if (ireg < 0 || ireg >= nreg) {
589 return g->getBScaling(ireg);
591 int jg = (ireg - nbase)/nmax;
592 return geometries[jg]->getBScaling(ireg - nbase - jg*nmax);
621 void setPropertyError(
const char *funcname) {
622 egsFatal(
"EGS_EnvelopeGeometry::%s: don't use this method\n Define "
623 "properties in the constituent geometries instead\n",
645 const vector<EnvelopeAux *> &fgeoms,
const string &Name =
"",
646 int newindexing=
false);
651 if (ireg < 0 || ireg >= nreg) {
655 return g->isRealRegion(ireg);
659 jg = reg_to_inscr[ireg-nbase];
660 ilocal = ireg - local_start[jg];
663 jg = (ireg - nbase)/nmax;
664 ilocal = ireg - nbase - jg*nmax;
666 return geometries[jg]->isRealRegion(ilocal);
670 return g->isInside(x);
674 int ireg = g->isWhere(x);
675 if (ireg < 0 || n_start[ireg] < 0) {
678 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
680 int i = geometries[j]->isWhere(x);
682 return nbase + nmax*j + i;
692 int medium(
int ireg)
const {
694 return g->medium(ireg);
696 int jg = (ireg - nbase)/nmax;
697 int ilocal = ireg - nbase - jg*nmax;
698 return geometries[jg]->medium(ilocal);
707 EGS_Float t, ttot = 0;
714 ireg =
howfar(ireg,x,u,t,&imed);
719 isections[0].
rhof = 1;
720 isections[0].
ireg = -1;
721 isections[0].
imed = -1;
735 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
737 egsFatal(
"EGS_FastEnvelope::computeIntersections: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
743 ig = (ireg - nbase)/nmax;
744 ij = ireg - nbase - ig*nmax;
746 isections[j].
imed = imed;
747 isections[j].
ireg = ireg;
751 int ibase = g->howfar(ireg,x,u,t,&imed);
754 for (
int ii=n_start[ireg]; ii<n_start[ireg+1]; ii++) {
756 int ireg_i = geometries[i]->howfar(-1,x,u,t,&imed);
763 isections[j++].
t = ttot;
770 ireg = nbase + ig*nmax + ij;
781 int iadd = nbase + ig*nmax;
782 int nsec = geometries[ig]->computeIntersections(ij,n-j,
786 int nm = nsec >= 0 ? nsec+j : n;
787 for (
int i=j; i<nm; i++) {
788 isections[i].
ireg += iadd;
789 isections[i].
t += ttot;
799 t = isections[j-1].
t - ttot;
801 ttot = isections[j-1].
t;
802 ireg = g->isWhere(x);
807 imed = g->medium(ireg);
820 d = g->howfarToOutside(ireg,x,u);
822 else if (g->regions() == 1) {
823 d = g->howfarToOutside(0,x,u);
826 int ir = g->isWhere(x);
827 d = g->howfarToOutside(ir,x,u);
833 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
840 int ibase = g->howfar(ireg,x,u,t,newmed,normal);
844 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
847 geometries[j]->howfar(-1,x,u,t,newmed,normal);
862 return nbase + jg*nmax + ij;
866 int jg = (ireg - nbase)/nmax;
867 int ilocal = ireg - nbase - jg*nmax;
869 int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal);
871 return nbase + jg*nmax + inew;
878 inew = g->isWhere(x+u*t);
879 if (inew >= 0 && newmed) {
880 *newmed = g->medium(inew);
886 int ienter = g->howfar(ireg,x,u,t,newmed,normal);
891 for (
int jj=n_start[ienter]; jj<n_start[ienter+1]; jj++) {
893 int i = geometries[j]->isWhere(x+u*t);
897 *newmed = geometries[j]->medium(i);
899 return nbase + nmax*j + i;
910 tmin = g->hownear(ireg,x);
914 for (
int jj=n_start[ireg]; jj<n_start[ireg+1]; jj++) {
916 EGS_Float tj = geometries[j]->hownear(-1,x);
926 int jg = (ireg - nbase)/nmax;
927 int ilocal = ireg - nbase - jg*nmax;
928 return geometries[jg]->hownear(ilocal,x);
930 return g->hownear(ireg,x);
934 if (ireg >= 0 && ireg < nreg) {
936 return g->hasBooleanProperty(ireg,prop);
938 int jg = (ireg - nbase)/nmax;
939 int ilocal = ireg - nbase - jg*nmax;
940 return geometries[jg]->hasBooleanProperty(ilocal,prop);
945 setPropertyError(
"setBooleanProperty()");
948 setPropertyError(
"addBooleanProperty()");
951 setPropertyError(
"setBooleanProperty()");
954 setPropertyError(
"addBooleanProperty()");
958 int nstep = g->getMaxStep();
959 for (
int j=0; j<n_in; ++j) {
960 nstep += geometries[j]->getMaxStep();
965 const string &
getType()
const {
974 if (ireg < 0 || ireg >= nreg) {
978 return g->getRelativeRho(ireg);
980 int jg = (ireg - nbase)/nmax;
981 return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax);
984 void setBScaling(
int start,
int end, EGS_Float bf);
987 if (ireg < 0 || ireg >= nreg) {
991 return g->getBScaling(ireg);
993 int jg = (ireg - nbase)/nmax;
994 return geometries[jg]->getBScaling(ireg - nbase - jg*nmax);
1025 void setPropertyError(
const char *funcname) {
1026 egsFatal(
"EGS_FastEnvelope::%s: don't use this method\n Define "
1027 "properties in the constituent geometries instead\n",
EGS_BaseGeometry * g
The envelope geometry.
virtual const string & getType() const =0
Get the geometry type.
EGS_BaseGeometry ** geometries
The inscribed geometries.
virtual bool isInside(const EGS_Vector &x)=0
Is the position x inside the geometry?
int * local_start
First region for each inscribed geometry.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
virtual bool hasBooleanProperty(int ireg, EGS_BPType prop) const
Is the boolean property prop set for region ireg ?
virtual int medium(int ireg) const
Returns the medium index in region ireg.
virtual void printInfo() const
Print information about this geometry.
An envelope geometry class.
EGS_Float t
distance to next region boundary
virtual EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, const EGS_Vector &u)
EGS_Float rhof
relative mass density in that region
virtual int getMaxStep() const
Returns the maximum number of steps through the geometry.
A class representing 3D vectors.
static string type
Geometry type.
Global egspp functions header file.
EGS_BaseGeometry * g
The envelope geometry.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
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.
const EGS_Float veryFar
A very large float.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
int n_in
Number of inscribed geometries.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
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.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
virtual void getLabelRegions(const string &str, vector< int > ®s)
Get the list of all regions labeled with str.
int * reg_to_inscr
Region to inscribed geometry conversion.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
virtual int inside(const EGS_Vector &x)=0
Returns the region index, if inside, or -1 if outside (obsolete)
bool new_indexing
If true, use new indexing style.
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 EGS_Float getRelativeRho(int ireg) const
Get the relative mass density in region ireg.
virtual bool isRealRegion(int ireg) const
Returnes true if ireg is a real region, false otherwise.
An envelope geometry class.
bool new_indexing
If true, use new indexing style.
EGS_BaseGeometry class header file.
int n_in
Number of inscribed geometries.
int * local_start
First region for each inscribed geometry.
int * reg_to_inscr
Region to inscribed geometry conversion.
EGS_BaseGeometry ** geometries
The inscribed geometries.
virtual void addBooleanProperty(int bit)
Add a boolean property for the entire geometry by setting the bit'th bit.
static string type
Geometry type.
virtual void setBooleanProperty(EGS_BPType prop)
Set the boolean properties of the entire geometry to prop.