source: tags/Visualization_after-vis09-02-01-tag/modeling/src/G4PhysicalVolumeModel.cc @ 958

Last change on this file since 958 was 958, checked in by garnier, 15 years ago

tag

File size: 27.2 KB
Line 
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,v 1.63 2007/11/10 14:56:36 allison Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// John Allison  31st December 1997.
32// Model for physical volumes.
33
34#include "G4PhysicalVolumeModel.hh"
35
36#include "G4ModelingParameters.hh"
37#include "G4VGraphicsScene.hh"
38#include "G4VPhysicalVolume.hh"
39#include "G4VPVParameterisation.hh"
40#include "G4LogicalVolume.hh"
41#include "G4VSolid.hh"
42#include "G4Material.hh"
43#include "G4VisAttributes.hh"
44#include "G4BoundingSphereScene.hh"
45#include "G4PhysicalVolumeSearchScene.hh"
46#include "G4TransportationManager.hh"
47#include "G4Polyhedron.hh"
48#include "G4AttDefStore.hh"
49#include "G4AttDef.hh"
50#include "G4AttValue.hh"
51#include "G4UnitsTable.hh"
52#include "G4Vector3D.hh"
53
54#include <sstream>
55
56G4bool G4PhysicalVolumeModel::G4PhysicalVolumeNodeID::operator<
57  (const G4PhysicalVolumeModel::G4PhysicalVolumeNodeID& right) const
58{
59  if (fpPV < right.fpPV) return true;
60  if (fpPV == right.fpPV) {
61    if (fCopyNo < right.fCopyNo) return true;
62    if (fCopyNo == right.fCopyNo)
63      return fNonCulledDepth < right.fNonCulledDepth;
64  }
65  return false;
66}
67
68std::ostream& operator<<
69  (std::ostream& os, const G4PhysicalVolumeModel::G4PhysicalVolumeNodeID node)
70{
71  G4VPhysicalVolume* pPV = node.GetPhysicalVolume();
72  if (pPV) {
73    os << pPV->GetName()
74       << ':' << node.GetCopyNo()
75       << '[' << node.GetNonCulledDepth() << ']';
76  } else {
77    os << "Null node";
78  }
79  return os;
80}
81
82G4PhysicalVolumeModel::G4PhysicalVolumeModel
83(G4VPhysicalVolume*          pVPV,
84 G4int                       requestedDepth,
85 const G4Transform3D& modelTransformation,
86 const G4ModelingParameters* pMP,
87 G4bool useFullExtent):
88  G4VModel        (modelTransformation, pMP),
89  fpTopPV         (pVPV),
90  fTopPVName      (pVPV -> GetName ()),
91  fTopPVCopyNo    (pVPV -> GetCopyNo ()),
92  fRequestedDepth (requestedDepth),
93  fUseFullExtent  (useFullExtent),
94  fCurrentDepth   (0),
95  fpCurrentPV     (0),
96  fpCurrentLV     (0),
97  fpCurrentMaterial (0),
98  fpCurrentTransform (0),
99  fCurtailDescent (false),
100  fpClippingPolyhedron (0),
101  fClippingMode   (subtraction)
102{
103  std::ostringstream o;
104  o << fpTopPV -> GetCopyNo ();
105  fGlobalTag = fpTopPV -> GetName () + "." + o.str();
106  fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
107
108  CalculateExtent ();
109}
110
111G4PhysicalVolumeModel::~G4PhysicalVolumeModel ()
112{
113  delete fpClippingPolyhedron;
114}
115
116void G4PhysicalVolumeModel::CalculateExtent ()
117{
118  if (fUseFullExtent) {
119    fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
120  }
121  else {
122    G4BoundingSphereScene bsScene(this);
123    const G4int tempRequestedDepth = fRequestedDepth;
124    fRequestedDepth = -1;  // Always search to all depths to define extent.
125    const G4ModelingParameters* tempMP = fpMP;
126    G4ModelingParameters mParams
127      (0,      // No default vis attributes needed.
128       G4ModelingParameters::wf,  // wireframe (not relevant for this).
129       true,   // Global culling.
130       true,   // Cull invisible volumes.
131       false,  // Density culling.
132       0.,     // Density (not relevant if density culling false).
133       true,   // Cull daughters of opaque mothers.
134       24);    // No of sides (not relevant for this operation).
135    fpMP = &mParams;
136    DescribeYourselfTo (bsScene);
137    G4double radius = bsScene.GetRadius();
138    if (radius < 0.) {  // Nothing in the scene.
139      fExtent = fpTopPV -> GetLogicalVolume () -> GetSolid () -> GetExtent ();
140    } else {
141      // Transform back to coordinates relative to the top
142      // transformation, which is in G4VModel::fTransform.  This makes
143      // it conform to all models, which are defined by a
144      // transformation and an extent relative to that
145      // transformation...
146      G4Point3D centre = bsScene.GetCentre();
147      centre.transform(fTransform.inverse());
148      fExtent = G4VisExtent(centre, radius);
149    }
150    fpMP = tempMP;
151    fRequestedDepth = tempRequestedDepth;
152  }
153}
154
155void G4PhysicalVolumeModel::DescribeYourselfTo
156(G4VGraphicsScene& sceneHandler)
157{
158  if (!fpMP) G4Exception
159    ("G4PhysicalVolumeModel::DescribeYourselfTo: No modeling parameters.");
160
161  // For safety...
162  fCurrentDepth = 0;
163
164  G4Transform3D startingTransformation = fTransform;
165
166  VisitGeometryAndGetVisReps
167    (fpTopPV,
168     fRequestedDepth,
169     startingTransformation,
170     sceneHandler);
171
172  // Clear data...
173  fCurrentDepth     = 0;
174  fpCurrentPV       = 0;
175  fpCurrentLV       = 0;
176  fpCurrentMaterial = 0;
177  fFullPVPath.clear();
178  fDrawnPVPath.clear();
179}
180
181G4String G4PhysicalVolumeModel::GetCurrentTag () const
182{
183  if (fpCurrentPV) {
184    std::ostringstream o;
185    o << fpCurrentPV -> GetCopyNo ();
186    return fpCurrentPV -> GetName () + "." + o.str();
187  }
188  else {
189    return "WARNING: NO CURRENT VOLUME - global tag is " + fGlobalTag;
190  }
191}
192
193G4String G4PhysicalVolumeModel::GetCurrentDescription () const
194{
195  return "G4PhysicalVolumeModel " + GetCurrentTag ();
196}
197
198void G4PhysicalVolumeModel::VisitGeometryAndGetVisReps
199(G4VPhysicalVolume* pVPV,
200 G4int requestedDepth,
201 const G4Transform3D& theAT,
202 G4VGraphicsScene& sceneHandler)
203{
204  // Visits geometry structure to a given depth (requestedDepth), starting
205  //   at given physical volume with given starting transformation and
206  //   describes volumes to the scene handler.
207  // requestedDepth < 0 (default) implies full visit.
208  // theAT is the Accumulated Transformation.
209
210  // Find corresponding logical volume and (later) solid, storing in
211  // local variables to preserve re-entrancy.
212  G4LogicalVolume* pLV  = pVPV -> GetLogicalVolume ();
213
214  G4VSolid* pSol;
215  G4Material* pMaterial;
216
217  if (!(pVPV -> IsReplicated ())) {
218    // Non-replicated physical volume.
219    pSol = pLV -> GetSolid ();
220    pMaterial = pLV -> GetMaterial ();
221    DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
222                        theAT, sceneHandler);
223  }
224  else {
225    // Replicated or parametrised physical volume.
226    EAxis axis;
227    G4int nReplicas;
228    G4double width;
229    G4double offset;
230    G4bool consuming;
231    pVPV -> GetReplicationData (axis, nReplicas, width,  offset, consuming);
232    G4VPVParameterisation* pP = pVPV -> GetParameterisation ();
233    if (pP) {  // Parametrised volume.
234      for (int n = 0; n < nReplicas; n++) {
235        pSol = pP -> ComputeSolid (n, pVPV);
236        pMaterial = pP -> ComputeMaterial (n, pVPV);
237        pP -> ComputeTransformation (n, pVPV);
238        pSol -> ComputeDimensions (pP, n, pVPV);
239        pVPV -> SetCopyNo (n);
240        DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
241                            theAT, sceneHandler);
242      }
243    }
244    else {  // Plain replicated volume.  From geometry_guide.txt...
245      // The replica's positions are claculated by means of a linear formula.
246      // Replication may occur along:
247      //
248      // o Cartesian axes (kXAxis,kYAxis,kZAxis)
249      //
250      //   The replications, of specified width have coordinates of
251      //   form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1
252      //   for the case of kXAxis, and are unrotated.
253      //
254      // o Radial axis (cylindrical polar) (kRho)
255      //
256      //   The replications are cons/tubs sections, centred on the origin
257      //   and are unrotated.
258      //   They have radii of width*n+offset to width*(n+1)+offset
259      //                      where n=0..nReplicas-1
260      //
261      // o Phi axis (cylindrical polar) (kPhi)
262      //   The replications are `phi sections' or wedges, and of cons/tubs form
263      //   They have phi of offset+n*width to offset+(n+1)*width where
264      //   n=0..nReplicas-1
265      //
266      pSol = pLV -> GetSolid ();
267      pMaterial = pLV -> GetMaterial ();
268      G4ThreeVector originalTranslation = pVPV -> GetTranslation ();
269      G4RotationMatrix* pOriginalRotation = pVPV -> GetRotation ();
270      G4double originalRMin = 0., originalRMax = 0.;
271      if (axis == kRho && pSol->GetEntityType() == "G4Tubs") {
272        originalRMin = ((G4Tubs*)pSol)->GetInnerRadius();
273        originalRMax = ((G4Tubs*)pSol)->GetOuterRadius();
274      }
275      G4bool visualisable = true;
276      for (int n = 0; n < nReplicas; n++) {
277        G4ThreeVector translation;  // Null.
278        G4RotationMatrix rotation;  // Null - life long enough for visualizing.
279        G4RotationMatrix* pRotation = 0;
280        switch (axis) {
281        default:
282        case kXAxis:
283          translation = G4ThreeVector (-width*(nReplicas-1)*0.5+n*width,0,0);
284          break;
285        case kYAxis:
286          translation = G4ThreeVector (0,-width*(nReplicas-1)*0.5+n*width,0);
287          break;
288        case kZAxis:
289          translation = G4ThreeVector (0,0,-width*(nReplicas-1)*0.5+n*width);
290          break;
291        case kRho:
292          if (pSol->GetEntityType() == "G4Tubs") {
293            ((G4Tubs*)pSol)->SetInnerRadius(width*n+offset);
294            ((G4Tubs*)pSol)->SetOuterRadius(width*(n+1)+offset);
295          } else {
296            if (fpMP->IsWarning())
297              G4cout <<
298                "G4PhysicalVolumeModel::VisitGeometryAndGetVisReps: WARNING:"
299                "\n  built-in replicated volumes replicated in radius for "
300                     << pSol->GetEntityType() <<
301                "-type\n  solids (your solid \""
302                     << pSol->GetName() <<
303                "\") are not visualisable."
304                     << G4endl;
305            visualisable = false;
306          }
307          break;
308        case kPhi:
309          rotation.rotateZ (-(offset+(n+0.5)*width));
310          // Minus Sign because for the physical volume we need the
311          // coordinate system rotation.
312          pRotation = &rotation;
313          break;
314        } 
315        pVPV -> SetTranslation (translation);
316        pVPV -> SetRotation    (pRotation);
317        pVPV -> SetCopyNo (n);
318        if (visualisable) {
319          DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
320                            theAT, sceneHandler);
321        }
322      }
323      // Restore originals...
324      pVPV -> SetTranslation (originalTranslation);
325      pVPV -> SetRotation    (pOriginalRotation);
326      if (axis == kRho && pSol->GetEntityType() == "G4Tubs") {
327        ((G4Tubs*)pSol)->SetInnerRadius(originalRMin);
328        ((G4Tubs*)pSol)->SetOuterRadius(originalRMax);
329      }
330    }
331  }
332
333  return;
334}
335
336void G4PhysicalVolumeModel::DescribeAndDescend
337(G4VPhysicalVolume* pVPV,
338 G4int requestedDepth,
339 G4LogicalVolume* pLV,
340 G4VSolid* pSol,
341 G4Material* pMaterial,
342 const G4Transform3D& theAT,
343 G4VGraphicsScene& sceneHandler)
344{
345  // Maintain useful data members...
346  fpCurrentPV = pVPV;
347  fpCurrentLV = pLV;
348  fpCurrentMaterial = pMaterial;
349
350  const G4RotationMatrix objectRotation = pVPV -> GetObjectRotationValue ();
351  const G4ThreeVector&  translation     = pVPV -> GetTranslation ();
352  G4Transform3D theLT (G4Transform3D (objectRotation, translation));
353
354  // Compute the accumulated transformation...
355  // Note that top volume's transformation relative to the world
356  // coordinate system is specified in theAT == startingTransformation
357  // = fTransform (see DescribeYourselfTo), so first time through the
358  // volume's own transformation, which is only relative to its
359  // mother, i.e., not relative to the world coordinate system, should
360  // not be accumulated.
361  G4Transform3D theNewAT (theAT);
362  if (fCurrentDepth != 0) theNewAT = theAT * theLT;
363  fpCurrentTransform = &theNewAT;
364
365  /********************************************************
366  G4cout << "G4PhysicalVolumeModel::DescribeAndDescend: "
367         << pVPV -> GetName () << "." << pVPV -> GetCopyNo ();
368  G4cout << "\n  theAT: ";
369  G4cout << "\n    Rotation: ";
370  G4RotationMatrix rotation = theAT.getRotation ();
371  G4cout << rotation.thetaX() << ", "
372         << rotation.phiX() << ", "
373         << rotation.thetaY() << ", "
374         << rotation.phiY() << ", "
375         << rotation.thetaZ() << ", "
376         << rotation.phiZ();
377  G4cout << "\n    Translation: " << theAT.getTranslation();
378  G4cout << "\n  theNewAT: ";
379  G4cout << "\n    Rotation: ";
380  rotation = theNewAT.getRotation ();
381  G4cout << rotation.thetaX() << ", "
382         << rotation.phiX() << ", "
383         << rotation.thetaY() << ", "
384         << rotation.phiY() << ", "
385         << rotation.thetaZ() << ", "
386         << rotation.phiZ();
387  G4cout << "\n    Translation: " << theNewAT.getTranslation();
388  G4cout << G4endl;
389  **********************************************************/
390
391  // Make decision to draw...
392  const G4VisAttributes* pVisAttribs = pLV->GetVisAttributes();
393  if (!pVisAttribs) pVisAttribs = fpMP->GetDefaultVisAttributes();
394  // Beware - pVisAttribs might still be zero - create a temporary default one...
395  G4bool visAttsCreated = false;
396  if (!pVisAttribs) {
397    pVisAttribs = new G4VisAttributes;
398    visAttsCreated = true;
399  }
400
401  // From here, can assume pVisAttribs is a valid pointer.
402
403  G4bool thisToBeDrawn = true;
404
405  // There are various reasons why this volume
406  // might not be drawn...
407  G4bool culling = fpMP->IsCulling();
408  G4bool cullingInvisible = fpMP->IsCullingInvisible();
409  G4bool markedVisible = pVisAttribs->IsVisible();
410  G4bool cullingLowDensity = fpMP->IsDensityCulling();
411  G4double density = pMaterial? pMaterial->GetDensity(): 0;
412  G4double densityCut = fpMP -> GetVisibleDensity ();
413
414  // 1) Global culling is on....
415  if (culling) {
416    // 2) Culling of invisible volumes is on...
417    if (cullingInvisible) {
418      // 3) ...and the volume is marked not visible...
419      if (!markedVisible) thisToBeDrawn = false;
420    }
421    // 4) Or culling of low density volumes is on...
422    if (cullingLowDensity) {
423      // 5) ...and density is less than cut value...
424      if (density < densityCut) thisToBeDrawn = false;
425    }
426  }
427
428  // Update full path of physical volumes...
429  G4int copyNo = fpCurrentPV->GetCopyNo();
430  fFullPVPath.push_back
431    (G4PhysicalVolumeNodeID(fpCurrentPV,copyNo,fCurrentDepth));
432
433  if (thisToBeDrawn) {
434
435    // Update path of drawn physical volumes...
436    G4int copyNo = fpCurrentPV->GetCopyNo();
437    fDrawnPVPath.push_back
438      (G4PhysicalVolumeNodeID(fpCurrentPV,copyNo,fCurrentDepth));
439
440    if (fpMP->IsExplode() && fDrawnPVPath.size() == 1) {
441      // For top-level drawn volumes, explode along radius...
442      G4Transform3D centering = G4Translate3D(fpMP->GetExplodeCentre());
443      G4Transform3D centred = centering.inverse() * theNewAT;
444      G4Scale3D scale;
445      G4Rotate3D rotation;
446      G4Translate3D translation;
447      centred.getDecomposition(scale, rotation, translation);
448      G4double explodeFactor = fpMP->GetExplodeFactor();
449      G4Translate3D newTranslation =
450        G4Translate3D(explodeFactor * translation.dx(),
451                      explodeFactor * translation.dy(),
452                      explodeFactor * translation.dz());
453      theNewAT = centering * newTranslation * rotation * scale;
454    }
455
456    DescribeSolid (theNewAT, pSol, pVisAttribs, sceneHandler);
457
458  }
459
460  // Make decision to draw daughters, if any.  There are various
461  // reasons why daughters might not be drawn...
462
463  // First, reasons that do not depend on culling policy...
464  G4int nDaughters = pLV->GetNoDaughters();
465  G4bool daughtersToBeDrawn = true;
466  // 1) There are no daughters...
467  if (!nDaughters) daughtersToBeDrawn = false;
468  // 2) We are at the limit if requested depth...
469  else if (requestedDepth == 0) daughtersToBeDrawn = false;
470  // 3) The user has asked that the descent be curtailed...
471  else if (fCurtailDescent) daughtersToBeDrawn = false;
472
473  // Now, reasons that depend on culling policy...
474  else {
475    G4bool culling = fpMP->IsCulling();
476    G4bool cullingInvisible = fpMP->IsCullingInvisible();
477    G4bool daughtersInvisible = pVisAttribs->IsDaughtersInvisible();
478    // Culling of covered daughters request.  This is computed in
479    // G4VSceneHandler::CreateModelingParameters() depending on view
480    // parameters...
481    G4bool cullingCovered = fpMP->IsCullingCovered();
482    G4bool surfaceDrawing =
483      fpMP->GetDrawingStyle() == G4ModelingParameters::hsr ||
484      fpMP->GetDrawingStyle() == G4ModelingParameters::hlhsr;   
485    if (pVisAttribs->IsForceDrawingStyle()) {
486      switch (pVisAttribs->GetForcedDrawingStyle()) {
487      default:
488      case G4VisAttributes::wireframe: surfaceDrawing = false; break;
489      case G4VisAttributes::solid: surfaceDrawing = true; break;
490      }
491    }
492    G4bool opaque = pVisAttribs->GetColour().GetAlpha() >= 1.;
493    // 4) Global culling is on....
494    if (culling) {
495      // 5) ..and culling of invisible volumes is on...
496      if (cullingInvisible) {
497        // 6) ...and the mother requests daughters invisible
498        if (daughtersInvisible) daughtersToBeDrawn = false;
499      }
500      // 7) Or culling of covered daughters is requested...
501      if (cullingCovered) {
502        // 8) ...and surface drawing is operating...
503        if (surfaceDrawing) {
504          // 9) ...but only if mother is visible...
505          if (thisToBeDrawn) {
506            // 10) ...and opaque...
507              if (opaque) daughtersToBeDrawn = false;
508          }
509        }
510      }
511    }
512  }
513
514  // Vis atts for this volume no longer needed if created...
515  if (visAttsCreated) delete pVisAttribs;
516
517  if (daughtersToBeDrawn) {
518    for (G4int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
519      G4VPhysicalVolume* pVPV = pLV -> GetDaughter (iDaughter);
520      // Descend the geometry structure recursively...
521      fCurrentDepth++;
522      VisitGeometryAndGetVisReps
523        (pVPV, requestedDepth - 1, theNewAT, sceneHandler);
524      fCurrentDepth--;
525    }
526  }
527
528  // Reset for normal descending of next volume at this level...
529  fCurtailDescent = false;
530
531  // Pop item from paths physical volumes...
532  fFullPVPath.pop_back();
533  if (thisToBeDrawn) {
534    fDrawnPVPath.pop_back();
535  }
536}
537
538void G4PhysicalVolumeModel::DescribeSolid
539(const G4Transform3D& theAT,
540 G4VSolid* pSol,
541 const G4VisAttributes* pVisAttribs,
542 G4VGraphicsScene& sceneHandler)
543{
544  sceneHandler.PreAddSolid (theAT, *pVisAttribs);
545
546  const G4Polyhedron* pSectionPolyhedron = fpMP->GetSectionPolyhedron();
547  const G4Polyhedron* pCutawayPolyhedron = fpMP->GetCutawayPolyhedron();
548
549  if (!fpClippingPolyhedron && !pSectionPolyhedron && !pCutawayPolyhedron) {
550
551    pSol -> DescribeYourselfTo (sceneHandler);  // Standard treatment.
552
553  } else {
554
555    // Clipping, etc., performed by Boolean operations on polyhedron objects.
556
557    // First, get polyhedron for current solid...
558    if (pVisAttribs->IsForceLineSegmentsPerCircle())
559      G4Polyhedron::SetNumberOfRotationSteps
560        (pVisAttribs->GetForcedLineSegmentsPerCircle());
561    else
562      G4Polyhedron::SetNumberOfRotationSteps(fpMP->GetNoOfSides());
563    G4Polyhedron* pOriginal = pSol->GetPolyhedron();
564    G4Polyhedron::ResetNumberOfRotationSteps();
565    if (!pOriginal) {
566        if (fpMP->IsWarning())
567          G4cout <<
568 "WARNING: G4PhysicalVolumeModel::DescribeSolid: solid\n  \""
569                 << pSol->GetName() <<
570 "\" has no polyhedron.  Cannot by clipped."
571                 << G4endl;
572        pSol -> DescribeYourselfTo (sceneHandler);  // Standard treatment.
573    } else {
574
575      G4Polyhedron resultant = *pOriginal;
576
577      if (fpClippingPolyhedron) {
578        G4Polyhedron clipper = *fpClippingPolyhedron;  // Local copy.
579        clipper.Transform(theAT.inverse());
580        switch (fClippingMode) {
581        default:
582        case subtraction: resultant = resultant.subtract(clipper); break;
583        case intersection: resultant = resultant.intersect(clipper); break;
584        }
585        if(resultant.IsErrorBooleanProcess()) {
586          if (fpMP->IsWarning())
587            G4cout <<
588 "WARNING: G4PhysicalVolumeModel::DescribeSolid: clipped polyhedron for"
589 "\n  solid \"" << pSol->GetName() <<
590 "\" not defined due to error during Boolean processing."
591                   << G4endl;
592          // Nevertheless, keep resultant.
593        }
594      }
595
596      if (pSectionPolyhedron) {
597        G4Polyhedron sectioner = *pSectionPolyhedron;  // Local copy.
598        sectioner.Transform(theAT.inverse());
599        resultant = resultant.intersect(sectioner);
600        if(resultant.IsErrorBooleanProcess()) {
601          if (fpMP->IsWarning())
602            G4cout <<
603 "WARNING: G4PhysicalVolumeModel::DescribeSolid: sectioned polyhedron for"
604 "\n  solid \"" << pSol->GetName() <<
605 "\" not defined due to error during Boolean processing."
606                   << G4endl;
607          // Nevertheless, keep resultant.
608        }
609      }
610
611      if (pCutawayPolyhedron) {
612        G4Polyhedron cutter = *pCutawayPolyhedron;  // Local copy.
613        cutter.Transform(theAT.inverse());
614        resultant = resultant.subtract(cutter);
615        if(resultant.IsErrorBooleanProcess()) {
616          if (fpMP->IsWarning())
617            G4cout <<
618 "WARNING: G4PhysicalVolumeModel::DescribeSolid: cutaway polyhedron for"
619 "\n  solid \"" << pSol->GetName() <<
620 "\" not defined due to error during Boolean processing."
621                   << G4endl;
622          // Nevertheless, keep resultant.
623        }
624      }
625
626      // Finally, force polyhedron drawing...
627      resultant.SetVisAttributes(pVisAttribs);
628      sceneHandler.BeginPrimitives(theAT);
629      sceneHandler.AddPrimitive(resultant);
630      sceneHandler.EndPrimitives();
631    }
632  }
633  sceneHandler.PostAddSolid ();
634}
635
636G4bool G4PhysicalVolumeModel::Validate (G4bool warn)
637{
638  G4VPhysicalVolume* world =
639    G4TransportationManager::GetTransportationManager ()
640    -> GetNavigatorForTracking () -> GetWorldVolume ();
641  // The idea now is to seek a PV with the same name and copy no
642  // in the hope it's the same one!!
643  if (warn) {
644    G4cout << "G4PhysicalVolumeModel::Validate() called." << G4endl;
645  }
646  G4PhysicalVolumeModel searchModel (world);
647  G4PhysicalVolumeSearchScene searchScene
648    (&searchModel, fTopPVName, fTopPVCopyNo);
649  G4ModelingParameters mp;  // Default modeling parameters for this search.
650  mp.SetDefaultVisAttributes(fpMP? fpMP->GetDefaultVisAttributes(): 0);
651  searchModel.SetModelingParameters (&mp);
652  searchModel.DescribeYourselfTo (searchScene);
653  G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
654  if (foundVolume) {
655    if (warn) {
656      G4cout << "  Volume of the same name and copy number (\""
657             << fTopPVName << "\", copy " << fTopPVCopyNo
658             << ") still exists and is being used."
659        "\n  WARNING: This does not necessarily guarantee it's the same"
660        "\n  volume you originally specified in /vis/scene/add/."
661             << G4endl;
662    }
663    fpTopPV = foundVolume;
664    CalculateExtent ();
665    return true;
666  }
667  else {
668    if (warn) {
669      G4cout << "  A volume of the same name and copy number (\""
670             << fTopPVName << "\", copy " << fTopPVCopyNo
671             << ") no longer exists."
672             << G4endl;
673    }
674    return false;
675  }
676}
677
678const std::map<G4String,G4AttDef>* G4PhysicalVolumeModel::GetAttDefs() const
679{
680    G4bool isNew;
681    std::map<G4String,G4AttDef>* store
682      = G4AttDefStore::GetInstance("G4PhysicalVolumeModel", isNew);
683    if (isNew) {
684      (*store)["PVPath"] =
685        G4AttDef("PVPath","Physical Volume Path","Physics","","G4String");
686      (*store)["LVol"] =
687        G4AttDef("LVol","Logical Volume","Physics","","G4String");
688      (*store)["Solid"] =
689        G4AttDef("Solid","Solid Name","Physics","","G4String");
690      (*store)["EType"] =
691        G4AttDef("EType","Entity Type","Physics","","G4String");
692      (*store)["DmpSol"] =
693        G4AttDef("DmpSol","Dump of Solid properties","Physics","","G4String");
694      (*store)["Trans"] =
695        G4AttDef("Trans","Transformation of volume","Physics","","G4String");
696      (*store)["Material"] =
697        G4AttDef("Material","Material Name","Physics","","G4String");
698      (*store)["Density"] =
699        G4AttDef("Density","Material Density","Physics","G4BestUnit","G4double");
700      (*store)["State"] =
701        G4AttDef("State","Material State (enum undefined,solid,liquid,gas)","Physics","","G4String");
702      (*store)["Radlen"] =
703        G4AttDef("Radlen","Material Radiation Length","Physics","G4BestUnit","G4double");
704    }
705      (*store)["Region"] =
706        G4AttDef("Region","Cuts Region","Physics","","G4String");
707      (*store)["RootRegion"] =
708        G4AttDef("RootRegion","Root Region (0/1 = false/true)","Physics","","G4bool");
709    return store;
710}
711
712#include <iomanip>
713
714static std::ostream& operator<< (std::ostream& o, const G4Transform3D t)
715{
716  using namespace std;
717
718  G4Scale3D s;
719  G4Rotate3D r;
720  G4Translate3D tl;
721  t.getDecomposition(s, r, tl);
722
723  const int w = 10;
724
725  // Transformation itself
726  o << setw(w) << t.xx() << setw(w) << t.xy() << setw(w) << t.xz() << setw(w) << t.dx() << endl;
727  o << setw(w) << t.yx() << setw(w) << t.yy() << setw(w) << t.yz() << setw(w) << t.dy() << endl;
728  o << setw(w) << t.zx() << setw(w) << t.zy() << setw(w) << t.zz() << setw(w) << t.dz() << endl;
729
730  // Translation
731  o << "= translation:" << endl;
732  o << setw(w) << tl.dx() << setw(w) << tl.dy() << setw(w) << tl.dz() << endl;
733
734  // Rotation
735  o << "* rotation:" << endl;
736  o << setw(w) << r.xx() << setw(w) << r.xy() << setw(w) << r.xz() << endl;
737  o << setw(w) << r.yx() << setw(w) << r.yy() << setw(w) << r.yz() << endl;
738  o << setw(w) << r.zx() << setw(w) << r.zy() << setw(w) << r.zz() << endl;
739
740  // Scale
741  o << "* scale:" << endl;
742  o << setw(w) << s.xx() << setw(w) << s.yy() << setw(w) << s.zz() << endl;
743
744  // Transformed axes
745  o << "Transformed axes:" << endl;
746  o << "x': " << r * G4Vector3D(1., 0., 0.) << endl;
747  o << "y': " << r * G4Vector3D(0., 1., 0.) << endl;
748  o << "z': " << r * G4Vector3D(0., 0., 1.) << endl;
749
750  return o;
751}
752
753std::vector<G4AttValue>* G4PhysicalVolumeModel::CreateCurrentAttValues() const
754{
755  std::vector<G4AttValue>* values = new std::vector<G4AttValue>;
756  std::ostringstream oss;
757  for (size_t i = 0; i < fFullPVPath.size(); ++i) {
758    oss << fFullPVPath[i].GetPhysicalVolume()->GetName()
759        << ':' << fFullPVPath[i].GetCopyNo();
760    if (i != fFullPVPath.size() - 1) oss << '/';
761  }
762  values->push_back(G4AttValue("PVPath", oss.str(),""));
763  values->push_back(G4AttValue("LVol", fpCurrentLV->GetName(),""));
764  G4VSolid* pSol = fpCurrentLV->GetSolid();
765  values->push_back(G4AttValue("Solid", pSol->GetName(),""));
766  values->push_back(G4AttValue("EType", pSol->GetEntityType(),""));
767  oss.str(""); oss << '\n' << *pSol;
768  values->push_back(G4AttValue("DmpSol", oss.str(),""));
769  oss.str(""); oss << '\n' << *fpCurrentTransform;
770  values->push_back(G4AttValue("Trans", oss.str(),""));
771  G4String matName = fpCurrentMaterial? fpCurrentMaterial->GetName(): G4String("No material");
772  values->push_back(G4AttValue("Material", matName,""));
773  G4double matDensity = fpCurrentMaterial? fpCurrentMaterial->GetDensity(): 0.;
774  values->push_back(G4AttValue("Density", G4BestUnit(matDensity,"Volumic Mass"),""));
775  G4State matState = fpCurrentMaterial? fpCurrentMaterial->GetState(): kStateUndefined;
776  oss.str(""); oss << matState;
777  values->push_back(G4AttValue("State", oss.str(),""));
778  G4double matRadlen = fpCurrentMaterial? fpCurrentMaterial->GetRadlen(): 0.;
779  values->push_back(G4AttValue("Radlen", G4BestUnit(matRadlen,"Length"),""));
780  G4Region* region = fpCurrentLV->GetRegion();
781  G4String regionName = region? region->GetName(): G4String("No region");
782  values->push_back(G4AttValue("Region", regionName,""));
783  oss.str(""); oss << fpCurrentLV->IsRootRegion();
784  values->push_back(G4AttValue("RootRegion", oss.str(),""));
785  return values;
786}
Note: See TracBrowser for help on using the repository browser.