ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4DisplacedSolid.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4DisplacedSolid.cc
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 // Implementation of G4DisplacedSolid class for Boolean
27 // operations between other solids
28 //
29 // 28.10.98 V.Grichine: created
30 // 28.02.18 E.Tcherniaev: improved contruction from G4DisplacedSolid
31 // --------------------------------------------------------------------
32 
33 #include "G4DisplacedSolid.hh"
34 
35 #include "G4VoxelLimits.hh"
36 
37 #include "G4VPVParameterisation.hh"
38 
39 #include "G4VGraphicsScene.hh"
40 #include "G4Polyhedron.hh"
41 
43 //
44 // Constructor for transformation like rotation of frame then translation
45 // in new frame. It is similar to 1st constractor in G4PVPlacement
46 
48  G4VSolid* pSolid ,
49  G4RotationMatrix* rotMatrix,
50  const G4ThreeVector& transVector )
51  : G4VSolid(pName)
52 {
53  if (pSolid->GetEntityType() == "G4DisplacedSolid")
54  {
55  fPtrSolid = ((G4DisplacedSolid*)pSolid)->GetConstituentMovedSolid();
56  G4AffineTransform t1 = ((G4DisplacedSolid*)pSolid)->GetDirectTransform();
57  G4AffineTransform t2 = G4AffineTransform(rotMatrix,transVector);
59  }
60  else
61  {
62  fPtrSolid = pSolid;
63  fDirectTransform = new G4AffineTransform(rotMatrix,transVector);
64  }
66 }
67 
69 //
70 // Constructor
71 
73  G4VSolid* pSolid ,
74  const G4Transform3D& transform )
75  : G4VSolid(pName)
76 {
77  if (pSolid->GetEntityType() == "G4DisplacedSolid")
78  {
79  fPtrSolid = ((G4DisplacedSolid*)pSolid)->GetConstituentMovedSolid();
80  G4AffineTransform t1 = ((G4DisplacedSolid*)pSolid)->GetDirectTransform();
82  transform.getTranslation());
84  }
85  else
86  {
87  fPtrSolid = pSolid;
89  transform.getTranslation()) ;
90  }
92 }
93 
95 //
96 // Constructor for use with creation of Transient object
97 // from Persistent object
98 
100  G4VSolid* pSolid ,
101  const G4AffineTransform directTransform )
102  : G4VSolid(pName)
103 {
104  if (pSolid->GetEntityType() == "G4DisplacedSolid")
105  {
106  fPtrSolid = ((G4DisplacedSolid*)pSolid)->GetConstituentMovedSolid();
107  G4AffineTransform t1 = ((G4DisplacedSolid*)pSolid)->GetDirectTransform();
108  G4AffineTransform t2 = G4AffineTransform(directTransform);
109  fDirectTransform = new G4AffineTransform(t1*t2);
110  }
111  else
112  {
113  fPtrSolid = pSolid;
114  fDirectTransform = new G4AffineTransform(directTransform);
115  }
117 }
118 
120 //
121 // Fake default constructor - sets only member data and allocates memory
122 // for usage restricted to object persistency.
123 
125  : G4VSolid(a)
126 {
127 }
128 
130 //
131 // Destructor
132 
134 {
136  delete fpPolyhedron; fpPolyhedron = nullptr;
137 }
138 
140 //
141 // Copy constructor
142 
144  : G4VSolid (rhs), fPtrSolid(rhs.fPtrSolid)
145 {
148 }
149 
151 //
152 // Assignment operator
153 
155 {
156  // Check assignment to self
157  //
158  if (this == &rhs) { return *this; }
159 
160  // Copy base class data
161  //
162  G4VSolid::operator=(rhs);
163 
164  // Copy data
165  //
166  fPtrSolid = rhs.fPtrSolid;
167  delete fPtrTransform; delete fDirectTransform;
170  fRebuildPolyhedron = false;
171  delete fpPolyhedron; fpPolyhedron = nullptr;
172 
173  return *this;
174 }
175 
177 {
178  if(fPtrTransform != nullptr)
179  {
180  delete fPtrTransform; fPtrTransform = nullptr;
181  delete fDirectTransform; fDirectTransform = nullptr;
182  }
183 }
184 
186 {
187  return this;
188 }
189 
191 {
192  return this;
193 }
194 
196 {
197  return fPtrSolid;
198 }
199 
201 
203 {
205  return aTransform;
206 }
207 
209 {
211  fRebuildPolyhedron = true;
212 }
213 
215 
217 {
219  return aTransform;
220 }
221 
223 {
225  fRebuildPolyhedron = true;
226 }
227 
229 
231 {
233  return InvRotation;
234 }
235 
237 {
239  fRebuildPolyhedron = true;
240 }
241 
243 
245 {
246  return fPtrTransform->NetTranslation();
247 }
248 
250 {
252  fRebuildPolyhedron = true;
253 }
254 
256 
258 {
260  return Rotation;
261 }
262 
264 {
265  fPtrTransform->SetNetRotation(matrix);
266  fRebuildPolyhedron = true;
267 }
268 
270 
272 {
274 }
275 
277 {
279  fRebuildPolyhedron = true;
280 }
281 
283 //
284 // Get bounding box
285 
287  G4ThreeVector& pMax) const
288 {
289  if (!fDirectTransform->IsRotated())
290  {
291  // Special case of pure translation
292  //
293  fPtrSolid->BoundingLimits(pMin,pMax);
295  pMin += offset;
296  pMax += offset;
297  }
298  else
299  {
300  // General case, use CalculateExtent() to find bounding box
301  //
302  G4VoxelLimits unLimit;
303  G4double xmin,xmax,ymin,ymax,zmin,zmax;
304  fPtrSolid->CalculateExtent(kXAxis,unLimit,*fDirectTransform,xmin,xmax);
305  fPtrSolid->CalculateExtent(kYAxis,unLimit,*fDirectTransform,ymin,ymax);
306  fPtrSolid->CalculateExtent(kZAxis,unLimit,*fDirectTransform,zmin,zmax);
307  pMin.set(xmin,ymin,zmin);
308  pMax.set(xmax,ymax,zmax);
309  }
310 
311  // Check correctness of the bounding box
312  //
313  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
314  {
315  std::ostringstream message;
316  message << "Bad bounding box (min >= max) for solid: "
317  << GetName() << " !"
318  << "\npMin = " << pMin
319  << "\npMax = " << pMax;
320  G4Exception("G4DisplacedSolid::BoundingLimits()", "GeomMgt0001",
321  JustWarning, message);
322  DumpInfo();
323  }
324 }
325 
327 //
328 // Calculate extent under transform and specified limit
329 
330 G4bool
332  const G4VoxelLimits& pVoxelLimit,
333  const G4AffineTransform& pTransform,
334  G4double& pMin,
335  G4double& pMax ) const
336 {
337  G4AffineTransform sumTransform ;
338  sumTransform.Product(*fDirectTransform,pTransform) ;
339  return fPtrSolid->CalculateExtent(pAxis,pVoxelLimit,sumTransform,pMin,pMax) ;
340 }
341 
343 //
344 // SurfaceNormal
345 
347 {
349  return fPtrSolid->Inside(newPoint) ;
350 }
351 
353 //
354 //
355 
358 {
361  return fDirectTransform->TransformAxis(normal) ;
362 }
363 
365 //
366 // The same algorithm as in DistanceToIn(p)
367 
368 G4double
370  const G4ThreeVector& v ) const
371 {
373  G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
374  return fPtrSolid->DistanceToIn(newPoint,newDirection) ;
375 }
376 
378 //
379 // Approximate nearest distance from the point p to the intersection of
380 // two solids
381 
382 G4double
384 {
386  return fPtrSolid->DistanceToIn(newPoint) ;
387 }
388 
390 //
391 // The same algorithm as DistanceToOut(p)
392 
393 G4double
395  const G4ThreeVector& v,
396  const G4bool calcNorm,
397  G4bool *validNorm,
398  G4ThreeVector *n ) const
399 {
400  G4ThreeVector solNorm ;
402  G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
403  G4double dist = fPtrSolid->DistanceToOut(newPoint,newDirection,
404  calcNorm,validNorm,&solNorm) ;
405  if(calcNorm)
406  {
407  *n = fDirectTransform->TransformAxis(solNorm) ;
408  }
409  return dist ;
410 }
411 
413 //
414 // Inverted algorithm of DistanceToIn(p)
415 
416 G4double
418 {
420  return fPtrSolid->DistanceToOut(newPoint) ;
421 }
422 
424 //
425 // ComputeDimensions
426 
427 void
429  const G4int,
430  const G4VPhysicalVolume* )
431 {
432  DumpInfo();
433  G4Exception("G4DisplacedSolid::ComputeDimensions()",
434  "GeomSolids0001", FatalException,
435  "Method not applicable in this context!");
436 }
437 
439 //
440 // Returns a point (G4ThreeVector) randomly and uniformly selected
441 // on the solid surface
442 //
443 
445 {
447  return fDirectTransform->TransformPoint(p);
448 }
449 
451 //
452 // Return object type name
453 
455 {
456  return G4String("G4DisplacedSolid");
457 }
458 
460 //
461 // Make a clone of the object
462 //
464 {
465  return new G4DisplacedSolid(*this);
466 }
467 
469 //
470 // Stream object contents to an output stream
471 
472 std::ostream& G4DisplacedSolid::StreamInfo(std::ostream& os) const
473 {
474  os << "-----------------------------------------------------------\n"
475  << " *** Dump for Displaced solid - " << GetName() << " ***\n"
476  << " ===================================================\n"
477  << " Solid type: " << GetEntityType() << "\n"
478  << " Parameters of constituent solid: \n"
479  << "===========================================================\n";
480  fPtrSolid->StreamInfo(os);
481  os << "===========================================================\n"
482  << " Transformations: \n"
483  << " Direct transformation - translation : \n"
484  << " " << fDirectTransform->NetTranslation() << "\n"
485  << " - rotation : \n"
486  << " ";
488  os << "\n"
489  << "===========================================================\n";
490 
491  return os;
492 }
493 
495 //
496 // DescribeYourselfTo
497 
498 void
500 {
501  scene.AddSolid (*this);
502 }
503 
505 //
506 // CreatePolyhedron
507 
508 G4Polyhedron*
510 {
511  G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron();
512  if (polyhedron != nullptr)
513  {
514  polyhedron
516  }
517  else
518  {
519  DumpInfo();
520  G4Exception("G4DisplacedSolid::CreatePolyhedron()",
521  "GeomSolids2002", JustWarning,
522  "No G4Polyhedron for displaced solid");
523  }
524  return polyhedron;
525 }
526 
528 //
529 // GetPolyhedron
530 
532 {
533  if (fpPolyhedron == nullptr ||
537  {
539  fRebuildPolyhedron = false;
540  }
541  return fpPolyhedron;
542 }