source: trunk/source/geometry/solids/Boolean/src/G4BooleanSolid.cc @ 1315

Last change on this file since 1315 was 1315, checked in by garnier, 14 years ago

update geant4-09-04-beta-cand-01 interfaces-V09-03-09 vis-V09-03-08

File size: 8.9 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: G4BooleanSolid.cc,v 1.23 2010/05/11 15:03:45 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-04-beta-cand-01 $
29//
30// Implementation for the abstract base class for solids created by boolean
31// operations between other solids
32//
33// History:
34//
35// 10.09.98 V.Grichine, created
36//
37// --------------------------------------------------------------------
38
39#include "G4BooleanSolid.hh"
40#include "G4VSolid.hh"
41#include "G4Polyhedron.hh"
42#include "HepPolyhedronProcessor.h"
43#include "Randomize.hh"
44
45//////////////////////////////////////////////////////////////////
46//
47// Constructor
48
49G4BooleanSolid::G4BooleanSolid( const G4String& pName,
50                                G4VSolid* pSolidA ,
51                                G4VSolid* pSolidB   ) :
52  G4VSolid(pName), fStatistics(1000000), fCubVolEpsilon(0.001),
53  fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
54  fpPolyhedron(0), createdDisplacedSolid(false)
55{
56  fPtrSolidA = pSolidA ;
57  fPtrSolidB = pSolidB ;
58}
59
60//////////////////////////////////////////////////////////////////
61//
62// Constructor
63
64G4BooleanSolid::G4BooleanSolid( const G4String& pName,
65                                      G4VSolid* pSolidA ,
66                                      G4VSolid* pSolidB ,
67                                      G4RotationMatrix* rotMatrix,
68                                const G4ThreeVector& transVector    ) :
69  G4VSolid(pName), fStatistics(1000000), fCubVolEpsilon(0.001),
70  fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
71  fpPolyhedron(0), createdDisplacedSolid(true)
72{
73  fPtrSolidA = pSolidA ;
74  fPtrSolidB = new G4DisplacedSolid("placedB",pSolidB,rotMatrix,transVector) ;
75}
76
77//////////////////////////////////////////////////////////////////
78//
79// Constructor
80
81G4BooleanSolid::G4BooleanSolid( const G4String& pName,
82                                      G4VSolid* pSolidA ,
83                                      G4VSolid* pSolidB ,
84                                const G4Transform3D& transform    ) :
85  G4VSolid(pName), fStatistics(1000000), fCubVolEpsilon(0.001),
86  fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
87  fpPolyhedron(0), createdDisplacedSolid(true)
88{
89  fPtrSolidA = pSolidA ;
90  fPtrSolidB = new G4DisplacedSolid("placedB",pSolidB,transform) ;
91}
92
93///////////////////////////////////////////////////////////////
94//
95// Fake default constructor - sets only member data and allocates memory
96//                            for usage restricted to object persistency.
97
98G4BooleanSolid::G4BooleanSolid( __void__& a )
99  : G4VSolid(a), fPtrSolidA(0), fPtrSolidB(0),
100    fStatistics(1000000), fCubVolEpsilon(0.001), 
101    fAreaAccuracy(-1.), fCubicVolume(0.), fSurfaceArea(0.),
102    fpPolyhedron(0), createdDisplacedSolid(false)
103{
104}
105
106///////////////////////////////////////////////////////////////
107//
108// Destructor deletes transformation contents of the created displaced solid
109
110G4BooleanSolid::~G4BooleanSolid() 
111{
112  if(createdDisplacedSolid)
113  {
114    ((G4DisplacedSolid*)fPtrSolidB)->CleanTransformations();
115  }
116  delete fpPolyhedron;
117}
118
119///////////////////////////////////////////////////////////////
120//
121// If Solid is made up from a Boolean operation of two solids,
122//   return the corresponding solid (for no=0 and 1)
123// If the solid is not a "Boolean", return 0
124
125const G4VSolid* G4BooleanSolid::GetConstituentSolid(G4int no) const
126{
127  const G4VSolid*  subSolid=0;
128  if( no == 0 ) 
129    subSolid = fPtrSolidA;
130  else if( no == 1 ) 
131    subSolid = fPtrSolidB;
132  else
133  {
134    DumpInfo();
135    G4Exception("G4BooleanSolid::GetConstituentSolid()",
136                "WrongArgumentValue", FatalException,
137                "Invalid solid index.");
138  }
139
140  return subSolid;
141}
142
143///////////////////////////////////////////////////////////////
144//
145// If Solid is made up from a Boolean operation of two solids,
146//   return the corresponding solid (for no=0 and 1)
147// If the solid is not a "Boolean", return 0
148
149G4VSolid* G4BooleanSolid::GetConstituentSolid(G4int no)
150{
151  G4VSolid*  subSolid=0;
152  if( no == 0 ) 
153    subSolid = fPtrSolidA;
154  else if( no == 1 ) 
155    subSolid = fPtrSolidB;
156  else
157  {
158    DumpInfo();
159    G4Exception("G4BooleanSolid::GetConstituentSolid()",
160                "WrongArgumentValue", FatalException,
161                "Invalid solid index.");
162  }
163
164  return subSolid;
165}
166
167//////////////////////////////////////////////////////////////////////////
168//
169// Returns entity type
170
171G4GeometryType G4BooleanSolid::GetEntityType() const 
172{
173  return G4String("G4BooleanSolid");
174}
175
176//////////////////////////////////////////////////////////////////////////
177//
178// Stream object contents to an output stream
179
180std::ostream& G4BooleanSolid::StreamInfo(std::ostream& os) const
181{
182  os << "-----------------------------------------------------------\n"
183     << "    *** Dump for Boolean solid - " << GetName() << " ***\n"
184     << "    ===================================================\n"
185     << " Solid type: " << GetEntityType() << "\n"
186     << " Parameters of constituent solids: \n"
187     << "===========================================================\n";
188  fPtrSolidA->StreamInfo(os);
189  fPtrSolidB->StreamInfo(os);
190  os << "===========================================================\n";
191
192  return os;
193}
194
195//////////////////////////////////////////////////////////////////////////
196//
197// Returns a point (G4ThreeVector) randomly and uniformly selected
198// on the solid surface
199//
200
201G4ThreeVector G4BooleanSolid::GetPointOnSurface() const
202{
203  G4bool condition = true;
204  G4double rand;
205  G4ThreeVector p;
206
207  while(condition)
208  {
209    rand = G4UniformRand();
210
211    if(rand > 0.5) { p = fPtrSolidA->GetPointOnSurface(); }
212    else           { p = fPtrSolidB->GetPointOnSurface(); }
213
214    if(Inside(p) == kSurface)  { break; }
215  }
216  return p;
217}
218
219//////////////////////////////////////////////////////////////////////////
220//
221// Returns polyhedron for visualization
222
223G4Polyhedron* G4BooleanSolid::GetPolyhedron () const
224{
225  if (!fpPolyhedron ||
226      fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
227      fpPolyhedron->GetNumberOfRotationSteps())
228    {
229      delete fpPolyhedron;
230      fpPolyhedron = CreatePolyhedron();
231    }
232  return fpPolyhedron;
233}
234
235//////////////////////////////////////////////////////////////////////////
236//
237// Stacks polyhedra for processing. Returns top polyhedron.
238
239G4Polyhedron*
240G4BooleanSolid::StackPolyhedron(HepPolyhedronProcessor& processor,
241                                const G4VSolid* solid) const
242{
243  HepPolyhedronProcessor::Operation operation;
244  const G4String& type = solid->GetEntityType();
245  if (type == "G4UnionSolid")
246    { operation = HepPolyhedronProcessor::UNION; }
247  else if (type == "G4IntersectionSolid")
248    { operation = HepPolyhedronProcessor::INTERSECTION; }
249  else if (type == "G4SubtractionSolid")
250    { operation = HepPolyhedronProcessor::SUBTRACTION; }
251  else
252  {
253    std::ostringstream oss;
254    oss << "Solid - " << solid->GetName()
255        << " - Unrecognised composite solid"
256        << "\n  Returning NULL !";
257    G4Exception("StackPolyhedron()", "InvalidSetup",
258                JustWarning, oss.str().c_str());
259    return 0;
260  }
261
262  G4Polyhedron* top = 0;
263  const G4VSolid* solidA = solid->GetConstituentSolid(0);
264  const G4VSolid* solidB = solid->GetConstituentSolid(1);
265
266  if (solidA->GetConstituentSolid(0))
267  {
268    top = StackPolyhedron(processor, solidA);
269  }
270  else
271  {
272    top = solidA->GetPolyhedron();
273  }
274  G4Polyhedron* operand = solidB->GetPolyhedron();
275  processor.push_back (operation, *operand);
276
277  return top;
278}
Note: See TracBrowser for help on using the repository browser.