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