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