00001
00002
00003
00004
00005
00006
00007
00008 #ifdef __GNUG__
00009 #pragma implementation
00010 #endif
00011
00012 #include "gismo/CompositeMedium.h"
00013
00014 #include "gismo/Detector.h"
00015 #include "gismo/Material.h"
00016 #include "gismo/Field.h"
00017 #include "gui/DisplayRep.h"
00018
00019 #include "geometry/Shape.h"
00020 #include "geometry/Volume.h"
00021 #include "geometry/Ray.h"
00022 #include "facilities/error.h"
00023
00024 # include <algorithm>
00026
00027
00028 CompositeMedium::CompositeMedium(Medium * prnt, float size)
00029 : Medium(prnt, size)
00030 {}
00031
00032 CompositeMedium::CompositeMedium(Medium* prnt, Shape* vol, const char* matName, Detector* det)
00033 : Medium(prnt, vol, matName, det)
00034 {}
00035
00036 CompositeMedium::~CompositeMedium()
00037 {
00038 deleteInnerMedia();
00039 if(_parent) {
00040 _parent->removeMedium(this);
00041 if(&_parent->field() != _field) delete _field;
00042 }
00043 }
00045
00046 Medium& CompositeMedium::setField(Field* fld)
00047 {
00048 for(iterator it=begin(); it !=end(); ++it )
00049 if(&((*it)->field()) == _field) (*it)->setField(fld);
00050 return Medium::setField(fld);
00051 }
00052
00053 Medium& CompositeMedium::setKECutOff(float keCut)
00054 {
00055 for(iterator it=begin(); it !=end(); ++it )
00056 if((*it)->kECutOff() == _keCutOff) (*it)->setKECutOff(keCut);
00057 return Medium::setKECutOff(keCut);
00058 }
00059
00060 Medium& CompositeMedium::setMaxStep(float mxStep)
00061 {
00062 for(iterator it=begin(); it !=end(); ++it )
00063 if( (*it)->maxStep() == maxStep()) (*it)->setMaxStep(mxStep);
00064
00065 return Medium::setMaxStep(mxStep);
00066 }
00067
00068
00070
00071 void CompositeMedium::deleteInnerMedia()
00072 {
00073 for(reverse_iterator it=rbegin(); it !=rend(); ++it)
00074 delete *it;
00075 }
00076
00077 Medium& CompositeMedium::addMedium ( Medium* nextMedium)
00078 {
00079 push_back(nextMedium);
00080 nextMedium->setParent(this);
00081 return *nextMedium;
00082 }
00083
00084 Medium& CompositeMedium::removeMedium (Medium* oldMedium)
00085 {
00086 iterator it = std::find(begin(), end(), oldMedium);
00087 if( it != end())
00088 erase(it);
00089 return *oldMedium;
00090 }
00091
00092 const char* CompositeMedium::nameOf() const {
00093 return "CompositeMedium";
00094 }
00095
00096 int CompositeMedium::isComposite() const {
00097 return 1;
00098 }
00099
00101
00102 GeomObject&
00103 CompositeMedium::transform(const CoordTransform& T)
00104 {
00105 Medium::transform(T);
00106 for(iterator it=begin(); it !=end(); ++it)
00107 (*it)->transform(T);
00108 return *this;
00109 }
00110
00112
00113 void CompositeMedium::clear()
00114 {
00115 Medium::clear();
00116
00117 for(iterator it=begin(); it !=end(); ++it)
00118 (*it)->clear();
00119 }
00120
00121 void CompositeMedium::generateResponse()
00122 {
00123 Medium::generateResponse();
00124 for(iterator it=begin(); it !=end(); ++it)
00125 (*it)->generateResponse();
00126
00127 }
00128 void CompositeMedium::accept(DetectorVisitor& a)
00129 {
00130 Medium::accept(a);
00131 for(iterator it=begin(); it !=end(); ++it)
00132 (*it)->accept(a);
00133 }
00134
00135 void
00136 CompositeMedium::writeData(std::ostream & os)
00137 {
00138 Medium::writeData(os);
00139 for(iterator it=begin(); it !=end(); ++it)
00140 (*it)->writeData(os);
00141 }
00142
00143 void
00144 CompositeMedium::readData(std::istream & is)
00145 {
00146 Medium::readData(is);
00147 for(iterator it=begin(); it !=end(); ++it)
00148 (*it)->readData(is);
00149 }
00150 void CompositeMedium::notify()
00151 {
00152 Medium::notify();
00153 for(iterator it=begin(); it !=end(); ++it)
00154 (*it)->notify();
00155 }
00156
00157
00159
00160
00161 const Medium *
00162 CompositeMedium::inside(const Point& r)const
00163 {
00164
00165 const Medium* nextStuff = Medium::inside(r);
00166 if( nextStuff != this )
00167 return nextStuff;
00168
00169
00170 nextStuff = this;
00171
00172 for(const_iterator it=begin(); it !=end(); ++it ) {
00173 nextStuff = (*it)->inside(r) ;
00174 if(nextStuff != this) break;
00175 }
00176 return nextStuff;
00177 }
00178
00179
00180
00181 double
00182 CompositeMedium::distanceToLeave( const Ray& r,
00183 const Medium* & newStuff,
00184 double maxDist ) const
00185 {
00186
00187
00188 float distance = Medium::distanceToLeave(r, newStuff, maxDist);
00189
00190
00191 if(distance < Volume::Surface_EPSILON) return distance;
00192
00193
00194
00195 for(const_iterator it=begin(); it !=end(); ++it){
00196 const Medium* inner = *it;
00197
00198 maxDist = (maxDist > distance) ? distance : maxDist;
00199 const Medium *nextStuff;
00200
00201 double testDistance = inner->distanceToEnter( r, nextStuff, maxDist );
00202 if(testDistance <= distance) {
00203 newStuff = nextStuff;
00204 distance = testDistance;
00205 if( distance==0 )
00206 {
00207
00208 break;
00209 }
00210 }
00211 }
00212 return distance;
00213 }
00214
00215
00216
00217
00218
00219 void CompositeMedium::printOn( std::ostream& os ) const
00220 {
00221 Medium::printOn(os);
00222 int i=0;
00223 for(const_iterator it=begin(); it !=end(); ++it) {
00224
00225 os << "\n" << title() <<" inner Medium# "<< ++i ;
00226 (*it)->printOn(os);
00227 }
00228 }
00229
00230 void
00231 CompositeMedium::printResponse(std::ostream& os)const
00232 {
00233 Medium::printResponse(os);
00234 for(const_iterator it=begin(); it !=end(); ++it)
00235 (*it)->printResponse(os);
00236 }
00237
00238 void CompositeMedium::createDetectorView(gui::DisplayRep& v)
00239 {
00240
00241 Medium::createDetectorView(v);
00242 for(iterator it=begin(); it !=end(); ++it )
00243 (*it)->createDetectorView(v.nested());
00244 }
00245
00246 void CompositeMedium::createResponseView(gui::DisplayRep& v)
00247 {
00248 Medium::createResponseView(v);
00249 for(iterator it=begin(); it !=end(); ++it )
00250 (*it)->createResponseView(v);
00251 }
00252
00253