source: trunk/source/visualization/management/src/G4VSceneHandler.cc @ 1140

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

update to CVS

  • Property svn:mime-type set to text/cpp
File size: 30.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: G4VSceneHandler.cc,v 1.86 2009/10/23 07:58:36 allison Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// John Allison  19th July 1996
32// Abstract interface class for graphics scenes.
33
34#include "G4VSceneHandler.hh"
35
36#include "G4ios.hh"
37#include <sstream>
38
39#include "G4VisManager.hh"
40#include "G4VGraphicsSystem.hh"
41#include "G4VViewer.hh"
42#include "G4VSolid.hh"
43#include "G4RotationMatrix.hh"
44#include "G4ThreeVector.hh"
45#include "G4VPhysicalVolume.hh"
46#include "G4Material.hh"
47#include "G4Polyline.hh"
48#include "G4Scale.hh"
49#include "G4Text.hh"
50#include "G4Circle.hh"
51#include "G4Square.hh"
52#include "G4Polymarker.hh"
53#include "G4Polyhedron.hh"
54#include "G4NURBS.hh"
55#include "G4Visible.hh"
56#include "G4VisAttributes.hh"
57#include "G4VModel.hh"
58#include "G4TrajectoriesModel.hh"
59#include "G4Box.hh"
60#include "G4Cons.hh"
61#include "G4Tubs.hh"
62#include "G4Trd.hh"
63#include "G4Trap.hh"
64#include "G4Sphere.hh"
65#include "G4Para.hh"
66#include "G4Torus.hh"
67#include "G4Polycone.hh"
68#include "G4Polyhedra.hh"
69#include "G4LogicalVolume.hh"
70#include "G4PhysicalVolumeModel.hh"
71#include "G4ModelingParameters.hh"
72#include "G4VTrajectory.hh"
73#include "G4VTrajectoryPoint.hh"
74#include "G4HitsModel.hh"
75#include "G4VHit.hh"
76#include "Randomize.hh"
77#include "G4StateManager.hh"
78#include "G4RunManager.hh"
79#include "G4Run.hh"
80#include "G4Transform3D.hh"
81#include "G4AttHolder.hh"
82#include "G4AttDef.hh"
83
84G4VSceneHandler::G4VSceneHandler (G4VGraphicsSystem& system, G4int id, const G4String& name):
85  fSystem                (system),
86  fSceneHandlerId        (id),
87  fViewCount             (0),
88  fpViewer               (0),
89  fpScene                (0),
90  fMarkForClearingTransientStore (true),  // Ready for first
91                                          // ClearTransientStoreIfMarked(),
92                                          // e.g., at end of run (see
93                                          // G4VisManager.cc).
94  fReadyForTransients    (true),  // Only false while processing scene.
95  fProcessingSolid       (false),
96  fSecondPassRequested   (false),
97  fSecondPass            (false),
98  fpModel                (0),
99  fpObjectTransformation (0),
100  fNestingDepth          (0),
101  fpVisAttribs           (0)
102{
103  G4VisManager* pVMan = G4VisManager::GetInstance ();
104  fpScene = pVMan -> GetCurrentScene ();
105  if (name == "") {
106    std::ostringstream ost;
107    ost << fSystem.GetName () << '-' << fSceneHandlerId;
108    fName = ost.str();
109  }
110  else {
111    fName = name;
112  }
113  fTransientsDrawnThisEvent = pVMan->GetTransientsDrawnThisEvent();
114  fTransientsDrawnThisRun = pVMan->GetTransientsDrawnThisRun();
115}
116
117G4VSceneHandler::~G4VSceneHandler () {
118  G4ViewerListIterator i;
119  for (i = fViewerList.begin(); i != fViewerList.end(); ++i) {
120    delete *i;
121  }
122}
123
124void G4VSceneHandler::PreAddSolid (const G4Transform3D& objectTransformation,
125                                  const G4VisAttributes& visAttribs) {
126  fpObjectTransformation = &objectTransformation;
127  fpVisAttribs = &visAttribs;
128  fProcessingSolid = true;
129}
130
131void G4VSceneHandler::PostAddSolid () {
132  fpObjectTransformation = 0;
133  fpVisAttribs = 0;
134  fProcessingSolid = false;
135  if (fReadyForTransients) {
136    fTransientsDrawnThisEvent = true;
137    fTransientsDrawnThisRun = true;
138  }
139}
140
141void G4VSceneHandler::BeginPrimitives
142(const G4Transform3D& objectTransformation) {
143  fNestingDepth++;
144  if (fNestingDepth > 1)
145    G4Exception("G4VSceneHandler::BeginPrimitives: Nesting detected."
146                "\n  It is illegal to nest Begin/EndPrimitives.");
147  fpObjectTransformation = &objectTransformation;
148}
149
150void G4VSceneHandler::EndPrimitives () {
151  if (fNestingDepth <= 0)
152    G4Exception("G4VSceneHandler::EndPrimitives: Nesting error");
153  fNestingDepth--;
154  fpObjectTransformation = 0;
155  if (fReadyForTransients) {
156    fTransientsDrawnThisEvent = true;
157    fTransientsDrawnThisRun = true;
158  }
159}
160
161void G4VSceneHandler::BeginPrimitives2D
162(const G4Transform3D& objectTransformation) {
163  fNestingDepth++;
164  if (fNestingDepth > 1)
165    G4Exception("G4VSceneHandler::BeginPrimitives2D: Nesting detected."
166                "\n  It is illegal to nest Begin/EndPrimitives.");
167  fpObjectTransformation = &objectTransformation;
168}
169
170void G4VSceneHandler::EndPrimitives2D () {
171  if (fNestingDepth <= 0)
172    G4Exception("G4VSceneHandler::EndPrimitives2D: Nesting error");
173  fNestingDepth--;
174  fpObjectTransformation = 0;
175  if (fReadyForTransients) {
176    fTransientsDrawnThisEvent = true;
177    fTransientsDrawnThisRun = true;
178  }
179}
180
181void G4VSceneHandler::BeginModeling () {
182}
183
184void G4VSceneHandler::EndModeling ()
185{
186  fpModel = 0;
187}
188
189void G4VSceneHandler::ClearStore () {
190  // if (fpViewer) fpViewer -> NeedKernelVisit (true);
191  // ?? Viewer is supposed to be smart enough to know when to visit
192  // kernel, but a problem in OpenGL Stored seems to require a forced
193  // kernel visit triggered by the above code.  John Allison Aug 2001
194  // Feb 2005 - commented out.  Let's fix OpenGL if necessary.
195}
196
197void G4VSceneHandler::ClearTransientStore () {
198}
199
200void G4VSceneHandler::AddSolid (const G4Box& box) {
201  RequestPrimitives (box);
202// If your graphics system is sophisticated enough to handle a
203//  particular solid shape as a primitive, in your derived class write a
204//  function to override this.  (Note: some compilers warn that your
205//  function "hides" this one.  That's OK.)
206// Your function might look like this...
207// void G4MyScene::AddSolid (const G4Box& box) {
208// Get parameters of appropriate object, e.g.:
209//   G4double dx = box.GetXHalfLength ();
210//   G4double dy = box.GetYHalfLength ();
211//   G4double dz = box.GetZHalfLength ();
212// and Draw or Store in your display List.
213}
214
215void G4VSceneHandler::AddSolid (const G4Tubs& tubs) {
216  RequestPrimitives (tubs);
217}
218
219void G4VSceneHandler::AddSolid (const G4Cons& cons) {
220  RequestPrimitives (cons);
221}
222
223void G4VSceneHandler::AddSolid (const G4Trd& trd) {
224  RequestPrimitives (trd);
225}
226
227void G4VSceneHandler::AddSolid (const G4Trap& trap) {
228  RequestPrimitives (trap);
229}
230
231void G4VSceneHandler::AddSolid (const G4Sphere& sphere) {
232  RequestPrimitives (sphere );
233}
234
235void G4VSceneHandler::AddSolid (const G4Para& para) {
236  RequestPrimitives (para);
237}
238
239void G4VSceneHandler::AddSolid (const G4Torus& torus) {
240  RequestPrimitives (torus);
241}
242
243void G4VSceneHandler::AddSolid (const G4Polycone& polycone) {
244  RequestPrimitives (polycone);
245}
246
247void G4VSceneHandler::AddSolid (const G4Polyhedra& polyhedra) {
248  RequestPrimitives (polyhedra);
249}
250
251void G4VSceneHandler::AddSolid (const G4VSolid& solid) {
252  RequestPrimitives (solid);
253}
254
255void G4VSceneHandler::AddCompound (const G4VTrajectory& traj) {
256  G4TrajectoriesModel* pTrModel =
257    dynamic_cast<G4TrajectoriesModel*>(fpModel);
258  if (!pTrModel) G4Exception
259    ("G4VSceneHandler::AddCompound(const G4VTrajectory&): Not a G4TrajectoriesModel.");
260  traj.DrawTrajectory(pTrModel->GetDrawingMode());
261}
262
263void G4VSceneHandler::AddCompound (const G4VHit& hit) {
264  static_cast<G4VHit>(hit).Draw(); // Cast because Draw is non-const!!!!
265}
266
267void G4VSceneHandler::AddCompound (const G4THitsMap<G4double>& hits) {
268  // Cast because DrawAllHits is non-const!!!!
269  static_cast<G4THitsMap<G4double> >(hits).DrawAllHits();
270}
271
272void G4VSceneHandler::AddViewerToList (G4VViewer* pViewer) {
273  fViewerList.push_back (pViewer);
274}
275
276void G4VSceneHandler::AddPrimitive (const G4Scale& scale) {
277
278  const G4double margin(0.01);
279  // Fractional margin - ensures scale is comfortably inside viewing
280  // volume.
281  const G4double oneMinusMargin (1. - margin);
282
283  const G4VisExtent& sceneExtent = fpScene->GetExtent();
284
285  // Useful constants...
286  const G4double length(scale.GetLength());
287  const G4double halfLength(length / 2.);
288  const G4double tickLength(length / 20.);
289  const G4double piBy2(halfpi);
290
291  // Get size of scene...
292  const G4double xmin = sceneExtent.GetXmin();
293  const G4double xmax = sceneExtent.GetXmax();
294  const G4double ymin = sceneExtent.GetYmin();
295  const G4double ymax = sceneExtent.GetYmax();
296  const G4double zmin = sceneExtent.GetZmin();
297  const G4double zmax = sceneExtent.GetZmax();
298
299  // Create (empty) polylines having the same vis attributes...
300  G4Polyline scaleLine, tick11, tick12, tick21, tick22;
301  G4VisAttributes visAtts(*scale.GetVisAttributes());  // Long enough life.
302  scaleLine.SetVisAttributes(&visAtts);
303  tick11.SetVisAttributes(&visAtts);
304  tick12.SetVisAttributes(&visAtts);
305  tick21.SetVisAttributes(&visAtts);
306  tick22.SetVisAttributes(&visAtts);
307
308  // Add points to the polylines to represent an scale parallel to the
309  // x-axis centred on the origin...
310  G4Point3D r1(G4Point3D(-halfLength, 0., 0.));
311  G4Point3D r2(G4Point3D( halfLength, 0., 0.));
312  scaleLine.push_back(r1);
313  scaleLine.push_back(r2);
314  G4Point3D ticky(0., tickLength, 0.);
315  G4Point3D tickz(0., 0., tickLength);
316  tick11.push_back(r1 + ticky);
317  tick11.push_back(r1 - ticky);
318  tick12.push_back(r1 + tickz);
319  tick12.push_back(r1 - tickz);
320  tick21.push_back(r2 + ticky);
321  tick21.push_back(r2 - ticky);
322  tick22.push_back(r2 + tickz);
323  tick22.push_back(r2 - tickz);
324  G4Point3D textPosition(0., tickLength, 0.);
325
326  // Transform appropriately...
327
328  G4Transform3D transformation;
329  if (scale.GetAutoPlacing()) {
330    G4Transform3D rotation;
331    switch (scale.GetDirection()) {
332    case G4Scale::x:
333      break;
334    case G4Scale::y:
335      rotation = G4RotateZ3D(piBy2);
336      break;
337    case G4Scale::z:
338      rotation = G4RotateY3D(piBy2);
339      break;
340    }
341    G4double sxmid(scale.GetXmid());
342    G4double symid(scale.GetYmid());
343    G4double szmid(scale.GetZmid());
344    sxmid = xmin + oneMinusMargin * (xmax - xmin);
345    symid = ymin + margin * (ymax - ymin);
346    szmid = zmin + oneMinusMargin * (zmax - zmin);
347    switch (scale.GetDirection()) {
348    case G4Scale::x:
349      sxmid -= halfLength;
350      break;
351    case G4Scale::y:
352      symid += halfLength;
353      break;
354    case G4Scale::z:
355      szmid -= halfLength;
356      break;
357    }
358    G4Translate3D translation(sxmid, symid, szmid);
359    transformation = translation * rotation;
360  } else {
361    if (fpModel) transformation = fpModel->GetTransformation();
362  }
363
364  // Draw...
365  // We would like to call BeginPrimitives(transformation) here but
366  // calling BeginPrimitives from within an AddPrimitive is not
367  // allowed!  So we have to do our own transformation...
368  AddPrimitive(scaleLine.transform(transformation));
369  AddPrimitive(tick11.transform(transformation));
370  AddPrimitive(tick12.transform(transformation));
371  AddPrimitive(tick21.transform(transformation));
372  AddPrimitive(tick22.transform(transformation));
373  G4Text text(scale.GetAnnotation(),textPosition.transform(transformation));
374  text.SetScreenSize(12.);
375  AddPrimitive(text);
376}
377
378void G4VSceneHandler::AddPrimitive (const G4Polymarker& polymarker) {
379  switch (polymarker.GetMarkerType()) {
380  default:
381  case G4Polymarker::dots:
382    {
383      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
384        G4Circle dot (polymarker);
385        dot.SetPosition (polymarker[iPoint]);
386        dot.SetWorldSize  (0.);
387        dot.SetScreenSize (0.1);  // Very small circle.
388        AddPrimitive (dot);
389      }
390    }
391    break;
392  case G4Polymarker::circles:
393    {
394      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
395        G4Circle circle (polymarker);
396        circle.SetPosition (polymarker[iPoint]);
397        AddPrimitive (circle);
398      }
399    }
400    break;
401  case G4Polymarker::squares:
402    {
403      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
404        G4Square square (polymarker);
405        square.SetPosition (polymarker[iPoint]);
406        AddPrimitive (square);
407      }
408    }
409    break;
410  }
411}
412
413void G4VSceneHandler::RemoveViewerFromList (G4VViewer* pViewer) {
414  fViewerList.remove(pViewer);
415}
416
417void G4VSceneHandler::SetScene (G4Scene* pScene) {
418  fpScene = pScene;
419  // Notify all viewers that a kernel visit is required.
420  G4ViewerListIterator i;
421  for (i = fViewerList.begin(); i != fViewerList.end(); i++) {
422    (*i) -> SetNeedKernelVisit (true);
423  }
424}
425
426void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid) {
427  BeginPrimitives (*fpObjectTransformation);
428  G4NURBS* pNURBS = 0;
429  G4Polyhedron* pPolyhedron = 0;
430  switch (fpViewer -> GetViewParameters () . GetRepStyle ()) {
431  case G4ViewParameters::nurbs:
432    pNURBS = solid.CreateNURBS ();
433    if (pNURBS) {
434      pNURBS -> SetVisAttributes (fpVisAttribs);
435      AddPrimitive (*pNURBS);
436      delete pNURBS;
437      break;
438    }
439    else {
440      G4VisManager::Verbosity verbosity =
441        G4VisManager::GetInstance()->GetVerbosity();
442      if (verbosity >= G4VisManager::errors) {
443        G4cout <<
444          "ERROR: G4VSceneHandler::RequestPrimitives"
445          "\n  NURBS not available for "
446               << solid.GetName () << G4endl;
447        G4cout << "Trying polyhedron." << G4endl;
448      }
449    }
450    // Dropping through to polyhedron...
451  case G4ViewParameters::polyhedron:
452  default:
453    G4Polyhedron::SetNumberOfRotationSteps (GetNoOfSides (fpVisAttribs));
454    pPolyhedron = solid.GetPolyhedron ();
455    G4Polyhedron::ResetNumberOfRotationSteps ();
456    if (pPolyhedron) {
457      pPolyhedron -> SetVisAttributes (fpVisAttribs);
458#ifdef G4DEBUG_VIS_MANAGEMENT
459      printf("G4VSceneHandler::RequestPrimitives VSolid: %d\n",pPolyhedron);
460#endif
461      G4cout <<
462        "G4VSceneHandler::RequestPrimitives VSolid " << solid.GetName () <<G4endl;
463      AddPrimitive (*pPolyhedron);
464    }
465    else {
466      G4VisManager::Verbosity verbosity =
467        G4VisManager::GetInstance()->GetVerbosity();
468      if (verbosity >= G4VisManager::errors) {
469        G4cout <<
470          "ERROR: G4VSceneHandler::RequestPrimitives"
471          "\n  Polyhedron not available for " << solid.GetName () <<
472          ".\n  This means it cannot be visualized on most systems."
473          "\n  Contact the Visualization Coordinator." << G4endl;
474      }
475    }
476    break;
477  }
478  EndPrimitives ();
479}
480
481void G4VSceneHandler::ProcessScene (G4VViewer&) {
482
483#ifdef G4DEBUG_VIS_MANAGEMENT
484  printf("G4VSceneHandler::ProcessScene : BEGIN\n");
485#endif
486
487  if (!fpScene) return;
488
489#ifdef G4DEBUG_VIS_MANAGEMENT
490  printf("G4VSceneHandler::ProcessScene : 2\n");
491#endif
492  G4VisManager* visManager = G4VisManager::GetInstance();
493
494#ifdef G4DEBUG_VIS_MANAGEMENT
495  printf("G4VSceneHandler::ProcessScene : 3\n");
496#endif
497  if (!visManager->GetConcreteInstance()) return;
498
499#ifdef G4DEBUG_VIS_MANAGEMENT
500  printf("G4VSceneHandler::ProcessScene : 4\n");
501#endif
502  G4VisManager::Verbosity verbosity = visManager->GetVerbosity();
503
504  fReadyForTransients = false;
505
506#ifdef G4DEBUG_VIS_MANAGEMENT
507  printf("G4VSceneHandler::ProcessScene : Before clear store \n");
508#endif
509  // Clear stored scene, if any, i.e., display lists, scene graphs.
510  ClearStore ();
511
512#ifdef G4DEBUG_VIS_MANAGEMENT
513  printf("G4VSceneHandler::ProcessScene : 5\n");
514#endif
515  // Reset fMarkForClearingTransientStore.  No need to clear transient
516  // store since it has just been cleared above.  (Leaving
517  // fMarkForClearingTransientStore true causes problems with
518  // recomputing transients below.)  Restore it again at end...
519  G4bool tmpMarkForClearingTransientStore = fMarkForClearingTransientStore;
520  fMarkForClearingTransientStore = false;
521
522  // Traverse geometry tree and send drawing primitives to window(s).
523
524  const std::vector<G4VModel*>& runDurationModelList =
525    fpScene -> GetRunDurationModelList ();
526
527  if (runDurationModelList.size ()) {
528#ifdef G4DEBUG_VIS_MANAGEMENT
529  printf("G4VSceneHandler::ProcessScene : 6\n");
530#endif
531    if (verbosity >= G4VisManager::confirmations) {
532      G4cout << "Traversing scene data..." << G4endl;
533    }
534
535#ifdef G4DEBUG_VIS_MANAGEMENT
536    printf("G4VSceneHandler::ProcessScene : begin model\n");
537#endif
538    BeginModeling ();
539
540    // Create modeling parameters from view parameters...
541    G4ModelingParameters* pMP = CreateModelingParameters ();
542
543    for (size_t i = 0; i < runDurationModelList.size (); i++) {
544#ifdef G4DEBUG_VIS_MANAGEMENT
545  printf("G4VSceneHandler::ProcessScene : 7\n");
546#endif
547      G4VModel* pModel = runDurationModelList[i];
548      // Note: this is not the place to take action on
549      // pModel->GetTransformation().  The model must take care of
550      // this in pModel->DescribeYourselfTo(*this).  See, for example,
551      // G4PhysicalVolumeModel and /vis/scene/add/logo.
552      pModel -> SetModelingParameters (pMP);
553      SetModel (pModel);  // Store for use by derived class.
554      pModel -> DescribeYourselfTo (*this);
555      pModel -> SetModelingParameters (0);
556    }
557
558    // Repeat if required...
559    if (fSecondPassRequested) {
560#ifdef G4DEBUG_VIS_MANAGEMENT
561  printf("G4VSceneHandler::ProcessScene : 8\n");
562#endif
563      fSecondPass = true;
564      for (size_t i = 0; i < runDurationModelList.size (); i++) {
565#ifdef G4DEBUG_VIS_MANAGEMENT
566  printf("G4VSceneHandler::ProcessScene : 9\n");
567#endif
568        G4VModel* pModel = runDurationModelList[i];
569        pModel -> SetModelingParameters (pMP);
570        SetModel (pModel);  // Store for use by derived class.
571        pModel -> DescribeYourselfTo (*this);
572        pModel -> SetModelingParameters (0);
573      }
574      fSecondPass = false;
575      fSecondPassRequested = false;
576    }
577
578    delete pMP;
579    EndModeling ();
580
581  }
582
583  fpViewer->FinishView();  // Flush streams and/or swap buffers.
584
585  fReadyForTransients = true;
586
587#ifdef G4DEBUG_VIS_MANAGEMENT
588  printf("G4VSceneHandler::ProcessScene : Idle ?\n");
589#endif
590  // Refresh event from end-of-event model list.
591  // Allow only in Idle or GeomClosed state...
592  G4StateManager* stateManager = G4StateManager::GetStateManager();
593  G4ApplicationState state = stateManager->GetCurrentState();
594  if (state == G4State_Idle || state == G4State_GeomClosed) {
595#ifdef G4DEBUG_VIS_MANAGEMENT
596    printf("G4VSceneHandler::ProcessScene : IDLE\n");
597#endif
598
599    visManager->SetEventRefreshing(true);
600
601    if (visManager->GetRequestedEvent()) {
602#ifdef G4DEBUG_VIS_MANAGEMENT
603      printf("G4VSceneHandler::ProcessScene : DrawEvent\n");
604#endif
605      DrawEvent(visManager->GetRequestedEvent());
606
607    } else {
608
609#ifdef G4DEBUG_VIS_MANAGEMENT
610      printf("G4VSceneHandler::ProcessScene : no event\n");
611#endif
612      G4RunManager* runManager = G4RunManager::GetRunManager();
613      if (runManager) {
614#ifdef G4DEBUG_VIS_MANAGEMENT
615        printf("G4VSceneHandler::ProcessScene : runManager\n");
616#endif
617        const G4Run* run = runManager->GetCurrentRun();
618        const std::vector<const G4Event*>* events =
619          run? run->GetEventVector(): 0;
620        size_t nKeptEvents = 0;
621        if (events) nKeptEvents = events->size();
622        if (nKeptEvents) {
623
624#ifdef G4DEBUG_VIS_MANAGEMENT
625        printf("G4VSceneHandler::ProcessScene : 1\n");
626#endif
627          if (fpScene->GetRefreshAtEndOfEvent()) {
628#ifdef G4DEBUG_VIS_MANAGEMENT
629        printf("G4VSceneHandler::ProcessScene : 2\n");
630#endif
631
632            if (verbosity >= G4VisManager::confirmations) {
633              G4cout << "Refreshing event..." << G4endl;
634            }
635            const G4Event* event = 0;
636            if (events && events->size()) event = events->back();
637            if (event) DrawEvent(event);
638
639          } else {  // Accumulating events.
640#ifdef G4DEBUG_VIS_MANAGEMENT
641        printf("G4VSceneHandler::ProcessScene : 3\n");
642#endif
643
644            if (verbosity >= G4VisManager::confirmations) {
645              G4cout << "Refreshing events in run..." << G4endl;
646            }
647            for (size_t i = 0; i < nKeptEvents; ++i) {
648#ifdef G4DEBUG_VIS_MANAGEMENT
649        printf("G4VSceneHandler::ProcessScene : 4\n");
650#endif
651              const G4Event* event = (*events)[i];
652              if (event) DrawEvent(event);
653            }
654
655            if (!fpScene->GetRefreshAtEndOfRun()) {
656#ifdef G4DEBUG_VIS_MANAGEMENT
657        printf("G4VSceneHandler::ProcessScene : 5\n");
658#endif
659              if (verbosity >= G4VisManager::warnings) {
660                G4cout <<
661                  "WARNING: Cannot refresh events accumulated over more"
662                  "\n  than one runs.  Refreshed just the last run."
663                       << G4endl;
664              }
665            }
666          }
667        }
668      }
669    }
670    visManager->SetEventRefreshing(false);
671  }
672
673  fMarkForClearingTransientStore = tmpMarkForClearingTransientStore;
674}
675
676void G4VSceneHandler::DrawEvent(const G4Event* event)
677{
678  const std::vector<G4VModel*>& EOEModelList =
679    fpScene -> GetEndOfEventModelList ();
680  size_t nModels = EOEModelList.size();
681  if (nModels) {
682    G4ModelingParameters* pMP = CreateModelingParameters();
683    pMP->SetEvent(event);
684    for (size_t i = 0; i < nModels; i++) {
685      G4VModel* pModel = EOEModelList [i];
686      pModel -> SetModelingParameters(pMP);
687      SetModel (pModel);
688      pModel -> DescribeYourselfTo (*this);
689      pModel -> SetModelingParameters(0);
690    }
691    delete pMP;
692    SetModel (0);
693  }
694}
695
696G4ModelingParameters* G4VSceneHandler::CreateModelingParameters ()
697{
698  // Create modeling parameters from View Parameters...
699  const G4ViewParameters& vp = fpViewer -> GetViewParameters ();
700
701  // Convert drawing styles...
702  G4ModelingParameters::DrawingStyle modelDrawingStyle =
703    G4ModelingParameters::wf;
704  switch (vp.GetDrawingStyle ()) {
705  default:
706  case G4ViewParameters::wireframe:
707    modelDrawingStyle = G4ModelingParameters::wf;
708    break;
709  case G4ViewParameters::hlr:
710    modelDrawingStyle = G4ModelingParameters::hlr;
711    break;
712  case G4ViewParameters::hsr:
713    modelDrawingStyle = G4ModelingParameters::hsr;
714    break;
715  case G4ViewParameters::hlhsr:
716    modelDrawingStyle = G4ModelingParameters::hlhsr;
717    break;
718  }
719
720  // Decide if covered daughters are really to be culled...
721  G4bool reallyCullCovered =
722    vp.IsCullingCovered()   // Culling daughters depends also on...
723    && !vp.IsSection ()     // Sections (DCUT) not requested.
724    && !vp.IsCutaway ()     // Cutaways not requested.
725    ;
726
727  G4ModelingParameters* pModelingParams = new G4ModelingParameters
728    (vp.GetDefaultVisAttributes (),
729     modelDrawingStyle,
730     vp.IsCulling (),
731     vp.IsCullingInvisible (),
732     vp.IsDensityCulling (),
733     vp.GetVisibleDensity (),
734     reallyCullCovered,
735     vp.GetNoOfSides ()
736     );
737
738  pModelingParams->SetWarning
739    (G4VisManager::GetInstance()->GetVerbosity() >= G4VisManager::warnings);
740
741  pModelingParams->SetExplodeFactor(vp.GetExplodeFactor());
742  pModelingParams->SetExplodeCentre(vp.GetExplodeCentre());
743
744  pModelingParams->SetSectionPolyhedron(CreateSectionPolyhedron());
745  pModelingParams->SetCutawayPolyhedron(CreateCutawayPolyhedron());
746  // The polyhedron objects are deleted in the modeling parameters destructor.
747
748  return pModelingParams;
749}
750
751const G4Polyhedron* G4VSceneHandler::CreateSectionPolyhedron()
752{
753  /* Disable for now.  Boolean processor not up to it.
754  const G4ViewParameters& vp = fpViewer->GetViewParameters();
755  if (vp.IsSection () ) {
756    G4double radius = fpScene->GetExtent().GetExtentRadius();
757    G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
758    G4Box sectionBox("clipper",
759                     safe, safe, 1.e-5 * radius);  // Thin in z-plane.
760    G4Polyhedron* sectioner = sectionBox.CreatePolyhedron();
761    const G4Plane3D& s = vp.GetSectionPlane ();
762    G4double a = s.a();
763    G4double b = s.b();
764    G4double c = s.c();
765    G4double d = s.d();
766    G4Transform3D transform = G4TranslateZ3D(-d);
767    const G4Normal3D normal(a,b,c);
768    if (normal != G4Normal3D(0,0,1)) {
769      const G4double angle = std::acos(normal.dot(G4Normal3D(0,0,1)));
770      const G4Vector3D axis = G4Normal3D(0,0,1).cross(normal);
771      transform = G4Rotate3D(angle, axis) * transform;
772    }
773    sectioner->Transform(transform);
774    return sectioner;
775  } else {
776    return 0;
777  }
778  */
779  return 0;
780}
781
782const G4Polyhedron* G4VSceneHandler::CreateCutawayPolyhedron()
783{
784  return 0;
785}
786
787void G4VSceneHandler::LoadAtts(const G4Visible& visible, G4AttHolder* holder)
788{
789  // Load G4Atts from G4VisAttributes, if any...
790  const G4VisAttributes* va = visible.GetVisAttributes();
791  if (va) {
792    const std::map<G4String,G4AttDef>* vaDefs =
793      va->GetAttDefs();
794    if (vaDefs) {
795      holder->AddAtts(visible.GetVisAttributes()->CreateAttValues(), vaDefs);
796    }
797  }
798
799  G4PhysicalVolumeModel* pPVModel =
800    dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
801  if (pPVModel) {
802    // Load G4Atts from G4PhysicalVolumeModel...
803    const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs();
804    if (defs) {
805      holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs);
806    }
807  }
808
809  G4TrajectoriesModel* trajModel = dynamic_cast<G4TrajectoriesModel*>(fpModel);
810  if (trajModel) {
811    // Load G4Atts from trajectory...
812    const G4VTrajectory* traj = trajModel->GetCurrentTrajectory();
813    const std::map<G4String,G4AttDef>* defs = traj->GetAttDefs();
814    if (defs) {
815      holder->AddAtts(traj->CreateAttValues(), defs);
816    }
817    G4int nPoints = traj->GetPointEntries();
818    for (G4int i = 0; i < nPoints; ++i) {
819      G4VTrajectoryPoint* trajPoint = traj->GetPoint(i);
820      const std::map<G4String,G4AttDef>* defs = trajPoint->GetAttDefs();
821      if (defs) {
822        holder->AddAtts(trajPoint->CreateAttValues(), defs);
823      }
824    }
825  }
826
827  G4HitsModel* hitsModel = dynamic_cast<G4HitsModel*>(fpModel);
828  if (hitsModel) {
829    // Load G4Atts from hit...
830    const G4VHit* hit = hitsModel->GetCurrentHit();
831    const std::map<G4String,G4AttDef>* defs = hit->GetAttDefs();
832    if (defs) {
833      holder->AddAtts(hit->CreateAttValues(), defs);
834    }
835  }
836}
837
838const G4Colour& G4VSceneHandler::GetColour (const G4Visible& visible) {
839  // Colour is determined by the applicable vis attributes.
840  const G4Colour& colour = fpViewer ->
841    GetApplicableVisAttributes (visible.GetVisAttributes ()) -> GetColour ();
842  return colour;
843}
844
845const G4Colour& G4VSceneHandler::GetTextColour (const G4Text& text) {
846  const G4VisAttributes* pVA = text.GetVisAttributes ();
847  if (!pVA) {
848    pVA = fpViewer -> GetViewParameters (). GetDefaultTextVisAttributes ();
849  }
850  const G4Colour& colour = pVA -> GetColour ();
851  return colour;
852}
853
854G4double G4VSceneHandler::GetLineWidth(const G4VisAttributes* pVisAttribs)
855{
856  G4double lineWidth = pVisAttribs->GetLineWidth();
857  if (lineWidth < 1.) lineWidth = 1.;
858  lineWidth *= fpViewer -> GetViewParameters().GetGlobalLineWidthScale();
859  if (lineWidth < 1.) lineWidth = 1.;
860  return lineWidth;
861}
862
863G4ViewParameters::DrawingStyle G4VSceneHandler::GetDrawingStyle
864(const G4VisAttributes* pVisAttribs) {
865  // Drawing style is normally determined by the view parameters, but
866  // it can be overriddden by the ForceDrawingStyle flag in the vis
867  // attributes.
868  G4ViewParameters::DrawingStyle style =
869    fpViewer->GetViewParameters().GetDrawingStyle();
870  if (pVisAttribs -> IsForceDrawingStyle ()) {
871    G4VisAttributes::ForcedDrawingStyle forcedStyle =
872      pVisAttribs -> GetForcedDrawingStyle ();
873    // This is complicated because if hidden line and surface removal
874    // has been requested we wish to preserve this sometimes.
875    switch (forcedStyle) {
876    case (G4VisAttributes::solid):
877      switch (style) {
878      case (G4ViewParameters::hlr):
879        style = G4ViewParameters::hlhsr;
880        break;
881      case (G4ViewParameters::wireframe):
882        style = G4ViewParameters::hsr;
883        break;
884      case (G4ViewParameters::hlhsr):
885      case (G4ViewParameters::hsr):
886      default:
887        break;
888      }
889      break;
890    case (G4VisAttributes::wireframe):
891    default:
892      // But if forced style is wireframe, do it, because one of its
893      // main uses is in displaying the consituent solids of a Boolean
894      // solid and their surfaces overlap with the resulting Booean
895      // solid, making a mess if hlr is specified.
896      style = G4ViewParameters::wireframe;
897      break;
898    }
899  }
900  return style;
901}
902
903G4bool G4VSceneHandler::GetAuxEdgeVisible (const G4VisAttributes* pVisAttribs) {
904  G4bool isAuxEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible ();
905  if (pVisAttribs -> IsForceAuxEdgeVisible()) isAuxEdgeVisible = true;
906  return isAuxEdgeVisible;
907}
908
909G4double G4VSceneHandler::GetMarkerSize
910(const G4VMarker& marker,
911 G4VSceneHandler::MarkerSizeType& markerSizeType)
912{
913  G4bool userSpecified = marker.GetWorldSize() || marker.GetScreenSize();
914  const G4VMarker& defaultMarker =
915    fpViewer -> GetViewParameters().GetDefaultMarker();
916  G4double size = userSpecified ?
917    marker.GetWorldSize() : defaultMarker.GetWorldSize();
918  if (size) {
919    // Draw in world coordinates.
920    markerSizeType = world;
921  }
922  else {
923    size = userSpecified ?
924      marker.GetScreenSize() : defaultMarker.GetScreenSize();
925    // Draw in screen coordinates.
926    markerSizeType = screen;
927  }
928  if (size <= 1.) size = 1.;
929  size *= fpViewer -> GetViewParameters().GetGlobalMarkerScale();
930  if (size <= 1.) size = 1.;
931  return size;
932}
933
934G4int G4VSceneHandler::GetNoOfSides(const G4VisAttributes* pVisAttribs)
935{
936  // No. of sides (lines segments per circle) is normally determined
937  // by the view parameters, but it can be overriddden by the
938  // ForceLineSegmentsPerCircle in the vis attributes.
939  G4int lineSegmentsPerCircle = fpViewer->GetViewParameters().GetNoOfSides();
940  if (pVisAttribs) {
941    if (pVisAttribs->IsForceLineSegmentsPerCircle())
942      lineSegmentsPerCircle = pVisAttribs->GetForcedLineSegmentsPerCircle();
943    const G4int nSegmentsMin = 12;
944    if (lineSegmentsPerCircle < nSegmentsMin) {
945      lineSegmentsPerCircle = nSegmentsMin;
946      G4cout <<
947        "G4VSceneHandler::GetNoOfSides: attempt to set the"
948        "\nnumber of line segements per circle < " << nSegmentsMin
949             << "; forced to " << lineSegmentsPerCircle << G4endl;
950    }
951  }
952  return lineSegmentsPerCircle;
953}
954
955std::ostream& operator << (std::ostream& os, const G4VSceneHandler& s) {
956
957  os << "Scene handler " << s.fName << " has "
958     << s.fViewerList.size () << " viewer(s):";
959  for (size_t i = 0; i < s.fViewerList.size (); i++) {
960    os << "\n  " << *(s.fViewerList [i]);
961  }
962
963  if (s.fpScene) {
964    os << "\n  " << *s.fpScene;
965  }
966  else {
967    os << "\n  This scene handler currently has no scene.";
968  }
969
970  return os;
971}
Note: See TracBrowser for help on using the repository browser.