00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Riostream.h"
00014
00015 #include "TGeoManager.h"
00016 #include "TGeoMatrix.h"
00017 #include "TGeoVolume.h"
00018 #include "TGeoNode.h"
00019 #include "TGeoScaledShape.h"
00020 #include "TBuffer3D.h"
00021 #include "TBuffer3DTypes.h"
00022 #include "TMath.h"
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 ClassImp(TGeoScaledShape)
00036
00037
00038 TGeoScaledShape::TGeoScaledShape()
00039 {
00040
00041 fShape = 0;
00042 fScale = 0;
00043 }
00044
00045
00046
00047 TGeoScaledShape::TGeoScaledShape(const char *name, TGeoShape *shape, TGeoScale *scale)
00048 :TGeoBBox(name,0,0,0)
00049 {
00050
00051 fShape = shape;
00052 fScale = scale;
00053 if (!fScale->IsRegistered()) fScale->RegisterYourself();
00054 ComputeBBox();
00055 }
00056
00057
00058 TGeoScaledShape::TGeoScaledShape(TGeoShape *shape, TGeoScale *scale)
00059 {
00060
00061 fShape = shape;
00062 fScale = scale;
00063 if (!fScale->IsRegistered()) fScale->RegisterYourself();
00064 ComputeBBox();
00065 }
00066
00067
00068 TGeoScaledShape::~TGeoScaledShape()
00069 {
00070
00071 }
00072
00073
00074 Double_t TGeoScaledShape::Capacity() const
00075 {
00076
00077 Double_t capacity = fShape->Capacity();
00078 const Double_t *scale = fScale->GetScale();
00079 capacity *= scale[0]*scale[1]*scale[2];
00080 return capacity;
00081 }
00082
00083
00084 void TGeoScaledShape::ComputeBBox()
00085 {
00086
00087 if (!fShape) {
00088 Error("ComputeBBox", "Scaled shape %s without shape", GetName());
00089 return;
00090 }
00091 TGeoBBox *box = (TGeoBBox*)fShape;
00092 const Double_t *orig = box->GetOrigin();
00093 Double_t point[3], master[3];
00094 point[0] = box->GetDX();
00095 point[1] = box->GetDY();
00096 point[2] = box->GetDZ();
00097
00098 fScale->LocalToMaster(orig, fOrigin);
00099 fScale->LocalToMaster(point, master);
00100 fDX = TMath::Abs(master[0]);
00101 fDY = TMath::Abs(master[1]);
00102 fDZ = TMath::Abs(master[2]);
00103 }
00104
00105
00106 void TGeoScaledShape::ComputeNormal(Double_t *point, Double_t *dir, Double_t *norm)
00107 {
00108
00109 Double_t local[3], ldir[3], lnorm[3];
00110 fScale->MasterToLocal(point,local);
00111 fScale->MasterToLocalVect(dir,ldir);
00112 TGeoMatrix::Normalize(ldir);
00113 fShape->ComputeNormal(local,ldir,lnorm);
00114
00115 fScale->MasterToLocalVect(lnorm, norm);
00116 TGeoMatrix::Normalize(norm);
00117 }
00118
00119
00120 Bool_t TGeoScaledShape::Contains(Double_t *point) const
00121 {
00122
00123 Double_t local[3];
00124 fScale->MasterToLocal(point,local);
00125 return fShape->Contains(local);
00126 }
00127
00128
00129 Int_t TGeoScaledShape::DistancetoPrimitive(Int_t px, Int_t py)
00130 {
00131
00132 Int_t n = fShape->GetNmeshVertices();
00133 return ShapeDistancetoPrimitive(n, px, py);
00134 }
00135
00136
00137 Double_t TGeoScaledShape::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00138 {
00139
00140 Double_t local[3], ldir[3];
00141 Double_t lstep;
00142 fScale->MasterToLocal(point,local);
00143 lstep = fScale->MasterToLocal(step, dir);
00144 fScale->MasterToLocalVect(dir,ldir);
00145 TGeoMatrix::Normalize(ldir);
00146 Double_t dist = fShape->DistFromInside(local,ldir, iact, lstep, safe);
00147 if (iact<3 && safe) *safe = fScale->LocalToMaster(*safe);
00148 dist = fScale->LocalToMaster(dist, ldir);
00149 return dist;
00150 }
00151
00152
00153
00154 Double_t TGeoScaledShape::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
00155 {
00156
00157 Double_t local[3], ldir[3];
00158 Double_t lstep;
00159
00160 fScale->MasterToLocal(point,local);
00161
00162 lstep = fScale->MasterToLocal(step, dir);
00163 fScale->MasterToLocalVect(dir,ldir);
00164 TGeoMatrix::Normalize(ldir);
00165
00166 Double_t dist = fShape->DistFromOutside(local,ldir, iact, lstep, safe);
00167
00168 if (safe) *safe = fScale->LocalToMaster(*safe);
00169 dist = fScale->LocalToMaster(dist, ldir);
00170
00171 return dist;
00172 }
00173
00174
00175 TGeoVolume *TGeoScaledShape::Divide(TGeoVolume * , const char *divname, Int_t , Int_t ,
00176 Double_t , Double_t )
00177 {
00178
00179 Error("Divide", "Scaled shapes cannot be divided. Division volume %s not created", divname);
00180 return 0;
00181 }
00182
00183
00184 const TBuffer3D & TGeoScaledShape::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
00185 {
00186
00187 TBuffer3D &buffer = (TBuffer3D &)fShape->GetBuffer3D(reqSections, localFrame);
00188
00189
00190 Double_t halfLengths[3] = { fDX, fDY, fDZ };
00191 buffer.SetAABoundingBox(fOrigin, halfLengths);
00192 if (!buffer.fLocalFrame) {
00193 TransformPoints(buffer.fBBVertex[0], 8);
00194 }
00195
00196 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
00197 SetPoints(buffer.fPnts);
00198 if (!buffer.fLocalFrame) {
00199 TransformPoints(buffer.fPnts, buffer.NbPnts());
00200 }
00201 }
00202
00203 return buffer;
00204 }
00205
00206 TGeoShape *TGeoScaledShape::GetMakeRuntimeShape(TGeoShape * , TGeoMatrix * ) const
00207 {
00208
00209
00210 Error("GetMakeRuntimeShape", "Scaled shapes cannot be parametrized.");
00211 return NULL;
00212 }
00213
00214
00215 void TGeoScaledShape::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
00216 {
00217
00218 fShape->GetMeshNumbers(nvert, nsegs, npols);
00219 }
00220
00221
00222 void TGeoScaledShape::InspectShape() const
00223 {
00224
00225 printf("*** Shape %s: TGeoScaledShape ***\n", GetName());
00226 fScale->Print();
00227 fShape->InspectShape();
00228 TGeoBBox::InspectShape();
00229 }
00230
00231
00232 Bool_t TGeoScaledShape::IsReflected() const
00233 {
00234
00235 return fScale->IsReflection();
00236 }
00237
00238
00239 TBuffer3D *TGeoScaledShape::MakeBuffer3D() const
00240 {
00241
00242
00243
00244 TBuffer3D *buff = fShape->MakeBuffer3D();
00245 if (buff) SetPoints(buff->fPnts);
00246 return buff;
00247 }
00248
00249
00250 TGeoShape *TGeoScaledShape::MakeScaledShape(const char *name, TGeoShape *shape, TGeoScale *scale)
00251 {
00252
00253 TGeoShape *new_shape;
00254 if (shape->IsA() == TGeoScaledShape::Class()) {
00255 TGeoScaledShape *sshape = (TGeoScaledShape*)shape;
00256 TGeoScale *old_scale = sshape->GetScale();
00257 TGeoShape *old_shape = sshape->GetShape();
00258 scale->SetScale(scale->GetScale()[0]*old_scale->GetScale()[0],
00259 scale->GetScale()[1]*old_scale->GetScale()[1],
00260 scale->GetScale()[2]*old_scale->GetScale()[2]);
00261 new_shape = new TGeoScaledShape(name, old_shape, scale);
00262 return new_shape;
00263 }
00264 new_shape = new TGeoScaledShape(name, shape, scale);
00265 return new_shape;
00266 }
00267
00268
00269 void TGeoScaledShape::SetSegsAndPols(TBuffer3D &buff) const
00270 {
00271
00272 fShape->SetSegsAndPols(buff);
00273 }
00274
00275
00276 Double_t TGeoScaledShape::Safety(Double_t *point, Bool_t in) const
00277 {
00278
00279
00280 Double_t local[3];
00281 fScale->MasterToLocal(point,local);
00282 Double_t safe = fShape->Safety(local,in);
00283 safe = fScale->LocalToMaster(safe);
00284 return safe;
00285 }
00286
00287
00288 void TGeoScaledShape::SavePrimitive(ostream &out, Option_t *option)
00289 {
00290
00291 if (TObject::TestBit(kGeoSavePrimitive)) return;
00292 out << " // Shape: " << GetName() << " type: " << ClassName() << endl;
00293 if (!fShape || !fScale) {
00294 out << "##### Invalid shape or scale !. Aborting. #####" << endl;
00295 return;
00296 }
00297 fShape->SavePrimitive(out, option);
00298 TString sname = fShape->GetPointerName();
00299 const Double_t *sc = fScale->GetScale();
00300 out << " // Scale factor:" << endl;
00301 out << " TGeoScale *pScale = new TGeoScale(\"" << fScale->GetName()
00302 << "\"," << sc[0] << "," << sc[1] << "," << sc[2] << ");" << endl;
00303 out << " TGeoScaledShape *" << GetPointerName() << " = new TGeoScaledShape(\""
00304 << GetName() << "\"," << sname << ", pScale);" << endl;
00305 }
00306
00307
00308 void TGeoScaledShape::SetPoints(Double_t *points) const
00309 {
00310
00311 Int_t npts = fShape->GetNmeshVertices();
00312 fShape->SetPoints(points);
00313 Double_t master[3];
00314 for (Int_t i=0; i<npts; i++) {
00315 fScale->LocalToMaster(&points[3*i], master);
00316 memcpy(&points[3*i], master, 3*sizeof(Double_t));
00317 }
00318 }
00319
00320
00321 void TGeoScaledShape::SetPoints(Float_t *points) const
00322 {
00323
00324 Int_t npts = fShape->GetNmeshVertices();
00325 fShape->SetPoints(points);
00326 Double_t master[3];
00327 Double_t local[3];
00328 Int_t index;
00329 for (Int_t i=0; i<npts; i++) {
00330 index = 3*i;
00331 local[0] = points[index];
00332 local[1] = points[index+1];
00333 local[2] = points[index+2];
00334 fScale->LocalToMaster(local, master);
00335 points[index] = master[0];
00336 points[index+1] = master[1];
00337 points[index+2] = master[2];
00338 }
00339 }