G4DisplacedSolid.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // Implementation for G4DisplacedSolid class for boolean 
00030 // operations between other solids
00031 //
00032 // History:
00033 //
00034 // 28.10.98 V.Grichine: created
00035 // 14.11.99 V.Grichine: modifications in CalculateExtent(...) method
00036 // 22.11.00 V.Grichine: new set methods for matrix/vectors
00037 //
00038 // --------------------------------------------------------------------
00039 
00040 #include "G4DisplacedSolid.hh"
00041 
00042 #include "G4VoxelLimits.hh"
00043 
00044 #include "G4VPVParameterisation.hh"
00045 
00046 #include "G4VGraphicsScene.hh"
00047 #include "G4Polyhedron.hh"
00048 #include "G4NURBS.hh"
00049 // #include "G4NURBSbox.hh"
00050 
00052 //
00053 // Constructor for transformation like rotation of frame then translation 
00054 // in new frame. It is similar to 1st constractor in G4PVPlacement
00055 
00056 G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
00057                                           G4VSolid* pSolid ,
00058                                           G4RotationMatrix* rotMatrix,
00059                                     const G4ThreeVector& transVector    )
00060   : G4VSolid(pName), fpPolyhedron(0)
00061 {
00062   fPtrSolid = pSolid ;
00063   fPtrTransform = new G4AffineTransform(rotMatrix,transVector) ;
00064   fPtrTransform->Invert() ;
00065   fDirectTransform = new G4AffineTransform(rotMatrix,transVector) ;
00066 }
00067 
00069 //
00070 // Constructor
00071 
00072 G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
00073                                           G4VSolid* pSolid ,
00074                                     const G4Transform3D& transform  )
00075   : G4VSolid(pName), fpPolyhedron(0)
00076 {
00077   fPtrSolid = pSolid ;
00078   fDirectTransform = new G4AffineTransform(transform.getRotation().inverse(),
00079                                            transform.getTranslation()) ;
00080 
00081   fPtrTransform    = new G4AffineTransform(transform.getRotation().inverse(),
00082                                            transform.getTranslation()) ;
00083   fPtrTransform->Invert() ;
00084 }
00085 
00087 //
00088 // Constructor for use with creation of Transient object
00089 // from Persistent object
00090 
00091 G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
00092                                           G4VSolid* pSolid ,
00093                                     const G4AffineTransform directTransform )
00094   : G4VSolid(pName), fpPolyhedron(0)
00095 {
00096   fPtrSolid = pSolid ;
00097   fDirectTransform = new G4AffineTransform( directTransform );
00098   fPtrTransform    = new G4AffineTransform( directTransform.Inverse() ) ; 
00099 }
00100 
00102 //
00103 // Fake default constructor - sets only member data and allocates memory
00104 //                            for usage restricted to object persistency.
00105 
00106 G4DisplacedSolid::G4DisplacedSolid( __void__& a )
00107   : G4VSolid(a), fPtrSolid(0), fPtrTransform(0),
00108     fDirectTransform(0), fpPolyhedron(0)
00109 {
00110 }
00111 
00113 //
00114 // Destructor
00115 
00116 G4DisplacedSolid::~G4DisplacedSolid() 
00117 {
00118   CleanTransformations();
00119   delete fpPolyhedron;
00120 }
00121 
00123 //
00124 // Copy constructor
00125 
00126 G4DisplacedSolid::G4DisplacedSolid(const G4DisplacedSolid& rhs)
00127   : G4VSolid (rhs), fPtrSolid(rhs.fPtrSolid), fpPolyhedron(0)
00128 {
00129   fPtrTransform = new G4AffineTransform(*(rhs.fPtrTransform));
00130   fDirectTransform = new G4AffineTransform(*(rhs.fDirectTransform));
00131 }
00132 
00134 //
00135 // Assignment operator
00136 
00137 G4DisplacedSolid& G4DisplacedSolid::operator = (const G4DisplacedSolid& rhs) 
00138 {
00139   // Check assignment to self
00140   //
00141   if (this == &rhs)  { return *this; }
00142 
00143   // Copy base class data
00144   //
00145   G4VSolid::operator=(rhs);
00146 
00147   // Copy data
00148   //
00149   fPtrSolid = rhs.fPtrSolid;
00150   delete fPtrTransform; delete fDirectTransform;
00151   fPtrTransform = new G4AffineTransform(*(rhs.fPtrTransform));
00152   fDirectTransform = new G4AffineTransform(*(rhs.fDirectTransform));
00153   delete fpPolyhedron; fpPolyhedron= 0;
00154 
00155   return *this;
00156 }  
00157 
00158 void G4DisplacedSolid::CleanTransformations()
00159 {
00160   if(fPtrTransform)
00161   {
00162     delete fPtrTransform;  fPtrTransform=0;
00163     delete fDirectTransform;  fDirectTransform=0;
00164   }
00165 }
00166 
00167 const G4DisplacedSolid* G4DisplacedSolid::GetDisplacedSolidPtr() const   
00168 {
00169   return this;
00170 }
00171 
00172 G4DisplacedSolid* G4DisplacedSolid::GetDisplacedSolidPtr() 
00173 {
00174   return this;
00175 }
00176 
00177 G4VSolid* G4DisplacedSolid::GetConstituentMovedSolid() const
00178 { 
00179   return fPtrSolid; 
00180 } 
00181 
00183 
00184 G4AffineTransform  G4DisplacedSolid::GetTransform() const
00185 {
00186   G4AffineTransform aTransform = *fPtrTransform;
00187   return aTransform;
00188 }
00189 
00190 void G4DisplacedSolid::SetTransform(G4AffineTransform& transform) 
00191 {
00192   fPtrTransform = &transform ;
00193   fpPolyhedron = 0;
00194 }
00195 
00197 
00198 G4AffineTransform  G4DisplacedSolid::GetDirectTransform() const
00199 {
00200   G4AffineTransform aTransform= *fDirectTransform;
00201   return aTransform;
00202 }
00203 
00204 void G4DisplacedSolid::SetDirectTransform(G4AffineTransform& transform) 
00205 {
00206   fDirectTransform = &transform ;
00207   fpPolyhedron = 0;
00208 }
00209 
00211 
00212 G4RotationMatrix G4DisplacedSolid::GetFrameRotation() const
00213 {
00214   G4RotationMatrix InvRotation= fDirectTransform->NetRotation();
00215   return InvRotation;
00216 }
00217 
00218 void G4DisplacedSolid::SetFrameRotation(const G4RotationMatrix& matrix)
00219 {
00220   fDirectTransform->SetNetRotation(matrix);
00221   fpPolyhedron = 0;
00222 }
00223 
00225 
00226 G4ThreeVector  G4DisplacedSolid::GetFrameTranslation() const
00227 {
00228   return fPtrTransform->NetTranslation();
00229 }
00230 
00231 void G4DisplacedSolid::SetFrameTranslation(const G4ThreeVector& vector)
00232 {
00233   fPtrTransform->SetNetTranslation(vector);
00234   fpPolyhedron = 0;
00235 }
00236 
00238 
00239 G4RotationMatrix G4DisplacedSolid::GetObjectRotation() const
00240 {
00241   G4RotationMatrix Rotation= fPtrTransform->NetRotation();
00242   return Rotation;
00243 }
00244 
00245 void G4DisplacedSolid::SetObjectRotation(const G4RotationMatrix& matrix)
00246 {
00247   fPtrTransform->SetNetRotation(matrix);
00248   fpPolyhedron = 0;
00249 }
00250 
00252 
00253 G4ThreeVector  G4DisplacedSolid::GetObjectTranslation() const
00254 {
00255   return fDirectTransform->NetTranslation();
00256 }
00257 
00258 void G4DisplacedSolid::SetObjectTranslation(const G4ThreeVector& vector)
00259 {
00260   fDirectTransform->SetNetTranslation(vector);
00261   fpPolyhedron = 0;
00262 }
00263 
00265 //
00266 //
00267      
00268 G4bool 
00269 G4DisplacedSolid::CalculateExtent( const EAxis pAxis,
00270                                    const G4VoxelLimits& pVoxelLimit,
00271                                    const G4AffineTransform& pTransform,
00272                                          G4double& pMin, 
00273                                          G4double& pMax           ) const 
00274 {
00275   G4AffineTransform sumTransform ;
00276   sumTransform.Product(*fDirectTransform,pTransform) ;
00277   return fPtrSolid->CalculateExtent(pAxis,pVoxelLimit,sumTransform,pMin,pMax) ;
00278 }
00279  
00281 //
00282 // 
00283 
00284 EInside G4DisplacedSolid::Inside(const G4ThreeVector& p) const
00285 {
00286   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
00287   return fPtrSolid->Inside(newPoint) ; 
00288 }
00289 
00291 //
00292 //
00293 
00294 G4ThreeVector 
00295 G4DisplacedSolid::SurfaceNormal( const G4ThreeVector& p ) const 
00296 {
00297   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
00298   G4ThreeVector normal = fPtrSolid->SurfaceNormal(newPoint) ; 
00299   return fDirectTransform->TransformAxis(normal) ;
00300 }
00301 
00303 //
00304 // The same algorithm as in DistanceToIn(p)
00305 
00306 G4double 
00307 G4DisplacedSolid::DistanceToIn( const G4ThreeVector& p,
00308                                 const G4ThreeVector& v  ) const 
00309 {    
00310   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
00311   G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
00312   return fPtrSolid->DistanceToIn(newPoint,newDirection) ;   
00313 }
00314 
00316 //
00317 // Approximate nearest distance from the point p to the intersection of
00318 // two solids
00319 
00320 G4double 
00321 G4DisplacedSolid::DistanceToIn( const G4ThreeVector& p ) const 
00322 {
00323   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
00324   return fPtrSolid->DistanceToIn(newPoint) ;   
00325 }
00326 
00328 //
00329 // The same algorithm as DistanceToOut(p)
00330 
00331 G4double 
00332 G4DisplacedSolid::DistanceToOut( const G4ThreeVector& p,
00333                                  const G4ThreeVector& v,
00334                                  const G4bool calcNorm,
00335                                        G4bool *validNorm,
00336                                        G4ThreeVector *n   ) const 
00337 {
00338   G4ThreeVector solNorm ; 
00339   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
00340   G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
00341   G4double dist = fPtrSolid->DistanceToOut(newPoint,newDirection,
00342                                            calcNorm,validNorm,&solNorm) ;
00343   if(calcNorm)
00344   { 
00345     *n = fDirectTransform->TransformAxis(solNorm) ;
00346   }
00347   return dist ;  
00348 }
00349 
00351 //
00352 // Inverted algorithm of DistanceToIn(p)
00353 
00354 G4double 
00355 G4DisplacedSolid::DistanceToOut( const G4ThreeVector& p ) const 
00356 {
00357   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
00358   return fPtrSolid->DistanceToOut(newPoint) ;   
00359 }
00360 
00362 //
00363 //
00364 
00365 void 
00366 G4DisplacedSolid::ComputeDimensions(       G4VPVParameterisation*,
00367                                      const G4int,
00368                                      const G4VPhysicalVolume* ) 
00369 {
00370   DumpInfo();
00371   G4Exception("G4DisplacedSolid::ComputeDimensions()",
00372               "GeomSolids0001", FatalException,
00373               "Method not applicable in this context!");
00374 }
00375 
00377 //
00378 // Returns a point (G4ThreeVector) randomly and uniformly selected
00379 // on the solid surface
00380 //
00381 
00382 G4ThreeVector G4DisplacedSolid::GetPointOnSurface() const
00383 {
00384   G4ThreeVector p =  fPtrSolid->GetPointOnSurface();
00385   return fDirectTransform->TransformPoint(p);
00386 }
00387 
00389 //
00390 // Return object type name
00391 
00392 G4GeometryType G4DisplacedSolid::GetEntityType() const 
00393 {
00394   return G4String("G4DisplacedSolid");
00395 }
00396 
00398 //
00399 // Make a clone of the object
00400 //
00401 G4VSolid* G4DisplacedSolid::Clone() const
00402 {
00403   return new G4DisplacedSolid(*this);
00404 }
00405 
00407 //
00408 // Stream object contents to an output stream
00409 
00410 std::ostream& G4DisplacedSolid::StreamInfo(std::ostream& os) const
00411 {
00412   os << "-----------------------------------------------------------\n"
00413      << "    *** Dump for Displaced solid - " << GetName() << " ***\n"
00414      << "    ===================================================\n"
00415      << " Solid type: " << GetEntityType() << "\n"
00416      << " Parameters of constituent solid: \n"
00417      << "===========================================================\n";
00418   fPtrSolid->StreamInfo(os);
00419   os << "===========================================================\n"
00420      << " Transformations: \n"
00421      << "    Direct transformation - translation : \n"
00422      << "           " << fDirectTransform->NetTranslation() << "\n"
00423      << "                          - rotation    : \n"
00424      << "           ";
00425   fDirectTransform->NetRotation().print(os);
00426   os << "\n"
00427      << "===========================================================\n";
00428 
00429   return os;
00430 }
00431 
00433 //
00434 //                    
00435 
00436 void 
00437 G4DisplacedSolid::DescribeYourselfTo ( G4VGraphicsScene& scene ) const 
00438 {
00439   scene.AddSolid (*this);
00440 }
00441 
00443 //
00444 //
00445 
00446 G4Polyhedron* 
00447 G4DisplacedSolid::CreatePolyhedron () const 
00448 {
00449   G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron();
00450   polyhedron
00451     ->Transform(G4Transform3D(GetObjectRotation(),GetObjectTranslation()));
00452   return polyhedron;
00453 }
00454 
00456 //
00457 //
00458 
00459 G4NURBS*      
00460 G4DisplacedSolid::CreateNURBS () const 
00461 {
00462   // Take into account local transformation - see CreatePolyhedron.
00463   // return fPtrSolid->CreateNURBS() ;
00464   return 0;
00465 }
00466 
00468 //
00469 //
00470 
00471 G4Polyhedron* G4DisplacedSolid::GetPolyhedron () const
00472 {
00473   if (!fpPolyhedron ||
00474       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
00475       fpPolyhedron->GetNumberOfRotationSteps())
00476     {
00477       delete fpPolyhedron;
00478       fpPolyhedron = CreatePolyhedron();
00479     }
00480   return fpPolyhedron;
00481 }

Generated on Mon May 27 17:48:01 2013 for Geant4 by  doxygen 1.4.7