Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
99{
101}
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 G4ThreeVector(0,0,0);
161}
162
163//////////////////////////////////////////////////////////////////////////
164//
165// Dummy implementations ...
166
168{ return nullptr; }
169
171{ return nullptr; }
172
174{ return nullptr; }
175
177{ return nullptr; }
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 )
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.size() ) return;
556
557 G4VoxelLimits simpleLimit2;
558 simpleLimit2.AddLimit(kXAxis,-kInfinity,pVoxelLimit.GetMaxXExtent());
559 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
560
561 if ( !pPolygon.size() ) 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.size() ) return;
576
577 G4VoxelLimits simpleLimit2;
578 simpleLimit2.AddLimit(kYAxis,-kInfinity,pVoxelLimit.GetMaxYExtent());
579 ClipPolygonToSimpleLimits(outputPolygon,pPolygon,simpleLimit2);
580
581 if ( !pPolygon.size() ) 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.size() ) 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 G4int 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)
Definition: G4Exception.cc:59
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)
Output solid information to given ostream.
Definition: G4VSolid.cc:46
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)
void SetMapValid(G4bool val)
Definition: G4SolidStore.hh:76
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)
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