Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VisCommandsSceneAdd.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 // /vis/scene/add commands - John Allison 9th August 1998
29 
30 #include "G4VisCommandsSceneAdd.hh"
31 
33 #include "G4LogicalVolumeStore.hh"
34 #include "G4PhysicalVolumeModel.hh"
35 #include "G4LogicalVolumeModel.hh"
36 #include "G4ModelingParameters.hh"
37 #include "G4HitsModel.hh"
38 #include "G4DigiModel.hh"
39 #include "G4PSHitsModel.hh"
40 #include "G4TrajectoriesModel.hh"
41 #include "G4ScaleModel.hh"
42 #include "G4TextModel.hh"
43 #include "G4ArrowModel.hh"
44 #include "G4AxesModel.hh"
47 #include "G4ParticleTable.hh"
48 #include "G4ParticleDefinition.hh"
50 #include "G4ApplicationState.hh"
51 #include "G4VUserVisAction.hh"
52 #include "G4CallbackModel.hh"
53 #include "G4UnionSolid.hh"
54 #include "G4SubtractionSolid.hh"
55 #include "G4Polyhedron.hh"
56 #include "G4UImanager.hh"
57 #include "G4UIcommand.hh"
58 #include "G4UIcmdWithAString.hh"
60 #include "G4Tokenizer.hh"
61 #include "G4RunManager.hh"
62 #include "G4StateManager.hh"
63 #include "G4Run.hh"
64 #include "G4Event.hh"
67 #include "G4PropagatorInField.hh"
68 #include "G4Trajectory.hh"
69 #include "G4TrajectoryPoint.hh"
70 #include "G4RichTrajectory.hh"
71 #include "G4RichTrajectoryPoint.hh"
72 #include "G4SmoothTrajectory.hh"
74 #include "G4AttDef.hh"
75 #include "G4Polyline.hh"
76 #include "G4UnitsTable.hh"
77 #include "G4PhysicalConstants.hh"
78 #include "G4SystemOfUnits.hh"
79 
80 #include <sstream>
81 
82 // Local function with some frequently used error printing...
83 static void G4VisCommandsSceneAddUnsuccessful
84 (G4VisManager::Verbosity verbosity) {
85  if (verbosity >= G4VisManager::warnings) {
86  G4cout <<
87  "WARNING: For some reason, possibly mentioned above, it has not been"
88  "\n possible to add to the scene."
89  << G4endl;
90  }
91 }
92 
94 
96  fpCommand = new G4UIcommand("/vis/scene/add/arrow", this);
97  fpCommand -> SetGuidance ("Adds arrow to current scene.");
98  G4bool omitable;
99  G4UIparameter* parameter;
100  parameter = new G4UIparameter ("x1", 'd', omitable = false);
101  fpCommand -> SetParameter (parameter);
102  parameter = new G4UIparameter ("y1", 'd', omitable = false);
103  fpCommand -> SetParameter (parameter);
104  parameter = new G4UIparameter ("z1", 'd', omitable = false);
105  fpCommand -> SetParameter (parameter);
106  parameter = new G4UIparameter ("x2", 'd', omitable = false);
107  fpCommand -> SetParameter (parameter);
108  parameter = new G4UIparameter ("y2", 'd', omitable = false);
109  fpCommand -> SetParameter (parameter);
110  parameter = new G4UIparameter ("z2", 'd', omitable = false);
111  fpCommand -> SetParameter (parameter);
112  parameter = new G4UIparameter ("unit", 's', omitable = true);
113  parameter->SetDefaultValue ("m");
114  fpCommand->SetParameter (parameter);
115 }
116 
118  delete fpCommand;
119 }
120 
122  return "";
123 }
124 
126 {
128  G4bool warn(verbosity >= G4VisManager::warnings);
129 
130  G4Scene* pScene = fpVisManager->GetCurrentScene();
131  if (!pScene) {
132  if (verbosity >= G4VisManager::errors) {
133  G4cout << "ERROR: No current scene. Please create one." << G4endl;
134  }
135  return;
136  }
137 
138  G4String unitString;
139  G4double x1, y1, z1, x2, y2, z2;
140  std::istringstream is(newValue);
141  is >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> unitString;
142  G4double unit = G4UIcommand::ValueOf(unitString);
143  x1 *= unit; y1 *= unit; z1 *= unit;
144  x2 *= unit; y2 *= unit; z2 *= unit;
145 
146  // Consult scene for arrow width.
147  const G4VisExtent& sceneExtent = pScene->GetExtent();
148  G4double arrowWidth =
149  0.005 * fCurrentLineWidth * sceneExtent.GetExtentRadius();
150 
152  (x1, y1, z1, x2, y2, z2,
153  arrowWidth, fCurrentColour, newValue);
154 
155  const G4String& currentSceneName = pScene -> GetName ();
156  G4bool successful = pScene -> AddRunDurationModel (model, warn);
157  if (successful) {
158  if (verbosity >= G4VisManager::confirmations) {
159  G4cout << "Arrow has been added to scene \""
160  << currentSceneName << "\"."
161  << G4endl;
162  }
163  }
164  else G4VisCommandsSceneAddUnsuccessful(verbosity);
165  UpdateVisManagerScene (currentSceneName);
166 }
167 
169 
171  fpCommand = new G4UIcommand("/vis/scene/add/arrow2D", this);
172  fpCommand -> SetGuidance ("Adds 2D arrow to current scene.");
173  G4bool omitable;
174  G4UIparameter* parameter;
175  parameter = new G4UIparameter ("x1", 'd', omitable = false);
176  fpCommand -> SetParameter (parameter);
177  parameter = new G4UIparameter ("y1", 'd', omitable = false);
178  fpCommand -> SetParameter (parameter);
179  parameter = new G4UIparameter ("x2", 'd', omitable = false);
180  fpCommand -> SetParameter (parameter);
181  parameter = new G4UIparameter ("y2", 'd', omitable = false);
182  fpCommand -> SetParameter (parameter);
183 }
184 
186  delete fpCommand;
187 }
188 
190  return "";
191 }
192 
194 {
196  G4bool warn(verbosity >= G4VisManager::warnings);
197 
198  G4Scene* pScene = fpVisManager->GetCurrentScene();
199  if (!pScene) {
200  if (verbosity >= G4VisManager::errors) {
201  G4cout << "ERROR: No current scene. Please create one." << G4endl;
202  }
203  return;
204  }
205 
206  G4double x1, y1, x2, y2;
207  std::istringstream is(newValue);
208  is >> x1 >> y1 >> x2 >> y2;
209 
210  Arrow2D* arrow2D = new Arrow2D
211  (x1, y1, x2, y2, fCurrentLineWidth, fCurrentColour);
212  G4VModel* model =
214  model->SetType("Arrow2D");
215  model->SetGlobalTag("Arrow2D");
216  model->SetGlobalDescription("Arrow2D: " + newValue);
217  const G4String& currentSceneName = pScene -> GetName ();
218  G4bool successful = pScene -> AddRunDurationModel (model, warn);
219  if (successful) {
220  if (verbosity >= G4VisManager::confirmations) {
221  G4cout << "A 2D arrow has been added to scene \""
222  << currentSceneName << "\"."
223  << G4endl;
224  }
225  }
226  else G4VisCommandsSceneAddUnsuccessful(verbosity);
227  UpdateVisManagerScene (currentSceneName);
228 }
229 
230 G4VisCommandSceneAddArrow2D::Arrow2D::Arrow2D
233  G4double width, const G4Colour& colour):
234  fWidth(width), fColour(colour)
235 {
236  fShaftPolyline.push_back(G4Point3D(x1,y1,0));
237  fShaftPolyline.push_back(G4Point3D(x2,y2,0));
238  G4Vector3D arrowDirection = G4Vector3D(x2-x1,y2-y1,0).unit();
239  G4Vector3D arrowPointLeftDirection(arrowDirection);
240  arrowPointLeftDirection.rotateZ(150.*deg);
241  G4Vector3D arrowPointRightDirection(arrowDirection);
242  arrowPointRightDirection.rotateZ(-150.*deg);
243  fHeadPolyline.push_back(G4Point3D(x2,y2,0)+0.04*arrowPointLeftDirection);
244  fHeadPolyline.push_back(G4Point3D(x2,y2,0));
245  fHeadPolyline.push_back(G4Point3D(x2,y2,0)+0.04*arrowPointRightDirection);
246  G4VisAttributes va;
247  va.SetLineWidth(fWidth);
248  va.SetColour(fColour);
249  fShaftPolyline.SetVisAttributes(va);
250  fHeadPolyline.SetVisAttributes(va);
251 }
252 
253 void G4VisCommandSceneAddArrow2D::Arrow2D::operator()
254  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
255 {
256  sceneHandler.BeginPrimitives2D();
257  sceneHandler.AddPrimitive(fShaftPolyline);
258  sceneHandler.AddPrimitive(fHeadPolyline);
259  sceneHandler.EndPrimitives2D();
260 }
261 
263 
265  G4bool omitable;
266  fpCommand = new G4UIcommand ("/vis/scene/add/axes", this);
267  fpCommand -> SetGuidance ("Add axes.");
268  fpCommand -> SetGuidance
269  ("Draws axes at (x0, y0, z0) of given length and colour.");
270  G4UIparameter* parameter;
271  parameter = new G4UIparameter ("x0", 'd', omitable = true);
272  parameter->SetDefaultValue (0.);
273  fpCommand->SetParameter (parameter);
274  parameter = new G4UIparameter ("y0", 'd', omitable = true);
275  parameter->SetDefaultValue (0.);
276  fpCommand->SetParameter (parameter);
277  parameter = new G4UIparameter ("z0", 'd', omitable = true);
278  parameter->SetDefaultValue (0.);
279  fpCommand->SetParameter (parameter);
280  parameter = new G4UIparameter ("length", 'd', omitable = true);
281  parameter->SetDefaultValue (-1.);
282  parameter->SetGuidance
283  ("If negative, length automatic, about 25% of scene extent.");
284  fpCommand->SetParameter (parameter);
285  parameter = new G4UIparameter ("unit", 's', omitable = true);
286  parameter->SetDefaultValue ("m");
287  fpCommand->SetParameter (parameter);
288  parameter = new G4UIparameter ("unitcolour", 's', omitable = true);
289  parameter->SetDefaultValue ("auto");
290  parameter->SetGuidance
291  ("If \"auto\", x, y and z will be red, green and blue respectively.");
292  parameter->SetGuidance
293  ("Otherwise choose from the pre-defined text-specified colours - "
294  "\n see information printed by the vis manager at start-up or"
295  "\n use \"/vis/list\".");
296  fpCommand->SetParameter (parameter);
297 }
298 
300  delete fpCommand;
301 }
302 
304  return "";
305 }
306 
308 
310  G4bool warn(verbosity >= G4VisManager::warnings);
311 
312  G4Scene* pScene = fpVisManager->GetCurrentScene();
313  if (!pScene) {
314  if (verbosity >= G4VisManager::errors) {
315  G4cout << "ERROR: No current scene. Please create one." << G4endl;
316  }
317  return;
318  }
319 
320  G4String unitString, colourString;
321  G4double x0, y0, z0, length;
322  std::istringstream is (newValue);
323  is >> x0 >> y0 >> z0 >> length >> unitString >> colourString;
324 
325  G4double unit = G4UIcommand::ValueOf(unitString);
326  x0 *= unit; y0 *= unit; z0 *= unit;
327  const G4VisExtent& sceneExtent = pScene->GetExtent(); // Existing extent.
328  if (length < 0.) {
329  length = 0.5 * sceneExtent.GetExtentRadius();
330  G4double intLog10Length = std::floor(std::log10(length));
331  length = std::pow(10,intLog10Length);
332  } else {
333  length *= unit;
334  }
335  G4String annotation = G4BestUnit(length,"Length");
336 
337  // Consult scene for arrow width...
338  G4double arrowWidth =
339  0.005 * fCurrentLineWidth * sceneExtent.GetExtentRadius();
340  // ...but limit it to length/50.
341  if (arrowWidth > length/50.) arrowWidth = length/50.;
342 
343  G4VModel* model = new G4AxesModel
344  (x0, y0, z0, length, arrowWidth, colourString, newValue);
345 
346  G4bool successful = pScene -> AddRunDurationModel (model, warn);
347  const G4String& currentSceneName = pScene -> GetName ();
348  if (successful) {
349  if (verbosity >= G4VisManager::confirmations) {
350  G4cout << "Axes have been added to scene \"" << currentSceneName << "\"."
351  << G4endl;
352  }
353  }
354  else G4VisCommandsSceneAddUnsuccessful(verbosity);
355  UpdateVisManagerScene (currentSceneName);
356 }
357 
359 
361  G4bool omitable;
362  fpCommand = new G4UIcommand ("/vis/scene/add/date", this);
363  fpCommand -> SetGuidance ("Adds date to current scene.");
364  G4UIparameter* parameter;
365  parameter = new G4UIparameter ("size", 'i', omitable = true);
366  parameter -> SetGuidance ("Screen size of text in pixels.");
367  parameter -> SetDefaultValue (18);
368  fpCommand -> SetParameter (parameter);
369  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
370  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
371  parameter -> SetDefaultValue (0.0); // Would prefer 0.95 right.
372  fpCommand -> SetParameter (parameter);
373  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
374  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
375  parameter -> SetDefaultValue (0.9);
376  fpCommand -> SetParameter (parameter);
377  parameter = new G4UIparameter ("layout", 's', omitable = true);
378  parameter -> SetGuidance ("Layout, i.e., adjustment: left|centre|right.");
379  parameter -> SetDefaultValue ("left"); // Would prefer right.
380  fpCommand -> SetParameter (parameter);
381  parameter = new G4UIparameter ("date", 's', omitable = true);
382  parameter -> SetGuidance
383  ("The date you want to appear on the view of the scene (this includes the"
384  "\nrest of the line, including spaces). The default, \'-\', writes the"
385  "\ndate and time of the moment of drawing.");
386  parameter -> SetDefaultValue ("-");
387  fpCommand -> SetParameter (parameter);
388 }
389 
391  delete fpCommand;
392 }
393 
395  return "";
396 }
397 
399 {
401  G4bool warn(verbosity >= G4VisManager::warnings);
402 
403  G4Scene* pScene = fpVisManager->GetCurrentScene();
404  if (!pScene) {
405  if (verbosity >= G4VisManager::errors) {
406  G4cout << "ERROR: No current scene. Please create one." << G4endl;
407  }
408  return;
409  }
410 
411  G4int size;
412  G4double x, y;
413  G4String layoutString, dateString;
414  std::istringstream is(newValue);
415  is >> size >> x >> y >> layoutString >> dateString;
416  // Read rest of line, if any.
417  const size_t NREMAINDER = 100;
418  char remainder[NREMAINDER];
419  is.getline(remainder, NREMAINDER);
420  dateString += remainder;
421  G4Text::Layout layout = G4Text::right;
422  if (layoutString(0) == 'l') layout = G4Text::left;
423  else if (layoutString(0) == 'c') layout = G4Text::centre;
424  else if (layoutString(0) == 'r') layout = G4Text::right;
425 
426  Date* date = new Date(fpVisManager, size, x, y, layout, dateString);
427  G4VModel* model =
429  model->SetType("Date");
430  model->SetGlobalTag("Date");
431  model->SetGlobalDescription("Date");
432  const G4String& currentSceneName = pScene -> GetName ();
433  G4bool successful = pScene -> AddRunDurationModel (model, warn);
434  if (successful) {
435  if (verbosity >= G4VisManager::confirmations) {
436  G4cout << "Date has been added to scene \""
437  << currentSceneName << "\"."
438  << G4endl;
439  }
440  }
441  else G4VisCommandsSceneAddUnsuccessful(verbosity);
442  UpdateVisManagerScene (currentSceneName);
443 }
444 
445 void G4VisCommandSceneAddDate::Date::operator()
446  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
447 {
448  G4String time;
449  if (fDate == "-") {
450  time = fTimer.GetClockTime();
451  } else {
452  time = fDate;
453  }
454  // Check for \n, starting from back, and erase.
455  std::string::size_type i = time.rfind('\n');
456  if (i != std::string::npos) time.erase(i);
457  G4Text text(time, G4Point3D(fX, fY, 0.));
458  text.SetScreenSize(fSize);
459  text.SetLayout(fLayout);
460  G4VisAttributes textAtts(G4Colour(0.,1.,1));
461  text.SetVisAttributes(textAtts);
462  sceneHandler.BeginPrimitives2D();
463  sceneHandler.AddPrimitive(text);
464  sceneHandler.EndPrimitives2D();
465 }
466 
468 
470  fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/add/digis", this);
471  fpCommand -> SetGuidance ("Adds digis to current scene.");
472  fpCommand -> SetGuidance
473  ("Digis are drawn at end of event when the scene in which"
474  "\nthey are added is current.");
475 }
476 
478  delete fpCommand;
479 }
480 
482  return "";
483 }
484 
486 
488  G4bool warn(verbosity >= G4VisManager::warnings);
489 
490  G4Scene* pScene = fpVisManager->GetCurrentScene();
491  if (!pScene) {
492  if (verbosity >= G4VisManager::errors) {
493  G4cout << "ERROR: No current scene. Please create one." << G4endl;
494  }
495  return;
496  }
497 
499  const G4String& currentSceneName = pScene -> GetName ();
500  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
501  if (successful) {
502  if (verbosity >= G4VisManager::confirmations) {
503  G4cout << "Digis, if any, will be drawn at end of run in scene \""
504  << currentSceneName << "\"."
505  << G4endl;
506  }
507  }
508  else G4VisCommandsSceneAddUnsuccessful(verbosity);
509  UpdateVisManagerScene (currentSceneName);
510 }
511 
513 
515  G4bool omitable;
516  fpCommand = new G4UIcommand ("/vis/scene/add/eventID", this);
517  fpCommand -> SetGuidance ("Adds eventID to current scene.");
518  fpCommand -> SetGuidance
519  ("Run and event numbers are drawn at end of event or run when"
520  "\n the scene in which they are added is current.");
521  G4UIparameter* parameter;
522  parameter = new G4UIparameter ("size", 'i', omitable = true);
523  parameter -> SetGuidance ("Screen size of text in pixels.");
524  parameter -> SetDefaultValue (18);
525  fpCommand -> SetParameter (parameter);
526  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
527  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
528  parameter -> SetDefaultValue (-0.95);
529  fpCommand -> SetParameter (parameter);
530  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
531  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
532  parameter -> SetDefaultValue (0.9);
533  fpCommand -> SetParameter (parameter);
534  parameter = new G4UIparameter ("layout", 's', omitable = true);
535  parameter -> SetGuidance ("Layout, i.e., adjustment: left|centre|right.");
536  parameter -> SetDefaultValue ("left");
537  fpCommand -> SetParameter (parameter);
538 }
539 
541  delete fpCommand;
542 }
543 
545  return "";
546 }
547 
549 {
551  G4bool warn(verbosity >= G4VisManager::warnings);
552 
553  G4Scene* pScene = fpVisManager->GetCurrentScene();
554  if (!pScene) {
555  if (verbosity >= G4VisManager::errors) {
556  G4cout << "ERROR: No current scene. Please create one." << G4endl;
557  }
558  return;
559  }
560 
561  G4int size;
562  G4double x, y;
563  G4String layoutString;
564  std::istringstream is(newValue);
565  is >> size >> x >> y >> layoutString;
566 
567  G4Text::Layout layout = G4Text::right;
568  if (layoutString(0) == 'l') layout = G4Text::left;
569  else if (layoutString(0) == 'c') layout = G4Text::centre;
570  else if (layoutString(0) == 'r') layout = G4Text::right;
571 
572  EventID* eventID = new EventID(fpVisManager, size, x, y, layout);
573  G4VModel* model =
575  model->SetType("EventID");
576  model->SetGlobalTag("EventID");
577  model->SetGlobalDescription("EventID");
578  const G4String& currentSceneName = pScene -> GetName ();
579  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
580  if (successful) {
581  if (verbosity >= G4VisManager::confirmations) {
582  G4cout << "EventID has been added to scene \""
583  << currentSceneName << "\"."
584  << G4endl;
585  }
586  }
587  else G4VisCommandsSceneAddUnsuccessful(verbosity);
588  UpdateVisManagerScene (currentSceneName);
589 }
590 
591 void G4VisCommandSceneAddEventID::EventID::operator()
592  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
593 {
594  const G4Run* currentRun = 0;
596  if (runManager) currentRun = runManager->GetCurrentRun();
597 
598  G4VModel* model = fpVisManager->GetCurrentSceneHandler()->GetModel();
599  const G4ModelingParameters* mp = 0;
600  const G4Event* currentEvent = 0;
601  if (model) {
602  mp = model->GetModelingParameters();
603  currentEvent = mp->GetEvent();
604  } else {
605  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
606  if (verbosity >= G4VisManager::errors) {
607  G4cout << "ERROR: No model defined for this SceneHandler : "
608  << fpVisManager->GetCurrentSceneHandler()->GetName()
609  << G4endl;
610  }
611  }
612  if (currentRun && currentEvent) {
613  G4int runID = currentRun->GetRunID();
614  G4int eventID = currentEvent->GetEventID();
615  std::ostringstream oss;
616  if (fpVisManager->GetCurrentScene()->GetRefreshAtEndOfEvent()) {
617  oss << "Run " << runID << " Event " << eventID;
618  } else {
619  G4int nEvents = 0;
621  G4ApplicationState state = stateManager->GetCurrentState();
622  if (state == G4State_EventProc) {
623  nEvents = currentRun->GetNumberOfEventToBeProcessed();
624  } else {
625  const std::vector<const G4Event*>* events =
626  currentRun->GetEventVector();
627  if (events) nEvents = events->size();
628  }
629  if (eventID < nEvents - 1) return; // Not last event.
630  else {
631  oss << "Run " << runID << " (" << nEvents << " event";
632  if (nEvents != 1) oss << 's';
633  oss << ')';
634  }
635  }
636  G4Text text(oss.str(), G4Point3D(fX, fY, 0.));
637  text.SetScreenSize(fSize);
638  text.SetLayout(fLayout);
639  G4VisAttributes textAtts(G4Colour(0.,1.,1));
640  text.SetVisAttributes(textAtts);
641  sceneHandler.BeginPrimitives2D();
642  sceneHandler.AddPrimitive(text);
643  sceneHandler.EndPrimitives2D();
644  }
645 }
646 
648 
650  fpCommand = new G4UIcommand("/vis/scene/add/frame", this);
651  fpCommand -> SetGuidance ("Adds frame to current scene.");
652  G4bool omitable;
653  G4UIparameter* parameter;
654  parameter = new G4UIparameter ("size", 'd', omitable = true);
655  parameter -> SetGuidance ("Size of frame. 1 = full window.");
656  parameter -> SetParameterRange ("size > 0 && size <=1");
657  parameter -> SetDefaultValue (0.97);
658  fpCommand -> SetParameter (parameter);
659 }
660 
662  delete fpCommand;
663 }
664 
666  return "";
667 }
668 
670 {
672  G4bool warn(verbosity >= G4VisManager::warnings);
673 
674  G4Scene* pScene = fpVisManager->GetCurrentScene();
675  if (!pScene) {
676  if (verbosity >= G4VisManager::errors) {
677  G4cout << "ERROR: No current scene. Please create one." << G4endl;
678  }
679  return;
680  }
681 
682  G4double size;
683  std::istringstream is(newValue);
684  is >> size;
685 
686  Frame* frame = new Frame(size, fCurrentLineWidth, fCurrentColour);
687  G4VModel* model =
689  model->SetType("Frame");
690  model->SetGlobalTag("Frame");
691  model->SetGlobalDescription("Frame: " + newValue);
692  const G4String& currentSceneName = pScene -> GetName ();
693  G4bool successful = pScene -> AddRunDurationModel (model, warn);
694  if (successful) {
695  if (verbosity >= G4VisManager::confirmations) {
696  G4cout << "Frame has been added to scene \""
697  << currentSceneName << "\"."
698  << G4endl;
699  }
700  }
701  else G4VisCommandsSceneAddUnsuccessful(verbosity);
702  UpdateVisManagerScene (currentSceneName);
703 }
704 
705 void G4VisCommandSceneAddFrame::Frame::operator()
706  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
707 {
708  G4Polyline frame;
709  frame.push_back(G4Point3D( fSize, fSize, 0.));
710  frame.push_back(G4Point3D(-fSize, fSize, 0.));
711  frame.push_back(G4Point3D(-fSize, -fSize, 0.));
712  frame.push_back(G4Point3D( fSize, -fSize, 0.));
713  frame.push_back(G4Point3D( fSize, fSize, 0.));
714  G4VisAttributes va;
715  va.SetLineWidth(fWidth);
716  va.SetColour(fColour);
717  frame.SetVisAttributes(va);
718  sceneHandler.BeginPrimitives2D();
719  sceneHandler.AddPrimitive(frame);
720  sceneHandler.EndPrimitives2D();
721 }
722 
724 
726  G4bool omitable;
727  fpCommand = new G4UIcmdWithAString ("/vis/scene/add/ghosts", this);
728  fpCommand -> SetGuidance
729  ("Adds ghost volumes (G4FlavoredParallelWorld) to the current scene.");
730  fpCommand -> SetGuidance ("Selects by particle.");
731  fpCommand -> SetParameterName ("particle", omitable = true);
732  fpCommand -> SetDefaultValue ("all");
733 }
734 
736  delete fpCommand;
737 }
738 
740  return "";
741 }
742 
744 
746  G4bool warn(verbosity >= G4VisManager::warnings);
747 
748  G4Scene* pScene = fpVisManager->GetCurrentScene();
749  if (!pScene) {
750  if (verbosity >= G4VisManager::errors) {
751  G4cout << "ERROR: No current scene. Please create one." << G4endl;
752  }
753  return;
754  }
755  const G4String& currentSceneName = pScene -> GetName ();
756 
757  // Gets the G4GlobalFastSimulationManager pointer if any.
758  G4VGlobalFastSimulationManager* theGlobalFastSimulationManager;
759  if(!(theGlobalFastSimulationManager =
761  if (verbosity >= G4VisManager::errors) {
762  G4cout << "ERROR: no G4GlobalFastSimulationManager" << G4endl;
763  }
764  return;
765  }
766 
767  // Gets the G4ParticleTable pointer.
769 
770  // If "all" (the default) loops on all known particles
771  if(newValue=="all")
772  {
773  G4VFlavoredParallelWorld* CurrentFlavoredWorld = 0;
774  G4bool successful = false;
775  for (G4int iParticle=0; iParticle<theParticleTable->entries();
776  iParticle++)
777  {
778  CurrentFlavoredWorld = theGlobalFastSimulationManager->
779  GetFlavoredWorldForThis(theParticleTable->GetParticle(iParticle));
780 
781  if(CurrentFlavoredWorld)
782  successful = successful || pScene ->
783  AddRunDurationModel(new G4FlavoredParallelWorldModel
784  (CurrentFlavoredWorld), warn);
785  }
786  if (successful)
787  {
788  if (verbosity >= G4VisManager::confirmations)
789  G4cout << "Ghosts have been added to scene \""
790  << currentSceneName << "\"."
791  << G4endl;
792  UpdateVisManagerScene (currentSceneName);
793  }
794  else
795  {
796  G4cout << "ERROR: There are no ghosts."<<G4endl;
797  G4VisCommandsSceneAddUnsuccessful(verbosity);
798  }
799  return;
800  }
801 
802  // Given a particle name looks just for the concerned Ghosts, if any.
803  G4ParticleDefinition* currentParticle =
804  theParticleTable->FindParticle(newValue);
805 
806  if (currentParticle == NULL)
807  {
808  if (verbosity >= G4VisManager::errors)
809  G4cout << "ERROR: \"" << newValue
810  << "\": not found this particle name!" << G4endl;
811  return;
812  }
813 
814  G4VFlavoredParallelWorld* worldForThis =
815  theGlobalFastSimulationManager->GetFlavoredWorldForThis(currentParticle);
816  if(worldForThis)
817  {
818  G4bool successful = pScene -> AddRunDurationModel
819  (new G4FlavoredParallelWorldModel (worldForThis), warn);
820  if (successful) {
821  if (verbosity >= G4VisManager::confirmations)
822  G4cout << "Ghosts have been added to scene \""
823  << currentSceneName << "\"."
824  << G4endl;
825  UpdateVisManagerScene (currentSceneName);
826  }
827  }
828  else
829  if (verbosity >= G4VisManager::errors)
830  {
831  G4cout << "ERROR: There are no ghosts for \""<<newValue<<"\""<<G4endl;
832  G4VisCommandsSceneAddUnsuccessful(verbosity);
833  }
834 }
835 
836 
838 
840  fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/add/hits", this);
841  fpCommand -> SetGuidance ("Adds hits to current scene.");
842  fpCommand -> SetGuidance
843  ("Hits are drawn at end of event when the scene in which"
844  "\nthey are added is current.");
845 }
846 
848  delete fpCommand;
849 }
850 
852  return "";
853 }
854 
856 
858  G4bool warn(verbosity >= G4VisManager::warnings);
859 
860  G4Scene* pScene = fpVisManager->GetCurrentScene();
861  if (!pScene) {
862  if (verbosity >= G4VisManager::errors) {
863  G4cout << "ERROR: No current scene. Please create one." << G4endl;
864  }
865  return;
866  }
867 
868  G4HitsModel* model = new G4HitsModel;
869  const G4String& currentSceneName = pScene -> GetName ();
870  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
871  if (successful) {
872  if (verbosity >= G4VisManager::confirmations) {
873  G4cout << "Hits, if any, will be drawn at end of run in scene \""
874  << currentSceneName << "\"."
875  << G4endl;
876  }
877  }
878  else G4VisCommandsSceneAddUnsuccessful(verbosity);
879  UpdateVisManagerScene (currentSceneName);
880 }
881 
883 
885  fpCommand = new G4UIcommand("/vis/scene/add/line", this);
886  fpCommand -> SetGuidance ("Adds line to current scene.");
887  G4bool omitable;
888  G4UIparameter* parameter;
889  parameter = new G4UIparameter ("x1", 'd', omitable = false);
890  fpCommand -> SetParameter (parameter);
891  parameter = new G4UIparameter ("y1", 'd', omitable = false);
892  fpCommand -> SetParameter (parameter);
893  parameter = new G4UIparameter ("z1", 'd', omitable = false);
894  fpCommand -> SetParameter (parameter);
895  parameter = new G4UIparameter ("x2", 'd', omitable = false);
896  fpCommand -> SetParameter (parameter);
897  parameter = new G4UIparameter ("y2", 'd', omitable = false);
898  fpCommand -> SetParameter (parameter);
899  parameter = new G4UIparameter ("z2", 'd', omitable = false);
900  fpCommand -> SetParameter (parameter);
901  parameter = new G4UIparameter ("unit", 's', omitable = true);
902  parameter->SetDefaultValue ("m");
903  fpCommand->SetParameter (parameter);
904 }
905 
907  delete fpCommand;
908 }
909 
911  return "";
912 }
913 
915 {
917  G4bool warn(verbosity >= G4VisManager::warnings);
918 
919  G4Scene* pScene = fpVisManager->GetCurrentScene();
920  if (!pScene) {
921  if (verbosity >= G4VisManager::errors) {
922  G4cout << "ERROR: No current scene. Please create one." << G4endl;
923  }
924  return;
925  }
926 
927  G4String unitString;
928  G4double x1, y1, z1, x2, y2, z2;
929  std::istringstream is(newValue);
930  is >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> unitString;
931  G4double unit = G4UIcommand::ValueOf(unitString);
932  x1 *= unit; y1 *= unit; z1 *= unit;
933  x2 *= unit; y2 *= unit; z2 *= unit;
934 
935  Line* line = new Line(x1, y1, z1, x2, y2, z2,
937  G4VModel* model =
939  model->SetType("Line");
940  model->SetGlobalTag("Line");
941  model->SetGlobalDescription("Line: " + newValue);
942  const G4String& currentSceneName = pScene -> GetName ();
943  G4bool successful = pScene -> AddRunDurationModel (model, warn);
944  if (successful) {
945  if (verbosity >= G4VisManager::confirmations) {
946  G4cout << "Line has been added to scene \""
947  << currentSceneName << "\"."
948  << G4endl;
949  }
950  }
951  else G4VisCommandsSceneAddUnsuccessful(verbosity);
952  UpdateVisManagerScene (currentSceneName);
953 }
954 
955 G4VisCommandSceneAddLine::Line::Line
956 (G4double x1, G4double y1, G4double z1,
957  G4double x2, G4double y2, G4double z2,
958  G4double width, const G4Colour& colour):
959  fWidth(width), fColour(colour)
960 {
961  fPolyline.push_back(G4Point3D(x1,y1,z1));
962  fPolyline.push_back(G4Point3D(x2,y2,z2));
963  G4VisAttributes va;
964  va.SetLineWidth(fWidth);
965  va.SetColour(fColour);
966  fPolyline.SetVisAttributes(va);
967 }
968 
969 void G4VisCommandSceneAddLine::Line::operator()
970  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
971 {
972  sceneHandler.BeginPrimitives();
973  sceneHandler.AddPrimitive(fPolyline);
974  sceneHandler.EndPrimitives();
975 }
976 
978 
980  fpCommand = new G4UIcommand("/vis/scene/add/line2D", this);
981  fpCommand -> SetGuidance ("Adds 2D line to current scene.");
982  G4bool omitable;
983  G4UIparameter* parameter;
984  parameter = new G4UIparameter ("x1", 'd', omitable = false);
985  fpCommand -> SetParameter (parameter);
986  parameter = new G4UIparameter ("y1", 'd', omitable = false);
987  fpCommand -> SetParameter (parameter);
988  parameter = new G4UIparameter ("x2", 'd', omitable = false);
989  fpCommand -> SetParameter (parameter);
990  parameter = new G4UIparameter ("y2", 'd', omitable = false);
991  fpCommand -> SetParameter (parameter);
992 }
993 
995  delete fpCommand;
996 }
997 
999  return "";
1000 }
1001 
1003 {
1005  G4bool warn(verbosity >= G4VisManager::warnings);
1006 
1007  G4Scene* pScene = fpVisManager->GetCurrentScene();
1008  if (!pScene) {
1009  if (verbosity >= G4VisManager::errors) {
1010  G4cout << "ERROR: No current scene. Please create one." << G4endl;
1011  }
1012  return;
1013  }
1014 
1015  G4double x1, y1, x2, y2;
1016  std::istringstream is(newValue);
1017  is >> x1 >> y1 >> x2 >> y2;
1018 
1019  Line2D* line2D = new Line2D
1020  (x1, y1, x2, y2, fCurrentLineWidth, fCurrentColour);
1021  G4VModel* model =
1023  model->SetType("Line2D");
1024  model->SetGlobalTag("Line2D");
1025  model->SetGlobalDescription("Line2D: " + newValue);
1026  const G4String& currentSceneName = pScene -> GetName ();
1027  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1028  if (successful) {
1029  if (verbosity >= G4VisManager::confirmations) {
1030  G4cout << "A 2D line has been added to scene \""
1031  << currentSceneName << "\"."
1032  << G4endl;
1033  }
1034  }
1035  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1036  UpdateVisManagerScene (currentSceneName);
1037 }
1038 
1039 G4VisCommandSceneAddLine2D::Line2D::Line2D
1040 (G4double x1, G4double y1,
1041  G4double x2, G4double y2,
1042  G4double width, const G4Colour& colour):
1043  fWidth(width), fColour(colour)
1044 {
1045  fPolyline.push_back(G4Point3D(x1,y1,0));
1046  fPolyline.push_back(G4Point3D(x2,y2,0));
1047  G4VisAttributes va;
1048  va.SetLineWidth(fWidth);
1049  va.SetColour(fColour);
1050  fPolyline.SetVisAttributes(va);
1051 }
1052 
1053 void G4VisCommandSceneAddLine2D::Line2D::operator()
1054  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
1055 {
1056  sceneHandler.BeginPrimitives2D();
1057  sceneHandler.AddPrimitive(fPolyline);
1058  sceneHandler.EndPrimitives2D();
1059 }
1060 
1062 
1064  G4bool omitable;
1065  fpCommand = new G4UIcommand ("/vis/scene/add/logicalVolume", this);
1066  fpCommand -> SetGuidance ("Adds a logical volume to the current scene,");
1067  fpCommand -> SetGuidance
1068  ("Shows boolean components (if any), voxels (if any) and readout geometry"
1069  "\n(if any). Note: voxels are not constructed until start of run -"
1070  "\n \"/run/beamOn\".");
1071  G4UIparameter* parameter;
1072  parameter = new G4UIparameter ("logical-volume-name", 's', omitable = false);
1073  fpCommand -> SetParameter (parameter);
1074  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
1075  parameter -> SetGuidance ("Depth of descent of geometry hierarchy.");
1076  parameter -> SetDefaultValue (1);
1077  fpCommand -> SetParameter (parameter);
1078  parameter = new G4UIparameter ("booleans-flag", 'b', omitable = true);
1079  parameter -> SetDefaultValue (true);
1080  fpCommand -> SetParameter (parameter);
1081  parameter = new G4UIparameter ("voxels-flag", 'b', omitable = true);
1082  parameter -> SetDefaultValue (true);
1083  fpCommand -> SetParameter (parameter);
1084  parameter = new G4UIparameter ("readout-flag", 'b', omitable = true);
1085  parameter -> SetDefaultValue (true);
1086  fpCommand -> SetParameter (parameter);
1087 }
1088 
1090  delete fpCommand;
1091 }
1092 
1094  return "";
1095 }
1096 
1098  G4String newValue) {
1099 
1101  G4bool warn(verbosity >= G4VisManager::warnings);
1102 
1103  G4Scene* pScene = fpVisManager->GetCurrentScene();
1104  if (!pScene) {
1105  if (verbosity >= G4VisManager::errors) {
1106  G4cout << "ERROR: No current scene. Please create one." << G4endl;
1107  }
1108  return;
1109  }
1110 
1111  G4String name;
1112  G4int requestedDepthOfDescent;
1113  G4String booleansString, voxelsString, readoutString;
1114  std::istringstream is (newValue);
1115  is >> name >> requestedDepthOfDescent
1116  >> booleansString >> voxelsString >> readoutString;
1117  G4bool booleans = G4UIcommand::ConvertToBool(booleansString);
1118  G4bool voxels = G4UIcommand::ConvertToBool(voxelsString);
1119  G4bool readout = G4UIcommand::ConvertToBool(readoutString);
1120 
1122  int nLV = pLVStore -> size ();
1123  int iLV;
1124  G4LogicalVolume* pLV = 0;
1125  for (iLV = 0; iLV < nLV; iLV++ ) {
1126  pLV = (*pLVStore) [iLV];
1127  if (pLV -> GetName () == name) break;
1128  }
1129  if (iLV == nLV) {
1130  if (verbosity >= G4VisManager::errors) {
1131  G4cout << "ERROR: Logical volume " << name
1132  << " not found in logical volume store." << G4endl;
1133  }
1134  return;
1135  }
1136 
1137  const std::vector<G4Scene::Model>& rdModelList = pScene -> GetRunDurationModelList();
1138  std::vector<G4Scene::Model>::const_iterator i;
1139  for (i = rdModelList.begin(); i != rdModelList.end(); ++i) {
1140  if (i->fpModel->GetGlobalDescription().find("Volume") != std::string::npos) break;
1141  }
1142  if (i != rdModelList.end()) {
1143  if (verbosity >= G4VisManager::errors) {
1144  G4cout << "There is already a volume, \""
1145  << i->fpModel->GetGlobalDescription()
1146  << "\",\n in the run-duration model list of scene \""
1147  << pScene -> GetName()
1148  << "\".\n Your logical volume must be the only volume in the scene."
1149  << "\n Create a new scene and try again:"
1150  << "\n /vis/specify " << name
1151  << "\n or"
1152  << "\n /vis/scene/create"
1153  << "\n /vis/scene/add/logicalVolume " << name
1154  << "\n /vis/sceneHandler/attach"
1155  << "\n (and also, if necessary, /vis/viewer/flush)"
1156  << G4endl;
1157  }
1158  }
1159 
1160  G4VModel* model = new G4LogicalVolumeModel
1161  (pLV, requestedDepthOfDescent, booleans, voxels, readout);
1162  const G4String& currentSceneName = pScene -> GetName ();
1163  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1164  if (successful) {
1165  if (verbosity >= G4VisManager::confirmations) {
1166  G4cout << "Logical volume \"" << pLV -> GetName ()
1167  << " with requested depth of descent "
1168  << requestedDepthOfDescent
1169  << ",\n with";
1170  if (!booleans) G4cout << "out";
1171  G4cout << " boolean components, with";
1172  if (!voxels) G4cout << "out";
1173  G4cout << " voxels and with";
1174  if (!readout) G4cout << "out";
1175  G4cout << " readout geometry,"
1176  << "\n has been added to scene \"" << currentSceneName << "\"."
1177  << G4endl;
1178  }
1179  }
1180  else {
1181  G4VisCommandsSceneAddUnsuccessful(verbosity);
1182  return;
1183  }
1184 
1185  UpdateVisManagerScene (currentSceneName);
1186 }
1187 
1188 
1190 
1192  G4bool omitable;
1193  fpCommand = new G4UIcommand ("/vis/scene/add/logo", this);
1194  fpCommand -> SetGuidance ("Adds a G4 logo to the current scene.");
1195  G4UIparameter* parameter;
1196  parameter = new G4UIparameter ("height", 'd', omitable = true);
1197  parameter->SetDefaultValue (1.);
1198  fpCommand->SetParameter (parameter);
1199  parameter = new G4UIparameter ("unit", 's', omitable = true);
1200  parameter->SetGuidance
1201  ("auto or valid length unit - defaults to auto."
1202  "\nIf auto, height is roughly one tenth of scene extent.");
1203  parameter->SetDefaultValue ("auto");
1204  fpCommand->SetParameter (parameter);
1205  parameter = new G4UIparameter ("direction", 's', omitable = true);
1206  parameter->SetGuidance
1207  ("auto|[-]x|[-]y|[-]z - defaults to auto."
1208  "\nDirection of outward-facing normal to front face of logo."
1209  "\nIf automatic, logo faces the user in the current viewer.");
1210  parameter->SetDefaultValue ("auto");
1211  fpCommand->SetParameter (parameter);
1212  parameter = new G4UIparameter ("red", 'd', omitable = true);
1213  parameter->SetDefaultValue (0.);
1214  fpCommand->SetParameter (parameter);
1215  parameter = new G4UIparameter ("green", 'd', omitable = true);
1216  parameter->SetDefaultValue (1.);
1217  fpCommand->SetParameter (parameter);
1218  parameter = new G4UIparameter ("blue", 'd', omitable = true);
1219  parameter->SetDefaultValue (0.);
1220  fpCommand->SetParameter (parameter);
1221  parameter = new G4UIparameter ("auto|manual", 's', omitable = true);
1222  parameter->SetGuidance
1223  ("Automatic placement or manual placement at (xmid,ymid,zmid).");
1224  parameter->SetGuidance
1225  ("If automatic, placed at bottom right of screen when viewed from");
1226  parameter->SetGuidance
1227  ("logo direction.");
1228  parameter -> SetParameterCandidates("auto manual");
1229  parameter->SetDefaultValue ("auto");
1230  fpCommand->SetParameter (parameter);
1231  parameter = new G4UIparameter ("xmid", 'd', omitable = true);
1232  parameter->SetDefaultValue (0.);
1233  fpCommand->SetParameter (parameter);
1234  parameter = new G4UIparameter ("ymid", 'd', omitable = true);
1235  parameter->SetDefaultValue (0.);
1236  fpCommand->SetParameter (parameter);
1237  parameter = new G4UIparameter ("zmid", 'd', omitable = true);
1238  parameter->SetDefaultValue (0.);
1239  fpCommand->SetParameter (parameter);
1240  parameter = new G4UIparameter ("unit", 's', omitable = true);
1241  parameter->SetDefaultValue ("m");
1242  fpCommand->SetParameter (parameter);
1243 }
1244 
1246  delete fpCommand;
1247 }
1248 
1250  return "";
1251 }
1252 
1254 
1256  G4bool warn = verbosity >= G4VisManager::warnings;
1257 
1258  G4Scene* pScene = fpVisManager->GetCurrentScene();
1259  if (!pScene) {
1260  if (verbosity >= G4VisManager::errors) {
1261  G4cout << "ERROR: No current scene. Please create one." << G4endl;
1262  }
1263  return;
1264  }
1265 
1266  G4VViewer* pViewer = fpVisManager->GetCurrentViewer();
1267  if (!pViewer) {
1268  if (verbosity >= G4VisManager::errors) {
1269  G4cout <<
1270  "ERROR: G4VisCommandSceneAddLogo::SetNewValue: no viewer."
1271  "\n Auto direction needs a viewer."
1272  << G4endl;
1273  }
1274  return;
1275  }
1276 
1277  G4double userHeight, red, green, blue, xmid, ymid, zmid;
1278  G4String userHeightUnit, direction, auto_manual, positionUnit;
1279  std::istringstream is (newValue);
1280  is >> userHeight >> userHeightUnit >> direction
1281  >> red >> green >> blue
1282  >> auto_manual
1283  >> xmid >> ymid >> zmid >> positionUnit;
1284 
1285  G4double height = userHeight;
1286  const G4VisExtent& sceneExtent = pScene->GetExtent(); // Existing extent.
1287  if (userHeightUnit == "auto") {
1288  height *= 0.2 * sceneExtent.GetExtentRadius();
1289  } else {
1290  height *= G4UIcommand::ValueOf(userHeightUnit);
1291  }
1292 
1293  G4double unit = G4UIcommand::ValueOf(positionUnit);
1294  xmid *= unit; ymid *= unit; zmid *= unit;
1295 
1296  Direction logoDirection = X; // Initialise to keep some compilers happy.
1297  if (direction == "auto") {
1298  // Take cue from viewer
1299  const G4Vector3D& vp =
1301  if (vp.x() > vp.y() && vp.x() > vp.z()) logoDirection = X;
1302  else if (vp.x() < vp.y() && vp.x() < vp.z()) logoDirection = minusX;
1303  else if (vp.y() > vp.x() && vp.y() > vp.z()) logoDirection = Y;
1304  else if (vp.y() < vp.x() && vp.y() < vp.z()) logoDirection = minusY;
1305  else if (vp.z() > vp.x() && vp.z() > vp.y()) logoDirection = Z;
1306  else if (vp.z() < vp.x() && vp.z() < vp.y()) logoDirection = minusZ;
1307  }
1308  else if (direction(0) == 'x') logoDirection = X;
1309  else if (direction(0) == 'y') logoDirection = Y;
1310  else if (direction(0) == 'z') logoDirection = Z;
1311  else if (direction(0) == '-') {
1312  if (direction(1) == 'x') logoDirection = minusX;
1313  else if (direction(1) == 'y') logoDirection = minusY;
1314  else if (direction(1) == 'z') logoDirection = minusZ;
1315  } else {
1316  if (verbosity >= G4VisManager::errors) {
1317  G4cout << "ERROR: Unrecogniseed direction: \""
1318  << direction << "\"." << G4endl;
1319  return;
1320  }
1321  }
1322 
1323  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
1324  // Parameters read and interpreted.
1325 
1326  // Current scene extent
1327  const G4double xmin = sceneExtent.GetXmin();
1328  const G4double xmax = sceneExtent.GetXmax();
1329  const G4double ymin = sceneExtent.GetYmin();
1330  const G4double ymax = sceneExtent.GetYmax();
1331  const G4double zmin = sceneExtent.GetZmin();
1332  const G4double zmax = sceneExtent.GetZmax();
1333 
1334  // Test existing extent and issue warnings...
1335  G4bool worried = false;
1336  if (sceneExtent.GetExtentRadius() == 0) {
1337  worried = true;
1338  if (verbosity >= G4VisManager::warnings) {
1339  G4cout <<
1340  "WARNING: Existing scene does not yet have any extent."
1341  "\n Maybe you have not yet added any geometrical object."
1342  << G4endl;
1343  }
1344  }
1345 
1346  // Useful constants, etc...
1347  const G4double halfHeight(height / 2.);
1348  const G4double comfort(0.01); // 0.15 seems too big. 0.05 might be better.
1349  const G4double freeHeightFraction (1. + 2. * comfort);
1350 
1351  // Test existing scene for room...
1352  G4bool room = true;
1353  switch (logoDirection) {
1354  case X:
1355  case minusX:
1356  if (freeHeightFraction * (xmax - xmin) < height) room = false; break;
1357  case Y:
1358  case minusY:
1359  if (freeHeightFraction * (ymax - ymin) < height) room = false; break;
1360  case Z:
1361  case minusZ:
1362  if (freeHeightFraction * (zmax - zmin) < height) room = false; break;
1363  }
1364  if (!room) {
1365  worried = true;
1366  if (verbosity >= G4VisManager::warnings) {
1367  G4cout <<
1368  "WARNING: Not enough room in existing scene. Maybe logo is too large."
1369  << G4endl;
1370  }
1371  }
1372  if (worried) {
1373  if (verbosity >= G4VisManager::warnings) {
1374  G4cout <<
1375  "WARNING: The logo you have asked for is bigger than the existing"
1376  "\n scene. Maybe you have added it too soon. It is recommended that"
1377  "\n you add the logo last so that it can be correctly auto-positioned"
1378  "\n so as not to be obscured by any existing object and so that the"
1379  "\n view parameters can be correctly recalculated."
1380  << G4endl;
1381  }
1382  }
1383 
1384  G4double sxmid(xmid), symid(ymid), szmid(zmid);
1385  if (autoPlacing) {
1386  // Aim to place at bottom right of screen when viewed from logoDirection.
1387  // Give some comfort zone.
1388  const G4double xComfort = comfort * (xmax - xmin);
1389  const G4double yComfort = comfort * (ymax - ymin);
1390  const G4double zComfort = comfort * (zmax - zmin);
1391  switch (logoDirection) {
1392  case X: // y-axis up, z-axis to left?
1393  sxmid = xmax + halfHeight + xComfort;
1394  symid = ymin - yComfort;
1395  szmid = zmin - zComfort;
1396  break;
1397  case minusX: // y-axis up, z-axis to right?
1398  sxmid = xmin - halfHeight - xComfort;
1399  symid = ymin - yComfort;
1400  szmid = zmax + zComfort;
1401  break;
1402  case Y: // z-axis up, x-axis to left?
1403  sxmid = xmin - xComfort;
1404  symid = ymax + halfHeight + yComfort;
1405  szmid = zmin - zComfort;
1406  break;
1407  case minusY: // z-axis up, x-axis to right?
1408  sxmid = xmax + xComfort;
1409  symid = ymin - halfHeight - yComfort;
1410  szmid = zmin - zComfort;
1411  break;
1412  case Z: // y-axis up, x-axis to right?
1413  sxmid = xmax + xComfort;
1414  symid = ymin - yComfort;
1415  szmid = zmax + halfHeight + zComfort;
1416  break;
1417  case minusZ: // y-axis up, x-axis to left?
1418  sxmid = xmin - xComfort;
1419  symid = ymin - yComfort;
1420  szmid = zmin - halfHeight - zComfort;
1421  break;
1422  }
1423  }
1424 
1425  G4Transform3D transform;
1426  switch (logoDirection) {
1427  case X: // y-axis up, z-axis to left?
1428  transform = G4RotateY3D(halfpi);
1429  break;
1430  case minusX: // y-axis up, z-axis to right?
1431  transform = G4RotateY3D(-halfpi);
1432  break;
1433  case Y: // z-axis up, x-axis to left?
1434  transform = G4RotateX3D(-halfpi) * G4RotateZ3D(pi);
1435  break;
1436  case minusY: // z-axis up, x-axis to right?
1437  transform = G4RotateX3D(halfpi);
1438  break;
1439  case Z: // y-axis up, x-axis to right?
1440  // No transformation required.
1441  break;
1442  case minusZ: // y-axis up, x-axis to left?
1443  transform = G4RotateY3D(pi);
1444  break;
1445  }
1446  transform = G4Translate3D(sxmid,symid,szmid) * transform;
1447 
1448  G4VisAttributes visAtts(G4Colour(red, green, blue));
1449  visAtts.SetForceSolid(true); // Always solid.
1450 
1451  G4Logo* logo = new G4Logo(height,visAtts);
1452  G4VModel* model =
1454  model->SetType("G4Logo");
1455  model->SetGlobalTag("G4Logo");
1456  model->SetGlobalDescription("G4Logo: " + newValue);
1457  model->SetTransformation(transform);
1458  // Note: it is the responsibility of the model to act upon this, but
1459  // the extent is in local coordinates...
1460  G4double& h = height;
1461  G4double h2 = h/2.;
1462  G4VisExtent extent(-h,h,-h2,h2,-h2,h2);
1463  model->SetExtent(extent);
1464  // This extent gets "added" to existing scene extent in
1465  // AddRunDurationModel below.
1466  const G4String& currentSceneName = pScene -> GetName ();
1467  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1468  if (successful) {
1469  if (verbosity >= G4VisManager::confirmations) {
1470  G4cout << "G4 Logo of height " << userHeight << ' ' << userHeightUnit
1471  << ", " << direction << "-direction, added to scene \""
1472  << currentSceneName << "\"";
1473  if (verbosity >= G4VisManager::parameters) {
1474  G4cout << "\n with extent " << extent
1475  << "\n at " << transform.getRotation()
1476  << transform.getTranslation();
1477  }
1478  G4cout << G4endl;
1479  }
1480  }
1481  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1482  UpdateVisManagerScene (currentSceneName);
1483 }
1484 
1485 G4VisCommandSceneAddLogo::G4Logo::G4Logo
1486 (G4double height, const G4VisAttributes& visAtts):
1487  fHeight(height),
1488  fVisAtts(visAtts)
1489  {
1490  const G4double& h = height;
1491  const G4double h2 = 0.5 * h; // Half height.
1492  const G4double ri = 0.25 * h; // Inner radius.
1493  const G4double ro = 0.5 * h; // Outer radius.
1494  const G4double ro2 = 0.5 * ro; // Half outer radius.
1495  const G4double w = ro - ri; // Width.
1496  const G4double w2 = 0.5 * w; // Half width.
1497  const G4double d2 = 0.2 * h; // Half depth.
1498  const G4double f1 = 0.05 * h; // left edge of stem of "4".
1499  const G4double f2 = -0.3 * h; // bottom edge of cross of "4".
1500  const G4double e = 1.e-4 * h; // epsilon.
1501  const G4double xt = f1, yt = h2; // Top of slope.
1502  const G4double xb = -h2, yb = f2 + w; // Bottom of slope.
1503  const G4double dx = xt - xb, dy = yt - yb;
1504  const G4double angle = std::atan2(dy,dx);
1505  G4RotationMatrix rm;
1506  rm.rotateZ(angle*rad);
1507  const G4double d = std::sqrt(dx * dx + dy * dy);
1508  const G4double ss = h; // Half height of square subtractor
1509  const G4double y8 = ss; // Choose y of subtractor for outer slope.
1510  const G4double x8 = ((-ss * d - dx * (yt - y8)) / dy) + xt;
1511  G4double y9 = ss; // Choose y of subtractor for inner slope.
1512  G4double x9 = ((-(ss - w) * d - dx * (yt - y8)) / dy) + xt;
1513  // But to get inner, we make a triangle translated by...
1514  const G4double xtr = ss - f1, ytr = -ss - f2 -w;
1515  x9 += xtr; y9 += ytr;
1516 
1517  // G...
1518  G4Tubs tG("tG",ri,ro,d2,0.15*pi,1.85*pi);
1519  G4Box bG("bG",w2,ro2,d2);
1520  G4UnionSolid logoG("logoG",&tG,&bG,G4Translate3D(ri+w2,-ro2,0.));
1521  fpG = logoG.CreatePolyhedron();
1522  fpG->SetVisAttributes(&fVisAtts);
1523  fpG->Transform(G4Translate3D(-0.55*h,0.,0.));
1524 
1525  // 4...
1526  G4Box b1("b1",h2,h2,d2);
1527  G4Box bS("bS",ss,ss,d2+e); // Subtractor.
1528  G4Box bS2("bS2",ss,ss,d2+2.*e); // 2nd Subtractor.
1529  G4SubtractionSolid s1("s1",&b1,&bS,G4Translate3D(f1-ss,f2-ss,0.));
1530  G4SubtractionSolid s2("s2",&s1,&bS,G4Translate3D(f1+ss+w,f2-ss,0.));
1531  G4SubtractionSolid s3("s3",&s2,&bS,G4Translate3D(f1+ss+w,f2+ss+w,0.));
1533  ("s4",&s3,&bS,G4Transform3D(rm,G4ThreeVector(x8,y8,0.)));
1534  G4SubtractionSolid s5 // Triangular hole.
1535  ("s5",&bS,&bS2,G4Transform3D(rm,G4ThreeVector(x9,y9,0.)));
1536  G4SubtractionSolid logo4("logo4",&s4,&s5,G4Translate3D(-xtr,-ytr,0.));
1537  fp4 = logo4.CreatePolyhedron();
1538  /* Experiment with creating own polyhedron...
1539  int nNodes = 4;
1540  int nFaces = 4;
1541  double xyz[][3] = {{0,0,0},{1*m,0,0},{0,1*m,0},{0,0,1*m}};
1542  int faces[][4] = {{1,3,2,0},{1,2,4,0},{1,4,3,0},{2,3,4,0}};
1543  fp4 = new G4Polyhedron();
1544  fp4->createPolyhedron(nNodes,nFaces,xyz,faces);
1545  */
1546  fp4->SetVisAttributes(&fVisAtts);
1547  fp4->Transform(G4Translate3D(0.55*h,0.,0.));
1548 }
1549 
1550 G4VisCommandSceneAddLogo::G4Logo::~G4Logo() {
1551  delete fpG;
1552  delete fp4;
1553 }
1554 
1555 void G4VisCommandSceneAddLogo::G4Logo::operator()
1556  (G4VGraphicsScene& sceneHandler, const G4Transform3D& transform) {
1557  sceneHandler.BeginPrimitives(transform);
1558  sceneHandler.AddPrimitive(*fpG);
1559  sceneHandler.AddPrimitive(*fp4);
1560  sceneHandler.EndPrimitives();
1561 }
1562 
1564 
1566  G4bool omitable;
1567  fpCommand = new G4UIcommand ("/vis/scene/add/logo2D", this);
1568  fpCommand -> SetGuidance ("Adds 2D logo to current scene.");
1569  G4UIparameter* parameter;
1570  parameter = new G4UIparameter ("size", 'i', omitable = true);
1571  parameter -> SetGuidance ("Screen size of text in pixels.");
1572  parameter -> SetDefaultValue (48);
1573  fpCommand -> SetParameter (parameter);
1574  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
1575  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
1576  parameter -> SetDefaultValue (-0.9);
1577  fpCommand -> SetParameter (parameter);
1578  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
1579  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
1580  parameter -> SetDefaultValue (-0.9);
1581  fpCommand -> SetParameter (parameter);
1582  parameter = new G4UIparameter ("layout", 's', omitable = true);
1583  parameter -> SetGuidance ("Layout, i.e., adjustment: left|centre|right.");
1584  parameter -> SetDefaultValue ("left");
1585  fpCommand -> SetParameter (parameter);
1586 }
1587 
1589  delete fpCommand;
1590 }
1591 
1593  return "";
1594 }
1595 
1597 {
1599  G4bool warn(verbosity >= G4VisManager::warnings);
1600 
1601  G4Scene* pScene = fpVisManager->GetCurrentScene();
1602  if (!pScene) {
1603  if (verbosity >= G4VisManager::errors) {
1604  G4cout << "ERROR: No current scene. Please create one." << G4endl;
1605  }
1606  return;
1607  }
1608 
1609  G4int size;
1610  G4double x, y;
1611  G4String layoutString;
1612  std::istringstream is(newValue);
1613  is >> size >> x >> y >> layoutString;
1614  G4Text::Layout layout = G4Text::right;
1615  if (layoutString(0) == 'l') layout = G4Text::left;
1616  else if (layoutString(0) == 'c') layout = G4Text::centre;
1617  else if (layoutString(0) == 'r') layout = G4Text::right;
1618 
1619  Logo2D* logo2D = new Logo2D(fpVisManager, size, x, y, layout);
1620  G4VModel* model =
1622  model->SetType("G4Logo2D");
1623  model->SetGlobalTag("G4Logo2D");
1624  model->SetGlobalDescription("G4Logo2D: " + newValue);
1625  const G4String& currentSceneName = pScene -> GetName ();
1626  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1627  if (successful) {
1628  if (verbosity >= G4VisManager::confirmations) {
1629  G4cout << "2D logo has been added to scene \""
1630  << currentSceneName << "\"."
1631  << G4endl;
1632  }
1633  }
1634  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1635  UpdateVisManagerScene (currentSceneName);
1636 }
1637 
1638 void G4VisCommandSceneAddLogo2D::Logo2D::operator()
1639  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
1640 {
1641  G4Text text("Geant4", G4Point3D(fX, fY, 0.));
1642  text.SetScreenSize(fSize);
1643  text.SetLayout(fLayout);
1644  G4VisAttributes textAtts(G4Colour::Brown());
1645  text.SetVisAttributes(textAtts);
1646  sceneHandler.BeginPrimitives2D();
1647  sceneHandler.AddPrimitive(text);
1648  sceneHandler.EndPrimitives2D();
1649 }
1650 
1652 
1654  G4bool omitable;
1655  fpCommand = new G4UIcmdWithAString ("/vis/scene/add/psHits", this);
1656  fpCommand -> SetGuidance
1657  ("Adds Primitive Scorer Hits (PSHits) to current scene.");
1658  fpCommand -> SetGuidance
1659  ("PSHits are drawn at end of run when the scene in which"
1660  "\nthey are added is current.");
1661  fpCommand -> SetGuidance
1662  ("Optional parameter specifies name of scoring map. By default all"
1663  "\nscoring maps registered with the G4ScoringManager are drawn.");
1664  fpCommand -> SetParameterName ("mapname", omitable = true);
1665  fpCommand -> SetDefaultValue ("all");
1666 }
1667 
1669  delete fpCommand;
1670 }
1671 
1673  return "";
1674 }
1675 
1677 (G4UIcommand*, G4String newValue)
1678 {
1679  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1680  G4bool warn(verbosity >= G4VisManager::warnings);
1681 
1682  G4Scene* pScene = fpVisManager->GetCurrentScene();
1683  if (!pScene) {
1684  if (verbosity >= G4VisManager::errors) {
1685  G4cout << "ERROR: No current scene. Please create one." << G4endl;
1686  }
1687  return;
1688  }
1689 
1690  G4PSHitsModel* model = new G4PSHitsModel(newValue);
1691  const G4String& currentSceneName = pScene -> GetName ();
1692  G4bool successful = pScene -> AddEndOfRunModel (model, warn);
1693  if (successful) {
1694  if (verbosity >= G4VisManager::confirmations) {
1695  if (newValue == "all") {
1696  G4cout << "All Primitive Scorer hits";
1697  } else {
1698  G4cout << "Hits of Primitive Scorer \"" << newValue << '"';
1699  }
1700  G4cout << " will be drawn at end of run in scene \""
1701  << currentSceneName << "\"."
1702  << G4endl;
1703  }
1704  }
1705  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1706  UpdateVisManagerScene (currentSceneName);
1707 }
1708 
1710 
1712  G4bool omitable;
1713  fpCommand = new G4UIcommand ("/vis/scene/add/scale", this);
1714  fpCommand -> SetGuidance
1715  ("Adds an annotated scale line to the current scene.");
1716  fpCommand -> SetGuidance (G4Scale::GetGuidanceString());
1717  G4UIparameter* parameter;
1718  parameter = new G4UIparameter ("length", 'd', omitable = true);
1719  parameter->SetDefaultValue (1.);
1720  fpCommand->SetParameter (parameter);
1721  parameter = new G4UIparameter ("unit", 's', omitable = true);
1722  parameter->SetGuidance
1723  ("auto or valid length unit - defaults to auto."
1724  "\nIf auto, length is roughly one tenth of the scene extent.");
1725  parameter->SetDefaultValue ("auto");
1726  fpCommand->SetParameter (parameter);
1727  parameter = new G4UIparameter ("direction", 's', omitable = true);
1728  parameter->SetGuidance
1729  ("auto|x|y|z - defaults to auto."
1730  "\nIf auto, scale is roughly in the plane of the current view.");
1731  parameter->SetDefaultValue ("auto");
1732  fpCommand->SetParameter (parameter);
1733  parameter = new G4UIparameter ("red", 'd', omitable = true);
1734  parameter->SetDefaultValue (1.);
1735  fpCommand->SetParameter (parameter);
1736  parameter = new G4UIparameter ("green", 'd', omitable = true);
1737  parameter->SetDefaultValue (0.);
1738  fpCommand->SetParameter (parameter);
1739  parameter = new G4UIparameter ("blue", 'd', omitable = true);
1740  parameter->SetDefaultValue (0.);
1741  fpCommand->SetParameter (parameter);
1742  parameter = new G4UIparameter ("auto|manual", 's', omitable = true);
1743  parameter->SetGuidance
1744  ("Automatic placement or manual placement at (xmid,ymid,zmid)."
1745  "\nIf automatic, scale is placed at bottom left of current view.");
1746  parameter -> SetParameterCandidates("auto manual");
1747  parameter->SetDefaultValue ("auto");
1748  fpCommand->SetParameter (parameter);
1749  parameter = new G4UIparameter ("xmid", 'd', omitable = true);
1750  parameter->SetDefaultValue (0.);
1751  fpCommand->SetParameter (parameter);
1752  parameter = new G4UIparameter ("ymid", 'd', omitable = true);
1753  parameter->SetDefaultValue (0.);
1754  fpCommand->SetParameter (parameter);
1755  parameter = new G4UIparameter ("zmid", 'd', omitable = true);
1756  parameter->SetDefaultValue (0.);
1757  fpCommand->SetParameter (parameter);
1758  parameter = new G4UIparameter ("unit", 's', omitable = true);
1759  parameter->SetDefaultValue ("m");
1760  fpCommand->SetParameter (parameter);
1761 }
1762 
1764  delete fpCommand;
1765 }
1766 
1768  return "";
1769 }
1770 
1772 
1774  G4bool warn = verbosity >= G4VisManager::warnings;
1775 
1776  G4Scene* pScene = fpVisManager->GetCurrentScene();
1777  if (!pScene) {
1778  if (verbosity >= G4VisManager::errors) {
1779  G4cout << "ERROR: No current scene. Please create one." << G4endl;
1780  }
1781  return;
1782  }
1783 
1784  G4double userLength, red, green, blue, xmid, ymid, zmid;
1785  G4String userLengthUnit, direction, auto_manual, positionUnit;
1786  std::istringstream is (newValue);
1787  is >> userLength >> userLengthUnit >> direction
1788  >> red >> green >> blue
1789  >> auto_manual
1790  >> xmid >> ymid >> zmid >> positionUnit;
1791 
1792  G4double length = userLength;
1793  const G4VisExtent& sceneExtent = pScene->GetExtent(); // Existing extent.
1794  if (userLengthUnit == "auto") {
1795  length *= sceneExtent.GetExtentRadius();
1796  G4double intLog10Length = std::floor(std::log10(length));
1797  length = std::pow(10,intLog10Length);
1798  } else {
1799  length *= G4UIcommand::ValueOf(userLengthUnit);
1800  }
1801  G4String annotation = G4BestUnit(length,"Length");
1802 
1803  G4double unit = G4UIcommand::ValueOf(positionUnit);
1804  xmid *= unit; ymid *= unit; zmid *= unit;
1805 
1806  G4Scale::Direction scaleDirection (G4Scale::x);
1807  if (direction(0) == 'y') scaleDirection = G4Scale::y;
1808  if (direction(0) == 'z') scaleDirection = G4Scale::z;
1809 
1810  G4VViewer* pViewer = fpVisManager->GetCurrentViewer();
1811  if (!pViewer) {
1812  if (verbosity >= G4VisManager::errors) {
1813  G4cout <<
1814  "ERROR: G4VisCommandSceneAddScale::SetNewValue: no viewer."
1815  "\n Auto direction needs a viewer."
1816  << G4endl;
1817  }
1818  return;
1819  }
1820 
1821  const G4Vector3D& vp =
1823  const G4Vector3D& up =
1824  pViewer->GetViewParameters().GetUpVector();
1825 
1826  if (direction == "auto") { // Takes cue from viewer.
1827  if (std::abs(vp.x()) > std::abs(vp.y()) &&
1828  std::abs(vp.x()) > std::abs(vp.z())) { // x viewpoint
1829  if (std::abs(up.y()) > std::abs(up.z())) scaleDirection = G4Scale::z;
1830  else scaleDirection = G4Scale::y;
1831  }
1832  else if (std::abs(vp.y()) > std::abs(vp.x()) &&
1833  std::abs(vp.y()) > std::abs(vp.z())) { // y viewpoint
1834  if (std::abs(up.x()) > std::abs(up.z())) scaleDirection = G4Scale::z;
1835  else scaleDirection = G4Scale::x;
1836  }
1837  else if (std::abs(vp.z()) > std::abs(vp.x()) &&
1838  std::abs(vp.z()) > std::abs(vp.y())) { // z viewpoint
1839  if (std::abs(up.y()) > std::abs(up.x())) scaleDirection = G4Scale::x;
1840  else scaleDirection = G4Scale::y;
1841  }
1842  }
1843 
1844  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
1845  // Parameters read and interpreted.
1846 
1847  // Useful constants, etc...
1848  const G4double halfLength(length / 2.);
1849  const G4double comfort(0.01); // 0.15 seems too big. 0.05 might be better.
1850  const G4double freeLengthFraction (1. + 2. * comfort);
1851 
1852  const G4double xmin = sceneExtent.GetXmin();
1853  const G4double xmax = sceneExtent.GetXmax();
1854  const G4double ymin = sceneExtent.GetYmin();
1855  const G4double ymax = sceneExtent.GetYmax();
1856  const G4double zmin = sceneExtent.GetZmin();
1857  const G4double zmax = sceneExtent.GetZmax();
1858 
1859  // Test existing extent and issue warnings...
1860  G4bool worried = false;
1861  if (sceneExtent.GetExtentRadius() == 0) {
1862  worried = true;
1863  if (verbosity >= G4VisManager::warnings) {
1864  G4cout <<
1865  "WARNING: Existing scene does not yet have any extent."
1866  "\n Maybe you have not yet added any geometrical object."
1867  << G4endl;
1868  }
1869  }
1870  // Test existing scene for room...
1871  G4bool room = true;
1872  switch (scaleDirection) {
1873  case G4Scale::x:
1874  if (freeLengthFraction * (xmax - xmin) < length) room = false; break;
1875  case G4Scale::y:
1876  if (freeLengthFraction * (ymax - ymin) < length) room = false; break;
1877  case G4Scale::z:
1878  if (freeLengthFraction * (zmax - zmin) < length) room = false; break;
1879  }
1880  if (!room) {
1881  worried = true;
1882  if (verbosity >= G4VisManager::warnings) {
1883  G4cout <<
1884  "WARNING: Not enough room in existing scene. Maybe scale is too long."
1885  << G4endl;
1886  }
1887  }
1888  if (worried) {
1889  if (verbosity >= G4VisManager::warnings) {
1890  G4cout <<
1891  "WARNING: The scale you have asked for is bigger than the existing"
1892  "\n scene. Maybe you have added it too soon. It is recommended that"
1893  "\n you add the scale last so that it can be correctly auto-positioned"
1894  "\n so as not to be obscured by any existing object and so that the"
1895  "\n view parameters can be correctly recalculated."
1896  << G4endl;
1897  }
1898  }
1899 
1900  // Let's go ahead a construct a scale and a scale model. Since the
1901  // placing is done here, this G4Scale is *not* auto-placed...
1902  G4Scale scale(length, annotation, scaleDirection,
1903  false, xmid, ymid, zmid);
1904  G4VisAttributes* pVisAttr = new G4VisAttributes(G4Colour(red, green, blue));
1905  // Created of the heap because it needs a long lifetime. This is a
1906  // mess. The model determines the life but the vis atttributes are
1907  // associated with the scale. There's no way of knowing when to
1908  // delete the vis atttributes!!!
1909  scale.SetVisAttributes(pVisAttr);
1910  G4VModel* model = new G4ScaleModel(scale);
1911 
1912  // Now figure out the extent...
1913  //
1914  // From the G4Scale.hh:
1915  //
1916  // This creates a representation of annotated line in the specified
1917  // direction with tick marks at the end. If autoPlacing is true it
1918  // is required to be centred at the front, right, bottom corner of
1919  // the world space, comfortably outside the existing bounding
1920  // box/sphere so that existing objects do not obscure it. Otherwise
1921  // it is required to be drawn with mid-point at (xmid, ymid, zmid).
1922  //
1923  // The auto placing algorithm might be:
1924  // x = xmin + (1 + comfort) * (xmax - xmin)
1925  // y = ymin - comfort * (ymax - ymin)
1926  // z = zmin + (1 + comfort) * (zmax - zmin)
1927  // if direction == x then (x - length,y,z) to (x,y,z)
1928  // if direction == y then (x,y,z) to (x,y + length,z)
1929  // if direction == z then (x,y,z - length) to (x,y,z)
1930  //
1931  // End of clip from G4Scale.hh:
1932  //
1933  // Implement this in two parts. Here, use the scale's extent to
1934  // "expand" the scene's extent. Then rendering - in
1935  // G4VSceneHandler::AddPrimitive(const G4Scale&) - simply has to
1936  // ensure it's within the new extent.
1937  //
1938 
1939  G4double sxmid(xmid), symid(ymid), szmid(zmid);
1940  if (autoPlacing) {
1941  // Aim to place at bottom right of screen in current view.
1942  // Give some comfort zone.
1943  const G4double xComfort = comfort * (xmax - xmin);
1944  const G4double yComfort = comfort * (ymax - ymin);
1945  const G4double zComfort = comfort * (zmax - zmin);
1946  switch (scaleDirection) {
1947  case G4Scale::x:
1948  if (vp.z() > 0.) {
1949  sxmid = xmax + xComfort;
1950  symid = ymin - yComfort;
1951  szmid = zmin - zComfort;
1952  } else {
1953  sxmid = xmin - xComfort;
1954  symid = ymin - yComfort;
1955  szmid = zmax + zComfort;
1956  }
1957  break;
1958  case G4Scale::y:
1959  if (vp.x() > 0.) {
1960  sxmid = xmin - xComfort;
1961  symid = ymax + yComfort;
1962  szmid = zmin - zComfort;
1963  } else {
1964  sxmid = xmax + xComfort;
1965  symid = ymin - yComfort;
1966  szmid = zmin - zComfort;
1967  }
1968  break;
1969  case G4Scale::z:
1970  if (vp.x() > 0.) {
1971  sxmid = xmax + xComfort;
1972  symid = ymin - yComfort;
1973  szmid = zmax + zComfort;
1974  } else {
1975  sxmid = xmin - xComfort;
1976  symid = ymin - yComfort;
1977  szmid = zmax + zComfort;
1978  }
1979  break;
1980  }
1981  }
1982 
1983  /* Old code - kept for future reference.
1984  G4double sxmid(xmid), symid(ymid), szmid(zmid);
1985  if (autoPlacing) {
1986  sxmid = xmin + onePlusComfort * (xmax - xmin);
1987  symid = ymin - comfort * (ymax - ymin);
1988  szmid = zmin + onePlusComfort * (zmax - zmin);
1989  switch (scaleDirection) {
1990  case G4Scale::x:
1991  sxmid -= halfLength;
1992  break;
1993  case G4Scale::y:
1994  symid += halfLength;
1995  break;
1996  case G4Scale::z:
1997  szmid -= halfLength;
1998  break;
1999  }
2000  }
2001  */
2002 
2003  /* sxmin, etc., not actually used. Comment out to prevent compiler
2004  warnings but keep in case need in future. Extract transform and
2005  scaleExtent into reduced code below.
2006  G4double sxmin(sxmid), sxmax(sxmid);
2007  G4double symin(symid), symax(symid);
2008  G4double szmin(szmid), szmax(szmid);
2009  G4Transform3D transform;
2010  G4VisExtent scaleExtent;
2011  switch (scaleDirection) {
2012  case G4Scale::x:
2013  sxmin = sxmid - halfLength;
2014  sxmax = sxmid + halfLength;
2015  scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
2016  break;
2017  case G4Scale::y:
2018  symin = symid - halfLength;
2019  symax = symid + halfLength;
2020  transform = G4RotateZ3D(halfpi);
2021  scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
2022  break;
2023  case G4Scale::z:
2024  szmin = szmid - halfLength;
2025  szmax = szmid + halfLength;
2026  transform = G4RotateY3D(halfpi);
2027  scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
2028  break;
2029  }
2030  */
2031  G4Transform3D transform;
2032  G4VisExtent scaleExtent;
2033  switch (scaleDirection) {
2034  case G4Scale::x:
2035  scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
2036  break;
2037  case G4Scale::y:
2038  transform = G4RotateZ3D(halfpi);
2039  scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
2040  break;
2041  case G4Scale::z:
2042  transform = G4RotateY3D(halfpi);
2043  scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
2044  break;
2045  }
2046  transform = G4Translate3D(sxmid,symid,szmid) * transform;
2048 
2049 
2050  model->SetTransformation(transform);
2051  // Note: it is the responsibility of the model to act upon this, but
2052  // the extent is in local coordinates...
2053  model->SetExtent(scaleExtent);
2054  // This extent gets "added" to existing scene extent in
2055  // AddRunDurationModel below.
2056 
2057  const G4String& currentSceneName = pScene -> GetName ();
2058  G4bool successful = pScene -> AddRunDurationModel (model, warn);
2059  if (successful) {
2060  if (verbosity >= G4VisManager::confirmations) {
2061  G4cout << "Scale of " << annotation
2062  << " added to scene \"" << currentSceneName << "\".";
2063  if (verbosity >= G4VisManager::parameters) {
2064  G4cout << "\n with extent " << scaleExtent
2065  << "\n at " << transform.getRotation()
2066  << transform.getTranslation();
2067  }
2068  G4cout << G4endl;
2069  }
2070  }
2071  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2072  UpdateVisManagerScene (currentSceneName);
2073 }
2074 
2075 
2077 
2079  G4bool omitable;
2080  fpCommand = new G4UIcommand ("/vis/scene/add/text", this);
2081  fpCommand -> SetGuidance ("Adds text to current scene.");
2082  fpCommand -> SetGuidance
2083  ("Use \"/vis/set/textColour\" to set colour.");
2084  fpCommand -> SetGuidance
2085  ("Use \"/vis/set/textLayout\" to set layout:");
2086  G4UIparameter* parameter;
2087  parameter = new G4UIparameter ("x", 'd', omitable = true);
2088  parameter->SetDefaultValue (0);
2089  parameter->SetGuidance ("x");
2090  fpCommand->SetParameter (parameter);
2091  parameter = new G4UIparameter ("y", 'd', omitable = true);
2092  parameter->SetDefaultValue (0);
2093  parameter->SetGuidance ("y");
2094  fpCommand->SetParameter (parameter);
2095  parameter = new G4UIparameter ("z", 'd', omitable = true);
2096  parameter->SetDefaultValue (0);
2097  parameter->SetGuidance ("z");
2098  fpCommand->SetParameter (parameter);
2099  parameter = new G4UIparameter ("unit", 's', omitable = true);
2100  parameter->SetDefaultValue ("m");
2101  fpCommand->SetParameter (parameter);
2102  parameter = new G4UIparameter ("font_size", 'd', omitable = true);
2103  parameter->SetDefaultValue (12);
2104  parameter->SetGuidance ("pixels");
2105  fpCommand->SetParameter (parameter);
2106  parameter = new G4UIparameter ("x_offset", 'd', omitable = true);
2107  parameter->SetDefaultValue (0);
2108  parameter->SetGuidance ("pixels");
2109  fpCommand->SetParameter (parameter);
2110  parameter = new G4UIparameter ("y_offset", 'd', omitable = true);
2111  parameter->SetDefaultValue (0);
2112  parameter->SetGuidance ("pixels");
2113  fpCommand->SetParameter (parameter);
2114  parameter = new G4UIparameter ("text", 's', omitable = true);
2115  parameter->SetGuidance ("The rest of the line is text.");
2116  parameter->SetDefaultValue ("Hello G4");
2117  fpCommand->SetParameter (parameter);
2118 }
2119 
2121  delete fpCommand;
2122 }
2123 
2125  return "";
2126 }
2127 
2129 
2131  G4bool warn = verbosity >= G4VisManager::warnings;
2132 
2133  G4Scene* pScene = fpVisManager->GetCurrentScene();
2134  if (!pScene) {
2135  if (verbosity >= G4VisManager::errors) {
2136  G4cout << "ERROR: No current scene. Please create one." << G4endl;
2137  }
2138  return;
2139  }
2140 
2141  G4Tokenizer next(newValue);
2142  G4double x = StoD(next());
2143  G4double y = StoD(next());
2144  G4double z = StoD(next());
2145  G4String unitString = next();
2146  G4double font_size = StoD(next());
2147  G4double x_offset = StoD(next());
2148  G4double y_offset = StoD(next());
2149  G4String text = next("\n");
2150 
2151  G4double unit = G4UIcommand::ValueOf(unitString);
2152  x *= unit; y *= unit; z *= unit;
2153 
2154  G4Text g4text(text, G4Point3D(x,y,z));
2156  g4text.SetVisAttributes(visAtts);
2157  g4text.SetLayout(fCurrentTextLayout);
2158  g4text.SetScreenSize(font_size);
2159  g4text.SetOffset(x_offset,y_offset);
2160  G4VModel* model = new G4TextModel(g4text);
2161  const G4String& currentSceneName = pScene -> GetName ();
2162  G4bool successful = pScene -> AddRunDurationModel (model, warn);
2163  if (successful) {
2164  if (verbosity >= G4VisManager::confirmations) {
2165  G4cout << "Text \"" << text
2166  << "\" has been added to scene \"" << currentSceneName << "\"."
2167  << G4endl;
2168  }
2169  }
2170  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2171  UpdateVisManagerScene (currentSceneName);
2172 }
2173 
2174 
2176 
2178  G4bool omitable;
2179  fpCommand = new G4UIcommand ("/vis/scene/add/text2D", this);
2180  fpCommand -> SetGuidance ("Adds 2D text to current scene.");
2181  fpCommand -> SetGuidance
2182  ("Use \"/vis/set/textColour\" to set colour.");
2183  fpCommand -> SetGuidance
2184  ("Use \"/vis/set/textLayout\" to set layout:");
2185  G4UIparameter* parameter;
2186  parameter = new G4UIparameter ("x", 'd', omitable = true);
2187  parameter->SetDefaultValue (0);
2188  parameter->SetGuidance ("x");
2189  fpCommand->SetParameter (parameter);
2190  parameter = new G4UIparameter ("y", 'd', omitable = true);
2191  parameter->SetDefaultValue (0);
2192  parameter->SetGuidance ("y");
2193  fpCommand->SetParameter (parameter);
2194  parameter = new G4UIparameter ("font_size", 'd', omitable = true);
2195  parameter->SetDefaultValue (12);
2196  parameter->SetGuidance ("pixels");
2197  fpCommand->SetParameter (parameter);
2198  parameter = new G4UIparameter ("x_offset", 'd', omitable = true);
2199  parameter->SetDefaultValue (0);
2200  parameter->SetGuidance ("pixels");
2201  fpCommand->SetParameter (parameter);
2202  parameter = new G4UIparameter ("y_offset", 'd', omitable = true);
2203  parameter->SetDefaultValue (0);
2204  parameter->SetGuidance ("pixels");
2205  fpCommand->SetParameter (parameter);
2206  parameter = new G4UIparameter ("text", 's', omitable = true);
2207  parameter->SetGuidance ("The rest of the line is text.");
2208  parameter->SetDefaultValue ("Hello G4");
2209  fpCommand->SetParameter (parameter);
2210 }
2211 
2213  delete fpCommand;
2214 }
2215 
2217  return "";
2218 }
2219 
2221 
2223  G4bool warn = verbosity >= G4VisManager::warnings;
2224 
2225  G4Scene* pScene = fpVisManager->GetCurrentScene();
2226  if (!pScene) {
2227  if (verbosity >= G4VisManager::errors) {
2228  G4cout << "ERROR: No current scene. Please create one." << G4endl;
2229  }
2230  return;
2231  }
2232 
2233  G4Tokenizer next(newValue);
2234  G4double x = StoD(next());
2235  G4double y = StoD(next());
2236  G4double font_size = StoD(next());
2237  G4double x_offset = StoD(next());
2238  G4double y_offset = StoD(next());
2239  G4String text = next("\n");
2240 
2241  G4Text g4text(text, G4Point3D(x,y,0.));
2243  g4text.SetVisAttributes(visAtts);
2244  g4text.SetLayout(fCurrentTextLayout);
2245  g4text.SetScreenSize(font_size);
2246  g4text.SetOffset(x_offset,y_offset);
2247  G4Text2D* g4text2D = new G4Text2D(g4text);
2248  G4VModel* model =
2250  model->SetType("Text2D");
2251  model->SetGlobalTag("Text2D");
2252  model->SetGlobalDescription("Text2D: " + newValue);
2253  const G4String& currentSceneName = pScene -> GetName ();
2254  G4bool successful = pScene -> AddRunDurationModel (model, warn);
2255  if (successful) {
2256  if (verbosity >= G4VisManager::confirmations) {
2257  G4cout << "2D text \"" << text
2258  << "\" has been added to scene \"" << currentSceneName << "\"."
2259  << G4endl;
2260  }
2261  }
2262  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2263  UpdateVisManagerScene (currentSceneName);
2264 }
2265 
2266 G4VisCommandSceneAddText2D::G4Text2D::G4Text2D(const G4Text& text):
2267  fText(text)
2268 {}
2269 
2270 void G4VisCommandSceneAddText2D::G4Text2D::operator()
2271  (G4VGraphicsScene& sceneHandler, const G4Transform3D& transform) {
2272  sceneHandler.BeginPrimitives2D(transform);
2273  sceneHandler.AddPrimitive(fText);
2274  sceneHandler.EndPrimitives2D();
2275 }
2276 
2277 
2279 
2281  G4bool omitable;
2282  fpCommand = new G4UIcmdWithAString
2283  ("/vis/scene/add/trajectories", this);
2284  fpCommand -> SetGuidance
2285  ("Adds trajectories to current scene.");
2286  fpCommand -> SetGuidance
2287  ("Causes trajectories, if any, to be drawn at the end of processing an"
2288  "\nevent. Switches on trajectory storing and sets the"
2289  "\ndefault trajectory type.");
2290  fpCommand -> SetGuidance
2291  ("The command line parameter list determines the default trajectory type."
2292  "\nIf it contains the string \"smooth\", auxiliary inter-step points will"
2293  "\nbe inserted to improve the smoothness of the drawing of a curved"
2294  "\ntrajectory."
2295  "\nIf it contains the string \"rich\", significant extra information will"
2296  "\nbe stored in the trajectory (G4RichTrajectory) amenable to modeling"
2297  "\nand filtering with \"/vis/modeling/trajectories/create/drawByAttribute\""
2298  "\nand \"/vis/filtering/trajectories/create/attributeFilter\" commands."
2299  "\nIt may contain both strings in any order.");
2300  fpCommand -> SetGuidance
2301  ("\nTo switch off trajectory storing: \"/tracking/storeTrajectory 0\"."
2302  "\nSee also \"/vis/scene/endOfEventAction\".");
2303  fpCommand -> SetGuidance
2304  ("Note: This only sets the default. Independently of the result of this"
2305  "\ncommand, a user may instantiate a trajectory that overrides this default"
2306  "\nin PreUserTrackingAction.");
2307  fpCommand -> SetParameterName ("default-trajectory-type", omitable = true);
2308  fpCommand -> SetDefaultValue ("");
2309 }
2310 
2312  delete fpCommand;
2313 }
2314 
2316  return "";
2317 }
2318 
2320  G4String newValue) {
2321 
2323  G4bool warn = verbosity >= G4VisManager::warnings;
2324 
2325  G4Scene* pScene = fpVisManager->GetCurrentScene();
2326  if (!pScene) {
2327  if (verbosity >= G4VisManager::errors) {
2328  G4cout << "ERROR: No current scene. Please create one." << G4endl;
2329  }
2330  return;
2331  }
2332 
2333  G4bool smooth = false, rich = false;
2334  if (newValue.find("smooth") != std::string::npos) smooth = true;
2335  if (newValue.find("rich") != std::string::npos) rich = true;
2336 
2337  G4UImanager* UImanager = G4UImanager::GetUIpointer();
2338  G4int keepVerbose = UImanager->GetVerboseLevel();
2339  G4int newVerbose = 2;
2340  UImanager->SetVerboseLevel(newVerbose);
2341  G4PropagatorInField* propagatorInField =
2343  GetPropagatorInField();
2344  propagatorInField->SetTrajectoryFilter(0); // Switch off smooth trajectories.
2345  static G4IdentityTrajectoryFilter auxiliaryPointsFilter;
2346  G4String defaultTrajectoryType;
2347  G4bool i_mode_found = false;
2348  G4int i_mode = 0;
2349  if (smooth && rich) {
2350  UImanager->ApplyCommand("/tracking/storeTrajectory 3");
2351  propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
2352  defaultTrajectoryType = "G4RichTrajectory configured for smooth steps";
2353  } else if (smooth) {
2354  UImanager->ApplyCommand("/tracking/storeTrajectory 2");
2355  propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
2356  defaultTrajectoryType = "G4SmoothTrajectory";
2357  } else if (rich) {
2358  UImanager->ApplyCommand("/tracking/storeTrajectory 3");
2359  defaultTrajectoryType = "G4RichTrajectory";
2360  } else {
2361  if (!newValue.empty()) {
2362  std::istringstream iss(newValue);
2363  iss >> i_mode;
2364  if (iss) {
2365  i_mode_found = true;
2366  if (verbosity >= G4VisManager::warnings) {
2367  G4cout <<
2368  "WARNING: Integer parameter " << i_mode << " found."
2369  "\n DEPRECATED - its use in this command will be removed at a future major"
2370  "\n release. Use \"/vis/modeling/trajectories\" commands."
2371  << G4endl;
2372  }
2373  } else {
2374  if (verbosity >= G4VisManager::errors) {
2375  G4cout << "ERROR: Unrecognised parameter \"" << newValue << "\""
2376  "\n No action taken."
2377  << G4endl;
2378  }
2379  return;
2380  }
2381  }
2382  UImanager->ApplyCommand("/tracking/storeTrajectory 1");
2383  defaultTrajectoryType = "G4Trajectory";
2384  }
2385  UImanager->SetVerboseLevel(keepVerbose);
2386 
2387  if (verbosity >= G4VisManager::errors) {
2388  G4cout <<
2389  "Attributes available for modeling and filtering with"
2390  "\n \"/vis/modeling/trajectories/create/drawByAttribute\" and"
2391  "\n \"/vis/filtering/trajectories/create/attributeFilter\" commands:"
2392  << G4endl;
2394  if (rich) {
2397  } else if (smooth) {
2400  } else {
2403  }
2404  }
2405 
2406  G4TrajectoriesModel* model = 0;
2407  if (i_mode_found) {
2408  model = new G4TrajectoriesModel(i_mode);
2409  } else {
2410  model = new G4TrajectoriesModel();
2411  }
2412  const G4String& currentSceneName = pScene -> GetName ();
2413  pScene -> AddEndOfEventModel (model, warn);
2414 
2415  if (verbosity >= G4VisManager::confirmations) {
2416  G4cout << "Default trajectory type " << defaultTrajectoryType
2417  << "\n will be used to store trajectories for scene \""
2418  << currentSceneName << "\"."
2419  << G4endl;
2420  }
2421 
2422  if (verbosity >= G4VisManager::warnings) {
2423  G4cout <<
2424  "WARNING: Trajectory storing has been requested. This action may be"
2425  "\n reversed with \"/tracking/storeTrajectory 0\"."
2426  << G4endl;
2427  }
2428  UpdateVisManagerScene (currentSceneName);
2429 }
2430 
2432 
2434  G4bool omitable;
2435  fpCommand = new G4UIcmdWithAString("/vis/scene/add/userAction",this);
2436  fpCommand -> SetGuidance
2437  ("Add named Vis User Action to current scene.");
2438  fpCommand -> SetGuidance
2439  ("Attempts to match search string to name of action - use unique sub-string.");
2440  fpCommand -> SetGuidance
2441  ("(Use /vis/list to see names of registered actions.)");
2442  fpCommand -> SetGuidance
2443  ("If name == \"all\" (default), all actions are added.");
2444  fpCommand -> SetParameterName("action-name", omitable = true);
2445  fpCommand -> SetDefaultValue("all");
2446 }
2447 
2449  delete fpCommand;
2450 }
2451 
2453  return "";
2454 }
2455 
2457 (G4UIcommand*, G4String newValue) {
2458 
2459  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
2460 
2461  G4Scene* pScene = fpVisManager->GetCurrentScene();
2462  if (!pScene) {
2463  if (verbosity >= G4VisManager::errors) {
2464  G4cout << "ERROR: No current scene. Please create one." << G4endl;
2465  }
2466  return;
2467  }
2468 
2469  G4bool any = false;
2470 
2471  const std::vector<G4VisManager::UserVisAction>& runDurationUserVisActions =
2472  fpVisManager->GetRunDurationUserVisActions();
2473  for (size_t i = 0; i < runDurationUserVisActions.size(); i++) {
2474  const G4String& name = runDurationUserVisActions[i].fName;
2475  G4VUserVisAction* visAction = runDurationUserVisActions[i].fpUserVisAction;
2476  if (newValue == "all" || name.find(newValue) != std::string::npos) {
2477  any = true;
2478  AddVisAction(name,visAction,pScene,runDuration,verbosity);
2479  }
2480  }
2481 
2482  const std::vector<G4VisManager::UserVisAction>& endOfEventUserVisActions =
2483  fpVisManager->GetEndOfEventUserVisActions();
2484  for (size_t i = 0; i < endOfEventUserVisActions.size(); i++) {
2485  const G4String& name = endOfEventUserVisActions[i].fName;
2486  G4VUserVisAction* visAction = endOfEventUserVisActions[i].fpUserVisAction;
2487  if (newValue == "all" || name.find(newValue) != std::string::npos) {
2488  any = true;
2489  AddVisAction(name,visAction,pScene,endOfEvent,verbosity);
2490  }
2491  }
2492 
2493  const std::vector<G4VisManager::UserVisAction>& endOfRunUserVisActions =
2494  fpVisManager->GetEndOfRunUserVisActions();
2495  for (size_t i = 0; i < endOfRunUserVisActions.size(); i++) {
2496  const G4String& name = endOfRunUserVisActions[i].fName;
2497  G4VUserVisAction* visAction = endOfRunUserVisActions[i].fpUserVisAction;
2498  if (newValue == "all" || name.find(newValue) != std::string::npos) {
2499  any = true;
2500  AddVisAction(name,visAction,pScene,endOfRun,verbosity);
2501  }
2502  }
2503 
2504  if (!any) {
2505  if (verbosity >= G4VisManager::warnings) {
2506  G4cout << "WARNING: No User Vis Action registered." << G4endl;
2507  }
2508  return;
2509  }
2510 
2511  const G4String& currentSceneName = pScene -> GetName ();
2512  UpdateVisManagerScene (currentSceneName);
2513 }
2514 
2515 void G4VisCommandSceneAddUserAction::AddVisAction
2516 (const G4String& name,
2517  G4VUserVisAction* visAction,
2518  G4Scene* pScene,
2519  G4VisCommandSceneAddUserAction::ActionType type,
2520  G4VisManager::Verbosity verbosity)
2521 {
2522  G4bool warn = verbosity >= G4VisManager::warnings;
2523 
2524  const std::map<G4VUserVisAction*,G4VisExtent>& visExtentMap =
2526  G4VisExtent extent;
2527  std::map<G4VUserVisAction*,G4VisExtent>::const_iterator i =
2528  visExtentMap.find(visAction);
2529  if (i != visExtentMap.end()) extent = i->second;
2530  if (warn) {
2531  if (extent.GetExtentRadius() <= 0.) {
2532  G4cout << "WARNING: User Vis Action extent is null." << G4endl;
2533  }
2534  }
2535 
2536  G4VModel* model = new G4CallbackModel<G4VUserVisAction>(visAction);
2537  model->SetType("User Vis Action");
2538  model->SetGlobalTag(name);
2539  model->SetGlobalDescription(name);
2540  model->SetExtent(extent);
2541  G4bool successful = false;;
2542  switch (type) {
2543  case runDuration:
2544  successful = pScene -> AddRunDurationModel (model, warn);
2545  break;
2546  case endOfEvent:
2547  successful = pScene -> AddEndOfEventModel (model, warn);
2548  break;
2549  case endOfRun:
2550  successful = pScene -> AddEndOfRunModel (model, warn);
2551  break;
2552  }
2553  if (successful && verbosity >= G4VisManager::confirmations) {
2554  const G4String& currentSceneName = pScene -> GetName ();
2555  G4cout << "User Vis Action added to scene \""
2556  << currentSceneName << "\"";
2557  if (verbosity >= G4VisManager::parameters) {
2558  G4cout << "\n with extent " << extent;
2559  }
2560  G4cout << G4endl;
2561  }
2562 }
2563 
2565 
2567  G4bool omitable;
2568  fpCommand = new G4UIcommand ("/vis/scene/add/volume", this);
2569  fpCommand -> SetGuidance
2570  ("Adds a physical volume to current scene, with optional clipping volume.");
2571  fpCommand -> SetGuidance
2572  ("If physical-volume-name is \"world\" (the default), the top of the"
2573  "\nmain geometry tree (material world) is added. If \"worlds\", the"
2574  "\ntop of all worlds - material world and parallel worlds, if any - are"
2575  "\nadded. Otherwise a search of all worlds is made, taking the first"
2576  "\nmatching occurence only. To see a representation of the geometry"
2577  "\nhierarchy of the worlds, try \"/vis/drawTree [worlds]\" or one of the"
2578  "\ndriver/browser combinations that have the required functionality, e.g., HepRep.");
2579  fpCommand -> SetGuidance
2580  ("If clip-volume-type is specified, the subsequent parameters are used to"
2581  "\nto define a clipping volume. For example,"
2582  "\n\"vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1\" will draw the world"
2583  "\nwith the positive octant cut away.");
2584  fpCommand -> SetGuidance
2585  ("If clip-volume-type is prepended with '-', the clip-volume is subtracted"
2586  "\n(cutaway). (This is the default if there is no prepended character.)"
2587  "\nIf '*' is prepended, the intersection of the physical-volume and the"
2588  "\nclip-volume is made. (You can make a section/DCUT with a thin box, for"
2589  "\nexample).");
2590  fpCommand -> SetGuidance
2591  ("For \"box\", the parameters are xmin,xmax,ymin,ymax,zmin,zmax."
2592  "\nOnly \"box\" is programmed at present.");
2593  G4UIparameter* parameter;
2594  parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
2595  parameter -> SetDefaultValue ("world");
2596  fpCommand -> SetParameter (parameter);
2597  parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
2598  parameter -> SetGuidance
2599  ("If negative, matches any copy no. First name match is taken.");
2600  parameter -> SetDefaultValue (-1);
2601  fpCommand -> SetParameter (parameter);
2602  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
2603  parameter -> SetGuidance
2604  ("Depth of descent of geometry hierarchy. Default = unlimited depth.");
2605  parameter -> SetDefaultValue (G4Scene::UNLIMITED);
2606  fpCommand -> SetParameter (parameter);
2607  parameter = new G4UIparameter ("clip-volume-type", 's', omitable = true);
2608  parameter -> SetParameterCandidates("none box -box *box");
2609  parameter -> SetDefaultValue ("none");
2610  parameter -> SetGuidance("[-|*]type. See general guidance.");
2611  fpCommand -> SetParameter (parameter);
2612  parameter = new G4UIparameter ("parameter-unit", 's', omitable = true);
2613  parameter -> SetDefaultValue ("m");
2614  fpCommand -> SetParameter (parameter);
2615  parameter = new G4UIparameter ("parameter-1", 'd', omitable = true);
2616  parameter -> SetDefaultValue (0.);
2617  fpCommand -> SetParameter (parameter);
2618  parameter = new G4UIparameter ("parameter-2", 'd', omitable = true);
2619  parameter -> SetDefaultValue (0.);
2620  fpCommand -> SetParameter (parameter);
2621  parameter = new G4UIparameter ("parameter-3", 'd', omitable = true);
2622  parameter -> SetDefaultValue (0.);
2623  fpCommand -> SetParameter (parameter);
2624  parameter = new G4UIparameter ("parameter-4", 'd', omitable = true);
2625  parameter -> SetDefaultValue (0.);
2626  fpCommand -> SetParameter (parameter);
2627  parameter = new G4UIparameter ("parameter-5", 'd', omitable = true);
2628  parameter -> SetDefaultValue (0.);
2629  fpCommand -> SetParameter (parameter);
2630  parameter = new G4UIparameter ("parameter-6", 'd', omitable = true);
2631  parameter -> SetDefaultValue (0.);
2632  fpCommand -> SetParameter (parameter);
2633 }
2634 
2636  delete fpCommand;
2637 }
2638 
2640  return "world 0 -1";
2641 }
2642 
2644  G4String newValue) {
2645 
2647  G4bool warn = verbosity >= G4VisManager::warnings;
2648 
2649  G4Scene* pScene = fpVisManager->GetCurrentScene();
2650  if (!pScene) {
2651  if (verbosity >= G4VisManager::errors) {
2652  G4cout << "ERROR: No current scene. Please create one." << G4endl;
2653  }
2654  return;
2655  }
2656 
2657  G4String name, clipVolumeType, parameterUnit;
2658  G4int copyNo, requestedDepthOfDescent;
2659  G4double param1, param2, param3, param4, param5, param6;
2660  std::istringstream is (newValue);
2661  is >> name >> copyNo >> requestedDepthOfDescent
2662  >> clipVolumeType >> parameterUnit
2663  >> param1 >> param2 >> param3 >> param4 >> param5 >> param6;
2665  G4PhysicalVolumeModel::subtraction; // Default subtraction mode.
2666  if (clipVolumeType[size_t(0)] == '-') {
2667  clipVolumeType = clipVolumeType.substr(1); // Remove first character.
2668  } else if (clipVolumeType[size_t(0)] == '*') {
2669  clippingMode = G4PhysicalVolumeModel::intersection;
2670  clipVolumeType = clipVolumeType.substr(1);
2671  }
2672  G4double unit = G4UIcommand::ValueOf(parameterUnit);
2673  param1 *= unit; param2 *= unit; param3 *= unit;
2674  param4 *= unit; param5 *= unit; param6 *= unit;
2675 
2676  G4TransportationManager* transportationManager =
2678 
2679  size_t nWorlds = transportationManager->GetNoWorlds();
2680  if (nWorlds > 1) { // Parallel worlds in operation...
2681  if (verbosity >= G4VisManager::warnings) {
2682  static G4bool warned = false;
2683  if (!warned && name != "worlds") {
2684  G4cout <<
2685  "WARNING: Parallel worlds in operation. To visualise, specify"
2686  "\n \"worlds\" or the parallel world volume or sub-volume name"
2687  "\n and control visibility with /vis/geometry."
2688  << G4endl;
2689  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
2690  transportationManager->GetWorldsIterator();
2691  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
2692  G4cout << " World " << i << ": " << (*iterWorld)->GetName()
2693  << G4endl;
2694  warned = true;
2695  }
2696  }
2697  }
2698  }
2699 
2700  G4VPhysicalVolume* world = *(transportationManager->GetWorldsIterator());
2701 
2702  if (!world) {
2703  if (verbosity >= G4VisManager::errors) {
2704  G4cout <<
2705  "ERROR: G4VisCommandSceneAddVolume::SetNewValue:"
2706  "\n No world. Maybe the geometry has not yet been defined."
2707  "\n Try \"/run/initialize\""
2708  << G4endl;
2709  }
2710  return;
2711  }
2712 
2713  const std::vector<G4Scene::Model>& rdModelList = pScene -> GetRunDurationModelList();
2714  std::vector<G4Scene::Model>::const_iterator it;
2715  for (it = rdModelList.begin(); it != rdModelList.end(); ++it) {
2716  if (it->fpModel->GetGlobalDescription().find("G4PhysicalVolumeModel")
2717  != std::string::npos) {
2718  if (((G4PhysicalVolumeModel*)(it->fpModel))->GetTopPhysicalVolume () == world) break;
2719  }
2720  }
2721  if (it != rdModelList.end()) {
2722  if (verbosity >= G4VisManager::warnings) {
2723  G4cout << "WARNING: There is already a volume, \""
2724  << it -> fpModel -> GetGlobalDescription()
2725  << "\",\n in the run-duration model list of scene \""
2726  << pScene -> GetName()
2727  << "\".\n To get a clean scene:"
2728  << "\n /vis/drawVolume " << name
2729  << "\n or"
2730  << "\n /vis/scene/create"
2731  << "\n /vis/scene/add/volume " << name
2732  << "\n /vis/sceneHandler/attach"
2733  << "\n (and also, if necessary, /vis/viewer/flush)"
2734  << G4endl;
2735  }
2736  return;
2737  }
2738 
2739  std::vector<G4PhysicalVolumeModel*> models;
2740  std::vector<G4VPhysicalVolume*> foundVolumes;
2741  G4VPhysicalVolume* foundWorld = 0;
2743  typedef std::vector<PVNodeID> PVPath;
2744  PVPath foundFullPVPath;
2745  std::vector<G4int> foundDepths;
2746  std::vector<G4Transform3D> transformations;
2747 
2748  if (name == "world") {
2749 
2750  models.push_back
2751  (new G4PhysicalVolumeModel (world, requestedDepthOfDescent));
2752  foundVolumes.push_back(world);
2753  foundDepths.push_back(0);
2754  transformations.push_back(G4Transform3D());
2755 
2756  } else if (name == "worlds") {
2757 
2758  if (nWorlds == 0) {
2759  if (verbosity >= G4VisManager::warnings) {
2760  G4cout <<
2761  "WARNING: G4VisCommandSceneAddVolume::SetNewValue:"
2762  "\n Parallel worlds requested but none exist."
2763  "\n Just adding material world."
2764  << G4endl;
2765  }
2766  }
2767  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
2768  transportationManager->GetWorldsIterator();
2769  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
2770  models.push_back
2771  (new G4PhysicalVolumeModel (*iterWorld, requestedDepthOfDescent));
2772  foundVolumes.push_back(*iterWorld);
2773  foundDepths.push_back(0);
2774  transformations.push_back(G4Transform3D());
2775  }
2776 
2777  } else { // Search all worlds...
2778 
2779  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
2780  transportationManager->GetWorldsIterator();
2781  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
2782  G4PhysicalVolumeModel searchModel (*iterWorld); // Unlimited depth.
2783  G4ModelingParameters mp; // Default - no culling.
2784  searchModel.SetModelingParameters (&mp);
2785  G4PhysicalVolumeSearchScene searchScene (&searchModel, name, copyNo);
2786  searchModel.DescribeYourselfTo (searchScene); // Initiate search.
2787  G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
2788  if (foundVolume) {
2789  foundWorld = *iterWorld;
2790  foundVolumes.push_back(foundVolume);
2791  foundFullPVPath = searchScene.GetFoundFullPVPath();
2792  foundDepths.push_back(searchScene.GetFoundDepth());
2793  transformations.push_back(searchScene.GetFoundTransformation());
2794  break;
2795  }
2796  }
2797 
2798  if (foundVolumes.size()) {
2799  for (size_t i = 0; i < foundVolumes.size(); ++i) {
2800  G4PhysicalVolumeModel* foundPVModel = new G4PhysicalVolumeModel
2801  (foundVolumes[i], requestedDepthOfDescent, transformations[i]);
2802  foundFullPVPath.pop_back(); // "Base" is "Found - 1".
2803  foundPVModel->SetBaseFullPVPath(foundFullPVPath);
2804  models.push_back(foundPVModel);
2805  }
2806  } else {
2807  if (verbosity >= G4VisManager::errors) {
2808  G4cout << "ERROR: Volume \"" << name << "\"";
2809  if (copyNo >= 0) {
2810  G4cout << ", copy no. " << copyNo << ",";
2811  }
2812  G4cout << " not found." << G4endl;
2813  }
2814  return;
2815  }
2816  }
2817 
2818  if (clipVolumeType == "box") {
2819  const G4double dX = (param2 - param1) / 2.;
2820  const G4double dY = (param4 - param3) / 2.;
2821  const G4double dZ = (param6 - param5) / 2.;
2822  const G4double x0 = (param2 + param1) / 2.;
2823  const G4double y0 = (param4 + param3) / 2.;
2824  const G4double z0 = (param6 + param5) / 2.;
2825  G4VSolid* clippingSolid =
2826  new G4DisplacedSolid
2827  ("_displaced_clipping_box",
2828  new G4Box("_clipping_box",dX,dY,dZ),
2829  G4Translate3D(x0,y0,z0));
2830  for (size_t i = 0; i < foundVolumes.size(); ++i) {
2831  models[i]->SetClippingSolid(clippingSolid);
2832  models[i]->SetClippingMode(clippingMode);
2833  }
2834  } // If any other shape consider NumberOfRotationSides!!!!!!!!!!!
2835 
2836  const G4String& currentSceneName = pScene -> GetName ();
2837  G4bool failure = true;
2838  for (size_t i = 0; i < foundVolumes.size(); ++i) {
2839  G4bool successful = pScene -> AddRunDurationModel (models[i], warn);
2840  if (successful) {
2841  failure = false;
2842  if (verbosity >= G4VisManager::confirmations) {
2843  G4cout << "First occurrence of \""
2844  << foundVolumes[i] -> GetName ()
2845  << "\"";
2846  if (copyNo >= 0) {
2847  G4cout << ", copy no. " << copyNo << ",";
2848  }
2849  G4cout << "\n found ";
2850  if (foundWorld)
2851  G4cout << "in world \"" << foundWorld->GetName() << "\" ";
2852  G4cout << "at depth " << foundDepths[i]
2853  << ",\n with a requested depth of further descent of ";
2854  if (requestedDepthOfDescent < 0) {
2855  G4cout << "<0 (unlimited)";
2856  }
2857  else {
2858  G4cout << requestedDepthOfDescent;
2859  }
2860  G4cout << ",\n has been added to scene \"" << currentSceneName << "\"."
2861  << G4endl;
2862  }
2863  }
2864  }
2865 
2866  if (failure) {
2867  G4VisCommandsSceneAddUnsuccessful(verbosity);
2868  return;
2869  }
2870 
2871  UpdateVisManagerScene (currentSceneName);
2872 }