source: trunk/source/geometry/solids/Boolean/src/G4DisplacedSolid.cc @ 850

Last change on this file since 850 was 850, checked in by garnier, 16 years ago

geant4.8.2 beta

File size: 13.1 KB
Line 
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,v 1.27 2006/06/29 18:43:41 gunter Exp $
28// GEANT4 tag $Name: HEAD $
29//
30// Implementation for G4DisplacedSolid class for boolean
31// operations between other solids
32//
33// History:
34//
35// 28.10.98 V.Grichine: created
36// 14.11.99 V.Grichine: modifications in CalculateExtent(...) method
37// 22.11.00 V.Grichine: new set methods for matrix/vectors
38//
39// --------------------------------------------------------------------
40
41#include "G4DisplacedSolid.hh"
42
43#include "G4VoxelLimits.hh"
44
45#include "G4VPVParameterisation.hh"
46
47#include "G4VGraphicsScene.hh"
48#include "G4Polyhedron.hh"
49#include "G4NURBS.hh"
50// #include "G4NURBSbox.hh"
51
52////////////////////////////////////////////////////////////////
53//
54// Constructor for transformation like rotation of frame then translation
55// in new frame. It is similar to 1st constractor in G4PVPlacement
56
57G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
58                                          G4VSolid* pSolid ,
59                                          G4RotationMatrix* rotMatrix,
60                                    const G4ThreeVector& transVector    )
61  : G4VSolid(pName), fpPolyhedron(0)
62{
63  fPtrSolid = pSolid ;
64  fPtrTransform = new G4AffineTransform(rotMatrix,transVector) ;
65  fPtrTransform->Invert() ;
66  fDirectTransform = new G4AffineTransform(rotMatrix,transVector) ;
67}
68
69/////////////////////////////////////////////////////////////////////////////////
70//
71// Constructor
72
73G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
74                                          G4VSolid* pSolid ,
75                                    const G4Transform3D& transform  )
76  : G4VSolid(pName), fpPolyhedron(0)
77{
78  fPtrSolid = pSolid ;
79  fDirectTransform = new G4AffineTransform(transform.getRotation().inverse(),
80                                           transform.getTranslation()) ;
81
82  fPtrTransform    = new G4AffineTransform(transform.getRotation().inverse(),
83                                           transform.getTranslation()) ;
84  fPtrTransform->Invert() ;
85}
86
87///////////////////////////////////////////////////////////////////
88//
89// Constructor for use with creation of Transient object
90// from Persistent object
91
92G4DisplacedSolid::G4DisplacedSolid( const G4String& pName,
93                                          G4VSolid* pSolid ,
94                                    const G4AffineTransform directTransform )
95  : G4VSolid(pName), fpPolyhedron(0)
96{
97  fPtrSolid = pSolid ;
98  fDirectTransform = new G4AffineTransform( directTransform );
99  fPtrTransform    = new G4AffineTransform( directTransform.Inverse() ) ; 
100}
101
102///////////////////////////////////////////////////////////////////
103//
104// Fake default constructor - sets only member data and allocates memory
105//                            for usage restricted to object persistency.
106
107G4DisplacedSolid::G4DisplacedSolid( __void__& a )
108  : G4VSolid(a), fPtrSolid(0), fPtrTransform(0),
109    fDirectTransform(0), fpPolyhedron(0)
110{
111}
112
113///////////////////////////////////////////////////////////////////
114//
115// Destructor
116
117G4DisplacedSolid::~G4DisplacedSolid() 
118{
119  CleanTransformations();
120  delete fpPolyhedron;
121}
122
123G4GeometryType G4DisplacedSolid::GetEntityType() const 
124{
125  return G4String("G4DisplacedSolid");
126}
127
128void G4DisplacedSolid::CleanTransformations()
129{
130  if(fPtrTransform)
131  {
132    delete fPtrTransform;  fPtrTransform=0;
133    delete fDirectTransform;  fDirectTransform=0;
134  }
135}
136
137const G4DisplacedSolid* G4DisplacedSolid::GetDisplacedSolidPtr() const   
138{
139  return this;
140}
141
142G4DisplacedSolid* G4DisplacedSolid::GetDisplacedSolidPtr() 
143{
144  return this;
145}
146
147G4VSolid* G4DisplacedSolid::GetConstituentMovedSolid() const
148{ 
149  return fPtrSolid; 
150} 
151
152/////////////////////////////////////////////////////////////////////////////
153
154G4AffineTransform  G4DisplacedSolid::GetTransform() const
155{
156  G4AffineTransform aTransform = *fPtrTransform;
157  return aTransform;
158}
159
160void G4DisplacedSolid::SetTransform(G4AffineTransform& transform) 
161{
162  fPtrTransform = &transform ;
163  fpPolyhedron = 0;
164}
165
166//////////////////////////////////////////////////////////////////////////////
167
168G4AffineTransform  G4DisplacedSolid::GetDirectTransform() const
169{
170  G4AffineTransform aTransform= *fDirectTransform;
171  return aTransform;
172}
173
174void G4DisplacedSolid::SetDirectTransform(G4AffineTransform& transform) 
175{
176  fDirectTransform = &transform ;
177  fpPolyhedron = 0;
178}
179
180/////////////////////////////////////////////////////////////////////////////
181
182G4RotationMatrix G4DisplacedSolid::GetFrameRotation() const
183{
184  G4RotationMatrix InvRotation= fDirectTransform->NetRotation();
185  return InvRotation;
186}
187
188void G4DisplacedSolid::SetFrameRotation(const G4RotationMatrix& matrix)
189{
190  fDirectTransform->SetNetRotation(matrix);
191  fpPolyhedron = 0;
192}
193
194/////////////////////////////////////////////////////////////////////////////
195
196G4ThreeVector  G4DisplacedSolid::GetFrameTranslation() const
197{
198  return fPtrTransform->NetTranslation();
199}
200
201void G4DisplacedSolid::SetFrameTranslation(const G4ThreeVector& vector)
202{
203  fPtrTransform->SetNetTranslation(vector);
204  fpPolyhedron = 0;
205}
206
207///////////////////////////////////////////////////////////////
208
209G4RotationMatrix G4DisplacedSolid::GetObjectRotation() const
210{
211  G4RotationMatrix Rotation= fPtrTransform->NetRotation();
212  return Rotation;
213}
214
215void G4DisplacedSolid::SetObjectRotation(const G4RotationMatrix& matrix)
216{
217  fPtrTransform->SetNetRotation(matrix);
218  fpPolyhedron = 0;
219}
220
221///////////////////////////////////////////////////////////////////////
222
223G4ThreeVector  G4DisplacedSolid::GetObjectTranslation() const
224{
225  return fDirectTransform->NetTranslation();
226}
227
228void G4DisplacedSolid::SetObjectTranslation(const G4ThreeVector& vector)
229{
230  fDirectTransform->SetNetTranslation(vector);
231  fpPolyhedron = 0;
232}
233
234///////////////////////////////////////////////////////////////
235//
236//
237     
238G4bool
239G4DisplacedSolid::CalculateExtent( const EAxis pAxis,
240                                   const G4VoxelLimits& pVoxelLimit,
241                                   const G4AffineTransform& pTransform,
242                                         G4double& pMin, 
243                                         G4double& pMax           ) const 
244{
245  G4AffineTransform sumTransform ;
246  sumTransform.Product(*fDirectTransform,pTransform) ;
247  return fPtrSolid->CalculateExtent(pAxis,pVoxelLimit,sumTransform,pMin,pMax) ;
248}
249 
250/////////////////////////////////////////////////////
251//
252//
253
254EInside G4DisplacedSolid::Inside(const G4ThreeVector& p) const
255{
256  G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
257  return fPtrSolid->Inside(newPoint) ; 
258}
259
260//////////////////////////////////////////////////////////////
261//
262//
263
264G4ThreeVector
265G4DisplacedSolid::SurfaceNormal( const G4ThreeVector& p ) const 
266{
267  G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
268  G4ThreeVector normal = fPtrSolid->SurfaceNormal(newPoint) ; 
269  return fDirectTransform->TransformAxis(normal) ;
270}
271
272/////////////////////////////////////////////////////////////
273//
274// The same algorithm as in DistanceToIn(p)
275
276G4double
277G4DisplacedSolid::DistanceToIn( const G4ThreeVector& p,
278                                const G4ThreeVector& v  ) const 
279{   
280  G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
281  G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
282  return fPtrSolid->DistanceToIn(newPoint,newDirection) ;   
283}
284
285////////////////////////////////////////////////////////
286//
287// Approximate nearest distance from the point p to the intersection of
288// two solids
289
290G4double
291G4DisplacedSolid::DistanceToIn( const G4ThreeVector& p ) const 
292{
293  G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
294  return fPtrSolid->DistanceToIn(newPoint) ;   
295}
296
297//////////////////////////////////////////////////////////
298//
299// The same algorithm as DistanceToOut(p)
300
301G4double
302G4DisplacedSolid::DistanceToOut( const G4ThreeVector& p,
303                                 const G4ThreeVector& v,
304                                 const G4bool calcNorm,
305                                       G4bool *validNorm,
306                                       G4ThreeVector *n   ) const 
307{
308  G4ThreeVector solNorm ; 
309  G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
310  G4ThreeVector newDirection = fPtrTransform->TransformAxis(v) ;
311  G4double dist = fPtrSolid->DistanceToOut(newPoint,newDirection,
312                                           calcNorm,validNorm,&solNorm) ;
313  if(calcNorm)
314  { 
315    *n = fDirectTransform->TransformAxis(solNorm) ;
316  }
317  return dist ; 
318}
319
320//////////////////////////////////////////////////////////////
321//
322// Inverted algorithm of DistanceToIn(p)
323
324G4double
325G4DisplacedSolid::DistanceToOut( const G4ThreeVector& p ) const 
326{
327  G4ThreeVector newPoint = fPtrTransform->TransformPoint(p) ;
328  return fPtrSolid->DistanceToOut(newPoint) ;   
329}
330
331//////////////////////////////////////////////////////////////
332//
333//
334
335void 
336G4DisplacedSolid::ComputeDimensions(       G4VPVParameterisation*,
337                                     const G4int,
338                                     const G4VPhysicalVolume* ) 
339{
340  DumpInfo();
341  G4Exception("G4DisplacedSolid::ComputeDimensions()",
342                "NotApplicable", FatalException,
343                "Method not applicable in this context!");
344}
345
346//////////////////////////////////////////////////////////////////////////
347//
348// Returns a point (G4ThreeVector) randomly and uniformly selected
349// on the solid surface
350//
351
352G4ThreeVector G4DisplacedSolid::GetPointOnSurface() const
353{
354  G4ThreeVector p =  fPtrSolid->GetPointOnSurface();
355  return fDirectTransform->TransformPoint(p);
356}
357
358//////////////////////////////////////////////////////////////////////////
359//
360// Stream object contents to an output stream
361
362std::ostream& G4DisplacedSolid::StreamInfo(std::ostream& os) const
363{
364  os << "-----------------------------------------------------------\n"
365     << "    *** Dump for Displaced solid - " << GetName() << " ***\n"
366     << "    ===================================================\n"
367     << " Solid type: " << GetEntityType() << "\n"
368     << " Parameters of constituent solid: \n"
369     << "===========================================================\n";
370  fPtrSolid->StreamInfo(os);
371  os << "===========================================================\n"
372     << " Transformations: \n"
373     << "    Direct transformation - translation : \n"
374     << "           " << fDirectTransform->NetTranslation() << "\n"
375     << "                          - rotation    : \n"
376     << "           ";
377  fDirectTransform->NetRotation().print(os);
378  os << "\n"
379     << "===========================================================\n";
380
381  return os;
382}
383
384//////////////////////////////////////////////////////////////////////////
385//
386//                   
387
388void 
389G4DisplacedSolid::DescribeYourselfTo ( G4VGraphicsScene& scene ) const 
390{
391  scene.AddSolid (*this);
392}
393
394//////////////////////////////////////////////////////////////////////////
395//
396//
397
398G4Polyhedron* 
399G4DisplacedSolid::CreatePolyhedron () const 
400{
401  G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron();
402  polyhedron
403    ->Transform(G4Transform3D(GetObjectRotation(),GetObjectTranslation()));
404  return polyhedron;
405}
406
407//////////////////////////////////////////////////////////////////////////
408//
409//
410
411G4NURBS*     
412G4DisplacedSolid::CreateNURBS () const 
413{
414  // Take into account local transformation - see CreatePolyhedron.
415  // return fPtrSolid->CreateNURBS() ;
416  return 0;
417}
418
419//////////////////////////////////////////////////////////////////////////
420//
421//
422
423G4Polyhedron* G4DisplacedSolid::GetPolyhedron () const
424{
425  if (!fpPolyhedron ||
426      fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
427      fpPolyhedron->GetNumberOfRotationSteps())
428    {
429      delete fpPolyhedron;
430      fpPolyhedron = CreatePolyhedron();
431    }
432  return fpPolyhedron;
433}
Note: See TracBrowser for help on using the repository browser.