Geant4  10.00.p01
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 inline 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  }
387 
388  return distance;
389 }
390 
391 
392 
393 
394 //
395 // DistanceTo
396 //
397 // Protected routine called by DistanceToIn and DistanceToOut
398 //
400  const bool outgoing) const
401 {
402  UVCSGface** face = faces;
403  double best = UUtils::kInfinity;
404  do
405  {
406  double distance = (*face)->Safety(p, outgoing);
407  if (distance < best) best = distance;
408  }
409  while (++face < faces + numFace);
410 
411  return (best < 0.5 * fgTolerance) ? 0 : best;
412 }
413 
414 //
415 // GetEntityType
416 //
418 {
419  return std::string("UCSGfaceted");
420 }
421 
422 
423 //
424 // Stream object contents to an output stream
425 //
426 std::ostream& UVCSGfaceted::StreamInfo(std::ostream& os) const
427 {
428  os << "-----------------------------------------------------------\n"
429  << " *** Dump for solid - " << GetName() << " ***\n"
430  << " ===================================================\n"
431  << " Solid type: UVCSGfaceted\n"
432  << " Parameters: \n"
433  << " number of faces: " << numFace << "\n"
434  << "-----------------------------------------------------------\n";
435 
436  return os;
437 }
438 
439 
440 //
441 // GetCubVolStatistics
442 //
444 {
445  return fStatistics;
446 }
447 
448 
449 //
450 // GetCubVolEpsilon
451 //
453 {
454  return fCubVolEpsilon;
455 }
456 
457 
458 //
459 // SetCubVolStatistics
460 //
462 {
463  fCubicVolume = 0.;
464  fStatistics = st;
465 }
466 
467 
468 //
469 // SetCubVolEpsilon
470 //
472 {
473  fCubicVolume = 0.;
474  fCubVolEpsilon = ep;
475 }
476 
477 
478 //
479 // GetAreaStatistics
480 //
482 {
483  return fStatistics;
484 }
485 
486 
487 //
488 // GetAreaAccuracy
489 //
491 {
492  return fAreaAccuracy;
493 }
494 
495 
496 //
497 // SetAreaStatistics
498 //
500 {
501  fSurfaceArea = 0.;
502  fStatistics = st;
503 }
504 
505 
506 //
507 // SetAreaAccuracy
508 //
510 {
511  fSurfaceArea = 0.;
512  fAreaAccuracy = ep;
513 }
514 
515 
516 //
517 // Capacity
518 //
520 {
521  if (fCubicVolume != 0.)
522  {
523  ;
524  }
525  else
526  {
528  }
529  return fCubicVolume;
530 }
531 
532 
533 //
534 // SurfaceArea
535 //
537 {
538  if (fSurfaceArea != 0.)
539  {
540  ;
541  }
542  else
543  {
545  }
546  return fSurfaceArea;
547 }
548 
549 //
550 // GetPointOnSurfaceGeneric proportional to Areas of faces
551 // in case of GenericPolycone or GenericPolyhedra
552 //
554 {
555  // Preparing variables
556  //
557  UVector3 answer = UVector3(0., 0., 0.);
558  UVCSGface** face = faces;
559  double area = 0;
560  int i;
561  std::vector<double> areas;
562 
563  // First step: calculate surface areas
564  //
565  do
566  {
567  double result = (*face)->SurfaceArea();
568  areas.push_back(result);
569  area = area + result;
570  }
571  while (++face < faces + numFace);
572 
573  // Second Step: choose randomly one surface
574  //
575  UVCSGface** face1 = faces;
576  double chose = area * UUtils::Random();
577  double Achose1, Achose2;
578  Achose1 = 0;
579  Achose2 = 0.;
580  i = 0;
581 
582  do
583  {
584  Achose2 += areas[i];
585  if (chose >= Achose1 && chose < Achose2)
586  {
587  UVector3 point;
588  point = (*face1)->GetPointOnFace();
589  return point;
590  }
591  i++;
592  Achose1 = Achose2;
593  }
594  while (++face1 < faces + numFace);
595 
596  return answer;
597 }
598 
599 double UVCSGfaceted::SafetyFromOutside(const UVector3& p, bool accurate) const
600 {
601  if (!accurate)
602  {
603  UVector3 pb(p.x, p.y, p.z - fBoxShift);
604  return fBox.SafetyFromOutside(pb);
605  }
606  return DistanceTo(p, false);
607 }
608 
610 {
611  return DistanceTo(p, true);
612 }
613 
614 
616 {
617  int size = rz.NumVertices() + 1;
618  vector<double> r(size), z(size), zs;
619  rz.CopyVertices(&r[0], &z[0]);
620 
621  fZs.clear();
622  for (int i = 0; i < size; ++i)
623  {
624  double v = z[i];
625  if (std::find(fZs.begin(), fZs.end(), v) == fZs.end())
626  {
627  fZs.push_back(v);
628  }
629  std::sort(fZs.begin(), fZs.end());
630  }
631 
632  size = fZs.size();
633  fMaxSection = size - 2;
634 
635  for (int i = 0; i <= fMaxSection; ++i)
636  {
637  vector<int> candidates;
638 
639  double left = fZs[i], right = fZs[i + 1];
640  double middle = (left + right) / 2;
641  FindCandidates(middle, candidates);
642 
643  FindCandidates(left, candidates, true);
644  FindCandidates(right, candidates, true);
645 
646  fCandidates.push_back(candidates);
647  }
648 
649  fBox.Set(radius, radius, (fZs.back() - fZs.front()) / 2);
650  fBoxShift = fZs[0] + fBox.GetZHalfLength();
651 }
652 
653 void UVCSGfaceted::FindCandidates(double z, vector <int>& candidates, bool sides)
654 {
655  for (int j = 0; j < numFace; j++)
656  {
657  UVCSGface* face = faces[j];
658  double minZ = -face->Extent(UVector3(0, 0, -1)) ;
659  double maxZ = face->Extent(UVector3(0, 0, 1));
660  if (z >= minZ - fgTolerance * 10 && z <= maxZ + fgTolerance * 10)
661  {
662  if (!sides || std::fabs(minZ - maxZ) < fgTolerance * 10)
663  if (std::find(candidates.begin(), candidates.end(), j) == candidates.end())
664  candidates.push_back(j);
665  }
666  }
667 }
668 
669 
670 double UVCSGfaceted::DistanceToIn(const UVector3& p, const UVector3& v, double /*aPstep*/) const
671 {
672  if (fNoVoxels) return DistanceToInNoVoxels(p, v);
673 
674  UVector3 pb(p.x, p.y, p.z - fBoxShift);
675 
676  double idistance, shift;
677  idistance = fBox.DistanceToIn(pb, v); // using only box, this appears
678  // to be faster than: idistance = enclosingCylinder->DistanceTo(pb, v);
679  if (idistance >= UUtils::kInfinity) return idistance;
680 
681  // this line can be here or not. not a big difference in performance
682  // TODO: fix enclosingCylinder for polyhedra!!! - the current radius appears to be too small
683  // if (enclosingCylinder->ShouldMiss(p, v)) return UUtils::kInfinity;
684 
685  // this just takes too much time
686  // idistance = enclosingCylinder->DistanceTo(pb, v);
687  // if (idistance == UUtils::kInfinity) return idistance;
688 
689  double z = p.z + idistance * v.z;
690  int index = GetSection(z);
691  int increment = (v.z > 0) ? 1 : -1;
692  if (std::fabs(v.z) < fgTolerance) increment = 0;
693 
694  double distance = UUtils::kInfinity;
695  double distFromSurface = UUtils::kInfinity;
696  UVCSGface* bestFace = 0;
697  UBits bits(numFace);
698  UVector3 faceNormal;
699 
700  do
701  {
702  const vector<int>& candidates = fCandidates[index];
703  int size = candidates.size();
704  for (int i = 0; i < size; ++i)
705  {
706  int candidate = candidates[i];
707  if (!bits[candidate])
708  {
709  bits.SetBitNumber(candidate);
710  UVCSGface& face = *faces[candidate];
711 
712  double faceDistance,
713  faceDistFromSurface;
714  bool faceAllBehind;
715  if (face.Distance(p, v, false, fgTolerance * 0.5,
716  faceDistance, faceDistFromSurface,
717  faceNormal, faceAllBehind))
718  {
719  // Intersecting face
720  if (faceDistance < distance)
721  {
722  distance = faceDistance;
723  distFromSurface = faceDistFromSurface;
724  bestFace = &face;
725  if (distFromSurface <= 0) return 0;
726  }
727  }
728  }
729  }
730 
731  if (!increment)
732  break;
733 
734  index += increment;
735  if (index < 0 || index > fMaxSection)
736  break;
737  int newz = increment > 0 ? index : index + 1;
738  shift = (fZs[newz] - z) / v.z;
739  }
740  while (idistance + shift < distance);
741 
742  if (distance < UUtils::kInfinity && distFromSurface < fgTolerance / 2)
743  {
744  if (bestFace->Safety(p, false) < fgTolerance / 2)
745  {
746  distance = 0;
747  }
748  }
749 
750  return distance;
751 }
752 
753 
754 
755 double UVCSGfaceted::DistanceToOut(const UVector3& p, const UVector3& v, UVector3& n, bool& aConvex, double /*aPstep*/) const
756 {
757  if (fNoVoxels) return DistanceToOutNoVoxels(p, v, n, aConvex);
758 
759  int index = GetSection(p.z);
760  int increment = (v.z > 0) ? 1 : -1;
761 
762  bool allBehind = true;
763  double distance = UUtils::kInfinity;
764  double distFromSurface = UUtils::kInfinity;
765  UVector3 normal, faceNormal;
766  double shift;
767 
768  UVCSGface* bestFace = 0;
769  UBits bits(numFace);
770 
771  do
772  {
773  const vector<int>& candidates = fCandidates[index];
774  int size = candidates.size();
775  for (int i = 0; i < size; ++i)
776  {
777  int candidate = candidates[i];
778  if (!bits[candidate])
779  {
780  bits.SetBitNumber(candidate);
781  UVCSGface& face = *faces[candidate];
782 
783  double faceDistance, faceDistFromSurface;
784  bool faceAllBehind;
785  if ((face.Distance(p, v, true, fgTolerance * 0.5, faceDistance, faceDistFromSurface,
786  faceNormal, faceAllBehind)))
787  {
788  // Intersecting face
789  if ((distance < UUtils::kInfinity) || (!faceAllBehind))
790  {
791  allBehind = false;
792  }
793  if (faceDistance < distance)
794  {
795  distance = faceDistance;
796  distFromSurface = faceDistFromSurface;
797  normal = faceNormal;
798  bestFace = &face;
799  if (distFromSurface <= 0) break;
800  }
801  }
802  }
803  }
804 
805  if (distFromSurface <= 0) break;
806  if (!increment) break;
807 
808  index += increment;
809  if (index < 0 || index > fMaxSection)
810  break;
811  int newz = increment > 0 ? index : index + 1;
812  shift = (fZs[newz] - p.z) / v.z;
813  }
814  while (shift < distance);
815 
816  if (distance < UUtils::kInfinity)
817  {
818  if (distFromSurface <= 0)
819  {
820  distance = 0;
821  }
822  else if (distFromSurface < fgTolerance / 2)
823  {
824  if (bestFace->Safety(p, true) < fgTolerance * 0.5)
825  {
826  distance = 0;
827  }
828  }
829 
830  aConvex = allBehind;
831  n = normal;
832  }
833  else
834  {
835  if (Inside(p) == eSurface)
836  {
837  distance = 0;
838  }
839  aConvex = false;
840  }
841 
842  return distance;
843 }
844 
845 
847 {
848  if (fNoVoxels) return InsideNoVoxels(p);
849 
850 // if (fEnclosingCylinder->MustBeOutside(p)) return eOutside;
851 
852  int index = GetSection(p.z);
853  double shift;
854 
855  UBits bits(numFace);
856  double best = UUtils::kInfinity;
857  VUSolid::EnumInside answer = eOutside;
858  int middle = index;
859 
860  do
861  {
862  const vector<int>& candidates = fCandidates[index];
863  int size = candidates.size();
864  for (int i = 0; i < size; ++i)
865  {
866  int candidate = candidates[i];
867  if (!bits[candidate])
868  {
869  UVCSGface& face = *faces[candidate];
870 
871  double distance;
872  VUSolid::EnumInside result = face.Inside(p, fgTolerance * 0.5, &distance);
873  if (result == eSurface) return eSurface;
874  if (distance < best)
875  {
876  best = distance;
877  answer = result;
878  }
879  bits.SetBitNumber(candidate);
880  }
881  }
882 
883  if (index <= middle)
884  {
885  if (--index >= 0)
886  {
887  shift = fZs[index + 1] - p.z;
888  if (shift < best) continue;
889  }
890  index = middle;
891  }
892  if (++index > fMaxSection) break;
893  shift = p.z - fZs[index];
894  }
895  while (shift > best);
896 
897  return answer;
898 }
899 
900 double UVCSGfaceted::SafetyFromInsideSection(int index, const UVector3& p, UBits& bits) const
901 {
902  double best = UUtils::kInfinity;
903 
904  const vector<int>& candidates = fCandidates[index];
905  int size = candidates.size();
906  for (int i = 0; i < size; ++i)
907  {
908  int candidate = candidates[i];
909  if (!bits[candidate])
910  {
911  bits.SetBitNumber(candidate);
912  UVCSGface& face = *faces[candidate];
913 
914  double distance = face.Safety(p, true);
915  if (distance < best) best = distance;
916  }
917  }
918  return best;
919 }
920 
921 double UVCSGfaceted::SafetyFromInside(const UVector3& p, bool) const
922 {
923  if (fNoVoxels) return SafetyFromInsideNoVoxels(p);
924 
925  int index = UVoxelizer::BinarySearch(fZs, p.z);
926  if (index < 0 || index > fMaxSection) return 0;
927 
928  UBits bits(numFace);
929  double minSafety = SafetyFromInsideSection(index, p, bits);
930 
931  if (minSafety > UUtils::kInfinity) return 0;
932  if (minSafety < 1e-6) return 0;
933 
934  double zbase = fZs[index + 1];
935  for (int i = index + 1; i <= fMaxSection; ++i)
936  {
937  double dz = fZs[i] - zbase;
938  if (dz >= minSafety) break;
939  double safety = SafetyFromInsideSection(i, p, bits);
940  if (safety < minSafety) minSafety = safety;
941  }
942 
943  if (index > 0)
944  {
945  zbase = fZs[index - 1];
946  for (int i = index - 1; i >= 0; --i)
947  {
948  double dz = zbase - fZs[i];
949  if (dz >= minSafety) break;
950  double safety = SafetyFromInsideSection(i, p, bits);
951  if (safety < minSafety) minSafety = safety;
952  }
953  }
954  return (minSafety < 0.5 * fgTolerance) ? 0 : minSafety;
955 }
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:58
static const double kInfinity
Definition: UUtils.hh:54
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:295
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