Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4DisplacedSolid.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4DisplacedSolid.cc 101046 2016-11-04 10:44:26Z gcosmo $
28 //
29 // Implementation for G4DisplacedSolid class for boolean
30 // operations between other solids
31 //
32 // History:
33 //
34 // 28.10.98 V.Grichine: created
35 // 14.11.99 V.Grichine: modifications in CalculateExtent(...) method
36 // 22.11.00 V.Grichine: new set methods for matrix/vectors
37 //
38 // --------------------------------------------------------------------
39 
40 #include "G4DisplacedSolid.hh"
41 
42 #include "G4VoxelLimits.hh"
43 
44 #include "G4VPVParameterisation.hh"
45 
46 #include "G4VGraphicsScene.hh"
47 #include "G4Polyhedron.hh"
48 
50 //
51 // Constructor for transformation like rotation of frame then translation
52 // in new frame. It is similar to 1st constractor in G4PVPlacement
53 
55  G4VSolid* pSolid ,
56  G4RotationMatrix* rotMatrix,
57  const G4ThreeVector& transVector )
58  : G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0)
59 {
60  fPtrSolid = pSolid ;
61  fPtrTransform = new G4AffineTransform(rotMatrix,transVector) ;
63  fDirectTransform = new G4AffineTransform(rotMatrix,transVector) ;
64 }
65 
67 //
68 // Constructor
69 
71  G4VSolid* pSolid ,
72  const G4Transform3D& transform )
73  : G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0)
74 {
75  fPtrSolid = pSolid ;
77  transform.getTranslation()) ;
78 
80  transform.getTranslation()) ;
81  fPtrTransform->Invert() ;
82 }
83 
85 //
86 // Constructor for use with creation of Transient object
87 // from Persistent object
88 
90  G4VSolid* pSolid ,
91  const G4AffineTransform directTransform )
92  : G4VSolid(pName), fRebuildPolyhedron(false), fpPolyhedron(0)
93 {
94  fPtrSolid = pSolid ;
95  fDirectTransform = new G4AffineTransform( directTransform );
96  fPtrTransform = new G4AffineTransform( directTransform.Inverse() ) ;
97 }
98 
100 //
101 // Fake default constructor - sets only member data and allocates memory
102 // for usage restricted to object persistency.
103 
105  : G4VSolid(a), fPtrSolid(0), fPtrTransform(0),
106  fDirectTransform(0), fRebuildPolyhedron(false), fpPolyhedron(0)
107 {
108 }
109 
111 //
112 // Destructor
113 
115 {
117  delete fpPolyhedron; fpPolyhedron = 0;
118 }
119 
121 //
122 // Copy constructor
123 
125  : G4VSolid (rhs), fPtrSolid(rhs.fPtrSolid),
126  fRebuildPolyhedron(false), fpPolyhedron(0)
127 {
130 }
131 
133 //
134 // Assignment operator
135 
137 {
138  // Check assignment to self
139  //
140  if (this == &rhs) { return *this; }
141 
142  // Copy base class data
143  //
144  G4VSolid::operator=(rhs);
145 
146  // Copy data
147  //
148  fPtrSolid = rhs.fPtrSolid;
149  delete fPtrTransform; delete fDirectTransform;
152  fRebuildPolyhedron = false;
153  delete fpPolyhedron; fpPolyhedron= 0;
154 
155  return *this;
156 }
157 
159 {
160  if(fPtrTransform)
161  {
162  delete fPtrTransform; fPtrTransform=0;
164  }
165 }
166 
168 {
169  return this;
170 }
171 
173 {
174  return this;
175 }
176 
178 {
179  return fPtrSolid;
180 }
181 
183 
185 {
186  G4AffineTransform aTransform = *fPtrTransform;
187  return aTransform;
188 }
189 
191 {
192  fPtrTransform = &transform ;
193  fRebuildPolyhedron = true;
194 }
195 
197 
199 {
200  G4AffineTransform aTransform= *fDirectTransform;
201  return aTransform;
202 }
203 
205 {
206  fDirectTransform = &transform ;
207  fRebuildPolyhedron = true;
208 }
209 
211 
213 {
215  return InvRotation;
216 }
217 
219 {
221  fRebuildPolyhedron = true;
222 }
223 
225 
227 {
228  return fPtrTransform->NetTranslation();
229 }
230 
232 {
234  fRebuildPolyhedron = true;
235 }
236 
238 
240 {
242  return Rotation;
243 }
244 
246 {
247  fPtrTransform->SetNetRotation(matrix);
248  fRebuildPolyhedron = true;
249 }
250 
252 
254 {
256 }
257 
259 {
261  fRebuildPolyhedron = true;
262 }
263 
265 //
266 // Get bounding box
267 
269 {
270  if (!fDirectTransform->IsRotated())
271  {
272  // Special case of pure translation
273  //
274  fPtrSolid->Extent(pMin,pMax);
276  pMin += offset;
277  pMax += offset;
278  }
279  else
280  {
281  // General case, use CalculateExtent() to find bounding box
282  //
283  G4VoxelLimits unLimit;
284  G4double xmin,xmax,ymin,ymax,zmin,zmax;
285  fPtrSolid->CalculateExtent(kXAxis,unLimit,*fDirectTransform,xmin,xmax);
286  fPtrSolid->CalculateExtent(kYAxis,unLimit,*fDirectTransform,ymin,ymax);
287  fPtrSolid->CalculateExtent(kZAxis,unLimit,*fDirectTransform,zmin,zmax);
288  pMin.set(xmin,ymin,zmin);
289  pMax.set(xmax,ymax,zmax);
290  }
291 
292  // Check correctness of the bounding box
293  //
294  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
295  {
296  std::ostringstream message;
297  message << "Bad bounding box (min >= max) for solid: "
298  << GetName() << " !"
299  << "\npMin = " << pMin
300  << "\npMax = " << pMax;
301  G4Exception("G4DisplacedSolid::Extent()", "GeomMgt0001",
302  JustWarning, message);
303  DumpInfo();
304  }
305 }
306 
308 //
309 // Calculate extent under transform and specified limit
310 
311 G4bool
313  const G4VoxelLimits& pVoxelLimit,
314  const G4AffineTransform& pTransform,
315  G4double& pMin,
316  G4double& pMax ) const
317 {
318  G4AffineTransform sumTransform ;
319  sumTransform.Product(*fDirectTransform,pTransform) ;
320  return fPtrSolid->CalculateExtent(pAxis,pVoxelLimit,sumTransform,pMin,pMax) ;
321 }
322 
324 //
325 //
326 
328 {
330  return fPtrSolid->Inside(newPoint) ;
331 }
332 
334 //
335 //
336 
339 {
342  return fDirectTransform->TransformAxis(normal) ;
343 }
344 
346 //
347 // The same algorithm as in DistanceToIn(p)
348 
349 G4double
351  const G4ThreeVector& v ) const
352 {
354  G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
355  return fPtrSolid->DistanceToIn(newPoint,newDirection) ;
356 }
357 
359 //
360 // Approximate nearest distance from the point p to the intersection of
361 // two solids
362 
363 G4double
365 {
367  return fPtrSolid->DistanceToIn(newPoint) ;
368 }
369 
371 //
372 // The same algorithm as DistanceToOut(p)
373 
374 G4double
376  const G4ThreeVector& v,
377  const G4bool calcNorm,
378  G4bool *validNorm,
379  G4ThreeVector *n ) const
380 {
381  G4ThreeVector solNorm ;
383  G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
384  G4double dist = fPtrSolid->DistanceToOut(newPoint,newDirection,
385  calcNorm,validNorm,&solNorm) ;
386  if(calcNorm)
387  {
388  *n = fDirectTransform->TransformAxis(solNorm) ;
389  }
390  return dist ;
391 }
392 
394 //
395 // Inverted algorithm of DistanceToIn(p)
396 
397 G4double
399 {
401  return fPtrSolid->DistanceToOut(newPoint) ;
402 }
403 
405 //
406 //
407 
408 void
410  const G4int,
411  const G4VPhysicalVolume* )
412 {
413  DumpInfo();
414  G4Exception("G4DisplacedSolid::ComputeDimensions()",
415  "GeomSolids0001", FatalException,
416  "Method not applicable in this context!");
417 }
418 
420 //
421 // Returns a point (G4ThreeVector) randomly and uniformly selected
422 // on the solid surface
423 //
424 
426 {
428  return fDirectTransform->TransformPoint(p);
429 }
430 
432 //
433 // Return object type name
434 
436 {
437  return G4String("G4DisplacedSolid");
438 }
439 
441 //
442 // Make a clone of the object
443 //
445 {
446  return new G4DisplacedSolid(*this);
447 }
448 
450 //
451 // Stream object contents to an output stream
452 
453 std::ostream& G4DisplacedSolid::StreamInfo(std::ostream& os) const
454 {
455  os << "-----------------------------------------------------------\n"
456  << " *** Dump for Displaced solid - " << GetName() << " ***\n"
457  << " ===================================================\n"
458  << " Solid type: " << GetEntityType() << "\n"
459  << " Parameters of constituent solid: \n"
460  << "===========================================================\n";
461  fPtrSolid->StreamInfo(os);
462  os << "===========================================================\n"
463  << " Transformations: \n"
464  << " Direct transformation - translation : \n"
465  << " " << fDirectTransform->NetTranslation() << "\n"
466  << " - rotation : \n"
467  << " ";
469  os << "\n"
470  << "===========================================================\n";
471 
472  return os;
473 }
474 
476 //
477 //
478 
479 void
481 {
482  scene.AddSolid (*this);
483 }
484 
486 //
487 //
488 
489 G4Polyhedron*
491 {
492  G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron();
493  polyhedron
495  return polyhedron;
496 }
497 
499 //
500 //
501 
503 {
504  if (!fpPolyhedron ||
508  {
510  fRebuildPolyhedron = false;
511  }
512  return fpPolyhedron;
513 }
void set(double x, double y, double z)
G4String GetName() const
G4DisplacedSolid & operator=(const G4DisplacedSolid &rhs)
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
G4Polyhedron * GetPolyhedron() const
virtual ~G4DisplacedSolid()
std::ostream & print(std::ostream &os) const
Definition: RotationIO.cc:21
double x() const
G4AffineTransform Inverse() const
G4ThreeVector GetFrameTranslation() const
const char * p
Definition: xmltok.h:285
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4bool IsRotated() const
G4RotationMatrix GetObjectRotation() const
const G4DisplacedSolid * GetDisplacedSolidPtr() const
G4AffineTransform GetDirectTransform() const
G4ThreeVector NetTranslation() const
G4Polyhedron * CreatePolyhedron() const
HepPolyhedron & Transform(const G4Transform3D &t)
virtual void AddSolid(const G4Box &)=0
int G4int
Definition: G4Types.hh:78
G4VSolid * Clone() const
G4ThreeVector GetObjectTranslation() const
double z() const
HepRotation inverse() const
void DumpInfo() const
G4RotationMatrix GetFrameRotation() const
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
G4AffineTransform & Invert()
virtual std::ostream & StreamInfo(std::ostream &os) const =0
void SetNetTranslation(const G4ThreeVector &tlate)
void SetNetRotation(const G4RotationMatrix &rot)
void SetDirectTransform(G4AffineTransform &)
virtual EInside Inside(const G4ThreeVector &p) const =0
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void SetFrameTranslation(const G4ThreeVector &)
bool G4bool
Definition: G4Types.hh:79
CLHEP::HepRotation getRotation() const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
G4DisplacedSolid(const G4String &pName, G4VSolid *pSolid, G4RotationMatrix *rotMatrix, const G4ThreeVector &transVector)
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
HepGeom::Transform3D G4Transform3D
virtual G4Polyhedron * CreatePolyhedron() const
Definition: G4VSolid.cc:660
G4GeometryType GetEntityType() const
G4AffineTransform GetTransform() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4AffineTransform * fPtrTransform
G4RotationMatrix NetRotation() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
static G4int GetNumberOfRotationSteps()
EInside
Definition: geomdefs.hh:58
G4VSolid * GetConstituentMovedSolid() const
EAxis
Definition: geomdefs.hh:54
virtual G4ThreeVector GetPointOnSurface() const
Definition: G4VSolid.cc:153
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
double y() const
G4Polyhedron * fpPolyhedron
G4AffineTransform * fDirectTransform
G4AffineTransform & Product(const G4AffineTransform &tf1, const G4AffineTransform &tf2)
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:111
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
void SetObjectTranslation(const G4ThreeVector &)
void SetTransform(G4AffineTransform &)
double G4double
Definition: G4Types.hh:76
std::ostream & StreamInfo(std::ostream &os) const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
CLHEP::Hep3Vector getTranslation() const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
void SetObjectRotation(const G4RotationMatrix &)
virtual void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition: G4VSolid.cc:626
void SetFrameRotation(const G4RotationMatrix &)
G4ThreeVector GetPointOnSurface() const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
EInside Inside(const G4ThreeVector &p) const