Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Scene.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 // Scene data John Allison 19th July 1996.
31 
32 #include "G4Scene.hh"
33 
34 #include "G4Vector3D.hh"
35 #include "G4BoundingSphereScene.hh"
36 #include "G4VisAttributes.hh"
37 #include "G4PhysicalVolumeModel.hh"
39 
41  fName (name),
42  fRefreshAtEndOfEvent(true),
43  fRefreshAtEndOfRun(true),
44  fMaxNumberOfKeptEvents(0)
45 {} // Note all other data members have default initial values.
46 
48 
50  std::vector<Model>::const_iterator i;
51  for (i = fRunDurationModelList.begin ();
52  i != fRunDurationModelList.end (); ++i) {
53  if (pModel -> GetGlobalDescription () ==
54  i->fpModel->GetGlobalDescription ()) break;
55  }
56  if (i != fRunDurationModelList.end ()) {
57  if (warn) {
58  G4cout << "G4Scene::AddRunDurationModel: model \""
59  << pModel -> GetGlobalDescription ()
60  << "\"\n is already in the run-duration list of scene \""
61  << fName
62  << "\"."
63  << G4endl;
64  }
65  return false;
66  }
67  fRunDurationModelList.push_back (Model(pModel));
68  CalculateExtent ();
69  return true;
70 }
71 
73 {
74  G4BoundingSphereScene boundingSphereScene;
75 
76  for (size_t i = 0; i < fRunDurationModelList.size(); i++) {
77  if (fRunDurationModelList[i].fActive) {
78  G4VModel* model = fRunDurationModelList[i].fpModel;
79  if (model -> Validate()) { // Validates and also recomputes extent.
80  const G4VisExtent& thisExtent = model -> GetExtent ();
81  G4double thisRadius = thisExtent.GetExtentRadius ();
82  if (thisRadius > 0.) {
83  G4Point3D thisCentre = thisExtent.GetExtentCentre ();
84  thisCentre.transform (model -> GetTransformation ());
85  boundingSphereScene.AccrueBoundingSphere (thisCentre, thisRadius);
86  }
87  } else {
89  ed << "Invalid model \"" << model->GetGlobalDescription()
90  << "\".\n Not included in extent calculation.";
92  ("G4Scene::CalculateExtent",
93  "visman0201", JustWarning, ed);
94  }
95  }
96  }
97 
98  for (size_t i = 0; i < fEndOfEventModelList.size(); i++) {
99  if (fEndOfEventModelList[i].fActive) {
100  G4VModel* model = fEndOfEventModelList[i].fpModel;
101  if (model -> Validate()) { // Validates and also recomputes extent.
102  const G4VisExtent& thisExtent = model -> GetExtent ();
103  G4double thisRadius = thisExtent.GetExtentRadius ();
104  if (thisRadius > 0.) {
105  G4Point3D thisCentre = thisExtent.GetExtentCentre ();
106  thisCentre.transform (model -> GetTransformation ());
107  boundingSphereScene.AccrueBoundingSphere (thisCentre, thisRadius);
108  }
109  } else {
111  ed << "Invalid model \"" << model->GetGlobalDescription()
112  << "\".\n Not included in extent calculation.";
114  ("G4Scene::CalculateExtent",
115  "visman0201", JustWarning, ed);
116  }
117  }
118  }
119 
120  for (size_t i = 0; i < fEndOfRunModelList.size(); i++) {
121  if (fEndOfRunModelList[i].fActive) {
122  G4VModel* model = fEndOfRunModelList[i].fpModel;
123  if (model -> Validate()) { // Validates and also recomputes extent.
124  const G4VisExtent& thisExtent = model -> GetExtent ();
125  G4double thisRadius = thisExtent.GetExtentRadius ();
126  if (thisRadius > 0.) {
127  G4Point3D thisCentre = thisExtent.GetExtentCentre ();
128  thisCentre.transform (model -> GetTransformation ());
129  boundingSphereScene.AccrueBoundingSphere (thisCentre, thisRadius);
130  }
131  } else {
133  ed << "Invalid model \"" << model->GetGlobalDescription()
134  << "\".\n Not included in extent calculation.";
136  ("G4Scene::CalculateExtent",
137  "visman0201", JustWarning, ed);
138  }
139  }
140  }
141 
142  fExtent = boundingSphereScene.GetBoundingSphereExtent ();
143  fStandardTargetPoint = fExtent.GetExtentCentre ();
144  if (fExtent.GetExtentRadius() <= 0.) {
146  ("G4Scene::CalculateExtent",
147  "visman0202", JustWarning,
148  "Scene has no extent. Please activate or add something."
149  "\nThe camera needs to have something to point at!"
150  "\n\"/vis/scene/list\" to see list of models.");
151  }
152 }
153 
155  G4bool successful = true;
156  if (IsEmpty ()) {
157  successful = false;
158  G4VPhysicalVolume* pWorld =
160  -> GetNavigatorForTracking () -> GetWorldVolume ();
161  if (pWorld) {
162  const G4VisAttributes* pVisAttribs =
163  pWorld -> GetLogicalVolume () -> GetVisAttributes ();
164  if (!pVisAttribs || pVisAttribs -> IsVisible ()) {
165  if (warn) {
166  G4cout <<
167  "Your \"world\" has no vis attributes or is marked as visible."
168  "\n For a better view of the contents, mark the world as"
169  " invisible, e.g.,"
170  "\n myWorldLogicalVol ->"
171  " SetVisAttributes (G4VisAttributes::Invisible);"
172  << G4endl;
173  }
174  }
175  successful = AddRunDurationModel (new G4PhysicalVolumeModel (pWorld));
176  // Note: default depth and no modeling parameters.
177  if (successful) {
178  if (warn) {
179  G4cout <<
180  "G4Scene::AddWorldIfEmpty: The scene was empty of run-duration models."
181  "\n \"world\" has been added.";
182  G4cout << G4endl;
183  }
184  }
185  }
186  }
187  return successful;
188 }
189 
191  G4int i, nModels = fEndOfEventModelList.size ();
192  for (i = 0; i < nModels; i++) {
193  if (pModel -> GetGlobalDescription () ==
194  fEndOfEventModelList[i].fpModel -> GetGlobalDescription ()) break;
195  }
196  if (i < nModels) {
197  if (warn) {
198  G4cout << "G4Scene::AddEndOfEventModel: a model \""
199  << pModel -> GetGlobalDescription ()
200  << "\"\n is already in the end-of-event list of scene \""
201  << fName << "\"."
202  << G4endl;
203  }
204  return false;
205  }
206  fEndOfEventModelList.push_back (Model(pModel));
207  return true;
208 }
209 
211  G4int i, nModels = fEndOfRunModelList.size ();
212  for (i = 0; i < nModels; i++) {
213  if (pModel -> GetGlobalDescription () ==
214  fEndOfRunModelList[i].fpModel -> GetGlobalDescription ()) break;
215  }
216  if (i < nModels) {
217  if (warn) {
218  G4cout << "G4Scene::AddEndOfRunModel: a model \""
219  << pModel -> GetGlobalDescription ()
220  << "\"\n is already in the end-of-run list of scene \""
221  << fName << "\"."
222  << G4endl;
223  }
224  return false;
225  }
226  fEndOfRunModelList.push_back (pModel);
227  return true;
228 }
229 
230 std::ostream& operator << (std::ostream& os, const G4Scene& scene) {
231 
232  size_t i;
233 
234  os << "Scene data:";
235 
236  os << "\n Run-duration model list:";
237  for (i = 0; i < scene.fRunDurationModelList.size (); i++) {
238  if (scene.fRunDurationModelList[i].fActive) os << "\n Active: ";
239  else os << "\n Inactive: ";
240  os << *(scene.fRunDurationModelList[i].fpModel);
241  }
242 
243  os << "\n End-of-event model list:";
244  for (i = 0; i < scene.fEndOfEventModelList.size (); i++) {
245  if (scene.fEndOfEventModelList[i].fActive) os << "\n Active: ";
246  else os << "\n Inactive: ";
247  os << *(scene.fEndOfEventModelList[i].fpModel);
248  }
249 
250  os << "\n End-of-run model list:";
251  for (i = 0; i < scene.fEndOfRunModelList.size (); i++) {
252  if (scene.fEndOfRunModelList[i].fActive) os << "\n Active: ";
253  else os << "\n Inactive: ";
254  os << *(scene.fEndOfRunModelList[i].fpModel);
255  }
256 
257  os << "\n Extent or bounding box: " << scene.fExtent;
258 
259  os << "\n Standard target point: " << scene.fStandardTargetPoint;
260 
261  os << "\n End of event action set to \"";
262  if (scene.fRefreshAtEndOfEvent) os << "refresh\"";
263  else {
264  os << "accumulate (maximum number of kept events: ";
265  if (scene.fMaxNumberOfKeptEvents >= 0) os << scene.fMaxNumberOfKeptEvents;
266  else os << "unlimited";
267  os << ")";
268  }
269 
270  os << "\n End of run action set to \"";
271  if (scene.fRefreshAtEndOfRun) os << "refresh";
272  else os << "accumulate";
273  os << "\"";
274 
275  return os;
276 }
277 
278 G4bool G4Scene::operator != (const G4Scene& scene) const {
279  if (
280  (fRunDurationModelList.size () !=
281  scene.fRunDurationModelList.size ()) ||
282  (fEndOfEventModelList.size () !=
283  scene.fEndOfEventModelList.size ()) ||
284  (fEndOfRunModelList.size () !=
285  scene.fEndOfRunModelList.size ()) ||
286  (fExtent != scene.fExtent) ||
287  !(fStandardTargetPoint == scene.fStandardTargetPoint) ||
288  fRefreshAtEndOfEvent != scene.fRefreshAtEndOfEvent ||
289  fRefreshAtEndOfRun != scene.fRefreshAtEndOfRun ||
290  fMaxNumberOfKeptEvents != scene.fMaxNumberOfKeptEvents
291  ) return true;
292 
293  /* A complete comparison should, perhaps, include a comparison of
294  individual models, but it is not easy to implement operator!= for
295  all models. Also, it would be unfeasible to ask users to
296  implement opeerator!= if we ever get round to allowing
297  user-defined models. Moreover, there is no editing of G4Scene
298  objects, apart from changing fRefreshAtEndOfEvent, etc; as far as
299  models are concerned, all you can ever do is add them, so a test
300  on size (above) is enough.
301 
302  for (size_t i = 0; i < fRunDurationModelList.size (); i++) {
303  if (fRunDurationModelList[i] != scene.fRunDurationModelList[i])
304  return true;
305  }
306 
307  for (size_t i = 0; i < fEndOfEventModelList.size (); i++) {
308  if (fEndOfEventModelList[i] != scene.fEndOfEventModelList[i])
309  return true;
310  }
311 
312  for (size_t i = 0; i < fEndOfRunModelList.size (); i++) {
313  if (fEndOfRunModelList[i] != scene.fEndOfRunModelList[i])
314  return true;
315  }
316  */
317 
318  return false;
319 }