ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VisCommandsSceneAdd.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4VisCommandsSceneAdd.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // /vis/scene/add commands - John Allison 9th August 1998
28 
29 #include "G4VisCommandsSceneAdd.hh"
30 
32 #include "G4LogicalVolumeStore.hh"
33 #include "G4PhysicalVolumeModel.hh"
34 #include "G4LogicalVolumeModel.hh"
35 #include "G4ModelingParameters.hh"
36 #include "G4HitsModel.hh"
37 #include "G4DigiModel.hh"
38 #include "G4GPSModel.hh"
39 #include "G4ElectricFieldModel.hh"
40 #include "G4MagneticFieldModel.hh"
41 #include "G4PSHitsModel.hh"
42 #include "G4TrajectoriesModel.hh"
43 #include "G4ScaleModel.hh"
44 #include "G4TextModel.hh"
45 #include "G4ArrowModel.hh"
46 #include "G4AxesModel.hh"
48 #include "G4ParticleTable.hh"
49 #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 "G4UIcommandTree.hh"
58 #include "G4UIcommand.hh"
59 #include "G4UIcmdWithAString.hh"
61 #include "G4UIcmdWithAnInteger.hh"
62 #include "G4Tokenizer.hh"
63 #include "G4RunManager.hh"
64 #ifdef G4MULTITHREADED
65 #include "G4MTRunManager.hh"
66 #endif
67 #include "G4StateManager.hh"
68 #include "G4Run.hh"
69 #include "G4Event.hh"
70 #include "G4Trajectory.hh"
71 #include "G4TrajectoryPoint.hh"
72 #include "G4RichTrajectory.hh"
73 #include "G4RichTrajectoryPoint.hh"
74 #include "G4SmoothTrajectory.hh"
76 #include "G4AttDef.hh"
77 #include "G4AttCheck.hh"
78 #include "G4Polyline.hh"
79 #include "G4UnitsTable.hh"
80 #include "G4PhysicalConstants.hh"
81 #include "G4SystemOfUnits.hh"
83 
84 #include <sstream>
85 
87 
89  fpCommand = new G4UIcommand("/vis/scene/add/arrow", this);
90  fpCommand -> SetGuidance ("Adds arrow to current scene.");
91  G4bool omitable;
92  G4UIparameter* parameter;
93  parameter = new G4UIparameter ("x1", 'd', omitable = false);
94  fpCommand -> SetParameter (parameter);
95  parameter = new G4UIparameter ("y1", 'd', omitable = false);
96  fpCommand -> SetParameter (parameter);
97  parameter = new G4UIparameter ("z1", 'd', omitable = false);
98  fpCommand -> SetParameter (parameter);
99  parameter = new G4UIparameter ("x2", 'd', omitable = false);
100  fpCommand -> SetParameter (parameter);
101  parameter = new G4UIparameter ("y2", 'd', omitable = false);
102  fpCommand -> SetParameter (parameter);
103  parameter = new G4UIparameter ("z2", 'd', omitable = false);
104  fpCommand -> SetParameter (parameter);
105  parameter = new G4UIparameter ("unit", 's', omitable = true);
106  parameter->SetDefaultValue ("m");
107  fpCommand->SetParameter (parameter);
108 }
109 
111  delete fpCommand;
112 }
113 
115  return "";
116 }
117 
119 {
121  G4bool warn(verbosity >= G4VisManager::warnings);
122 
123  G4Scene* pScene = fpVisManager->GetCurrentScene();
124  if (!pScene) {
125  if (verbosity >= G4VisManager::errors) {
126  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
127  }
128  return;
129  }
130 
131  G4String unitString;
132  G4double x1, y1, z1, x2, y2, z2;
133  std::istringstream is(newValue);
134  is >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> unitString;
135  G4double unit = G4UIcommand::ValueOf(unitString);
136  x1 *= unit; y1 *= unit; z1 *= unit;
137  x2 *= unit; y2 *= unit; z2 *= unit;
138 
139  // Consult scene for arrow width.
140  const G4VisExtent& sceneExtent = pScene->GetExtent();
141  G4double arrowWidth =
142  0.005 * fCurrentLineWidth * sceneExtent.GetExtentRadius();
143 
145  (x1, y1, z1, x2, y2, z2,
146  arrowWidth, fCurrentColour, newValue,
148 
149  const G4String& currentSceneName = pScene -> GetName ();
150  G4bool successful = pScene -> AddRunDurationModel (model, warn);
151  if (successful) {
152  if (verbosity >= G4VisManager::confirmations) {
153  G4cout << "Arrow has been added to scene \""
154  << currentSceneName << "\"."
155  << G4endl;
156  }
157  }
158  else G4VisCommandsSceneAddUnsuccessful(verbosity);
159 
161 }
162 
164 
166  fpCommand = new G4UIcommand("/vis/scene/add/arrow2D", this);
167  fpCommand -> SetGuidance ("Adds 2D arrow to current scene.");
168  G4bool omitable;
169  G4UIparameter* parameter;
170  parameter = new G4UIparameter ("x1", 'd', omitable = false);
171  fpCommand -> SetParameter (parameter);
172  parameter = new G4UIparameter ("y1", 'd', omitable = false);
173  fpCommand -> SetParameter (parameter);
174  parameter = new G4UIparameter ("x2", 'd', omitable = false);
175  fpCommand -> SetParameter (parameter);
176  parameter = new G4UIparameter ("y2", 'd', omitable = false);
177  fpCommand -> SetParameter (parameter);
178 }
179 
181  delete fpCommand;
182 }
183 
185  return "";
186 }
187 
189 {
191  G4bool warn(verbosity >= G4VisManager::warnings);
192 
193  G4Scene* pScene = fpVisManager->GetCurrentScene();
194  if (!pScene) {
195  if (verbosity >= G4VisManager::errors) {
196  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
197  }
198  return;
199  }
200 
201  G4double x1, y1, x2, y2;
202  std::istringstream is(newValue);
203  is >> x1 >> y1 >> x2 >> y2;
204 
205  Arrow2D* arrow2D = new Arrow2D
206  (x1, y1, x2, y2, fCurrentLineWidth, fCurrentColour);
207  G4VModel* model =
209  model->SetType("Arrow2D");
210  model->SetGlobalTag("Arrow2D");
211  model->SetGlobalDescription("Arrow2D: " + newValue);
212  const G4String& currentSceneName = pScene -> GetName ();
213  G4bool successful = pScene -> AddRunDurationModel (model, warn);
214  if (successful) {
215  if (verbosity >= G4VisManager::confirmations) {
216  G4cout << "A 2D arrow has been added to scene \""
217  << currentSceneName << "\"."
218  << G4endl;
219  }
220  }
221  else G4VisCommandsSceneAddUnsuccessful(verbosity);
222 
224 }
225 
229  G4double width, const G4Colour& colour):
230  fWidth(width), fColour(colour)
231 {
232  fShaftPolyline.push_back(G4Point3D(x1,y1,0));
233  fShaftPolyline.push_back(G4Point3D(x2,y2,0));
234  G4Vector3D arrowDirection = G4Vector3D(x2-x1,y2-y1,0).unit();
235  G4Vector3D arrowPointLeftDirection(arrowDirection);
236  arrowPointLeftDirection.rotateZ(150.*deg);
237  G4Vector3D arrowPointRightDirection(arrowDirection);
238  arrowPointRightDirection.rotateZ(-150.*deg);
239  fHeadPolyline.push_back(G4Point3D(x2,y2,0)+0.04*arrowPointLeftDirection);
240  fHeadPolyline.push_back(G4Point3D(x2,y2,0));
241  fHeadPolyline.push_back(G4Point3D(x2,y2,0)+0.04*arrowPointRightDirection);
242  G4VisAttributes va;
243  va.SetLineWidth(fWidth);
244  va.SetColour(fColour);
245  fShaftPolyline.SetVisAttributes(va);
246  fHeadPolyline.SetVisAttributes(va);
247 }
248 
249 void G4VisCommandSceneAddArrow2D::Arrow2D::operator()
250  (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters*)
251 {
252  sceneHandler.BeginPrimitives2D();
253  sceneHandler.AddPrimitive(fShaftPolyline);
254  sceneHandler.AddPrimitive(fHeadPolyline);
255  sceneHandler.EndPrimitives2D();
256 }
257 
259 
261  G4bool omitable;
262  fpCommand = new G4UIcommand ("/vis/scene/add/axes", this);
263  fpCommand -> SetGuidance ("Add axes.");
264  fpCommand -> SetGuidance
265  ("Draws axes at (x0, y0, z0) of given length and colour.");
266  fpCommand -> SetGuidance
267  ("If \"colour-string\" is \"auto\", x, y and z will be red, green and blue"
268  "\n respectively. Otherwise it can be one of the pre-defined text-specified"
269  "\n colours - see information printed by the vis manager at start-up or"
270  "\n use \"/vis/list\".");
271  fpCommand -> SetGuidance
272  ("If \"length\" is negative, it is set to about 25% of scene extent.");
273  fpCommand -> SetGuidance
274  ("If \"showtext\" is false, annotations are suppressed.");
275  G4UIparameter* parameter;
276  parameter = new G4UIparameter ("x0", 'd', omitable = true);
277  parameter->SetDefaultValue (0.);
278  fpCommand->SetParameter (parameter);
279  parameter = new G4UIparameter ("y0", 'd', omitable = true);
280  parameter->SetDefaultValue (0.);
281  fpCommand->SetParameter (parameter);
282  parameter = new G4UIparameter ("z0", 'd', omitable = true);
283  parameter->SetDefaultValue (0.);
284  fpCommand->SetParameter (parameter);
285  parameter = new G4UIparameter ("length", 'd', omitable = true);
286  parameter->SetDefaultValue (-1.);
287  fpCommand->SetParameter (parameter);
288  parameter = new G4UIparameter ("unit", 's', omitable = true);
289  parameter->SetDefaultValue ("m");
290  fpCommand->SetParameter (parameter);
291  parameter = new G4UIparameter ("colour-string", 's', omitable = true);
292  parameter->SetDefaultValue ("auto");
293  fpCommand->SetParameter (parameter);
294  parameter = new G4UIparameter ("showtext", 'b', omitable = true);
295  parameter->SetDefaultValue ("true");
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  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
316  }
317  return;
318  } else {
319  if (pScene->GetExtent().GetExtentRadius() <= 0.) {
320  if (verbosity >= G4VisManager::errors) {
321  G4cerr
322  << "ERROR: Scene has no extent. Add volumes or use \"/vis/scene/add/extent\"."
323  << G4endl;
324  }
325  return;
326  }
327  }
328 
329  G4String unitString, colourString, showTextString;
330  G4double x0, y0, z0, length;
331  std::istringstream is (newValue);
332  is >> x0 >> y0 >> z0 >> length >> unitString
333  >> colourString >> showTextString;
334  G4bool showText = G4UIcommand::ConvertToBool(showTextString);
335 
336 
337  G4double unit = G4UIcommand::ValueOf(unitString);
338  x0 *= unit; y0 *= unit; z0 *= unit;
339  const G4VisExtent& sceneExtent = pScene->GetExtent(); // Existing extent.
340  if (length < 0.) {
341  const G4double lengthMax = 0.5 * sceneExtent.GetExtentRadius();
342  const G4double intLog10Length = std::floor(std::log10(lengthMax));
343  length = std::pow(10,intLog10Length);
344  if (5.*length < lengthMax) length *= 5.;
345  else if (2.*length < lengthMax) length *= 2.;
346  } else {
347  length *= unit;
348  }
349 
350  // Consult scene for arrow width...
351  G4double arrowWidth =
352  0.005 * fCurrentLineWidth * sceneExtent.GetExtentRadius();
353  // ...but limit it to length/50.
354  if (arrowWidth > length/50.) arrowWidth = length/50.;
355 
356  G4VModel* model = new G4AxesModel
357  (x0, y0, z0, length, arrowWidth, colourString, newValue,
358  showText, fCurrentTextSize);
359 
360  G4bool successful = pScene -> AddRunDurationModel (model, warn);
361  const G4String& currentSceneName = pScene -> GetName ();
362  if (successful) {
363  if (verbosity >= G4VisManager::confirmations) {
364  G4cout << "Axes of length " << G4BestUnit(length,"Length")
365  << "have been added to scene \"" << currentSceneName << "\"."
366  << G4endl;
367  }
368  }
369  else G4VisCommandsSceneAddUnsuccessful(verbosity);
370 
372 }
373 
375 
377  G4bool omitable;
378  fpCommand = new G4UIcommand ("/vis/scene/add/date", this);
379  fpCommand -> SetGuidance ("Adds date to current scene.");
380  fpCommand -> SetGuidance
381  ("If \"date\"is omitted, the current date and time is drawn."
382  "\nOtherwise, the string, including the rest of the line, is drawn.");
383  G4UIparameter* parameter;
384  parameter = new G4UIparameter ("size", 'i', omitable = true);
385  parameter -> SetGuidance ("Screen size of text in pixels.");
386  parameter -> SetDefaultValue (18);
387  fpCommand -> SetParameter (parameter);
388  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
389  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
390  parameter -> SetDefaultValue (0.95);
391  fpCommand -> SetParameter (parameter);
392  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
393  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
394  parameter -> SetDefaultValue (0.9);
395  fpCommand -> SetParameter (parameter);
396  parameter = new G4UIparameter ("layout", 's', omitable = true);
397  parameter -> SetGuidance ("Layout, i.e., adjustment: left|centre|right.");
398  parameter -> SetDefaultValue ("right");
399  fpCommand -> SetParameter (parameter);
400  parameter = new G4UIparameter ("date", 's', omitable = true);
401  parameter -> SetDefaultValue ("-");
402  fpCommand -> SetParameter (parameter);
403 }
404 
406  delete fpCommand;
407 }
408 
410  return "";
411 }
412 
414 {
416  G4bool warn(verbosity >= G4VisManager::warnings);
417 
418  G4Scene* pScene = fpVisManager->GetCurrentScene();
419  if (!pScene) {
420  if (verbosity >= G4VisManager::errors) {
421  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
422  }
423  return;
424  }
425 
426  G4int size;
427  G4double x, y;
428  G4String layoutString, dateString;
429  std::istringstream is(newValue);
430  is >> size >> x >> y >> layoutString >> dateString;
431  // Read rest of line, if any.
432  const size_t NREMAINDER = 100;
433  char remainder[NREMAINDER];
434  remainder[0]='\0'; // In case there is nothing remaining.
435  is.getline(remainder, NREMAINDER);
436  dateString += remainder;
437  G4Text::Layout layout = G4Text::right;
438  if (layoutString(0) == 'l') layout = G4Text::left;
439  else if (layoutString(0) == 'c') layout = G4Text::centre;
440  else if (layoutString(0) == 'r') layout = G4Text::right;
441 
442  Date* date = new Date(fpVisManager, size, x, y, layout, dateString);
443  G4VModel* model =
445  model->SetType("Date");
446  model->SetGlobalTag("Date");
447  model->SetGlobalDescription("Date: " + newValue);
448  const G4String& currentSceneName = pScene -> GetName ();
449  G4bool successful = pScene -> AddRunDurationModel (model, warn);
450  if (successful) {
451  if (verbosity >= G4VisManager::confirmations) {
452  G4cout << "Date has been added to scene \""
453  << currentSceneName << "\"."
454  << G4endl;
455  }
456  }
457  else G4VisCommandsSceneAddUnsuccessful(verbosity);
458 
460 }
461 
462 void G4VisCommandSceneAddDate::Date::operator()
463  (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters*)
464 {
465  G4String time;
466  if (fDate == "-") {
467  time = fTimer.GetClockTime();
468  } else {
469  time = fDate;
470  }
471  // Check for \n, starting from back, and erase.
472  std::string::size_type i = time.rfind('\n');
473  if (i != std::string::npos) time.erase(i);
474  G4Text text(time, G4Point3D(fX, fY, 0.));
475  text.SetScreenSize(fSize);
476  text.SetLayout(fLayout);
477  G4VisAttributes textAtts(G4Colour(0.,1.,1));
478  text.SetVisAttributes(textAtts);
479  sceneHandler.BeginPrimitives2D();
480  sceneHandler.AddPrimitive(text);
481  sceneHandler.EndPrimitives2D();
482 }
483 
485 
487  fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/add/digis", this);
488  fpCommand -> SetGuidance ("Adds digis to current scene.");
489  fpCommand -> SetGuidance
490  ("Digis are drawn at end of event when the scene in which"
491  "\nthey are added is current.");
492 }
493 
495  delete fpCommand;
496 }
497 
499  return "";
500 }
501 
503 
505  G4bool warn(verbosity >= G4VisManager::warnings);
506 
507  G4Scene* pScene = fpVisManager->GetCurrentScene();
508  if (!pScene) {
509  if (verbosity >= G4VisManager::errors) {
510  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
511  }
512  return;
513  }
514 
515  G4VModel* model = new G4DigiModel;
516  const G4String& currentSceneName = pScene -> GetName ();
517  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
518  if (successful) {
519  if (verbosity >= G4VisManager::confirmations) {
520  G4cout << "Digis, if any, will be drawn at end of run in scene \""
521  << currentSceneName << "\"."
522  << G4endl;
523  }
524  }
525  else G4VisCommandsSceneAddUnsuccessful(verbosity);
526 
528 }
529 
531 
533  G4bool omitable;
534  fpCommand = new G4UIcommand ("/vis/scene/add/electricField", this);
535  fpCommand -> SetGuidance
536  ("Adds electric field representation to current scene.");
537  fpCommand -> SetGuidance
538  ("The first parameter is no. of data points per half scene. So, possibly, at"
539  "\nmaximum, the number of data points sampled is (2*n+1)^3, which can grow"
540  "\nlarge--be warned!"
541  "\nThe default value is 10, i.e., a 21x21x21 array, i.e., 9,261 sampling points."
542  "\nThat may swamp you scene, but usually, a field is limited to a small part of"
543  "\nthe scene, so it's not a problem. But if it is, here are some of the things"
544  "\nyou can do:"
545  "\n- reduce the number of data points per half scene (first parameter);"
546  "\n- specify \"lightArrow\" (second parameter);"
547  "\n- restrict the region sampled with \"/vis/set/extentForField\";"
548  "\n- restrict the drawing to a specific volume with"
549  "\n \"/vis/set/volumeForField\" or \"/vis/touchable/volumeForField\"."
550  "\nNote: you may have to deactivate existing field models with"
551  "\n \"/vis/scene/activateModel Field false\" and re-issue"
552  "\n \"/vis/scene/add/...Field\" command again.");
553  fpCommand -> SetGuidance
554  ("In the arrow representation, the length of the arrow is proportional"
555  "\nto the magnitude of the field and the colour is mapped onto the range"
556  "\nas a fraction of the maximum magnitude: 0->0.5->1 is blue->green->red.");
557  G4UIparameter* parameter;
558  parameter = new G4UIparameter ("nDataPointsPerHalfScene", 'i', omitable = true);
559  parameter -> SetDefaultValue (10);
560  fpCommand -> SetParameter (parameter);
561  parameter = new G4UIparameter ("representation", 's', omitable = true);
562  parameter -> SetParameterCandidates("fullArrow lightArrow");
563  parameter -> SetDefaultValue ("fullArrow");
564  fpCommand -> SetParameter (parameter);
565 }
566 
568  delete fpCommand;
569 }
570 
572  return "";
573 }
574 
576 (G4UIcommand*, G4String newValue) {
577 
578  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
579  G4bool warn(verbosity >= G4VisManager::warnings);
580 
581  G4Scene* pScene = fpVisManager->GetCurrentScene();
582  if (!pScene) {
583  if (verbosity >= G4VisManager::errors) {
584  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
585  }
586  return;
587  }
588 
589  G4int nDataPointsPerHalfScene;
590  G4String representation;
591  std::istringstream iss(newValue);
592  iss >> nDataPointsPerHalfScene >> representation;
594  modelRepresentation = G4ElectricFieldModel::fullArrow;
595  if (representation == "lightArrow") {
596  modelRepresentation = G4ElectricFieldModel::lightArrow;
597  }
598  G4VModel* model;
599  model = new G4ElectricFieldModel
600  (nDataPointsPerHalfScene,modelRepresentation,
601  fCurrentArrow3DLineSegmentsPerCircle,
602  fCurrentExtentForField,
603  fCurrrentPVFindingsForField);
604  const G4String& currentSceneName = pScene -> GetName ();
605  G4bool successful = pScene -> AddRunDurationModel (model, warn);
606  if (successful) {
607  if (verbosity >= G4VisManager::confirmations) {
608  G4cout
609  << "Electric field, if any, will be drawn in scene \""
610  << currentSceneName
611  << "\"\n with "
612  << nDataPointsPerHalfScene
613  << " data points per half scene and with representation \""
614  << representation
615  << '\"'
616  << G4endl;
617  }
618  }
619  else G4VisCommandsSceneAddUnsuccessful(verbosity);
620 
621  CheckSceneAndNotifyHandlers (pScene);
622 }
623 
625 
627  G4bool omitable;
628  fpCommand = new G4UIcommand ("/vis/scene/add/eventID", this);
629  fpCommand -> SetGuidance ("Adds eventID to current scene.");
630  fpCommand -> SetGuidance
631  ("Run and event numbers are drawn at end of event or run when"
632  "\n the scene in which they are added is current.");
633  G4UIparameter* parameter;
634  parameter = new G4UIparameter ("size", 'i', omitable = true);
635  parameter -> SetGuidance ("Screen size of text in pixels.");
636  parameter -> SetDefaultValue (18);
637  fpCommand -> SetParameter (parameter);
638  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
639  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
640  parameter -> SetDefaultValue (-0.95);
641  fpCommand -> SetParameter (parameter);
642  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
643  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
644  parameter -> SetDefaultValue (0.9);
645  fpCommand -> SetParameter (parameter);
646  parameter = new G4UIparameter ("layout", 's', omitable = true);
647  parameter -> SetGuidance ("Layout, i.e., adjustment: left|centre|right.");
648  parameter -> SetDefaultValue ("left");
649  fpCommand -> SetParameter (parameter);
650 }
651 
653  delete fpCommand;
654 }
655 
657  return "";
658 }
659 
661 {
663  G4bool warn(verbosity >= G4VisManager::warnings);
664 
665  G4Scene* pScene = fpVisManager->GetCurrentScene();
666  if (!pScene) {
667  if (verbosity >= G4VisManager::errors) {
668  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
669  }
670  return;
671  }
672 
673  G4int size;
674  G4double x, y;
675  G4String layoutString;
676  std::istringstream is(newValue);
677  is >> size >> x >> y >> layoutString;
678 
679  G4Text::Layout layout = G4Text::right;
680  if (layoutString(0) == 'l') layout = G4Text::left;
681  else if (layoutString(0) == 'c') layout = G4Text::centre;
682  else if (layoutString(0) == 'r') layout = G4Text::right;
683 
684  // For End of Event (only for reviewing kept events one by one)
685  EventID* eoeEventID
686  = new EventID(forEndOfEvent, fpVisManager, size, x, y, layout);
687  G4VModel* eoeModel =
689  eoeModel->SetType("EoEEventID");
690  eoeModel->SetGlobalTag("EoEEventID");
691  eoeModel->SetGlobalDescription("EoEEventID: " + newValue);
692  G4bool successfulEoE = pScene -> AddEndOfEventModel (eoeModel, warn);
693 
694  // For End of Run
695  EventID* eorEventID
696  = new EventID(forEndOfRun, fpVisManager, size, x, y, layout);
697  G4VModel* eorModel =
699  eorModel->SetType("EoREventID");
700  eorModel->SetGlobalTag("EoREventID");
701  eorModel->SetGlobalDescription("EoREventID: " + newValue);
702  G4bool successfulEoR = pScene -> AddEndOfRunModel (eorModel, warn);
703 
704  if (successfulEoE && successfulEoR) {
705  if (verbosity >= G4VisManager::confirmations) {
706  const G4String& currentSceneName = pScene -> GetName ();
707  G4cout << "EventID has been added to scene \""
708  << currentSceneName << "\"."
709  << G4endl;
710  }
711  }
712  else G4VisCommandsSceneAddUnsuccessful(verbosity);
713 
715 }
716 
717 void G4VisCommandSceneAddEventID::EventID::operator()
718 (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters* mp)
719 {
721 #ifdef G4MULTITHREADED
724  }
725 #endif
726  if (!runManager) return;
727 
728  const G4Run* currentRun = runManager->GetCurrentRun();
729  if (!currentRun) return;
730 
731  const G4int currentRunID = currentRun->GetRunID();
732 
733  std::ostringstream oss;
734  switch (fForWhat) {
735  case forEndOfEvent:
736  {
737  // Only use if reviewing kept events
738  if (!fpVisManager->GetReviewingKeptEvents()) return;
739  const G4Event* currentEvent = mp->GetEvent();
740  if (!currentEvent) return;
741  G4int eventID = currentEvent->GetEventID();
742  oss << "Run " << currentRunID << " Event " << eventID;
743  break;
744  }
745  case forEndOfRun:
746  {
747  // Only use if NOT reviewing kept events
748  if (fpVisManager->GetReviewingKeptEvents()) return;
749  const G4int nEvents = currentRun->GetNumberOfEventToBeProcessed();
750  const auto* events = currentRun->GetEventVector();
751  size_t nKeptEvents = events? events->size(): 0;
752  oss << "Run " << currentRunID << " (" << nEvents << " event";
753  if (nEvents != 1) oss << 's';
754  oss << ", " << nKeptEvents << " kept)";
755  break;
756  }
757  default:
758  return;
759  }
760 
761  G4Text text(oss.str(), G4Point3D(fX, fY, 0.));
762  text.SetScreenSize(fSize);
763  text.SetLayout(fLayout);
764  G4VisAttributes textAtts(G4Colour(0.,1.,1));
765  text.SetVisAttributes(textAtts);
766  sceneHandler.BeginPrimitives2D();
767  sceneHandler.AddPrimitive(text);
768  sceneHandler.EndPrimitives2D();
769 }
770 
772 
774  fpCommand = new G4UIcommand("/vis/scene/add/extent", this);
775  fpCommand -> SetGuidance
776  ("Adds a dummy model with given extent to the current scene."
777  "\nRequires the limits: xmin, xmax, ymin, ymax, zmin, zmax unit."
778  "\nThis can be used to provide an extent to the scene even if"
779  "\nno other models with extent are available. For example,"
780  "\neven if there is no geometry. In that case, for example:"
781  "\n /vis/open OGL"
782  "\n /vis/scene/create"
783  "\n /vis/scene/add/extent -300 300 -300 300 -300 300 cm"
784  "\n /vis/sceneHandler/attach");
785  G4bool omitable;
786  G4UIparameter* parameter;
787  parameter = new G4UIparameter ("xmin", 'd', omitable = true);
788  parameter -> SetDefaultValue (0.);
789  fpCommand -> SetParameter (parameter);
790  parameter = new G4UIparameter ("xmax", 'd', omitable = true);
791  parameter -> SetDefaultValue (0.);
792  fpCommand -> SetParameter (parameter);
793  parameter = new G4UIparameter ("ymin", 'd', omitable = true);
794  parameter -> SetDefaultValue (0.);
795  fpCommand -> SetParameter (parameter);
796  parameter = new G4UIparameter ("ymax", 'd', omitable = true);
797  parameter -> SetDefaultValue (0.);
798  fpCommand -> SetParameter (parameter);
799  parameter = new G4UIparameter ("zmin", 'd', omitable = true);
800  parameter -> SetDefaultValue (0.);
801  fpCommand -> SetParameter (parameter);
802  parameter = new G4UIparameter ("zmax", 'd', omitable = true);
803  parameter -> SetDefaultValue (0.);
804  fpCommand -> SetParameter (parameter);
805  parameter = new G4UIparameter ("unit", 's', omitable = true);
806  parameter -> SetDefaultValue ("m");
807  fpCommand -> SetParameter (parameter);
808 }
809 
811  delete fpCommand;
812 }
813 
815  return "";
816 }
817 
819 {
821  G4bool warn(verbosity >= G4VisManager::warnings);
822 
823  G4Scene* pScene = fpVisManager->GetCurrentScene();
824  if (!pScene) {
825  if (verbosity >= G4VisManager::errors) {
826  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
827  }
828  return;
829  }
830 
831  G4double xmin, xmax, ymin, ymax, zmin, zmax;
832  G4String unitString;
833  std::istringstream is(newValue);
834  is >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax >> unitString;
835  G4double unit = G4UIcommand::ValueOf(unitString);
836  xmin *= unit; xmax *= unit;
837  ymin *= unit; ymax *= unit;
838  zmin *= unit; zmax *= unit;
839 
840  G4VisExtent visExtent(xmin, xmax, ymin, ymax, zmin, zmax);
841  Extent* extent = new Extent(xmin, xmax, ymin, ymax, zmin, zmax);
842  G4VModel* model =
844  model->SetType("Extent");
845  model->SetGlobalTag("Extent");
846  model->SetGlobalDescription("Extent: " + newValue);
847  model->SetExtent(visExtent);
848  const G4String& currentSceneName = pScene -> GetName ();
849  G4bool successful = pScene -> AddRunDurationModel (model, warn);
850  if (successful) {
851  if (verbosity >= G4VisManager::confirmations) {
852  G4cout << "A benign model with extent "
853  << visExtent
854  << " has been added to scene \""
855  << currentSceneName << "\"."
856  << G4endl;
857  }
858  }
859  else G4VisCommandsSceneAddUnsuccessful(verbosity);
860 
862 }
863 
867  G4double zmin, G4double zmax):
868 fExtent(xmin,xmax,ymin,ymax,zmin,zmax)
869 {}
870 
871 void G4VisCommandSceneAddExtent::Extent::operator()
872 (G4VGraphicsScene&, const G4Transform3D&, const G4ModelingParameters*)
873 {}
874 
876 
878  fpCommand = new G4UIcommand("/vis/scene/add/frame", this);
879  fpCommand -> SetGuidance ("Add frame to current scene.");
880  G4bool omitable;
881  G4UIparameter* parameter;
882  parameter = new G4UIparameter ("size", 'd', omitable = true);
883  parameter -> SetGuidance ("Size of frame. 1 = full window.");
884  parameter -> SetParameterRange ("size > 0 && size <=1");
885  parameter -> SetDefaultValue (0.97);
886  fpCommand -> SetParameter (parameter);
887 }
888 
890  delete fpCommand;
891 }
892 
894  return "";
895 }
896 
898 {
900  G4bool warn(verbosity >= G4VisManager::warnings);
901 
902  G4Scene* pScene = fpVisManager->GetCurrentScene();
903  if (!pScene) {
904  if (verbosity >= G4VisManager::errors) {
905  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
906  }
907  return;
908  }
909 
910  G4double size;
911  std::istringstream is(newValue);
912  is >> size;
913 
914  Frame* frame = new Frame(size, fCurrentLineWidth, fCurrentColour);
915  G4VModel* model =
917  model->SetType("Frame");
918  model->SetGlobalTag("Frame");
919  model->SetGlobalDescription("Frame: " + newValue);
920  const G4String& currentSceneName = pScene -> GetName ();
921  G4bool successful = pScene -> AddRunDurationModel (model, warn);
922  if (successful) {
923  if (verbosity >= G4VisManager::confirmations) {
924  G4cout << "Frame has been added to scene \""
925  << currentSceneName << "\"."
926  << G4endl;
927  }
928  }
929  else G4VisCommandsSceneAddUnsuccessful(verbosity);
930 
932 }
933 
934 void G4VisCommandSceneAddFrame::Frame::operator()
935  (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters*)
936 {
937  G4Polyline frame;
938  frame.push_back(G4Point3D( fSize, fSize, 0.));
939  frame.push_back(G4Point3D(-fSize, fSize, 0.));
940  frame.push_back(G4Point3D(-fSize, -fSize, 0.));
941  frame.push_back(G4Point3D( fSize, -fSize, 0.));
942  frame.push_back(G4Point3D( fSize, fSize, 0.));
943  G4VisAttributes va;
944  va.SetLineWidth(fWidth);
945  va.SetColour(fColour);
946  frame.SetVisAttributes(va);
947  sceneHandler.BeginPrimitives2D();
948  sceneHandler.AddPrimitive(frame);
949  sceneHandler.EndPrimitives2D();
950 }
951 
953 
955  G4bool omitable;
956  G4UIparameter* parameter;
957  fpCommand = new G4UIcommand ("/vis/scene/add/gps", this);
958  fpCommand -> SetGuidance
959  ("A representation of the source(s) of the General Particle Source"
960  "\nwill be added to current scene and drawn, if applicable.");
962  fpCommand->SetGuidance("Default: red and transparent.");
963  parameter = new G4UIparameter("red_or_string", 's', omitable = true);
964  parameter -> SetDefaultValue ("1.");
965  fpCommand -> SetParameter (parameter);
966  parameter = new G4UIparameter("green", 'd', omitable = true);
967  parameter -> SetDefaultValue (0.);
968  fpCommand -> SetParameter (parameter);
969  parameter = new G4UIparameter ("blue", 'd', omitable = true);
970  parameter -> SetDefaultValue (0.);
971  fpCommand -> SetParameter (parameter);
972  parameter = new G4UIparameter ("opacity", 'd', omitable = true);
973  parameter -> SetDefaultValue (0.3);
974  fpCommand -> SetParameter (parameter);
975 }
976 
978  delete fpCommand;
979 }
980 
982  return "";
983 }
984 
986 
988  G4bool warn(verbosity >= G4VisManager::warnings);
989 
990  G4Scene* pScene = fpVisManager->GetCurrentScene();
991  if (!pScene) {
992  if (verbosity >= G4VisManager::errors) {
993  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
994  }
995  return;
996  }
997 
998  G4String redOrString;
999  G4double green, blue, opacity;
1000  std::istringstream iss(newValue);
1001  iss >> redOrString >> green >> blue >> opacity;
1002  G4Colour colour(1.,0.,0.,0.3); // Default red and transparent.
1003  ConvertToColour(colour, redOrString, green, blue, opacity);
1004 
1005  G4VModel* model = new G4GPSModel(colour);
1006  const G4String& currentSceneName = pScene -> GetName ();
1007  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1008  if (successful) {
1009  if (verbosity >= G4VisManager::confirmations) {
1010  G4cout <<
1011  "A representation of the source(s) of the General Particle Source will be drawn"
1012  "\n in colour " << colour << " for scene \""
1013  << currentSceneName << "\" if applicable."
1014  << G4endl;
1015  }
1016  }
1017  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1018 
1019  CheckSceneAndNotifyHandlers (pScene);
1020 }
1021 
1023 
1025  fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/add/hits", this);
1026  fpCommand -> SetGuidance ("Adds hits to current scene.");
1027  fpCommand -> SetGuidance
1028  ("Hits are drawn at end of event when the scene in which"
1029  "\nthey are added is current.");
1030 }
1031 
1033  delete fpCommand;
1034 }
1035 
1037  return "";
1038 }
1039 
1041 
1043  G4bool warn(verbosity >= G4VisManager::warnings);
1044 
1045  G4Scene* pScene = fpVisManager->GetCurrentScene();
1046  if (!pScene) {
1047  if (verbosity >= G4VisManager::errors) {
1048  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1049  }
1050  return;
1051  }
1052 
1053  G4VModel* model = new G4HitsModel;
1054  const G4String& currentSceneName = pScene -> GetName ();
1055  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
1056  if (successful) {
1057  if (verbosity >= G4VisManager::confirmations) {
1058  G4cout << "Hits, if any, will be drawn at end of run in scene \""
1059  << currentSceneName << "\"."
1060  << G4endl;
1061  }
1062  }
1063  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1064 
1065  CheckSceneAndNotifyHandlers (pScene);
1066 }
1067 
1069 
1071  fpCommand = new G4UIcommand("/vis/scene/add/line", this);
1072  fpCommand -> SetGuidance ("Adds line to current scene.");
1073  G4bool omitable;
1074  G4UIparameter* parameter;
1075  parameter = new G4UIparameter ("x1", 'd', omitable = false);
1076  fpCommand -> SetParameter (parameter);
1077  parameter = new G4UIparameter ("y1", 'd', omitable = false);
1078  fpCommand -> SetParameter (parameter);
1079  parameter = new G4UIparameter ("z1", 'd', omitable = false);
1080  fpCommand -> SetParameter (parameter);
1081  parameter = new G4UIparameter ("x2", 'd', omitable = false);
1082  fpCommand -> SetParameter (parameter);
1083  parameter = new G4UIparameter ("y2", 'd', omitable = false);
1084  fpCommand -> SetParameter (parameter);
1085  parameter = new G4UIparameter ("z2", 'd', omitable = false);
1086  fpCommand -> SetParameter (parameter);
1087  parameter = new G4UIparameter ("unit", 's', omitable = true);
1088  parameter->SetDefaultValue ("m");
1089  fpCommand->SetParameter (parameter);
1090 }
1091 
1093  delete fpCommand;
1094 }
1095 
1097  return "";
1098 }
1099 
1101 {
1103  G4bool warn(verbosity >= G4VisManager::warnings);
1104 
1105  G4Scene* pScene = fpVisManager->GetCurrentScene();
1106  if (!pScene) {
1107  if (verbosity >= G4VisManager::errors) {
1108  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1109  }
1110  return;
1111  }
1112 
1113  G4String unitString;
1114  G4double x1, y1, z1, x2, y2, z2;
1115  std::istringstream is(newValue);
1116  is >> x1 >> y1 >> z1 >> x2 >> y2 >> z2 >> unitString;
1117  G4double unit = G4UIcommand::ValueOf(unitString);
1118  x1 *= unit; y1 *= unit; z1 *= unit;
1119  x2 *= unit; y2 *= unit; z2 *= unit;
1120 
1121  Line* line = new Line(x1, y1, z1, x2, y2, z2,
1123  G4VModel* model =
1125  model->SetType("Line");
1126  model->SetGlobalTag("Line");
1127  model->SetGlobalDescription("Line: " + newValue);
1128  const G4String& currentSceneName = pScene -> GetName ();
1129  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1130  if (successful) {
1131  if (verbosity >= G4VisManager::confirmations) {
1132  G4cout << "Line has been added to scene \""
1133  << currentSceneName << "\"."
1134  << G4endl;
1135  }
1136  }
1137  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1138 
1139  CheckSceneAndNotifyHandlers (pScene);
1140 }
1141 
1144  G4double x2, G4double y2, G4double z2,
1145  G4double width, const G4Colour& colour):
1146  fWidth(width), fColour(colour)
1147 {
1148  fPolyline.push_back(G4Point3D(x1,y1,z1));
1149  fPolyline.push_back(G4Point3D(x2,y2,z2));
1150  G4VisAttributes va;
1151  va.SetLineWidth(fWidth);
1152  va.SetColour(fColour);
1153  fPolyline.SetVisAttributes(va);
1154 }
1155 
1156 void G4VisCommandSceneAddLine::Line::operator()
1157  (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters*)
1158 {
1159  sceneHandler.BeginPrimitives();
1160  sceneHandler.AddPrimitive(fPolyline);
1161  sceneHandler.EndPrimitives();
1162 }
1163 
1165 
1167  fpCommand = new G4UIcommand("/vis/scene/add/line2D", this);
1168  fpCommand -> SetGuidance ("Adds 2D line to current scene.");
1169  G4bool omitable;
1170  G4UIparameter* parameter;
1171  parameter = new G4UIparameter ("x1", 'd', omitable = false);
1172  fpCommand -> SetParameter (parameter);
1173  parameter = new G4UIparameter ("y1", 'd', omitable = false);
1174  fpCommand -> SetParameter (parameter);
1175  parameter = new G4UIparameter ("x2", 'd', omitable = false);
1176  fpCommand -> SetParameter (parameter);
1177  parameter = new G4UIparameter ("y2", 'd', omitable = false);
1178  fpCommand -> SetParameter (parameter);
1179 }
1180 
1182  delete fpCommand;
1183 }
1184 
1186  return "";
1187 }
1188 
1190 {
1192  G4bool warn(verbosity >= G4VisManager::warnings);
1193 
1194  G4Scene* pScene = fpVisManager->GetCurrentScene();
1195  if (!pScene) {
1196  if (verbosity >= G4VisManager::errors) {
1197  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1198  }
1199  return;
1200  }
1201 
1202  G4double x1, y1, x2, y2;
1203  std::istringstream is(newValue);
1204  is >> x1 >> y1 >> x2 >> y2;
1205 
1206  Line2D* line2D = new Line2D
1207  (x1, y1, x2, y2, fCurrentLineWidth, fCurrentColour);
1208  G4VModel* model =
1210  model->SetType("Line2D");
1211  model->SetGlobalTag("Line2D");
1212  model->SetGlobalDescription("Line2D: " + newValue);
1213  const G4String& currentSceneName = pScene -> GetName ();
1214  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1215  if (successful) {
1216  if (verbosity >= G4VisManager::confirmations) {
1217  G4cout << "A 2D line has been added to scene \""
1218  << currentSceneName << "\"."
1219  << G4endl;
1220  }
1221  }
1222  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1223 
1224  CheckSceneAndNotifyHandlers (pScene);
1225 }
1226 
1229  G4double x2, G4double y2,
1230  G4double width, const G4Colour& colour):
1231  fWidth(width), fColour(colour)
1232 {
1233  fPolyline.push_back(G4Point3D(x1,y1,0));
1234  fPolyline.push_back(G4Point3D(x2,y2,0));
1235  G4VisAttributes va;
1236  va.SetLineWidth(fWidth);
1237  va.SetColour(fColour);
1238  fPolyline.SetVisAttributes(va);
1239 }
1240 
1241 void G4VisCommandSceneAddLine2D::Line2D::operator()
1242  (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters*)
1243 {
1244  sceneHandler.BeginPrimitives2D();
1245  sceneHandler.AddPrimitive(fPolyline);
1246  sceneHandler.EndPrimitives2D();
1247 }
1248 
1250 
1252  G4bool omitable;
1253  fpCommand = new G4UIcommand ("/vis/scene/add/logicalVolume", this);
1254  fpCommand -> SetGuidance ("Adds a logical volume to the current scene,");
1255  fpCommand -> SetGuidance
1256  ("Shows boolean components (if any), voxels (if any), readout geometry"
1257  "\n (if any), local axes and overlaps (if any), under control of the"
1258  "\n appropriate flag."
1259  "\n Note: voxels are not constructed until start of run -"
1260  "\n \"/run/beamOn\". (For voxels without a run, \"/run/beamOn 0\".)");
1261  G4UIparameter* parameter;
1262  parameter = new G4UIparameter ("logical-volume-name", 's', omitable = false);
1263  fpCommand -> SetParameter (parameter);
1264  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
1265  parameter -> SetGuidance ("Depth of descent of geometry hierarchy.");
1266  parameter -> SetDefaultValue (1);
1267  fpCommand -> SetParameter (parameter);
1268  parameter = new G4UIparameter ("booleans-flag", 'b', omitable = true);
1269  parameter -> SetDefaultValue (true);
1270  fpCommand -> SetParameter (parameter);
1271  parameter = new G4UIparameter ("voxels-flag", 'b', omitable = true);
1272  parameter -> SetDefaultValue (true);
1273  fpCommand -> SetParameter (parameter);
1274  parameter = new G4UIparameter ("readout-flag", 'b', omitable = true);
1275  parameter -> SetDefaultValue (true);
1276  fpCommand -> SetParameter (parameter);
1277  parameter = new G4UIparameter ("axes-flag", 'b', omitable = true);
1278  parameter -> SetDefaultValue (true);
1279  parameter -> SetGuidance ("Set \"false\" to suppress axes.");
1280  fpCommand -> SetParameter (parameter);
1281  parameter = new G4UIparameter("check-overlap-flag", 'b', omitable = true);
1282  parameter->SetDefaultValue(true);
1283  parameter -> SetGuidance ("Set \"false\" to suppress overlap check.");
1284  fpCommand->SetParameter(parameter);
1285 }
1286 
1288  delete fpCommand;
1289 }
1290 
1292  return "";
1293 }
1294 
1296  G4String newValue) {
1297 
1299  G4bool warn(verbosity >= G4VisManager::warnings);
1300 
1301  G4Scene* pScene = fpVisManager->GetCurrentScene();
1302  if (!pScene) {
1303  if (verbosity >= G4VisManager::errors) {
1304  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1305  }
1306  return;
1307  }
1308 
1309  G4String name;
1310  G4int requestedDepthOfDescent;
1311  G4String booleansString, voxelsString, readoutString, axesString;
1312  G4String overlapString;
1313  std::istringstream is (newValue);
1314  is >> name >> requestedDepthOfDescent
1315  >> booleansString >> voxelsString >> readoutString >> axesString
1316  >> overlapString;
1317  G4bool booleans = G4UIcommand::ConvertToBool(booleansString);
1318  G4bool voxels = G4UIcommand::ConvertToBool(voxelsString);
1319  G4bool readout = G4UIcommand::ConvertToBool(readoutString);
1320  G4bool axes = G4UIcommand::ConvertToBool(axesString);
1321  G4bool checkOverlaps = G4UIcommand::ConvertToBool(overlapString);
1322 
1324  int nLV = pLVStore -> size ();
1325  int iLV;
1326  G4LogicalVolume* pLV = 0;
1327  for (iLV = 0; iLV < nLV; iLV++ ) {
1328  pLV = (*pLVStore) [iLV];
1329  if (pLV -> GetName () == name) break;
1330  }
1331  if (iLV == nLV) {
1332  if (verbosity >= G4VisManager::errors) {
1333  G4cerr << "ERROR: Logical volume " << name
1334  << " not found in logical volume store." << G4endl;
1335  }
1336  return;
1337  }
1338 
1339  const std::vector<G4Scene::Model>& rdModelList =
1340  pScene -> GetRunDurationModelList();
1341  std::vector<G4Scene::Model>::const_iterator i;
1342  for (i = rdModelList.begin(); i != rdModelList.end(); ++i) {
1343  if (i->fpModel->GetGlobalDescription().find("Volume") != std::string::npos) break;
1344  }
1345  if (i != rdModelList.end()) {
1346  if (verbosity >= G4VisManager::errors) {
1347  G4cout << "There is already a volume, \""
1348  << i->fpModel->GetGlobalDescription()
1349  << "\",\n in the run-duration model list of scene \""
1350  << pScene -> GetName()
1351  << "\".\n Your logical volume must be the only volume in the scene."
1352  << "\n Create a new scene and try again:"
1353  << "\n /vis/specify " << name
1354  << "\n or"
1355  << "\n /vis/scene/create"
1356  << "\n /vis/scene/add/logicalVolume " << name
1357  << "\n /vis/sceneHandler/attach"
1358  << "\n (and also, if necessary, /vis/viewer/flush)"
1359  << G4endl;
1360  }
1361  return;
1362  }
1363 
1365  (pLV, requestedDepthOfDescent, booleans, voxels, readout, checkOverlaps);
1366  const G4String& currentSceneName = pScene -> GetName ();
1367  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1368 
1369  if (successful) {
1370 
1371  G4bool axesSuccessful = false;
1372  if (axes) {
1373  const G4double radius = model->GetExtent().GetExtentRadius();
1374  const G4double axisLengthMax = radius / 2.;
1375  const G4double intLog10Length = std::floor(std::log10(axisLengthMax));
1376  G4double axisLength = std::pow(10,intLog10Length);
1377  if (5.*axisLength < axisLengthMax) axisLength *= 5.;
1378  else if (2.*axisLength < axisLengthMax) axisLength *= 2.;
1379  const G4double axisWidth = axisLength / 20.;
1380  G4VModel* axesModel = new G4AxesModel(0.,0.,0.,axisLength,axisWidth);
1381  axesSuccessful = pScene -> AddRunDurationModel (axesModel, warn);
1382  }
1383 
1384 // if (verbosity >= G4VisManager::warnings) {
1385 // const std::map<G4String,G4AttDef>* attDefs = model->GetAttDefs();
1386 // std::vector<G4AttValue>* attValues = model->CreateCurrentAttValues();
1387 // G4cout << G4AttCheck(attValues, attDefs);
1388 // delete attValues;
1389 // }
1390 
1391  if (verbosity >= G4VisManager::confirmations) {
1392  G4cout << "Logical volume \"" << pLV -> GetName ()
1393  << "\" with requested depth of descent "
1394  << requestedDepthOfDescent
1395  << ",\n with";
1396  if (!booleans) G4cout << "out";
1397  G4cout << " boolean components, with";
1398  if (!voxels) G4cout << "out";
1399  G4cout << " voxels,\n with";
1400  if (!readout) G4cout << "out";
1401  G4cout << " readout geometry and with";
1402  if (!checkOverlaps) G4cout << "out";
1403  G4cout << " overlap checking"
1404  << "\n has been added to scene \"" << currentSceneName << "\".";
1405  if (axes) {
1406  if (axesSuccessful) {
1407  G4cout <<
1408  "\n Axes have also been added at the origin of local cooordinates.";
1409  } else {
1410  G4cout <<
1411  "\n Axes have not been added for some reason possibly stated above.";
1412  }
1413  }
1414  G4cout << G4endl;
1415  }
1416  }
1417  else {
1419  return;
1420  }
1421 
1422  CheckSceneAndNotifyHandlers (pScene);
1423 }
1424 
1425 
1427 
1429  G4bool omitable;
1430  fpCommand = new G4UIcommand ("/vis/scene/add/logo", this);
1431  fpCommand -> SetGuidance ("Adds a G4 logo to the current scene.");
1432  fpCommand -> SetGuidance
1433  ("If \"unit\" is \"auto\", height is roughly one tenth of scene extent.");
1434  fpCommand -> SetGuidance
1435  ("\"direction\" is that of outward-facing normal to front face of logo."
1436  "\nIf \"direction\" is \"auto\", logo faces the user in the current viewer.");
1437  fpCommand -> SetGuidance
1438  ("\nIf \"placement\" is \"auto\", logo is placed at bottom right of screen"
1439  "\n when viewed from logo direction.");
1440  G4UIparameter* parameter;
1441  parameter = new G4UIparameter ("height", 'd', omitable = true);
1442  parameter->SetDefaultValue (1.);
1443  fpCommand->SetParameter (parameter);
1444  parameter = new G4UIparameter ("unit", 's', omitable = true);
1445  parameter->SetDefaultValue ("auto");
1446  fpCommand->SetParameter (parameter);
1447  parameter = new G4UIparameter ("direction", 's', omitable = true);
1448  parameter->SetGuidance ("auto|[-]x|[-]y|[-]z");
1449  parameter->SetDefaultValue ("auto");
1450  fpCommand->SetParameter (parameter);
1451  parameter = new G4UIparameter ("red", 'd', omitable = true);
1452  parameter->SetDefaultValue (0.);
1453  fpCommand->SetParameter (parameter);
1454  parameter = new G4UIparameter ("green", 'd', omitable = true);
1455  parameter->SetDefaultValue (1.);
1456  fpCommand->SetParameter (parameter);
1457  parameter = new G4UIparameter ("blue", 'd', omitable = true);
1458  parameter->SetDefaultValue (0.);
1459  fpCommand->SetParameter (parameter);
1460  parameter = new G4UIparameter ("placement", 's', omitable = true);
1461  parameter -> SetParameterCandidates("auto manual");
1462  parameter->SetDefaultValue ("auto");
1463  fpCommand->SetParameter (parameter);
1464  parameter = new G4UIparameter ("xmid", 'd', omitable = true);
1465  parameter->SetDefaultValue (0.);
1466  fpCommand->SetParameter (parameter);
1467  parameter = new G4UIparameter ("ymid", 'd', omitable = true);
1468  parameter->SetDefaultValue (0.);
1469  fpCommand->SetParameter (parameter);
1470  parameter = new G4UIparameter ("zmid", 'd', omitable = true);
1471  parameter->SetDefaultValue (0.);
1472  fpCommand->SetParameter (parameter);
1473  parameter = new G4UIparameter ("unit", 's', omitable = true);
1474  parameter->SetDefaultValue ("m");
1475  fpCommand->SetParameter (parameter);
1476 }
1477 
1479  delete fpCommand;
1480 }
1481 
1483  return "";
1484 }
1485 
1487 
1489  G4bool warn = verbosity >= G4VisManager::warnings;
1490 
1491  G4Scene* pScene = fpVisManager->GetCurrentScene();
1492  if (!pScene) {
1493  if (verbosity >= G4VisManager::errors) {
1494  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1495  }
1496  return;
1497  } else {
1498  if (pScene->GetExtent().GetExtentRadius() <= 0.) {
1499  if (verbosity >= G4VisManager::errors) {
1500  G4cerr
1501  << "ERROR: Scene has no extent. Add volumes or use \"/vis/scene/add/extent\"."
1502  << G4endl;
1503  }
1504  return;
1505  }
1506  }
1507 
1508  G4VViewer* pViewer = fpVisManager->GetCurrentViewer();
1509  if (!pViewer) {
1510  if (verbosity >= G4VisManager::errors) {
1511  G4cerr <<
1512  "ERROR: G4VisCommandSceneAddLogo::SetNewValue: no viewer."
1513  "\n Auto direction needs a viewer."
1514  << G4endl;
1515  }
1516  return;
1517  }
1518 
1519  G4double userHeight, red, green, blue, xmid, ymid, zmid;
1520  G4String userHeightUnit, direction, auto_manual, positionUnit;
1521  std::istringstream is (newValue);
1522  is >> userHeight >> userHeightUnit >> direction
1523  >> red >> green >> blue
1524  >> auto_manual
1525  >> xmid >> ymid >> zmid >> positionUnit;
1526 
1527  G4double height = userHeight;
1528  const G4VisExtent& sceneExtent = pScene->GetExtent(); // Existing extent.
1529  if (userHeightUnit == "auto") {
1530  height *= 0.2 * sceneExtent.GetExtentRadius();
1531  } else {
1532  height *= G4UIcommand::ValueOf(userHeightUnit);
1533  }
1534 
1535  G4double unit = G4UIcommand::ValueOf(positionUnit);
1536  xmid *= unit; ymid *= unit; zmid *= unit;
1537 
1538  Direction logoDirection = X; // Initialise to keep some compilers happy.
1539  if (direction == "auto") {
1540  // Take cue from viewer
1541  const G4Vector3D& vp =
1543  if (vp.x() > vp.y() && vp.x() > vp.z()) logoDirection = X;
1544  else if (vp.x() < vp.y() && vp.x() < vp.z()) logoDirection = minusX;
1545  else if (vp.y() > vp.x() && vp.y() > vp.z()) logoDirection = Y;
1546  else if (vp.y() < vp.x() && vp.y() < vp.z()) logoDirection = minusY;
1547  else if (vp.z() > vp.x() && vp.z() > vp.y()) logoDirection = Z;
1548  else if (vp.z() < vp.x() && vp.z() < vp.y()) logoDirection = minusZ;
1549  }
1550  else if (direction(0) == 'x') logoDirection = X;
1551  else if (direction(0) == 'y') logoDirection = Y;
1552  else if (direction(0) == 'z') logoDirection = Z;
1553  else if (direction(0) == '-') {
1554  if (direction(1) == 'x') logoDirection = minusX;
1555  else if (direction(1) == 'y') logoDirection = minusY;
1556  else if (direction(1) == 'z') logoDirection = minusZ;
1557  } else {
1558  if (verbosity >= G4VisManager::errors) {
1559  G4cerr << "ERROR: Unrecogniseed direction: \""
1560  << direction << "\"." << G4endl;
1561  return;
1562  }
1563  }
1564 
1565  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
1566  // Parameters read and interpreted.
1567 
1568  // Current scene extent
1569  const G4double xmin = sceneExtent.GetXmin();
1570  const G4double xmax = sceneExtent.GetXmax();
1571  const G4double ymin = sceneExtent.GetYmin();
1572  const G4double ymax = sceneExtent.GetYmax();
1573  const G4double zmin = sceneExtent.GetZmin();
1574  const G4double zmax = sceneExtent.GetZmax();
1575 
1576  // Test existing extent and issue warnings...
1577  G4bool worried = false;
1578  if (sceneExtent.GetExtentRadius() == 0) {
1579  worried = true;
1580  if (verbosity >= G4VisManager::warnings) {
1581  G4cout <<
1582  "WARNING: Existing scene does not yet have any extent."
1583  "\n Maybe you have not yet added any geometrical object."
1584  << G4endl;
1585  }
1586  }
1587 
1588  // Useful constants, etc...
1589  const G4double halfHeight(height / 2.);
1590  const G4double comfort(0.01); // 0.15 seems too big. 0.05 might be better.
1591  const G4double freeHeightFraction (1. + 2. * comfort);
1592 
1593  // Test existing scene for room...
1594  G4bool room = true;
1595  switch (logoDirection) {
1596  case X:
1597  case minusX:
1598  if (freeHeightFraction * (xmax - xmin) < height) room = false;
1599  break;
1600  case Y:
1601  case minusY:
1602  if (freeHeightFraction * (ymax - ymin) < height) room = false;
1603  break;
1604  case Z:
1605  case minusZ:
1606  if (freeHeightFraction * (zmax - zmin) < height) room = false;
1607  break;
1608  }
1609  if (!room) {
1610  worried = true;
1611  if (verbosity >= G4VisManager::warnings) {
1612  G4cout <<
1613  "WARNING: Not enough room in existing scene. Maybe logo is too large."
1614  << G4endl;
1615  }
1616  }
1617  if (worried) {
1618  if (verbosity >= G4VisManager::warnings) {
1619  G4cout <<
1620  "WARNING: The logo you have asked for is bigger than the existing"
1621  "\n scene. Maybe you have added it too soon. It is recommended that"
1622  "\n you add the logo last so that it can be correctly auto-positioned"
1623  "\n so as not to be obscured by any existing object and so that the"
1624  "\n view parameters can be correctly recalculated."
1625  << G4endl;
1626  }
1627  }
1628 
1629  G4double sxmid(xmid), symid(ymid), szmid(zmid);
1630  if (autoPlacing) {
1631  // Aim to place at bottom right of screen when viewed from logoDirection.
1632  // Give some comfort zone.
1633  const G4double xComfort = comfort * (xmax - xmin);
1634  const G4double yComfort = comfort * (ymax - ymin);
1635  const G4double zComfort = comfort * (zmax - zmin);
1636  switch (logoDirection) {
1637  case X: // y-axis up, z-axis to left?
1638  sxmid = xmax + halfHeight + xComfort;
1639  symid = ymin - yComfort;
1640  szmid = zmin - zComfort;
1641  break;
1642  case minusX: // y-axis up, z-axis to right?
1643  sxmid = xmin - halfHeight - xComfort;
1644  symid = ymin - yComfort;
1645  szmid = zmax + zComfort;
1646  break;
1647  case Y: // z-axis up, x-axis to left?
1648  sxmid = xmin - xComfort;
1649  symid = ymax + halfHeight + yComfort;
1650  szmid = zmin - zComfort;
1651  break;
1652  case minusY: // z-axis up, x-axis to right?
1653  sxmid = xmax + xComfort;
1654  symid = ymin - halfHeight - yComfort;
1655  szmid = zmin - zComfort;
1656  break;
1657  case Z: // y-axis up, x-axis to right?
1658  sxmid = xmax + xComfort;
1659  symid = ymin - yComfort;
1660  szmid = zmax + halfHeight + zComfort;
1661  break;
1662  case minusZ: // y-axis up, x-axis to left?
1663  sxmid = xmin - xComfort;
1664  symid = ymin - yComfort;
1665  szmid = zmin - halfHeight - zComfort;
1666  break;
1667  }
1668  }
1669 
1670  G4Transform3D transform;
1671  switch (logoDirection) {
1672  case X: // y-axis up, z-axis to left?
1673  transform = G4RotateY3D(halfpi);
1674  break;
1675  case minusX: // y-axis up, z-axis to right?
1676  transform = G4RotateY3D(-halfpi);
1677  break;
1678  case Y: // z-axis up, x-axis to left?
1679  transform = G4RotateX3D(-halfpi) * G4RotateZ3D(pi);
1680  break;
1681  case minusY: // z-axis up, x-axis to right?
1682  transform = G4RotateX3D(halfpi);
1683  break;
1684  case Z: // y-axis up, x-axis to right?
1685  // No transformation required.
1686  break;
1687  case minusZ: // y-axis up, x-axis to left?
1688  transform = G4RotateY3D(pi);
1689  break;
1690  }
1691  transform = G4Translate3D(sxmid,symid,szmid) * transform;
1692 
1693  G4VisAttributes visAtts(G4Colour(red, green, blue));
1694  visAtts.SetForceSolid(true); // Always solid.
1695 
1696  G4Logo* logo = new G4Logo(height,visAtts);
1697  G4VModel* model =
1699  model->SetType("G4Logo");
1700  model->SetGlobalTag("G4Logo");
1701  model->SetGlobalDescription("G4Logo: " + newValue);
1702  model->SetTransformation(transform);
1703  // Note: it is the responsibility of the model to act upon this, but
1704  // the extent is in local coordinates...
1705  G4double& h = height;
1706  G4double h2 = h/2.;
1707  G4VisExtent extent(-h,h,-h2,h2,-h2,h2);
1708  model->SetExtent(extent);
1709  // This extent gets "added" to existing scene extent in
1710  // AddRunDurationModel below.
1711  const G4String& currentSceneName = pScene -> GetName ();
1712  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1713  if (successful) {
1714  if (verbosity >= G4VisManager::confirmations) {
1715  G4cout << "G4 Logo of height " << userHeight << ' ' << userHeightUnit
1716  << ", " << direction << "-direction, added to scene \""
1717  << currentSceneName << "\"";
1718  if (verbosity >= G4VisManager::parameters) {
1719  G4cout << "\n with extent " << extent
1720  << "\n at " << transform.getRotation()
1721  << transform.getTranslation();
1722  }
1723  G4cout << G4endl;
1724  }
1725  }
1726  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1727 
1728  CheckSceneAndNotifyHandlers (pScene);
1729 }
1730 
1732 (G4double height, const G4VisAttributes& visAtts):
1733  fVisAtts(visAtts)
1734 {
1735  const G4double& h = height;
1736  const G4double h2 = 0.5 * h; // Half height.
1737  const G4double ri = 0.25 * h; // Inner radius.
1738  const G4double ro = 0.5 * h; // Outer radius.
1739  const G4double ro2 = 0.5 * ro; // Half outer radius.
1740  const G4double w = ro - ri; // Width.
1741  const G4double w2 = 0.5 * w; // Half width.
1742  const G4double d2 = 0.2 * h; // Half depth.
1743  const G4double f1 = 0.05 * h; // left edge of stem of "4".
1744  const G4double f2 = -0.3 * h; // bottom edge of cross of "4".
1745  const G4double e = 1.e-4 * h; // epsilon.
1746  const G4double xt = f1, yt = h2; // Top of slope.
1747  const G4double xb = -h2, yb = f2 + w; // Bottom of slope.
1748  const G4double dx = xt - xb, dy = yt - yb;
1749  const G4double angle = std::atan2(dy,dx);
1750  G4RotationMatrix rm;
1751  rm.rotateZ(angle*rad);
1752  const G4double d = std::sqrt(dx * dx + dy * dy);
1753  const G4double ss = h; // Half height of square subtractor
1754  const G4double y8 = ss; // Choose y of subtractor for outer slope.
1755  const G4double x8 = ((-ss * d - dx * (yt - y8)) / dy) + xt;
1756  G4double y9 = ss; // Choose y of subtractor for inner slope.
1757  G4double x9 = ((-(ss - w) * d - dx * (yt - y8)) / dy) + xt;
1758  // But to get inner, we make a triangle translated by...
1759  const G4double xtr = ss - f1, ytr = -ss - f2 -w;
1760  x9 += xtr; y9 += ytr;
1761 
1762  // The idea here is to create a polyhedron for the G and the 4. To do
1763  // this we use Geant4 geometry solids and make boolean operations.
1764  // Note that we do not need to keep the solids. We use local objects,
1765  // which, of course, are deleted on leaving this function. This
1766  // is contrary to the usual requirement for solids that are part of the
1767  // detector for which solids MUST be created on the heap (with "new").
1768  // Finally we invoke CreatePolyhedron, which creates a polyhedron on the heap
1769  // and returns a pointer. It is the user's responsibility to delete,
1770  // which is done in the destructor of this class. Thus the polyhedra,
1771  // created here, remain on the heap for the lifetime of the job.
1772 
1773  // G...
1774  G4Tubs tG("tG",ri,ro,d2,0.15*pi,1.85*pi);
1775  G4Box bG("bG",w2,ro2,d2);
1776  G4UnionSolid logoG("logoG",&tG,&bG,G4Translate3D(ri+w2,-ro2,0.));
1777  fpG = logoG.CreatePolyhedron();
1778  fpG->SetVisAttributes(&fVisAtts);
1779  fpG->Transform(G4Translate3D(-0.55*h,0.,0.));
1780 
1781  // 4...
1782  G4Box b1("b1",h2,h2,d2);
1783  G4Box bS("bS",ss,ss,d2+e); // Subtractor.
1784  G4Box bS2("bS2",ss,ss,d2+2.*e); // 2nd Subtractor.
1785  G4SubtractionSolid s1("s1",&b1,&bS,G4Translate3D(f1-ss,f2-ss,0.));
1786  G4SubtractionSolid s2("s2",&s1,&bS,G4Translate3D(f1+ss+w,f2-ss,0.));
1787  G4SubtractionSolid s3("s3",&s2,&bS,G4Translate3D(f1+ss+w,f2+ss+w,0.));
1789  ("s4",&s3,&bS,G4Transform3D(rm,G4ThreeVector(x8,y8,0.)));
1790  G4SubtractionSolid s5 // Triangular hole.
1791  ("s5",&bS,&bS2,G4Transform3D(rm,G4ThreeVector(x9,y9,0.)));
1792  G4SubtractionSolid logo4("logo4",&s4,&s5,G4Translate3D(-xtr,-ytr,0.));
1793  fp4 = logo4.CreatePolyhedron();
1794  /* Experiment with creating own polyhedron...
1795  int nNodes = 4;
1796  int nFaces = 4;
1797  double xyz[][3] = {{0,0,0},{1*m,0,0},{0,1*m,0},{0,0,1*m}};
1798  int faces[][4] = {{1,3,2,0},{1,2,4,0},{1,4,3,0},{2,3,4,0}};
1799  fp4 = new G4Polyhedron();
1800  fp4->createPolyhedron(nNodes,nFaces,xyz,faces);
1801  */
1802  fp4->SetVisAttributes(&fVisAtts);
1803  fp4->Transform(G4Translate3D(0.55*h,0.,0.));
1804 }
1805 
1807  delete fpG;
1808  delete fp4;
1809 }
1810 
1811 void G4VisCommandSceneAddLogo::G4Logo::operator()
1812  (G4VGraphicsScene& sceneHandler, const G4Transform3D& transform, const G4ModelingParameters*) {
1813  sceneHandler.BeginPrimitives(transform);
1814  sceneHandler.AddPrimitive(*fpG);
1815  sceneHandler.AddPrimitive(*fp4);
1816  sceneHandler.EndPrimitives();
1817 }
1818 
1820 
1822  G4bool omitable;
1823  fpCommand = new G4UIcommand ("/vis/scene/add/logo2D", this);
1824  fpCommand -> SetGuidance ("Adds 2D logo to current scene.");
1825  G4UIparameter* parameter;
1826  parameter = new G4UIparameter ("size", 'i', omitable = true);
1827  parameter -> SetGuidance ("Screen size of text in pixels.");
1828  parameter -> SetDefaultValue (48);
1829  fpCommand -> SetParameter (parameter);
1830  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
1831  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
1832  parameter -> SetDefaultValue (-0.9);
1833  fpCommand -> SetParameter (parameter);
1834  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
1835  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
1836  parameter -> SetDefaultValue (-0.9);
1837  fpCommand -> SetParameter (parameter);
1838  parameter = new G4UIparameter ("layout", 's', omitable = true);
1839  parameter -> SetGuidance ("Layout, i.e., adjustment: left|centre|right.");
1840  parameter -> SetDefaultValue ("left");
1841  fpCommand -> SetParameter (parameter);
1842 }
1843 
1845  delete fpCommand;
1846 }
1847 
1849  return "";
1850 }
1851 
1853 {
1855  G4bool warn(verbosity >= G4VisManager::warnings);
1856 
1857  G4Scene* pScene = fpVisManager->GetCurrentScene();
1858  if (!pScene) {
1859  if (verbosity >= G4VisManager::errors) {
1860  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1861  }
1862  return;
1863  }
1864 
1865  G4int size;
1866  G4double x, y;
1867  G4String layoutString;
1868  std::istringstream is(newValue);
1869  is >> size >> x >> y >> layoutString;
1870  G4Text::Layout layout = G4Text::right;
1871  if (layoutString(0) == 'l') layout = G4Text::left;
1872  else if (layoutString(0) == 'c') layout = G4Text::centre;
1873  else if (layoutString(0) == 'r') layout = G4Text::right;
1874 
1875  Logo2D* logo2D = new Logo2D(fpVisManager, size, x, y, layout);
1876  G4VModel* model =
1878  model->SetType("G4Logo2D");
1879  model->SetGlobalTag("G4Logo2D");
1880  model->SetGlobalDescription("G4Logo2D: " + newValue);
1881  const G4String& currentSceneName = pScene -> GetName ();
1882  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1883  if (successful) {
1884  if (verbosity >= G4VisManager::confirmations) {
1885  G4cout << "2D logo has been added to scene \""
1886  << currentSceneName << "\"."
1887  << G4endl;
1888  }
1889  }
1890  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1891 
1892  CheckSceneAndNotifyHandlers (pScene);
1893 }
1894 
1895 void G4VisCommandSceneAddLogo2D::Logo2D::operator()
1896  (G4VGraphicsScene& sceneHandler, const G4Transform3D&, const G4ModelingParameters*)
1897 {
1898  G4Text text("Geant4", G4Point3D(fX, fY, 0.));
1899  text.SetScreenSize(fSize);
1900  text.SetLayout(fLayout);
1901  G4VisAttributes textAtts(G4Colour::Brown());
1902  text.SetVisAttributes(textAtts);
1903  sceneHandler.BeginPrimitives2D();
1904  sceneHandler.AddPrimitive(text);
1905  sceneHandler.EndPrimitives2D();
1906 }
1907 
1909 
1911  fpCommand = new G4UIcommand ("/vis/scene/add/magneticField", this);
1912  fpCommand -> SetGuidance
1913  ("Adds magnetic field representation to current scene.");
1915  const G4UIcommand* addElecFieldCmd = tree->FindPath("/vis/scene/add/electricField");
1916  // Pick up additional guidance from /vis/scene/add/electricField
1917  CopyGuidanceFrom(addElecFieldCmd,fpCommand,1);
1918  // Pick up parameters from /vis/scene/add/electricField
1919  CopyParametersFrom(addElecFieldCmd,fpCommand);
1920 }
1921 
1923  delete fpCommand;
1924 }
1925 
1927  return "";
1928 }
1929 
1931 (G4UIcommand*, G4String newValue) {
1932 
1934  G4bool warn(verbosity >= G4VisManager::warnings);
1935 
1936  G4Scene* pScene = fpVisManager->GetCurrentScene();
1937  if (!pScene) {
1938  if (verbosity >= G4VisManager::errors) {
1939  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
1940  }
1941  return;
1942  }
1943 
1944  G4int nDataPointsPerHalfScene;
1945  G4String representation;
1946  std::istringstream iss(newValue);
1947  iss >> nDataPointsPerHalfScene >> representation;
1949  modelRepresentation = G4ElectricFieldModel::fullArrow;
1950  if (representation == "lightArrow") {
1951  modelRepresentation = G4ElectricFieldModel::lightArrow;
1952  }
1953  G4VModel* model;
1954  model = new G4MagneticFieldModel
1955  (nDataPointsPerHalfScene,modelRepresentation,
1959  const G4String& currentSceneName = pScene -> GetName ();
1960  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1961  if (successful) {
1962  if (verbosity >= G4VisManager::confirmations) {
1963  G4cout
1964  << "Magnetic field, if any, will be drawn in scene \""
1965  << currentSceneName
1966  << "\"\n with "
1967  << nDataPointsPerHalfScene
1968  << " data points per half extent and with representation \""
1969  << representation
1970  << '\"'
1971  << G4endl;
1972  }
1973  }
1974  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1975 
1976  CheckSceneAndNotifyHandlers (pScene);
1977 }
1978 
1980 
1982  G4bool omitable;
1983  fpCommand = new G4UIcmdWithAString ("/vis/scene/add/psHits", this);
1984  fpCommand -> SetGuidance
1985  ("Adds Primitive Scorer Hits (PSHits) to current scene.");
1986  fpCommand -> SetGuidance
1987  ("PSHits are drawn at end of run when the scene in which"
1988  "\nthey are added is current.");
1989  fpCommand -> SetGuidance
1990  ("Optional parameter specifies name of scoring map. By default all"
1991  "\nscoring maps registered with the G4ScoringManager are drawn.");
1992  fpCommand -> SetParameterName ("mapname", omitable = true);
1993  fpCommand -> SetDefaultValue ("all");
1994 }
1995 
1997  delete fpCommand;
1998 }
1999 
2001  return "";
2002 }
2003 
2005 (G4UIcommand*, G4String newValue)
2006 {
2008  G4bool warn(verbosity >= G4VisManager::warnings);
2009 
2010  G4Scene* pScene = fpVisManager->GetCurrentScene();
2011  if (!pScene) {
2012  if (verbosity >= G4VisManager::errors) {
2013  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2014  }
2015  return;
2016  }
2017 
2018  G4VModel* model = new G4PSHitsModel(newValue);
2019  const G4String& currentSceneName = pScene -> GetName ();
2020  G4bool successful = pScene -> AddEndOfRunModel (model, warn);
2021  if (successful) {
2022  if (verbosity >= G4VisManager::confirmations) {
2023  if (newValue == "all") {
2024  G4cout << "All Primitive Scorer hits";
2025  } else {
2026  G4cout << "Hits of Primitive Scorer \"" << newValue << '"';
2027  }
2028  G4cout << " will be drawn at end of run in scene \""
2029  << currentSceneName << "\"."
2030  << G4endl;
2031  }
2032  }
2033  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2034 
2035  CheckSceneAndNotifyHandlers (pScene);
2036 }
2037 
2039 
2041  G4bool omitable;
2042  fpCommand = new G4UIcommand ("/vis/scene/add/scale", this);
2043  fpCommand -> SetGuidance
2044  ("Adds an annotated scale line to the current scene.");
2045  fpCommand -> SetGuidance
2046  ("If \"unit\" is \"auto\", length is roughly one tenth of the scene extent.");
2047  fpCommand -> SetGuidance
2048  ("If \"direction\" is \"auto\", scale is roughly in the plane of the current view.");
2049  fpCommand -> SetGuidance
2050  ("If \"placement\" is \"auto\", scale is placed at bottom left of current view."
2051  "\n Otherwise placed at (xmid,ymid,zmid).");
2052  fpCommand -> SetGuidance (G4Scale::GetGuidanceString());
2053  G4UIparameter* parameter;
2054  parameter = new G4UIparameter ("length", 'd', omitable = true);
2055  parameter->SetDefaultValue (1.);
2056  fpCommand->SetParameter (parameter);
2057  parameter = new G4UIparameter ("unit", 's', omitable = true);
2058  parameter->SetDefaultValue ("auto");
2059  fpCommand->SetParameter (parameter);
2060  parameter = new G4UIparameter ("direction", 's', omitable = true);
2061  parameter->SetGuidance ("auto|x|y|z");
2062  parameter->SetDefaultValue ("auto");
2063  fpCommand->SetParameter (parameter);
2064  parameter = new G4UIparameter ("red", 'd', omitable = true);
2065  parameter->SetDefaultValue (1.);
2066  fpCommand->SetParameter (parameter);
2067  parameter = new G4UIparameter ("green", 'd', omitable = true);
2068  parameter->SetDefaultValue (0.);
2069  fpCommand->SetParameter (parameter);
2070  parameter = new G4UIparameter ("blue", 'd', omitable = true);
2071  parameter->SetDefaultValue (0.);
2072  fpCommand->SetParameter (parameter);
2073  parameter = new G4UIparameter ("placement", 's', omitable = true);
2074  parameter -> SetParameterCandidates("auto manual");
2075  parameter->SetDefaultValue ("auto");
2076  fpCommand->SetParameter (parameter);
2077  parameter = new G4UIparameter ("xmid", 'd', omitable = true);
2078  parameter->SetDefaultValue (0.);
2079  fpCommand->SetParameter (parameter);
2080  parameter = new G4UIparameter ("ymid", 'd', omitable = true);
2081  parameter->SetDefaultValue (0.);
2082  fpCommand->SetParameter (parameter);
2083  parameter = new G4UIparameter ("zmid", 'd', omitable = true);
2084  parameter->SetDefaultValue (0.);
2085  fpCommand->SetParameter (parameter);
2086  parameter = new G4UIparameter ("unit", 's', omitable = true);
2087  parameter->SetDefaultValue ("m");
2088  fpCommand->SetParameter (parameter);
2089 }
2090 
2092  delete fpCommand;
2093 }
2094 
2096  return "";
2097 }
2098 
2100 
2102  G4bool warn = verbosity >= G4VisManager::warnings;
2103 
2104  G4Scene* pScene = fpVisManager->GetCurrentScene();
2105  if (!pScene) {
2106  if (verbosity >= G4VisManager::errors) {
2107  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2108  }
2109  return;
2110  } else {
2111  if (pScene->GetExtent().GetExtentRadius() <= 0.) {
2112  if (verbosity >= G4VisManager::errors) {
2113  G4cerr
2114  << "ERROR: Scene has no extent. Add volumes or use \"/vis/scene/add/extent\"."
2115  << G4endl;
2116  }
2117  return;
2118  }
2119  }
2120 
2121  G4double userLength, red, green, blue, xmid, ymid, zmid;
2122  G4String userLengthUnit, direction, auto_manual, positionUnit;
2123  std::istringstream is (newValue);
2124  is >> userLength >> userLengthUnit >> direction
2125  >> red >> green >> blue
2126  >> auto_manual
2127  >> xmid >> ymid >> zmid >> positionUnit;
2128 
2129  G4double length = userLength;
2130  const G4VisExtent& sceneExtent = pScene->GetExtent(); // Existing extent.
2131  if (userLengthUnit == "auto") {
2132  const G4double lengthMax = 0.5 * sceneExtent.GetExtentRadius();
2133  const G4double intLog10Length = std::floor(std::log10(lengthMax));
2134  length = std::pow(10,intLog10Length);
2135  if (5.*length < lengthMax) length *= 5.;
2136  else if (2.*length < lengthMax) length *= 2.;
2137  } else {
2138  length *= G4UIcommand::ValueOf(userLengthUnit);
2139  }
2140  G4String annotation = G4BestUnit(length,"Length");
2141 
2142  G4double unit = G4UIcommand::ValueOf(positionUnit);
2143  xmid *= unit; ymid *= unit; zmid *= unit;
2144 
2145  G4Scale::Direction scaleDirection (G4Scale::x);
2146  if (direction(0) == 'y') scaleDirection = G4Scale::y;
2147  if (direction(0) == 'z') scaleDirection = G4Scale::z;
2148 
2149  G4VViewer* pViewer = fpVisManager->GetCurrentViewer();
2150  if (!pViewer) {
2151  if (verbosity >= G4VisManager::errors) {
2152  G4cerr <<
2153  "ERROR: G4VisCommandSceneAddScale::SetNewValue: no viewer."
2154  "\n Auto direction needs a viewer."
2155  << G4endl;
2156  }
2157  return;
2158  }
2159 
2160  const G4Vector3D& vp =
2162  const G4Vector3D& up =
2163  pViewer->GetViewParameters().GetUpVector();
2164 
2165  if (direction == "auto") { // Takes cue from viewer.
2166  if (std::abs(vp.x()) > std::abs(vp.y()) &&
2167  std::abs(vp.x()) > std::abs(vp.z())) { // x viewpoint
2168  if (std::abs(up.y()) > std::abs(up.z())) scaleDirection = G4Scale::z;
2169  else scaleDirection = G4Scale::y;
2170  }
2171  else if (std::abs(vp.y()) > std::abs(vp.x()) &&
2172  std::abs(vp.y()) > std::abs(vp.z())) { // y viewpoint
2173  if (std::abs(up.x()) > std::abs(up.z())) scaleDirection = G4Scale::z;
2174  else scaleDirection = G4Scale::x;
2175  }
2176  else if (std::abs(vp.z()) > std::abs(vp.x()) &&
2177  std::abs(vp.z()) > std::abs(vp.y())) { // z viewpoint
2178  if (std::abs(up.y()) > std::abs(up.x())) scaleDirection = G4Scale::x;
2179  else scaleDirection = G4Scale::y;
2180  }
2181  }
2182 
2183  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
2184  // Parameters read and interpreted.
2185 
2186  // Useful constants, etc...
2187  const G4double halfLength(length / 2.);
2188  const G4double comfort(0.01); // 0.15 seems too big. 0.05 might be better.
2189  const G4double freeLengthFraction (1. + 2. * comfort);
2190 
2191  const G4double xmin = sceneExtent.GetXmin();
2192  const G4double xmax = sceneExtent.GetXmax();
2193  const G4double ymin = sceneExtent.GetYmin();
2194  const G4double ymax = sceneExtent.GetYmax();
2195  const G4double zmin = sceneExtent.GetZmin();
2196  const G4double zmax = sceneExtent.GetZmax();
2197 
2198  // Test existing extent and issue warnings...
2199  G4bool worried = false;
2200  if (sceneExtent.GetExtentRadius() == 0) {
2201  worried = true;
2202  if (verbosity >= G4VisManager::warnings) {
2203  G4cout <<
2204  "WARNING: Existing scene does not yet have any extent."
2205  "\n Maybe you have not yet added any geometrical object."
2206  << G4endl;
2207  }
2208  }
2209  // Test existing scene for room...
2210  G4bool room = true;
2211  switch (scaleDirection) {
2212  case G4Scale::x:
2213  if (freeLengthFraction * (xmax - xmin) < length) room = false;
2214  break;
2215  case G4Scale::y:
2216  if (freeLengthFraction * (ymax - ymin) < length) room = false;
2217  break;
2218  case G4Scale::z:
2219  if (freeLengthFraction * (zmax - zmin) < length) room = false;
2220  break;
2221  }
2222  if (!room) {
2223  worried = true;
2224  if (verbosity >= G4VisManager::warnings) {
2225  G4cout <<
2226  "WARNING: Not enough room in existing scene. Maybe scale is too long."
2227  << G4endl;
2228  }
2229  }
2230  if (worried) {
2231  if (verbosity >= G4VisManager::warnings) {
2232  G4cout <<
2233  "WARNING: The scale you have asked for is bigger than the existing"
2234  "\n scene. Maybe you have added it too soon. It is recommended that"
2235  "\n you add the scale last so that it can be correctly auto-positioned"
2236  "\n so as not to be obscured by any existing object and so that the"
2237  "\n view parameters can be correctly recalculated."
2238  << G4endl;
2239  }
2240  }
2241 
2242  // Let's go ahead a construct a scale and a scale model. Since the
2243  // placing is done here, this G4Scale is *not* auto-placed...
2244  G4Scale scale(length, annotation, scaleDirection,
2245  false, xmid, ymid, zmid,
2247  G4VisAttributes visAttr(G4Colour(red, green, blue));
2248  scale.SetVisAttributes(visAttr);
2249  G4VModel* model = new G4ScaleModel(scale);
2250  G4String globalDescription = model->GetGlobalDescription();
2251  globalDescription += " (" + newValue + ")";
2252  model->SetGlobalDescription(globalDescription);
2253 
2254  // Now figure out the extent...
2255  //
2256  // From the G4Scale.hh:
2257  //
2258  // This creates a representation of annotated line in the specified
2259  // direction with tick marks at the end. If autoPlacing is true it
2260  // is required to be centred at the front, right, bottom corner of
2261  // the world space, comfortably outside the existing bounding
2262  // box/sphere so that existing objects do not obscure it. Otherwise
2263  // it is required to be drawn with mid-point at (xmid, ymid, zmid).
2264  //
2265  // The auto placing algorithm might be:
2266  // x = xmin + (1 + comfort) * (xmax - xmin)
2267  // y = ymin - comfort * (ymax - ymin)
2268  // z = zmin + (1 + comfort) * (zmax - zmin)
2269  // if direction == x then (x - length,y,z) to (x,y,z)
2270  // if direction == y then (x,y,z) to (x,y + length,z)
2271  // if direction == z then (x,y,z - length) to (x,y,z)
2272  //
2273  // End of clip from G4Scale.hh:
2274  //
2275  // Implement this in two parts. Here, use the scale's extent to
2276  // "expand" the scene's extent. Then rendering - in
2277  // G4VSceneHandler::AddPrimitive(const G4Scale&) - simply has to
2278  // ensure it's within the new extent.
2279  //
2280 
2281  G4double sxmid(xmid), symid(ymid), szmid(zmid);
2282  if (autoPlacing) {
2283  // Aim to place at bottom right of screen in current view.
2284  // Give some comfort zone.
2285  const G4double xComfort = comfort * (xmax - xmin);
2286  const G4double yComfort = comfort * (ymax - ymin);
2287  const G4double zComfort = comfort * (zmax - zmin);
2288  switch (scaleDirection) {
2289  case G4Scale::x:
2290  if (vp.z() > 0.) {
2291  sxmid = xmax + xComfort;
2292  symid = ymin - yComfort;
2293  szmid = zmin - zComfort;
2294  } else {
2295  sxmid = xmin - xComfort;
2296  symid = ymin - yComfort;
2297  szmid = zmax + zComfort;
2298  }
2299  break;
2300  case G4Scale::y:
2301  if (vp.x() > 0.) {
2302  sxmid = xmin - xComfort;
2303  symid = ymax + yComfort;
2304  szmid = zmin - zComfort;
2305  } else {
2306  sxmid = xmax + xComfort;
2307  symid = ymin - yComfort;
2308  szmid = zmin - zComfort;
2309  }
2310  break;
2311  case G4Scale::z:
2312  if (vp.x() > 0.) {
2313  sxmid = xmax + xComfort;
2314  symid = ymin - yComfort;
2315  szmid = zmax + zComfort;
2316  } else {
2317  sxmid = xmin - xComfort;
2318  symid = ymin - yComfort;
2319  szmid = zmax + zComfort;
2320  }
2321  break;
2322  }
2323  }
2324 
2325  /* Old code - kept for future reference.
2326  G4double sxmid(xmid), symid(ymid), szmid(zmid);
2327  if (autoPlacing) {
2328  sxmid = xmin + onePlusComfort * (xmax - xmin);
2329  symid = ymin - comfort * (ymax - ymin);
2330  szmid = zmin + onePlusComfort * (zmax - zmin);
2331  switch (scaleDirection) {
2332  case G4Scale::x:
2333  sxmid -= halfLength;
2334  break;
2335  case G4Scale::y:
2336  symid += halfLength;
2337  break;
2338  case G4Scale::z:
2339  szmid -= halfLength;
2340  break;
2341  }
2342  }
2343  */
2344 
2345  /* sxmin, etc., not actually used. Comment out to prevent compiler
2346  warnings but keep in case need in future. Extract transform and
2347  scaleExtent into reduced code below.
2348  G4double sxmin(sxmid), sxmax(sxmid);
2349  G4double symin(symid), symax(symid);
2350  G4double szmin(szmid), szmax(szmid);
2351  G4Transform3D transform;
2352  G4VisExtent scaleExtent;
2353  switch (scaleDirection) {
2354  case G4Scale::x:
2355  sxmin = sxmid - halfLength;
2356  sxmax = sxmid + halfLength;
2357  scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
2358  break;
2359  case G4Scale::y:
2360  symin = symid - halfLength;
2361  symax = symid + halfLength;
2362  transform = G4RotateZ3D(halfpi);
2363  scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
2364  break;
2365  case G4Scale::z:
2366  szmin = szmid - halfLength;
2367  szmax = szmid + halfLength;
2368  transform = G4RotateY3D(halfpi);
2369  scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
2370  break;
2371  }
2372  */
2373  G4Transform3D transform;
2374  G4VisExtent scaleExtent;
2375  switch (scaleDirection) {
2376  case G4Scale::x:
2377  scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
2378  break;
2379  case G4Scale::y:
2380  transform = G4RotateZ3D(halfpi);
2381  scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
2382  break;
2383  case G4Scale::z:
2384  transform = G4RotateY3D(halfpi);
2385  scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
2386  break;
2387  }
2388  transform = G4Translate3D(sxmid,symid,szmid) * transform;
2390 
2391  model->SetTransformation(transform);
2392  // Note: it is the responsibility of the model to act upon this, but
2393  // the extent is in local coordinates...
2394  model->SetExtent(scaleExtent);
2395  // This extent gets "added" to existing scene extent in
2396  // AddRunDurationModel below.
2397 
2398  const G4String& currentSceneName = pScene -> GetName ();
2399  G4bool successful = pScene -> AddRunDurationModel (model, warn);
2400  if (successful) {
2401  if (verbosity >= G4VisManager::confirmations) {
2402  G4cout << "Scale of " << annotation
2403  << " added to scene \"" << currentSceneName << "\".";
2404  if (verbosity >= G4VisManager::parameters) {
2405  G4cout << "\n with extent " << scaleExtent
2406  << "\n at " << transform.getRotation()
2407  << transform.getTranslation();
2408  }
2409  G4cout << G4endl;
2410  }
2411  }
2412  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2413 
2414  CheckSceneAndNotifyHandlers (pScene);
2415 }
2416 
2417 
2419 
2421  G4bool omitable;
2422  fpCommand = new G4UIcommand ("/vis/scene/add/text", this);
2423  fpCommand -> SetGuidance ("Adds text to current scene.");
2424  fpCommand -> SetGuidance
2425  ("Use \"/vis/set/textColour\" to set colour.");
2426  fpCommand -> SetGuidance
2427  ("Use \"/vis/set/textLayout\" to set layout:");
2428  G4UIparameter* parameter;
2429  parameter = new G4UIparameter ("x", 'd', omitable = true);
2430  parameter->SetDefaultValue (0);
2431  fpCommand->SetParameter (parameter);
2432  parameter = new G4UIparameter ("y", 'd', omitable = true);
2433  parameter->SetDefaultValue (0);
2434  fpCommand->SetParameter (parameter);
2435  parameter = new G4UIparameter ("z", 'd', omitable = true);
2436  parameter->SetDefaultValue (0);
2437  fpCommand->SetParameter (parameter);
2438  parameter = new G4UIparameter ("unit", 's', omitable = true);
2439  parameter->SetDefaultValue ("m");
2440  fpCommand->SetParameter (parameter);
2441  parameter = new G4UIparameter ("font_size", 'd', omitable = true);
2442  parameter->SetDefaultValue (12);
2443  parameter->SetGuidance ("pixels");
2444  fpCommand->SetParameter (parameter);
2445  parameter = new G4UIparameter ("x_offset", 'd', omitable = true);
2446  parameter->SetDefaultValue (0);
2447  parameter->SetGuidance ("pixels");
2448  fpCommand->SetParameter (parameter);
2449  parameter = new G4UIparameter ("y_offset", 'd', omitable = true);
2450  parameter->SetDefaultValue (0);
2451  parameter->SetGuidance ("pixels");
2452  fpCommand->SetParameter (parameter);
2453  parameter = new G4UIparameter ("text", 's', omitable = true);
2454  parameter->SetGuidance ("The rest of the line is text.");
2455  parameter->SetDefaultValue ("Hello G4");
2456  fpCommand->SetParameter (parameter);
2457 }
2458 
2460  delete fpCommand;
2461 }
2462 
2464  return "";
2465 }
2466 
2468 
2470  G4bool warn = verbosity >= G4VisManager::warnings;
2471 
2472  G4Scene* pScene = fpVisManager->GetCurrentScene();
2473  if (!pScene) {
2474  if (verbosity >= G4VisManager::errors) {
2475  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2476  }
2477  return;
2478  }
2479 
2480  G4Tokenizer next(newValue);
2481  G4double x = StoD(next());
2482  G4double y = StoD(next());
2483  G4double z = StoD(next());
2484  G4String unitString = next();
2485  G4double font_size = StoD(next());
2486  G4double x_offset = StoD(next());
2487  G4double y_offset = StoD(next());
2488  G4String text = next("\n");
2489 
2490  G4double unit = G4UIcommand::ValueOf(unitString);
2491  x *= unit; y *= unit; z *= unit;
2492 
2493  G4Text g4text(text, G4Point3D(x,y,z));
2495  g4text.SetVisAttributes(visAtts);
2496  g4text.SetLayout(fCurrentTextLayout);
2497  g4text.SetScreenSize(font_size);
2498  g4text.SetOffset(x_offset,y_offset);
2499  G4VModel* model = new G4TextModel(g4text);
2500  const G4String& currentSceneName = pScene -> GetName ();
2501  G4bool successful = pScene -> AddRunDurationModel (model, warn);
2502  if (successful) {
2503  if (verbosity >= G4VisManager::confirmations) {
2504  G4cout << "Text \"" << text
2505  << "\" has been added to scene \"" << currentSceneName << "\"."
2506  << G4endl;
2507  }
2508  }
2509  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2510 
2511  CheckSceneAndNotifyHandlers (pScene);
2512 }
2513 
2514 
2516 
2518  G4bool omitable;
2519  fpCommand = new G4UIcommand ("/vis/scene/add/text2D", this);
2520  fpCommand -> SetGuidance ("Adds 2D text to current scene.");
2521  fpCommand -> SetGuidance
2522  ("Use \"/vis/set/textColour\" to set colour.");
2523  fpCommand -> SetGuidance
2524  ("Use \"/vis/set/textLayout\" to set layout:");
2525  G4UIparameter* parameter;
2526  parameter = new G4UIparameter ("x", 'd', omitable = true);
2527  parameter->SetDefaultValue (0);
2528  fpCommand->SetParameter (parameter);
2529  parameter = new G4UIparameter ("y", 'd', omitable = true);
2530  parameter->SetDefaultValue (0);
2531  fpCommand->SetParameter (parameter);
2532  parameter = new G4UIparameter ("font_size", 'd', omitable = true);
2533  parameter->SetDefaultValue (12);
2534  parameter->SetGuidance ("pixels");
2535  fpCommand->SetParameter (parameter);
2536  parameter = new G4UIparameter ("x_offset", 'd', omitable = true);
2537  parameter->SetDefaultValue (0);
2538  parameter->SetGuidance ("pixels");
2539  fpCommand->SetParameter (parameter);
2540  parameter = new G4UIparameter ("y_offset", 'd', omitable = true);
2541  parameter->SetDefaultValue (0);
2542  parameter->SetGuidance ("pixels");
2543  fpCommand->SetParameter (parameter);
2544  parameter = new G4UIparameter ("text", 's', omitable = true);
2545  parameter->SetGuidance ("The rest of the line is text.");
2546  parameter->SetDefaultValue ("Hello G4");
2547  fpCommand->SetParameter (parameter);
2548 }
2549 
2551  delete fpCommand;
2552 }
2553 
2555  return "";
2556 }
2557 
2559 
2561  G4bool warn = verbosity >= G4VisManager::warnings;
2562 
2563  G4Scene* pScene = fpVisManager->GetCurrentScene();
2564  if (!pScene) {
2565  if (verbosity >= G4VisManager::errors) {
2566  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2567  }
2568  return;
2569  }
2570 
2571  G4Tokenizer next(newValue);
2572  G4double x = StoD(next());
2573  G4double y = StoD(next());
2574  G4double font_size = StoD(next());
2575  G4double x_offset = StoD(next());
2576  G4double y_offset = StoD(next());
2577  G4String text = next("\n");
2578 
2579  G4Text g4text(text, G4Point3D(x,y,0.));
2581  g4text.SetVisAttributes(visAtts);
2582  g4text.SetLayout(fCurrentTextLayout);
2583  g4text.SetScreenSize(font_size);
2584  g4text.SetOffset(x_offset,y_offset);
2585  G4Text2D* g4text2D = new G4Text2D(g4text);
2586  G4VModel* model =
2588  model->SetType("Text2D");
2589  model->SetGlobalTag("Text2D");
2590  model->SetGlobalDescription("Text2D: " + newValue);
2591  const G4String& currentSceneName = pScene -> GetName ();
2592  G4bool successful = pScene -> AddRunDurationModel (model, warn);
2593  if (successful) {
2594  if (verbosity >= G4VisManager::confirmations) {
2595  G4cout << "2D text \"" << text
2596  << "\" has been added to scene \"" << currentSceneName << "\"."
2597  << G4endl;
2598  }
2599  }
2600  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2601 
2602  CheckSceneAndNotifyHandlers (pScene);
2603 }
2604 
2606  fText(text)
2607 {}
2608 
2609 void G4VisCommandSceneAddText2D::G4Text2D::operator()
2610  (G4VGraphicsScene& sceneHandler, const G4Transform3D& transform, const G4ModelingParameters*) {
2611  sceneHandler.BeginPrimitives2D(transform);
2612  sceneHandler.AddPrimitive(fText);
2613  sceneHandler.EndPrimitives2D();
2614 }
2615 
2616 
2618 
2620  G4bool omitable;
2622  ("/vis/scene/add/trajectories", this);
2623  fpCommand -> SetGuidance
2624  ("Adds trajectories to current scene.");
2625  fpCommand -> SetGuidance
2626  ("Causes trajectories, if any, to be drawn at the end of processing an"
2627  "\nevent. Switches on trajectory storing and sets the"
2628  "\ndefault trajectory type.");
2629  fpCommand -> SetGuidance
2630  ("The command line parameter list determines the default trajectory type."
2631  "\nIf it contains the string \"smooth\", auxiliary inter-step points will"
2632  "\nbe inserted to improve the smoothness of the drawing of a curved"
2633  "\ntrajectory."
2634  "\nIf it contains the string \"rich\", significant extra information will"
2635  "\nbe stored in the trajectory (G4RichTrajectory) amenable to modeling"
2636  "\nand filtering with \"/vis/modeling/trajectories/create/drawByAttribute\""
2637  "\nand \"/vis/filtering/trajectories/create/attributeFilter\" commands."
2638  "\nIt may contain both strings in any order.");
2639  fpCommand -> SetGuidance
2640  ("\nTo switch off trajectory storing: \"/tracking/storeTrajectory 0\"."
2641  "\nSee also \"/vis/scene/endOfEventAction\".");
2642  fpCommand -> SetGuidance
2643  ("Note: This only sets the default. Independently of the result of this"
2644  "\ncommand, a user may instantiate a trajectory that overrides this default"
2645  "\nin PreUserTrackingAction.");
2646  fpCommand -> SetParameterName ("default-trajectory-type", omitable = true);
2647  fpCommand -> SetDefaultValue ("");
2648 }
2649 
2651  delete fpCommand;
2652 }
2653 
2655  return "";
2656 }
2657 
2659  G4String newValue) {
2660 
2662  G4bool warn = verbosity >= G4VisManager::warnings;
2663 
2664  G4Scene* pScene = fpVisManager->GetCurrentScene();
2665  if (!pScene) {
2666  if (verbosity >= G4VisManager::errors) {
2667  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2668  }
2669  return;
2670  }
2671  const G4String& currentSceneName = pScene -> GetName ();
2672 
2673  G4bool smooth = false;
2674  G4bool rich = false;
2675  if (newValue.find("smooth") != std::string::npos) smooth = true;
2676  if (newValue.find("rich") != std::string::npos) rich = true;
2677  if (newValue.size() && !(rich || smooth)) {
2678  if (verbosity >= G4VisManager::errors) {
2679  G4cerr << "ERROR: Unrecognised parameter \"" << newValue << "\""
2680  "\n No action taken."
2681  << G4endl;
2682  }
2683  return;
2684  }
2685 
2686  G4UImanager* UImanager = G4UImanager::GetUIpointer();
2687  G4int keepVerbose = UImanager->GetVerboseLevel();
2688  G4int newVerbose = 2;
2689  UImanager->SetVerboseLevel(newVerbose);
2690  G4String defaultTrajectoryType;
2691  if (smooth && rich) {
2692  UImanager->ApplyCommand("/tracking/storeTrajectory 4");
2693  defaultTrajectoryType = "G4RichTrajectory configured for smooth steps";
2694  } else if (smooth) {
2695  UImanager->ApplyCommand("/tracking/storeTrajectory 2");
2696  defaultTrajectoryType = "G4SmoothTrajectory";
2697  } else if (rich) {
2698  UImanager->ApplyCommand("/tracking/storeTrajectory 3");
2699  defaultTrajectoryType = "G4RichTrajectory";
2700  } else {
2701  UImanager->ApplyCommand("/tracking/storeTrajectory 1");
2702  defaultTrajectoryType = "G4Trajectory";
2703  }
2704  UImanager->SetVerboseLevel(keepVerbose);
2705 
2706  if (verbosity >= G4VisManager::errors) {
2707  G4cout <<
2708  "Attributes available for modeling and filtering with"
2709  "\n \"/vis/modeling/trajectories/create/drawByAttribute\" and"
2710  "\n \"/vis/filtering/trajectories/create/attributeFilter\" commands:"
2711  << G4endl;
2713  if (rich) {
2716  } else if (smooth) {
2719  } else {
2721  << *G4TrajectoryPoint().GetAttDefs();
2722  }
2723  }
2724 
2725  const auto& eoeList = pScene->GetEndOfEventModelList();
2726  auto eoeModel = eoeList.begin();
2727  for (; eoeModel != eoeList.end(); ++eoeModel) {
2728  const auto* actualModel = eoeModel->fpModel;
2729  if (dynamic_cast<const G4TrajectoriesModel*>(actualModel)) break;
2730  }
2731  if (eoeModel == eoeList.end()) {
2732  // No trajectories model exists in the scene so create a new one...
2734  pScene -> AddEndOfEventModel (model, warn);
2735  } // ...else it already exists and there is no need to add a new one
2736  // because G4TrajectoriesModel simply describes trajectories in the
2737  // trajectories store whatever the type.
2738 
2739  if (verbosity >= G4VisManager::confirmations) {
2740  G4cout << "Default trajectory type " << defaultTrajectoryType
2741  << "\n will be used to store trajectories for scene \""
2742  << currentSceneName << "\"."
2743  << G4endl;
2744  }
2745 
2746  if (verbosity >= G4VisManager::warnings) {
2747  G4cout <<
2748  "WARNING: Trajectory storing has been requested. This action may be"
2749  "\n reversed with \"/tracking/storeTrajectory 0\"."
2750  << G4endl;
2751  }
2752 
2753  CheckSceneAndNotifyHandlers (pScene);
2754 }
2755 
2757 
2759  G4bool omitable;
2760  fpCommand = new G4UIcmdWithAString("/vis/scene/add/userAction",this);
2761  fpCommand -> SetGuidance
2762  ("Add named Vis User Action to current scene.");
2763  fpCommand -> SetGuidance
2764  ("Attempts to match search string to name of action - use unique sub-string.");
2765  fpCommand -> SetGuidance
2766  ("(Use /vis/list to see names of registered actions.)");
2767  fpCommand -> SetGuidance
2768  ("If name == \"all\" (default), all actions are added.");
2769  fpCommand -> SetParameterName("action-name", omitable = true);
2770  fpCommand -> SetDefaultValue("all");
2771 }
2772 
2774  delete fpCommand;
2775 }
2776 
2778  return "";
2779 }
2780 
2782 (G4UIcommand*, G4String newValue) {
2783 
2785 
2786  G4Scene* pScene = fpVisManager->GetCurrentScene();
2787  if (!pScene) {
2788  if (verbosity >= G4VisManager::errors) {
2789  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2790  }
2791  return;
2792  }
2793 
2794  G4bool any = false;
2795 
2796  const std::vector<G4VisManager::UserVisAction>& runDurationUserVisActions =
2798  for (size_t i = 0; i < runDurationUserVisActions.size(); i++) {
2799  const G4String& name = runDurationUserVisActions[i].fName;
2800  G4VUserVisAction* visAction = runDurationUserVisActions[i].fpUserVisAction;
2801  if (newValue == "all" || name.find(newValue) != std::string::npos) {
2802  any = true;
2803  AddVisAction(name,visAction,pScene,runDuration,verbosity);
2804  }
2805  }
2806 
2807  const std::vector<G4VisManager::UserVisAction>& endOfEventUserVisActions =
2809  for (size_t i = 0; i < endOfEventUserVisActions.size(); i++) {
2810  const G4String& name = endOfEventUserVisActions[i].fName;
2811  G4VUserVisAction* visAction = endOfEventUserVisActions[i].fpUserVisAction;
2812  if (newValue == "all" || name.find(newValue) != std::string::npos) {
2813  any = true;
2814  AddVisAction(name,visAction,pScene,endOfEvent,verbosity);
2815  }
2816  }
2817 
2818  const std::vector<G4VisManager::UserVisAction>& endOfRunUserVisActions =
2820  for (size_t i = 0; i < endOfRunUserVisActions.size(); i++) {
2821  const G4String& name = endOfRunUserVisActions[i].fName;
2822  G4VUserVisAction* visAction = endOfRunUserVisActions[i].fpUserVisAction;
2823  if (newValue == "all" || name.find(newValue) != std::string::npos) {
2824  any = true;
2825  AddVisAction(name,visAction,pScene,endOfRun,verbosity);
2826  }
2827  }
2828 
2829  if (!any) {
2830  if (verbosity >= G4VisManager::warnings) {
2831  G4cout << "WARNING: No User Vis Action registered." << G4endl;
2832  }
2833  return;
2834  }
2835 
2836  CheckSceneAndNotifyHandlers (pScene);
2837 }
2838 
2840 (const G4String& name,
2841  G4VUserVisAction* visAction,
2842  G4Scene* pScene,
2844  G4VisManager::Verbosity verbosity)
2845 {
2846  G4bool warn = verbosity >= G4VisManager::warnings;
2847 
2848  const std::map<G4VUserVisAction*,G4VisExtent>& visExtentMap =
2850  G4VisExtent extent;
2851  std::map<G4VUserVisAction*,G4VisExtent>::const_iterator i =
2852  visExtentMap.find(visAction);
2853  if (i != visExtentMap.end()) extent = i->second;
2854  if (warn) {
2855  if (extent.GetExtentRadius() <= 0.) {
2856  G4cout
2857  << "WARNING: User Vis Action \"" << name << "\" extent is null."
2858  << G4endl;
2859  }
2860  }
2861 
2863  model->SetType("User Vis Action");
2864  model->SetGlobalTag(name);
2865  model->SetGlobalDescription(name);
2866  model->SetExtent(extent);
2867  G4bool successful = false;;
2868  switch (type) {
2869  case runDuration:
2870  successful = pScene -> AddRunDurationModel (model, warn);
2871  break;
2872  case endOfEvent:
2873  successful = pScene -> AddEndOfEventModel (model, warn);
2874  break;
2875  case endOfRun:
2876  successful = pScene -> AddEndOfRunModel (model, warn);
2877  break;
2878  }
2879  if (successful) {
2880  if (verbosity >= G4VisManager::confirmations) {
2881  const G4String& currentSceneName = pScene -> GetName ();
2882  G4cout << "User Vis Action added to scene \""
2883  << currentSceneName << "\"";
2884  if (verbosity >= G4VisManager::parameters) {
2885  G4cout << "\n with extent " << extent;
2886  }
2887  G4cout << G4endl;
2888  }
2889  }
2890  else G4VisCommandsSceneAddUnsuccessful(verbosity);
2891 }
2892 
2894 
2896  G4bool omitable;
2897  fpCommand = new G4UIcommand ("/vis/scene/add/volume", this);
2898  fpCommand -> SetGuidance
2899  ("Adds a physical volume to current scene, with optional clipping volume.");
2900  fpCommand -> SetGuidance
2901  ("If physical-volume-name is \"world\" (the default), the top of the"
2902  "\nmain geometry tree (material world) is added. If \"worlds\", the"
2903  "\ntops of all worlds - material world and parallel worlds, if any - are"
2904  "\nadded. Otherwise a search of all worlds is made.");
2905  fpCommand -> SetGuidance
2906  ("In the last case the names of all volumes in all worlds are matched"
2907  "\nagainst physical-volume-name. If this is of the form \"/regexp/\","
2908  "\nwhere regexp is a regular expression (see C++ regex), the match uses"
2909  "\nthe usual rules of regular expression matching. Otherwise an exact"
2910  "\nmatch is required."
2911  "\nFor example, \"/Shap/\" adds \"Shape1\" and \"Shape2\".");
2912  fpCommand -> SetGuidance
2913  ("It may help to see a textual representation of the geometry hierarchy of"
2914  "\nthe worlds. Try \"/vis/drawTree [worlds]\" or one of the driver/browser"
2915  "\ncombinations that have the required functionality, e.g., HepRepFile.");
2916  fpCommand -> SetGuidance
2917  ("If clip-volume-type is specified, the subsequent parameters are used to"
2918  "\nto define a clipping volume. For example,"
2919  "\n\"/vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1\" will draw the world"
2920  "\nwith the positive octant cut away. (If the Boolean Processor issues"
2921  "\nwarnings try replacing 0 by 0.000000001 or something.)");
2922  fpCommand -> SetGuidance
2923  ("If clip-volume-type is prepended with '-', the clip-volume is subtracted"
2924  "\n(cutaway). (This is the default if there is no prepended character.)"
2925  "\nIf '*' is prepended, the intersection of the physical-volume and the"
2926  "\nclip-volume is made. (You can make a section through the detector with"
2927  "\na thin box, for example).");
2928  fpCommand -> SetGuidance
2929  ("For \"box\", the parameters are xmin,xmax,ymin,ymax,zmin,zmax."
2930  "\nOnly \"box\" is programmed at present.");
2931  G4UIparameter* parameter;
2932  parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
2933  parameter -> SetDefaultValue ("world");
2934  fpCommand -> SetParameter (parameter);
2935  parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
2936  parameter -> SetGuidance ("If negative, matches any copy no.");
2937  parameter -> SetDefaultValue (-1);
2938  fpCommand -> SetParameter (parameter);
2939  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
2940  parameter -> SetGuidance
2941  ("Depth of descent of geometry hierarchy. Default = unlimited depth.");
2942  parameter -> SetDefaultValue (G4Scene::UNLIMITED);
2943  fpCommand -> SetParameter (parameter);
2944  parameter = new G4UIparameter ("clip-volume-type", 's', omitable = true);
2945  parameter -> SetParameterCandidates("none box -box *box");
2946  parameter -> SetDefaultValue ("none");
2947  parameter -> SetGuidance("[-|*]type. See general guidance.");
2948  fpCommand -> SetParameter (parameter);
2949  parameter = new G4UIparameter ("parameter-unit", 's', omitable = true);
2950  parameter -> SetDefaultValue ("m");
2951  fpCommand -> SetParameter (parameter);
2952  parameter = new G4UIparameter ("parameter-1", 'd', omitable = true);
2953  parameter -> SetDefaultValue (0.);
2954  fpCommand -> SetParameter (parameter);
2955  parameter = new G4UIparameter ("parameter-2", 'd', omitable = true);
2956  parameter -> SetDefaultValue (0.);
2957  fpCommand -> SetParameter (parameter);
2958  parameter = new G4UIparameter ("parameter-3", 'd', omitable = true);
2959  parameter -> SetDefaultValue (0.);
2960  fpCommand -> SetParameter (parameter);
2961  parameter = new G4UIparameter ("parameter-4", 'd', omitable = true);
2962  parameter -> SetDefaultValue (0.);
2963  fpCommand -> SetParameter (parameter);
2964  parameter = new G4UIparameter ("parameter-5", 'd', omitable = true);
2965  parameter -> SetDefaultValue (0.);
2966  fpCommand -> SetParameter (parameter);
2967  parameter = new G4UIparameter ("parameter-6", 'd', omitable = true);
2968  parameter -> SetDefaultValue (0.);
2969  fpCommand -> SetParameter (parameter);
2970 }
2971 
2973  delete fpCommand;
2974 }
2975 
2977  return "world 0 -1";
2978 }
2979 
2981  G4String newValue) {
2982 
2984  G4bool warn = verbosity >= G4VisManager::warnings;
2985 
2986  G4Scene* pScene = fpVisManager->GetCurrentScene();
2987  if (!pScene) {
2988  if (verbosity >= G4VisManager::errors) {
2989  G4cerr << "ERROR: No current scene. Please create one." << G4endl;
2990  }
2991  return;
2992  }
2993 
2994  G4String name, clipVolumeType, parameterUnit;
2995  G4int copyNo, requestedDepthOfDescent;
2996  G4double param1, param2, param3, param4, param5, param6;
2997  std::istringstream is (newValue);
2998  is >> name >> copyNo >> requestedDepthOfDescent
2999  >> clipVolumeType >> parameterUnit
3000  >> param1 >> param2 >> param3 >> param4 >> param5 >> param6;
3002  G4PhysicalVolumeModel::subtraction; // Default subtraction mode.
3003  if (clipVolumeType[size_t(0)] == '-') {
3004  clipVolumeType = clipVolumeType.substr(1); // Remove first character.
3005  } else if (clipVolumeType[size_t(0)] == '*') {
3006  clippingMode = G4PhysicalVolumeModel::intersection;
3007  clipVolumeType = clipVolumeType.substr(1);
3008  }
3009  G4double unit = G4UIcommand::ValueOf(parameterUnit);
3010  param1 *= unit; param2 *= unit; param3 *= unit;
3011  param4 *= unit; param5 *= unit; param6 *= unit;
3012 
3013  G4VSolid* clippingSolid = nullptr;
3014  if (clipVolumeType == "box") {
3015  const G4double dX = (param2 - param1) / 2.;
3016  const G4double dY = (param4 - param3) / 2.;
3017  const G4double dZ = (param6 - param5) / 2.;
3018  const G4double x0 = (param2 + param1) / 2.;
3019  const G4double y0 = (param4 + param3) / 2.;
3020  const G4double z0 = (param6 + param5) / 2.;
3021  clippingSolid = new G4DisplacedSolid
3022  ("_displaced_clipping_box",
3023  new G4Box("_clipping_box",dX,dY,dZ),
3024  G4Translate3D(x0,y0,z0));
3025  }
3026 
3027  G4TransportationManager* transportationManager =
3029 
3030  size_t nWorlds = transportationManager->GetNoWorlds();
3031  if (nWorlds > 1) { // Parallel worlds in operation...
3032  if (verbosity >= G4VisManager::warnings) {
3033  static G4bool warned = false;
3034  if (!warned && name != "worlds") {
3035  G4cout <<
3036  "WARNING: Parallel worlds in operation. To visualise, specify"
3037  "\n \"worlds\" or the parallel world volume or sub-volume name"
3038  "\n and control visibility with /vis/geometry."
3039  << G4endl;
3040  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
3041  transportationManager->GetWorldsIterator();
3042  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
3043  G4cout << " World " << i << ": " << (*iterWorld)->GetName()
3044  << G4endl;
3045  warned = true;
3046  }
3047  }
3048  }
3049  }
3050 
3051  // Get the world (the initial value of the iterator points to the mass world).
3052  G4VPhysicalVolume* world = *(transportationManager->GetWorldsIterator());
3053 
3054  if (!world) {
3055  if (verbosity >= G4VisManager::errors) {
3056  G4cerr <<
3057  "ERROR: G4VisCommandSceneAddVolume::SetNewValue:"
3058  "\n No world. Maybe the geometry has not yet been defined."
3059  "\n Try \"/run/initialize\""
3060  << G4endl;
3061  }
3062  return;
3063  }
3064 
3065  std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
3066 
3067  if (name == "world") {
3068 
3069  findingsVector.push_back
3071 
3072  } else if (name == "worlds") {
3073 
3074  if (nWorlds <= 1) {
3075  if (verbosity >= G4VisManager::warnings) {
3076  G4cout <<
3077  "WARNING: G4VisCommandSceneAddVolume::SetNewValue:"
3078  "\n Parallel worlds requested but none exist."
3079  "\n Just adding material world."
3080  << G4endl;
3081  }
3082  }
3083  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
3084  transportationManager->GetWorldsIterator();
3085  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
3086  findingsVector.push_back
3088  (*iterWorld,*iterWorld));
3089  }
3090 
3091  } else { // Search all worlds...
3092 
3093  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
3094  transportationManager->GetWorldsIterator();
3095  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
3096  G4PhysicalVolumeModel searchModel (*iterWorld); // Unlimited depth.
3097  G4ModelingParameters mp; // Default - no culling.
3098  searchModel.SetModelingParameters (&mp);
3099  G4PhysicalVolumesSearchScene searchScene (&searchModel, name, copyNo);
3100  searchModel.DescribeYourselfTo (searchScene); // Initiate search.
3101  for (const auto& findings: searchScene.GetFindings()) {
3102  findingsVector.push_back(findings);
3103  }
3104  }
3105  }
3106 
3107  for (const auto& findings: findingsVector) {
3108  // Set copy number from search findings for replicas and parameterisations.
3109  findings.fpFoundPV->SetCopyNo(findings.fFoundPVCopyNo);
3110  // Create a physical volume model...
3111  G4PhysicalVolumeModel* foundPVModel = new G4PhysicalVolumeModel
3112  (findings.fpFoundPV,
3113  requestedDepthOfDescent,
3114  findings.fFoundObjectTransformation,
3115  0, // No modelling parameters (these are set later by the scene handler).
3116  false, // Do not use full extent - only use non-culled extent.
3117  findings.fFoundBasePVPath);
3118  if (clippingSolid) {
3119  foundPVModel->SetClippingSolid(clippingSolid);
3120  foundPVModel->SetClippingMode(clippingMode);
3121  }
3122  if (!foundPVModel->Validate(warn)) return; // Calculates extent
3123  // ...so add it to the scene.
3124  G4bool successful = pScene->AddRunDurationModel(foundPVModel,warn);
3125  if (successful) {
3126  if (verbosity >= G4VisManager::confirmations) {
3127  G4cout << "\"" << findings.fpFoundPV->GetName()
3128  << "\", copy no. " << findings.fFoundPVCopyNo
3129  << ",\n found in searched volume \""
3130  << findings.fpSearchPV->GetName()
3131  << "\" at depth " << findings.fFoundDepth
3132  << ",\n base path: \"" << findings.fFoundBasePVPath
3133  << "\",\n with a requested depth of further descent of ";
3134  if (requestedDepthOfDescent < 0) {
3135  G4cout << "<0 (unlimited)";
3136  }
3137  else {
3138  G4cout << requestedDepthOfDescent;
3139  }
3140  G4cout << ",\n has been added to scene \"" << pScene->GetName() << "\"."
3141  << G4endl;
3142  }
3143  } else {
3145  }
3146  }
3147 
3148  if (findingsVector.empty()) {
3149  if (verbosity >= G4VisManager::errors) {
3150  G4cerr << "ERROR: Volume \"" << name << "\"";
3151  if (copyNo >= 0) {
3152  G4cerr << ", copy no. " << copyNo << ",";
3153  }
3154  G4cerr << " not found." << G4endl;
3155  }
3157  return;
3158  }
3159 
3161 }