ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VisCommandsViewer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4VisCommandsViewer.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 
28 // /vis/viewer commands - John Allison 25th October 1998
29 
30 #include "G4VisCommandsViewer.hh"
31 
32 #include "G4VisManager.hh"
33 #include "G4GraphicsSystemList.hh"
34 #include "G4VisCommandsScene.hh"
35 #include "G4UImanager.hh"
36 #include "G4UIcommand.hh"
38 #include "G4UIcmdWithAString.hh"
39 #include "G4UIcmdWithADouble.hh"
41 #include "G4UIcmdWith3Vector.hh"
44 #include "G4Point3D.hh"
45 #include "G4SystemOfUnits.hh"
46 #include "G4UnitsTable.hh"
47 #include "G4ios.hh"
48 #ifdef G4VIS_USE_STD11
49 #include <chrono>
50 #include <thread>
51 #endif
52 #include <sstream>
53 #include <fstream>
54 #include <sstream>
55 #include <iomanip>
56 #include <cstdio>
57 #ifdef WIN32
58 #include <regex>
59 #include <filesystem>
60 #endif //WIN32
61 
63 
65  G4bool omitable;
66  fpCommand = new G4UIcommand ("/vis/viewer/addCutawayPlane", this);
67  fpCommand -> SetGuidance
68  ("Add cutaway plane to current viewer.");
69  G4UIparameter* parameter;
70  parameter = new G4UIparameter("x",'d',omitable = true);
71  parameter -> SetDefaultValue (0);
72  parameter -> SetGuidance ("Coordinate of point on the plane.");
73  fpCommand->SetParameter(parameter);
74  parameter = new G4UIparameter("y",'d',omitable = true);
75  parameter -> SetDefaultValue (0);
76  parameter -> SetGuidance ("Coordinate of point on the plane.");
77  fpCommand->SetParameter(parameter);
78  parameter = new G4UIparameter("z",'d',omitable = true);
79  parameter -> SetDefaultValue (0);
80  parameter -> SetGuidance ("Coordinate of point on the plane.");
81  fpCommand->SetParameter(parameter);
82  parameter = new G4UIparameter("unit",'s',omitable = true);
83  parameter -> SetDefaultValue ("m");
84  parameter -> SetGuidance ("Unit of point on the plane.");
85  fpCommand->SetParameter(parameter);
86  parameter = new G4UIparameter("nx",'d',omitable = true);
87  parameter -> SetDefaultValue (1);
88  parameter -> SetGuidance ("Component of plane normal.");
89  fpCommand->SetParameter(parameter);
90  parameter = new G4UIparameter("ny",'d',omitable = true);
91  parameter -> SetDefaultValue (0);
92  parameter -> SetGuidance ("Component of plane normal.");
93  fpCommand->SetParameter(parameter);
94  parameter = new G4UIparameter("nz",'d',omitable = true);
95  parameter -> SetDefaultValue (0);
96  parameter -> SetGuidance ("Component of plane normal.");
97  fpCommand->SetParameter(parameter);
98 }
99 
101  delete fpCommand;
102 }
103 
105  return "";
106 }
107 
109 
111 
112  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
113  if (!viewer) {
114  if (verbosity >= G4VisManager::errors) {
115  G4cerr <<
116  "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
117  << G4endl;
118  }
119  return;
120  }
121 
122  G4double x, y, z, nx, ny, nz;
123  G4String unit;
124  std::istringstream is (newValue);
125  is >> x >> y >> z >> unit >> nx >> ny >> nz;
127  x *= F; y *= F; z *= F;
128 
129  G4ViewParameters vp = viewer->GetViewParameters();
130  vp.AddCutawayPlane(G4Plane3D(G4Normal3D(nx,ny,nz), G4Point3D(x,y,z)));
131  if (verbosity >= G4VisManager::confirmations) {
132  G4cout << "Cutaway planes for viewer \"" << viewer->GetName() << "\" now:";
133  const G4Planes& cutaways = vp.GetCutawayPlanes();
134  for (size_t i = 0; i < cutaways.size(); ++i)
135  G4cout << "\n " << i << ": " << cutaways[i];
136  G4cout << G4endl;
137  }
138 
139  SetViewParameters(viewer, vp);
140 }
141 
143 
145  G4bool omitable;
146  fpCommandCentreAndZoomInOn = new G4UIcommand ("/vis/viewer/centreAndZoomInOn", this);
148  ("Centre and zoom in on the given physical volume.");
150  ("The names of all volumes in all worlds are matched against pv-name. If"
151  "\ncopy-no is supplied, it matches the copy number too. If pv-name is of the"
152  "\nform \"/regexp/\", where regexp is a regular expression (see C++ regex),"
153  "\nthe match uses the usual rules of regular expression matching."
154  "\nOtherwise an exact match is required."
155  "\nFor example, \"/Shap/\" matches \"Shape1\" and \"Shape2\".");
157  ("It may help to see a textual representation of the geometry hierarchy of"
158  "\nthe worlds. Try \"/vis/drawTree [worlds]\" or one of the driver/browser"
159  "\ncombinations that have the required functionality, e.g., HepRepFile.");
161  ("If there are more than one matching physical volumes they will all be"
162  "\nincluded. If this is not what you want, and what you want is to centre on a"
163  "\nparticular touchable, then select the touchable (\"/vis/set/touchable\") and"
164  "\nuse \"/vis/touchable/centreOn\". (You may need \"/vis/touchable/findPath\".)");
165  G4UIparameter* parameter;
166  parameter = new G4UIparameter("pv-name",'s',omitable = false);
167  parameter->SetGuidance ("Physical volume name.");
169  parameter = new G4UIparameter("copy-no",'i',omitable = true);
170  parameter->SetDefaultValue (-1);
171  parameter->SetGuidance ("Copy number. -1 means any or all copy numbers");
173 
174  fpCommandCentreOn = new G4UIcommand ("/vis/viewer/centreOn", this);
175  fpCommandCentreOn->SetGuidance ("Centre the view on the given physical volume.");
176  // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
178  // Pick up parameters from /vis/viewer/centreAndZoomInOn
180 }
181 
184  delete fpCommandCentreOn;
185 }
186 
188  return "";
189 }
190 
192 
194  G4bool warn = verbosity >= G4VisManager::warnings;
195 
196  G4VViewer* currentViewer = fpVisManager -> GetCurrentViewer ();
197  if (!currentViewer) {
198  if (verbosity >= G4VisManager::errors) {
199  G4cerr <<
200  "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
201  << G4endl;
202  }
203  return;
204  }
205 
206  G4String pvName;
207  G4int copyNo;
208  std::istringstream is (newValue);
209  is >> pvName >> copyNo;
210 
211  // Find physical volumes
212  G4TransportationManager* transportationManager =
214  size_t nWorlds = transportationManager->GetNoWorlds();
215  std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
216  std::vector<G4VPhysicalVolume*>::iterator iterWorld =
217  transportationManager->GetWorldsIterator();
218  for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
219  G4PhysicalVolumeModel searchModel (*iterWorld); // Unlimited depth.
220  G4ModelingParameters mp; // Default - no culling.
221  searchModel.SetModelingParameters (&mp);
222  G4PhysicalVolumesSearchScene searchScene (&searchModel, pvName, copyNo);
223  searchModel.DescribeYourselfTo (searchScene); // Initiate search.
224  for (const auto& findings: searchScene.GetFindings()) {
225  findingsVector.push_back(findings);
226  }
227  }
228 
229  if (findingsVector.empty()) {
230  if (verbosity >= G4VisManager::warnings) {
231  G4cerr
232  << "WARNING: Volume \"" << pvName << "\" ";
233  if (copyNo > 0) {
234  G4cerr << "copy number " << copyNo;
235  }
236  G4cerr << " not found." << G4endl;
237  }
238  return;
239  }
240 
241  // Use a temporary scene in order to find vis extent
242  G4Scene tempScene("Centre Scene");
243  for (const auto& findings: findingsVector) {
244  // To handle paramaterisations we have to set the copy number
245  findings.fpFoundPV->SetCopyNo(findings.fFoundPVCopyNo);
246  // Create a temporary physical volume model.
247  // They have to be created on the heap because they have
248  // to hang about long enough to be conflated.
250  (findings.fpFoundPV,
251  0, // Only interested in top volume
252  findings.fFoundObjectTransformation,
253  0, // No modelling parameters (these are set later by the scene handler).
254  true, // Use full extent
255  findings.fFoundBasePVPath);
256  // ...and add it to the scene.
257  G4bool successful = tempScene.AddRunDurationModel(tempPVModel,warn);
258  if (successful) {
259  if (verbosity >= G4VisManager::confirmations) {
260  G4cout << "\"" << findings.fpFoundPV->GetName()
261  << "\", copy no. " << findings.fFoundPVCopyNo
262  << ",\n found in searched volume \""
263  << findings.fpSearchPV->GetName()
264  << "\" at depth " << findings.fFoundDepth
265  << ",\n base path: \"" << findings.fFoundBasePVPath
266  << ",\n has been added to temporary scene \"" << tempScene.GetName() << "\"."
267  << G4endl;
268  }
269  }
270  }
271  // Delete temporary physical volume models
272  for (const auto& sceneModel: tempScene.GetRunDurationModelList()) {
273  delete sceneModel.fpModel;
274  }
275 
276  // Relevant results
277  const G4VisExtent& newExtent = tempScene.GetExtent();
278  const G4ThreeVector& newTargetPoint = newExtent.GetExtentCentre();
279 
280  G4Scene* currentScene = currentViewer->GetSceneHandler()->GetScene();
281  G4ViewParameters saveVP = currentViewer->GetViewParameters();
282  G4ViewParameters newVP = saveVP;
283  if (command == fpCommandCentreAndZoomInOn) {
284  // Calculate the new zoom factor
285  const G4double zoomFactor
286  = currentScene->GetExtent().GetExtentRadius()/newExtent.GetExtentRadius();
287  newVP.SetZoomFactor(zoomFactor);
288  }
289  // Change the target point
290  const G4Point3D& standardTargetPoint = currentScene->GetStandardTargetPoint();
291  newVP.SetCurrentTargetPoint(newTargetPoint - standardTargetPoint);
292  // Interpolate
293  InterpolateToNewView(currentViewer, saveVP, newVP);
294 
295  if (verbosity >= G4VisManager::confirmations) {
296  G4cout
297  << "Viewer \"" << currentViewer->GetName()
298  << "\" centred ";
300  G4cout << "and zoomed in";
301  }
302  G4cout << " on physical volume(s) \"" << pvName << '\"'
303  << G4endl;
304  }
305 
306  SetViewParameters(currentViewer, newVP);
307 }
308 
310 
312  G4bool omitable;
313  fpCommand = new G4UIcommand ("/vis/viewer/changeCutawayPlane", this);
314  fpCommand -> SetGuidance("Change cutaway plane.");
315  G4UIparameter* parameter;
316  parameter = new G4UIparameter("index",'i',omitable = false);
317  parameter -> SetGuidance ("Index of plane: 0, 1, 2.");
318  fpCommand->SetParameter(parameter);
319  parameter = new G4UIparameter("x",'d',omitable = true);
320  parameter -> SetDefaultValue (0);
321  parameter -> SetGuidance ("Coordinate of point on the plane.");
322  fpCommand->SetParameter(parameter);
323  parameter = new G4UIparameter("y",'d',omitable = true);
324  parameter -> SetDefaultValue (0);
325  parameter -> SetGuidance ("Coordinate of point on the plane.");
326  fpCommand->SetParameter(parameter);
327  parameter = new G4UIparameter("z",'d',omitable = true);
328  parameter -> SetDefaultValue (0);
329  parameter -> SetGuidance ("Coordinate of point on the plane.");
330  fpCommand->SetParameter(parameter);
331  parameter = new G4UIparameter("unit",'s',omitable = true);
332  parameter -> SetDefaultValue ("m");
333  parameter -> SetGuidance ("Unit of point on the plane.");
334  fpCommand->SetParameter(parameter);
335  parameter = new G4UIparameter("nx",'d',omitable = true);
336  parameter -> SetDefaultValue (1);
337  parameter -> SetGuidance ("Component of plane normal.");
338  fpCommand->SetParameter(parameter);
339  parameter = new G4UIparameter("ny",'d',omitable = true);
340  parameter -> SetDefaultValue (0);
341  parameter -> SetGuidance ("Component of plane normal.");
342  fpCommand->SetParameter(parameter);
343  parameter = new G4UIparameter("nz",'d',omitable = true);
344  parameter -> SetDefaultValue (0);
345  parameter -> SetGuidance ("Component of plane normal.");
346  fpCommand->SetParameter(parameter);
347 }
348 
350  delete fpCommand;
351 }
352 
354  return "";
355 }
356 
358 
360 
361  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
362  if (!viewer) {
363  if (verbosity >= G4VisManager::errors) {
364  G4cerr <<
365  "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
366  << G4endl;
367  }
368  return;
369  }
370 
371  size_t index;
372  G4double x, y, z, nx, ny, nz;
373  G4String unit;
374  std::istringstream is (newValue);
375  is >> index >> x >> y >> z >> unit >> nx >> ny >> nz;
377  x *= F; y *= F; z *= F;
378 
379  G4ViewParameters vp = viewer->GetViewParameters();
380  vp.ChangeCutawayPlane(index,
381  G4Plane3D(G4Normal3D(nx,ny,nz), G4Point3D(x,y,z)));
382  if (verbosity >= G4VisManager::confirmations) {
383  G4cout << "Cutaway planes for viewer \"" << viewer->GetName() << "\" now:";
384  const G4Planes& cutaways = vp.GetCutawayPlanes();
385  for (size_t i = 0; i < cutaways.size(); ++i)
386  G4cout << "\n " << i << ": " << cutaways[i];
387  G4cout << G4endl;
388  }
389 
390  SetViewParameters(viewer, vp);
391 }
392 
394 
396  G4bool omitable, currentAsDefault;
397  fpCommand = new G4UIcmdWithAString ("/vis/viewer/clear", this);
398  fpCommand -> SetGuidance ("Clears viewer.");
399  fpCommand -> SetGuidance
400  ("By default, clears current viewer. Specified viewer becomes current."
401  "\n\"/vis/viewer/list\" to see possible viewer names.");
402  fpCommand -> SetParameterName ("viewer-name",
403  omitable = true,
404  currentAsDefault = true);
405 }
406 
408  delete fpCommand;
409 }
410 
412  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
413  return viewer ? viewer -> GetName () : G4String("none");
414 }
415 
417 
419 
420  G4String& clearName = newValue;
421  G4VViewer* viewer = fpVisManager -> GetViewer (clearName);
422  if (!viewer) {
423  if (verbosity >= G4VisManager::errors) {
424  G4cerr << "ERROR: Viewer \"" << clearName
425  << "\" not found - \"/vis/viewer/list\" to see possibilities."
426  << G4endl;
427  }
428  return;
429  }
430 
431  viewer->SetView();
432  viewer->ClearView();
433  viewer->FinishView();
434  if (verbosity >= G4VisManager::confirmations) {
435  G4cout << "Viewer \"" << clearName << "\" cleared." << G4endl;
436  }
437 
438 }
439 
441 
444  ("/vis/viewer/clearCutawayPlanes", this);
445  fpCommand -> SetGuidance ("Clear cutaway planes of current viewer.");
446 }
447 
449  delete fpCommand;
450 }
451 
453  return "";
454 }
455 
457 
459 
460  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
461  if (!viewer) {
462  if (verbosity >= G4VisManager::errors) {
463  G4cerr <<
464  "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
465  << G4endl;
466  }
467  return;
468  }
469 
470  G4ViewParameters vp = viewer->GetViewParameters();
471  vp.ClearCutawayPlanes();
472  if (verbosity >= G4VisManager::confirmations) {
473  G4cout << "Cutaway planes for viewer \"" << viewer->GetName()
474  << "\" now cleared." << G4endl;
475  }
476 
477  SetViewParameters(viewer, vp);
478 }
479 
481 
483  G4bool omitable, currentAsDefault;
484  fpCommand = new G4UIcmdWithAString ("/vis/viewer/clearTransients", this);
485  fpCommand -> SetGuidance ("Clears transients from viewer.");
486  fpCommand -> SetGuidance
487  ("By default, operates on current viewer. Specified viewer becomes current."
488  "\n\"/vis/viewer/list\" to see possible viewer names.");
489  fpCommand -> SetParameterName ("viewer-name",
490  omitable = true,
491  currentAsDefault = true);
492 }
493 
495  delete fpCommand;
496 }
497 
499  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
500  return viewer ? viewer -> GetName () : G4String("none");
501 }
502 
504 
506 
507  G4String& clearName = newValue;
508  G4VViewer* viewer = fpVisManager -> GetViewer (clearName);
509  if (!viewer) {
510  if (verbosity >= G4VisManager::errors) {
511  G4cerr << "ERROR: Viewer \"" << clearName
512  << "\" not found - \"/vis/viewer/list\" to see possibilities."
513  << G4endl;
514  }
515  return;
516  }
517 
518  G4VSceneHandler* sceneHandler = viewer->GetSceneHandler();
519  sceneHandler->SetMarkForClearingTransientStore(false);
521  sceneHandler->ClearTransientStore();
522  if (verbosity >= G4VisManager::confirmations) {
523  G4cout << "Viewer \"" << clearName << "\" cleared of transients."
524  << G4endl;
525  }
526 
527 }
528 
530 
533  ("/vis/viewer/clearVisAttributesModifiers", this);
534  fpCommand -> SetGuidance ("Clear vis attribute modifiers of current viewer.");
535  fpCommand -> SetGuidance ("(These are used for touchables, etc.)");
536 }
537 
539  delete fpCommand;
540 }
541 
543  return "";
544 }
545 
547 
549 
550  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
551  if (!viewer) {
552  if (verbosity >= G4VisManager::errors) {
553  G4cerr <<
554  "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
555  << G4endl;
556  }
557  return;
558  }
559 
560  G4ViewParameters vp = viewer->GetViewParameters();
562  if (verbosity >= G4VisManager::confirmations) {
563  G4cout << "Vis attributes modifiers for viewer \"" << viewer->GetName()
564  << "\" now cleared." << G4endl;
565  }
566 
567  SetViewParameters(viewer, vp);
568 }
569 
571 
573  G4bool omitable;
574  fpCommand = new G4UIcommand ("/vis/viewer/clone", this);
575  fpCommand -> SetGuidance ("Clones viewer.");
576  fpCommand -> SetGuidance
577  ("By default, clones current viewer. Clone becomes current."
578  "\nClone name, if not provided, is derived from the original name."
579  "\n\"/vis/viewer/list\" to see possible viewer names.");
580  G4UIparameter* parameter;
581  parameter = new G4UIparameter ("original-viewer-name", 's', omitable = true);
582  parameter -> SetCurrentAsDefault (true);
583  fpCommand -> SetParameter (parameter);
584  parameter = new G4UIparameter ("clone-name", 's', omitable = true);
585  parameter -> SetDefaultValue ("none");
586  fpCommand -> SetParameter (parameter);
587 }
588 
590  delete fpCommand;
591 }
592 
594  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
595  G4String originalName = viewer ? viewer -> GetName () : G4String("none");
596  return "\"" + originalName + "\"";
597 }
598 
600 
602 
603  G4String originalName, cloneName;
604  std::istringstream is (newValue);
605 
606  // Need to handle the possibility that the names contain embedded
607  // blanks within quotation marks...
608  char c = ' ';
609  while (is.get(c) && c == ' '){}
610  if (c == '"') {
611  while (is.get(c) && c != '"') {originalName += c;}
612  }
613  else {
614  originalName += c;
615  while (is.get(c) && c != ' ') {originalName += c;}
616  }
617  originalName = originalName.strip (G4String::both, ' ');
618  originalName = originalName.strip (G4String::both, '"');
619 
620  G4VViewer* originalViewer = fpVisManager -> GetViewer (originalName);
621  if (!originalViewer) {
622  if (verbosity >= G4VisManager::errors) {
623  G4cerr << "ERROR: Viewer \"" << originalName
624  << "\" not found - \"/vis/viewer/list\" to see possibilities."
625  << G4endl;
626  }
627  return;
628  }
629  originalName = originalViewer->GetName(); // Ensures long name.
630 
631  while (is.get(c) && c == ' '){}
632  if (c == '"') {
633  while (is.get(c) && c != '"') {cloneName += c;}
634  }
635  else {
636  cloneName += c;
637  while (is.get(c) && c != ' ') {cloneName += c;}
638  }
639  cloneName = cloneName.strip (G4String::both, ' ');
640  cloneName = cloneName.strip (G4String::both, '"');
641 
642  G4bool errorWhileNaming = false;
643  if (cloneName == "none") {
644  G4int subID = 0;
645  do {
646  cloneName = originalName;
647  std::ostringstream oss;
648  oss << '-' << subID++;
649  G4String::size_type lastDashPosition, nextSpacePosition;
650  if ((lastDashPosition = cloneName.rfind('-')) != G4String::npos &&
651  (nextSpacePosition = cloneName.find(" ", lastDashPosition)) !=
652  G4String::npos) {
653  cloneName.insert(nextSpacePosition, oss.str());
654  } else {
655  G4String::size_type spacePosition = cloneName.find(' ');
656  if (spacePosition != G4String::npos)
657  cloneName.insert(spacePosition, oss.str());
658  else
659  errorWhileNaming = true;
660  }
661  } while (!errorWhileNaming && fpVisManager -> GetViewer (cloneName));
662  }
663 
664  if (errorWhileNaming) {
665  if (verbosity >= G4VisManager::errors) {
666  G4cerr << "ERROR: While naming clone viewer \"" << cloneName
667  << "\"."
668  << G4endl;
669  }
670  return;
671  }
672 
673  if (fpVisManager -> GetViewer (cloneName)) {
674  if (verbosity >= G4VisManager::errors) {
675  G4cerr << "ERROR: Putative clone viewer \"" << cloneName
676  << "\" already exists."
677  << G4endl;
678  }
679  return;
680  }
681 
682  G4String windowSizeHint =
683  originalViewer->GetViewParameters().GetXGeometryString();
684 
685  G4UImanager* UImanager = G4UImanager::GetUIpointer();
686  G4int keepVerbose = UImanager->GetVerboseLevel();
687  G4int newVerbose(0);
688  if (keepVerbose >= 2 ||
690  newVerbose = 2;
691  UImanager->SetVerboseLevel(newVerbose);
692  UImanager->ApplyCommand(G4String("/vis/viewer/select " + originalName));
693  UImanager->ApplyCommand
694  (G4String("/vis/viewer/create ! \"" + cloneName + "\" " + windowSizeHint));
695  UImanager->ApplyCommand(G4String("/vis/viewer/set/all " + originalName));
696  UImanager->SetVerboseLevel(keepVerbose);
697 
698  if (verbosity >= G4VisManager::confirmations) {
699  G4cout << "Viewer \"" << originalName << "\" cloned." << G4endl;
700  G4cout << "Clone \"" << cloneName << "\" now current." << G4endl;
701  }
702 }
703 
705 
707  G4bool omitable;
708  fpCommand = new G4UIcommand ("/vis/viewer/colourByDensity", this);
709  fpCommand -> SetGuidance
710  ("If a volume has no vis attributes, colour it by density.");
711  fpCommand -> SetGuidance
712  ("Provide algorithm number, e.g., \"1\" (or \"0\" to switch off)."
713  "\nThen a unit of density, e.g., \"g/cm3\"."
714  "\nThen parameters for the algorithm assumed to be densities in that unit.");
715  fpCommand -> SetGuidance
716  ("Algorithm 1: Simple algorithm takes 3 parameters: d0, d1 and d2."
717  "\n Volumes with density < d0 are invisible."
718  "\n Volumes with d0 <= density < d1 have colour on range red->green."
719  "\n Volumes with d1 <= density < d2 have colour on range green->blue."
720  "\n Volumes with density > d2 are blue.");
721  G4UIparameter* parameter;
722  parameter = new G4UIparameter("n",'i',omitable = true);
723  parameter -> SetGuidance ("Algorithm number (or \"0\" to switch off).");
724  parameter -> SetDefaultValue (1);
725  fpCommand->SetParameter(parameter);
726  parameter = new G4UIparameter("unit",'s',omitable = true);
727  parameter -> SetGuidance ("Unit of following densities, e.g., \"g/cm3\".");
728  parameter -> SetDefaultValue ("g/cm3");
729  fpCommand->SetParameter(parameter);
730  parameter = new G4UIparameter("d0",'d',omitable = true);
731  parameter -> SetGuidance ("Density parameter 0");
732  parameter -> SetDefaultValue (0.5);
733  fpCommand->SetParameter(parameter);
734  parameter = new G4UIparameter("d1",'d',omitable = true);
735  parameter -> SetGuidance ("Density parameter 1");
736  parameter -> SetDefaultValue (3.0);
737  fpCommand->SetParameter(parameter);
738  parameter = new G4UIparameter("d2",'d',omitable = true);
739  parameter -> SetGuidance ("Density parameter 2.");
740  parameter -> SetDefaultValue (10.0);
741  fpCommand->SetParameter(parameter);
742 }
743 
745  delete fpCommand;
746 }
747 
749  return "";
750 }
751 
753 
755 
756  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
757  if (!viewer) {
758  if (verbosity >= G4VisManager::errors) {
759  G4cerr <<
760  "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
761  << G4endl;
762  }
763  return;
764  }
765  G4ViewParameters vp = viewer->GetViewParameters();
766 
767  G4int algorithmNumber;
768  G4double d0, d1, d2;
769  G4String unit;
770  std::istringstream is (newValue);
771  is >> algorithmNumber >> unit >> d0 >> d1 >> d2;
772 
773  if (algorithmNumber < 0 || algorithmNumber > 1) {
774  if (verbosity >= G4VisManager::errors) {
775  G4cerr <<
776  "ERROR: Unrecognised algorithm number: " << algorithmNumber
777  << G4endl;
778  }
779  return;
780  }
781 
782  std::vector<G4double> parameters;
783  if (algorithmNumber > 0) {
784  const G4String where = "G4VisCommandViewerColourByDensity::SetNewValue";
785  G4double valueOfUnit;
786  // "Volumic Mass" is Michel's phrase for "Density"
787  if (ProvideValueOfUnit(where,unit,"Volumic Mass",valueOfUnit)) {
788  // Successful outcome of unit search
789  d0 *= valueOfUnit; d1 *= valueOfUnit; d2 *= valueOfUnit;
790  } else {
791  if (verbosity >= G4VisManager::errors) {
792  G4cerr <<
793  "ERROR: Unrecognised or inappropriate unit: " << unit
794  << G4endl;
795  }
796  return;
797  }
798  parameters.push_back(d0);
799  parameters.push_back(d1);
800  parameters.push_back(d2);
801  }
802  vp.SetCBDAlgorithmNumber(algorithmNumber);
803  vp.SetCBDParameters(parameters);
804 
805  if (verbosity >= G4VisManager::confirmations) {
806  if (vp.GetCBDAlgorithmNumber() == 0) {
807  G4cout << "Colour by density deactivated" << G4endl;
808  } else {
809  G4cout << "Colour by density algorithm " << vp.GetCBDAlgorithmNumber()
810  << " selected for viewer \"" << viewer->GetName()
811  << "\n Parameters:";
812  for (auto p: vp.GetCBDParameters()) {
813  G4cout << ' ' << G4BestUnit(p,"Volumic Mass");
814  }
815  G4cout << G4endl;
816  }
817  }
818 
819  SetViewParameters(viewer, vp);
820 }
821 
823 
825  G4bool omitable;
826  fpCommand = new G4UIcmdWithAString ("/vis/viewer/copyViewFrom", this);
827  fpCommand -> SetGuidance
828  ("Copy the camera-specific parameters from the specified viewer.");
829  fpCommand -> SetGuidance
830  ("Note: To copy ALL view parameters, including scene modifications,"
831  "\nuse \"/vis/viewer/set/all\"");
832  fpCommand -> SetParameterName ("from-viewer-name", omitable = false);
833 }
834 
836  delete fpCommand;
837 }
838 
840  return "";
841 }
842 
844 
846 
847  G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
848  if (!currentViewer) {
849  if (verbosity >= G4VisManager::errors) {
850  G4cerr <<
851  "ERROR: G4VisCommandsViewerCopyViewFrom::SetNewValue: no current viewer."
852  << G4endl;
853  }
854  return;
855  }
856 
857  const G4String& fromViewerName = newValue;
858  G4VViewer* fromViewer = fpVisManager -> GetViewer (fromViewerName);
859  if (!fromViewer) {
860  if (verbosity >= G4VisManager::errors) {
861  G4cerr << "ERROR: Viewer \"" << fromViewerName
862  << "\" not found - \"/vis/viewer/list\" to see possibilities."
863  << G4endl;
864  }
865  return;
866  }
867 
868  if (fromViewer == currentViewer) {
869  if (verbosity >= G4VisManager::warnings) {
870  G4cout <<
871  "WARNING: G4VisCommandsViewerSet::SetNewValue:"
872  "\n from-viewer and current viewer are identical."
873  << G4endl;
874  }
875  return;
876  }
877 
878  // Copy camera-specific view parameters
879  G4ViewParameters vp = currentViewer->GetViewParameters();
880  const G4ViewParameters& fromVP = fromViewer->GetViewParameters();
884  vp.SetUpVector (fromVP.GetUpVector());
885  vp.SetFieldHalfAngle (fromVP.GetFieldHalfAngle());
886  vp.SetZoomFactor (fromVP.GetZoomFactor());
887  vp.SetScaleFactor (fromVP.GetScaleFactor());
889  vp.SetDolly (fromVP.GetDolly());
890  SetViewParameters(currentViewer, vp);
891 
892  if (verbosity >= G4VisManager::confirmations) {
893  G4cout << "Camera parameters of viewer \"" << currentViewer->GetName()
894  << "\"\n set to those of viewer \"" << fromViewer->GetName()
895  << "\"."
896  << G4endl;
897  }
898 }
899 
901 
903  G4bool omitable;
904  fpCommand = new G4UIcommand ("/vis/viewer/create", this);
905  fpCommand -> SetGuidance
906  ("Creates a viewer for the specified scene handler.");
907  fpCommand -> SetGuidance
908  ("Default scene handler is the current scene handler. Invents a name"
909  "\nif not supplied. (Note: the system adds information to the name"
910  "\nfor identification - only the characters up to the first blank are"
911  "\nused for removing, selecting, etc.) This scene handler and viewer"
912  "\nbecome current.");
913  G4UIparameter* parameter;
914  parameter = new G4UIparameter ("scene-handler", 's', omitable = true);
915  parameter -> SetCurrentAsDefault (true);
916  fpCommand -> SetParameter (parameter);
917  parameter = new G4UIparameter ("viewer-name", 's', omitable = true);
918  parameter -> SetCurrentAsDefault (true);
919  fpCommand -> SetParameter (parameter);
920  parameter = new G4UIparameter ("window-size-hint", 's', omitable = true);
921  parameter->SetGuidance
922  ("integer (pixels) for square window placed by window manager or"
923  " X-Windows-type geometry string, e.g. 600x600-100+100");
924  parameter->SetDefaultValue("600");
925  fpCommand -> SetParameter (parameter);
926 }
927 
929  delete fpCommand;
930 }
931 
933  std::ostringstream oss;
934  G4VSceneHandler* sceneHandler = fpVisManager -> GetCurrentSceneHandler ();
935  oss << "viewer-" << fId << " (";
936  if (sceneHandler) {
937  oss << sceneHandler -> GetGraphicsSystem () -> GetName ();
938  }
939  else {
940  oss << "no_scene_handlers";
941  }
942  oss << ")";
943  return oss.str();
944 }
945 
947  G4String currentValue;
948  G4VSceneHandler* currentSceneHandler =
949  fpVisManager -> GetCurrentSceneHandler ();
950  if (currentSceneHandler) {
951  currentValue = currentSceneHandler -> GetName ();
952  }
953  else {
954  currentValue = "none";
955  }
956  currentValue += ' ';
957  currentValue += '"';
958  currentValue += NextName ();
959  currentValue += '"';
960 
961  currentValue += " 600"; // Default number of pixels for window size hint.
962 
963  return currentValue;
964 }
965 
967 
969 
970  G4String sceneHandlerName, newName;
971  G4String windowSizeHintString;
972  std::istringstream is (newValue);
973  is >> sceneHandlerName;
974 
975  // Now need to handle the possibility that the second string
976  // contains embedded blanks within quotation marks...
977  char c = ' ';
978  while (is.get(c) && c == ' '){}
979  if (c == '"') {
980  while (is.get(c) && c != '"') {newName += c;}
981  }
982  else {
983  newName += c;
984  while (is.get(c) && c != ' ') {newName += c;}
985  }
986  newName = newName.strip (G4String::both, ' ');
987  newName = newName.strip (G4String::both, '"');
988 
989  // Now get window size hint...
990  is >> windowSizeHintString;
991 
992  const G4SceneHandlerList& sceneHandlerList =
993  fpVisManager -> GetAvailableSceneHandlers ();
994  G4int nHandlers = sceneHandlerList.size ();
995  if (nHandlers <= 0) {
996  if (verbosity >= G4VisManager::errors) {
997  G4cerr <<
998  "ERROR: G4VisCommandViewerCreate::SetNewValue: no scene handlers."
999  "\n Create a scene handler with \"/vis/sceneHandler/create\""
1000  << G4endl;
1001  }
1002  return;
1003  }
1004 
1005  G4int iHandler;
1006  for (iHandler = 0; iHandler < nHandlers; iHandler++) {
1007  if (sceneHandlerList [iHandler] -> GetName () == sceneHandlerName) break;
1008  }
1009 
1010  if (iHandler < 0 || iHandler >= nHandlers) {
1011  // Invalid command line argument or none.
1012  // This shouldn't happen!!!!!!
1013  if (verbosity >= G4VisManager::errors) {
1014  G4cout << "G4VisCommandViewerCreate::SetNewValue:"
1015  " invalid scene handler specified."
1016  << G4endl;
1017  }
1018  return;
1019  }
1020 
1021  // Valid index. Set current scene handler and graphics system in
1022  // preparation for creating viewer.
1023  G4VSceneHandler* sceneHandler = sceneHandlerList [iHandler];
1024  if (sceneHandler != fpVisManager -> GetCurrentSceneHandler ()) {
1025  fpVisManager -> SetCurrentSceneHandler (sceneHandler);
1026  }
1027 
1028  // Now deal with name of viewer.
1029  G4String nextName = NextName ();
1030  if (newName == "") {
1031  newName = nextName;
1032  }
1033  if (newName == nextName) fId++;
1034  G4String newShortName = fpVisManager -> ViewerShortName (newName);
1035 
1036  for (G4int ih = 0; ih < nHandlers; ih++) {
1037  G4VSceneHandler* sh = sceneHandlerList [ih];
1038  const G4ViewerList& viewerList = sh -> GetViewerList ();
1039  for (size_t iViewer = 0; iViewer < viewerList.size (); iViewer++) {
1040  if (viewerList [iViewer] -> GetShortName () == newShortName ) {
1041  if (verbosity >= G4VisManager::errors) {
1042  G4cerr << "ERROR: Viewer \"" << newShortName << "\" already exists."
1043  << G4endl;
1044  }
1045  return;
1046  }
1047  }
1048  }
1049 
1050  // WindowSizeHint and XGeometryString are picked up from the vis
1051  // manager in the G4VViewer constructor. In G4VisManager, after Viewer
1052  // creation, we will store theses parameters in G4ViewParameters.
1053 
1054  fpVisManager -> CreateViewer (newName,windowSizeHintString);
1055 
1056  G4VViewer* newViewer = fpVisManager -> GetCurrentViewer ();
1057  if (newViewer && newViewer -> GetName () == newName) {
1058  if (verbosity >= G4VisManager::confirmations) {
1059  G4cout << "New viewer \"" << newName << "\" created." << G4endl;
1060  }
1061  }
1062  else {
1063  if (verbosity >= G4VisManager::errors) {
1064  if (newViewer) {
1065  G4cerr << "ERROR: New viewer doesn\'t match!!! Curious!!" << G4endl;
1066  } else {
1067  G4cout << "WARNING: No viewer created." << G4endl;
1068  }
1069  }
1070  }
1071  // Refresh if appropriate...
1072  if (newViewer) {
1073  if (newViewer->GetViewParameters().IsAutoRefresh()) {
1074  G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/refresh");
1075  }
1076  else {
1077  if (verbosity >= G4VisManager::warnings) {
1078  G4cout << "Issue /vis/viewer/refresh or flush to see effect."
1079  << G4endl;
1080  }
1081  }
1082  }
1083 }
1084 
1086 
1088  fDollyIncrement (0.),
1089  fDollyTo (0.)
1090 {
1091  G4bool omitable, currentAsDefault;
1092 
1094  ("/vis/viewer/dolly", this);
1095  fpCommandDolly -> SetGuidance
1096  ("Incremental dolly.");
1097  fpCommandDolly -> SetGuidance
1098  ("Moves the camera incrementally towards target point.");
1099  fpCommandDolly -> SetParameterName("increment",
1100  omitable=true,
1101  currentAsDefault=true);
1102  fpCommandDolly -> SetDefaultUnit("m");
1103 
1105  ("/vis/viewer/dollyTo", this);
1106  fpCommandDollyTo -> SetGuidance
1107  ("Dolly to specific coordinate.");
1108  fpCommandDollyTo -> SetGuidance
1109  ("Places the camera towards target point relative to standard camera point.");
1110  fpCommandDollyTo -> SetParameterName("distance",
1111  omitable=true,
1112  currentAsDefault=true);
1113  fpCommandDollyTo -> SetDefaultUnit("m");
1114 }
1115 
1117  delete fpCommandDolly;
1118  delete fpCommandDollyTo;
1119 }
1120 
1122  G4String currentValue;
1123  if (command == fpCommandDolly) {
1124  currentValue = fpCommandDolly->ConvertToString(fDollyIncrement, "m");
1125  }
1126  else if (command == fpCommandDollyTo) {
1127  currentValue = fpCommandDollyTo->ConvertToString(fDollyTo, "m");
1128  }
1129  return currentValue;
1130 }
1131 
1133  G4String newValue) {
1134 
1135 
1137 
1138  G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
1139  if (!currentViewer) {
1140  if (verbosity >= G4VisManager::errors) {
1141  G4cerr <<
1142  "ERROR: G4VisCommandsViewerDolly::SetNewValue: no current viewer."
1143  << G4endl;
1144  }
1145  return;
1146  }
1147 
1148  G4ViewParameters vp = currentViewer->GetViewParameters();
1149 
1150  if (command == fpCommandDolly) {
1153  }
1154  else if (command == fpCommandDollyTo) {
1156  vp.SetDolly(fDollyTo);
1157  }
1158 
1159  if (verbosity >= G4VisManager::confirmations) {
1160  G4cout << "Dolly distance changed to " << vp.GetDolly() << G4endl;
1161  }
1162 
1163  SetViewParameters(currentViewer, vp);
1164 }
1165 
1167 
1169  G4bool omitable, currentAsDefault;
1170  fpCommand = new G4UIcmdWithAString ("/vis/viewer/flush", this);
1171  fpCommand -> SetGuidance
1172  ("Compound command: \"/vis/viewer/refresh\" + \"/vis/viewer/update\".");
1173  fpCommand -> SetGuidance
1174  ("Useful for refreshing and initiating post-processing for graphics"
1175  "\nsystems which need post-processing. By default, acts on current"
1176  "\nviewer. \"/vis/viewer/list\" to see possible viewers. Viewer"
1177  "\nbecomes current.");
1178  fpCommand -> SetParameterName ("viewer-name",
1179  omitable = true,
1180  currentAsDefault = true);
1181 }
1182 
1184  delete fpCommand;
1185 }
1186 
1189  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
1190  return viewer ? viewer -> GetName () : G4String("none");
1191 }
1192 
1194 
1196 
1197  G4String& flushName = newValue;
1198  G4VViewer* viewer = fpVisManager -> GetViewer (flushName);
1199  if (!viewer) {
1200  if (verbosity >= G4VisManager::errors) {
1201  G4cerr << "ERROR: Viewer \"" << flushName << "\"" <<
1202  " not found - \"/vis/viewer/list\"\n to see possibilities."
1203  << G4endl;
1204  }
1205  return;
1206  }
1207 
1209  G4int keepVerbose = ui->GetVerboseLevel();
1210  G4int newVerbose(0);
1211  if (keepVerbose >= 2 || verbosity >= G4VisManager::confirmations)
1212  newVerbose = 2;
1213  ui->SetVerboseLevel(newVerbose);
1214  ui->ApplyCommand(G4String("/vis/viewer/refresh " + flushName));
1215  ui->ApplyCommand(G4String("/vis/viewer/update " + flushName));
1216  ui->SetVerboseLevel(keepVerbose);
1217  if (verbosity >= G4VisManager::confirmations) {
1218  G4cout << "Viewer \"" << viewer -> GetName () << "\""
1219  << " flushed." << G4endl;
1220  }
1221 }
1222 
1224 
1226  G4bool omitable;
1227  fpCommand = new G4UIcommand ("/vis/viewer/interpolate", this);
1228  fpCommand -> SetGuidance
1229  ("Interpolate views defined by the first argument, which can contain "
1230  "Unix-shell-style pattern matching characters such as '*', '?' and '[' "
1231  "- see \"man sh\" and look for \"Pattern Matching\". The contents "
1232  "of each file are assumed to be \"/vis/viewer\" commands "
1233  "that specify a particular view. The files are processed in alphanumeric "
1234  "order of filename. The files may be written by hand or produced by the "
1235  "\"/vis/viewer/save\" command.");
1236  fpCommand -> SetGuidance
1237  ("The default is to search the working directory for files with a .g4view "
1238  "extension. Another procedure is to assemble view files in a subdirectory, "
1239  "e.g., \"myviews\"; then they can be interpolated with\n"
1240  "\"/vis/viewer/interpolate myviews/*\".");
1241  fpCommand -> SetGuidance
1242  ("To export interpolated views to file for a future possible movie, "
1243  "write \"export\" as 5th parameter (OpenGL only).");
1244  G4UIparameter* parameter;
1245  parameter = new G4UIparameter("pattern", 's', omitable = true);
1246  parameter -> SetGuidance("Pattern that defines the view files.");
1247  parameter -> SetDefaultValue("*.g4view");
1248  fpCommand -> SetParameter(parameter);
1249  parameter = new G4UIparameter("no-of-points", 'i', omitable = true);
1250  parameter -> SetGuidance ("Number of interpolation points per interval.");
1251  parameter -> SetDefaultValue(50);
1252  fpCommand -> SetParameter(parameter);
1253  parameter = new G4UIparameter("wait-time", 's', omitable = true);
1254  parameter -> SetGuidance("Wait time per interpolated point");
1255  parameter -> SetDefaultValue("20.");
1256  fpCommand -> SetParameter(parameter);
1257  parameter = new G4UIparameter("time-unit", 's', omitable = true);
1258  parameter -> SetDefaultValue("millisecond");
1259  fpCommand -> SetParameter (parameter);
1260  parameter = new G4UIparameter("export", 's', omitable = true);
1261  parameter -> SetDefaultValue("no");
1262  fpCommand -> SetParameter (parameter);
1263 }
1264 
1266  delete fpCommand;
1267 }
1268 
1270  return "";
1271 }
1272 
1274 
1276 
1277  G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
1278  if (!currentViewer) {
1279  if (verbosity >= G4VisManager::errors) {
1280  G4cerr <<
1281  "ERROR: G4VisCommandViewerInterpolate::SetNewValue: no current viewer."
1282  << G4endl;
1283  }
1284  return;
1285  }
1286 
1287  G4String pattern;
1288  G4int nInterpolationPoints;
1289  G4String waitTimePerPointString;
1290  G4String timeUnit;
1291  G4String exportString;
1292 
1293  std::istringstream iss (newValue);
1294  iss
1295  >> pattern
1296  >> nInterpolationPoints
1297  >> waitTimePerPointString
1298  >> timeUnit
1299  >> exportString;
1300  G4String waitTimePerPointDimString(waitTimePerPointString + ' ' + timeUnit);
1301  const G4double waitTimePerPoint =
1302  G4UIcommand::ConvertToDimensionedDouble(waitTimePerPointDimString.c_str());
1303  G4int waitTimePerPointmilliseconds = waitTimePerPoint/millisecond;
1304  if (waitTimePerPointmilliseconds < 0) waitTimePerPointmilliseconds = 0;
1305 
1306  G4UImanager* uiManager = G4UImanager::GetUIpointer();
1307 
1308  // Save current view parameters
1309  G4ViewParameters saveVP = currentViewer->GetViewParameters();
1310 
1311  // Save current verbosities
1312  G4VisManager::Verbosity keepVisVerbosity = fpVisManager->GetVerbosity();
1313  G4int keepUIVerbosity = uiManager->GetVerboseLevel();
1314 
1315  // Set verbosities for this operation
1317  uiManager->SetVerboseLevel(0);
1318 
1319  // Switch off auto-refresh while we read in the view files (it will be
1320  // restored later). Note: the view files do not set auto-refresh.
1321  G4ViewParameters non_auto = saveVP;
1322  non_auto.SetAutoRefresh(false);
1323  currentViewer->SetViewParameters(non_auto);
1324 
1325  // View vector of way points
1326  std::vector<G4ViewParameters> viewVector;
1327 
1328  const G4int safety = 9999;
1329  G4int safetyCount = 0;
1330  G4String pathname;
1331 
1332 #ifndef WIN32
1333 
1334  // Execute pattern and get resulting list of files
1335  G4String shellCommand = "echo " + pattern;
1336  FILE *filelist = popen(shellCommand.c_str(), "r");
1337  if (!filelist) {
1338  if (verbosity >= G4VisManager::errors) {
1339  G4cerr
1340  << "ERROR: G4VisCommandViewerInterpolate::SetNewValue:"
1341  << "\n Error obtaining pipe."
1342  << G4endl;
1343  }
1344  return;
1345  }
1346 
1347  // Build view vector of way points
1348  const size_t BUFLENGTH = 999999;
1349  char buf[BUFLENGTH];
1350  char* result = std::fgets(buf, BUFLENGTH, filelist);
1351  if (result) {
1352  std::istringstream fileliststream(result);
1353  while (fileliststream >> pathname
1354  && safetyCount++ < safety) { // Loop checking, 16.02.2016, J.Allison
1355  uiManager->ApplyCommand("/control/execute " + pathname);
1356  G4ViewParameters vp = currentViewer->GetViewParameters();
1357  // Set original auto-refresh status.
1358  vp.SetAutoRefresh(saveVP.IsAutoRefresh());
1359  viewVector.push_back(vp);
1360  }
1361  }
1362  pclose(filelist);
1363 
1364 #else // WIN32 (popen is not available in Windows)
1365 
1366  std::filesystem::path filePattern = pattern.c_str();
1367 
1368  // Default pattern : *.g4view
1369  // Translated to a regexp : ^.*\\.g4view
1370  // Convert pattern into a regexp
1371  std::string regexp_pattern("^" + filePattern.filename().string());
1372  std::string result_pattern = "";
1373  // Replace '.' by "\\."
1374  size_t currentPos = 0;
1375  size_t nextPos = 0;
1376  std::string currentReplacement = "";
1377  size_t pos1 = regexp_pattern.find('.', nextPos);
1378  size_t pos2 = regexp_pattern.find('*', nextPos);
1379  size_t pos3 = regexp_pattern.find('?', nextPos);
1380  while ((pos1 != std::string::npos) || (pos2 != std::string::npos) || (pos3 != std::string::npos)) {
1381  nextPos = pos1;
1382  currentReplacement = "\\.";
1383  if (pos2 < nextPos) {
1384  nextPos = pos2;
1385  currentReplacement = ".*";
1386  }
1387  if (pos3 < nextPos) {
1388  nextPos = pos3;
1389  currentReplacement = "(.{1,1})";
1390  }
1391  result_pattern += regexp_pattern.substr(currentPos, nextPos - currentPos) + currentReplacement;
1392  nextPos++;
1393  currentPos = nextPos;
1394  pos1 = regexp_pattern.find('.', currentPos);
1395  pos2 = regexp_pattern.find('*', currentPos);
1396  pos3 = regexp_pattern.find('?', currentPos);
1397  }
1398  result_pattern += regexp_pattern.substr(currentPos);
1399 
1400  // Build view vector of way points
1401  // Add "./" for empty paths
1402  G4String parentPath(filePattern.parent_path().string().length() ? filePattern.parent_path().string() : std::string("./"));
1403  std::filesystem::path parentPathPattern = parentPath.c_str();
1404  // Iterate through files in directory and apply regex match to filter appropriate files
1405  std::regex result_pattern_regex (result_pattern, std::regex_constants::basic | std::regex_constants::icase);
1406  for (auto iter = std::filesystem::directory_iterator(parentPathPattern);
1407  iter != std::filesystem::directory_iterator() && safetyCount++ < safety;
1408  ++iter)
1409  {
1410  const auto& file = iter->path();
1411 
1412  G4String filename(file.filename().string());
1413  if (std::regex_match(filename, result_pattern_regex))
1414  {
1415  uiManager->ApplyCommand("/control/execute " + filename);
1416  G4ViewParameters vp = currentViewer->GetViewParameters();
1417  // Set original auto-refresh status.
1418  vp.SetAutoRefresh(saveVP.IsAutoRefresh());
1419  viewVector.push_back(vp);
1420  }
1421  }
1422 
1423 #endif // WIN32
1424 
1425  if (safetyCount >= safety) {
1426  if (verbosity >= G4VisManager::errors) {
1427  G4cout <<
1428  "/vis/viewer/interpolate:"
1429  "\n the number of way points exceeds the maximum currently allowed: "
1430  << safety << G4endl;
1431  }
1432  return;
1433  }
1434 
1436  (currentViewer,viewVector,
1437  nInterpolationPoints,waitTimePerPointmilliseconds,exportString);
1438 
1439  // Restore original verbosities
1440  uiManager->SetVerboseLevel(keepUIVerbosity);
1441  fpVisManager->SetVerboseLevel(keepVisVerbosity);
1442 
1443  // Restore original view parameters
1444  currentViewer->SetViewParameters(saveVP);
1445  currentViewer->RefreshView();
1446  if (verbosity >= G4VisManager::confirmations) {
1447  G4cout << "Viewer \"" << currentViewer -> GetName () << "\""
1448  << " restored." << G4endl;
1449  }
1450 }
1451 
1453 
1455  G4bool omitable;
1456  fpCommand = new G4UIcommand ("/vis/viewer/list", this);
1457  fpCommand -> SetGuidance ("Lists viewers(s).");
1458  fpCommand -> SetGuidance
1459  ("See \"/vis/verbose\" for definition of verbosity.");
1460  G4UIparameter* parameter;
1461  parameter = new G4UIparameter("viewer-name", 's',
1462  omitable = true);
1463  parameter -> SetDefaultValue ("all");
1464  fpCommand -> SetParameter (parameter);
1465  parameter = new G4UIparameter ("verbosity", 's',
1466  omitable = true);
1467  parameter -> SetDefaultValue ("warnings");
1468  fpCommand -> SetParameter (parameter);
1469 }
1470 
1472  delete fpCommand;
1473 }
1474 
1476  return "";
1477 }
1478 
1480  G4String name, verbosityString;
1481  std::istringstream is (newValue);
1482  is >> name >> verbosityString;
1483  G4String shortName = fpVisManager -> ViewerShortName (name);
1484  G4VisManager::Verbosity verbosity =
1485  fpVisManager->GetVerbosityValue(verbosityString);
1486 
1487  const G4VViewer* currentViewer = fpVisManager -> GetCurrentViewer ();
1488  G4String currentViewerShortName;
1489  if (currentViewer) {
1490  currentViewerShortName = currentViewer -> GetShortName ();
1491  }
1492  else {
1493  currentViewerShortName = "none";
1494  }
1495 
1496  const G4SceneHandlerList& sceneHandlerList =
1497  fpVisManager -> GetAvailableSceneHandlers ();
1498  G4int nHandlers = sceneHandlerList.size ();
1499  G4bool found = false;
1500  G4bool foundCurrent = false;
1501  for (int iHandler = 0; iHandler < nHandlers; iHandler++) {
1502  G4VSceneHandler* sceneHandler = sceneHandlerList [iHandler];
1503  const G4ViewerList& viewerList = sceneHandler -> GetViewerList ();
1504  G4cout
1505  << "Scene handler \"" << sceneHandler -> GetName () << "\" ("
1506  << sceneHandler->GetGraphicsSystem()->GetNickname() << ')';
1507  const G4Scene* pScene = sceneHandler -> GetScene ();
1508  if (pScene) {
1509  G4cout << ", scene \"" << pScene -> GetName () << "\"";
1510  }
1511  G4cout << ':';
1512  G4int nViewers = viewerList.size ();
1513  if (nViewers == 0) {
1514  G4cout << "\n No viewers for this scene handler." << G4endl;
1515  }
1516  else {
1517  for (int iViewer = 0; iViewer < nViewers; iViewer++) {
1518  const G4VViewer* thisViewer = viewerList [iViewer];
1519  G4String thisName = thisViewer -> GetName ();
1520  G4String thisShortName = thisViewer -> GetShortName ();
1521  if (name != "all") {
1522  if (thisShortName != shortName) continue;
1523  }
1524  found = true;
1525  G4cout << "\n ";
1526  if (thisShortName == currentViewerShortName) {
1527  foundCurrent = true;
1528  G4cout << "(current)";
1529  }
1530  else {
1531  G4cout << " ";
1532  }
1533  G4cout << " viewer \"" << thisName << "\"";
1534  if (verbosity >= G4VisManager::parameters) {
1535  G4cout << "\n " << *thisViewer;
1536  }
1537  }
1538  }
1539  G4cout << G4endl;
1540  }
1541 
1542  if (!foundCurrent) {
1543  G4cout << "No valid current viewer - please create or select one."
1544  << G4endl;
1545  }
1546 
1547  if (!found) {
1548  G4cout << "No viewers";
1549  if (name != "all") {
1550  G4cout << " of name \"" << name << "\"";
1551  }
1552  G4cout << " found." << G4endl;
1553  }
1554 }
1555 
1557 
1559  fPanIncrementRight (0.),
1560  fPanIncrementUp (0.),
1561  fPanToRight (0.),
1562  fPanToUp (0.)
1563 {
1564  G4bool omitable;
1565 
1567  ("/vis/viewer/pan", this);
1568  fpCommandPan -> SetGuidance
1569  ("Incremental pan.");
1570  fpCommandPan -> SetGuidance
1571  ("Moves the camera incrementally right and up by these amounts (as seen"
1572  "\nfrom viewpoint direction).");
1573  G4UIparameter* parameter;
1574  parameter = new G4UIparameter("right-increment", 'd', omitable = true);
1575  parameter -> SetCurrentAsDefault (true);
1576  fpCommandPan -> SetParameter (parameter);
1577  parameter = new G4UIparameter("up-increment", 'd', omitable = true);
1578  parameter -> SetCurrentAsDefault (true);
1579  fpCommandPan -> SetParameter (parameter);
1580  parameter = new G4UIparameter ("unit", 's', omitable = true);
1581  parameter -> SetDefaultValue ("m");
1582  fpCommandPan -> SetParameter (parameter);
1583 
1585  ("/vis/viewer/panTo", this);
1586  fpCommandPanTo -> SetGuidance
1587  ("Pan to specific coordinate.");
1588  fpCommandPanTo -> SetGuidance
1589  ("Places the camera in this position right and up relative to standard"
1590  "\ntarget point (as seen from viewpoint direction).");
1591  parameter = new G4UIparameter("right", 'd', omitable = true);
1592  parameter -> SetCurrentAsDefault (true);
1593  fpCommandPanTo -> SetParameter (parameter);
1594  parameter = new G4UIparameter("up", 'd', omitable = true);
1595  parameter -> SetCurrentAsDefault (true);
1596  fpCommandPanTo -> SetParameter (parameter);
1597  parameter = new G4UIparameter ("unit", 's', omitable = true);
1598  parameter -> SetDefaultValue ("m");
1599  fpCommandPanTo -> SetParameter (parameter);
1600 }
1601 
1603  delete fpCommandPan;
1604  delete fpCommandPanTo;
1605 }
1606 
1608  G4String currentValue;
1609  if (command == fpCommandPan) {
1610  currentValue = ConvertToString(fPanIncrementRight, fPanIncrementUp, "m");
1611  }
1612  else if (command == fpCommandPanTo) {
1613  currentValue = ConvertToString(fPanToRight, fPanToUp, "m");
1614  }
1615  return currentValue;
1616 }
1617 
1619  G4String newValue) {
1620 
1621 
1623 
1624  G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
1625  if (!currentViewer) {
1626  if (verbosity >= G4VisManager::errors) {
1627  G4cerr <<
1628  "ERROR: G4VisCommandsViewerPan::SetNewValue: no current viewer."
1629  << G4endl;
1630  }
1631  return;
1632  }
1633 
1634  G4ViewParameters vp = currentViewer->GetViewParameters();
1635 
1636  if (command == fpCommandPan) {
1639  }
1640  else if (command == fpCommandPanTo) {
1643  }
1644 
1645  if (verbosity >= G4VisManager::confirmations) {
1646  G4cout << "Current target point now " << vp.GetCurrentTargetPoint()
1647  << G4endl;
1648  }
1649 
1650  SetViewParameters(currentViewer, vp);
1651 }
1652 
1654 
1656  G4bool omitable, currentAsDefault;
1657  fpCommand = new G4UIcmdWithAString ("/vis/viewer/rebuild", this);
1658  fpCommand -> SetGuidance ("Forces rebuild of graphical database.");
1659  fpCommand -> SetGuidance
1660  ("By default, acts on current viewer. \"/vis/viewer/list\""
1661  "\nto see possible viewers. Viewer becomes current.");
1662  fpCommand -> SetParameterName ("viewer-name",
1663  omitable = true,
1664  currentAsDefault = true);
1665 }
1666 
1668  delete fpCommand;
1669 }
1670 
1672  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
1673  if (viewer) {
1674  return viewer -> GetName ();
1675  }
1676  else {
1677  return "none";
1678  }
1679 }
1680 
1682 
1684 
1685  G4String& rebuildName = newValue;
1686 
1687  G4VViewer* viewer = fpVisManager -> GetViewer (rebuildName);
1688  if (!viewer) {
1689  if (verbosity >= G4VisManager::errors) {
1690  G4cerr << "ERROR: Viewer \"" << rebuildName
1691  << "\" not found - \"/vis/viewer/list\" to see possibilities."
1692  << G4endl;
1693  }
1694  return;
1695  }
1696 
1697  G4VSceneHandler* sceneHandler = viewer->GetSceneHandler();
1698  if (!sceneHandler) {
1699  if (verbosity >= G4VisManager::errors) {
1700  G4cerr << "ERROR: Viewer \"" << viewer->GetName() << "\"" <<
1701  " has no scene handler - report serious bug."
1702  << G4endl;
1703  }
1704  return;
1705  }
1706 
1707  sceneHandler->ClearTransientStore();
1708  viewer->NeedKernelVisit();
1709  viewer->SetView();
1710  viewer->ClearView();
1711  viewer->DrawView();
1712 
1713  // Check auto-refresh and print confirmations.
1714  RefreshIfRequired(viewer);
1715 }
1716 
1718 
1720  G4bool omitable, currentAsDefault;
1721  fpCommand = new G4UIcmdWithAString ("/vis/viewer/refresh", this);
1722  fpCommand -> SetGuidance
1723  ("Refreshes viewer.");
1724  fpCommand -> SetGuidance
1725  ("By default, acts on current viewer. \"/vis/viewer/list\""
1726  "\nto see possible viewers. Viewer becomes current.");
1727  fpCommand -> SetParameterName ("viewer-name",
1728  omitable = true,
1729  currentAsDefault = true);
1730 }
1731 
1733  delete fpCommand;
1734 }
1735 
1737  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
1738  return viewer ? viewer -> GetName () : G4String("none");
1739 }
1740 
1742 
1744  G4bool warn(verbosity >= G4VisManager::warnings);
1745 
1746  G4String& refreshName = newValue;
1747  G4VViewer* viewer = fpVisManager -> GetViewer (refreshName);
1748  if (!viewer) {
1749  if (verbosity >= G4VisManager::errors) {
1750  G4cerr << "ERROR: Viewer \"" << refreshName << "\"" <<
1751  " not found - \"/vis/viewer/list\"\n to see possibilities."
1752  << G4endl;
1753  }
1754  return;
1755  }
1756 
1757  G4VSceneHandler* sceneHandler = viewer->GetSceneHandler();
1758  if (!sceneHandler) {
1759  if (verbosity >= G4VisManager::errors) {
1760  G4cerr << "ERROR: Viewer \"" << refreshName << "\"" <<
1761  " has no scene handler - report serious bug."
1762  << G4endl;
1763  }
1764  return;
1765  }
1766 
1767  G4Scene* scene = sceneHandler->GetScene();
1768  if (!scene) {
1769  if (verbosity >= G4VisManager::confirmations) {
1770  G4cout << "NOTE: SceneHandler \"" << sceneHandler->GetName()
1771  << "\", to which viewer \"" << refreshName << "\"" <<
1772  "\n is attached, has no scene - \"/vis/scene/create\" and"
1773  " \"/vis/sceneHandler/attach\""
1774  "\n (or use compound command \"/vis/drawVolume\")."
1775  << G4endl;
1776  }
1777  return;
1778  }
1779  if (scene->GetRunDurationModelList().empty()) {
1780  G4bool successful = scene -> AddWorldIfEmpty (warn);
1781  if (!successful) {
1782  if (verbosity >= G4VisManager::warnings) {
1783  G4cout <<
1784  "WARNING: Scene is empty. Perhaps no geometry exists."
1785  "\n Try /run/initialize."
1786  << G4endl;
1787  }
1788  return;
1789  }
1790  // Scene has changed. CheckSceneAndNotifyHandlers issues
1791  // /vis/scene/notifyHandlers, which does a refresh anyway, so the
1792  // ordinary refresh becomes part of the else phrase...
1794  } else {
1795  if (verbosity >= G4VisManager::confirmations) {
1796  G4cout << "Refreshing viewer \"" << viewer -> GetName () << "\"..."
1797  << G4endl;
1798  }
1799  viewer -> SetView ();
1800  viewer -> ClearView ();
1801  viewer -> DrawView ();
1802  if (verbosity >= G4VisManager::confirmations) {
1803  G4cout << "Viewer \"" << viewer -> GetName () << "\"" << " refreshed."
1804  "\n (You might also need \"/vis/viewer/update\".)" << G4endl;
1805  }
1806  }
1807 }
1808 
1810 
1812  G4bool omitable, currentAsDefault;
1813  fpCommand = new G4UIcmdWithAString ("/vis/viewer/reset", this);
1814  fpCommand -> SetGuidance ("Resets viewer.");
1815  fpCommand -> SetGuidance
1816  ("By default, acts on current viewer. \"/vis/viewer/list\""
1817  "\nto see possible viewers. Viewer becomes current.");
1818  fpCommand -> SetParameterName ("viewer-name",
1819  omitable = true,
1820  currentAsDefault = true);
1821 }
1822 
1824  delete fpCommand;
1825 }
1826 
1828  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
1829  if (viewer) {
1830  return viewer -> GetName ();
1831  }
1832  else {
1833  return "none";
1834  }
1835 }
1836 
1838 
1840 
1841  G4String& resetName = newValue;
1842  G4VViewer* viewer = fpVisManager -> GetViewer (resetName);
1843  if (!viewer) {
1844  if (verbosity >= G4VisManager::errors) {
1845  G4cerr << "ERROR: Viewer \"" << resetName
1846  << "\" not found - \"/vis/viewer/list\" to see possibilities."
1847  << G4endl;
1848  }
1849  return;
1850  }
1851 
1852  viewer->ResetView();
1853  RefreshIfRequired(viewer);
1854 }
1855 
1857 
1859  G4bool omitable;
1860  fpCommand = new G4UIcmdWithAString ("/vis/viewer/save", this);
1861  fpCommand -> SetGuidance
1862  ("Write commands that define the current view to file.");
1863  fpCommand -> SetGuidance
1864  ("Read them back into the same or any viewer with \"/control/execute\".");
1865  fpCommand -> SetGuidance
1866  ("If the filename is omitted the view is saved to a file "
1867  "\"g4_nn.g4view\", where nn is a sequential two-digit number.");
1868  fpCommand -> SetGuidance
1869  ("If the filename is \"-\", the data are written to G4cout.");
1870  fpCommand -> SetGuidance
1871  ("If you are wanting to save views for future interpolation a recommended "
1872  "procedure is: save views to \"g4_nn.g4view\", as above, then move the files "
1873  "into a sub-directory, say, \"views\", then interpolate with"
1874  "\"/vis/viewer/interpolate views/\" (note the trailing \'/\').");
1875  fpCommand -> SetParameterName ("filename", omitable = true);
1876  fpCommand -> SetDefaultValue ("");
1877 }
1878 
1880  delete fpCommand;
1881 }
1882 
1885  return "";
1886 }
1887 
1888 namespace {
1889  void WriteCommands
1890  (std::ostream& os,
1891  const G4ViewParameters& vp,
1892  const G4Point3D& stp) // Standard Target Point
1893  {
1894  os
1895  << vp.CameraAndLightingCommands(stp)
1896  << vp.DrawingStyleCommands()
1897  << vp.SceneModifyingCommands()
1898  << vp.TouchableCommands()
1899  << vp.TimeWindowCommands()
1900  << std::endl;
1901  }
1902 }
1903 
1905 
1907 
1908  const G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
1909  if (!currentViewer) {
1910  if (verbosity >= G4VisManager::errors) {
1911  G4cerr <<
1912  "ERROR: G4VisCommandsViewerSave::SetNewValue: no current viewer."
1913  << G4endl;
1914  }
1915  return;
1916  }
1917 
1918  const G4Scene* currentScene = currentViewer->GetSceneHandler()->GetScene();
1919  if (!currentScene) {
1920  if (verbosity >= G4VisManager::errors) {
1921  G4cerr <<
1922  "ERROR: G4VisCommandsViewerSave::SetNewValue: no current scene."
1923  << G4endl;
1924  }
1925  return;
1926  }
1927 
1928  // Get view parameters and ther relevant information.
1929  G4ViewParameters vp = currentViewer->GetViewParameters();
1930  // Concatenate any private vis attributes modifiers...
1931  const std::vector<G4ModelingParameters::VisAttributesModifier>*
1932  privateVAMs = currentViewer->GetPrivateVisAttributesModifiers();
1933  if (privateVAMs) {
1934  std::vector<G4ModelingParameters::VisAttributesModifier>::const_iterator i;
1935  for (i = privateVAMs->begin(); i != privateVAMs->end(); ++i) {
1936  vp.AddVisAttributesModifier(*i);
1937  }
1938  }
1939  const G4Point3D& stp = currentScene->GetStandardTargetPoint();
1940 
1941  G4String filename = newValue;
1942 
1943  if (newValue.length() == 0) {
1944  // Null filename - generate a filename
1945  const G4int maxNoOfFiles = 100;
1946  static G4int sequenceNumber = 0;
1947  if (sequenceNumber >= maxNoOfFiles) {
1948  if (verbosity >= G4VisManager::errors) {
1949  G4cerr
1950  << "ERROR: G4VisCommandsViewerSave::SetNewValue: Maximum number, "
1951  << maxNoOfFiles
1952  << ", of files exceeded."
1953  << G4endl;
1954  }
1955  return;
1956  }
1957  std::ostringstream oss;
1958  oss << std::setw(2) << std::setfill('0') << sequenceNumber++;
1959  filename = "g4_" + oss.str() + ".g4view";
1960  }
1961 
1962  if (filename == "-") {
1963  // Write to standard output
1964  WriteCommands(G4cout,vp,stp);
1965  } else {
1966  // Write to file - but add extension if not prescribed
1967  if (!filename.contains('.')) {
1968  // No extension supplied - add .g4view
1969  filename += ".g4view";
1970  }
1971  std::ofstream ofs(filename);
1972  if (!ofs) {
1973  if (verbosity >= G4VisManager::errors) {
1974  G4cerr <<
1975  "ERROR: G4VisCommandsViewerSave::SetNewValue: Trouble opening file \""
1976  << filename << "\"."
1977  << G4endl;
1978  }
1979  ofs.close();
1980  return;
1981  }
1982  WriteCommands(ofs,vp,stp);
1983  ofs.close();
1984  }
1985 
1986  if (verbosity >= G4VisManager::warnings) {
1987  G4cout << "Viewer \"" << currentViewer -> GetName ()
1988  << "\"" << " saved to ";
1989  if (filename == "-") {
1990  G4cout << "G4cout.";
1991  } else {
1992  G4cout << "file \'" << filename << "\"." <<
1993  "\n Read the view back into this or any viewer with"
1994  "\n \"/control/execute " << filename << "\" or use"
1995  "\n \"/vis/viewer/interpolate\" if you have several saved files -"
1996  "\n see \"help /vis/viewer/interpolate\" for guidance.";
1997  }
1998  G4cout << G4endl;
1999  }
2000 }
2001 
2003 
2005  fScaleMultiplier (G4Vector3D (1., 1., 1.)),
2006  fScaleTo (G4Vector3D (1., 1., 1.))
2007 {
2008  G4bool omitable, currentAsDefault;
2009 
2011  ("/vis/viewer/scale", this);
2012  fpCommandScale -> SetGuidance ("Incremental (non-uniform) scaling.");
2013  fpCommandScale -> SetGuidance
2014  ("Multiplies components of current scaling by components of this factor."
2015  "\n Scales (x,y,z) by corresponding components of the resulting factor.");
2016  fpCommandScale -> SetGuidance
2017  ("");
2018  fpCommandScale -> SetParameterName
2019  ("x-scale-multiplier","y-scale-multiplier","z-scale-multiplier",
2020  omitable=true, currentAsDefault=true);
2021 
2023  ("/vis/viewer/scaleTo", this);
2024  fpCommandScaleTo -> SetGuidance ("Absolute (non-uniform) scaling.");
2025  fpCommandScaleTo -> SetGuidance
2026  ("Scales (x,y,z) by corresponding components of this factor.");
2027  fpCommandScaleTo -> SetParameterName
2028  ("x-scale-factor","y-scale-factor","z-scale-factor",
2029  omitable=true, currentAsDefault=true);
2030 }
2031 
2033  delete fpCommandScale;
2034  delete fpCommandScaleTo;
2035 }
2036 
2038  G4String currentValue;
2039  if (command == fpCommandScale) {
2041  }
2042  else if (command == fpCommandScaleTo) {
2044  }
2045  return currentValue;
2046 }
2047 
2049  G4String newValue) {
2050 
2051 
2053 
2054  G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
2055  if (!currentViewer) {
2056  if (verbosity >= G4VisManager::errors) {
2057  G4cerr <<
2058  "ERROR: G4VisCommandsViewerScale::SetNewValue: no current viewer."
2059  << G4endl;
2060  }
2061  return;
2062  }
2063 
2064  G4ViewParameters vp = currentViewer->GetViewParameters();
2065 
2066  if (command == fpCommandScale) {
2069  }
2070  else if (command == fpCommandScaleTo) {
2073  }
2074 
2075  if (verbosity >= G4VisManager::confirmations) {
2076  G4cout << "Scale factor changed to " << vp.GetScaleFactor() << G4endl;
2077  }
2078 
2079  SetViewParameters(currentViewer, vp);
2080 }
2081 
2083 
2085  G4bool omitable;
2086  fpCommand = new G4UIcmdWithAString ("/vis/viewer/select", this);
2087  fpCommand -> SetGuidance ("Selects viewer.");
2088  fpCommand -> SetGuidance
2089  ("Specify viewer by name. \"/vis/viewer/list\" to see possible viewers.");
2090  fpCommand -> SetParameterName ("viewer-name", omitable = false);
2091 }
2092 
2094  delete fpCommand;
2095 }
2096 
2098  return "";
2099 }
2100 
2102 
2104 
2105  G4String& selectName = newValue;
2106  G4VViewer* viewer = fpVisManager -> GetViewer (selectName);
2107 
2108  if (!viewer) {
2109  if (verbosity >= G4VisManager::errors) {
2110  G4cerr << "ERROR: Viewer \"" << selectName << "\"";
2111  G4cerr << " not found - \"/vis/viewer/list\""
2112  "\n to see possibilities."
2113  << G4endl;
2114  }
2115  return;
2116  }
2117 
2118  if (viewer == fpVisManager -> GetCurrentViewer ()) {
2119  if (verbosity >= G4VisManager::warnings) {
2120  G4cout << "WARNING: Viewer \"" << viewer -> GetName () << "\""
2121  << " already selected." << G4endl;
2122  }
2123  return;
2124  }
2125 
2126  // Set pointers, call SetView and print confirmation.
2127  fpVisManager -> SetCurrentViewer (viewer);
2128 
2129  RefreshIfRequired(viewer);
2130 }
2131 
2133 
2135  G4bool omitable, currentAsDefault;
2136  fpCommand = new G4UIcmdWithAString ("/vis/viewer/update", this);
2137  fpCommand -> SetGuidance
2138  ("Triggers graphical database post-processing for viewers"
2139  "\nusing that technique.");
2140  fpCommand -> SetGuidance
2141  ("For such viewers the view only becomes visible with this command."
2142  "\nBy default, acts on current viewer. \"/vis/viewer/list\""
2143  "\nto see possible viewers. Viewer becomes current.");
2144  fpCommand -> SetParameterName ("viewer-name",
2145  omitable = true,
2146  currentAsDefault = true);
2147 }
2148 
2150  delete fpCommand;
2151 }
2152 
2154  G4VViewer* viewer = fpVisManager -> GetCurrentViewer ();
2155  if (viewer) {
2156  return viewer -> GetName ();
2157  }
2158  else {
2159  return "none";
2160  }
2161 }
2162 
2164 
2166 
2167  G4String& updateName = newValue;
2168 
2169  G4VViewer* viewer = fpVisManager -> GetViewer (updateName);
2170  if (!viewer) {
2171  if (verbosity >= G4VisManager::errors) {
2172  G4cout <<
2173  "WARNING: command \"/vis/viewer/update\" could not be applied: no current viewer."
2174  << G4endl;
2175  }
2176  return;
2177  }
2178 
2179  G4VSceneHandler* sceneHandler = viewer->GetSceneHandler();
2180  if (!sceneHandler) {
2181  if (verbosity >= G4VisManager::errors) {
2182  G4cerr << "ERROR: Viewer \"" << updateName << "\"" <<
2183  " has no scene handler - report serious bug."
2184  << G4endl;
2185  }
2186  return;
2187  }
2188 
2189  G4Scene* scene = sceneHandler->GetScene();
2190  if (!scene) {
2191  if (verbosity >= G4VisManager::confirmations) {
2192  G4cout << "NOTE: SceneHandler \"" << sceneHandler->GetName()
2193  << "\", to which viewer \"" << updateName << "\"" <<
2194  "\n is attached, has no scene - \"/vis/scene/create\" and"
2195  " \"/vis/sceneHandler/attach\""
2196  "\n (or use compound command \"/vis/drawVolume\")."
2197  << G4endl;
2198  }
2199  return;
2200  }
2201 
2202  if (verbosity >= G4VisManager::confirmations) {
2203  G4cout << "Viewer \"" << viewer -> GetName () << "\"";
2204  G4cout << " post-processing triggered." << G4endl;
2205  }
2206  viewer -> ShowView ();
2207  // Assume future need to "refresh" transients...
2208  sceneHandler -> SetMarkForClearingTransientStore(true);
2209 }
2210 
2212 
2214  fZoomMultiplier (1.),
2215  fZoomTo (1.)
2216 {
2217  G4bool omitable, currentAsDefault;
2218 
2220  ("/vis/viewer/zoom", this);
2221  fpCommandZoom -> SetGuidance ("Incremental zoom.");
2222  fpCommandZoom -> SetGuidance
2223  ("Multiplies current magnification by this factor.");
2224  fpCommandZoom -> SetParameterName("multiplier",
2225  omitable=true,
2226  currentAsDefault=true);
2227 
2229  ("/vis/viewer/zoomTo", this);
2230  fpCommandZoomTo -> SetGuidance ("Absolute zoom.");
2231  fpCommandZoomTo -> SetGuidance
2232  ("Magnifies standard magnification by this factor.");
2233  fpCommandZoomTo -> SetParameterName("factor",
2234  omitable=true,
2235  currentAsDefault=true);
2236 }
2237 
2239  delete fpCommandZoom;
2240  delete fpCommandZoomTo;
2241 }
2242 
2244  G4String currentValue;
2245  if (command == fpCommandZoom) {
2247  }
2248  else if (command == fpCommandZoomTo) {
2249  currentValue = fpCommandZoomTo->ConvertToString(fZoomTo);
2250  }
2251  return currentValue;
2252 }
2253 
2255  G4String newValue) {
2256 
2257 
2259 
2260  G4VViewer* currentViewer = fpVisManager->GetCurrentViewer();
2261  if (!currentViewer) {
2262  if (verbosity >= G4VisManager::errors) {
2263  G4cerr <<
2264  "ERROR: G4VisCommandsViewerZoom::SetNewValue: no current viewer."
2265  << G4endl;
2266  }
2267  return;
2268  }
2269 
2270  G4ViewParameters vp = currentViewer->GetViewParameters();
2271 
2272  if (command == fpCommandZoom) {
2275  }
2276  else if (command == fpCommandZoomTo) {
2278  vp.SetZoomFactor(fZoomTo);
2279  }
2280 
2281  if (verbosity >= G4VisManager::confirmations) {
2282  G4cout << "Zoom factor changed to " << vp.GetZoomFactor() << G4endl;
2283  }
2284 
2285  SetViewParameters(currentViewer, vp);
2286 }