Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/Boolean/src/G4DisplacedSolid.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 42 ////////////////////////////////////////////////////////////////
 43 //
 44 // Constructor for transformation like rotation of frame then translation 
 45 // in new frame. It is similar to 1st constractor in G4PVPlacement
 46 
 47 G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
 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);
 58     fDirectTransform = new G4AffineTransform(t1*t2);
 59   }
 60   else
 61   { 
 62     fPtrSolid = pSolid;
 63     fDirectTransform = new G4AffineTransform(rotMatrix,transVector);
 64   }
 65   fPtrTransform = new G4AffineTransform(fDirectTransform->Inverse());
 66 }
 67 
 68 /////////////////////////////////////////////////////////////////////////////////
 69 //
 70 // Constructor
 71 
 72 G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
 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();
 81     G4AffineTransform t2 = G4AffineTransform(transform.getRotation().inverse(),
 82                                              transform.getTranslation());
 83     fDirectTransform = new G4AffineTransform(t1*t2);
 84   }
 85   else
 86   { 
 87     fPtrSolid = pSolid;
 88     fDirectTransform = new G4AffineTransform(transform.getRotation().inverse(),
 89                                              transform.getTranslation()) ;
 90   }
 91   fPtrTransform = new G4AffineTransform(fDirectTransform->Inverse());
 92 }
 93 
 94 ///////////////////////////////////////////////////////////////////
 95 //
 96 // Constructor for use with creation of Transient object
 97 // from Persistent object
 98 
 99 G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
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     auto  t2 = G4AffineTransform(directTransform);
109     fDirectTransform = new G4AffineTransform(t1*t2);
110   }
111   else
112   { 
113     fPtrSolid = pSolid;
114     fDirectTransform = new G4AffineTransform(directTransform);
115   }
116   fPtrTransform = new G4AffineTransform(fDirectTransform->Inverse());
117 }
118 
119 ///////////////////////////////////////////////////////////////////
120 //
121 // Fake default constructor - sets only member data and allocates memory
122 //                            for usage restricted to object persistency.
123 
124 G4DisplacedSolid::G4DisplacedSolid( __void__& a )
125   : G4VSolid(a)
126 {
127 }
128 
129 ///////////////////////////////////////////////////////////////////
130 //
131 // Destructor
132 
133 G4DisplacedSolid::~G4DisplacedSolid() 
134 {
135   CleanTransformations();
136   delete fpPolyhedron; fpPolyhedron = nullptr;
137 }
138 
139 ///////////////////////////////////////////////////////////////
140 //
141 // Copy constructor
142 
143 G4DisplacedSolid::G4DisplacedSolid(const G4DisplacedSolid& rhs)
144   : G4VSolid (rhs), fPtrSolid(rhs.fPtrSolid)
145 {
146   fPtrTransform = new G4AffineTransform(*(rhs.fPtrTransform));
147   fDirectTransform = new G4AffineTransform(*(rhs.fDirectTransform));
148 }
149 
150 ///////////////////////////////////////////////////////////////
151 //
152 // Assignment operator
153 
154 G4DisplacedSolid& G4DisplacedSolid::operator = (const G4DisplacedSolid& rhs) 
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;
168   fPtrTransform = new G4AffineTransform(*(rhs.fPtrTransform));
169   fDirectTransform = new G4AffineTransform(*(rhs.fDirectTransform));
170   fRebuildPolyhedron = false;
171   delete fpPolyhedron; fpPolyhedron = nullptr;
172 
173   return *this;
174 }  
175 
176 void G4DisplacedSolid::CleanTransformations()
177 {
178   if(fPtrTransform != nullptr)
179   {
180     delete fPtrTransform; fPtrTransform = nullptr;
181     delete fDirectTransform; fDirectTransform = nullptr;
182   }
183 }
184 
185 const G4DisplacedSolid* G4DisplacedSolid::GetDisplacedSolidPtr() const   
186 {
187   return this;
188 }
189 
190 G4DisplacedSolid* G4DisplacedSolid::GetDisplacedSolidPtr() 
191 {
192   return this;
193 }
194 
195 G4VSolid* G4DisplacedSolid::GetConstituentMovedSolid() const
196 { 
197   return fPtrSolid; 
198 } 
199 
200 /////////////////////////////////////////////////////////////////////////////
201 
202 G4AffineTransform  G4DisplacedSolid::GetTransform() const
203 {
204   G4AffineTransform aTransform = *fPtrTransform;
205   return aTransform;
206 }
207 
208 void G4DisplacedSolid::SetTransform(G4AffineTransform& transform) 
209 {
210   fPtrTransform = &transform ;
211   fRebuildPolyhedron = true;
212 }
213 
214 //////////////////////////////////////////////////////////////////////////////
215 
216 G4AffineTransform  G4DisplacedSolid::GetDirectTransform() const
217 {
218   G4AffineTransform aTransform= *fDirectTransform;
219   return aTransform;
220 }
221 
222 void G4DisplacedSolid::SetDirectTransform(G4AffineTransform& transform) 
223 {
224   fDirectTransform = &transform ;
225   fRebuildPolyhedron = true;
226 }
227 
228 /////////////////////////////////////////////////////////////////////////////
229 
230 G4RotationMatrix G4DisplacedSolid::GetFrameRotation() const
231 {
232   G4RotationMatrix InvRotation = fDirectTransform->NetRotation();
233   return InvRotation;
234 }
235 
236 void G4DisplacedSolid::SetFrameRotation(const G4RotationMatrix& matrix)
237 {
238   fDirectTransform->SetNetRotation(matrix);
239   fRebuildPolyhedron = true;
240 }
241 
242 /////////////////////////////////////////////////////////////////////////////
243 
244 G4ThreeVector  G4DisplacedSolid::GetFrameTranslation() const
245 {
246   return fPtrTransform->NetTranslation();
247 }
248 
249 void G4DisplacedSolid::SetFrameTranslation(const G4ThreeVector& vector)
250 {
251   fPtrTransform->SetNetTranslation(vector);
252   fRebuildPolyhedron = true;
253 }
254 
255 ///////////////////////////////////////////////////////////////
256 
257 G4RotationMatrix G4DisplacedSolid::GetObjectRotation() const
258 {
259   G4RotationMatrix Rotation = fPtrTransform->NetRotation();
260   return Rotation;
261 }
262 
263 void G4DisplacedSolid::SetObjectRotation(const G4RotationMatrix& matrix)
264 {
265   fPtrTransform->SetNetRotation(matrix);
266   fRebuildPolyhedron = true;
267 }
268 
269 ///////////////////////////////////////////////////////////////////////
270 
271 G4ThreeVector  G4DisplacedSolid::GetObjectTranslation() const
272 {
273   return fDirectTransform->NetTranslation();
274 }
275 
276 void G4DisplacedSolid::SetObjectTranslation(const G4ThreeVector& vector)
277 {
278   fDirectTransform->SetNetTranslation(vector);
279   fRebuildPolyhedron = true;
280 }
281 
282 //////////////////////////////////////////////////////////////////////////
283 //
284 // Get bounding box
285 
286 void G4DisplacedSolid::BoundingLimits(G4ThreeVector& pMin,
287                                       G4ThreeVector& pMax) const
288 {
289   if (!fDirectTransform->IsRotated())
290   {
291     // Special case of pure translation
292     //
293     fPtrSolid->BoundingLimits(pMin,pMax);
294     G4ThreeVector offset = fDirectTransform->NetTranslation();
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 
326 //////////////////////////////////////////////////////////////////////////
327 //
328 // Calculate extent under transform and specified limit
329      
330 G4bool 
331 G4DisplacedSolid::CalculateExtent( const EAxis pAxis,
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  
342 /////////////////////////////////////////////////////
343 //
344 // SurfaceNormal
345 
346 EInside G4DisplacedSolid::Inside(const G4ThreeVector& p) const
347 {
348   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
349   return fPtrSolid->Inside(newPoint) ; 
350 }
351 
352 //////////////////////////////////////////////////////////////
353 //
354 //
355 
356 G4ThreeVector 
357 G4DisplacedSolid::SurfaceNormal( const G4ThreeVector& p ) const 
358 {
359   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
360   G4ThreeVector normal = fPtrSolid->SurfaceNormal(newPoint) ; 
361   return fDirectTransform->TransformAxis(normal) ;
362 }
363 
364 /////////////////////////////////////////////////////////////
365 //
366 // The same algorithm as in DistanceToIn(p)
367 
368 G4double 
369 G4DisplacedSolid::DistanceToIn( const G4ThreeVector& p,
370                                 const G4ThreeVector& v  ) const 
371 {    
372   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
373   G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
374   return fPtrSolid->DistanceToIn(newPoint,newDirection) ;   
375 }
376 
377 ////////////////////////////////////////////////////////
378 //
379 // Approximate nearest distance from the point p to the intersection of
380 // two solids
381 
382 G4double 
383 G4DisplacedSolid::DistanceToIn( const G4ThreeVector& p ) const 
384 {
385   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
386   return fPtrSolid->DistanceToIn(newPoint) ;   
387 }
388 
389 //////////////////////////////////////////////////////////
390 //
391 // The same algorithm as DistanceToOut(p)
392 
393 G4double 
394 G4DisplacedSolid::DistanceToOut( const G4ThreeVector& p,
395                                  const G4ThreeVector& v,
396                                  const G4bool calcNorm,
397                                        G4bool *validNorm,
398                                        G4ThreeVector *n   ) const 
399 {
400   G4ThreeVector solNorm ; 
401   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
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 
412 //////////////////////////////////////////////////////////////
413 //
414 // Inverted algorithm of DistanceToIn(p)
415 
416 G4double 
417 G4DisplacedSolid::DistanceToOut( const G4ThreeVector& p ) const 
418 {
419   G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
420   return fPtrSolid->DistanceToOut(newPoint) ;   
421 }
422 
423 //////////////////////////////////////////////////////////////
424 //
425 // ComputeDimensions
426 
427 void 
428 G4DisplacedSolid::ComputeDimensions(       G4VPVParameterisation*,
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 
438 //////////////////////////////////////////////////////////////
439 //
440 // Return volume
441 
442 G4double G4DisplacedSolid::GetCubicVolume()
443 {
444   return fPtrSolid->GetCubicVolume();
445 }
446 
447 //////////////////////////////////////////////////////////////
448 //
449 // Return surface area
450 
451 G4double G4DisplacedSolid::GetSurfaceArea()
452 {
453   return fPtrSolid->GetSurfaceArea();
454 }
455 
456 //////////////////////////////////////////////////////////////////////////
457 //
458 // Returns a point (G4ThreeVector) randomly and uniformly selected
459 // on the solid surface
460 //
461 
462 G4ThreeVector G4DisplacedSolid::GetPointOnSurface() const
463 {
464   G4ThreeVector p = fPtrSolid->GetPointOnSurface();
465   return fDirectTransform->TransformPoint(p);
466 }
467 
468 //////////////////////////////////////////////////////////////////////////
469 //
470 // Return the number of constituents used for construction of the solid
471 
472 G4int G4DisplacedSolid::GetNumOfConstituents() const
473 {
474   return fPtrSolid->GetNumOfConstituents();
475 }
476 
477 //////////////////////////////////////////////////////////////////////////
478 //
479 // Return true if the solid has only planar faces
480 
481 G4bool G4DisplacedSolid::IsFaceted() const
482 {
483   return fPtrSolid->IsFaceted();  
484 }
485 
486 //////////////////////////////////////////////////////////////////////////
487 //
488 // Return object type name
489 
490 G4GeometryType G4DisplacedSolid::GetEntityType() const 
491 {
492   return {"G4DisplacedSolid"};
493 }
494 
495 //////////////////////////////////////////////////////////////////////////
496 //
497 // Make a clone of the object
498 //
499 G4VSolid* G4DisplacedSolid::Clone() const
500 {
501   return new G4DisplacedSolid(*this);
502 }
503 
504 //////////////////////////////////////////////////////////////////////////
505 //
506 // Stream object contents to an output stream
507 
508 std::ostream& G4DisplacedSolid::StreamInfo(std::ostream& os) const
509 {
510   os << "-----------------------------------------------------------\n"
511      << "    *** Dump for Displaced solid - " << GetName() << " ***\n"
512      << "    ===================================================\n"
513      << " Solid type: " << GetEntityType() << "\n"
514      << " Parameters of constituent solid: \n"
515      << "===========================================================\n";
516   fPtrSolid->StreamInfo(os);
517   os << "===========================================================\n"
518      << " Transformations: \n"
519      << "    Direct transformation - translation : \n"
520      << "           " << fDirectTransform->NetTranslation() << "\n"
521      << "                          - rotation    : \n"
522      << "           ";
523   fDirectTransform->NetRotation().print(os);
524   os << "\n"
525      << "===========================================================\n";
526 
527   return os;
528 }
529 
530 //////////////////////////////////////////////////////////////////////////
531 //
532 // DescribeYourselfTo               
533 
534 void 
535 G4DisplacedSolid::DescribeYourselfTo ( G4VGraphicsScene& scene ) const 
536 {
537   scene.AddSolid (*this);
538 }
539 
540 //////////////////////////////////////////////////////////////////////////
541 //
542 // CreatePolyhedron
543 
544 G4Polyhedron* 
545 G4DisplacedSolid::CreatePolyhedron () const 
546 {
547   G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron();
548   if (polyhedron != nullptr)
549   {
550     polyhedron
551     ->Transform(G4Transform3D(GetObjectRotation(),GetObjectTranslation()));
552   }
553   else
554   {
555     DumpInfo();
556     G4Exception("G4DisplacedSolid::CreatePolyhedron()",
557                 "GeomSolids2002", JustWarning,
558                 "No G4Polyhedron for displaced solid");
559   }
560   return polyhedron;
561 }
562 
563 //////////////////////////////////////////////////////////////////////////
564 //
565 // GetPolyhedron
566 
567 G4Polyhedron* G4DisplacedSolid::GetPolyhedron () const
568 {
569   if (fpPolyhedron == nullptr ||
570       fRebuildPolyhedron ||
571       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
572       fpPolyhedron->GetNumberOfRotationSteps())
573     {
574       fpPolyhedron = CreatePolyhedron();
575       fRebuildPolyhedron = false;
576     }
577   return fpPolyhedron;
578 }
579