Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PhysicalVolumeModel.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//
27//
28//
29// John Allison 31st December 1997.
30// Model for physical volumes.
31
33
34#include "G4VGraphicsScene.hh"
35#include "G4VPhysicalVolume.hh"
38#include "G4LogicalVolume.hh"
39#include "G4VSolid.hh"
40#include "G4SubtractionSolid.hh"
42#include "G4Material.hh"
43#include "G4VisAttributes.hh"
46#include "G4Polyhedron.hh"
48#include "G4AttDefStore.hh"
49#include "G4AttDef.hh"
50#include "G4AttValue.hh"
51#include "G4UnitsTable.hh"
52#include "G4Vector3D.hh"
53#include "G4Mesh.hh"
54
55#include <sstream>
56#include <iomanip>
57
58#define G4warn G4cout
59
62 , G4int requestedDepth
63 , const G4Transform3D& modelTransform
64 , const G4ModelingParameters* pMP
65 , G4bool useFullExtent
66 , const std::vector<G4PhysicalVolumeNodeID>& baseFullPVPath)
67: G4VModel (pMP)
68, fpTopPV (pVPV)
69, fTopPVCopyNo (pVPV? pVPV->GetCopyNo(): 0)
70, fRequestedDepth (requestedDepth)
71, fUseFullExtent (useFullExtent)
72, fTransform (modelTransform)
73, fCurrentDepth (0)
74, fpCurrentPV (fpTopPV)
75, fCurrentPVCopyNo (fpTopPV? fpTopPV->GetCopyNo(): 0)
76, fpCurrentLV (fpTopPV? fpTopPV->GetLogicalVolume(): 0)
77, fpCurrentMaterial (fpCurrentLV? fpCurrentLV->GetMaterial(): 0)
78, fCurrentTransform (modelTransform)
79, fBaseFullPVPath (baseFullPVPath)
80, fFullPVPath (fBaseFullPVPath)
81, fAbort (false)
82, fCurtailDescent (false)
83, fpClippingSolid (0)
84, fClippingMode (subtraction)
85, fNClippers (0)
86{
87 fType = "G4PhysicalVolumeModel";
88
89 if (!fpTopPV) {
90
91 // In some circumstances creating an "empty" G4PhysicalVolumeModel is
92 // allowed, so I have supressed the G4Exception below. If it proves to
93 // be a problem we might have to re-instate it, but it is unlikley to
94 // be used except by visualisation experts. See, for example, /vis/list,
95 // where it is used simply to get a list of G4AttDefs.
96 // G4Exception
97 // ("G4PhysicalVolumeModel::G4PhysicalVolumeModel",
98 // "modeling0010", FatalException, "Null G4PhysicalVolumeModel pointer.");
99
100 fTopPVName = "NULL";
101 fGlobalTag = "Empty";
102 fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
103
104 } else {
105
106 fTopPVName = fpTopPV -> GetName ();
107 std::ostringstream oss;
108 oss << fpTopPV->GetName() << ':' << fpTopPV->GetCopyNo()
109 << " BasePath:" << fBaseFullPVPath;
110 fGlobalTag = oss.str();
111 fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
113 }
114}
115
120
122(const std::vector<G4PhysicalVolumeNodeID>& path)
123{
125 for (const auto& node: path) {
126 PVNameCopyNoPath.push_back
128 (node.GetPhysicalVolume()->GetName(),node.GetCopyNo()));
129 }
130 return PVNameCopyNoPath;
131}
132
134(const std::vector<G4PhysicalVolumeNodeID>& path)
135// Converts to path string, e.g., " World 0 Envelope 0 Shape1 0".
136// Note leading space character.
137{
138 std::ostringstream oss;
139 oss << path;
140 return oss.str();
141}
142
144{
145 // To handle paramaterisations, set copy number and compute dimensions
146 // to get extent right
147 G4VPVParameterisation* pP = fpTopPV -> GetParameterisation ();
148 if (pP) {
149 fpTopPV -> SetCopyNo (fTopPVCopyNo);
150 G4VSolid* solid = pP -> ComputeSolid (fTopPVCopyNo, fpTopPV);
151 solid -> ComputeDimensions (pP, fTopPVCopyNo, fpTopPV);
152 }
153 if (fUseFullExtent) {
154 fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
155 } else {
156 // Calculate extent of *drawn* volumes, i.e., ignoring culled, e.g.,
157 // invisible volumes, by traversing the whole geometry hierarchy below
158 // this physical volume.
159 G4BoundingExtentScene beScene(this);
160 const G4int tempRequestedDepth = fRequestedDepth;
161 const G4Transform3D tempTransform = fTransform;
162 const G4ModelingParameters* tempMP = fpMP;
163 fRequestedDepth = -1; // Always search to all depths to define extent.
164 fTransform = G4Transform3D(); // Extent is in local cooridinates
166 (0, // No default vis attributes needed.
167 G4ModelingParameters::wf, // wireframe (not relevant for this).
168 true, // Global culling.
169 true, // Cull invisible volumes.
170 false, // Density culling.
171 0., // Density (not relevant if density culling false).
172 true, // Cull daughters of opaque mothers.
173 24); // No of sides (not relevant for this operation).
174 mParams.SetSpecialMeshRendering(true); // Avoids traversing parameterisations
175 fpMP = &mParams;
176 DescribeYourselfTo (beScene);
177 fExtent = beScene.GetBoundingExtent();
178 fpMP = tempMP;
179 fTransform = tempTransform;
180 fRequestedDepth = tempRequestedDepth;
181 }
183 if (radius < 0.) { // Nothing in the scene - revert to top extent
184 fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
185 }
187}
188
190(G4VGraphicsScene& sceneHandler)
191{
192 if (!fpTopPV) {
194 ("G4PhysicalVolumeModel::DescribeYourselfTo",
195 "modeling0012", FatalException, "No model.");
196 return; // Should never reach here, but keeps Coverity happy.
197 }
198
199 if (!fpMP) {
201 ("G4PhysicalVolumeModel::DescribeYourselfTo",
202 "modeling0013", FatalException, "No modeling parameters.");
203 return; // Should never reach here, but keeps Coverity happy.
204 }
205
206 fNClippers = 0;
207 G4DisplacedSolid* pSectionSolid = fpMP->GetSectionSolid();
208 G4DisplacedSolid* pCutawaySolid = fpMP->GetCutawaySolid();
210 if (pSectionSolid) fNClippers++;
211 if (pCutawaySolid) fNClippers++;
212 if (fNClippers > 1) {
214 ed << "More than one solid cutter/clipper:";
215 if (fpClippingSolid) ed << "\nclipper in force";
216 if (pSectionSolid) ed << "\nsectioner in force";
217 if (pCutawaySolid) ed << "\ncutaway in force";
218 G4Exception("G4PhysicalVolumeModel::DescribeSolid", "modeling0016", JustWarning, ed);
219 }
220
221 G4Transform3D startingTransformation = fTransform;
222
223 fNTouchables.clear(); // Keeps count of touchable drawn at each depth
224
226 (fpTopPV,
228 startingTransformation,
229 sceneHandler);
230
231 // Reset or clear data...
232 fCurrentDepth = 0;
238 fDrawnPVPath.clear();
239 fAbort = false;
240 fCurtailDescent = false;
241}
242
244{
245 if (fpCurrentPV) {
246 std::ostringstream o;
247 o << fpCurrentPV -> GetCopyNo ();
248 return fpCurrentPV -> GetName () + ":" + o.str();
249 }
250 else {
251 return "WARNING: NO CURRENT VOLUME - global tag is " + fGlobalTag;
252 }
253}
254
256{
257 return "G4PhysicalVolumeModel " + GetCurrentTag ();
258}
259
261(G4VPhysicalVolume* pVPV,
262 G4int requestedDepth,
263 const G4Transform3D& theAT,
264 G4VGraphicsScene& sceneHandler)
265{
266 // Visits geometry structure to a given depth (requestedDepth), starting
267 // at given physical volume with given starting transformation and
268 // describes volumes to the scene handler.
269 // requestedDepth < 0 (default) implies full visit.
270 // theAT is the Accumulated Transformation.
271
272 // Find corresponding logical volume and (later) solid, storing in
273 // local variables to preserve re-entrancy.
274 G4LogicalVolume* pLV = pVPV -> GetLogicalVolume ();
275 G4VSolid* pSol = nullptr;
276 G4Material* pMaterial = nullptr;
277
278 if (!(pVPV -> IsReplicated ())) {
279 // Non-replicated physical volume.
280 pSol = pLV -> GetSolid ();
281 pMaterial = pLV -> GetMaterial ();
282 DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
283 theAT, sceneHandler);
284 }
285 else {
286 // Replicated or parametrised physical volume.
287 EAxis axis;
288 G4int nReplicas;
289 G4double width;
290 G4double offset;
291 G4bool consuming;
292 pVPV -> GetReplicationData (axis, nReplicas, width, offset, consuming);
293 G4int nBegin = 0;
294 G4int nEnd = nReplicas;
295 if (fCurrentDepth == 0) { // i.e., top volume
296 nBegin = fTopPVCopyNo; // Describe only one volume, namely the one
297 nEnd = nBegin + 1; // specified by the given copy number.
298 }
299 G4VPVParameterisation* pP = pVPV -> GetParameterisation ();
300 if (pP) { // Parametrised volume.
301 for (int n = nBegin; n < nEnd; n++) {
302 pSol = pP -> ComputeSolid (n, pVPV);
303 pP -> ComputeTransformation (n, pVPV);
304 pSol -> ComputeDimensions (pP, n, pVPV);
305 pVPV -> SetCopyNo (n);
307 // Create a touchable of current parent for ComputeMaterial.
308 // fFullPVPath has not been updated yet so at this point it
309 // corresponds to the parent.
311 pMaterial = pP -> ComputeMaterial (n, pVPV, &parentTouchable);
312 DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
313 theAT, sceneHandler);
314 }
315 }
316 else { // Plain replicated volume. From geometry_guide.txt...
317 // The replica's positions are claculated by means of a linear formula.
318 // Replication may occur along:
319 //
320 // o Cartesian axes (kXAxis,kYAxis,kZAxis)
321 //
322 // The replications, of specified width have coordinates of
323 // form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1
324 // for the case of kXAxis, and are unrotated.
325 //
326 // o Radial axis (cylindrical polar) (kRho)
327 //
328 // The replications are cons/tubs sections, centred on the origin
329 // and are unrotated.
330 // They have radii of width*n+offset to width*(n+1)+offset
331 // where n=0..nReplicas-1
332 //
333 // o Phi axis (cylindrical polar) (kPhi)
334 // The replications are `phi sections' or wedges, and of cons/tubs form
335 // They have phi of offset+n*width to offset+(n+1)*width where
336 // n=0..nReplicas-1
337 //
338 pSol = pLV -> GetSolid ();
339 pMaterial = pLV -> GetMaterial ();
340 G4ThreeVector originalTranslation = pVPV -> GetTranslation ();
341 G4RotationMatrix* pOriginalRotation = pVPV -> GetRotation ();
342 G4double originalRMin = 0., originalRMax = 0.;
343 if (axis == kRho && pSol->GetEntityType() == "G4Tubs") {
344 originalRMin = ((G4Tubs*)pSol)->GetInnerRadius();
345 originalRMax = ((G4Tubs*)pSol)->GetOuterRadius();
346 }
347 G4bool visualisable = true;
348 for (int n = nBegin; n < nEnd; n++) {
349 G4ThreeVector translation; // Identity.
350 G4RotationMatrix rotation; // Identity - life enough for visualizing.
351 G4RotationMatrix* pRotation = 0;
352 switch (axis) {
353 default:
354 case kXAxis:
355 translation = G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0);
356 break;
357 case kYAxis:
358 translation = G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0);
359 break;
360 case kZAxis:
361 translation = G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width);
362 break;
363 case kRho:
364 if (pSol->GetEntityType() == "G4Tubs") {
365 ((G4Tubs*)pSol)->SetInnerRadius(width*n+offset);
366 ((G4Tubs*)pSol)->SetOuterRadius(width*(n+1)+offset);
367 } else {
368 if (fpMP->IsWarning())
369 G4warn <<
370 "G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
371 "\n built-in replicated volumes replicated in radius for "
372 << pSol->GetEntityType() <<
373 "-type\n solids (your solid \""
374 << pSol->GetName() <<
375 "\") are not visualisable."
376 << G4endl;
377 visualisable = false;
378 }
379 break;
380 case kPhi:
381 rotation.rotateZ (-(offset+(n+0.5)*width));
382 // Minus Sign because for the physical volume we need the
383 // coordinate system rotation.
384 pRotation = &rotation;
385 break;
386 }
387 pVPV -> SetTranslation (translation);
388 pVPV -> SetRotation (pRotation);
389 pVPV -> SetCopyNo (n);
391 if (visualisable) {
392 DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
393 theAT, sceneHandler);
394 }
395 }
396 // Restore originals...
397 pVPV -> SetTranslation (originalTranslation);
398 pVPV -> SetRotation (pOriginalRotation);
399 if (axis == kRho && pSol->GetEntityType() == "G4Tubs") {
400 ((G4Tubs*)pSol)->SetInnerRadius(originalRMin);
401 ((G4Tubs*)pSol)->SetOuterRadius(originalRMax);
402 }
403 }
404 }
405}
406
408(G4VPhysicalVolume* pVPV,
409 G4int requestedDepth,
410 G4LogicalVolume* pLV,
411 G4VSolid* pSol,
412 G4Material* pMaterial,
413 const G4Transform3D& theAT,
414 G4VGraphicsScene& sceneHandler)
415{
416 // Maintain useful data members...
417 fpCurrentPV = pVPV;
418 fCurrentPVCopyNo = pVPV->GetCopyNo();
419 fpCurrentLV = pLV;
420 fpCurrentMaterial = pMaterial;
421
422 // Create a nodeID for use below - note the "drawn" flag is true
423 G4int copyNo = fpCurrentPV->GetCopyNo();
424 auto nodeID = G4PhysicalVolumeNodeID
426
427 // Update full path of physical volumes...
428 fFullPVPath.push_back(nodeID);
429
430 const G4RotationMatrix objectRotation = pVPV -> GetObjectRotationValue ();
431 const G4ThreeVector& translation = pVPV -> GetTranslation ();
432 G4Transform3D theLT (G4Transform3D (objectRotation, translation));
433
434 // Compute the accumulated transformation...
435 // Note that top volume's transformation relative to the world
436 // coordinate system is specified in theAT == startingTransformation
437 // = fTransform (see DescribeYourselfTo), so first time through the
438 // volume's own transformation, which is only relative to its
439 // mother, i.e., not relative to the world coordinate system, should
440 // not be accumulated.
441 G4Transform3D theNewAT (theAT);
442 if (fCurrentDepth != 0) theNewAT = theAT * theLT;
443 fCurrentTransform = theNewAT;
444
445 const G4VisAttributes* pVisAttribs = pLV->GetVisAttributes();
446 // If the volume does not have any vis attributes, create it.
447 G4VisAttributes* tempVisAtts = nullptr;
448 if (!pVisAttribs) {
450 tempVisAtts = new G4VisAttributes(*fpMP->GetDefaultVisAttributes());
451 } else {
452 tempVisAtts = new G4VisAttributes;
453 }
454 // The user may request /vis/viewer/set/colourByDensity.
455 if (fpMP->GetCBDAlgorithmNumber() == 1) {
456 // Algorithm 1: 3 parameters: Simple rainbow mapping.
457 if (fpMP->GetCBDParameters().size() != 3) {
458 G4Exception("G4PhysicalVolumeModelTouchable::DescribeAndDescend",
459 "modeling0014",
461 "Algorithm-parameter mismatch for Colour By Density");
462 } else {
463 const G4double d = pMaterial? pMaterial->GetDensity(): 0.;
464 const G4double d0 = fpMP->GetCBDParameters()[0]; // Invisible d < d0.
465 const G4double d1 = fpMP->GetCBDParameters()[1]; // Rainbow d0->d1->d2.
466 const G4double d2 = fpMP->GetCBDParameters()[2]; // Blue d > d2.
467 if (d < d0) { // Density < d0 is invisible.
468 tempVisAtts->SetVisibility(false);
469 } else { // Intermediate densities are on a spectrum.
470 G4double red, green, blue;
471 if (d < d1) {
472 red = (d1-d)/(d1-d0); green = (d-d0)/(d1-d0); blue = 0.;
473 } else if (d < d2) {
474 red = 0.; green = (d2-d)/(d2-d1); blue = (d-d1)/(d2-d1);
475 } else { // Density >= d2 is blue.
476 red = 0.; green = 0.; blue = 1.;
477 }
478 tempVisAtts->SetColour(G4Colour(red,green,blue));
479 }
480 }
481 } else if (fpMP->GetCBDAlgorithmNumber() == 2) {
482 // Algorithm 2
483 // ...etc.
484 }
485 pVisAttribs = tempVisAtts;
486 }
487 // From here, can assume pVisAttribs is a valid pointer. This is necessary
488 // because PreAddSolid needs a vis attributes object.
489
490 // Check if vis attributes are to be modified by a /vis/touchable/set/ command.
491 const auto& vams = fpMP->GetVisAttributesModifiers();
492 if (vams.size()) {
493 // OK, we have some VAMs (Vis Attributes Modifiers).
494 for (const auto& vam: vams) {
495 const auto& vamPath = vam.GetPVNameCopyNoPath();
496 if (vamPath.size() == fFullPVPath.size()) {
497 // OK, we have a size match.
498 // Check the volume name/copy number path.
499 auto iVAMNameCopyNo = vamPath.begin();
500 auto iPVNodeId = fFullPVPath.begin();
501 for (; iVAMNameCopyNo != vamPath.end(); ++iVAMNameCopyNo, ++iPVNodeId) {
502 if (!(
503 iVAMNameCopyNo->GetName() ==
504 iPVNodeId->GetPhysicalVolume()->GetName() &&
505 iVAMNameCopyNo->GetCopyNo() ==
506 iPVNodeId->GetPhysicalVolume()->GetCopyNo()
507 )) {
508 // This path element does NOT match.
509 break;
510 }
511 }
512 if (iVAMNameCopyNo == vamPath.end()) {
513 // OK, the paths match (the above loop terminated normally).
514 // Create a vis atts object for the modified vis atts.
515 // It is static so that we may return a reliable pointer to it.
516 static G4VisAttributes modifiedVisAtts;
517 // Initialise it with the current vis atts and reset the pointer.
518 modifiedVisAtts = *pVisAttribs;
519 pVisAttribs = &modifiedVisAtts;
520 const G4VisAttributes& transVisAtts = vam.GetVisAttributes();
521 switch (vam.GetVisAttributesSignifier()) {
523 modifiedVisAtts.SetVisibility(transVisAtts.IsVisible());
524 break;
526 modifiedVisAtts.SetDaughtersInvisible
527 (transVisAtts.IsDaughtersInvisible());
528 break;
530 modifiedVisAtts.SetColour(transVisAtts.GetColour());
531 break;
533 modifiedVisAtts.SetLineStyle(transVisAtts.GetLineStyle());
534 break;
536 modifiedVisAtts.SetLineWidth(transVisAtts.GetLineWidth());
537 break;
539 if (transVisAtts.IsForceDrawingStyle()) {
540 if (transVisAtts.GetForcedDrawingStyle() ==
542 modifiedVisAtts.SetForceWireframe(true);
543 }
544 }
545 break;
547 if (transVisAtts.IsForceDrawingStyle()) {
548 if (transVisAtts.GetForcedDrawingStyle() ==
550 modifiedVisAtts.SetForceSolid(true);
551 }
552 }
553 break;
555 if (transVisAtts.IsForceDrawingStyle()) {
556 if (transVisAtts.GetForcedDrawingStyle() ==
558 modifiedVisAtts.SetForceCloud(true);
559 }
560 }
561 break;
563 modifiedVisAtts.SetForceNumberOfCloudPoints
564 (transVisAtts.GetForcedNumberOfCloudPoints());
565 break;
567 if (transVisAtts.IsForceAuxEdgeVisible()) {
568 modifiedVisAtts.SetForceAuxEdgeVisible
569 (transVisAtts.IsForcedAuxEdgeVisible());
570 }
571 break;
573 modifiedVisAtts.SetForceLineSegmentsPerCircle
574 (transVisAtts.GetForcedLineSegmentsPerCircle());
575 break;
576 }
577 }
578 }
579 }
580 }
581
582 // Check for special mesh rendering
584 G4bool potentialG4Mesh = false;
585 if (fpMP->GetSpecialMeshVolumes().empty()) {
586 // No volumes specified - all are potentially possible
587 potentialG4Mesh = true;
588 } else {
589 // Name and (optionally) copy number of container volume is specified
590 for (const auto& pvNameCopyNo: fpMP->GetSpecialMeshVolumes()) {
591 if (pVPV->GetName() == pvNameCopyNo.GetName()) {
592 // We have a name match
593 if (pvNameCopyNo.GetCopyNo() < 0) {
594 // Any copy number is OK
595 potentialG4Mesh = true;
596 } else {
597 if (pVPV->GetCopyNo() == pvNameCopyNo.GetCopyNo()) {
598 // We have a name and copy number match
599 potentialG4Mesh = true;
600 }
601 }
602 }
603 }
604 }
605 if (potentialG4Mesh) {
606 // Create - or at least attempt to create - a mesh. If it cannot be created
607 // out of this pVPV the type will be "invalid".
608 G4Mesh mesh(pVPV,theNewAT);
609 if (mesh.GetMeshType() != G4Mesh::invalid) {
610 // Create "artificial" nodeID to represent the replaced volumes
611 G4int artCopyNo = 0;
612 auto artPV = mesh.GetParameterisedVolume();
613 auto artDepth = fCurrentDepth + 1;
614 auto artNodeID = G4PhysicalVolumeNodeID(artPV,artCopyNo,artDepth);
615 fFullPVPath.push_back(artNodeID);
616 fDrawnPVPath.push_back(artNodeID);
617 sceneHandler.AddCompound(mesh);
618 fFullPVPath.pop_back();
619 fDrawnPVPath.pop_back();
620 delete tempVisAtts; // Needs cleaning up (Coverity warning!!)
621 return; // Mesh found and processed - nothing more to do.
622 } // else continue processing
623 }
624 }
625
626 // Make decision to draw...
627 G4bool thisToBeDrawn = true;
628
629 // There are various reasons why this volume
630 // might not be drawn...
631 G4bool culling = fpMP->IsCulling();
632 G4bool cullingInvisible = fpMP->IsCullingInvisible();
633 G4bool markedVisible
634 = pVisAttribs->IsVisible() && pVisAttribs->GetColour().GetAlpha() > 0;
635 G4bool cullingLowDensity = fpMP->IsDensityCulling();
636 G4double density = pMaterial? pMaterial->GetDensity(): 0;
637 G4double densityCut = fpMP -> GetVisibleDensity ();
638
639 // 1) Global culling is on....
640 if (culling) {
641 // 2) Culling of invisible volumes is on...
642 if (cullingInvisible) {
643 // 3) ...and the volume is marked not visible...
644 if (!markedVisible) thisToBeDrawn = false;
645 }
646 // 4) Or culling of low density volumes is on...
647 if (cullingLowDensity) {
648 // 5) ...and density is less than cut value...
649 if (density < densityCut) thisToBeDrawn = false;
650 }
651 }
652 // 6) The user has asked for all further traversing to be aborted...
653 if (fAbort) thisToBeDrawn = false;
654
655 // Set "drawn" flag (it was true by default) - thisToBeDrawn may be false
656 nodeID.SetDrawn(thisToBeDrawn);
657
658 if (thisToBeDrawn) {
659
660 // Update path of drawn physical volumes...
661 fDrawnPVPath.push_back(nodeID);
662
663 if (fpMP->IsExplode() && fDrawnPVPath.size() == 1) {
664 // For top-level drawn volumes, explode along radius...
666 G4Transform3D centred = centering.inverse() * theNewAT;
667 G4Scale3D oldScale;
668 G4Rotate3D oldRotation;
669 G4Translate3D oldTranslation;
670 centred.getDecomposition(oldScale, oldRotation, oldTranslation);
671 G4double explodeFactor = fpMP->GetExplodeFactor();
672 G4Translate3D newTranslation =
673 G4Translate3D(explodeFactor * oldTranslation.dx(),
674 explodeFactor * oldTranslation.dy(),
675 explodeFactor * oldTranslation.dz());
676 theNewAT = centering * newTranslation * oldRotation * oldScale;
677 }
678
679 auto fullDepth = fCurrentDepth + (G4int)fBaseFullPVPath.size();
680 fNTouchables[fullDepth]++; // Increment for every touchable drawn at each depth
681
682 DescribeSolid (theNewAT, pSol, pVisAttribs, sceneHandler);
683
684 }
685
686 // Make decision to draw daughters, if any. There are various
687 // reasons why daughters might not be drawn...
688
689 // First, reasons that do not depend on culling policy...
690 G4int nDaughters = (G4int)pLV->GetNoDaughters();
691 G4bool daughtersToBeDrawn = true;
692 // 1) There are no daughters...
693 if (!nDaughters) daughtersToBeDrawn = false;
694 // 2) We are at the limit if requested depth...
695 else if (requestedDepth == 0) daughtersToBeDrawn = false;
696 // 3) The user has asked for all further traversing to be aborted...
697 else if (fAbort) daughtersToBeDrawn = false;
698 // 4) The user has asked that the descent be curtailed...
699 else if (fCurtailDescent) daughtersToBeDrawn = false;
700
701 // Now, reasons that depend on culling policy...
702 else {
703 G4bool daughtersInvisible = pVisAttribs->IsDaughtersInvisible();
704 // Culling of covered daughters request. This is computed in
705 // G4VSceneHandler::CreateModelingParameters() depending on view
706 // parameters...
707 G4bool cullingCovered = fpMP->IsCullingCovered();
708 G4bool surfaceDrawing =
711 if (pVisAttribs->IsForceDrawingStyle()) {
712 switch (pVisAttribs->GetForcedDrawingStyle()) {
713 default:
714 case G4VisAttributes::wireframe: surfaceDrawing = false; break;
715 case G4VisAttributes::solid: surfaceDrawing = true; break;
716 }
717 }
718 G4bool opaque = pVisAttribs->GetColour().GetAlpha() >= 1.;
719 // 5) Global culling is on....
720 if (culling) {
721 // 6) ..and culling of invisible volumes is on...
722 if (cullingInvisible) {
723 // 7) ...and the mother requests daughters invisible
724 if (daughtersInvisible) daughtersToBeDrawn = false;
725 }
726 // 8) Or culling of covered daughters is requested...
727 if (cullingCovered) {
728 // 9) ...and surface drawing is operating...
729 if (surfaceDrawing) {
730 // 10) ...but only if mother is visible...
731 if (thisToBeDrawn) {
732 // 11) ...and opaque...
733 if (opaque) daughtersToBeDrawn = false;
734 }
735 }
736 }
737 }
738 }
739
740 if (daughtersToBeDrawn) {
741 for (G4int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
742 // Store daughter pVPV in local variable ready for recursion...
743 G4VPhysicalVolume* pDaughterVPV = pLV -> GetDaughter (iDaughter);
744 // Descend the geometry structure recursively...
747 (pDaughterVPV, requestedDepth - 1, theNewAT, sceneHandler);
749 }
750 }
751
752 // Clean up
753 delete tempVisAtts;
754
755 // Reset for normal descending of next volume at this level...
756 fCurtailDescent = false;
757
758 // Pop item from paths physical volumes...
759 fFullPVPath.pop_back();
760 if (thisToBeDrawn) {
761 fDrawnPVPath.pop_back();
762 }
763}
764
765namespace
766{
767 G4bool SubtractionBoundingLimits(const G4VSolid* target)
768 {
769 // Algorithm from G4SubtractionSolid::BoundingLimits
770 // Since it is unclear how the shape of the first solid will be changed
771 // after subtraction, just return its original bounding box.
772 G4ThreeVector pMin, pMax;
773 const auto& pSolA = target;
774 pSolA->BoundingLimits(pMin,pMax);
775 // Check correctness of the bounding box
776 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) {
777 // Bad bounding box (min >= max)
778 // This signifies a subtraction of non-intersecting volumes
779 return false;
780 }
781 return true;
782 }
783
784 G4bool IntersectionBoundingLimits(const G4VSolid* target, const G4DisplacedSolid* intersector)
785 {
786 // Algorithm from G4IntersectionSolid::BoundingLimits
787 G4ThreeVector pMin, pMax;
788 G4ThreeVector minA,maxA, minB,maxB;
789 const auto& pSolA = target;
790 const auto& pSolB = intersector;
791 pSolA->BoundingLimits(minA,maxA);
792 pSolB->BoundingLimits(minB,maxB);
793 pMin.set(std::max(minA.x(),minB.x()),
794 std::max(minA.y(),minB.y()),
795 std::max(minA.z(),minB.z()));
796 pMax.set(std::min(maxA.x(),maxB.x()),
797 std::min(maxA.y(),maxB.y()),
798 std::min(maxA.z(),maxB.z()));
799 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) {
800 // Bad bounding box (min >= max)
801 // This signifies a subtraction of non-intersecting volumes
802 return false;
803 }
804 return true;
805 }
806}
807
809(const G4Transform3D& theAT,
810 G4VSolid* pSol,
811 const G4VisAttributes* pVisAttribs,
812 G4VGraphicsScene& sceneHandler)
813{
814 G4DisplacedSolid* pSectionSolid = fpMP->GetSectionSolid();
815 G4DisplacedSolid* pCutawaySolid = fpMP->GetCutawaySolid();
816
818
819 // Normal case - no clipping, etc. - or, illegally, more than one of those
820 sceneHandler.PreAddSolid (theAT, *pVisAttribs);
821 pSol -> DescribeYourselfTo (sceneHandler); // Standard treatment.
822 sceneHandler.PostAddSolid ();
823
824 } else { // fNClippers == 1
825
826 G4VSolid* pResultantSolid = nullptr;
827 G4DisplacedSolid* pDisplacedSolid = nullptr;
828
829 if (fpClippingSolid) {
830 pDisplacedSolid = new G4DisplacedSolid("clipper", fpClippingSolid, theAT.inverse());
831 switch (fClippingMode) {
832 case subtraction:
833 if (SubtractionBoundingLimits(pSol)) {
834 pResultantSolid = new G4SubtractionSolid
835 ("subtracted_clipped_solid", pSol, pDisplacedSolid);
836 }
837 break;
838 case intersection:
839 if (IntersectionBoundingLimits(pSol, pDisplacedSolid)) {
840 pResultantSolid = new G4IntersectionSolid
841 ("intersected_clipped_solid", pSol, pDisplacedSolid);
842 }
843 break;
844 }
845
846 } else if (pSectionSolid) {
847 pDisplacedSolid = new G4DisplacedSolid("intersector", pSectionSolid, theAT.inverse());
848 if (IntersectionBoundingLimits(pSol, pDisplacedSolid)) {
849 pResultantSolid = new G4IntersectionSolid("sectioned_solid", pSol, pDisplacedSolid);
850 }
851
852 } else if (pCutawaySolid) {
853 pDisplacedSolid = new G4DisplacedSolid("cutaway", pCutawaySolid, theAT.inverse());
854 switch (fpMP->GetCutawayMode()) {
856 if (SubtractionBoundingLimits(pSol)) {
857 pResultantSolid = new G4SubtractionSolid("cutaway_solid", pSol, pDisplacedSolid);
858 }
859 break;
861 if (IntersectionBoundingLimits(pSol, pDisplacedSolid)) {
862 pResultantSolid = new G4IntersectionSolid("cutaway_solid", pSol, pDisplacedSolid);
863 }
864 break;
865 }
866 }
867
868 if (pResultantSolid) {
869 sceneHandler.PreAddSolid (theAT, *pVisAttribs);
870 pResultantSolid -> DescribeYourselfTo (sceneHandler);
871 sceneHandler.PostAddSolid ();
872 }
873
874 delete pResultantSolid;
875 delete pDisplacedSolid;
876 }
877}
878
880{
881// Not easy to see how to validate this sort of model. Previously there was
882// a check that a volume of the same name (fTopPVName) existed somewhere in
883// the geometry tree but under some circumstances this consumed lots of CPU
884// time. Instead, let us simply check that the volume (fpTopPV) exists in the
885// physical volume store.
886 const auto& pvStore = G4PhysicalVolumeStore::GetInstance();
887 auto iterator = find(pvStore->begin(),pvStore->end(),fpTopPV);
888 if (iterator == pvStore->end()) {
889 if (warn) {
891 ed << "Attempt to validate a volume that is no longer in the physical volume store.";
892 G4Exception("G4PhysicalVolumeModel::Validate", "modeling0015", JustWarning, ed);
893 }
894 return false;
895 } else {
896 return true;
897 }
898}
899
900const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
901{
902 G4bool isNew;
903 std::map<G4String,G4AttDef>* store
904 = G4AttDefStore::GetInstance("G4PhysicalVolumeModel", isNew);
905 if (isNew) {
906 (*store)["PVPath"] =
907 G4AttDef("PVPath","Physical Volume Path","Physics","","G4String");
908 (*store)["BasePVPath"] =
909 G4AttDef("BasePVPath","Base Physical Volume Path","Physics","","G4String");
910 (*store)["LVol"] =
911 G4AttDef("LVol","Logical Volume","Physics","","G4String");
912 (*store)["Solid"] =
913 G4AttDef("Solid","Solid Name","Physics","","G4String");
914 (*store)["EType"] =
915 G4AttDef("EType","Entity Type","Physics","","G4String");
916 (*store)["DmpSol"] =
917 G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
918 (*store)["LocalTrans"] =
919 G4AttDef("LocalTrans","Local transformation of volume","Physics","","G4String");
920 (*store)["LocalExtent"] =
921 G4AttDef("LocalExtent","Local extent of volume","Physics","","G4String");
922 (*store)["GlobalTrans"] =
923 G4AttDef("GlobalTrans","Global transformation of volume","Physics","","G4String");
924 (*store)["GlobalExtent"] =
925 G4AttDef("GlobalExtent","Global extent of volume","Physics","","G4String");
926 (*store)["Material"] =
927 G4AttDef("Material","Material Name","Physics","","G4String");
928 (*store)["Density"] =
929 G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
930 (*store)["State"] =
931 G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
932 (*store)["Radlen"] =
933 G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
934 (*store)["Region"] =
935 G4AttDef("Region","Cuts Region","Physics","","G4String");
936 (*store)["RootRegion"] =
937 G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
938 }
939 return store;
940}
941
942static std::ostream& operator<< (std::ostream& o, const G4Transform3D t)
943{
944 using namespace std;
945
946 G4Scale3D sc;
947 G4Rotate3D r;
948 G4Translate3D tl;
949 t.getDecomposition(sc, r, tl);
950
951 const int w = 10;
952
953 // Transformation itself
954 o << setw(w) << t.xx() << setw(w) << t.xy() << setw(w) << t.xz() << setw(w) << t.dx() << endl;
955 o << setw(w) << t.yx() << setw(w) << t.yy() << setw(w) << t.yz() << setw(w) << t.dy() << endl;
956 o << setw(w) << t.zx() << setw(w) << t.zy() << setw(w) << t.zz() << setw(w) << t.dz() << endl;
957
958 // Translation
959 o << "= translation:" << endl;
960 o << setw(w) << tl.dx() << setw(w) << tl.dy() << setw(w) << tl.dz() << endl;
961
962 // Rotation
963 o << "* rotation:" << endl;
964 o << setw(w) << r.xx() << setw(w) << r.xy() << setw(w) << r.xz() << endl;
965 o << setw(w) << r.yx() << setw(w) << r.yy() << setw(w) << r.yz() << endl;
966 o << setw(w) << r.zx() << setw(w) << r.zy() << setw(w) << r.zz() << endl;
967
968 // Scale
969 o << "* scale:" << endl;
970 o << setw(w) << sc.xx() << setw(w) << sc.yy() << setw(w) << sc.zz() << endl;
971
972 // Transformed axes
973 o << "Transformed axes:" << endl;
974 o << "x': " << r * G4Vector3D(1., 0., 0.) << endl;
975 o << "y': " << r * G4Vector3D(0., 1., 0.) << endl;
976 o << "z': " << r * G4Vector3D(0., 0., 1.) << endl;
977
978 return o;
979}
980
981std::vector<G4AttValue>* G4PhysicalVolumeModel::CreateCurrentAttValues() const
982{
983 std::vector<G4AttValue>* values = new std::vector<G4AttValue>;
984
985 if (!fpCurrentLV) {
987 ("G4PhysicalVolumeModel::CreateCurrentAttValues",
988 "modeling0004",
990 "Current logical volume not defined.");
991 return values;
992 }
993
994 std::ostringstream oss; oss << fFullPVPath;
995 values->push_back(G4AttValue("PVPath", oss.str(),""));
996
997 oss.str(""); oss << fBaseFullPVPath;
998 values->push_back(G4AttValue("BasePVPath", oss.str(),""));
999
1000 values->push_back(G4AttValue("LVol", fpCurrentLV->GetName(),""));
1001 G4VSolid* pSol = fpCurrentLV->GetSolid();
1002
1003 values->push_back(G4AttValue("Solid", pSol->GetName(),""));
1004
1005 values->push_back(G4AttValue("EType", pSol->GetEntityType(),""));
1006
1007 oss.str(""); oss << '\n' << *pSol;
1008 values->push_back(G4AttValue("DmpSol", oss.str(),""));
1009
1010 const G4RotationMatrix localRotation = fpCurrentPV->GetObjectRotationValue();
1011 const G4ThreeVector& localTranslation = fpCurrentPV->GetTranslation();
1012 oss.str(""); oss << '\n' << G4Transform3D(localRotation,localTranslation);
1013 values->push_back(G4AttValue("LocalTrans", oss.str(),""));
1014
1015 oss.str(""); oss << '\n' << pSol->GetExtent() << std::endl;
1016 values->push_back(G4AttValue("LocalExtent", oss.str(),""));
1017
1018 oss.str(""); oss << '\n' << fCurrentTransform;
1019 values->push_back(G4AttValue("GlobalTrans", oss.str(),""));
1020
1021 oss.str(""); oss << '\n' << (pSol->GetExtent()).Transform(fCurrentTransform) << std::endl;
1022 values->push_back(G4AttValue("GlobalExtent", oss.str(),""));
1023
1024 G4String matName = fpCurrentMaterial? fpCurrentMaterial->GetName(): G4String("No material");
1025 values->push_back(G4AttValue("Material", matName,""));
1026
1028 values->push_back(G4AttValue("Density", G4BestUnit(matDensity,"Volumic Mass"),""));
1029
1031 oss.str(""); oss << matState;
1032 values->push_back(G4AttValue("State", oss.str(),""));
1033
1035 values->push_back(G4AttValue("Radlen", G4BestUnit(matRadlen,"Length"),""));
1036
1037 G4Region* region = fpCurrentLV->GetRegion();
1038 G4String regionName = region? region->GetName(): G4String("No region");
1039 values->push_back(G4AttValue("Region", regionName,""));
1040
1041 oss.str(""); oss << fpCurrentLV->IsRootRegion();
1042 values->push_back(G4AttValue("RootRegion", oss.str(),""));
1043
1044 return values;
1045}
1046
1047G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator<
1049{
1050 if (fpPV < right.fpPV) return true;
1051 if (fpPV == right.fpPV) {
1052 if (fCopyNo < right.fCopyNo) return true;
1053 if (fCopyNo == right.fCopyNo)
1054 return fNonCulledDepth < right.fNonCulledDepth;
1055 }
1056 return false;
1057}
1058
1059G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator!=
1061{
1062 if (fpPV != right.fpPV ||
1063 fCopyNo != right.fCopyNo ||
1064 fNonCulledDepth != right.fNonCulledDepth ||
1065 fTransform != right.fTransform ||
1066 fDrawn != right.fDrawn) return true;
1067 return false;
1068}
1069
1070std::ostream& operator<<
1071 (std::ostream& os, const G4PhysicalVolumeModel::G4PhysicalVolumeNodeID& node)
1072{
1073 G4VPhysicalVolume* pPV = node.GetPhysicalVolume();
1074 if (pPV) {
1075 os << pPV->GetName()
1076 << ' ' << node.GetCopyNo()
1077// << '[' << node.GetNonCulledDepth() << ']'
1078// << ':' << node.GetTransform()
1079 ;
1080// os << " (";
1081// if (!node.GetDrawn()) os << "not ";
1082// os << "drawn)";
1083 } else {
1084 os << " (Null PV node)";
1085 }
1086 return os;
1087}
1088
1089std::ostream& operator<<
1090(std::ostream& os, const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& path)
1091{
1092 if (path.empty()) {
1093 os << " TOP";
1094 } else {
1095 for (const auto& nodeID: path) {
1096 os << ' ' << nodeID;
1097 }
1098 }
1099 return os;
1100}
1101
1103(const std::vector<G4PhysicalVolumeNodeID>& fullPVPath):
1104 fFullPVPath(fullPVPath) {}
1105
1107{
1108 size_t i = fFullPVPath.size() - depth - 1;
1109 if (i >= fFullPVPath.size()) {
1110 G4Exception("G4PhysicalVolumeModelTouchable::GetTranslation",
1111 "modeling0005",
1113 "Index out of range. Asking for non-existent depth");
1114 }
1115 static G4ThreeVector tempTranslation;
1116 tempTranslation = fFullPVPath[i].GetTransform().getTranslation();
1117 return tempTranslation;
1118}
1119
1121{
1122 size_t i = fFullPVPath.size() - depth - 1;
1123 if (i >= fFullPVPath.size()) {
1124 G4Exception("G4PhysicalVolumeModelTouchable::GetRotation",
1125 "modeling0006",
1127 "Index out of range. Asking for non-existent depth");
1128 }
1129 static G4RotationMatrix tempRotation;
1130 tempRotation = fFullPVPath[i].GetTransform().getRotation();
1131 return &tempRotation;
1132}
1133
1135{
1136 size_t i = fFullPVPath.size() - depth - 1;
1137 if (i >= fFullPVPath.size()) {
1138 G4Exception("G4PhysicalVolumeModelTouchable::GetVolume",
1139 "modeling0007",
1141 "Index out of range. Asking for non-existent depth");
1142 }
1143 return fFullPVPath[i].GetPhysicalVolume();
1144}
1145
1147{
1148 size_t i = fFullPVPath.size() - depth - 1;
1149 if (i >= fFullPVPath.size()) {
1150 G4Exception("G4PhysicalVolumeModelTouchable::GetSolid",
1151 "modeling0008",
1153 "Index out of range. Asking for non-existent depth");
1154 }
1155 return fFullPVPath[i].GetPhysicalVolume()->GetLogicalVolume()->GetSolid();
1156}
1157
1159{
1160 size_t i = fFullPVPath.size() - depth - 1;
1161 if (i >= fFullPVPath.size()) {
1162 G4Exception("G4PhysicalVolumeModelTouchable::GetReplicaNumber",
1163 "modeling0009",
1165 "Index out of range. Asking for non-existent depth");
1166 }
1167 return fFullPVPath[i].GetCopyNo();
1168}
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4State
@ kStateUndefined
#define G4warn
Definition G4Scene.cc:41
#define G4BestUnit(a, b)
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Transform3D G4Transform3D
HepGeom::Translate3D G4Translate3D
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
HepGeom::Vector3D< G4double > G4Vector3D
Definition G4Vector3D.hh:34
#define G4endl
Definition G4ios.hh:67
double z() const
double x() const
double y() const
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
Definition Rotation.cc:87
const G4VisExtent & GetBoundingExtent() const
G4double GetAlpha() const
Definition G4Colour.hh:155
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
G4VSolid * GetSolid() const
const G4VisAttributes * GetVisAttributes() const
std::size_t GetNoDaughters() const
G4bool IsRootRegion() const
G4Region * GetRegion() const
G4Material * GetMaterial() const
const G4String & GetName() const
G4double GetDensity() const
G4State GetState() const
G4double GetRadlen() const
const G4String & GetName() const
G4VPhysicalVolume * GetParameterisedVolume() const
Definition G4Mesh.hh:74
MeshType GetMeshType() const
Definition G4Mesh.hh:75
@ invalid
Definition G4Mesh.hh:52
G4bool IsWarning() const
const G4VisAttributes * GetDefaultVisAttributes() const
const std::vector< VisAttributesModifier > & GetVisAttributesModifiers() const
std::vector< PVNameCopyNo > PVNameCopyNoPath
CutawayMode GetCutawayMode() const
const G4Point3D & GetExplodeCentre() const
G4bool IsCullingInvisible() const
const std::vector< PVNameCopyNo > & GetSpecialMeshVolumes() const
G4bool IsExplode() const
G4bool IsCulling() const
const std::vector< G4double > & GetCBDParameters() const
G4bool IsDensityCulling() const
G4bool IsSpecialMeshRendering() const
DrawingStyle GetDrawingStyle() const
G4DisplacedSolid * GetSectionSolid() const
G4double GetExplodeFactor() const
G4DisplacedSolid * GetCutawaySolid() const
G4bool IsCullingCovered() const
G4int GetCBDAlgorithmNumber() const
void SetSpecialMeshRendering(G4bool)
const G4RotationMatrix * GetRotation(G4int depth) const
G4PhysicalVolumeModelTouchable(const std::vector< G4PhysicalVolumeNodeID > &fullPVPath)
const G4ThreeVector & GetTranslation(G4int depth) const
void DescribeAndDescend(G4VPhysicalVolume *, G4int requestedDepth, G4LogicalVolume *, G4VSolid *, G4Material *, const G4Transform3D &, G4VGraphicsScene &)
std::vector< G4PhysicalVolumeNodeID > fFullPVPath
void VisitGeometryAndGetVisReps(G4VPhysicalVolume *, G4int requestedDepth, const G4Transform3D &, G4VGraphicsScene &)
std::vector< G4AttValue > * CreateCurrentAttValues() const
G4PhysicalVolumeModel(G4VPhysicalVolume *=0, G4int requestedDepth=UNLIMITED, const G4Transform3D &modelTransformation=G4Transform3D(), const G4ModelingParameters *=0, G4bool useFullExtent=false, const std::vector< G4PhysicalVolumeNodeID > &baseFullPVPath=std::vector< G4PhysicalVolumeNodeID >())
std::vector< G4PhysicalVolumeNodeID > fDrawnPVPath
virtual void DescribeSolid(const G4Transform3D &theAT, G4VSolid *pSol, const G4VisAttributes *pVisAttribs, G4VGraphicsScene &sceneHandler)
static G4String GetPVNamePathString(const std::vector< G4PhysicalVolumeNodeID > &)
G4String GetCurrentDescription() const
void DescribeYourselfTo(G4VGraphicsScene &)
std::vector< G4PhysicalVolumeNodeID > fBaseFullPVPath
G4VPhysicalVolume * fpCurrentPV
std::map< G4int, G4int > fNTouchables
const std::map< G4String, G4AttDef > * GetAttDefs() const
static G4ModelingParameters::PVNameCopyNoPath GetPVNameCopyNoPath(const std::vector< G4PhysicalVolumeNodeID > &)
static G4PhysicalVolumeStore * GetInstance()
const G4String & GetName() const
virtual void AddCompound(const G4VTrajectory &)=0
virtual void PostAddSolid()=0
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &visAttribs)=0
G4VisExtent fExtent
Definition G4VModel.hh:97
G4String fGlobalDescription
Definition G4VModel.hh:96
const G4VisExtent & GetExtent() const
G4String fType
Definition G4VModel.hh:94
const G4ModelingParameters * fpMP
Definition G4VModel.hh:98
G4String fGlobalTag
Definition G4VModel.hh:95
const G4ThreeVector GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
G4RotationMatrix GetObjectRotationValue() const
virtual G4int GetCopyNo() const =0
const G4String & GetName() const
G4String GetName() const
virtual G4VisExtent GetExtent() const
Definition G4VSolid.cc:682
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition G4VSolid.cc:665
virtual G4GeometryType GetEntityType() const =0
G4int GetForcedNumberOfCloudPoints() const
G4double GetLineWidth() const
G4bool IsDaughtersInvisible() const
void SetColour(const G4Colour &)
void SetVisibility(G4bool=true)
void SetForceAuxEdgeVisible(G4bool=true)
void SetForceCloud(G4bool=true)
G4int GetForcedLineSegmentsPerCircle() const
void SetForceWireframe(G4bool=true)
void SetLineWidth(G4double)
LineStyle GetLineStyle() const
const G4Colour & GetColour() const
G4bool IsVisible() const
G4bool IsForceAuxEdgeVisible() const
G4bool IsForcedAuxEdgeVisible() const
ForcedDrawingStyle GetForcedDrawingStyle() const
void SetForceSolid(G4bool=true)
void SetLineStyle(LineStyle)
void SetForceLineSegmentsPerCircle(G4int nSegments)
void SetDaughtersInvisible(G4bool=true)
void SetForceNumberOfCloudPoints(G4int nPoints)
G4bool IsForceDrawingStyle() const
G4double GetExtentRadius() const
G4VisExtent & Transform(const G4Transform3D &)
double dy() const
double zz() const
double yz() const
double dz() const
double dx() const
void getDecomposition(Scale3D &scale, Rotate3D &rotation, Translate3D &translation) const
double xy() const
double zx() const
double yx() const
Transform3D inverse() const
double zy() const
double xx() const
double yy() const
double xz() const
EAxis
Definition geomdefs.hh:54
@ kPhi
Definition geomdefs.hh:60
@ kYAxis
Definition geomdefs.hh:56
@ kXAxis
Definition geomdefs.hh:55
@ kZAxis
Definition geomdefs.hh:57
@ kRho
Definition geomdefs.hh:58
std::map< G4String, G4AttDef > * GetInstance(const G4String &storeKey, G4bool &isNew)