TGeoScaledShape.cxx

Go to the documentation of this file.
00001 // @(#)root/geom:$Id: TGeoScaledShape.cxx 32735 2010-03-24 16:27:32Z brun $
00002 // Author: Andrei Gheata   26/09/05
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
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 // TGeoScaledShape - A shape scaled by a TGeoScale transformation
00026 //    
00027 //Begin_Html
00028 /*
00029 <img src="gif/TGeoScaledShape.gif">
00030 */
00031 //End_Html
00032 //_____________________________________________________________________________
00033 
00034 
00035 ClassImp(TGeoScaledShape)
00036    
00037 //_____________________________________________________________________________
00038 TGeoScaledShape::TGeoScaledShape()
00039 {
00040 // Default constructor
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 // Constructor
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 // Constructor
00061    fShape = shape;
00062    fScale = scale;
00063    if (!fScale->IsRegistered()) fScale->RegisterYourself();
00064    ComputeBBox();
00065 }
00066 
00067 //_____________________________________________________________________________
00068 TGeoScaledShape::~TGeoScaledShape()
00069 {
00070 // destructor
00071 }
00072 
00073 //_____________________________________________________________________________
00074 Double_t TGeoScaledShape::Capacity() const
00075 {
00076 // Computes capacity of this shape [length^3]
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 // Compute bounding box of the scaled shape
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 // Compute normal to closest surface from POINT.
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 //   fScale->LocalToMasterVect(lnorm, norm);
00115    fScale->MasterToLocalVect(lnorm, norm);
00116    TGeoMatrix::Normalize(norm);
00117 }
00118 
00119 //_____________________________________________________________________________
00120 Bool_t TGeoScaledShape::Contains(Double_t *point) const
00121 {
00122 // Test if point is inside the scaled shape
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 // compute closest distance from point px,py to each vertex. Should not be called.
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 // Compute distance from inside point to surface of the scaled shape.
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 // Compute distance from outside point to surface of the scaled shape.
00157    Double_t local[3], ldir[3];
00158    Double_t lstep;
00159 //   printf("DistFromOutside(%f,%f,%f,  %f,%f,%f)\n", point[0], point[1], point[2], dir[0], dir[1],dir[2]);
00160    fScale->MasterToLocal(point,local);
00161 //   printf("local: %f,%f,%f\n", local[0],local[1], local[2]);
00162    lstep = fScale->MasterToLocal(step, dir);
00163    fScale->MasterToLocalVect(dir,ldir);
00164    TGeoMatrix::Normalize(ldir);
00165 //   printf("localdir: %f,%f,%f\n",ldir[0],ldir[1],ldir[2]);
00166    Double_t dist = fShape->DistFromOutside(local,ldir, iact, lstep, safe);
00167 //   printf("local distance: %f\n", dist);
00168    if (safe) *safe = fScale->LocalToMaster(*safe);
00169    dist = fScale->LocalToMaster(dist, ldir);
00170 //   printf("converted distance: %f\n",dist);
00171    return dist;
00172 }
00173    
00174 //_____________________________________________________________________________
00175 TGeoVolume *TGeoScaledShape::Divide(TGeoVolume * /*voldiv*/, const char *divname, Int_t /*iaxis*/, Int_t /*ndiv*/, 
00176                              Double_t /*start*/, Double_t /*step*/) 
00177 {
00178 // Cannot divide assemblies.
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 // Fills a static 3D buffer and returns a reference.
00187    TBuffer3D &buffer = (TBuffer3D &)fShape->GetBuffer3D(reqSections, localFrame);
00188 
00189 //   TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
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 * /*mother*/, TGeoMatrix * /*mat*/) const
00207 {
00208 // in case shape has some negative parameters, these has to be computed
00209 // in order to fit the mother
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 // Returns numbers of vertices, segments and polygons composing the shape mesh.
00218    fShape->GetMeshNumbers(nvert, nsegs, npols);
00219 }
00220         
00221 //_____________________________________________________________________________
00222 void TGeoScaledShape::InspectShape() const
00223 {
00224 // print shape parameters
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 // Check if the scale transformation is a reflection.
00235    return fScale->IsReflection();
00236 }
00237 
00238 //_____________________________________________________________________________
00239 TBuffer3D *TGeoScaledShape::MakeBuffer3D() const
00240 { 
00241    // Creates a TBuffer3D describing *this* shape.
00242    // Coordinates are in local reference frame.
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 // Create a scaled shape starting from a non-scaled one.
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 // Fill TBuffer3D structure for segments and polygons.
00272    fShape->SetSegsAndPols(buff);
00273 }
00274 
00275 //_____________________________________________________________________________
00276 Double_t TGeoScaledShape::Safety(Double_t *point, Bool_t in) const
00277 {
00278 // computes the closest distance from given point to this shape, according
00279 // to option. The matching point on the shape is stored in spoint.
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 // Save a primitive as a C++ statement(s) on output stream "out".
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 // Mesh points for scaled shapes.
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 // Mesh points for scaled shapes.
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 }

Generated on Tue Jul 5 14:12:57 2011 for ROOT_528-00b_version by  doxygen 1.5.1