Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4GenericPolycone.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 //
27 // $Id: G4GenericPolycone.cc 72131 2013-07-11 07:12:24Z gcosmo $
28 //
29 //
30 // --------------------------------------------------------------------
31 // GEANT 4 class source file
32 //
33 //
34 // G4GenericPolycone.cc
35 //
36 // Implementation of a CSG polycone
37 //
38 // --------------------------------------------------------------------
39 
40 #include "G4GenericPolycone.hh"
41 
42 //#if !defined(G4GEOM_USE_UGENERICPOLYCONE)
43 
44 #include "G4PolyconeSide.hh"
45 #include "G4PolyPhiFace.hh"
46 
47 #include "G4GeomTools.hh"
48 #include "G4VoxelLimits.hh"
49 #include "G4AffineTransform.hh"
50 #include "G4BoundingEnvelope.hh"
51 
52 #include "Randomize.hh"
53 
54 #include "G4Polyhedron.hh"
55 #include "G4EnclosingCylinder.hh"
56 #include "G4ReduciblePolygon.hh"
57 #include "G4VPVParameterisation.hh"
58 
59 using namespace CLHEP;
60 
61 //
62 // Constructor (generic parameters)
63 //
65  G4double phiStart,
66  G4double phiTotal,
67  G4int numRZ,
68  const G4double r[],
69  const G4double z[] )
70  : G4VCSGfaceted( name )
71 {
72 
73  G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
74 
75  Create( phiStart, phiTotal, rz );
76 
77  // Set original_parameters struct for consistency
78  //
79  //SetOriginalParameters(rz);
80 
81  delete rz;
82 }
83 
84 //
85 // Create
86 //
87 // Generic create routine, called by each constructor after
88 // conversion of arguments
89 //
91  G4double phiTotal,
92  G4ReduciblePolygon *rz )
93 {
94  //
95  // Perform checks of rz values
96  //
97  if (rz->Amin() < 0.0)
98  {
99  std::ostringstream message;
100  message << "Illegal input parameters - " << GetName() << G4endl
101  << " All R values must be >= 0 !";
102  G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
103  FatalErrorInArgument, message);
104  }
105 
106  G4double rzArea = rz->Area();
107  if (rzArea < -kCarTolerance)
108  {
109  rz->ReverseOrder();
110  }
111  else if (rzArea < kCarTolerance)
112  {
113  std::ostringstream message;
114  message << "Illegal input parameters - " << GetName() << G4endl
115  << " R/Z cross section is zero or near zero: " << rzArea;
116  G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
117  FatalErrorInArgument, message);
118  }
119 
121  || (!rz->RemoveRedundantVertices( kCarTolerance )) )
122  {
123  std::ostringstream message;
124  message << "Illegal input parameters - " << GetName() << G4endl
125  << " Too few unique R/Z values !";
126  G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
127  FatalErrorInArgument, message);
128  }
129 
130  if (rz->CrossesItself(1/kInfinity))
131  {
132  std::ostringstream message;
133  message << "Illegal input parameters - " << GetName() << G4endl
134  << " R/Z segments cross !";
135  G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
136  FatalErrorInArgument, message);
137  }
138 
139  numCorner = rz->NumVertices();
140 
141  //
142  // Phi opening? Account for some possible roundoff, and interpret
143  // nonsense value as representing no phi opening
144  //
145  if (phiTotal <= 0 || phiTotal > twopi-1E-10)
146  {
147  phiIsOpen = false;
148  startPhi = 0;
149  endPhi = twopi;
150  }
151  else
152  {
153  phiIsOpen = true;
154 
155  //
156  // Convert phi into our convention
157  //
158  startPhi = phiStart;
159  while( startPhi < 0 ) // Loop checking, 13.08.2015, G.Cosmo
160  startPhi += twopi;
161 
162  endPhi = phiStart+phiTotal;
163  while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
164  endPhi += twopi;
165  }
166 
167  //
168  // Allocate corner array.
169  //
171 
172  //
173  // Copy corners
174  //
175  G4ReduciblePolygonIterator iterRZ(rz);
176 
177  G4PolyconeSideRZ *next = corners;
178  iterRZ.Begin();
179  do // Loop checking, 13.08.2015, G.Cosmo
180  {
181  next->r = iterRZ.GetA();
182  next->z = iterRZ.GetB();
183  } while( ++next, iterRZ.Next() );
184 
185  //
186  // Allocate face pointer array
187  //
189  faces = new G4VCSGface*[numFace];
190 
191  //
192  // Construct conical faces
193  //
194  // But! Don't construct a face if both points are at zero radius!
195  //
196  G4PolyconeSideRZ *corner = corners,
197  *prev = corners + numCorner-1,
198  *nextNext;
199  G4VCSGface **face = faces;
200  do // Loop checking, 13.08.2015, G.Cosmo
201  {
202  next = corner+1;
203  if (next >= corners+numCorner) next = corners;
204  nextNext = next+1;
205  if (nextNext >= corners+numCorner) nextNext = corners;
206 
207  if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
208 
209  //
210  // We must decide here if we can dare declare one of our faces
211  // as having a "valid" normal (i.e. allBehind = true). This
212  // is never possible if the face faces "inward" in r.
213  //
214  G4bool allBehind;
215  if (corner->z > next->z)
216  {
217  allBehind = false;
218  }
219  else
220  {
221  //
222  // Otherwise, it is only true if the line passing
223  // through the two points of the segment do not
224  // split the r/z cross section
225  //
226  allBehind = !rz->BisectedBy( corner->r, corner->z,
227  next->r, next->z, kCarTolerance );
228  }
229 
230  *face++ = new G4PolyconeSide( prev, corner, next, nextNext,
231  startPhi, endPhi-startPhi, phiIsOpen, allBehind );
232  } while( prev=corner, corner=next, corner > corners );
233 
234  if (phiIsOpen)
235  {
236  //
237  // Construct phi open edges
238  //
239  *face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
240  *face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
241  }
242 
243  //
244  // We might have dropped a face or two: recalculate numFace
245  //
246  numFace = face-faces;
247 
248  //
249  // Make enclosingCylinder
250  //
252  new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
253 }
254 
255 
256 //
257 // Fake default constructor - sets only member data and allocates memory
258 // for usage restricted to object persistency.
259 //
261  : G4VCSGfaceted(a), startPhi(0.), endPhi(0.), phiIsOpen(false),
262  numCorner(0), corners(0), enclosingCylinder(0)
263 {
264 }
265 
266 
267 //
268 // Destructor
269 //
271 {
272  delete [] corners;
273  delete enclosingCylinder;
274 }
275 
276 
277 //
278 // Copy constructor
279 //
281  : G4VCSGfaceted( source )
282 {
283  CopyStuff( source );
284 }
285 
286 
287 //
288 // Assignment operator
289 //
292 {
293  if (this == &source) return *this;
294 
295  G4VCSGfaceted::operator=( source );
296 
297  delete [] corners;
298  // if (original_parameters) delete original_parameters;
299 
300  delete enclosingCylinder;
301 
302  CopyStuff( source );
303 
304  return *this;
305 }
306 
307 
308 //
309 // CopyStuff
310 //
312 {
313  //
314  // Simple stuff
315  //
316  startPhi = source.startPhi;
317  endPhi = source.endPhi;
318  phiIsOpen = source.phiIsOpen;
319  numCorner = source.numCorner;
320 
321  //
322  // The corner array
323  //
325 
326  G4PolyconeSideRZ *corn = corners,
327  *sourceCorn = source.corners;
328  do // Loop checking, 13.08.2015, G.Cosmo
329  {
330  *corn = *sourceCorn;
331  } while( ++sourceCorn, ++corn < corners+numCorner );
332 
333  //
334  // Enclosing cylinder
335  //
337 
338  fRebuildPolyhedron = false;
339  fpPolyhedron = 0;
340 }
341 
342 
343 //
344 // Reset
345 //
347 {
348 
349  std::ostringstream message;
350  message << "Solid " << GetName() << " built using generic construct."
351  << G4endl << "Not applicable to the generic construct !";
352  G4Exception("G4GenericPolycone::Reset()", "GeomSolids1001",
353  JustWarning, message, "Parameters NOT resetted.");
354  return 1;
355 
356 }
357 
358 
359 //
360 // Inside
361 //
362 // This is an override of G4VCSGfaceted::Inside, created in order
363 // to speed things up by first checking with G4EnclosingCylinder.
364 //
366 {
367  //
368  // Quick test
369  //
370  if (enclosingCylinder->MustBeOutside(p)) return kOutside;
371 
372  //
373  // Long answer
374  //
375  return G4VCSGfaceted::Inside(p);
376 }
377 
378 
379 //
380 // DistanceToIn
381 //
382 // This is an override of G4VCSGfaceted::Inside, created in order
383 // to speed things up by first checking with G4EnclosingCylinder.
384 //
386  const G4ThreeVector &v ) const
387 {
388  //
389  // Quick test
390  //
391  if (enclosingCylinder->ShouldMiss(p,v))
392  return kInfinity;
393 
394  //
395  // Long answer
396  //
397  return G4VCSGfaceted::DistanceToIn( p, v );
398 }
399 
400 
401 //
402 // DistanceToIn
403 //
405 {
406  return G4VCSGfaceted::DistanceToIn(p);
407 }
408 
410 //
411 // Get bounding box
412 
413 void
415  G4ThreeVector& pMax) const
416 {
417  G4double rmin = kInfinity, rmax = -kInfinity;
418  G4double zmin = kInfinity, zmax = -kInfinity;
419 
420  for (G4int i=0; i<GetNumRZCorner(); ++i)
421  {
422  G4PolyconeSideRZ corner = GetCorner(i);
423  if (corner.r < rmin) rmin = corner.r;
424  if (corner.r > rmax) rmax = corner.r;
425  if (corner.z < zmin) zmin = corner.z;
426  if (corner.z > zmax) zmax = corner.z;
427  }
428 
429  if (IsOpen())
430  {
431  G4TwoVector vmin,vmax;
432  G4GeomTools::DiskExtent(rmin,rmax,
435  vmin,vmax);
436  pMin.set(vmin.x(),vmin.y(),zmin);
437  pMax.set(vmax.x(),vmax.y(),zmax);
438  }
439  else
440  {
441  pMin.set(-rmax,-rmax, zmin);
442  pMax.set( rmax, rmax, zmax);
443  }
444 
445  // Check correctness of the bounding box
446  //
447  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
448  {
449  std::ostringstream message;
450  message << "Bad bounding box (min >= max) for solid: "
451  << GetName() << " !"
452  << "\npMin = " << pMin
453  << "\npMax = " << pMax;
454  G4Exception("GenericG4Polycone::BoundingLimits()", "GeomMgt0001",
455  JustWarning, message);
456  DumpInfo();
457  }
458 }
459 
461 //
462 // Calculate extent under transform and specified limit
463 
464 G4bool
466  const G4VoxelLimits& pVoxelLimit,
467  const G4AffineTransform& pTransform,
468  G4double& pMin, G4double& pMax) const
469 {
470  G4ThreeVector bmin, bmax;
471  G4bool exist;
472 
473  // Check bounding box (bbox)
474  //
475  BoundingLimits(bmin,bmax);
476  G4BoundingEnvelope bbox(bmin,bmax);
477 #ifdef G4BBOX_EXTENT
478  if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
479 #endif
480  if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
481  {
482  return exist = (pMin < pMax) ? true : false;
483  }
484 
485  // To find the extent, RZ contour of the polycone is subdivided
486  // in triangles. The extent is calculated as cumulative extent of
487  // all sub-polycones formed by rotation of triangles around Z
488  //
489  G4TwoVectorList contourRZ;
490  G4TwoVectorList triangles;
491  G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
492  G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
493 
494  // get RZ contour, ensure anticlockwise order of corners
495  for (G4int i=0; i<GetNumRZCorner(); ++i)
496  {
497  G4PolyconeSideRZ corner = GetCorner(i);
498  contourRZ.push_back(G4TwoVector(corner.r,corner.z));
499  }
500  G4double area = G4GeomTools::PolygonArea(contourRZ);
501  if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
502 
503  // triangulate RZ countour
504  if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
505  {
506  std::ostringstream message;
507  message << "Triangulation of RZ contour has failed for solid: "
508  << GetName() << " !"
509  << "\nExtent has been calculated using boundary box";
510  G4Exception("G4GenericPolycone::CalculateExtent()",
511  "GeomMgt1002", JustWarning, message);
512  return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
513  }
514 
515  // set trigonometric values
516  const G4int NSTEPS = 24; // number of steps for whole circle
517  G4double astep = twopi/NSTEPS; // max angle for one step
518 
519  G4double sphi = GetStartPhi();
520  G4double ephi = GetEndPhi();
521  G4double dphi = IsOpen() ? ephi-sphi : twopi;
522  G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1;
523  G4double ang = dphi/ksteps;
524 
525  G4double sinHalf = std::sin(0.5*ang);
526  G4double cosHalf = std::cos(0.5*ang);
527  G4double sinStep = 2.*sinHalf*cosHalf;
528  G4double cosStep = 1. - 2.*sinHalf*sinHalf;
529 
530  G4double sinStart = GetSinStartPhi();
531  G4double cosStart = GetCosStartPhi();
532  G4double sinEnd = GetSinEndPhi();
533  G4double cosEnd = GetCosEndPhi();
534 
535  // define vectors and arrays
536  std::vector<const G4ThreeVectorList *> polygons;
537  polygons.resize(ksteps+2);
538  G4ThreeVectorList pols[NSTEPS+2];
539  for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
540  for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
541  G4double r0[6],z0[6]; // contour with original edges of triangle
542  G4double r1[6]; // shifted radii of external edges of triangle
543 
544  // main loop along triangles
545  pMin = kInfinity;
546  pMax =-kInfinity;
547  G4int ntria = triangles.size()/3;
548  for (G4int i=0; i<ntria; ++i)
549  {
550  G4int i3 = i*3;
551  for (G4int k=0; k<3; ++k)
552  {
553  G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
554  G4int k2 = k*2;
555  // set contour with original edges of triangle
556  r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
557  r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
558  // set shifted radii
559  r1[k2+0] = r0[k2+0];
560  r1[k2+1] = r0[k2+1];
561  if (z0[k2+1] - z0[k2+0] <= 0) continue;
562  r1[k2+0] /= cosHalf;
563  r1[k2+1] /= cosHalf;
564  }
565 
566  // rotate countour, set sequence of 6-sided polygons
567  G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
568  G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
569  for (G4int j=0; j<6; ++j)
570  {
571  pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
572  }
573  for (G4int k=1; k<ksteps+1; ++k)
574  {
575  for (G4int j=0; j<6; ++j)
576  {
577  pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
578  }
579  G4double sinTmp = sinCur;
580  sinCur = sinCur*cosStep + cosCur*sinStep;
581  cosCur = cosCur*cosStep - sinTmp*sinStep;
582  }
583  for (G4int j=0; j<6; ++j)
584  {
585  pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
586  }
587 
588  // set sub-envelope and adjust extent
589  G4double emin,emax;
590  G4BoundingEnvelope benv(polygons);
591  if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
592  if (emin < pMin) pMin = emin;
593  if (emax > pMax) pMax = emax;
594  if (eminlim > pMin && emaxlim < pMax) return true; // max possible extent
595  }
596  return (pMin < pMax);
597 }
598 
599 //
600 // ComputeDimensions
601 //
602 /*void G4GenericPolycone::ComputeDimensions( G4VPVParameterisation* p,
603  const G4int n,
604  const G4VPhysicalVolume* pRep )
605 {
606  p->ComputeDimensions(*this,n,pRep);
607 }
608 */
609 //
610 // GetEntityType
611 //
613 {
614  return G4String("G4GenericPolycone");
615 }
616 
617 
618 //
619 // Make a clone of the object
620 //
622 {
623  return new G4GenericPolycone(*this);
624 }
625 
626 //
627 // Stream object contents to an output stream
628 //
629 std::ostream& G4GenericPolycone::StreamInfo( std::ostream& os ) const
630 {
631  G4int oldprc = os.precision(16);
632  os << "-----------------------------------------------------------\n"
633  << " *** Dump for solid - " << GetName() << " ***\n"
634  << " ===================================================\n"
635  << " Solid type: G4GenericPolycone\n"
636  << " Parameters: \n"
637  << " starting phi angle : " << startPhi/degree << " degrees \n"
638  << " ending phi angle : " << endPhi/degree << " degrees \n";
639  G4int i=0;
640 
641  os << " number of RZ points: " << numCorner << "\n"
642  << " RZ values (corners): \n";
643  for (i=0; i<numCorner; i++)
644  {
645  os << " "
646  << corners[i].r << ", " << corners[i].z << "\n";
647  }
648  os << "-----------------------------------------------------------\n";
649  os.precision(oldprc);
650 
651  return os;
652 }
653 
654 
655 
656 //
657 // GetPointOnSurface
658 //
660 {
661  return GetPointOnSurfaceGeneric();
662 
663 }
664 
665 //
666 // CreatePolyhedron
667 //
669 {
670  // The following code prepares for:
671  // HepPolyhedron::createPolyhedron(int Nnodes, int Nfaces,
672  // const double xyz[][3],
673  // const int faces_vec[][4])
674  // Here is an extract from the header file HepPolyhedron.h:
692  const G4int numSide =
694  * (endPhi - startPhi) / twopi) + 1;
695  G4int nNodes;
696  G4int nFaces;
697  typedef G4double double3[3];
698  double3* xyz;
699  typedef G4int int4[4];
700  int4* faces_vec;
701  if (phiIsOpen)
702  {
703  // Triangulate open ends. Simple ear-chopping algorithm...
704  // I'm not sure how robust this algorithm is (J.Allison).
705  //
706  std::vector<G4bool> chopped(numCorner, false);
707  std::vector<G4int*> triQuads;
708  G4int remaining = numCorner;
709  G4int iStarter = 0;
710  while (remaining >= 3) // Loop checking, 13.08.2015, G.Cosmo
711  {
712  // Find unchopped corners...
713  //
714  G4int A = -1, B = -1, C = -1;
715  G4int iStepper = iStarter;
716  do // Loop checking, 13.08.2015, G.Cosmo
717  {
718  if (A < 0) { A = iStepper; }
719  else if (B < 0) { B = iStepper; }
720  else if (C < 0) { C = iStepper; }
721  do // Loop checking, 13.08.2015, G.Cosmo
722  {
723  if (++iStepper >= numCorner) { iStepper = 0; }
724  }
725  while (chopped[iStepper]);
726  }
727  while (C < 0 && iStepper != iStarter);
728 
729  // Check triangle at B is pointing outward (an "ear").
730  // Sign of z cross product determines...
731  //
732  G4double BAr = corners[A].r - corners[B].r;
733  G4double BAz = corners[A].z - corners[B].z;
734  G4double BCr = corners[C].r - corners[B].r;
735  G4double BCz = corners[C].z - corners[B].z;
736  if (BAr * BCz - BAz * BCr < kCarTolerance)
737  {
738  G4int* tq = new G4int[3];
739  tq[0] = A + 1;
740  tq[1] = B + 1;
741  tq[2] = C + 1;
742  triQuads.push_back(tq);
743  chopped[B] = true;
744  --remaining;
745  }
746  else
747  {
748  do // Loop checking, 13.08.2015, G.Cosmo
749  {
750  if (++iStarter >= numCorner) { iStarter = 0; }
751  }
752  while (chopped[iStarter]);
753  }
754  }
755  // Transfer to faces...
756  //
757  nNodes = (numSide + 1) * numCorner;
758  nFaces = numSide * numCorner + 2 * triQuads.size();
759  faces_vec = new int4[nFaces];
760  G4int iface = 0;
761  G4int addition = numCorner * numSide;
762  G4int d = numCorner - 1;
763  for (G4int iEnd = 0; iEnd < 2; ++iEnd)
764  {
765  for (size_t i = 0; i < triQuads.size(); ++i)
766  {
767  // Negative for soft/auxiliary/normally invisible edges...
768  //
769  G4int a, b, c;
770  if (iEnd == 0)
771  {
772  a = triQuads[i][0];
773  b = triQuads[i][1];
774  c = triQuads[i][2];
775  }
776  else
777  {
778  a = triQuads[i][0] + addition;
779  b = triQuads[i][2] + addition;
780  c = triQuads[i][1] + addition;
781  }
782  G4int ab = std::abs(b - a);
783  G4int bc = std::abs(c - b);
784  G4int ca = std::abs(a - c);
785  faces_vec[iface][0] = (ab == 1 || ab == d)? a: -a;
786  faces_vec[iface][1] = (bc == 1 || bc == d)? b: -b;
787  faces_vec[iface][2] = (ca == 1 || ca == d)? c: -c;
788  faces_vec[iface][3] = 0;
789  ++iface;
790  }
791  }
792 
793  // Continue with sides...
794 
795  xyz = new double3[nNodes];
796  const G4double dPhi = (endPhi - startPhi) / numSide;
797  G4double phi = startPhi;
798  G4int ixyz = 0;
799  for (G4int iSide = 0; iSide < numSide; ++iSide)
800  {
801  for (G4int iCorner = 0; iCorner < numCorner; ++iCorner)
802  {
803  xyz[ixyz][0] = corners[iCorner].r * std::cos(phi);
804  xyz[ixyz][1] = corners[iCorner].r * std::sin(phi);
805  xyz[ixyz][2] = corners[iCorner].z;
806  if (iSide == 0) // startPhi
807  {
808  if (iCorner < numCorner - 1)
809  {
810  faces_vec[iface][0] = ixyz + 1;
811  faces_vec[iface][1] = -(ixyz + numCorner + 1);
812  faces_vec[iface][2] = ixyz + numCorner + 2;
813  faces_vec[iface][3] = ixyz + 2;
814  }
815  else
816  {
817  faces_vec[iface][0] = ixyz + 1;
818  faces_vec[iface][1] = -(ixyz + numCorner + 1);
819  faces_vec[iface][2] = ixyz + 2;
820  faces_vec[iface][3] = ixyz - numCorner + 2;
821  }
822  }
823  else if (iSide == numSide - 1) // endPhi
824  {
825  if (iCorner < numCorner - 1)
826  {
827  faces_vec[iface][0] = ixyz + 1;
828  faces_vec[iface][1] = ixyz + numCorner + 1;
829  faces_vec[iface][2] = ixyz + numCorner + 2;
830  faces_vec[iface][3] = -(ixyz + 2);
831  }
832  else
833  {
834  faces_vec[iface][0] = ixyz + 1;
835  faces_vec[iface][1] = ixyz + numCorner + 1;
836  faces_vec[iface][2] = ixyz + 2;
837  faces_vec[iface][3] = -(ixyz - numCorner + 2);
838  }
839  }
840  else
841  {
842  if (iCorner < numCorner - 1)
843  {
844  faces_vec[iface][0] = ixyz + 1;
845  faces_vec[iface][1] = -(ixyz + numCorner + 1);
846  faces_vec[iface][2] = ixyz + numCorner + 2;
847  faces_vec[iface][3] = -(ixyz + 2);
848  }
849  else
850  {
851  faces_vec[iface][0] = ixyz + 1;
852  faces_vec[iface][1] = -(ixyz + numCorner + 1);
853  faces_vec[iface][2] = ixyz + 2;
854  faces_vec[iface][3] = -(ixyz - numCorner + 2);
855  }
856  }
857  ++iface;
858  ++ixyz;
859  }
860  phi += dPhi;
861  }
862 
863  // Last corners...
864 
865  for (G4int iCorner = 0; iCorner < numCorner; ++iCorner)
866  {
867  xyz[ixyz][0] = corners[iCorner].r * std::cos(phi);
868  xyz[ixyz][1] = corners[iCorner].r * std::sin(phi);
869  xyz[ixyz][2] = corners[iCorner].z;
870  ++ixyz;
871  }
872  }
873  else // !phiIsOpen - i.e., a complete 360 degrees.
874  {
875  nNodes = numSide * numCorner;
876  nFaces = numSide * numCorner;;
877  xyz = new double3[nNodes];
878  faces_vec = new int4[nFaces];
879  const G4double dPhi = (endPhi - startPhi) / numSide;
880  G4double phi = startPhi;
881  G4int ixyz = 0, iface = 0;
882  for (G4int iSide = 0; iSide < numSide; ++iSide)
883  {
884  for (G4int iCorner = 0; iCorner < numCorner; ++iCorner)
885  {
886  xyz[ixyz][0] = corners[iCorner].r * std::cos(phi);
887  xyz[ixyz][1] = corners[iCorner].r * std::sin(phi);
888  xyz[ixyz][2] = corners[iCorner].z;
889 
890  if (iSide < numSide - 1)
891  {
892  if (iCorner < numCorner - 1)
893  {
894  faces_vec[iface][0] = ixyz + 1;
895  faces_vec[iface][1] = -(ixyz + numCorner + 1);
896  faces_vec[iface][2] = ixyz + numCorner + 2;
897  faces_vec[iface][3] = -(ixyz + 2);
898  }
899  else
900  {
901  faces_vec[iface][0] = ixyz + 1;
902  faces_vec[iface][1] = -(ixyz + numCorner + 1);
903  faces_vec[iface][2] = ixyz + 2;
904  faces_vec[iface][3] = -(ixyz - numCorner + 2);
905  }
906  }
907  else // Last side joins ends...
908  {
909  if (iCorner < numCorner - 1)
910  {
911  faces_vec[iface][0] = ixyz + 1;
912  faces_vec[iface][1] = -(ixyz + numCorner - nFaces + 1);
913  faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
914  faces_vec[iface][3] = -(ixyz + 2);
915  }
916  else
917  {
918  faces_vec[iface][0] = ixyz + 1;
919  faces_vec[iface][1] = -(ixyz - nFaces + numCorner + 1);
920  faces_vec[iface][2] = ixyz - nFaces + 2;
921  faces_vec[iface][3] = -(ixyz - numCorner + 2);
922  }
923  }
924  ++ixyz;
925  ++iface;
926  }
927  phi += dPhi;
928  }
929  }
930  G4Polyhedron* polyhedron = new G4Polyhedron;
931  G4int prob = polyhedron->createPolyhedron(nNodes, nFaces, xyz, faces_vec);
932  delete [] faces_vec;
933  delete [] xyz;
934  if (prob)
935  {
936  std::ostringstream message;
937  message << "Problem creating G4Polyhedron for: " << GetName();
938  G4Exception("G4GenericPolycone::CreatePolyhedron()", "GeomSolids1002",
939  JustWarning, message);
940  delete polyhedron;
941  return 0;
942  }
943  else
944  {
945  return polyhedron;
946  }
947 }
948 
949 //#endif
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
void set(double x, double y, double z)
const XML_Char * name
Definition: expat.h:151
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
Definition: G4GeomTools.cc:199
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
G4double GetMaxExtent(const EAxis pAxis) const
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
static const G4double kInfinity
Definition: geomdefs.hh:42
G4bool IsOpen() const
G4double GetStartPhi() const
G4double GetEndPhi() const
#define G4endl
Definition: G4ios.hh:61
G4GenericPolycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numRZ, const G4double r[], const G4double z[])
const char * p
Definition: xmltok.h:285
G4PolyconeSideRZ * corners
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:42
Double_t z
G4double GetCosStartPhi() const
void message(RunManager *runmanager)
Definition: ts_scorers.cc:72
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
double z() const
static const G4double emax
G4double GetSinEndPhi() const
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4Polyhedron * CreatePolyhedron() const
static G4bool DiskExtent(G4double rmin, G4double rmax, G4double startPhi, G4double delPhi, G4TwoVector &pmin, G4TwoVector &pmax)
Definition: G4GeomTools.cc:396
G4double GetSinStartPhi() const
G4bool MustBeOutside(const G4ThreeVector &p) const
virtual EInside Inside(const G4ThreeVector &p) const
G4GeometryType GetEntityType() const
static const G4double ab
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
std::vector< G4ThreeVector > G4ThreeVectorList
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4GenericPolycone & operator=(const G4GenericPolycone &source)
G4double GetMinExtent(const EAxis pAxis) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
double x() const
static constexpr double deg
Definition: G4SIunits.hh:152
G4bool RemoveDuplicateVertices(G4double tolerance)
EInside Inside(const G4ThreeVector &p) const
G4double kCarTolerance
Definition: G4VSolid.hh:307
static constexpr double twopi
Definition: G4SIunits.hh:76
double A(double temperature)
Float_t d
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4double Amin() const
std::ostream & StreamInfo(std::ostream &os) const
G4bool CrossesItself(G4double tolerance)
G4PolyconeSideRZ GetCorner(G4int index) const
G4VCSGface ** faces
static G4int GetNumberOfRotationSteps()
void CopyStuff(const G4GenericPolycone &source)
G4ThreeVector GetPointOnSurface() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
int G4int
Definition: G4Types.hh:78
EInside
Definition: geomdefs.hh:58
G4int NumVertices() const
std::vector< G4TwoVector > G4TwoVectorList
Definition: G4GeomTools.hh:50
G4bool RemoveRedundantVertices(G4double tolerance)
EAxis
Definition: geomdefs.hh:54
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
G4String GetName() const
void DumpInfo() const
double C(double temp)
double y() const
G4ThreeVector GetPointOnSurfaceGeneric() const
G4EnclosingCylinder * enclosingCylinder
static constexpr double degree
Definition: G4SIunits.hh:144
double x() const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
double y() const
double B(double temperature)
G4VSolid * Clone() const
G4bool fRebuildPolyhedron
G4double GetCosEndPhi() const
G4int GetNumRZCorner() const
G4Polyhedron * fpPolyhedron
static G4double PolygonArea(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:82