Geant4  10.00.p02
UVCSGfaceted.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UVCSGfaceted
12 //
13 // 19.09.13 Marek Gayer
14 // Created from original implementation in Geant4
15 // --------------------------------------------------------------------
16 
17 #include "UUtils.hh"
18 #include <string>
19 #include <cmath>
20 #include <sstream>
21 #include "UVCSGfaceted.hh"
22 #include "UVCSGface.hh"
23 #include "UVoxelizer.hh"
24 #include "UReduciblePolygon.hh"
25 
26 using namespace std;
27 
28 //
29 // Constructor
30 //
31 UVCSGfaceted::UVCSGfaceted(const std::string& name)
32  : VUSolid(name),
33  numFace(0), faces(0), fCubicVolume(0.), fSurfaceArea(0.),
34  fMaxSection(0),fBoxShift(0.), fNoVoxels(true),fStatistics(1000000), fCubVolEpsilon(0.001), fAreaAccuracy(-1.)
35 {
36 }
37 
38 //
39 // Destructor
40 //
42 {
43  DeleteStuff();
44 }
45 
46 //
47 // Copy constructor
48 //
50  : VUSolid(source)
51 {
52  fStatistics = source.fStatistics;
55 
56  CopyStuff(source);
57 }
58 
59 
60 //
61 // Assignment operator
62 //
64 {
65  if (&source == this)
66  {
67  return *this;
68  }
69 
70  // Copy base class data
71  //
72  VUSolid::operator=(source);
73 
74  // Copy data
75  //
76  fStatistics = source.fStatistics;
79 
80  CopyStuff(source);
81 
82  return *this;
83 }
84 
85 
86 //
87 // CopyStuff (protected)
88 //
89 // Copy the contents of source
90 //
92 {
93  numFace = source.numFace;
94  if (numFace == 0)
95  {
96  return; // odd, but permissable?
97  }
98 
99  faces = new UVCSGface*[numFace];
100 
101  UVCSGface** face = faces,
102  **sourceFace = source.faces;
103  do
104  {
105  *face = (*sourceFace)->Clone();
106  }
107  while (++sourceFace, ++face < faces + numFace);
108  fCubicVolume = source.fCubicVolume;
109  fSurfaceArea = source.fSurfaceArea;
110 
111  fMaxSection = source.fMaxSection;
112  fNoVoxels = source.fNoVoxels;
113  fZs = source.fZs;
114  fBox = source.fBox;
115  fBoxShift = source.fBoxShift;
116 }
117 
118 
119 //
120 // DeleteStuff (protected)
121 //
122 // Delete all allocated objects
123 //
125 {
126  if (numFace)
127  {
128  UVCSGface** face = faces;
129  do
130  {
131  delete *face;
132  }
133  while (++face < faces + numFace);
134 
135  delete [] faces;
136  }
137 }
138 
139 //
140 // Inside
141 //
142 // It could be a good idea to override this virtual
143 // member to add first a simple test (such as spherical
144 // test or whatnot) and to call this version only if
145 // the simplier test fails.
146 //
147 
148 /*
149 VUSolid::EnumInside UVCSGfaceted::Inside( const UVector3 &p ) const
150 {
151  VUSolid::EnumInside answer=eOutside;
152  UVCSGface **face = faces;
153  double best = UUtils::kInfinity;
154  do
155  {
156  double distance;
157  VUSolid::EnumInside result = (*face)->Inside( p, fgTolerance*0.5, &distance );
158  if (result == eSurface) { return eSurface; }
159  if (distance < best)
160  {
161  best = distance;
162  answer = result;
163  }
164  } while( ++face < faces + numFace );
165 
166  return answer;
167 }
168 */
169 
170 
171 //
172 // Inside
173 //
174 // It could be a good idea to override this virtual
175 // member to add first a simple test (such as spherical
176 // test or whatnot) and to call this version only if
177 // the simplier test fails.
178 //
180 {
181  VUSolid::EnumInside answer = eOutside;
182  UVCSGface** face = faces;
183  double best = UUtils::kInfinity;
184  do
185  {
186  double distance;
187  VUSolid::EnumInside result = (*face)->Inside(p, fgTolerance * 0.5, &distance);
188  if (result == eSurface)
189  {
190  return eSurface;
191  }
192  if (distance < best)
193  {
194  best = distance;
195  answer = result;
196  }
197  }
198  while (++face < faces + numFace);
199 
200  return answer;
201 }
202 
203 
204 
205 //
206 // SurfaceNormal
207 //
208 
209 bool UVCSGfaceted::Normal(const UVector3& p, UVector3& n) const
210 {
211  UVector3 answer;
212  double best = UUtils::kInfinity;
214 
215  UBits bits(numFace);
216 
217  int index = GetSection(p.z);
218  const vector<int>& candidates = fCandidates[index];
219  int size = candidates.size();
220  for (int i = 0; i < size; ++i)
221  {
222  int candidate = candidates[i];
223  if (!bits[candidate])
224  {
225  bits.SetBitNumber(candidate);
226  UVCSGface& face = *faces[candidate];
227  double distance;
228  normal = face.Normal(p, &distance);
229  if (distance < best)
230  {
231  best = distance;
232  answer = normal;
233  if (distance < fgTolerance)
234  break;
235  }
236  }
237  }
238  n = answer;
239  return true;
240 }
241 
242 /*
243 
244 // non voxelized version:
245 
246  bool UVCSGfaceted::Normal( const UVector3 &p, UVector3 &n) const
247  {
248  UVector3 answer;
249  double best = UUtils::kInfinity;
250  UVector3 normal;
251 
252  for (int i = 0; i < numFace; ++i)
253  {
254  UVCSGface &face = *faces[i];
255  double distance;
256  normal = face.Normal( p, &distance);
257  if (distance < best)
258  {
259  best = distance;
260  answer = normal;
261  }
262  }
263  n = answer;
264  return true;
265  }
266 */
267 
268 //
269 // DistanceToIn(p,v)
270 //
271 
273  const UVector3& v) const
274 {
275  double distance = UUtils::kInfinity;
276  double distFromSurface = UUtils::kInfinity;
277  UVCSGface** face = faces;
278  UVCSGface* bestFace = *face;
279  static double htol = fgTolerance * 0.5;
280  UVector3 faceNormal;
281 
282  do
283  {
284  double faceDistance, faceDistFromSurface;
285  bool faceAllBehind;
286  if ((*face)->Distance(p, v, false, htol,
287  faceDistance, faceDistFromSurface,
288  faceNormal, faceAllBehind))
289  {
290  //
291  // Intersecting face
292  //
293  if (faceDistance < distance)
294  {
295  distance = faceDistance;
296  distFromSurface = faceDistFromSurface;
297  bestFace = *face;
298  if (distFromSurface <= 0)
299  {
300  return 0;
301  }
302  }
303  }
304  }
305  while (++face < faces + numFace);
306 
307  if (distance < UUtils::kInfinity && distFromSurface < htol)
308  {
309  if (bestFace->Safety(p, false) < htol)
310  {
311  distance = 0;
312  }
313  }
314 
315  return distance;
316 }
317 
318 
319 
320 
321 //
322 // DistanceToOut(p,v)
323 //
324 
325 double UVCSGfaceted::DistanceToOutNoVoxels(const UVector3& p, const UVector3& v, UVector3& n, bool& aConvex) const
326 {
327  bool allBehind = true;
328  double distance = UUtils::kInfinity;
329  double distFromSurface = UUtils::kInfinity;
330  UVector3 normal, faceNormal;
331 
332  UVCSGface** face = faces;
333  UVCSGface* bestFace = *face;
334  do
335  {
336  double faceDistance, faceDistFromSurface;
337  bool faceAllBehind;
338  if ((*face)->Distance(p, v, true, fgTolerance / 2,
339  faceDistance, faceDistFromSurface,
340  faceNormal, faceAllBehind))
341  {
342  // Intersecting face
343  if ((distance < UUtils::kInfinity) || (!faceAllBehind))
344  {
345  allBehind = false;
346  }
347  if (faceDistance < distance)
348  {
349  distance = faceDistance;
350  distFromSurface = faceDistFromSurface;
351  normal = faceNormal;
352  bestFace = *face;
353  if (distFromSurface <= 0)
354  {
355  break;
356  }
357  }
358  }
359  }
360  while (++face < faces + numFace);
361 
362  if (distance < UUtils::kInfinity)
363  {
364  if (distFromSurface <= 0)
365  {
366  distance = 0;
367  }
368  else if (distFromSurface < fgTolerance / 2)
369  {
370  if (bestFace->Safety(p, true) < fgTolerance / 2)
371  {
372  distance = 0;
373  }
374  }
375 
376  aConvex = allBehind;
377  n = normal;
378  }
379  else
380  {
381  if (Inside(p) == eSurface)
382  {
383  distance = 0;
384  }
385  aConvex = false;
386  n = normal;
387  }
388 
389  return distance;
390 }
391 
392 
393 
394 
395 //
396 // DistanceTo
397 //
398 // Protected routine called by DistanceToIn and DistanceToOut
399 //
401  const bool outgoing) const
402 {
403  UVCSGface** face = faces;
404  double best = UUtils::kInfinity;
405  do
406  {
407  double distance = (*face)->Safety(p, outgoing);
408  if (distance < best) best = distance;
409  }
410  while (++face < faces + numFace);
411 
412  return (best < 0.5 * fgTolerance) ? 0 : best;
413 }
414 
415 //
416 // GetEntityType
417 //
419 {
420  return std::string("UCSGfaceted");
421 }
422 
423 
424 //
425 // Stream object contents to an output stream
426 //
427 std::ostream& UVCSGfaceted::StreamInfo(std::ostream& os) const
428 {
429  os << "-----------------------------------------------------------\n"
430  << " *** Dump for solid - " << GetName() << " ***\n"
431  << " ===================================================\n"
432  << " Solid type: UVCSGfaceted\n"
433  << " Parameters: \n"
434  << " number of faces: " << numFace << "\n"
435  << "-----------------------------------------------------------\n";
436 
437  return os;
438 }
439 
440 
441 //
442 // GetCubVolStatistics
443 //
445 {
446  return fStatistics;
447 }
448 
449 
450 //
451 // GetCubVolEpsilon
452 //
454 {
455  return fCubVolEpsilon;
456 }
457 
458 
459 //
460 // SetCubVolStatistics
461 //
463 {
464  fCubicVolume = 0.;
465  fStatistics = st;
466 }
467 
468 
469 //
470 // SetCubVolEpsilon
471 //
473 {
474  fCubicVolume = 0.;
475  fCubVolEpsilon = ep;
476 }
477 
478 
479 //
480 // GetAreaStatistics
481 //
483 {
484  return fStatistics;
485 }
486 
487 
488 //
489 // GetAreaAccuracy
490 //
492 {
493  return fAreaAccuracy;
494 }
495 
496 
497 //
498 // SetAreaStatistics
499 //
501 {
502  fSurfaceArea = 0.;
503  fStatistics = st;
504 }
505 
506 
507 //
508 // SetAreaAccuracy
509 //
511 {
512  fSurfaceArea = 0.;
513  fAreaAccuracy = ep;
514 }
515 
516 
517 //
518 // Capacity
519 //
521 {
522  if (fCubicVolume != 0.)
523  {
524  ;
525  }
526  else
527  {
529  }
530  return fCubicVolume;
531 }
532 
533 
534 //
535 // SurfaceArea
536 //
538 {
539  if (fSurfaceArea != 0.)
540  {
541  ;
542  }
543  else
544  {
546  }
547  return fSurfaceArea;
548 }
549 
550 //
551 // GetPointOnSurfaceGeneric proportional to Areas of faces
552 // in case of GenericPolycone or GenericPolyhedra
553 //
555 {
556  // Preparing variables
557  //
558  UVector3 answer = UVector3(0., 0., 0.);
559  UVCSGface** face = faces;
560  double area = 0;
561  int i;
562  std::vector<double> areas;
563 
564  // First step: calculate surface areas
565  //
566  do
567  {
568  double result = (*face)->SurfaceArea();
569  areas.push_back(result);
570  area = area + result;
571  }
572  while (++face < faces + numFace);
573 
574  // Second Step: choose randomly one surface
575  //
576  UVCSGface** face1 = faces;
577  double chose = area * UUtils::Random();
578  double Achose1, Achose2;
579  Achose1 = 0;
580  Achose2 = 0.;
581  i = 0;
582 
583  do
584  {
585  Achose2 += areas[i];
586  if (chose >= Achose1 && chose < Achose2)
587  {
588  UVector3 point;
589  point = (*face1)->GetPointOnFace();
590  return point;
591  }
592  i++;
593  Achose1 = Achose2;
594  }
595  while (++face1 < faces + numFace);
596 
597  return answer;
598 }
599 
600 double UVCSGfaceted::SafetyFromOutside(const UVector3& p, bool accurate) const
601 {
602  if (!accurate)
603  {
604  UVector3 pb(p.x, p.y, p.z - fBoxShift);
605  return fBox.SafetyFromOutside(pb);
606  }
607  return DistanceTo(p, false);
608 }
609 
611 {
612  return DistanceTo(p, true);
613 }
614 
615 
617 {
618  int size = rz.NumVertices() + 1;
619  vector<double> r(size), z(size), zs;
620  rz.CopyVertices(&r[0], &z[0]);
621 
622  fZs.clear();
623  for (int i = 0; i < size; ++i)
624  {
625  double v = z[i];
626  if (std::find(fZs.begin(), fZs.end(), v) == fZs.end())
627  {
628  fZs.push_back(v);
629  }
630  std::sort(fZs.begin(), fZs.end());
631  }
632 
633  size = fZs.size();
634  fMaxSection = size - 2;
635 
636  for (int i = 0; i <= fMaxSection; ++i)
637  {
638  vector<int> candidates;
639 
640  double left = fZs[i], right = fZs[i + 1];
641  double middle = (left + right) / 2;
642  FindCandidates(middle, candidates);
643 
644  FindCandidates(left, candidates, true);
645  FindCandidates(right, candidates, true);
646 
647  fCandidates.push_back(candidates);
648  }
649 
650  fBox.Set(radius, radius, (fZs.back() - fZs.front()) / 2);
651  fBoxShift = fZs[0] + fBox.GetZHalfLength();
652 }
653 
654 void UVCSGfaceted::FindCandidates(double z, vector <int>& candidates, bool sides)
655 {
656  for (int j = 0; j < numFace; j++)
657  {
658  UVCSGface* face = faces[j];
659  double minZ = -face->Extent(UVector3(0, 0, -1)) ;
660  double maxZ = face->Extent(UVector3(0, 0, 1));
661  if (z >= minZ - fgTolerance * 10 && z <= maxZ + fgTolerance * 10)
662  {
663  if (!sides || std::fabs(minZ - maxZ) < fgTolerance * 10)
664  if (std::find(candidates.begin(), candidates.end(), j) == candidates.end())
665  candidates.push_back(j);
666  }
667  }
668 }
669 
670 
671 double UVCSGfaceted::DistanceToIn(const UVector3& p, const UVector3& v, double /*aPstep*/) const
672 {
673  if (fNoVoxels) return DistanceToInNoVoxels(p, v);
674 
675  UVector3 pb(p.x, p.y, p.z - fBoxShift);
676 
677  double idistance, shift;
678  idistance = fBox.DistanceToIn(pb, v); // using only box, this appears
679  // to be faster than: idistance = enclosingCylinder->DistanceTo(pb, v);
680  if (idistance >= UUtils::kInfinity) return idistance;
681 
682  // this line can be here or not. not a big difference in performance
683  // TODO: fix enclosingCylinder for polyhedra!!! - the current radius appears to be too small
684  // if (enclosingCylinder->ShouldMiss(p, v)) return UUtils::kInfinity;
685 
686  // this just takes too much time
687  // idistance = enclosingCylinder->DistanceTo(pb, v);
688  // if (idistance == UUtils::kInfinity) return idistance;
689 
690  double z = p.z + idistance * v.z;
691  int index = GetSection(z);
692  int increment = (v.z > 0) ? 1 : -1;
693  if (std::fabs(v.z) < fgTolerance) increment = 0;
694 
695  double distance = UUtils::kInfinity;
696  double distFromSurface = UUtils::kInfinity;
697  UVCSGface* bestFace = 0;
698  UBits bits(numFace);
699  UVector3 faceNormal;
700 
701  do
702  {
703  const vector<int>& candidates = fCandidates[index];
704  int size = candidates.size();
705  for (int i = 0; i < size; ++i)
706  {
707  int candidate = candidates[i];
708  if (!bits[candidate])
709  {
710  bits.SetBitNumber(candidate);
711  UVCSGface& face = *faces[candidate];
712 
713  double faceDistance,
714  faceDistFromSurface;
715  bool faceAllBehind;
716  if (face.Distance(p, v, false, fgTolerance * 0.5,
717  faceDistance, faceDistFromSurface,
718  faceNormal, faceAllBehind))
719  {
720  // Intersecting face
721  if (faceDistance < distance)
722  {
723  distance = faceDistance;
724  distFromSurface = faceDistFromSurface;
725  bestFace = &face;
726  if (distFromSurface <= 0) return 0;
727  }
728  }
729  }
730  }
731 
732  if (!increment)
733  break;
734 
735  index += increment;
736  if (index < 0 || index > fMaxSection)
737  break;
738  int newz = increment > 0 ? index : index + 1;
739  shift = (fZs[newz] - z) / v.z;
740  }
741  while (idistance + shift < distance);
742 
743  if (distance < UUtils::kInfinity && distFromSurface < fgTolerance / 2)
744  {
745  if (bestFace->Safety(p, false) < fgTolerance / 2)
746  {
747  distance = 0;
748  }
749  }
750 
751  return distance;
752 }
753 
754 
755 
756 double UVCSGfaceted::DistanceToOut(const UVector3& p, const UVector3& v, UVector3& n, bool& aConvex, double /*aPstep*/) const
757 {
758  if (fNoVoxels) return DistanceToOutNoVoxels(p, v, n, aConvex);
759 
760  int index = GetSection(p.z);
761  int increment = (v.z > 0) ? 1 : -1;
762 
763  bool allBehind = true;
764  double distance = UUtils::kInfinity;
765  double distFromSurface = UUtils::kInfinity;
766  UVector3 normal, faceNormal;
767  double shift;
768 
769  UVCSGface* bestFace = 0;
770  UBits bits(numFace);
771 
772  do
773  {
774  const vector<int>& candidates = fCandidates[index];
775  int size = candidates.size();
776  for (int i = 0; i < size; ++i)
777  {
778  int candidate = candidates[i];
779  if (!bits[candidate])
780  {
781  bits.SetBitNumber(candidate);
782  UVCSGface& face = *faces[candidate];
783 
784  double faceDistance, faceDistFromSurface;
785  bool faceAllBehind;
786  if ((face.Distance(p, v, true, fgTolerance * 0.5, faceDistance, faceDistFromSurface,
787  faceNormal, faceAllBehind)))
788  {
789  // Intersecting face
790  if ((distance < UUtils::kInfinity) || (!faceAllBehind))
791  {
792  allBehind = false;
793  }
794  if (faceDistance < distance)
795  {
796  distance = faceDistance;
797  distFromSurface = faceDistFromSurface;
798  normal = faceNormal;
799  bestFace = &face;
800  if (distFromSurface <= 0) break;
801  }
802  }
803  }
804  }
805 
806  if (distFromSurface <= 0) break;
807  if (!increment) break;
808 
809  index += increment;
810  if (index < 0 || index > fMaxSection)
811  break;
812  int newz = increment > 0 ? index : index + 1;
813  shift = (fZs[newz] - p.z) / v.z;
814  }
815  while (shift < distance);
816 
817  if (distance < UUtils::kInfinity)
818  {
819  if (distFromSurface <= 0)
820  {
821  distance = 0;
822  }
823  else if (distFromSurface < fgTolerance / 2)
824  {
825  if (bestFace->Safety(p, true) < fgTolerance * 0.5)
826  {
827  distance = 0;
828  }
829  }
830 
831  aConvex = allBehind;
832  n = normal;
833  }
834  else
835  {
836  if (Inside(p) == eSurface)
837  {
838  distance = 0;
839  }
840  aConvex = false;
841  }
842 
843  return distance;
844 }
845 
846 
848 {
849  if (fNoVoxels) return InsideNoVoxels(p);
850 
851 // if (fEnclosingCylinder->MustBeOutside(p)) return eOutside;
852 
853  int index = GetSection(p.z);
854  double shift;
855 
856  UBits bits(numFace);
857  double best = UUtils::kInfinity;
858  VUSolid::EnumInside answer = eOutside;
859  int middle = index;
860 
861  do
862  {
863  const vector<int>& candidates = fCandidates[index];
864  int size = candidates.size();
865  for (int i = 0; i < size; ++i)
866  {
867  int candidate = candidates[i];
868  if (!bits[candidate])
869  {
870  UVCSGface& face = *faces[candidate];
871 
872  double distance;
873  VUSolid::EnumInside result = face.Inside(p, fgTolerance * 0.5, &distance);
874  if (result == eSurface) return eSurface;
875  if (distance < best)
876  {
877  best = distance;
878  answer = result;
879  }
880  bits.SetBitNumber(candidate);
881  }
882  }
883 
884  if (index <= middle)
885  {
886  if (--index >= 0)
887  {
888  shift = fZs[index + 1] - p.z;
889  if (shift < best) continue;
890  }
891  index = middle;
892  }
893  if (++index > fMaxSection) break;
894  shift = p.z - fZs[index];
895  }
896  while (shift > best);
897 
898  return answer;
899 }
900 
901 double UVCSGfaceted::SafetyFromInsideSection(int index, const UVector3& p, UBits& bits) const
902 {
903  double best = UUtils::kInfinity;
904 
905  const vector<int>& candidates = fCandidates[index];
906  int size = candidates.size();
907  for (int i = 0; i < size; ++i)
908  {
909  int candidate = candidates[i];
910  if (!bits[candidate])
911  {
912  bits.SetBitNumber(candidate);
913  UVCSGface& face = *faces[candidate];
914 
915  double distance = face.Safety(p, true);
916  if (distance < best) best = distance;
917  }
918  }
919  return best;
920 }
921 
922 double UVCSGfaceted::SafetyFromInside(const UVector3& p, bool) const
923 {
924  if (fNoVoxels) return SafetyFromInsideNoVoxels(p);
925 
926  int index = UVoxelizer::BinarySearch(fZs, p.z);
927  if (index < 0 || index > fMaxSection) return 0;
928 
929  UBits bits(numFace);
930  double minSafety = SafetyFromInsideSection(index, p, bits);
931 
932  if (minSafety > UUtils::kInfinity) return 0;
933  if (minSafety < 1e-6) return 0;
934 
935  double zbase = fZs[index + 1];
936  for (int i = index + 1; i <= fMaxSection; ++i)
937  {
938  double dz = fZs[i] - zbase;
939  if (dz >= minSafety) break;
940  double safety = SafetyFromInsideSection(i, p, bits);
941  if (safety < minSafety) minSafety = safety;
942  }
943 
944  if (index > 0)
945  {
946  zbase = fZs[index - 1];
947  for (int i = index - 1; i >= 0; --i)
948  {
949  double dz = zbase - fZs[i];
950  if (dz >= minSafety) break;
951  double safety = SafetyFromInsideSection(i, p, bits);
952  if (safety < minSafety) minSafety = safety;
953  }
954  }
955  return (minSafety < 0.5 * fgTolerance) ? 0 : minSafety;
956 }
void SetCubVolStatistics(int st)
virtual ~UVCSGfaceted()
Definition: UVCSGfaceted.cc:41
double DistanceTo(const UVector3 &p, const bool outgoing) const
virtual bool Distance(const UVector3 &p, const UVector3 &v, bool outgoing, double surfTolerance, double &distance, double &distFromSurface, UVector3 &normal, bool &allBehind)=0
double fBoxShift
G4double z
Definition: TRTMaterials.hh:39
const std::string & GetName() const
Definition: VUSolid.hh:103
static double fgTolerance
Definition: VUSolid.hh:30
virtual bool Normal(const UVector3 &p, UVector3 &n) const
G4String name
Definition: TRTMaterials.hh:40
void FindCandidates(double z, std::vector< int > &candidates, bool sides=false)
double EstimateCubicVolume(int nStat, double epsilon) const
Definition: VUSolid.cc:214
double fSurfaceArea
double DistanceToOutNoVoxels(const UVector3 &p, const UVector3 &v, UVector3 &n, bool &aConvex) const
void SetAreaStatistics(int st)
void DeleteStuff()
void CopyVertices(double a[], double b[]) const
double EstimateSurfaceArea(int nStat, double ell) const
Definition: VUSolid.cc:268
double x
Definition: UVector3.hh:136
virtual UVCSGface * Clone()=0
int GetCubVolStatistics() const
double fCubVolEpsilon
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
virtual double SafetyFromInsideNoVoxels(const UVector3 &aPoint, bool aAccurate=false) const
void SetCubVolEpsilon(double ep)
std::vector< double > fZs
virtual VUSolid::EnumInside Inside(const UVector3 &p, double tolerance, double *bestDistance)=0
static int BinarySearch(const std::vector< T > &vec, T value)
Definition: UVoxelizer.hh:57
static const double kInfinity
Definition: UUtils.hh:53
void InitVoxels(UReduciblePolygon &z, double radius)
void SetAreaAccuracy(double ep)
UVCSGfaceted & operator=(const UVCSGfaceted &source)
Definition: UVCSGfaceted.cc:63
double fCubicVolume
double fAreaAccuracy
int NumVertices() const
int GetSection(double z) const
virtual double Capacity()
EnumInside
Definition: VUSolid.hh:23
const G4int n
virtual double Safety(const UVector3 &p, bool outgoing)=0
void SetBitNumber(unsigned int bitnumber, bool value=true)
Definition: UBits.hh:172
double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const
Definition: UBox.cc:117
double GetZHalfLength() const
Definition: UBox.hh:121
virtual double SurfaceArea()
double SafetyFromInsideSection(int index, const UVector3 &p, UBits &bits) const
virtual double Extent(const UVector3 axis)=0
double DistanceToInNoVoxels(const UVector3 &p, const UVector3 &v) const
std::vector< std::vector< int > > fCandidates
void Set(double dx, double dy, double dz)
Definition: UBox.cc:43
virtual UVector3 Normal(const UVector3 &p, double *bestDistance)=0
std::string UGeometryType
Definition: UTypes.hh:70
double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
Definition: UBox.cc:292
UVCSGfaceted(const std::string &name)
Definition: UVCSGfaceted.cc:31
UVCSGface ** faces
double z
Definition: UVector3.hh:138
virtual double SurfaceArea()=0
void CopyStuff(const UVCSGfaceted &source)
Definition: UVCSGfaceted.cc:91
UVector3 GetPointOnSurfaceGeneric() const
virtual double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
virtual double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
double GetCubVolEpsilon() const
VUSolid::EnumInside InsideNoVoxels(const UVector3 &p) const
virtual double DistanceToOut(const UVector3 &p, const UVector3 &v, UVector3 &n, bool &aConvex, double aPstep=UUtils::kInfinity) const
double Random(double min=0.0, double max=1.0)
Definition: UUtils.cc:69
virtual VUSolid::EnumInside Inside(const UVector3 &p) const
int GetAreaStatistics() const
double y
Definition: UVector3.hh:137
virtual UGeometryType GetEntityType() const
Definition: UBits.hh:38
double GetAreaAccuracy() const
virtual double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
virtual std::ostream & StreamInfo(std::ostream &os) const