Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VSolid.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// G4VSolid implementation for solid base class
27//
28// 10.10.18 E.Tcherniaev, more robust EstimateSurfaceArea() based on distance
29// 30.06.95 P.Kent, Created.
30// --------------------------------------------------------------------
31
32#include "G4VSolid.hh"
33#include "G4SolidStore.hh"
34#include "globals.hh"
35#include "G4QuickRand.hh"
37
38#include "G4VoxelLimits.hh"
39#include "G4AffineTransform.hh"
40#include "G4VisExtent.hh"
41
42//////////////////////////////////////////////////////////////////////////
43//
44// Constructor
45// - Copies name
46// - Add ourselves to solid Store
47
49 : fshapeName(name)
50{
52
53 // Register to store
54 //
56}
57
58//////////////////////////////////////////////////////////////////////////
59//
60// Copy constructor
61//
62
64 : kCarTolerance(rhs.kCarTolerance), fshapeName(rhs.fshapeName)
65{
66 // Register to store
67 //
69}
70
71//////////////////////////////////////////////////////////////////////////
72//
73// Fake default constructor - sets only member data and allocates memory
74// for usage restricted to object persistency.
75//
77 : fshapeName("")
78{
79 // Register to store
80 //
82}
83
84//////////////////////////////////////////////////////////////////////////
85//
86// Destructor (virtual)
87// - Remove ourselves from solid Store
88
90{
92}
93
94//////////////////////////////////////////////////////////////////////////
95//
96// Assignment operator
97
99{
100 // Check assignment to self
101 //
102 if (this == &rhs) { return *this; }
103
104 // Copy data
105 //
107 fshapeName = rhs.fshapeName;
108
109 return *this;
110}
111
112//////////////////////////////////////////////////////////////////////////
113//
114// Streaming operator dumping solid contents
115
116std::ostream& operator<< ( std::ostream& os, const G4VSolid& e )
117{
118 return e.StreamInfo(os);
119}
120
121//////////////////////////////////////////////////////////////////////////
122//
123// Throw exception if ComputeDimensions called for illegal derived class
124
126 const G4int,
127 const G4VPhysicalVolume*)
128{
129 std::ostringstream message;
130 message << "Illegal call to G4VSolid::ComputeDimensions()" << G4endl
131 << "Method not overloaded by derived class !";
132 G4Exception("G4VSolid::ComputeDimensions()", "GeomMgt0003",
133 FatalException, message);
134}
135
136//////////////////////////////////////////////////////////////////////////
137//
138// Throw exception (warning) for solids not implementing the method
139
141{
142 std::ostringstream message;
143 message << "Not implemented for solid: "
144 << GetEntityType() << " !" << G4endl
145 << "Returning origin.";
146 G4Exception("G4VSolid::GetPointOnSurface()", "GeomMgt1001",
147 JustWarning, message);
148 return G4ThreeVector(0,0,0);
149}
150
151//////////////////////////////////////////////////////////////////////////
152//
153// Dummy implementations ...
154
156{ return nullptr; }
157
159{ return nullptr; }
160
162{ return nullptr; }
163
165{ return nullptr; }
166
167////////////////////////////////////////////////////////////////
168//
169// Returns an estimation of the solid volume in internal units.
170// The number of statistics and error accuracy is fixed.
171// This method may be overloaded by derived classes to compute the
172// exact geometrical quantity for solids where this is possible.
173// or anyway to cache the computed value.
174// This implementation does NOT cache the computed value.
175
177{
178 G4int cubVolStatistics = 1000000;
179 G4double cubVolEpsilon = 0.001;
180 return EstimateCubicVolume(cubVolStatistics, cubVolEpsilon);
181}
182
183////////////////////////////////////////////////////////////////
184//
185// Calculate cubic volume based on Inside() method.
186// Accuracy is limited by the second argument or the statistics
187// expressed by the first argument.
188// Implementation is courtesy of Vasiliki Despoina Mitsou,
189// University of Athens.
190
192{
193 G4int iInside=0;
194 G4double px,py,pz,minX,maxX,minY,maxY,minZ,maxZ,volume,halfepsilon;
196 EInside in;
197
198 // values needed for CalculateExtent signature
199
200 G4VoxelLimits limit; // Unlimited
201 G4AffineTransform origin;
202
203 // min max extents of pSolid along X,Y,Z
204
205 CalculateExtent(kXAxis,limit,origin,minX,maxX);
206 CalculateExtent(kYAxis,limit,origin,minY,maxY);
207 CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
208
209 // limits
210
211 if(nStat < 100) nStat = 100;
212 if(epsilon > 0.01) epsilon = 0.01;
213 halfepsilon = 0.5*epsilon;
214
215 for(auto i = 0; i < nStat; ++i )
216 {
217 px = minX-halfepsilon+(maxX-minX+epsilon)*G4QuickRand();
218 py = minY-halfepsilon+(maxY-minY+epsilon)*G4QuickRand();
219 pz = minZ-halfepsilon+(maxZ-minZ+epsilon)*G4QuickRand();
220 p = G4ThreeVector(px,py,pz);
221 in = Inside(p);
222 if(in != kOutside) ++iInside;
223 }
224 volume = (maxX-minX+epsilon)*(maxY-minY+epsilon)
225 * (maxZ-minZ+epsilon)*iInside/nStat;
226 return volume;
227}
228
229////////////////////////////////////////////////////////////////
230//
231// Returns an estimation of the solid surface area in internal units.
232// The number of statistics and error accuracy is fixed.
233// This method may be overloaded by derived classes to compute the
234// exact geometrical quantity for solids where this is possible.
235// or anyway to cache the computed value.
236// This implementation does NOT cache the computed value.
237
239{
240 G4int stat = 1000000;
241 G4double ell = -1.;
242 return EstimateSurfaceArea(stat,ell);
243}
244
245//////////////////////////////////////////////////////////////////////////
246//
247// Calculate surface area by estimating volume of a thin shell
248// surrounding the surface using Monte-Carlo method.
249// Input parameters:
250// nstat - statistics (number of random points)
251// eps - shell thinkness
252
254{
255 static const G4double s2 = 1./std::sqrt(2.);
256 static const G4double s3 = 1./std::sqrt(3.);
257 static const G4ThreeVector directions[64] =
258 {
259 G4ThreeVector( 0, 0, 0), G4ThreeVector( -1, 0, 0), // ( , , ) ( -, , )
260 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +, , ) (-+, , )
261 G4ThreeVector( 0, -1, 0), G4ThreeVector(-s2,-s2, 0), // ( , -, ) ( -, -, )
262 G4ThreeVector( s2, -s2, 0), G4ThreeVector( 0, -1, 0), // ( +, -, ) (-+, -, )
263
264 G4ThreeVector( 0, 1, 0), G4ThreeVector( -s2, s2, 0), // ( , +, ) ( -, +, )
265 G4ThreeVector( s2, s2, 0), G4ThreeVector( 0, 1, 0), // ( +, +, ) (-+, +, )
266 G4ThreeVector( 0, -1, 0), G4ThreeVector( -1, 0, 0), // ( ,-+, ) ( -,-+, )
267 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +,-+, ) (-+,-+, )
268
269 G4ThreeVector( 0, 0, -1), G4ThreeVector(-s2, 0,-s2), // ( , , -) ( -, , -)
270 G4ThreeVector( s2, 0,-s2), G4ThreeVector( 0, 0, -1), // ( +, , -) (-+, , -)
271 G4ThreeVector( 0,-s2,-s2), G4ThreeVector(-s3,-s3,-s3), // ( , -, -) ( -, -, -)
272 G4ThreeVector( s3,-s3,-s3), G4ThreeVector( 0,-s2,-s2), // ( +, -, -) (-+, -, -)
273
274 G4ThreeVector( 0, s2,-s2), G4ThreeVector(-s3, s3,-s3), // ( , +, -) ( -, +, -)
275 G4ThreeVector( s3, s3,-s3), G4ThreeVector( 0, s2,-s2), // ( +, +, -) (-+, +, -)
276 G4ThreeVector( 0, 0, -1), G4ThreeVector(-s2, 0,-s2), // ( ,-+, -) ( -,-+, -)
277 G4ThreeVector( s2, 0,-s2), G4ThreeVector( 0, 0, -1), // ( +,-+, -) (-+,-+, -)
278
279 G4ThreeVector( 0, 0, 1), G4ThreeVector(-s2, 0, s2), // ( , , +) ( -, , +)
280 G4ThreeVector( s2, 0, s2), G4ThreeVector( 0, 0, 1), // ( +, , +) (-+, , +)
281 G4ThreeVector( 0,-s2, s2), G4ThreeVector(-s3,-s3, s3), // ( , -, +) ( -, -, +)
282 G4ThreeVector( s3,-s3, s3), G4ThreeVector( 0,-s2, s2), // ( +, -, +) (-+, -, +)
283
284 G4ThreeVector( 0, s2, s2), G4ThreeVector(-s3, s3, s3), // ( , +, +) ( -, +, +)
285 G4ThreeVector( s3, s3, s3), G4ThreeVector( 0, s2, s2), // ( +, +, +) (-+, +, +)
286 G4ThreeVector( 0, 0, 1), G4ThreeVector(-s2, 0, s2), // ( ,-+, +) ( -,-+, +)
287 G4ThreeVector( s2, 0, s2), G4ThreeVector( 0, 0, 1), // ( +,-+, +) (-+,-+, +)
288
289 G4ThreeVector( 0, 0, -1), G4ThreeVector( -1, 0, 0), // ( , ,-+) ( -, ,-+)
290 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +, ,-+) (-+, ,-+)
291 G4ThreeVector( 0, -1, 0), G4ThreeVector(-s2,-s2, 0), // ( , -,-+) ( -, -,-+)
292 G4ThreeVector( s2, -s2, 0), G4ThreeVector( 0, -1, 0), // ( +, -,-+) (-+, -,-+)
293
294 G4ThreeVector( 0, 1, 0), G4ThreeVector( -s2, s2, 0), // ( , +,-+) ( -, +,-+)
295 G4ThreeVector( s2, s2, 0), G4ThreeVector( 0, 1, 0), // ( +, +,-+) (-+, +,-+)
296 G4ThreeVector( 0, -1, 0), G4ThreeVector( -1, 0, 0), // ( ,-+,-+) ( -,-+,-+)
297 G4ThreeVector( 1, 0, 0), G4ThreeVector( -1, 0, 0), // ( +,-+,-+) (-+,-+,-+)
298 };
299
300 G4ThreeVector bmin, bmax;
301 BoundingLimits(bmin, bmax);
302
303 G4double dX = bmax.x() - bmin.x();
304 G4double dY = bmax.y() - bmin.y();
305 G4double dZ = bmax.z() - bmin.z();
306
307 // Define statistics and shell thickness
308 //
309 G4int npoints = (nstat < 1000) ? 1000 : nstat;
310 G4double coeff = 0.5 / std::cbrt(G4double(npoints));
311 G4double eps = (ell > 0) ? ell : coeff * std::min(std::min(dX, dY), dZ);
312 G4double del = 1.8 * eps; // shold be more than sqrt(3.)
313
314 G4double minX = bmin.x() - eps;
315 G4double minY = bmin.y() - eps;
316 G4double minZ = bmin.z() - eps;
317
318 G4double dd = 2. * eps;
319 dX += dd;
320 dY += dd;
321 dZ += dd;
322
323 // Calculate surface area
324 //
325 G4int icount = 0;
326 for(auto i = 0; i < npoints; ++i)
327 {
328 G4double px = minX + dX*G4QuickRand();
329 G4double py = minY + dY*G4QuickRand();
330 G4double pz = minZ + dZ*G4QuickRand();
331 G4ThreeVector p = G4ThreeVector(px, py, pz);
332 EInside in = Inside(p);
333 G4double dist = 0;
334 if (in == kInside)
335 {
336 if (DistanceToOut(p) >= eps) continue;
337 G4int icase = 0;
338 if (Inside(G4ThreeVector(px-del, py, pz)) != kInside) icase += 1;
339 if (Inside(G4ThreeVector(px+del, py, pz)) != kInside) icase += 2;
340 if (Inside(G4ThreeVector(px, py-del, pz)) != kInside) icase += 4;
341 if (Inside(G4ThreeVector(px, py+del, pz)) != kInside) icase += 8;
342 if (Inside(G4ThreeVector(px, py, pz-del)) != kInside) icase += 16;
343 if (Inside(G4ThreeVector(px, py, pz+del)) != kInside) icase += 32;
344 if (icase == 0) continue;
345 G4ThreeVector v = directions[icase];
346 dist = DistanceToOut(p, v);
347 G4ThreeVector n = SurfaceNormal(p + v*dist);
348 dist *= v.dot(n);
349 }
350 else if (in == kOutside)
351 {
352 if (DistanceToIn(p) >= eps) continue;
353 G4int icase = 0;
354 if (Inside(G4ThreeVector(px-del, py, pz)) != kOutside) icase += 1;
355 if (Inside(G4ThreeVector(px+del, py, pz)) != kOutside) icase += 2;
356 if (Inside(G4ThreeVector(px, py-del, pz)) != kOutside) icase += 4;
357 if (Inside(G4ThreeVector(px, py+del, pz)) != kOutside) icase += 8;
358 if (Inside(G4ThreeVector(px, py, pz-del)) != kOutside) icase += 16;
359 if (Inside(G4ThreeVector(px, py, pz+del)) != kOutside) icase += 32;
360 if (icase == 0) continue;
361 G4ThreeVector v = directions[icase];
362 dist = DistanceToIn(p, v);
363 if (dist == kInfinity) continue;
364 G4ThreeVector n = SurfaceNormal(p + v*dist);
365 dist *= -(v.dot(n));
366 }
367 if (dist < eps) ++icount;
368 }
369 return dX*dY*dZ*icount/npoints/dd;
370}
371
372///////////////////////////////////////////////////////////////////////////
373//
374// Returns a pointer of a dynamically allocated copy of the solid.
375// Returns NULL pointer with warning in case the concrete solid does not
376// implement this method. The caller has responsibility for ownership.
377//
378
380{
381 std::ostringstream message;
382 message << "Clone() method not implemented for type: "
383 << GetEntityType() << "!" << G4endl
384 << "Returning NULL pointer!";
385 G4Exception("G4VSolid::Clone()", "GeomMgt1001", JustWarning, message);
386 return nullptr;
387}
388
389///////////////////////////////////////////////////////////////////////////
390//
391// Calculate the maximum and minimum extents of the polygon described
392// by the vertices: pSectionIndex->pSectionIndex+1->
393// pSectionIndex+2->pSectionIndex+3->pSectionIndex
394// in the List pVertices
395//
396// If the minimum is <pMin pMin is set to the new minimum
397// If the maximum is >pMax pMax is set to the new maximum
398//
399// No modifications are made to pVertices
400//
401
403 const G4int pSectionIndex,
404 const G4VoxelLimits& pVoxelLimit,
405 const EAxis pAxis,
406 G4double& pMin, G4double& pMax) const
407{
408
409 G4ThreeVectorList polygon;
410 polygon.reserve(4);
411 polygon.push_back((*pVertices)[pSectionIndex]);
412 polygon.push_back((*pVertices)[pSectionIndex+1]);
413 polygon.push_back((*pVertices)[pSectionIndex+2]);
414 polygon.push_back((*pVertices)[pSectionIndex+3]);
415 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
416 return;
417}
418
419//////////////////////////////////////////////////////////////////////////////////
420//
421// Calculate the maximum and minimum extents of the polygons
422// joining the CrossSections at pSectionIndex->pSectionIndex+3 and
423// pSectionIndex+4->pSectionIndex7
424//
425// in the List pVertices, within the boundaries of the voxel limits pVoxelLimit
426//
427// If the minimum is <pMin pMin is set to the new minimum
428// If the maximum is >pMax pMax is set to the new maximum
429//
430// No modifications are made to pVertices
431
433 const G4int pSectionIndex,
434 const G4VoxelLimits& pVoxelLimit,
435 const EAxis pAxis,
436 G4double& pMin, G4double& pMax) const
437{
438 G4ThreeVectorList polygon;
439 polygon.reserve(4);
440 polygon.push_back((*pVertices)[pSectionIndex]);
441 polygon.push_back((*pVertices)[pSectionIndex+4]);
442 polygon.push_back((*pVertices)[pSectionIndex+5]);
443 polygon.push_back((*pVertices)[pSectionIndex+1]);
444 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
445 polygon.clear();
446
447 polygon.push_back((*pVertices)[pSectionIndex+1]);
448 polygon.push_back((*pVertices)[pSectionIndex+5]);
449 polygon.push_back((*pVertices)[pSectionIndex+6]);
450 polygon.push_back((*pVertices)[pSectionIndex+2]);
451 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
452 polygon.clear();
453
454 polygon.push_back((*pVertices)[pSectionIndex+2]);
455 polygon.push_back((*pVertices)[pSectionIndex+6]);
456 polygon.push_back((*pVertices)[pSectionIndex+7]);
457 polygon.push_back((*pVertices)[pSectionIndex+3]);
458 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
459 polygon.clear();
460
461 polygon.push_back((*pVertices)[pSectionIndex+3]);
462 polygon.push_back((*pVertices)[pSectionIndex+7]);
463 polygon.push_back((*pVertices)[pSectionIndex+4]);
464 polygon.push_back((*pVertices)[pSectionIndex]);
465 CalculateClippedPolygonExtent(polygon,pVoxelLimit,pAxis,pMin,pMax);
466 return;
467}
468
469
470///////////////////////////////////////////////////////////////////////////////
471//
472// Calculate the maximum and minimum extents of the convex polygon pPolygon
473// along the axis pAxis, within the limits pVoxelLimit
474//
475
476void
478 const G4VoxelLimits& pVoxelLimit,
479 const EAxis pAxis,
480 G4double& pMin,
481 G4double& pMax) const
482{
483 G4int noLeft,i;
484 G4double component;
485
486 ClipPolygon(pPolygon,pVoxelLimit,pAxis);
487 noLeft = pPolygon.size();
488
489 if ( noLeft )
490 {
491 for (i=0; i<noLeft; ++i)
492 {
493 component = pPolygon[i].operator()(pAxis);
494
495 if (component < pMin)
496 {
497 pMin = component;
498 }
499 if (component > pMax)
500 {
501 pMax = component;
502 }
503 }
504 }
505}
506
507/////////////////////////////////////////////////////////////////////////////
508//
509// Clip the convex polygon described by the vertices at
510// pSectionIndex ->pSectionIndex+3 within pVertices to the limits pVoxelLimit
511//
512// Set pMin to the smallest
513//
514// Calculate the extent of the polygon along pAxis, when clipped to the
515// limits pVoxelLimit. If the polygon exists after clippin, set pMin to
516// the polygon's minimum extent along the axis if <pMin, and set pMax to
517// the polygon's maximum extent along the axis if >pMax.
518//
519// The polygon is described by a set of vectors, where each vector represents
520// a vertex, so that the polygon is described by the vertex sequence:
521// 0th->1st 1st->2nd 2nd->... nth->0th
522//
523// Modifications to the polygon are made
524//
525// NOTE: Execessive copying during clipping
526
528 const G4VoxelLimits& pVoxelLimit,
529 const EAxis ) const
530{
531 G4ThreeVectorList outputPolygon;
532
533 if ( pVoxelLimit.IsLimited() )
534 {
535 if (pVoxelLimit.IsXLimited() ) // && pAxis != kXAxis)
536 {
537 G4VoxelLimits simpleLimit1;
538 simpleLimit1.AddLimit(kXAxis,pVoxelLimit.GetMinXExtent(),kInfinity);
539 ClipPolygonToSimpleLimits(pPolygon,outputPolygon,simpleLimit1);
540
541 pPolygon.clear();
542
543 if ( !outputPolygon.size() ) return;
544
545 G4VoxelLimits simpleLimit2;
546 simpleLimit2.AddLimit(kXAxis,-kInfinity,pVoxelLimit.GetMaxXExtent());
547 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
548
549 if ( !pPolygon.size() ) return;
550 else outputPolygon.clear();
551 }
552 if ( pVoxelLimit.IsYLimited() ) // && pAxis != kYAxis)
553 {
554 G4VoxelLimits simpleLimit1;
555 simpleLimit1.AddLimit(kYAxis,pVoxelLimit.GetMinYExtent(),kInfinity);
556 ClipPolygonToSimpleLimits(pPolygon,outputPolygon,simpleLimit1);
557
558 // Must always clear pPolygon - for clip to simpleLimit2 and in case of
559 // early exit
560
561 pPolygon.clear();
562
563 if ( !outputPolygon.size() ) return;
564
565 G4VoxelLimits simpleLimit2;
566 simpleLimit2.AddLimit(kYAxis,-kInfinity,pVoxelLimit.GetMaxYExtent());
567 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
568
569 if ( !pPolygon.size() ) return;
570 else outputPolygon.clear();
571 }
572 if ( pVoxelLimit.IsZLimited() ) // && pAxis != kZAxis)
573 {
574 G4VoxelLimits simpleLimit1;
575 simpleLimit1.AddLimit(kZAxis,pVoxelLimit.GetMinZExtent(),kInfinity);
576 ClipPolygonToSimpleLimits(pPolygon,outputPolygon,simpleLimit1);
577
578 // Must always clear pPolygon - for clip to simpleLimit2 and in case of
579 // early exit
580
581 pPolygon.clear();
582
583 if ( !outputPolygon.size() ) return;
584
585 G4VoxelLimits simpleLimit2;
586 simpleLimit2.AddLimit(kZAxis,-kInfinity,pVoxelLimit.GetMaxZExtent());
587 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
588
589 // Return after final clip - no cleanup
590 }
591 }
592}
593
594////////////////////////////////////////////////////////////////////////////
595//
596// pVoxelLimits must be only limited along one axis, and either the maximum
597// along the axis must be +kInfinity, or the minimum -kInfinity
598
599void
600G4VSolid::ClipPolygonToSimpleLimits( G4ThreeVectorList& pPolygon,
601 G4ThreeVectorList& outputPolygon,
602 const G4VoxelLimits& pVoxelLimit ) const
603{
604 G4int i;
605 G4int noVertices=pPolygon.size();
606 G4ThreeVector vEnd,vStart;
607
608 for (i = 0 ; i < noVertices ; ++i )
609 {
610 vStart = pPolygon[i];
611 if ( i == noVertices-1 ) vEnd = pPolygon[0];
612 else vEnd = pPolygon[i+1];
613
614 if ( pVoxelLimit.Inside(vStart) )
615 {
616 if (pVoxelLimit.Inside(vEnd))
617 {
618 // vStart and vEnd inside -> output end point
619 //
620 outputPolygon.push_back(vEnd);
621 }
622 else
623 {
624 // vStart inside, vEnd outside -> output crossing point
625 //
626 pVoxelLimit.ClipToLimits(vStart,vEnd);
627 outputPolygon.push_back(vEnd);
628 }
629 }
630 else
631 {
632 if (pVoxelLimit.Inside(vEnd))
633 {
634 // vStart outside, vEnd inside -> output inside section
635 //
636 pVoxelLimit.ClipToLimits(vStart,vEnd);
637 outputPolygon.push_back(vStart);
638 outputPolygon.push_back(vEnd);
639 }
640 else // Both point outside -> no output
641 {
642 // outputPolygon.push_back(vStart);
643 // outputPolygon.push_back(vEnd);
644 }
645 }
646 }
647}
648
649//////////////////////////////////////////////////////////////////////////
650//
651// Throw exception (warning) for solids not implementing the method
652
654{
655 std::ostringstream message;
656 message << "Not implemented for solid: "
657 << GetEntityType() << " !"
658 << "\nReturning infinite boundinx box.";
659 G4Exception("G4VSolid::BoundingLimits()", "GeomMgt1001",
660 JustWarning, message);
661
662 pMin.set(-kInfinity,-kInfinity,-kInfinity);
663 pMax.set( kInfinity, kInfinity, kInfinity);
664}
665
666//////////////////////////////////////////////////////////////////////////
667//
668// Get G4VisExtent - bounding box for graphics
669
671{
672 G4VisExtent extent;
673 G4VoxelLimits voxelLimits; // Defaults to "infinite" limits.
674 G4AffineTransform affineTransform;
675 G4double vmin, vmax;
676 CalculateExtent(kXAxis,voxelLimits,affineTransform,vmin,vmax);
677 extent.SetXmin (vmin);
678 extent.SetXmax (vmax);
679 CalculateExtent(kYAxis,voxelLimits,affineTransform,vmin,vmax);
680 extent.SetYmin (vmin);
681 extent.SetYmax (vmax);
682 CalculateExtent(kZAxis,voxelLimits,affineTransform,vmin,vmax);
683 extent.SetZmin (vmin);
684 extent.SetZmax (vmax);
685 return extent;
686}
687
689{
690 return nullptr;
691}
692
694{
695 return nullptr;
696}
const G4double kCarTolerance
std::vector< G4ThreeVector > G4ThreeVectorList
double epsilon(double density, double temperature)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4double G4QuickRand()
Definition: G4QuickRand.hh:34
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
std::ostream & operator<<(std::ostream &os, const G4VSolid &e)
Definition: G4VSolid.cc:116
std::vector< G4ThreeVector > G4ThreeVectorList
Definition: G4VSolid.hh:79
#define G4endl
Definition: G4ios.hh:57
double z() const
double x() const
double y() const
double dot(const Hep3Vector &) const
void set(double x, double y, double z)
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
static void Register(G4VSolid *pSolid)
static void DeRegister(G4VSolid *pSolid)
static G4SolidStore * GetInstance()
G4double EstimateSurfaceArea(G4int nStat, G4double ell) const
Definition: G4VSolid.cc:253
virtual G4VSolid * Clone() const
Definition: G4VSolid.cc:379
virtual const G4VSolid * GetConstituentSolid(G4int no) const
Definition: G4VSolid.cc:155
virtual ~G4VSolid()
Definition: G4VSolid.cc:89
virtual std::ostream & StreamInfo(std::ostream &os) const =0
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:432
G4double EstimateCubicVolume(G4int nStat, G4double epsilon) const
Definition: G4VSolid.cc:191
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
virtual G4VisExtent GetExtent() const
Definition: G4VSolid.cc:670
G4VSolid(const G4String &name)
Definition: G4VSolid.cc:48
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:125
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
G4double kCarTolerance
Definition: G4VSolid.hh:302
virtual G4ThreeVector GetPointOnSurface() const
Definition: G4VSolid.cc:140
void ClipPolygon(G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const
Definition: G4VSolid.cc:527
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4Polyhedron * GetPolyhedron() const
Definition: G4VSolid.cc:693
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition: G4VSolid.cc:653
virtual G4Polyhedron * CreatePolyhedron() const
Definition: G4VSolid.cc:688
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:98
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
virtual const G4DisplacedSolid * GetDisplacedSolidPtr() const
Definition: G4VSolid.cc:161
virtual G4double GetCubicVolume()
Definition: G4VSolid.cc:176
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:402
virtual G4double GetSurfaceArea()
Definition: G4VSolid.cc:238
void CalculateClippedPolygonExtent(G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:477
virtual G4GeometryType GetEntityType() const =0
void SetYmin(G4double ymin)
Definition: G4VisExtent.hh:114
void SetYmax(G4double ymax)
Definition: G4VisExtent.hh:116
void SetXmax(G4double xmax)
Definition: G4VisExtent.hh:112
void SetXmin(G4double xmin)
Definition: G4VisExtent.hh:110
void SetZmax(G4double zmax)
Definition: G4VisExtent.hh:120
void SetZmin(G4double zmin)
Definition: G4VisExtent.hh:118
G4bool IsYLimited() const
G4bool ClipToLimits(G4ThreeVector &pStart, G4ThreeVector &pEnd) const
G4double GetMinZExtent() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4bool IsXLimited() const
G4double GetMaxYExtent() const
G4bool Inside(const G4ThreeVector &pVec) const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4bool IsLimited() const
G4double GetMaxXExtent() const
EAxis
Definition: geomdefs.hh:54
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57
EInside
Definition: geomdefs.hh:67
@ kInside
Definition: geomdefs.hh:70
@ kOutside
Definition: geomdefs.hh:68