ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ReflectedSolid.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ReflectedSolid.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 for G4ReflectedSolid class
27 //
28 // Author: Vladimir Grichine, 23.07.01 (Vladimir.Grichine@cern.ch)
29 // --------------------------------------------------------------------
30 
31 #include "G4ReflectedSolid.hh"
32 
33 #include <sstream>
34 
35 #include "G4Point3D.hh"
36 #include "G4Vector3D.hh"
37 
38 #include "G4AffineTransform.hh"
39 #include "G4Transform3D.hh"
40 #include "G4VoxelLimits.hh"
41 
42 #include "G4VPVParameterisation.hh"
43 
44 #include "G4VGraphicsScene.hh"
45 #include "G4Polyhedron.hh"
46 
48 //
49 // Constructor using HepTransform3D, in fact HepReflect3D
50 
52  G4VSolid* pSolid ,
53  const G4Transform3D& transform )
54  : G4VSolid(pName)
55 {
56  fPtrSolid = pSolid;
57  fDirectTransform3D = new G4Transform3D(transform);
58 }
59 
61 //
62 
64 {
65  delete fDirectTransform3D; fDirectTransform3D = nullptr;
66  delete fpPolyhedron; fpPolyhedron = nullptr;
67 }
68 
70 //
71 
73  : G4VSolid(rhs), fPtrSolid(rhs.fPtrSolid)
74 {
76 }
77 
79 //
80 
82 {
83  // Check assignment to self
84  //
85  if (this == &rhs) { return *this; }
86 
87  // Copy base class data
88  //
90 
91  // Copy data
92  //
93  fPtrSolid = rhs.fPtrSolid;
94  delete fDirectTransform3D;
96  fRebuildPolyhedron = false;
97  delete fpPolyhedron; fpPolyhedron = nullptr;
98 
99  return *this;
100 }
101 
103 //
104 
106 {
107  return G4String("G4ReflectedSolid");
108 }
109 
111 {
112  return this;
113 }
114 
116 {
117  return this;
118 }
119 
121 {
122  return fPtrSolid;
123 }
124 
126 //
127 
129 {
130  return fDirectTransform3D->inverse();
131 }
132 
134 {
136  return aTransform;
137 }
138 
140 {
142  fRebuildPolyhedron = true;
143 }
144 
146 //
147 // Get bounding box
148 
150  G4ThreeVector& pMax) const
151 {
152  fPtrSolid->BoundingLimits(pMin,pMax);
153  G4double xmin = pMin.x(), ymin = pMin.y(), zmin = pMin.z();
154  G4double xmax = pMax.x(), ymax = pMax.y(), zmax = pMax.z();
158 
159  if (std::abs(xx) == 1 && std::abs(yy) == 1 && std::abs(zz) == 1)
160  {
161  // Special case of reflection in axis and pure translation
162  //
163  if (xx == -1) { G4double tmp = -xmin; xmin = -xmax; xmax = tmp; }
164  if (yy == -1) { G4double tmp = -ymin; ymin = -ymax; ymax = tmp; }
165  if (zz == -1) { G4double tmp = -zmin; zmin = -zmax; zmax = tmp; }
166  xmin += fDirectTransform3D->dx();
167  xmax += fDirectTransform3D->dx();
168  ymin += fDirectTransform3D->dy();
169  ymax += fDirectTransform3D->dy();
170  zmin += fDirectTransform3D->dz();
171  zmax += fDirectTransform3D->dz();
172  }
173  else
174  {
175  // Use additional reflection in Z to set up affine transformation
176  //
177  G4Transform3D transform3D = G4ReflectZ3D()*(*fDirectTransform3D);
179  transform3D.getTranslation());
180 
181  // Find bounding box
182  //
183  G4VoxelLimits unLimit;
184  fPtrSolid->CalculateExtent(kXAxis,unLimit,transform,xmin,xmax);
186  fPtrSolid->CalculateExtent(kZAxis,unLimit,transform,zmin,zmax);
187  }
188 
189  pMin.set(xmin,ymin,-zmax);
190  pMax.set(xmax,ymax,-zmin);
191 
192  // Check correctness of the bounding box
193  //
194  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
195  {
196  std::ostringstream message;
197  message << "Bad bounding box (min >= max) for solid: "
198  << GetName() << " !"
199  << "\npMin = " << pMin
200  << "\npMax = " << pMax;
201  G4Exception("G4ReflectedSolid::BoundingLimits()", "GeomMgt0001",
202  JustWarning, message);
203  DumpInfo();
204  }
205 }
206 
208 //
209 // Calculate extent under transform and specified limit
210 
211 G4bool
213  const G4VoxelLimits& pVoxelLimits,
214  const G4AffineTransform& pTransform,
215  G4double& pMin,
216  G4double& pMax ) const
217 {
218  // Separation of transformations. Calculation of the extent is done
219  // in a reflection of the global space. In such way, the voxel is
220  // reflected, but the solid is transformed just by G4AffineTransform.
221  // It allows to use CalculateExtent() of the solid.
222 
223  // Reflect voxel limits in Z
224  //
225  G4VoxelLimits limits;
226  limits.AddLimit(kXAxis, pVoxelLimits.GetMinXExtent(),
227  pVoxelLimits.GetMaxXExtent());
228  limits.AddLimit(kYAxis, pVoxelLimits.GetMinYExtent(),
229  pVoxelLimits.GetMaxYExtent());
230  limits.AddLimit(kZAxis,-pVoxelLimits.GetMaxZExtent(),
231  -pVoxelLimits.GetMinZExtent());
232 
233  // Set affine transformation
234  //
235  G4Transform3D transform3D = G4ReflectZ3D()*pTransform*(*fDirectTransform3D);
237  transform3D.getTranslation());
238 
239  // Find extent
240  //
241  if (!fPtrSolid->CalculateExtent(pAxis, limits, transform, pMin, pMax))
242  {
243  return false;
244  }
245  if (pAxis == kZAxis)
246  {
247  G4double tmp= -pMin; pMin= -pMax; pMax= tmp;
248  }
249 
250  return true;
251 }
252 
254 //
255 //
256 
258 {
259  G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
260  return fPtrSolid->Inside(newPoint);
261 }
262 
264 //
265 //
266 
269 {
270  G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
272  return (*fDirectTransform3D)*normal;
273 }
274 
276 //
277 // The same algorithm as in DistanceToIn(p)
278 
279 G4double
281  const G4ThreeVector& v ) const
282 {
283  G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
284  G4ThreeVector newDirection = (*fDirectTransform3D)*G4Vector3D(v);
285  return fPtrSolid->DistanceToIn(newPoint,newDirection);
286 }
287 
289 //
290 // Approximate nearest distance from the point p to the intersection of
291 // two solids
292 
293 G4double
295 {
296  G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
297  return fPtrSolid->DistanceToIn(newPoint);
298 }
299 
301 //
302 // The same algorithm as DistanceToOut(p)
303 
304 G4double
306  const G4ThreeVector& v,
307  const G4bool calcNorm,
308  G4bool* validNorm,
309  G4ThreeVector* n ) const
310 {
311  G4ThreeVector solNorm;
312 
313  G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
314  G4ThreeVector newDirection = (*fDirectTransform3D)*G4Vector3D(v);
315 
316  G4double dist = fPtrSolid->DistanceToOut(newPoint, newDirection,
317  calcNorm, validNorm, &solNorm);
318  if(calcNorm)
319  {
320  *n = (*fDirectTransform3D)*G4Vector3D(solNorm);
321  }
322  return dist;
323 }
324 
326 //
327 // Inverted algorithm of DistanceToIn(p)
328 
329 G4double
331 {
332  G4ThreeVector newPoint = (*fDirectTransform3D)*G4Point3D(p);
333  return fPtrSolid->DistanceToOut(newPoint);
334 }
335 
337 //
338 //
339 
340 void
342  const G4int,
343  const G4VPhysicalVolume* )
344 {
345  DumpInfo();
346  G4Exception("G4ReflectedSolid::ComputeDimensions()",
347  "GeomMgt0001", FatalException,
348  "Method not applicable in this context!");
349 }
350 
352 //
353 // Return a point (G4ThreeVector) randomly and uniformly selected
354 // on the solid surface
355 
357 {
359  return (*fDirectTransform3D)*G4Point3D(p);
360 }
361 
363 //
364 // Make a clone of this object
365 
367 {
368  return new G4ReflectedSolid(*this);
369 }
370 
371 
373 //
374 // Stream object contents to an output stream
375 
376 std::ostream& G4ReflectedSolid::StreamInfo(std::ostream& os) const
377 {
378  os << "-----------------------------------------------------------\n"
379  << " *** Dump for Reflected solid - " << GetName() << " ***\n"
380  << " ===================================================\n"
381  << " Solid type: " << GetEntityType() << "\n"
382  << " Parameters of constituent solid: \n"
383  << "===========================================================\n";
384  fPtrSolid->StreamInfo(os);
385  os << "===========================================================\n"
386  << " Transformations: \n"
387  << " Direct transformation - translation : \n"
388  << " " << fDirectTransform3D->getTranslation() << "\n"
389  << " - rotation : \n"
390  << " ";
392  os << "\n"
393  << "===========================================================\n";
394 
395  return os;
396 }
397 
399 //
400 //
401 
402 void
404 {
405  scene.AddSolid (*this);
406 }
407 
409 //
410 //
411 
412 G4Polyhedron*
414 {
415  G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron();
416  if (polyhedron != nullptr)
417  {
418  polyhedron->Transform(*fDirectTransform3D);
419  return polyhedron;
420  }
421  else
422  {
423  std::ostringstream message;
424  message << "Solid - " << GetName()
425  << " - original solid has no" << G4endl
426  << "corresponding polyhedron. Returning NULL!";
427  G4Exception("G4ReflectedSolid::CreatePolyhedron()",
428  "GeomMgt1001", JustWarning, message);
429  return nullptr;
430  }
431 }
432 
434 //
435 //
436 
439 {
440  if ((fpPolyhedron == nullptr) || fRebuildPolyhedron ||
443  {
445  fRebuildPolyhedron = false;
446  }
447  return fpPolyhedron;
448 }