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