Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 // $Id: G4PhysicalVolumeModel.cc 70646 2013-06-03 15:07:58Z gcosmo $
28 //
29 //
30 // John Allison 31st December 1997.
31 // Model for physical volumes.
32 
33 #include "G4PhysicalVolumeModel.hh"
34 
35 #include "G4ModelingParameters.hh"
36 #include "G4VGraphicsScene.hh"
37 #include "G4VPhysicalVolume.hh"
38 #include "G4VPVParameterisation.hh"
39 #include "G4LogicalVolume.hh"
40 #include "G4VSolid.hh"
41 #include "G4SubtractionSolid.hh"
42 #include "G4IntersectionSolid.hh"
43 #include "G4Material.hh"
44 #include "G4VisAttributes.hh"
45 #include "G4BoundingSphereScene.hh"
48 #include "G4Polyhedron.hh"
49 #include "HepPolyhedronProcessor.h"
50 #include "G4AttDefStore.hh"
51 #include "G4AttDef.hh"
52 #include "G4AttValue.hh"
53 #include "G4UnitsTable.hh"
54 #include "G4Vector3D.hh"
55 
56 #include <sstream>
57 
60  G4int requestedDepth,
61  const G4Transform3D& modelTransformation,
62  const G4ModelingParameters* pMP,
63  G4bool useFullExtent):
64  G4VModel (modelTransformation, pMP),
65  fpTopPV (pVPV),
66  fTopPVCopyNo (0),
67  fRequestedDepth (requestedDepth),
68  fUseFullExtent (useFullExtent),
69  fCurrentDepth (0),
70  fpCurrentPV (0),
71  fpCurrentLV (0),
72  fpCurrentMaterial (0),
73  fpCurrentTransform (0),
74  fCurtailDescent (false),
75  fpClippingSolid (0),
76  fClippingMode (subtraction)
77 {
78  if (fpTopPV) {
79 
80  fType = "G4PhysicalVolumeModel";
81  fTopPVName = fpTopPV -> GetName ();
82  fTopPVCopyNo = fpTopPV -> GetCopyNo ();
83  std::ostringstream o;
84  o << fpTopPV -> GetCopyNo ();
85  fGlobalTag = fpTopPV -> GetName () + "." + o.str();
86  fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
87 
88  CalculateExtent ();
89  }
90 }
91 
93 {
94  delete fpClippingSolid;
95 }
96 
98 {
99  if (fUseFullExtent) {
100  fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
101  }
102  else {
103  G4BoundingSphereScene bsScene(this);
104  const G4int tempRequestedDepth = fRequestedDepth;
105  fRequestedDepth = -1; // Always search to all depths to define extent.
106  const G4ModelingParameters* tempMP = fpMP;
107  G4ModelingParameters mParams
108  (0, // No default vis attributes needed.
109  G4ModelingParameters::wf, // wireframe (not relevant for this).
110  true, // Global culling.
111  true, // Cull invisible volumes.
112  false, // Density culling.
113  0., // Density (not relevant if density culling false).
114  true, // Cull daughters of opaque mothers.
115  24); // No of sides (not relevant for this operation).
116  fpMP = &mParams;
117  DescribeYourselfTo (bsScene);
118  G4double radius = bsScene.GetRadius();
119  if (radius < 0.) { // Nothing in the scene.
120  fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
121  } else {
122  // Transform back to coordinates relative to the top
123  // transformation, which is in G4VModel::fTransform. This makes
124  // it conform to all models, which are defined by a
125  // transformation and an extent relative to that
126  // transformation...
127  G4Point3D centre = bsScene.GetCentre();
128  centre.transform(fTransform.inverse());
129  fExtent = G4VisExtent(centre, radius);
130  }
131  fpMP = tempMP;
132  fRequestedDepth = tempRequestedDepth;
133  }
134 }
135 
137 (G4VGraphicsScene& sceneHandler)
138 {
139  if (!fpTopPV) G4Exception
140  ("G4PhysicalVolumeModel::DescribeYourselfTo",
141  "modeling0012", FatalException, "No model.");
142 
143  if (!fpMP) G4Exception
144  ("G4PhysicalVolumeModel::DescribeYourselfTo",
145  "modeling0003", FatalException, "No modeling parameters.");
146 
147  // For safety...
148  fCurrentDepth = 0;
149 
150  G4Transform3D startingTransformation = fTransform;
151 
152  VisitGeometryAndGetVisReps
153  (fpTopPV,
154  fRequestedDepth,
155  startingTransformation,
156  sceneHandler);
157 
158  // Clear data...
159  fCurrentDepth = 0;
160  fpCurrentPV = 0;
161  fpCurrentLV = 0;
162  fpCurrentMaterial = 0;
163  if (fFullPVPath.size() != fBaseFullPVPath.size()) {
164  // They should be equal if pushing and popping is happening properly.
166  ("G4PhysicalVolumeModel::DescribeYourselfTo",
167  "modeling0013",
169  "Path at start of modeling not equal to base path. Something badly"
170  "\nwrong. Please contact visualisation coordinator.");
171  }
172  fDrawnPVPath.clear();
173 }
174 
176 {
177  if (fpCurrentPV) {
178  std::ostringstream o;
179  o << fpCurrentPV -> GetCopyNo ();
180  return fpCurrentPV -> GetName () + "." + o.str();
181  }
182  else {
183  return "WARNING: NO CURRENT VOLUME - global tag is " + fGlobalTag;
184  }
185 }
186 
188 {
189  return "G4PhysicalVolumeModel " + GetCurrentTag ();
190 }
191 
194  G4int requestedDepth,
195  const G4Transform3D& theAT,
196  G4VGraphicsScene& sceneHandler)
197 {
198  // Visits geometry structure to a given depth (requestedDepth), starting
199  // at given physical volume with given starting transformation and
200  // describes volumes to the scene handler.
201  // requestedDepth < 0 (default) implies full visit.
202  // theAT is the Accumulated Transformation.
203 
204  // Find corresponding logical volume and (later) solid, storing in
205  // local variables to preserve re-entrancy.
206  G4LogicalVolume* pLV = pVPV -> GetLogicalVolume ();
207 
208  G4VSolid* pSol;
209  G4Material* pMaterial;
210 
211  if (!(pVPV -> IsReplicated ())) {
212  // Non-replicated physical volume.
213  pSol = pLV -> GetSolid ();
214  pMaterial = pLV -> GetMaterial ();
215  DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
216  theAT, sceneHandler);
217  }
218  else {
219  // Replicated or parametrised physical volume.
220  EAxis axis;
221  G4int nReplicas;
222  G4double width;
223  G4double offset;
224  G4bool consuming;
225  pVPV -> GetReplicationData (axis, nReplicas, width, offset, consuming);
226  if (fCurrentDepth == 0) nReplicas = 1; // Just draw first
227  G4VPVParameterisation* pP = pVPV -> GetParameterisation ();
228  if (pP) { // Parametrised volume.
229  for (int n = 0; n < nReplicas; n++) {
230  pSol = pP -> ComputeSolid (n, pVPV);
231  pP -> ComputeTransformation (n, pVPV);
232  pSol -> ComputeDimensions (pP, n, pVPV);
233  pVPV -> SetCopyNo (n);
234  // Create a touchable of current parent for ComputeMaterial.
235  // fFullPVPath has not been updated yet so at this point it
236  // corresponds to the parent.
237  G4PhysicalVolumeModelTouchable parentTouchable(fFullPVPath);
238  pMaterial = pP -> ComputeMaterial (n, pVPV, &parentTouchable);
239  DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
240  theAT, sceneHandler);
241  }
242  }
243  else { // Plain replicated volume. From geometry_guide.txt...
244  // The replica's positions are claculated by means of a linear formula.
245  // Replication may occur along:
246  //
247  // o Cartesian axes (kXAxis,kYAxis,kZAxis)
248  //
249  // The replications, of specified width have coordinates of
250  // form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1
251  // for the case of kXAxis, and are unrotated.
252  //
253  // o Radial axis (cylindrical polar) (kRho)
254  //
255  // The replications are cons/tubs sections, centred on the origin
256  // and are unrotated.
257  // They have radii of width*n+offset to width*(n+1)+offset
258  // where n=0..nReplicas-1
259  //
260  // o Phi axis (cylindrical polar) (kPhi)
261  // The replications are `phi sections' or wedges, and of cons/tubs form
262  // They have phi of offset+n*width to offset+(n+1)*width where
263  // n=0..nReplicas-1
264  //
265  pSol = pLV -> GetSolid ();
266  pMaterial = pLV -> GetMaterial ();
267  G4ThreeVector originalTranslation = pVPV -> GetTranslation ();
268  G4RotationMatrix* pOriginalRotation = pVPV -> GetRotation ();
269  G4double originalRMin = 0., originalRMax = 0.;
270  if (axis == kRho && pSol->GetEntityType() == "G4Tubs") {
271  originalRMin = ((G4Tubs*)pSol)->GetInnerRadius();
272  originalRMax = ((G4Tubs*)pSol)->GetOuterRadius();
273  }
274  G4bool visualisable = true;
275  for (int n = 0; n < nReplicas; n++) {
276  G4ThreeVector translation; // Null.
277  G4RotationMatrix rotation; // Null - life long enough for visualizing.
278  G4RotationMatrix* pRotation = 0;
279  switch (axis) {
280  default:
281  case kXAxis:
282  translation = G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0);
283  break;
284  case kYAxis:
285  translation = G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0);
286  break;
287  case kZAxis:
288  translation = G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width);
289  break;
290  case kRho:
291  if (pSol->GetEntityType() == "G4Tubs") {
292  ((G4Tubs*)pSol)->SetInnerRadius(width*n+offset);
293  ((G4Tubs*)pSol)->SetOuterRadius(width*(n+1)+offset);
294  } else {
295  if (fpMP->IsWarning())
296  G4cout <<
297  "G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
298  "\n built-in replicated volumes replicated in radius for "
299  << pSol->GetEntityType() <<
300  "-type\n solids (your solid \""
301  << pSol->GetName() <<
302  "\") are not visualisable."
303  << G4endl;
304  visualisable = false;
305  }
306  break;
307  case kPhi:
308  rotation.rotateZ (-(offset+(n+0.5)*width));
309  // Minus Sign because for the physical volume we need the
310  // coordinate system rotation.
311  pRotation = &rotation;
312  break;
313  }
314  pVPV -> SetTranslation (translation);
315  pVPV -> SetRotation (pRotation);
316  pVPV -> SetCopyNo (n);
317  if (visualisable) {
318  DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
319  theAT, sceneHandler);
320  }
321  }
322  // Restore originals...
323  pVPV -> SetTranslation (originalTranslation);
324  pVPV -> SetRotation (pOriginalRotation);
325  if (axis == kRho && pSol->GetEntityType() == "G4Tubs") {
326  ((G4Tubs*)pSol)->SetInnerRadius(originalRMin);
327  ((G4Tubs*)pSol)->SetOuterRadius(originalRMax);
328  }
329  }
330  }
331 
332  return;
333 }
334 
337  G4int requestedDepth,
338  G4LogicalVolume* pLV,
339  G4VSolid* pSol,
340  G4Material* pMaterial,
341  const G4Transform3D& theAT,
342  G4VGraphicsScene& sceneHandler)
343 {
344  // Maintain useful data members...
345  fpCurrentPV = pVPV;
346  fpCurrentLV = pLV;
347  fpCurrentMaterial = pMaterial;
348 
349  const G4RotationMatrix objectRotation = pVPV -> GetObjectRotationValue ();
350  const G4ThreeVector& translation = pVPV -> GetTranslation ();
351  G4Transform3D theLT (G4Transform3D (objectRotation, translation));
352 
353  // Compute the accumulated transformation...
354  // Note that top volume's transformation relative to the world
355  // coordinate system is specified in theAT == startingTransformation
356  // = fTransform (see DescribeYourselfTo), so first time through the
357  // volume's own transformation, which is only relative to its
358  // mother, i.e., not relative to the world coordinate system, should
359  // not be accumulated.
360  G4Transform3D theNewAT (theAT);
361  if (fCurrentDepth != 0) theNewAT = theAT * theLT;
362  fpCurrentTransform = &theNewAT;
363 
364  const G4VisAttributes* pVisAttribs = pLV->GetVisAttributes();
365  if (!pVisAttribs) pVisAttribs = fpMP->GetDefaultVisAttributes();
366  // Beware - pVisAttribs might still be zero - create a temporary default one...
367  G4bool visAttsCreated = false;
368  if (!pVisAttribs) {
369  pVisAttribs = new G4VisAttributes;
370  visAttsCreated = true;
371  }
372  // From here, can assume pVisAttribs is a valid pointer.
373 
374  // Make decision to draw...
375  G4bool thisToBeDrawn = true;
376 
377  // Update full path of physical volumes...
378  G4int copyNo = fpCurrentPV->GetCopyNo();
379  fFullPVPath.push_back
381  (fpCurrentPV,copyNo,fCurrentDepth,*fpCurrentTransform));
382 
383  // In case we need to copy the vis atts for modification...
384  G4bool copyForVAM = false;
385  const G4VisAttributes* pUnmodifiedVisAtts = pVisAttribs;
386  G4VisAttributes* pModifiedVisAtts = 0;
387 
388  // Check if vis attributes are to be modified by a /vis/touchable/set/ command.
389  const std::vector<G4ModelingParameters::VisAttributesModifier>& vams =
390  fpMP->GetVisAttributesModifiers();
391  std::vector<G4ModelingParameters::VisAttributesModifier>::const_iterator
392  iModifier;
393  for (iModifier = vams.begin();
394  iModifier != vams.end();
395  ++iModifier) {
397  iModifier->GetPVNameCopyNoPath();
398  if (vamPath.size() == fFullPVPath.size()) {
399  // OK - there's a size match. Check it out.
400 // G4cout << "Size match" << G4endl;
402  std::vector<G4PhysicalVolumeNodeID>::const_iterator iPVNodeId;
403  for (iVAMNameCopyNo = vamPath.begin(), iPVNodeId = fFullPVPath.begin();
404  iVAMNameCopyNo != vamPath.end();
405  ++iVAMNameCopyNo, ++iPVNodeId) {
406 // G4cout
407 // << iVAMNameCopyNo->fName
408 // << ',' << iVAMNameCopyNo->fCopyNo
409 // << "; " << iPVNodeId->GetPhysicalVolume()->GetName()
410 // << ',' << iPVNodeId->GetPhysicalVolume()->GetCopyNo()
411 // << G4endl;
412  if (!(
413  iVAMNameCopyNo->GetName() ==
414  iPVNodeId->GetPhysicalVolume()->GetName() &&
415  iVAMNameCopyNo->GetCopyNo() ==
416  iPVNodeId->GetPhysicalVolume()->GetCopyNo()
417  )) {
418  break;
419  }
420  }
421  if (iVAMNameCopyNo == vamPath.end()) {
422 // G4cout << "Match found" << G4endl;
423  if (!copyForVAM) {
424  pModifiedVisAtts = new G4VisAttributes(*pUnmodifiedVisAtts);
425  pVisAttribs = pModifiedVisAtts;
426  copyForVAM = true;
427  }
428  const G4VisAttributes& transVisAtts = iModifier->GetVisAttributes();
429  switch (iModifier->GetVisAttributesSignifier()) {
431  pModifiedVisAtts->SetVisibility(transVisAtts.IsVisible());
432  break;
434  pModifiedVisAtts->SetDaughtersInvisible
435  (transVisAtts.IsDaughtersInvisible());
436  break;
438  pModifiedVisAtts->SetColour(transVisAtts.GetColour());
439  break;
441  pModifiedVisAtts->SetLineStyle(transVisAtts.GetLineStyle());
442  break;
444  pModifiedVisAtts->SetLineWidth(transVisAtts.GetLineWidth());
445  break;
447  if (transVisAtts.GetForcedDrawingStyle() ==
449  pModifiedVisAtts->SetForceWireframe
450  (transVisAtts.IsForceDrawingStyle());
451  }
452  break;
454  if (transVisAtts.GetForcedDrawingStyle() ==
456  pModifiedVisAtts->SetForceSolid
457  (transVisAtts.IsForceDrawingStyle());
458  }
459  break;
461  pModifiedVisAtts->SetForceAuxEdgeVisible
462  (transVisAtts.IsForceAuxEdgeVisible());
463  break;
465  pModifiedVisAtts->SetForceLineSegmentsPerCircle
466  (transVisAtts.GetForcedLineSegmentsPerCircle());
467  break;
468  }
469  }
470  }
471  }
472 
473  // There are various reasons why this volume
474  // might not be drawn...
475  G4bool culling = fpMP->IsCulling();
476  G4bool cullingInvisible = fpMP->IsCullingInvisible();
477  G4bool markedVisible = pVisAttribs->IsVisible();
478  G4bool cullingLowDensity = fpMP->IsDensityCulling();
479  G4double density = pMaterial? pMaterial->GetDensity(): 0;
480  G4double densityCut = fpMP -> GetVisibleDensity ();
481 
482  // 1) Global culling is on....
483  if (culling) {
484  // 2) Culling of invisible volumes is on...
485  if (cullingInvisible) {
486  // 3) ...and the volume is marked not visible...
487  if (!markedVisible) thisToBeDrawn = false;
488  }
489  // 4) Or culling of low density volumes is on...
490  if (cullingLowDensity) {
491  // 5) ...and density is less than cut value...
492  if (density < densityCut) thisToBeDrawn = false;
493  }
494  }
495 
496  // Record thisToBeDrawn in path...
497  fFullPVPath.back().SetDrawn(thisToBeDrawn);
498 
499  if (thisToBeDrawn) {
500 
501  // Update path of drawn physical volumes...
502  fDrawnPVPath.push_back
504  (fpCurrentPV,copyNo,fCurrentDepth,*fpCurrentTransform,thisToBeDrawn));
505 
506  if (fpMP->IsExplode() && fDrawnPVPath.size() == 1) {
507  // For top-level drawn volumes, explode along radius...
508  G4Transform3D centering = G4Translate3D(fpMP->GetExplodeCentre());
509  G4Transform3D centred = centering.inverse() * theNewAT;
510  G4Scale3D oldScale;
511  G4Rotate3D oldRotation;
512  G4Translate3D oldTranslation;
513  centred.getDecomposition(oldScale, oldRotation, oldTranslation);
514  G4double explodeFactor = fpMP->GetExplodeFactor();
515  G4Translate3D newTranslation =
516  G4Translate3D(explodeFactor * oldTranslation.dx(),
517  explodeFactor * oldTranslation.dy(),
518  explodeFactor * oldTranslation.dz());
519  theNewAT = centering * newTranslation * oldRotation * oldScale;
520  }
521 
522  DescribeSolid (theNewAT, pSol, pVisAttribs, sceneHandler);
523 
524  }
525 
526  // Make decision to draw daughters, if any. There are various
527  // reasons why daughters might not be drawn...
528 
529  // First, reasons that do not depend on culling policy...
530  G4int nDaughters = pLV->GetNoDaughters();
531  G4bool daughtersToBeDrawn = true;
532  // 1) There are no daughters...
533  if (!nDaughters) daughtersToBeDrawn = false;
534  // 2) We are at the limit if requested depth...
535  else if (requestedDepth == 0) daughtersToBeDrawn = false;
536  // 3) The user has asked that the descent be curtailed...
537  else if (fCurtailDescent) daughtersToBeDrawn = false;
538 
539  // Now, reasons that depend on culling policy...
540  else {
541  G4bool daughtersInvisible = pVisAttribs->IsDaughtersInvisible();
542  // Culling of covered daughters request. This is computed in
543  // G4VSceneHandler::CreateModelingParameters() depending on view
544  // parameters...
545  G4bool cullingCovered = fpMP->IsCullingCovered();
546  G4bool surfaceDrawing =
547  fpMP->GetDrawingStyle() == G4ModelingParameters::hsr ||
548  fpMP->GetDrawingStyle() == G4ModelingParameters::hlhsr;
549  if (pVisAttribs->IsForceDrawingStyle()) {
550  switch (pVisAttribs->GetForcedDrawingStyle()) {
551  default:
552  case G4VisAttributes::wireframe: surfaceDrawing = false; break;
553  case G4VisAttributes::solid: surfaceDrawing = true; break;
554  }
555  }
556  G4bool opaque = pVisAttribs->GetColour().GetAlpha() >= 1.;
557  // 4) Global culling is on....
558  if (culling) {
559  // 5) ..and culling of invisible volumes is on...
560  if (cullingInvisible) {
561  // 6) ...and the mother requests daughters invisible
562  if (daughtersInvisible) daughtersToBeDrawn = false;
563  }
564  // 7) Or culling of covered daughters is requested...
565  if (cullingCovered) {
566  // 8) ...and surface drawing is operating...
567  if (surfaceDrawing) {
568  // 9) ...but only if mother is visible...
569  if (thisToBeDrawn) {
570  // 10) ...and opaque...
571  if (opaque) daughtersToBeDrawn = false;
572  }
573  }
574  }
575  }
576  }
577 
578  // Delete modified vis atts if created...
579  if (copyForVAM) {
580  delete pModifiedVisAtts;
581  pVisAttribs = pUnmodifiedVisAtts;
582  copyForVAM = false;
583  }
584 
585  // Vis atts for this volume no longer needed if created...
586  if (visAttsCreated) delete pVisAttribs;
587 
588  if (daughtersToBeDrawn) {
589  for (G4int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
590  // Store daughter pVPV in local variable ready for recursion...
591  G4VPhysicalVolume* pDaughterVPV = pLV -> GetDaughter (iDaughter);
592  // Descend the geometry structure recursively...
593  fCurrentDepth++;
594  VisitGeometryAndGetVisReps
595  (pDaughterVPV, requestedDepth - 1, theNewAT, sceneHandler);
596  fCurrentDepth--;
597  }
598  }
599 
600  // Reset for normal descending of next volume at this level...
601  fCurtailDescent = false;
602 
603  // Pop item from paths physical volumes...
604  fFullPVPath.pop_back();
605  if (thisToBeDrawn) {
606  fDrawnPVPath.pop_back();
607  }
608 }
609 
611 (const G4Transform3D& theAT,
612  G4VSolid* pSol,
613  const G4VisAttributes* pVisAttribs,
614  G4VGraphicsScene& sceneHandler)
615 {
616  sceneHandler.PreAddSolid (theAT, *pVisAttribs);
617 
618  G4VSolid* pSectionSolid = fpMP->GetSectionSolid();
619  G4VSolid* pCutawaySolid = fpMP->GetCutawaySolid();
620 
621  if (!fpClippingSolid && !pSectionSolid && !pCutawaySolid) {
622 
623  pSol -> DescribeYourselfTo (sceneHandler); // Standard treatment.
624 
625  } else {
626 
627  // Clipping, etc., performed by Boolean operations.
628 
629  // First, get polyhedron for current solid...
630  if (pVisAttribs->IsForceLineSegmentsPerCircle())
632  (pVisAttribs->GetForcedLineSegmentsPerCircle());
633  else
634  G4Polyhedron::SetNumberOfRotationSteps(fpMP->GetNoOfSides());
635  const G4Polyhedron* pOriginal = pSol->GetPolyhedron();
637 
638  if (!pOriginal) {
639 
640  if (fpMP->IsWarning())
641  G4cout <<
642  "WARNING: G4PhysicalVolumeModel::DescribeSolid: solid\n \""
643  << pSol->GetName() <<
644  "\" has no polyhedron. Cannot by clipped."
645  << G4endl;
646  pSol -> DescribeYourselfTo (sceneHandler); // Standard treatment.
647 
648  } else {
649 
650  G4Polyhedron resultant(*pOriginal);
651  G4VisAttributes resultantVisAttribs(*pVisAttribs);
652  G4VSolid* resultantSolid = 0;
653 
654  if (fpClippingSolid) {
655  switch (fClippingMode) {
656  default:
657  case subtraction:
658  resultantSolid = new G4SubtractionSolid
659  ("resultant_solid", pSol, fpClippingSolid, theAT.inverse());
660  break;
661  case intersection:
662  resultantSolid = new G4IntersectionSolid
663  ("resultant_solid", pSol, fpClippingSolid, theAT.inverse());
664  break;
665  }
666  }
667 
668  if (pSectionSolid) {
669  resultantSolid = new G4IntersectionSolid
670  ("sectioned_solid", pSol, pSectionSolid, theAT.inverse());
671  }
672 
673  if (pCutawaySolid) {
674  resultantSolid = new G4SubtractionSolid
675  ("cutaway_solid", pSol, pCutawaySolid, theAT.inverse());
676  }
677 
678  G4Polyhedron* tmpResultant = resultantSolid->GetPolyhedron();
679  if (tmpResultant) resultant = *tmpResultant;
680  else {
681  if (fpMP->IsWarning())
682  G4cout <<
683  "WARNING: G4PhysicalVolumeModel::DescribeSolid: resultant polyhedron for"
684  "\n solid \"" << pSol->GetName() <<
685  "\" not defined due to error during Boolean processing."
686  "\n Original will be drawn in red."
687  << G4endl;
688  resultantVisAttribs.SetColour(G4Colour::Red());
689  }
690 
691  delete resultantSolid;
692 
693  // Finally, force polyhedron drawing...
694  resultant.SetVisAttributes(resultantVisAttribs);
695  sceneHandler.BeginPrimitives(theAT);
696  sceneHandler.AddPrimitive(resultant);
697  sceneHandler.EndPrimitives();
698  }
699  }
700  sceneHandler.PostAddSolid ();
701 }
702 
704 {
705  G4TransportationManager* transportationManager =
707 
708  size_t nWorlds = transportationManager->GetNoWorlds();
709 
710  G4bool found = false;
711 
712  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
713  transportationManager->GetWorldsIterator();
714  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
715  G4VPhysicalVolume* world = (*iterWorld);
716  // The idea now is to seek a PV with the same name and copy no
717  // in the hope it's the same one!!
718  G4PhysicalVolumeModel searchModel (world);
719  G4int verbosity = 0; // Suppress messages from G4PhysicalVolumeSearchScene.
720  G4PhysicalVolumeSearchScene searchScene
721  (&searchModel, fTopPVName, fTopPVCopyNo, verbosity);
722  G4ModelingParameters mp; // Default modeling parameters for this search.
724  searchModel.SetModelingParameters (&mp);
725  searchModel.DescribeYourselfTo (searchScene);
726  G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
727  if (foundVolume) {
728  if (foundVolume != fpTopPV && warn) {
729  G4cout <<
730  "G4PhysicalVolumeModel::Validate(): A volume of the same name and"
731  "\n copy number (\""
732  << fTopPVName << "\", copy " << fTopPVCopyNo
733  << ") still exists and is being used."
734  "\n But it is not the same volume you originally specified"
735  "\n in /vis/scene/add/."
736  << G4endl;
737  }
738  fpTopPV = foundVolume;
739  CalculateExtent ();
740  found = true;
741  }
742  }
743  if (found) return true;
744  else {
745  if (warn) {
746  G4cout <<
747  "G4PhysicalVolumeModel::Validate(): No volume of name and"
748  "\n copy number (\""
749  << fTopPVName << "\", copy " << fTopPVCopyNo
750  << ") exists."
751  << G4endl;
752  }
753  return false;
754  }
755 }
756 
757 const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
758 {
759  G4bool isNew;
760  std::map<G4String,G4AttDef>* store
761  = G4AttDefStore::GetInstance("G4PhysicalVolumeModel", isNew);
762  if (isNew) {
763  (*store)["PVPath"] =
764  G4AttDef("PVPath","Physical Volume Path","Physics","","G4String");
765  (*store)["LVol"] =
766  G4AttDef("LVol","Logical Volume","Physics","","G4String");
767  (*store)["Solid"] =
768  G4AttDef("Solid","Solid Name","Physics","","G4String");
769  (*store)["EType"] =
770  G4AttDef("EType","Entity Type","Physics","","G4String");
771  (*store)["DmpSol"] =
772  G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
773  (*store)["Trans"] =
774  G4AttDef("Trans","Transformation of volume","Physics","","G4String");
775  (*store)["Material"] =
776  G4AttDef("Material","Material Name","Physics","","G4String");
777  (*store)["Density"] =
778  G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
779  (*store)["State"] =
780  G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
781  (*store)["Radlen"] =
782  G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
783  (*store)["Region"] =
784  G4AttDef("Region","Cuts Region","Physics","","G4String");
785  (*store)["RootRegion"] =
786  G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
787  }
788  return store;
789 }
790 
791 #include <iomanip>
792 
793 static std::ostream& operator<< (std::ostream& o, const G4Transform3D t)
794 {
795  using namespace std;
796 
797  G4Scale3D sc;
798  G4Rotate3D r;
799  G4Translate3D tl;
800  t.getDecomposition(sc, r, tl);
801 
802  const int w = 10;
803 
804  // Transformation itself
805  o << setw(w) << t.xx() << setw(w) << t.xy() << setw(w) << t.xz() << setw(w) << t.dx() << endl;
806  o << setw(w) << t.yx() << setw(w) << t.yy() << setw(w) << t.yz() << setw(w) << t.dy() << endl;
807  o << setw(w) << t.zx() << setw(w) << t.zy() << setw(w) << t.zz() << setw(w) << t.dz() << endl;
808 
809  // Translation
810  o << "= translation:" << endl;
811  o << setw(w) << tl.dx() << setw(w) << tl.dy() << setw(w) << tl.dz() << endl;
812 
813  // Rotation
814  o << "* rotation:" << endl;
815  o << setw(w) << r.xx() << setw(w) << r.xy() << setw(w) << r.xz() << endl;
816  o << setw(w) << r.yx() << setw(w) << r.yy() << setw(w) << r.yz() << endl;
817  o << setw(w) << r.zx() << setw(w) << r.zy() << setw(w) << r.zz() << endl;
818 
819  // Scale
820  o << "* scale:" << endl;
821  o << setw(w) << sc.xx() << setw(w) << sc.yy() << setw(w) << sc.zz() << endl;
822 
823  // Transformed axes
824  o << "Transformed axes:" << endl;
825  o << "x': " << r * G4Vector3D(1., 0., 0.) << endl;
826  o << "y': " << r * G4Vector3D(0., 1., 0.) << endl;
827  o << "z': " << r * G4Vector3D(0., 0., 1.) << endl;
828 
829  return o;
830 }
831 
832 std::vector<G4AttValue>* G4PhysicalVolumeModel::CreateCurrentAttValues() const
833 {
834  std::vector<G4AttValue>* values = new std::vector<G4AttValue>;
835  std::ostringstream oss;
836  for (size_t i = 0; i < fFullPVPath.size(); ++i) {
837  oss << fFullPVPath[i].GetPhysicalVolume()->GetName()
838  << ':' << fFullPVPath[i].GetCopyNo();
839  if (i != fFullPVPath.size() - 1) oss << '/';
840  }
841 
842  if (!fpCurrentLV) {
844  ("G4PhysicalVolumeModel::CreateCurrentAttValues",
845  "modeling0004",
846  JustWarning,
847  "Current logical volume not defined.");
848  return values;
849  }
850 
851  values->push_back(G4AttValue("PVPath", oss.str(),""));
852  values->push_back(G4AttValue("LVol", fpCurrentLV->GetName(),""));
853  G4VSolid* pSol = fpCurrentLV->GetSolid();
854  values->push_back(G4AttValue("Solid", pSol->GetName(),""));
855  values->push_back(G4AttValue("EType", pSol->GetEntityType(),""));
856  oss.str(""); oss << '\n' << *pSol;
857  values->push_back(G4AttValue("DmpSol", oss.str(),""));
858  oss.str(""); oss << '\n' << *fpCurrentTransform;
859  values->push_back(G4AttValue("Trans", oss.str(),""));
860  G4String matName = fpCurrentMaterial? fpCurrentMaterial->GetName(): G4String("No material");
861  values->push_back(G4AttValue("Material", matName,""));
863  values->push_back(G4AttValue("Density", G4BestUnit(matDensity,"Volumic Mass"),""));
865  oss.str(""); oss << matState;
866  values->push_back(G4AttValue("State", oss.str(),""));
868  values->push_back(G4AttValue("Radlen", G4BestUnit(matRadlen,"Length"),""));
869  G4Region* region = fpCurrentLV->GetRegion();
870  G4String regionName = region? region->GetName(): G4String("No region");
871  values->push_back(G4AttValue("Region", regionName,""));
872  oss.str(""); oss << fpCurrentLV->IsRootRegion();
873  values->push_back(G4AttValue("RootRegion", oss.str(),""));
874  return values;
875 }
876 
877 G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator<
879 {
880  if (fpPV < right.fpPV) return true;
881  if (fpPV == right.fpPV) {
882  if (fCopyNo < right.fCopyNo) return true;
883  if (fCopyNo == right.fCopyNo)
884  return fNonCulledDepth < right.fNonCulledDepth;
885  }
886  return false;
887 }
888 
889 std::ostream& operator<<
890  (std::ostream& os, const G4PhysicalVolumeModel::G4PhysicalVolumeNodeID node)
891 {
892  G4VPhysicalVolume* pPV = node.GetPhysicalVolume();
893  if (pPV) {
894  os << pPV->GetName()
895  << ':' << node.GetCopyNo()
896  << '[' << node.GetNonCulledDepth() << ']'
897  << ':' << node.GetTransform();
898  if (!node.GetDrawn()) os << " Not "; os << "drawn";
899  } else {
900  os << "Null node";
901  }
902  return os;
903 }
904 
906 (const std::vector<G4PhysicalVolumeNodeID>& fullPVPath):
907  fFullPVPath(fullPVPath) {}
908 
910 {
911  size_t i = fFullPVPath.size() - depth - 1;
912  if (i >= fFullPVPath.size()) {
913  G4Exception("G4PhysicalVolumeModelTouchable::GetTranslation",
914  "modeling0005",
916  "Index out of range. Asking for non-existent depth");
917  }
918  static G4ThreeVector tempTranslation;
919  tempTranslation = fFullPVPath[i].GetTransform().getTranslation();
920  return tempTranslation;
921 }
922 
924 {
925  size_t i = fFullPVPath.size() - depth - 1;
926  if (i >= fFullPVPath.size()) {
927  G4Exception("G4PhysicalVolumeModelTouchable::GetRotation",
928  "modeling0006",
930  "Index out of range. Asking for non-existent depth");
931  }
932  static G4RotationMatrix tempRotation;
933  tempRotation = fFullPVPath[i].GetTransform().getRotation();
934  return &tempRotation;
935 }
936 
938 {
939  size_t i = fFullPVPath.size() - depth - 1;
940  if (i >= fFullPVPath.size()) {
941  G4Exception("G4PhysicalVolumeModelTouchable::GetVolume",
942  "modeling0007",
944  "Index out of range. Asking for non-existent depth");
945  }
946  return fFullPVPath[i].GetPhysicalVolume();
947 }
948 
950 {
951  size_t i = fFullPVPath.size() - depth - 1;
952  if (i >= fFullPVPath.size()) {
953  G4Exception("G4PhysicalVolumeModelTouchable::GetSolid",
954  "modeling0008",
956  "Index out of range. Asking for non-existent depth");
957  }
958  return fFullPVPath[i].GetPhysicalVolume()->GetLogicalVolume()->GetSolid();
959 }
960 
962 {
963  size_t i = fFullPVPath.size() - depth - 1;
964  if (i >= fFullPVPath.size()) {
965  G4Exception("G4PhysicalVolumeModelTouchable::GetReplicaNumber",
966  "modeling0009",
968  "Index out of range. Asking for non-existent depth");
969  }
970  return fFullPVPath[i].GetCopyNo();
971 }
virtual void PostAddSolid()=0
virtual G4Polyhedron * GetPolyhedron() const
Definition: G4VSolid.cc:644
Definition: geomdefs.hh:54
G4bool IsForceAuxEdgeVisible() const
G4String GetName() const
G4Transform3D fTransform
Definition: G4VModel.hh:112
double yy() const
Definition: Transform3D.h:264
void SetColour(const G4Colour &)
const G4String & GetName() const
G4double GetAlpha() const
Definition: G4Colour.hh:142
void SetForceWireframe(G4bool)
const std::map< G4String, G4AttDef > * GetAttDefs() const
G4String GetName() const
CLHEP::Hep3Vector G4ThreeVector
const G4VisAttributes * GetDefaultVisAttributes() const
G4double GetLineWidth() const
std::vector< G4VPhysicalVolume * >::iterator GetWorldsIterator()
G4State
Definition: G4Material.hh:114
double yx() const
Definition: Transform3D.h:261
void getDecomposition(Scale3D &scale, Rotate3D &rotation, Translate3D &translation) const
Definition: Transform3D.cc:174
const G4String & GetName() const
Definition: G4Material.hh:176
void SetLineStyle(LineStyle)
void SetLineWidth(G4double)
void SetVisibility(G4bool)
Definition: G4Tubs.hh:84
const G4ThreeVector & GetTranslation(G4int depth) const
G4double GetDensity() const
Definition: G4Material.hh:178
G4bool IsVisible() const
const G4Colour & GetColour() const
virtual void BeginPrimitives(const G4Transform3D &objectTransformation=G4Transform3D())=0
Transform3D inverse() const
Definition: Transform3D.cc:142
#define width
double dx() const
Definition: Transform3D.h:279
HepGeom::Vector3D< G4double > G4Vector3D
Definition: G4Vector3D.hh:35
G4bool Validate(G4bool warn)
const G4Point3D & GetCentre() const
#define G4BestUnit(a, b)
#define G4_USE_G4BESTUNIT_FOR_VERBOSE 1
G4Region * GetRegion() const
G4Transform3D * fpCurrentTransform
void SetForceSolid(G4bool)
double zz() const
Definition: Transform3D.h:276
virtual G4GeometryType GetEntityType() const =0
const G4VisExtent & GetExtent() const
int G4int
Definition: G4Types.hh:78
void SetModelingParameters(const G4ModelingParameters *)
G4VPhysicalVolume * fpCurrentPV
LineStyle GetLineStyle() const
G4String fGlobalTag
Definition: G4VModel.hh:109
virtual void AddPrimitive(const G4Polyline &)=0
std::vector< G4PhysicalVolumeNodeID > fFullPVPath
double xz() const
Definition: Transform3D.h:258
G4double density
Definition: TRTMaterials.hh:39
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
G4bool IsDaughtersInvisible() const
bool G4bool
Definition: G4Types.hh:79
G4bool IsRootRegion() const
const G4VisAttributes * GetVisAttributes() const
const G4ModelingParameters * fpMP
Definition: G4VModel.hh:113
G4String GetCurrentDescription() const
const G4int n
virtual void DescribeSolid(const G4Transform3D &theAT, G4VSolid *pSol, const G4VisAttributes *pVisAttribs, G4VGraphicsScene &sceneHandler)
double xy() const
Definition: Transform3D.h:255
G4double GetRadlen() const
Definition: G4Material.hh:218
double dy() const
Definition: Transform3D.h:282
G4int GetNoDaughters() const
void SetForceAuxEdgeVisible(G4bool)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
void SetVisAttributes(const G4VisAttributes *)
Definition: G4Visible.cc:80
static G4TransportationManager * GetTransportationManager()
G4int GetForcedLineSegmentsPerCircle() const
G4VPhysicalVolume * fpTopPV
G4PhysicalVolumeModelTouchable(const std::vector< G4PhysicalVolumeNodeID > &fullPVPath)
std::vector< PVNameCopyNo > PVNameCopyNoPath
double yz() const
Definition: Transform3D.h:267
double dz() const
Definition: Transform3D.h:285
std::vector< G4AttValue > * CreateCurrentAttValues() const
EAxis
Definition: geomdefs.hh:54
G4bool IsForceDrawingStyle() const
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &visAttribs)=0
G4VPhysicalVolume * GetFoundVolume() const
std::ostream & operator<<(std::ostream &, const BasicVector3D< float > &)
double xx() const
Definition: Transform3D.h:252
HepGeom::Translate3D G4Translate3D
HepRotation & rotateZ(double delta)
Definition: Rotation.cc:92
G4String GetCurrentTag() const
size_t GetNoWorlds() const
#define G4endl
Definition: G4ios.hh:61
static G4Colour Red()
Definition: G4Colour.hh:148
G4PhysicalVolumeModel(G4VPhysicalVolume *=0, G4int requestedDepth=UNLIMITED, const G4Transform3D &modelTransformation=G4Transform3D(), const G4ModelingParameters *=0, G4bool useFullExtent=false)
virtual void EndPrimitives()=0
static void SetNumberOfRotationSteps(G4int n)
G4State GetState() const
Definition: G4Material.hh:179
std::map< G4String, G4AttDef > * GetInstance(const G4String &storeKey, G4bool &isNew)
G4VisExtent fExtent
Definition: G4VModel.hh:111
double G4double
Definition: G4Types.hh:76
void VisitGeometryAndGetVisReps(G4VPhysicalVolume *, G4int requestedDepth, const G4Transform3D &, G4VGraphicsScene &)
Definition: geomdefs.hh:54
void SetDefaultVisAttributes(const G4VisAttributes *pDefaultVisAttributes)
G4bool IsForceLineSegmentsPerCircle() const
double zy() const
Definition: Transform3D.h:273
void SetDaughtersInvisible(G4bool)
void DescribeAndDescend(G4VPhysicalVolume *, G4int requestedDepth, G4LogicalVolume *, G4VSolid *, G4Material *, const G4Transform3D &, G4VGraphicsScene &)
ForcedDrawingStyle GetForcedDrawingStyle() const
PVNameCopyNoPath::const_iterator PVNameCopyNoPathConstIterator
G4VSolid * GetSolid() const
double zx() const
Definition: Transform3D.h:270
const G4RotationMatrix * GetRotation(G4int depth) const
void SetForceLineSegmentsPerCircle(G4int nSegments)
static void ResetNumberOfRotationSteps()
void DescribeYourselfTo(G4VGraphicsScene &)