Geant4_10
G4UPolyhedra.cc
Go to the documentation of this file.
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:$
28 //
29 // Implementation of G4UPolycone wrapper class
30 // --------------------------------------------------------------------
31 
32 #include "G4Polyhedra.hh"
33 #include "G4UPolyhedra.hh"
34 #include "G4Polyhedron.hh"
35 #include "G4VPVParameterisation.hh"
36 
37 using CLHEP::twopi;
38 
40 //
41 // Constructor (GEANT3 style parameters)
42 //
43 // GEANT3 PGON radii are specified in the distance to the norm of each face.
44 //
46  G4double phiStart,
47  G4double phiTotal,
48  G4int numSide,
49  G4int numZPlanes,
50  const G4double zPlane[],
51  const G4double rInner[],
52  const G4double rOuter[] )
53  : G4USolid(name, new UPolyhedra(name,phiStart, phiTotal, numSide,
54  numZPlanes, zPlane, rInner, rOuter))
55 {
56 }
57 
58 
60 //
61 // Constructor (generic parameters)
62 //
64  G4double phiStart,
65  G4double phiTotal,
66  G4int numSide,
67  G4int numRZ,
68  const G4double r[],
69  const G4double z[] )
70  : G4USolid(name, new UPolyhedra(name, phiStart, phiTotal, numSide,
71  numRZ, r, z))
72 {
73 }
74 
75 
77 //
78 // Fake default constructor - sets only member data and allocates memory
79 // for usage restricted to object persistency.
80 //
82  : G4USolid(a)
83 {
84 }
85 
86 
88 //
89 // Destructor
90 //
92 {
93 }
94 
95 
97 //
98 // Copy constructor
99 //
101  : G4USolid( source )
102 {
103 }
104 
105 
107 //
108 // Assignment operator
109 //
111 {
112  if (this == &source) return *this;
113 
114  G4USolid::operator=( source );
115 
116  return *this;
117 }
118 
119 
121 //
122 // Dispatch to parameterisation for replication mechanism dimension
123 // computation & modification.
124 //
126  const G4int n,
127  const G4VPhysicalVolume* pRep)
128 {
129  p->ComputeDimensions(*(G4Polyhedra*)this,n,pRep);
130 }
131 
132 
134 //
135 // CreatePolyhedron
136 //
138 {
139  if (!IsGeneric())
140  {
141  G4PolyhedraHistorical* original_parameters = GetOriginalParameters();
143  polyhedron = new G4PolyhedronPgon( GetOriginalParameters()->Start_angle,
144  GetOriginalParameters()->Opening_angle,
145  GetOriginalParameters()->numSide,
146  GetOriginalParameters()->Num_z_planes,
147  GetOriginalParameters()->Z_values,
148  GetOriginalParameters()->Rmin,
149  GetOriginalParameters()->Rmax);
150  delete original_parameters; // delete local copy
151  return polyhedron;
152  }
153  else
154  {
155  // The following code prepares for:
156  // HepPolyhedron::createPolyhedron(int Nnodes, int Nfaces,
157  // const double xyz[][3],
158  // const int faces_vec[][4])
159  // Here is an extract from the header file HepPolyhedron.h:
177  G4int nNodes;
178  G4int nFaces;
179  typedef G4double double3[3];
180  double3* xyz;
181  typedef G4int int4[4];
182  int4* faces_vec;
183  if (IsOpen())
184  {
185  // Triangulate open ends. Simple ear-chopping algorithm...
186  // I'm not sure how robust this algorithm is (J.Allison).
187  //
188  std::vector<G4bool> chopped(GetNumRZCorner(), false);
189  std::vector<G4int*> triQuads;
190  G4int remaining = GetNumRZCorner();
191  G4int iStarter = 0;
192  while (remaining >= 3)
193  {
194  // Find unchopped corners...
195  //
196  G4int A = -1, B = -1, C = -1;
197  G4int iStepper = iStarter;
198  do
199  {
200  if (A < 0) { A = iStepper; }
201  else if (B < 0) { B = iStepper; }
202  else if (C < 0) { C = iStepper; }
203  do
204  {
205  if (++iStepper >= GetNumRZCorner()) iStepper = 0;
206  }
207  while (chopped[iStepper]);
208  }
209  while (C < 0 && iStepper != iStarter);
210 
211  // Check triangle at B is pointing outward (an "ear").
212  // Sign of z cross product determines...
213 
214  G4double BAr = GetCorner(A).r - GetCorner(B).r;
215  G4double BAz = GetCorner(A).z - GetCorner(B).z;
216  G4double BCr = GetCorner(C).r - GetCorner(B).r;
217  G4double BCz = GetCorner(C).z - GetCorner(B).z;
218  if (BAr * BCz - BAz * BCr < kCarTolerance)
219  {
220  G4int* tq = new G4int[3];
221  tq[0] = A + 1;
222  tq[1] = B + 1;
223  tq[2] = C + 1;
224  triQuads.push_back(tq);
225  chopped[B] = true;
226  --remaining;
227  }
228  else
229  {
230  do
231  {
232  if (++iStarter >= GetNumRZCorner()) { iStarter = 0; }
233  }
234  while (chopped[iStarter]);
235  }
236  }
237 
238  // Transfer to faces...
239  G4int numSide=GetNumSide();
240  nNodes = (numSide + 1) * GetNumRZCorner();
241  nFaces = numSide * GetNumRZCorner() + 2 * triQuads.size();
242  faces_vec = new int4[nFaces];
243  G4int iface = 0;
244  G4int addition = GetNumRZCorner() * numSide;
245  G4int d = GetNumRZCorner() - 1;
246  for (G4int iEnd = 0; iEnd < 2; ++iEnd)
247  {
248  for (size_t i = 0; i < triQuads.size(); ++i)
249  {
250  // Negative for soft/auxiliary/normally invisible edges...
251  //
252  G4int a, b, c;
253  if (iEnd == 0)
254  {
255  a = triQuads[i][0];
256  b = triQuads[i][1];
257  c = triQuads[i][2];
258  }
259  else
260  {
261  a = triQuads[i][0] + addition;
262  b = triQuads[i][2] + addition;
263  c = triQuads[i][1] + addition;
264  }
265  G4int ab = std::abs(b - a);
266  G4int bc = std::abs(c - b);
267  G4int ca = std::abs(a - c);
268  faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
269  faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
270  faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
271  faces_vec[iface][3] = 0;
272  ++iface;
273  }
274  }
275 
276  // Continue with sides...
277 
278  xyz = new double3[nNodes];
279  const G4double dPhi = (GetEndPhi() - GetStartPhi()) / numSide;
280  G4double phi = GetStartPhi();
281  G4int ixyz = 0;
282  for (G4int iSide = 0; iSide < numSide; ++iSide)
283  {
284  for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
285  {
286  xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
287  xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
288  xyz[ixyz][2] = GetCorner(iCorner).z;
289  if (iCorner < GetNumRZCorner() - 1)
290  {
291  faces_vec[iface][0] = ixyz + 1;
292  faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
293  faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
294  faces_vec[iface][3] = ixyz + 2;
295  }
296  else
297  {
298  faces_vec[iface][0] = ixyz + 1;
299  faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
300  faces_vec[iface][2] = ixyz + 2;
301  faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
302  }
303  ++iface;
304  ++ixyz;
305  }
306  phi += dPhi;
307  }
308 
309  // Last GetCorner...
310 
311  for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
312  {
313  xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
314  xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
315  xyz[ixyz][2] = GetCorner(iCorner).z;
316  ++ixyz;
317  }
318  }
319  else // !phiIsOpen - i.e., a complete 360 degrees.
320  {
321  nNodes = GetNumSide() * GetNumRZCorner();
322  nFaces = GetNumSide() * GetNumRZCorner();;
323  xyz = new double3[nNodes];
324  faces_vec = new int4[nFaces];
325  // const G4double dPhi = (endPhi - startPhi) / numSide;
326  const G4double dPhi = twopi / GetNumSide(); // !phiIsOpen endPhi-startPhi = 360 degrees.
327  G4double phi = GetStartPhi();
328  G4int ixyz = 0, iface = 0;
329  for (G4int iSide = 0; iSide < GetNumSide(); ++iSide)
330  {
331  for (G4int iCorner = 0; iCorner < GetNumRZCorner(); ++iCorner)
332  {
333  xyz[ixyz][0] = GetCorner(iCorner).r * std::cos(phi);
334  xyz[ixyz][1] = GetCorner(iCorner).r * std::sin(phi);
335  xyz[ixyz][2] = GetCorner(iCorner).z;
336  if (iSide < GetNumSide() - 1)
337  {
338  if (iCorner < GetNumRZCorner() - 1)
339  {
340  faces_vec[iface][0] = ixyz + 1;
341  faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
342  faces_vec[iface][2] = ixyz + GetNumRZCorner() + 2;
343  faces_vec[iface][3] = ixyz + 2;
344  }
345  else
346  {
347  faces_vec[iface][0] = ixyz + 1;
348  faces_vec[iface][1] = ixyz + GetNumRZCorner() + 1;
349  faces_vec[iface][2] = ixyz + 2;
350  faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
351  }
352  }
353  else // Last side joins ends...
354  {
355  if (iCorner < GetNumRZCorner() - 1)
356  {
357  faces_vec[iface][0] = ixyz + 1;
358  faces_vec[iface][1] = ixyz + GetNumRZCorner() - nFaces + 1;
359  faces_vec[iface][2] = ixyz + GetNumRZCorner() - nFaces + 2;
360  faces_vec[iface][3] = ixyz + 2;
361  }
362  else
363  {
364  faces_vec[iface][0] = ixyz + 1;
365  faces_vec[iface][1] = ixyz - nFaces + GetNumRZCorner() + 1;
366  faces_vec[iface][2] = ixyz - nFaces + 2;
367  faces_vec[iface][3] = ixyz - GetNumRZCorner() + 2;
368  }
369  }
370  ++ixyz;
371  ++iface;
372  }
373  phi += dPhi;
374  }
375  }
376  G4Polyhedron* polyhedron = new G4Polyhedron;
377  G4int problem = polyhedron->createPolyhedron(nNodes, nFaces, xyz, faces_vec);
378  delete [] faces_vec;
379  delete [] xyz;
380  if (problem)
381  {
382  std::ostringstream message;
383  message << "Problem creating G4Polyhedron for: " << GetName();
384  G4Exception("G4Polyhedra::CreatePolyhedron()", "GeomSolids1002",
385  JustWarning, message);
386  delete polyhedron;
387  return 0;
388  }
389  else
390  {
391  return polyhedron;
392  }
393  }
394 }
G4String GetName() const
G4UPolyhedra & operator=(const G4UPolyhedra &source)
tuple a
Definition: test.py:11
Float_t d
Definition: plot.C:237
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
const char * p
Definition: xmltok.h:285
const XML_Char * name
Definition: expat.h:151
int G4int
Definition: G4Types.hh:78
G4int GetNumRZCorner() const
G4UPolyhedra(const G4String &name, G4double phiStart, G4double phiTotal, G4int numSide, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
Definition: G4UPolyhedra.cc:45
tuple b
Definition: test.py:12
Char_t n[5]
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4double GetEndPhi() const
G4double GetStartPhi() const
G4PolyhedraHistorical * GetOriginalParameters() const
G4bool IsGeneric() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4PolyhedraSideRZ GetCorner(const G4int index) const
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
jump r
Definition: plot.C:36
G4Polyhedron * CreatePolyhedron() const
G4int GetNumSide() const
G4USolid & operator=(const G4USolid &rhs)
Definition: G4USolid.cc:357
tuple z
Definition: test.py:28
G4double kCarTolerance
Definition: G4VSolid.hh:305
double G4double
Definition: G4Types.hh:76
tuple c
Definition: test.py:13
G4bool IsOpen() const