ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VSceneHandler.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4VSceneHandler.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 //
29 // John Allison 19th July 1996
30 // Abstract interface class for graphics scenes.
31 
32 #include "G4VSceneHandler.hh"
33 
34 #include "G4ios.hh"
35 #include <sstream>
36 
37 #include "G4VisManager.hh"
38 #include "G4VGraphicsSystem.hh"
39 #include "G4VViewer.hh"
40 #include "G4VSolid.hh"
41 #include "G4RotationMatrix.hh"
42 #include "G4ThreeVector.hh"
43 #include "G4VPhysicalVolume.hh"
44 #include "G4Material.hh"
45 #include "G4Polyline.hh"
46 #include "G4Scale.hh"
47 #include "G4Text.hh"
48 #include "G4Circle.hh"
49 #include "G4Square.hh"
50 #include "G4Polymarker.hh"
51 #include "G4Polyhedron.hh"
52 #include "G4Visible.hh"
53 #include "G4VisAttributes.hh"
54 #include "G4VModel.hh"
55 #include "G4TrajectoriesModel.hh"
56 #include "G4Box.hh"
57 #include "G4Cons.hh"
58 #include "G4Orb.hh"
59 #include "G4Para.hh"
60 #include "G4Sphere.hh"
61 #include "G4Torus.hh"
62 #include "G4Trap.hh"
63 #include "G4Trd.hh"
64 #include "G4Tubs.hh"
65 #include "G4Ellipsoid.hh"
66 #include "G4Polycone.hh"
67 #include "G4Polyhedra.hh"
68 #include "G4DisplacedSolid.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 "G4VDigi.hh"
77 #include "G4ScoringManager.hh"
78 #include "G4VScoringMesh.hh"
80 #include "Randomize.hh"
81 #include "G4StateManager.hh"
82 #include "G4RunManager.hh"
83 #ifdef G4MULTITHREADED
84 #include "G4MTRunManager.hh"
85 #endif
86 #include "G4Run.hh"
87 #include "G4Transform3D.hh"
88 #include "G4AttHolder.hh"
89 #include "G4AttDef.hh"
90 #include "G4VVisCommand.hh"
91 #include "G4PhysicalConstants.hh"
92 #include "G4SystemOfUnits.hh"
93 
94 #include <set>
95 
97  fSystem (system),
98  fSceneHandlerId (id),
99  fViewCount (0),
100  fpViewer (0),
101  fpScene (0),
102  fMarkForClearingTransientStore (true), // Ready for first
103  // ClearTransientStoreIfMarked(),
104  // e.g., at end of run (see
105  // G4VisManager.cc).
106  fReadyForTransients (true), // Only false while processing scene.
107  fProcessingSolid (false),
108  fProcessing2D (false),
109  fpModel (0),
110  fNestingDepth (0),
111  fpVisAttribs (0)
112 {
114  fpScene = pVMan -> GetCurrentScene ();
115  if (name == "") {
116  std::ostringstream ost;
117  ost << fSystem.GetName () << '-' << fSceneHandlerId;
118  fName = ost.str();
119  }
120  else {
121  fName = name;
122  }
125 }
126 
128  G4VViewer* last;
129  while( ! fViewerList.empty() ) {
130  last = fViewerList.back();
131  fViewerList.pop_back();
132  delete last;
133  }
134 }
135 
137 {
138  if (fpScene) {
139  return fpScene->GetExtent();
140  } else {
141  static const G4VisExtent defaultExtent = G4VisExtent();
142  return defaultExtent;
143  }
144 }
145 
146 void G4VSceneHandler::PreAddSolid (const G4Transform3D& objectTransformation,
147  const G4VisAttributes& visAttribs) {
148  fObjectTransformation = objectTransformation;
149  fpVisAttribs = &visAttribs;
150  fProcessingSolid = true;
151 }
152 
154  fpVisAttribs = 0;
155  fProcessingSolid = false;
156  if (fReadyForTransients) {
159  }
160 }
161 
163 (const G4Transform3D& objectTransformation) {
164  //static G4int count = 0;
165  //G4cout << "G4VSceneHandler::BeginPrimitives: " << count++ << G4endl;
166  fNestingDepth++;
167  if (fNestingDepth > 1)
169  ("G4VSceneHandler::BeginPrimitives",
170  "visman0101", FatalException,
171  "Nesting detected. It is illegal to nest Begin/EndPrimitives.");
172  fObjectTransformation = objectTransformation;
173 }
174 
176  if (fNestingDepth <= 0)
177  G4Exception("G4VSceneHandler::EndPrimitives",
178  "visman0102", FatalException, "Nesting error.");
179  fNestingDepth--;
180  if (fReadyForTransients) {
183  }
184 }
185 
187 (const G4Transform3D& objectTransformation) {
188  fNestingDepth++;
189  if (fNestingDepth > 1)
191  ("G4VSceneHandler::BeginPrimitives2D",
192  "visman0103", FatalException,
193  "Nesting detected. It is illegal to nest Begin/EndPrimitives.");
194  fObjectTransformation = objectTransformation;
195  fProcessing2D = true;
196 }
197 
199  if (fNestingDepth <= 0)
200  G4Exception("G4VSceneHandler::EndPrimitives2D",
201  "visman0104", FatalException, "Nesting error.");
202  fNestingDepth--;
203  if (fReadyForTransients) {
206  }
207  fProcessing2D = false;
208 }
209 
211 }
212 
214 {
215  fpModel = 0;
216 }
217 
219 
221 
222 template <class T> void G4VSceneHandler::AddSolidT
223 (const T& solid)
224 {
225  // Get and check applicable vis attributes.
226  fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
227  RequestPrimitives (solid);
228 }
229 
230 template <class T> void G4VSceneHandler::AddSolidWithAuxiliaryEdges
231 (const T& solid)
232 {
233  // Get and check applicable vis attributes.
234  fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
235  // Draw with auxiliary edges unless otherwise specified.
236  if (!fpVisAttribs->IsForceAuxEdgeVisible()) {
237  // Create a vis atts object for the modified vis atts.
238  // It is static so that we may return a reliable pointer to it.
239  static G4VisAttributes visAttsWithAuxEdges;
240  // Initialise it with the current vis atts and reset the pointer.
241  visAttsWithAuxEdges = *fpVisAttribs;
242  // Force auxiliary edges visible.
243  visAttsWithAuxEdges.SetForceAuxEdgeVisible();
244  fpVisAttribs = &visAttsWithAuxEdges;
245  }
246  RequestPrimitives (solid);
247 }
248 
250  AddSolidT (box);
251  // If your graphics system is sophisticated enough to handle a
252  // particular solid shape as a primitive, in your derived class write a
253  // function to override this.
254  // Your function might look like this...
255  // void G4MySceneHandler::AddSolid (const G4Box& box) {
256  // Get and check applicable vis attributes.
257  // fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
258  // Do not draw if not visible.
259  // if (fpVisAttribs->IsVisible()) {
260  // Get parameters of appropriate object, e.g.:
261  // G4double dx = box.GetXHalfLength ();
262  // G4double dy = box.GetYHalfLength ();
263  // G4double dz = box.GetZHalfLength ();
264  // ...
265  // and Draw or Store in your display List.
266 }
267 
268 void G4VSceneHandler::AddSolid (const G4Cons& cons) {
269  AddSolidT (cons);
270 }
271 
272 void G4VSceneHandler::AddSolid (const G4Orb& orb) {
274 }
275 
276 void G4VSceneHandler::AddSolid (const G4Para& para) {
277  AddSolidT (para);
278 }
279 
280 void G4VSceneHandler::AddSolid (const G4Sphere& sphere) {
282 }
283 
284 void G4VSceneHandler::AddSolid (const G4Torus& torus) {
286 }
287 
288 void G4VSceneHandler::AddSolid (const G4Trap& trap) {
289  AddSolidT (trap);
290 }
291 
292 void G4VSceneHandler::AddSolid (const G4Trd& trd) {
293  AddSolidT (trd);
294 }
295 
296 void G4VSceneHandler::AddSolid (const G4Tubs& tubs) {
297  AddSolidT (tubs);
298 }
299 
300 void G4VSceneHandler::AddSolid (const G4Ellipsoid& ellipsoid) {
301  AddSolidWithAuxiliaryEdges (ellipsoid);
302 }
303 
304 void G4VSceneHandler::AddSolid (const G4Polycone& polycone) {
305  AddSolidT (polycone);
306 }
307 
308 void G4VSceneHandler::AddSolid (const G4Polyhedra& polyhedra) {
309  AddSolidT (polyhedra);
310 }
311 
313  AddSolidT (tess);
314 }
315 
316 void G4VSceneHandler::AddSolid (const G4VSolid& solid) {
317  AddSolidT (solid);
318 }
319 
321  G4TrajectoriesModel* trajectoriesModel =
322  dynamic_cast<G4TrajectoriesModel*>(fpModel);
323  if (trajectoriesModel)
324  traj.DrawTrajectory();
325  else {
327  ("G4VSceneHandler::AddCompound(const G4VTrajectory&)",
328  "visman0105", FatalException, "Not a G4TrajectoriesModel.");
329  }
330 }
331 
333  // Cast away const because Draw is non-const!!!!
334  const_cast<G4VHit&>(hit).Draw();
335 }
336 
338  // Cast away const because Draw is non-const!!!!
339  const_cast<G4VDigi&>(digi).Draw();
340 }
341 
343  using MeshScoreMap = G4VScoringMesh::MeshScoreMap;
344  //G4cout << "AddCompound: hits: " << &hits << G4endl;
345  G4bool scoreMapHits = false;
347  if (scoringManager) {
348  size_t nMeshes = scoringManager->GetNumberOfMesh();
349  for (size_t iMesh = 0; iMesh < nMeshes; ++iMesh) {
350  G4VScoringMesh* mesh = scoringManager->GetMesh(iMesh);
351  if (mesh && mesh->IsActive()) {
352  MeshScoreMap scoreMap = mesh->GetScoreMap();
353  const G4String& mapNam = const_cast<G4THitsMap<G4double>&>(hits).GetName();
354  for(MeshScoreMap::const_iterator i = scoreMap.begin();
355  i != scoreMap.end(); ++i) {
356  const G4String& scoreMapName = i->first;
357  if (scoreMapName == mapNam) {
358  G4DefaultLinearColorMap colorMap("G4VSceneHandlerColorMap");
359  scoreMapHits = true;
360  mesh->DrawMesh(scoreMapName, &colorMap);
361  }
362  }
363  }
364  }
365  }
366  if (scoreMapHits) {
367  static G4bool first = true;
368  if (first) {
369  first = false;
370  G4cout <<
371  "Scoring map drawn with default parameters."
372  "\n To get gMocren file for gMocren browser:"
373  "\n /vis/open gMocrenFile"
374  "\n /vis/viewer/flush"
375  "\n Many other options available with /score/draw... commands."
376  "\n You might want to \"/vis/viewer/set/autoRefresh false\"."
377  << G4endl;
378  }
379  } else { // Not score map hits. Just call DrawAllHits.
380  // Cast away const because DrawAllHits is non-const!!!!
381  const_cast<G4THitsMap<G4double>&>(hits).DrawAllHits();
382  }
383 }
384 
386  using MeshScoreMap = G4VScoringMesh::MeshScoreMap;
387  //G4cout << "AddCompound: hits: " << &hits << G4endl;
388  G4bool scoreMapHits = false;
390  if (scoringManager) {
391  size_t nMeshes = scoringManager->GetNumberOfMesh();
392  for (size_t iMesh = 0; iMesh < nMeshes; ++iMesh) {
393  G4VScoringMesh* mesh = scoringManager->GetMesh(iMesh);
394  if (mesh && mesh->IsActive()) {
395  MeshScoreMap scoreMap = mesh->GetScoreMap();
396  for(MeshScoreMap::const_iterator i = scoreMap.begin();
397  i != scoreMap.end(); ++i) {
398  const G4String& scoreMapName = i->first;
399  const G4THitsMap<G4StatDouble>* foundHits = i->second;
400  if (foundHits == &hits) {
401  G4DefaultLinearColorMap colorMap("G4VSceneHandlerColorMap");
402  scoreMapHits = true;
403  mesh->DrawMesh(scoreMapName, &colorMap);
404  }
405  }
406  }
407  }
408  }
409  if (scoreMapHits) {
410  static G4bool first = true;
411  if (first) {
412  first = false;
413  G4cout <<
414  "Scoring map drawn with default parameters."
415  "\n To get gMocren file for gMocren browser:"
416  "\n /vis/open gMocrenFile"
417  "\n /vis/viewer/flush"
418  "\n Many other options available with /score/draw... commands."
419  "\n You might want to \"/vis/viewer/set/autoRefresh false\"."
420  << G4endl;
421  }
422  } else { // Not score map hits. Just call DrawAllHits.
423  // Cast away const because DrawAllHits is non-const!!!!
424  const_cast<G4THitsMap<G4StatDouble>&>(hits).DrawAllHits();
425  }
426 }
427 
429  fViewerList.push_back (pViewer);
430 }
431 
433 
434  const G4double margin(0.01);
435  // Fractional margin - ensures scale is comfortably inside viewing
436  // volume.
437  const G4double oneMinusMargin (1. - margin);
438 
439  const G4VisExtent& sceneExtent = fpScene->GetExtent();
440 
441  // Useful constants...
442  const G4double length(scale.GetLength());
443  const G4double halfLength(length / 2.);
444  const G4double tickLength(length / 20.);
445  const G4double piBy2(halfpi);
446 
447  // Get size of scene...
448  const G4double xmin = sceneExtent.GetXmin();
449  const G4double xmax = sceneExtent.GetXmax();
450  const G4double ymin = sceneExtent.GetYmin();
451  const G4double ymax = sceneExtent.GetYmax();
452  const G4double zmin = sceneExtent.GetZmin();
453  const G4double zmax = sceneExtent.GetZmax();
454 
455  // Create (empty) polylines having the same vis attributes...
456  G4Polyline scaleLine, tick11, tick12, tick21, tick22;
457  G4VisAttributes visAtts(*scale.GetVisAttributes()); // Long enough life.
458  scaleLine.SetVisAttributes(&visAtts);
459  tick11.SetVisAttributes(&visAtts);
460  tick12.SetVisAttributes(&visAtts);
461  tick21.SetVisAttributes(&visAtts);
462  tick22.SetVisAttributes(&visAtts);
463 
464  // Add points to the polylines to represent an scale parallel to the
465  // x-axis centred on the origin...
466  G4Point3D r1(G4Point3D(-halfLength, 0., 0.));
467  G4Point3D r2(G4Point3D( halfLength, 0., 0.));
468  scaleLine.push_back(r1);
469  scaleLine.push_back(r2);
470  G4Point3D ticky(0., tickLength, 0.);
471  G4Point3D tickz(0., 0., tickLength);
472  tick11.push_back(r1 + ticky);
473  tick11.push_back(r1 - ticky);
474  tick12.push_back(r1 + tickz);
475  tick12.push_back(r1 - tickz);
476  tick21.push_back(r2 + ticky);
477  tick21.push_back(r2 - ticky);
478  tick22.push_back(r2 + tickz);
479  tick22.push_back(r2 - tickz);
480  G4Point3D textPosition(0., tickLength, 0.);
481 
482  // Transform appropriately...
483 
484  G4Transform3D transformation;
485  if (scale.GetAutoPlacing()) {
486  G4Transform3D rotation;
487  switch (scale.GetDirection()) {
488  case G4Scale::x:
489  break;
490  case G4Scale::y:
491  rotation = G4RotateZ3D(piBy2);
492  break;
493  case G4Scale::z:
494  rotation = G4RotateY3D(piBy2);
495  break;
496  }
497  G4double sxmid;
498  G4double symid;
499  G4double szmid;
500  sxmid = xmin + oneMinusMargin * (xmax - xmin);
501  symid = ymin + margin * (ymax - ymin);
502  szmid = zmin + oneMinusMargin * (zmax - zmin);
503  switch (scale.GetDirection()) {
504  case G4Scale::x:
505  sxmid -= halfLength;
506  break;
507  case G4Scale::y:
508  symid += halfLength;
509  break;
510  case G4Scale::z:
511  szmid -= halfLength;
512  break;
513  }
514  G4Translate3D translation(sxmid, symid, szmid);
515  transformation = translation * rotation;
516  } else {
517  if (fpModel) transformation = fpModel->GetTransformation();
518  }
519 
520  // Draw...
521  // We would like to call BeginPrimitives(transformation) here but
522  // calling BeginPrimitives from within an AddPrimitive is not
523  // allowed! So we have to do our own transformation...
524  AddPrimitive(scaleLine.transform(transformation));
525  AddPrimitive(tick11.transform(transformation));
526  AddPrimitive(tick12.transform(transformation));
527  AddPrimitive(tick21.transform(transformation));
528  AddPrimitive(tick22.transform(transformation));
529  G4Text text(scale.GetAnnotation(),textPosition.transform(transformation));
531  text.SetVisAttributes(va);
532  text.SetScreenSize(scale.GetAnnotationSize());
533  AddPrimitive(text);
534 }
535 
536 void G4VSceneHandler::AddPrimitive (const G4Polymarker& polymarker) {
537  switch (polymarker.GetMarkerType()) {
538  default:
539  case G4Polymarker::dots:
540  {
541  G4Circle dot (polymarker);
542  dot.SetWorldSize (0.);
543  dot.SetScreenSize (0.1); // Very small circle.
544  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
545  dot.SetPosition (polymarker[iPoint]);
546  AddPrimitive (dot);
547  }
548  }
549  break;
551  {
552  G4Circle circle (polymarker); // Default circle
553  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
554  circle.SetPosition (polymarker[iPoint]);
555  AddPrimitive (circle);
556  }
557  }
558  break;
560  {
561  G4Square square (polymarker); // Default square
562  for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
563  square.SetPosition (polymarker[iPoint]);
564  AddPrimitive (square);
565  }
566  }
567  break;
568  }
569 }
570 
572  fViewerList.remove(pViewer);
573 }
574 
576  fpScene = pScene;
577  // Notify all viewers that a kernel visit is required.
579  for (i = fViewerList.begin(); i != fViewerList.end(); i++) {
580  (*i) -> SetNeedKernelVisit (true);
581  }
582 }
583 
585 {
588 
589  switch (style) {
590  default:
595  {
596  // Use polyhedral representation
598  G4Polyhedron* pPolyhedron = solid.GetPolyhedron ();
600  if (pPolyhedron) {
601  pPolyhedron -> SetVisAttributes (fpVisAttribs);
603  AddPrimitive (*pPolyhedron);
604  EndPrimitives ();
605  break;
606  } else { // Print warnings and drop through to cloud
608  static std::set<const G4VSolid*> problematicSolids;
609  if (verbosity >= G4VisManager::errors &&
610  problematicSolids.find(&solid) == problematicSolids.end()) {
611  problematicSolids.insert(&solid);
612  G4cerr <<
613  "ERROR: G4VSceneHandler::RequestPrimitives"
614  "\n Polyhedron not available for " << solid.GetName ();
615  G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
616  if (pPVModel) {
617  G4cerr << "\n Touchable path: " << pPVModel->GetFullPVPath();
618  }
619  static G4bool explanation = false;
620  if (!explanation) {
621  explanation = true;
622  G4cerr <<
623  "\n This means it cannot be visualized in the usual way on most systems."
624  "\n 1) The solid may not have implemented the CreatePolyhedron method."
625  "\n 2) For Boolean solids, the BooleanProcessor, which attempts to create"
626  "\n the resultant polyhedron, may have failed."
627  "\n Try RayTracer. It uses Geant4's tracking algorithms instead.";
628  }
629  G4cerr << "\n Drawing solid with cloud of points.";
630  G4cerr << G4endl;
631  }
632  }
633  } // fallthrough
634 
636  {
637  // Form solid out of cloud of dots
638  G4Polymarker dots;
639  // Note: OpenGL has a fast implementation of polymarker so it's better
640  // to build a polymarker rather than add a succession of circles.
641  // And anyway, in Qt, in the latter case each circle would be a scene-tree
642  // entry, something we would want to avoid.
645  dots.SetSize(G4VMarker::screen,1.);
646  G4int numberOfCloudPoints = GetNumberOfCloudPoints(fpVisAttribs);
647  if (numberOfCloudPoints <= 0) numberOfCloudPoints = vp.GetNumberOfCloudPoints();
648  for (G4int i = 0; i < numberOfCloudPoints; ++i) {
650  dots.push_back(p);
651  }
653  AddPrimitive(dots);
654  EndPrimitives ();
655  }
656  break;
657  }
658 }
659 
661 
662  // Assumes graphics database store has already been cleared if
663  // relevant for the particular scene handler.
664 
665  if (!fpScene) return;
666 
669  ("G4VSceneHandler::ProcessScene",
670  "visman0106", JustWarning,
671  "The scene has no extent.");
672  }
673 
674  G4VisManager* visManager = G4VisManager::GetInstance();
675 
676  if (!visManager->GetConcreteInstance()) return;
677 
678  G4VisManager::Verbosity verbosity = visManager->GetVerbosity();
679 
680  fReadyForTransients = false;
681 
682  // Reset fMarkForClearingTransientStore. (Leaving
683  // fMarkForClearingTransientStore true causes problems with
684  // recomputing transients below.) Restore it again at end...
685  G4bool tmpMarkForClearingTransientStore = fMarkForClearingTransientStore;
687 
688  // Traverse geometry tree and send drawing primitives to window(s).
689 
690  const std::vector<G4Scene::Model>& runDurationModelList =
691  fpScene -> GetRunDurationModelList ();
692 
693  if (runDurationModelList.size ()) {
694  if (verbosity >= G4VisManager::confirmations) {
695  G4cout << "Traversing scene data..." << G4endl;
696  }
697 
698  BeginModeling ();
699 
700  // Create modeling parameters from view parameters...
702 
703  for (size_t i = 0; i < runDurationModelList.size (); i++) {
704  if (runDurationModelList[i].fActive) {
705  fpModel = runDurationModelList[i].fpModel;
706  // Note: this is not the place to take action on
707  // pModel->GetTransformation(). The model must take care of
708  // this in pModel->DescribeYourselfTo(*this). See, for example,
709  // G4PhysicalVolumeModel and /vis/scene/add/logo.
710  fpModel -> SetModelingParameters (pMP);
711  fpModel -> DescribeYourselfTo (*this);
712  fpModel -> SetModelingParameters (0);
713  }
714  }
715 
716  fpModel = 0;
717  delete pMP;
718 
719  EndModeling ();
720  }
721 
722  fReadyForTransients = true;
723 
724  // Refresh event from end-of-event model list.
725  // Allow only in Idle or GeomClosed state...
727  G4ApplicationState state = stateManager->GetCurrentState();
728  if (state == G4State_Idle || state == G4State_GeomClosed) {
729 
730  visManager->SetEventRefreshing(true);
731 
732  if (visManager->GetRequestedEvent()) {
733  DrawEvent(visManager->GetRequestedEvent());
734 
735  } else {
736 
738 #ifdef G4MULTITHREADED
740  { runManager = G4MTRunManager::GetMasterRunManager(); }
741 #endif
742  if (runManager) {
743  const G4Run* run = runManager->GetCurrentRun();
744  const std::vector<const G4Event*>* events =
745  run? run->GetEventVector(): 0;
746  size_t nKeptEvents = 0;
747  if (events) nKeptEvents = events->size();
748  if (nKeptEvents) {
749 
751 
752  if (verbosity >= G4VisManager::confirmations) {
753  G4cout << "Refreshing event..." << G4endl;
754  }
755  const G4Event* event = 0;
756  if (events && events->size()) event = events->back();
757  if (event) DrawEvent(event);
758 
759  } else { // Accumulating events.
760 
761  if (verbosity >= G4VisManager::confirmations) {
762  G4cout << "Refreshing events in run..." << G4endl;
763  }
764  for (const auto& event: *events) {
765  if (event) DrawEvent(event);
766  }
767 
768  if (!fpScene->GetRefreshAtEndOfRun()) {
769  if (verbosity >= G4VisManager::warnings) {
770  G4cout <<
771  "WARNING: Cannot refresh events accumulated over more"
772  "\n than one runs. Refreshed just the last run."
773  << G4endl;
774  }
775  }
776  }
777  }
778  }
779  }
780  visManager->SetEventRefreshing(false);
781  }
782 
783  // Refresh end-of-run model list.
784  // Allow only in Idle or GeomClosed state...
785  if (state == G4State_Idle || state == G4State_GeomClosed) {
787  }
788 
789  fMarkForClearingTransientStore = tmpMarkForClearingTransientStore;
790 }
791 
793 {
794  const std::vector<G4Scene::Model>& EOEModelList =
795  fpScene -> GetEndOfEventModelList ();
796  size_t nModels = EOEModelList.size();
797  if (nModels) {
799  pMP->SetEvent(event);
800  for (size_t i = 0; i < nModels; i++) {
801  if (EOEModelList[i].fActive) {
802  fpModel = EOEModelList[i].fpModel;
803  fpModel -> SetModelingParameters(pMP);
804  fpModel -> DescribeYourselfTo (*this);
805  fpModel -> SetModelingParameters(0);
806  }
807  }
808  fpModel = 0;
809  delete pMP;
810  }
811 }
812 
814 {
815  const std::vector<G4Scene::Model>& EORModelList =
816  fpScene -> GetEndOfRunModelList ();
817  size_t nModels = EORModelList.size();
818  if (nModels) {
820  pMP->SetEvent(0);
821  for (size_t i = 0; i < nModels; i++) {
822  if (EORModelList[i].fActive) {
823  fpModel = EORModelList[i].fpModel;
824  fpModel -> SetModelingParameters(pMP);
825  fpModel -> DescribeYourselfTo (*this);
826  fpModel -> SetModelingParameters(0);
827  }
828  }
829  fpModel = 0;
830  delete pMP;
831  }
832 }
833 
835 {
836  // Create modeling parameters from View Parameters...
837  if (!fpViewer) return NULL;
838 
839  const G4ViewParameters& vp = fpViewer -> GetViewParameters ();
840 
841  // Convert drawing styles...
842  G4ModelingParameters::DrawingStyle modelDrawingStyle =
844  switch (vp.GetDrawingStyle ()) {
845  default:
847  modelDrawingStyle = G4ModelingParameters::wf;
848  break;
850  modelDrawingStyle = G4ModelingParameters::hlr;
851  break;
853  modelDrawingStyle = G4ModelingParameters::hsr;
854  break;
856  modelDrawingStyle = G4ModelingParameters::hlhsr;
857  break;
859  modelDrawingStyle = G4ModelingParameters::cloud;
860  break;
861  }
862 
863  // Decide if covered daughters are really to be culled...
864  G4bool reallyCullCovered =
865  vp.IsCullingCovered() // Culling daughters depends also on...
866  && !vp.IsSection () // Sections (DCUT) not requested.
867  && !vp.IsCutaway () // Cutaways not requested.
868  ;
869 
870  G4ModelingParameters* pModelingParams = new G4ModelingParameters
872  modelDrawingStyle,
873  vp.IsCulling (),
874  vp.IsCullingInvisible (),
875  vp.IsDensityCulling (),
876  vp.GetVisibleDensity (),
877  reallyCullCovered,
878  vp.GetNoOfSides ()
879  );
880 
881  pModelingParams->SetNumberOfCloudPoints(vp.GetNumberOfCloudPoints());
882  pModelingParams->SetWarning
884 
885  pModelingParams->SetCBDAlgorithmNumber(vp.GetCBDAlgorithmNumber());
886  pModelingParams->SetCBDParameters(vp.GetCBDParameters());
887 
888  pModelingParams->SetExplodeFactor(vp.GetExplodeFactor());
889  pModelingParams->SetExplodeCentre(vp.GetExplodeCentre());
890 
891  pModelingParams->SetSectionSolid(CreateSectionSolid());
892  pModelingParams->SetCutawaySolid(CreateCutawaySolid());
893  // The polyhedron objects are deleted in the modeling parameters destructor.
894 
896 
897  return pModelingParams;
898 }
899 
901 {
902  G4DisplacedSolid* sectioner = 0;
903 
905  if (vp.IsSection () ) {
906 
908  G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
909  G4VSolid* sectionBox =
910  new G4Box("_sectioner", safe, safe, 1.e-5 * radius); // Thin in z-plane...
911  const G4Normal3D originalNormal(0,0,1); // ...so this is original normal.
912 
913  const G4Plane3D& sp = vp.GetSectionPlane ();
914  const G4double& a = sp.a();
915  const G4double& b = sp.b();
916  const G4double& c = sp.c();
917  const G4double& d = sp.d();
918  const G4Normal3D newNormal(a,b,c);
919 
920  G4Transform3D requiredTransform;
921  // Rotate
922  if (newNormal != originalNormal) {
923  const G4double& angle = std::acos(newNormal.dot(originalNormal));
924  const G4Vector3D& axis = originalNormal.cross(newNormal);
925  requiredTransform = G4Rotate3D(angle, axis);
926  }
927  // Translate
928  requiredTransform = requiredTransform * G4TranslateZ3D(-d);
929 
930  sectioner = new G4DisplacedSolid
931  ("_displaced_sectioning_box", sectionBox, requiredTransform);
932  }
933 
934  return sectioner;
935 }
936 
938 {
939  // To be reviewed.
940  return 0;
941  /*** An alternative way of getting a cutaway is to use
942  Command /vis/scene/add/volume
943  Guidance :
944  Adds a physical volume to current scene, with optional clipping volume.
945  If physical-volume-name is "world" (the default), the top of the
946  main geometry tree (material world) is added. If "worlds", the
947  top of all worlds - material world and parallel worlds, if any - are
948  added. Otherwise a search of all worlds is made, taking the first
949  matching occurrence only. To see a representation of the geometry
950  hierarchy of the worlds, try "/vis/drawTree [worlds]" or one of the
951  driver/browser combinations that have the required functionality, e.g., HepRep.
952  If clip-volume-type is specified, the subsequent parameters are used to
953  to define a clipping volume. For example,
954  "/vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1" will draw the world
955  with the positive octant cut away. (If the Boolean Processor issues
956  warnings try replacing 0 by 0.000000001 or something.)
957  If clip-volume-type is prepended with '-', the clip-volume is subtracted
958  (cutaway). (This is the default if there is no prepended character.)
959  If '*' is prepended, the intersection of the physical-volume and the
960  clip-volume is made. (You can make a section/DCUT with a thin box, for
961  example).
962  For "box", the parameters are xmin,xmax,ymin,ymax,zmin,zmax.
963  Only "box" is programmed at present.
964  ***/
965 }
966 
968 {
969  // Load G4Atts from G4VisAttributes, if any...
970  const G4VisAttributes* va = visible.GetVisAttributes();
971  if (va) {
972  const std::map<G4String,G4AttDef>* vaDefs =
973  va->GetAttDefs();
974  if (vaDefs) {
975  holder->AddAtts(visible.GetVisAttributes()->CreateAttValues(), vaDefs);
976  }
977  }
978 
979  G4PhysicalVolumeModel* pPVModel =
980  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
981  if (pPVModel) {
982  // Load G4Atts from G4PhysicalVolumeModel...
983  const std::map<G4String,G4AttDef>* pvDefs = pPVModel->GetAttDefs();
984  if (pvDefs) {
985  holder->AddAtts(pPVModel->CreateCurrentAttValues(), pvDefs);
986  }
987  }
988 
989  G4TrajectoriesModel* trajModel = dynamic_cast<G4TrajectoriesModel*>(fpModel);
990  if (trajModel) {
991  // Load G4Atts from trajectory model...
992  const std::map<G4String,G4AttDef>* trajModelDefs = trajModel->GetAttDefs();
993  if (trajModelDefs) {
994  holder->AddAtts(trajModel->CreateCurrentAttValues(), trajModelDefs);
995  }
996  // Load G4Atts from trajectory...
997  const G4VTrajectory* traj = trajModel->GetCurrentTrajectory();
998  if (traj) {
999  const std::map<G4String,G4AttDef>* trajDefs = traj->GetAttDefs();
1000  if (trajDefs) {
1001  holder->AddAtts(traj->CreateAttValues(), trajDefs);
1002  }
1003  G4int nPoints = traj->GetPointEntries();
1004  for (G4int i = 0; i < nPoints; ++i) {
1005  G4VTrajectoryPoint* trajPoint = traj->GetPoint(i);
1006  if (trajPoint) {
1007  const std::map<G4String,G4AttDef>* pointDefs = trajPoint->GetAttDefs();
1008  if (pointDefs) {
1009  holder->AddAtts(trajPoint->CreateAttValues(), pointDefs);
1010  }
1011  }
1012  }
1013  }
1014  }
1015 
1016  G4HitsModel* hitsModel = dynamic_cast<G4HitsModel*>(fpModel);
1017  if (hitsModel) {
1018  // Load G4Atts from hit...
1019  const G4VHit* hit = hitsModel->GetCurrentHit();
1020  const std::map<G4String,G4AttDef>* hitsDefs = hit->GetAttDefs();
1021  if (hitsDefs) {
1022  holder->AddAtts(hit->CreateAttValues(), hitsDefs);
1023  }
1024  }
1025 }
1026 
1028  const G4VisAttributes* pVA = text.GetVisAttributes ();
1029  if (!pVA) {
1031  }
1032  const G4Colour& colour = pVA -> GetColour ();
1033  return colour;
1034 }
1035 
1037 {
1038  G4double lineWidth = pVisAttribs->GetLineWidth();
1039  if (lineWidth < 1.) lineWidth = 1.;
1040  lineWidth *= fpViewer -> GetViewParameters().GetGlobalLineWidthScale();
1041  if (lineWidth < 1.) lineWidth = 1.;
1042  return lineWidth;
1043 }
1044 
1046 (const G4VisAttributes* pVisAttribs) {
1047  // Drawing style is normally determined by the view parameters, but
1048  // it can be overriddden by the ForceDrawingStyle flag in the vis
1049  // attributes.
1050  const G4ViewParameters& vp = fpViewer->GetViewParameters();
1051  const G4ViewParameters::DrawingStyle viewerStyle = vp.GetDrawingStyle();
1052  G4ViewParameters::DrawingStyle resultantStyle = viewerStyle;
1053  if (pVisAttribs -> IsForceDrawingStyle ()) {
1055  pVisAttribs -> GetForcedDrawingStyle ();
1056  // This is complicated because if hidden line and surface removal
1057  // has been requested we wish to preserve this sometimes.
1058  switch (forcedStyle) {
1059  case (G4VisAttributes::solid):
1060  switch (viewerStyle) {
1061  case (G4ViewParameters::hlr):
1062  resultantStyle = G4ViewParameters::hlhsr;
1063  break;
1065  resultantStyle = G4ViewParameters::hsr;
1066  break;
1067  case (G4ViewParameters::cloud):
1068  resultantStyle = G4ViewParameters::hsr;
1069  break;
1070  case (G4ViewParameters::hlhsr):
1071  case (G4ViewParameters::hsr):
1072  break;
1073  }
1074  break;
1075  case (G4VisAttributes::cloud):
1076  resultantStyle = G4ViewParameters::cloud;
1077  break;
1079  default:
1080  // But if forced style is wireframe, do it, because one of its
1081  // main uses is in displaying the consituent solids of a Boolean
1082  // solid and their surfaces overlap with the resulting Booean
1083  // solid, making a mess if hlr is specified.
1084  resultantStyle = G4ViewParameters::wireframe;
1085  break;
1086  }
1087  }
1088  return resultantStyle;
1089 }
1090 
1092 (const G4VisAttributes* pVisAttribs) const {
1093  // Returns no of cloud points from current view parameters, unless the user
1094  // has forced through the vis attributes, thereby over-riding the
1095  // current view parameter.
1096  G4int numberOfCloudPoints = fpViewer->GetViewParameters().GetNumberOfCloudPoints();
1097  if (pVisAttribs -> IsForceDrawingStyle() &&
1098  pVisAttribs -> GetForcedDrawingStyle() == G4VisAttributes::cloud &&
1099  pVisAttribs -> GetForcedNumberOfCloudPoints() > 0) {
1100  numberOfCloudPoints = pVisAttribs -> GetForcedNumberOfCloudPoints();
1101  }
1102  return numberOfCloudPoints;
1103 }
1104 
1106  G4bool isAuxEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible ();
1107  if (pVisAttribs -> IsForceAuxEdgeVisible()) {
1108  isAuxEdgeVisible = pVisAttribs->IsForcedAuxEdgeVisible();
1109  }
1110  return isAuxEdgeVisible;
1111 }
1112 
1114 (const G4VMarker& marker,
1115  G4VSceneHandler::MarkerSizeType& markerSizeType)
1116 {
1117  G4bool userSpecified = marker.GetWorldSize() || marker.GetScreenSize();
1118  const G4VMarker& defaultMarker =
1119  fpViewer -> GetViewParameters().GetDefaultMarker();
1120  G4double size = userSpecified ?
1121  marker.GetWorldSize() : defaultMarker.GetWorldSize();
1122  if (size) {
1123  // Draw in world coordinates.
1124  markerSizeType = world;
1125  }
1126  else {
1127  size = userSpecified ?
1128  marker.GetScreenSize() : defaultMarker.GetScreenSize();
1129  // Draw in screen coordinates.
1130  markerSizeType = screen;
1131  }
1132  size *= fpViewer -> GetViewParameters().GetGlobalMarkerScale();
1133  if (markerSizeType == screen && size < 1.) size = 1.;
1134  return size;
1135 }
1136 
1138 {
1139  // No. of sides (lines segments per circle) is normally determined
1140  // by the view parameters, but it can be overriddden by the
1141  // ForceLineSegmentsPerCircle in the vis attributes.
1142  G4int lineSegmentsPerCircle = fpViewer->GetViewParameters().GetNoOfSides();
1143  if (pVisAttribs) {
1144  if (pVisAttribs->IsForceLineSegmentsPerCircle())
1145  lineSegmentsPerCircle = pVisAttribs->GetForcedLineSegmentsPerCircle();
1146  if (lineSegmentsPerCircle < pVisAttribs->GetMinLineSegmentsPerCircle()) {
1147  lineSegmentsPerCircle = pVisAttribs->GetMinLineSegmentsPerCircle();
1148  G4cout <<
1149  "G4VSceneHandler::GetNoOfSides: attempt to set the"
1150  "\nnumber of line segements per circle < " << lineSegmentsPerCircle
1151  << "; forced to " << pVisAttribs->GetMinLineSegmentsPerCircle() << G4endl;
1152  }
1153  }
1154  return lineSegmentsPerCircle;
1155 }
1156 
1157 std::ostream& operator << (std::ostream& os, const G4VSceneHandler& sh) {
1158 
1159  os << "Scene handler " << sh.fName << " has "
1160  << sh.fViewerList.size () << " viewer(s):";
1161  for (size_t i = 0; i < sh.fViewerList.size (); i++) {
1162  os << "\n " << *(sh.fViewerList [i]);
1163  }
1164 
1165  if (sh.fpScene) {
1166  os << "\n " << *sh.fpScene;
1167  }
1168  else {
1169  os << "\n This scene handler currently has no scene.";
1170  }
1171 
1172  return os;
1173 }