source: trunk/source/visualization/management/src/G4VisCommandsSceneAdd.cc @ 1288

Last change on this file since 1288 was 1288, checked in by garnier, 14 years ago

update from CVS

  • Property svn:mime-type set to text/cpp
File size: 68.1 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4VisCommandsSceneAdd.cc,v 1.81 2010/06/01 16:08:15 allison Exp $
28// GEANT4 tag $Name:  $
29// /vis/scene commands - John Allison  9th August 1998
30
31#include "G4VisCommandsSceneAdd.hh"
32
33#include "G4TransportationManager.hh"
34#include "G4LogicalVolumeStore.hh"
35#include "G4PhysicalVolumeModel.hh"
36#include "G4LogicalVolumeModel.hh"
37#include "G4ModelingParameters.hh"
38#include "G4HitsModel.hh"
39#include "G4DigiModel.hh"
40#include "G4PSHitsModel.hh"
41#include "G4TrajectoriesModel.hh"
42#include "G4ScaleModel.hh"
43#include "G4TextModel.hh"
44#include "G4AxesModel.hh"
45#include "G4PhysicalVolumeSearchScene.hh"
46#include "G4VGlobalFastSimulationManager.hh"
47#include "G4ParticleTable.hh"
48#include "G4ParticleDefinition.hh"
49#include "G4FlavoredParallelWorldModel.hh"
50#include "G4ApplicationState.hh"
51#include "G4VUserVisAction.hh"
52#include "G4CallbackModel.hh"
53#include "G4UnionSolid.hh"
54#include "G4SubtractionSolid.hh"
55#include "G4Polyhedron.hh"
56#include "G4UImanager.hh"
57#include "G4UIcommand.hh"
58#include "G4UIcmdWithAString.hh"
59#include "G4UIcmdWithoutParameter.hh"
60#include "G4Tokenizer.hh"
61#include "G4RunManager.hh"
62#include "G4StateManager.hh"
63#include "G4Run.hh"
64#include "G4Event.hh"
65#include "G4IdentityTrajectoryFilter.hh"
66#include "G4TransportationManager.hh"
67#include "G4PropagatorInField.hh"
68#include "G4RichTrajectory.hh"
69#include "G4RichTrajectoryPoint.hh"
70#include "G4AttDef.hh"
71#include "G4ios.hh"
72#include <sstream>
73
74// Local function with some frequently used error printing...
75static void G4VisCommandsSceneAddUnsuccessful
76(G4VisManager::Verbosity verbosity) {
77  if (verbosity >= G4VisManager::warnings) {
78    G4cout <<
79      "WARNING: For some reason, possibly mentioned above, it has not been"
80      "\n  possible to add to the scene."
81           << G4endl;
82  }
83}
84
85////////////// /vis/scene/add/axes //////////////////////////////////
86
87G4VisCommandSceneAddAxes::G4VisCommandSceneAddAxes () {
88  G4bool omitable;
89  fpCommand = new G4UIcommand ("/vis/scene/add/axes", this);
90  fpCommand -> SetGuidance ("Add axes.");
91  fpCommand -> SetGuidance
92    ("Draws axes at (x0, y0, z0) of given length.");
93  G4UIparameter* parameter;
94  parameter =  new G4UIparameter ("x0", 'd', omitable = true);
95  parameter->SetDefaultValue (0.);
96  fpCommand->SetParameter (parameter);
97  parameter =  new G4UIparameter ("y0", 'd', omitable = true);
98  parameter->SetDefaultValue (0.);
99  fpCommand->SetParameter (parameter);
100  parameter =  new G4UIparameter ("z0", 'd', omitable = true);
101  parameter->SetDefaultValue (0.);
102  fpCommand->SetParameter (parameter);
103  parameter =  new G4UIparameter ("length", 'd', omitable = true);
104  parameter->SetDefaultValue (1.);
105  fpCommand->SetParameter (parameter);
106  parameter =  new G4UIparameter ("unit", 's', omitable = true);
107  parameter->SetDefaultValue  ("m");
108  fpCommand->SetParameter     (parameter);
109}
110
111G4VisCommandSceneAddAxes::~G4VisCommandSceneAddAxes () {
112  delete fpCommand;
113}
114
115G4String G4VisCommandSceneAddAxes::GetCurrentValue (G4UIcommand*) {
116  return "";
117}
118
119void G4VisCommandSceneAddAxes::SetNewValue (G4UIcommand*, G4String newValue) {
120
121  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
122  G4bool warn(verbosity >= G4VisManager::warnings);
123
124  G4Scene* pScene = fpVisManager->GetCurrentScene();
125  if (!pScene) {
126    if (verbosity >= G4VisManager::errors) {
127      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
128    }
129    return;
130  }
131
132  G4String unitString;
133  G4double x0, y0, z0, length;
134  std::istringstream is (newValue);
135  is >> x0 >> y0 >> z0 >> length >> unitString;
136
137  G4double unit = G4UIcommand::ValueOf(unitString);
138  x0 *= unit; y0 *= unit; z0 *= unit; length *= unit;
139
140  G4VModel* model = new G4AxesModel(x0, y0, z0, length);
141
142  model->SetExtent(G4VisExtent(x0 - length, x0 + length,
143                               y0 - length, y0 + length,
144                               z0 - length, z0 + length));
145  // This extent gets "added" to existing scene extent in
146  // AddRunDurationModel below.
147
148  const G4String& currentSceneName = pScene -> GetName ();
149  G4bool successful = pScene -> AddRunDurationModel (model, warn);
150  if (successful) {
151    if (verbosity >= G4VisManager::confirmations) {
152      G4cout << "Axes have been added to scene \"" << currentSceneName << "\"."
153             << G4endl;
154    }
155  }
156  else G4VisCommandsSceneAddUnsuccessful(verbosity);
157  UpdateVisManagerScene (currentSceneName);
158}
159
160
161////////////// /vis/scene/add/digis ///////////////////////////////////////
162
163G4VisCommandSceneAddDigis::G4VisCommandSceneAddDigis () {
164  fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/add/digitisations", this);
165  fpCommand -> SetGuidance ("Adds digis to current scene.");
166  fpCommand -> SetGuidance
167    ("Digis are drawn at end of event when the scene in which"
168     "\nthey are added is current.");
169
170  fpCommandUS = new G4UIcmdWithoutParameter ("/vis/scene/add/digitizations", this);
171  fpCommandUS -> SetGuidance ("Adds digis to current scene.");
172  fpCommandUS -> SetGuidance
173    ("Digis are drawn at end of event when the scene in which"
174     "\nthey are added is current.");
175}
176
177G4VisCommandSceneAddDigis::~G4VisCommandSceneAddDigis () {
178  delete fpCommandUS;
179  delete fpCommand;
180}
181
182G4String G4VisCommandSceneAddDigis::GetCurrentValue (G4UIcommand*) {
183  return "";
184}
185
186void G4VisCommandSceneAddDigis::SetNewValue (G4UIcommand*, G4String) {
187
188  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
189  G4bool warn(verbosity >= G4VisManager::warnings);
190
191  G4Scene* pScene = fpVisManager->GetCurrentScene();
192  if (!pScene) {
193    if (verbosity >= G4VisManager::errors) {
194      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
195    }
196    return;
197  }
198
199  G4DigiModel* model = new G4DigiModel;
200  const G4String& currentSceneName = pScene -> GetName ();
201  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
202  if (successful) {
203    if (verbosity >= G4VisManager::confirmations) {
204      G4cout << "Digis will be drawn in scene \""
205             << currentSceneName << "\"."
206             << G4endl;
207    }
208  }
209  else G4VisCommandsSceneAddUnsuccessful(verbosity);
210  UpdateVisManagerScene (currentSceneName);
211}
212
213////////////// /vis/scene/add/eventID ///////////////////////////////////////
214
215G4VisCommandSceneAddEventID::G4VisCommandSceneAddEventID () {
216  G4bool omitable;
217  fpCommand = new G4UIcommand ("/vis/scene/add/eventID", this);
218  fpCommand -> SetGuidance ("Adds eventID to current scene.");
219  fpCommand -> SetGuidance
220    ("Run and event numbers are drawn at end of event or run when"
221     "\n the scene in which they are added is current.");
222  G4UIparameter* parameter;
223  parameter = new G4UIparameter ("size", 'i', omitable = true);
224  parameter -> SetGuidance ("Screen size of text in pixels.");
225  parameter -> SetDefaultValue (18);
226  fpCommand -> SetParameter (parameter);
227  parameter = new G4UIparameter ("x-position", 'd', omitable = true);
228  parameter -> SetGuidance ("x screen position in range -1 < x < 1.");
229  parameter -> SetDefaultValue (-0.95);
230  fpCommand -> SetParameter (parameter);
231  parameter = new G4UIparameter ("y-position", 'd', omitable = true);
232  parameter -> SetGuidance ("y screen position in range -1 < y < 1.");
233  parameter -> SetDefaultValue (0.9);
234  fpCommand -> SetParameter (parameter);
235}
236
237G4VisCommandSceneAddEventID::~G4VisCommandSceneAddEventID () {
238  delete fpCommand;
239}
240
241G4String G4VisCommandSceneAddEventID::GetCurrentValue (G4UIcommand*) {
242  return "";
243}
244
245void G4VisCommandSceneAddEventID::SetNewValue (G4UIcommand*, G4String newValue)
246{
247  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
248  G4bool warn(verbosity >= G4VisManager::warnings);
249
250  G4Scene* pScene = fpVisManager->GetCurrentScene();
251  if (!pScene) {
252    if (verbosity >= G4VisManager::errors) {
253      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
254    }
255    return;
256  }
257
258  G4int size;
259  G4double x, y;
260  std::istringstream is(newValue);
261  is >> size >> x >> y;
262
263  EventID* eventID = new EventID(fpVisManager, size, x, y);
264  G4VModel* model =
265    new G4CallbackModel<G4VisCommandSceneAddEventID::EventID>(eventID);
266  model->SetGlobalDescription("EventID");
267  model->SetGlobalTag("EventID");
268  const G4String& currentSceneName = pScene -> GetName ();
269  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
270  if (successful) {
271    if (verbosity >= G4VisManager::confirmations) {
272      G4cout << "EventID will be drawn in scene \""
273             << currentSceneName << "\"."
274             << G4endl;
275    }
276  }
277  else G4VisCommandsSceneAddUnsuccessful(verbosity);
278  UpdateVisManagerScene (currentSceneName);
279}
280
281void G4VisCommandSceneAddEventID::EventID::operator()
282  (G4VGraphicsScene& sceneHandler, const G4Transform3D&)
283{
284  const G4Run* currentRun = 0;
285  G4RunManager* runManager = G4RunManager::GetRunManager();
286  if (runManager) currentRun = runManager->GetCurrentRun();
287
288  G4VModel* model = fpVisManager->GetCurrentSceneHandler()->GetModel();
289  const G4ModelingParameters* mp = 0;
290  const G4Event* currentEvent = 0;
291  if (model) {
292   mp = model->GetModelingParameters();
293   currentEvent = mp->GetEvent();
294  } else {
295    G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
296    if (verbosity >= G4VisManager::errors) {
297      G4cout << "ERROR: No model defined for this SceneHandler : "
298             << fpVisManager->GetCurrentSceneHandler()->GetName()
299             << G4endl;
300    }
301  }
302  if (currentRun && currentEvent) {
303    G4int runID = currentRun->GetRunID();
304    G4int eventID = currentEvent->GetEventID();
305    std::ostringstream oss;
306    if (fpVisManager->GetCurrentScene()->GetRefreshAtEndOfEvent()) {
307      oss << "Run " << runID << " Event " << eventID;
308    } else {
309      G4int nEvents = 0;
310      G4StateManager* stateManager = G4StateManager::GetStateManager();
311      G4ApplicationState state = stateManager->GetCurrentState();
312      if (state == G4State_EventProc) {
313        nEvents = currentRun->GetNumberOfEventToBeProcessed();
314      } else {
315        const std::vector<const G4Event*>* events =
316          currentRun? currentRun->GetEventVector(): 0;
317        if (events) nEvents = events->size();
318      }
319      if (eventID < nEvents - 1) return;  // Not last event.
320      else {
321        oss << "Run " << runID << " (" << nEvents << " accumulated events)";
322      }
323    }
324    G4Text text(oss.str(), G4Point3D(fX, fY, 0.));
325    text.SetScreenSize(fSize);
326    G4VisAttributes textAtts(G4Colour(0.,1.,1));
327    text.SetVisAttributes(textAtts);
328    sceneHandler.BeginPrimitives2D();
329    sceneHandler.AddPrimitive(text);
330    sceneHandler.EndPrimitives2D();
331  }
332}
333
334////////////// /vis/scene/add/ghosts ///////////////////////////////////////
335
336G4VisCommandSceneAddGhosts::G4VisCommandSceneAddGhosts () {
337  G4bool omitable;
338  fpCommand = new G4UIcmdWithAString ("/vis/scene/add/ghosts", this);
339  fpCommand -> SetGuidance
340    ("Adds ghost volumes (G4FlavoredParallelWorld) to the current scene.");
341  fpCommand -> SetGuidance ("Selects by particle.");
342  fpCommand -> SetParameterName ("particle", omitable = true);
343  fpCommand -> SetDefaultValue ("all");
344}
345
346G4VisCommandSceneAddGhosts::~G4VisCommandSceneAddGhosts () {
347  delete fpCommand;
348}
349
350G4String G4VisCommandSceneAddGhosts::GetCurrentValue (G4UIcommand*) {
351  return "";
352}
353
354void G4VisCommandSceneAddGhosts::SetNewValue(G4UIcommand*, G4String newValue) {
355
356  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
357  G4bool warn(verbosity >= G4VisManager::warnings);
358
359  G4Scene* pScene = fpVisManager->GetCurrentScene();
360  if (!pScene) {
361    if (verbosity >= G4VisManager::errors) {
362      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
363    }
364    return;
365  }
366  const G4String& currentSceneName = pScene -> GetName ();
367
368  // Gets the G4GlobalFastSimulationManager pointer if any.
369  G4VGlobalFastSimulationManager* theGlobalFastSimulationManager;
370  if(!(theGlobalFastSimulationManager =
371       G4VGlobalFastSimulationManager::GetConcreteInstance ())){
372    if (verbosity >= G4VisManager::errors) {
373      G4cout << "ERROR: no G4GlobalFastSimulationManager" << G4endl;
374    }
375    return;
376  }
377 
378  // Gets the G4ParticleTable pointer.
379  G4ParticleTable* theParticleTable=G4ParticleTable::GetParticleTable();
380 
381  // If "all" (the default) loops on all known particles
382  if(newValue=="all")
383    {
384      G4VFlavoredParallelWorld* CurrentFlavoredWorld = 0;
385      G4bool successful = false;
386      for (G4int iParticle=0; iParticle<theParticleTable->entries();
387           iParticle++)
388        {
389          CurrentFlavoredWorld = theGlobalFastSimulationManager->
390            GetFlavoredWorldForThis(theParticleTable->GetParticle(iParticle));
391         
392          if(CurrentFlavoredWorld)
393            successful = successful || pScene ->
394              AddRunDurationModel(new G4FlavoredParallelWorldModel
395                                  (CurrentFlavoredWorld), warn);
396        }
397      if (successful)
398        {
399          if (verbosity >= G4VisManager::confirmations)
400            G4cout << "Ghosts have been added to scene \""
401                   << currentSceneName << "\"."
402                   << G4endl;
403          UpdateVisManagerScene (currentSceneName);
404        }
405      else
406        {
407          G4cout << "ERROR: There are no ghosts."<<G4endl;
408          G4VisCommandsSceneAddUnsuccessful(verbosity);
409        }
410      return;
411    }
412 
413  // Given a particle name looks just for the concerned Ghosts, if any.
414  G4ParticleDefinition* currentParticle =
415    theParticleTable->FindParticle(newValue);
416 
417  if (currentParticle == NULL)
418    {
419      if (verbosity >= G4VisManager::errors)
420        G4cout << "ERROR: \"" << newValue
421               << "\": not found this particle name!" << G4endl;
422      return;
423    }
424 
425  G4VFlavoredParallelWorld* worldForThis =
426    theGlobalFastSimulationManager->GetFlavoredWorldForThis(currentParticle);
427  if(worldForThis)
428    {
429      G4bool successful = pScene -> AddRunDurationModel
430        (new G4FlavoredParallelWorldModel (worldForThis), warn);
431      if (successful) {
432        if (verbosity >= G4VisManager::confirmations)
433          G4cout << "Ghosts have been added to scene \""
434                 << currentSceneName << "\"."
435                 << G4endl;
436        UpdateVisManagerScene (currentSceneName);
437      }
438    }
439  else
440    if (verbosity >= G4VisManager::errors)
441      {
442        G4cout << "ERROR: There are no ghosts for \""<<newValue<<"\""<<G4endl;
443        G4VisCommandsSceneAddUnsuccessful(verbosity);
444      }
445}
446
447
448////////////// /vis/scene/add/hits ///////////////////////////////////////
449
450G4VisCommandSceneAddHits::G4VisCommandSceneAddHits () {
451  fpCommand = new G4UIcmdWithoutParameter ("/vis/scene/add/hits", this);
452  fpCommand -> SetGuidance ("Adds hits to current scene.");
453  fpCommand -> SetGuidance
454    ("Hits are drawn at end of event when the scene in which"
455     "\nthey are added is current.");
456}
457
458G4VisCommandSceneAddHits::~G4VisCommandSceneAddHits () {
459  delete fpCommand;
460}
461
462G4String G4VisCommandSceneAddHits::GetCurrentValue (G4UIcommand*) {
463  return "";
464}
465
466void G4VisCommandSceneAddHits::SetNewValue (G4UIcommand*, G4String) {
467
468  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
469  G4bool warn(verbosity >= G4VisManager::warnings);
470
471  G4Scene* pScene = fpVisManager->GetCurrentScene();
472  if (!pScene) {
473    if (verbosity >= G4VisManager::errors) {
474      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
475    }
476    return;
477  }
478
479  G4HitsModel* model = new G4HitsModel;
480  const G4String& currentSceneName = pScene -> GetName ();
481  G4bool successful = pScene -> AddEndOfEventModel (model, warn);
482  if (successful) {
483    if (verbosity >= G4VisManager::confirmations) {
484      G4cout << "Hits will be drawn in scene \""
485             << currentSceneName << "\"."
486             << G4endl;
487    }
488  }
489  else G4VisCommandsSceneAddUnsuccessful(verbosity);
490  UpdateVisManagerScene (currentSceneName);
491}
492
493////////////// /vis/scene/add/logicalVolume //////////////////////////////////
494
495G4VisCommandSceneAddLogicalVolume::G4VisCommandSceneAddLogicalVolume () {
496  G4bool omitable;
497  fpCommand = new G4UIcommand ("/vis/scene/add/logicalVolume", this);
498  fpCommand -> SetGuidance ("Adds a logical volume to the current scene,");
499  fpCommand -> SetGuidance
500    ("Shows boolean components (if any), voxels (if any) and readout geometry"
501     "\n(if any).  Note: voxels are not constructed until start of run -"
502     "\n \"/run/beamOn\".");
503  G4UIparameter* parameter;
504  parameter = new G4UIparameter ("logical-volume-name", 's', omitable = false);
505  fpCommand -> SetParameter (parameter);
506  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
507  parameter -> SetGuidance ("Depth of descent of geometry hierarchy.");
508  parameter -> SetDefaultValue (1);
509  fpCommand -> SetParameter (parameter);
510  parameter = new G4UIparameter ("booleans-flag", 'b', omitable = true);
511  parameter -> SetDefaultValue (true);
512  fpCommand -> SetParameter (parameter);
513  parameter = new G4UIparameter ("voxels-flag", 'b', omitable = true);
514  parameter -> SetDefaultValue (true);
515  fpCommand -> SetParameter (parameter);
516  parameter = new G4UIparameter ("readout-flag", 'b', omitable = true);
517  parameter -> SetDefaultValue (true);
518  fpCommand -> SetParameter (parameter);
519}
520
521G4VisCommandSceneAddLogicalVolume::~G4VisCommandSceneAddLogicalVolume () {
522  delete fpCommand;
523}
524
525G4String G4VisCommandSceneAddLogicalVolume::GetCurrentValue (G4UIcommand*) {
526  return "";
527}
528
529void G4VisCommandSceneAddLogicalVolume::SetNewValue (G4UIcommand*,
530                                                     G4String newValue) {
531
532  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
533  G4bool warn(verbosity >= G4VisManager::warnings);
534
535  G4Scene* pScene = fpVisManager->GetCurrentScene();
536  if (!pScene) {
537    if (verbosity >= G4VisManager::errors) {
538      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
539    }
540    return;
541  }
542
543  G4String name;
544  G4int requestedDepthOfDescent;
545  G4String booleansString, voxelsString, readoutString;
546  std::istringstream is (newValue);
547  is >> name >> requestedDepthOfDescent
548     >>  booleansString >> voxelsString >> readoutString;
549  G4bool booleans = G4UIcommand::ConvertToBool(booleansString);
550  G4bool voxels = G4UIcommand::ConvertToBool(voxelsString);
551  G4bool readout = G4UIcommand::ConvertToBool(readoutString);
552
553  G4LogicalVolumeStore *pLVStore = G4LogicalVolumeStore::GetInstance();
554  int nLV = pLVStore -> size ();
555  int iLV;
556  G4LogicalVolume* pLV = 0;
557  for (iLV = 0; iLV < nLV; iLV++ ) {
558    pLV = (*pLVStore) [iLV];
559    if (pLV -> GetName () == name) break;
560  }
561  if (iLV == nLV) {
562    if (verbosity >= G4VisManager::errors) {
563      G4cout << "ERROR: Logical volume " << name
564             << " not found in logical volume store." << G4endl;
565    }
566    return;
567  }
568
569  const std::vector<G4VModel*>& rdModelList = pScene -> GetRunDurationModelList();
570  std::vector<G4VModel*>::const_iterator i;
571  for (i = rdModelList.begin(); i != rdModelList.end(); ++i) {
572    if ((*i) -> GetGlobalDescription().find("Volume") != std::string::npos) break;
573  }
574  if (i != rdModelList.end()) {
575    if (verbosity >= G4VisManager::errors) {
576      G4cout << "There is already a volume, \""
577             << (*i) -> GetGlobalDescription()
578             << "\",\n in the run-duration model list of scene \""
579             << pScene -> GetName()
580             << "\".\n Your logical volume must be the only volume in the scene."
581             << "\n Create a new scene and try again:"
582             << "\n  /vis/specify " << name
583             << "\n or"
584             << "\n  /vis/scene/create"
585             << "\n  /vis/scene/add/logicalVolume " << name
586             << "\n  /vis/sceneHandler/attach"
587             << "\n (and also, if necessary, /vis/viewer/flush)"
588             << G4endl;
589    }
590  }
591
592  G4VModel* model = new G4LogicalVolumeModel
593    (pLV, requestedDepthOfDescent, booleans, voxels, readout);
594  const G4String& currentSceneName = pScene -> GetName ();
595  G4bool successful = pScene -> AddRunDurationModel (model, warn);
596  if (successful) {
597    if (verbosity >= G4VisManager::confirmations) {
598      G4cout << "Logical volume \"" << pLV -> GetName ()
599             << " with requested depth of descent "
600             << requestedDepthOfDescent
601             << ",\n with";
602      if (!booleans) G4cout << "out";
603      G4cout << " boolean components, with";
604      if (!voxels) G4cout << "out";
605      G4cout << " voxels and with";
606      if (!readout) G4cout << "out";
607      G4cout << " readout geometry,"
608             << "\n  has been added to scene \"" << currentSceneName << "\"."
609             << G4endl;
610    }
611  }
612  else {
613    G4VisCommandsSceneAddUnsuccessful(verbosity);
614    return;
615  }
616
617  UpdateVisManagerScene (currentSceneName);
618}
619
620
621////////////// /vis/scene/add/logo //////////////////////////////////
622
623G4VisCommandSceneAddLogo::G4VisCommandSceneAddLogo () {
624  G4bool omitable;
625  fpCommand = new G4UIcommand ("/vis/scene/add/logo", this);
626  fpCommand -> SetGuidance
627    ("Adds a G4 logo to the current scene.");
628  fpCommand -> SetGuidance
629    ("The placement, if automatic, is similar to that of scale -"
630     "\n\"help /vis/scene/add/scale\" for more information.");
631  G4UIparameter* parameter;
632  parameter = new G4UIparameter ("height", 'd', omitable = true);
633  parameter->SetDefaultValue (1.);
634  fpCommand->SetParameter (parameter);
635  parameter =  new G4UIparameter ("unit", 's', omitable = true);
636  parameter->SetDefaultValue ("m");
637  fpCommand->SetParameter (parameter);
638  parameter =  new G4UIparameter ("direction", 's', omitable = true);
639  parameter->SetGuidance ("'x', 'y' or 'z' - otherwise defaults to 'x'.");
640  parameter->SetDefaultValue ("x");
641  fpCommand->SetParameter (parameter);
642  parameter =  new G4UIparameter ("red", 'd', omitable = true);
643  parameter->SetDefaultValue (0.);
644  fpCommand->SetParameter (parameter);
645  parameter =  new G4UIparameter ("green", 'd', omitable = true);
646  parameter->SetDefaultValue (1.);
647  fpCommand->SetParameter (parameter);
648  parameter =  new G4UIparameter ("blue", 'd', omitable = true);
649  parameter->SetDefaultValue (0.);
650  fpCommand->SetParameter (parameter);
651  parameter =  new G4UIparameter ("auto|manual", 's', omitable = true);
652  parameter->SetGuidance
653    ("Automatic placement or manual placement at (xmid,ymid,zmid).");
654  parameter -> SetParameterCandidates("auto manual");
655  parameter->SetDefaultValue  ("auto");
656  fpCommand->SetParameter     (parameter);
657  parameter =  new G4UIparameter ("xmid", 'd', omitable = true);
658  parameter->SetDefaultValue (0.);
659  fpCommand->SetParameter (parameter);
660  parameter =  new G4UIparameter ("ymid", 'd', omitable = true);
661  parameter->SetDefaultValue (0.);
662  fpCommand->SetParameter (parameter);
663  parameter =  new G4UIparameter ("zmid", 'd', omitable = true);
664  parameter->SetDefaultValue (0.);
665  fpCommand->SetParameter (parameter);
666  parameter =  new G4UIparameter ("unit", 's', omitable = true);
667  parameter->SetDefaultValue ("m");
668  fpCommand->SetParameter (parameter);
669}
670
671G4VisCommandSceneAddLogo::~G4VisCommandSceneAddLogo () {
672  delete fpCommand;
673}
674
675G4String G4VisCommandSceneAddLogo::GetCurrentValue (G4UIcommand*) {
676  return "";
677}
678
679void G4VisCommandSceneAddLogo::SetNewValue (G4UIcommand*, G4String newValue) {
680
681  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
682  G4bool warn = verbosity >= G4VisManager::warnings;
683
684  G4Scene* pScene = fpVisManager->GetCurrentScene();
685  if (!pScene) {
686    if (verbosity >= G4VisManager::errors) {
687      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
688    }
689    return;
690  }
691
692  G4double userHeight, red, green, blue, xmid, ymid, zmid;
693  G4String userHeightUnit, direction, auto_manual, positionUnit;
694  std::istringstream is (newValue);
695  is >> userHeight >> userHeightUnit >> direction
696     >> red >> green >> blue
697     >> auto_manual
698     >> xmid >> ymid >> zmid >> positionUnit;
699
700  G4double height = userHeight * G4UIcommand::ValueOf(userHeightUnit);
701  G4double unit = G4UIcommand::ValueOf(positionUnit);
702  xmid *= unit; ymid *= unit; zmid *= unit;
703
704  G4Scale::Direction logoDirection (G4Scale::x);
705  if (direction(0) == 'y') logoDirection = G4Scale::y;
706  if (direction(0) == 'z') logoDirection = G4Scale::z;
707
708  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
709  // Parameters read and interpreted.
710
711  // Useful constants, etc...
712  const G4double halfHeight(height / 2.);
713  const G4double comfort(0.01);  // 0.15 seems too big.  0.05 might be better.
714  const G4double onePlusComfort(1. + comfort);
715  const G4double freeHeightFraction (1. + 2. * comfort);
716
717  const G4VisExtent& sceneExtent = pScene->GetExtent();  // Existing extent.
718  const G4double xmin = sceneExtent.GetXmin();
719  const G4double xmax = sceneExtent.GetXmax();
720  const G4double ymin = sceneExtent.GetYmin();
721  const G4double ymax = sceneExtent.GetYmax();
722  const G4double zmin = sceneExtent.GetZmin();
723  const G4double zmax = sceneExtent.GetZmax();
724
725  // Test existing extent and issue warnings...
726  G4bool worried = false;
727  if (sceneExtent.GetExtentRadius() == 0) {
728    worried = true;
729    if (verbosity >= G4VisManager::warnings) {
730      G4cout <<
731        "WARNING: Existing scene does not yet have any extent."
732        "\n  Maybe you have not yet added any geometrical object."
733             << G4endl;
734    }
735  }
736  // Test existing scene for room...
737  G4bool room = true;
738  switch (logoDirection) {
739  case G4Scale::x:
740    if (freeHeightFraction * (xmax - xmin) < height) room = false; break;
741  case G4Scale::y:
742    if (freeHeightFraction * (ymax - ymin) < height) room = false; break;
743  case G4Scale::z:
744    if (freeHeightFraction * (zmax - zmin) < height) room = false; break;
745  }
746  if (!room) {
747    worried = true;
748    if (verbosity >= G4VisManager::warnings) {
749      G4cout <<
750        "WARNING: Not enough room in existing scene.  Maybe logo is too large."
751             << G4endl;
752    }
753  }
754  if (worried) {
755    if (verbosity >= G4VisManager::warnings) {
756      G4cout <<
757        "WARNING: The logo you have asked for is bigger than the existing"
758        "\n  scene.  Maybe you have added it too soon.  It is recommended that"
759        "\n  you add the logo last so that it can be correctly auto-positioned"
760        "\n  so as not to be obscured by any existing object and so that the"
761        "\n  view parameters can be correctly recalculated."
762             << G4endl;
763    }
764  }
765
766  // Now figure out the extent...
767  //
768  // From the G4Scale.hh:
769  //
770  // This creates a representation of annotated line in the specified
771  // direction with tick marks at the end.  If autoPlacing is true it
772  // is required to be centred at the front, right, bottom corner of
773  // the world space, comfortably outside the existing bounding
774  // box/sphere so that existing objects do not obscure it.  Otherwise
775  // it is required to be drawn with mid-point at (xmid, ymid, zmid).
776  //
777  // The auto placing algorithm might be:
778  //   x = xmin + (1 + comfort) * (xmax - xmin)
779  //   y = ymin - comfort * (ymax - ymin)
780  //   z = zmin + (1 + comfort) * (zmax - zmin)
781  //   if direction == x then (x - length,y,z) to (x,y,z)
782  //   if direction == y then (x,y,z) to (x,y + length,z)
783  //   if direction == z then (x,y,z - length) to (x,y,z)
784  //
785  // End of clip from G4Scale.hh:
786
787  G4double sxmid(xmid), symid(ymid), szmid(zmid);
788  if (autoPlacing) {
789    sxmid = xmin + onePlusComfort * (xmax - xmin);
790    symid = ymin - comfort * (ymax - ymin);
791    szmid = zmin + onePlusComfort * (zmax - zmin);
792    switch (logoDirection) {
793    case G4Scale::x:
794      sxmid -= halfHeight;
795      break;
796    case G4Scale::y:
797      symid += halfHeight;
798      break;
799    case G4Scale::z:
800      szmid -= halfHeight;
801      break;
802    }
803  }
804  G4double sxmin(sxmid), sxmax(sxmid);
805  G4double symin(symid), symax(symid);
806  G4double szmin(szmid), szmax(szmid);
807  G4Transform3D transform;
808  switch (logoDirection) {
809  case G4Scale::x:
810    sxmin = sxmid - halfHeight;
811    sxmax = sxmid + halfHeight;
812    break;
813  case G4Scale::y:
814    symin = symid - halfHeight;
815    symax = symid + halfHeight;
816    transform = G4RotateZ3D(halfpi);
817    break;
818  case G4Scale::z:
819    szmin = szmid - halfHeight;
820    szmax = szmid + halfHeight;
821    transform = G4RotateY3D(halfpi);
822    break;
823  }
824  transform = G4Translate3D(sxmid,symid,szmid) * transform;
825
826  G4VisAttributes visAtts(G4Colour(red, green, blue));
827  visAtts.SetForceSolid(true);         // Always solid.
828
829  G4Logo* logo = new G4Logo(height,visAtts);
830  G4VModel* model =
831    new G4CallbackModel<G4VisCommandSceneAddLogo::G4Logo>(logo);
832  model->SetGlobalDescription("G4Logo");
833  model->SetGlobalTag("G4Logo");
834  model->SetTransformation(transform);
835  // Note: it is the responsibility of the model to act upon this, but
836  // the extent is in local coordinates...
837  G4double& h = height;
838  G4double h2 = h/2.;
839  G4VisExtent extent(-h,h,-h2,h2,-h2,h2);
840  model->SetExtent(extent);
841  // This extent gets "added" to existing scene extent in
842  // AddRunDurationModel below.
843  const G4String& currentSceneName = pScene -> GetName ();
844  G4bool successful = pScene -> AddRunDurationModel (model, warn);
845  if (successful) {
846    if (verbosity >= G4VisManager::confirmations) {
847      G4cout << "G4 Logo of height " << userHeight << ' ' << userHeightUnit
848             << ", ";
849      switch (logoDirection) {
850      case G4Scale::x:
851        G4cout << 'x';
852        break;
853      case G4Scale::y:
854        G4cout << 'y';
855        break;
856      case G4Scale::z:
857        G4cout << 'z';
858        break;
859      }
860      G4cout << "-direction, added to scene \"" << currentSceneName << "\"";
861      if (verbosity >= G4VisManager::parameters) {
862        G4cout << "\n  with extent " << extent
863               << "\n  at " << transform.getRotation()
864               << transform.getTranslation();
865      }
866      G4cout << G4endl;
867    }
868  }
869  else G4VisCommandsSceneAddUnsuccessful(verbosity);
870  UpdateVisManagerScene (currentSceneName);
871}
872
873G4VisCommandSceneAddLogo::G4Logo::G4Logo
874(G4double height, const G4VisAttributes& visAtts):
875  fHeight(height),
876  fVisAtts(visAtts)
877 {
878  const G4double& h =  height;
879  const G4double h2  = 0.5 * h;   // Half height.
880  const G4double ri  = 0.25 * h;  // Inner radius.
881  const G4double ro  = 0.5 * h;   // Outer radius.
882  const G4double ro2 = 0.5 * ro;  // Half outer radius.
883  const G4double w   = ro - ri;   // Width.
884  const G4double w2  = 0.5 * w;   // Half width.
885  const G4double d2  = 0.2 * h;   // Half depth.
886  const G4double f1  = 0.05 * h;  // left edge of stem of "4".
887  const G4double f2  = -0.3 * h;  // bottom edge of cross of "4".
888  const G4double e = 1.e-4 * h;   // epsilon.
889  const G4double xt = f1, yt = h2;      // Top of slope.
890  const G4double xb = -h2, yb = f2 + w; // Bottom of slope.
891  const G4double dx = xt - xb, dy = yt - yb;
892  const G4double angle = std::atan2(dy,dx);
893  G4RotationMatrix rm;
894  rm.rotateZ(angle*rad);
895  const G4double d = std::sqrt(dx * dx + dy * dy);
896  const G4double s = h;  // Half height of square subtractor
897  const G4double y8 = s; // Choose y of subtractor for outer slope.
898  const G4double x8 = ((-s * d - dx * (yt - y8)) / dy) + xt;
899  G4double y9 = s; // Choose y of subtractor for inner slope.
900  G4double x9 = ((-(s - w) * d - dx * (yt - y8)) / dy) + xt;
901  // But to get inner, we make a triangle translated by...
902  const G4double xtr = s - f1, ytr = -s - f2 -w;
903  x9 += xtr; y9 += ytr;
904
905  // G...
906  G4Tubs tG("tG",ri,ro,d2,0.15*pi,1.85*pi);
907  G4Box bG("bG",w2,ro2,d2);
908  G4UnionSolid logoG("logoG",&tG,&bG,G4Translate3D(ri+w2,-ro2,0.));
909  fpG = logoG.CreatePolyhedron();
910  fpG->SetVisAttributes(&fVisAtts);
911  fpG->Transform(G4Translate3D(-0.55*h,0.,0.));
912
913  // 4...
914  G4Box b1("b1",h2,h2,d2);
915  G4Box bS("bS",s,s,d2+e);  // Subtractor.
916  G4Box bS2("bS2",s,s,d2+2.*e);  // 2nd Subtractor.
917  G4SubtractionSolid s1("s1",&b1,&bS,G4Translate3D(f1-s,f2-s,0.));
918  G4SubtractionSolid s2("s2",&s1,&bS,G4Translate3D(f1+s+w,f2-s,0.));
919  G4SubtractionSolid s3("s3",&s2,&bS,G4Translate3D(f1+s+w,f2+s+w,0.));
920  G4SubtractionSolid s4
921    ("s4",&s3,&bS,G4Transform3D(rm,G4ThreeVector(x8,y8,0.)));
922  G4SubtractionSolid s5    // Triangular hole.
923    ("s5",&bS,&bS2,G4Transform3D(rm,G4ThreeVector(x9,y9,0.)));
924  G4SubtractionSolid logo4("logo4",&s4,&s5,G4Translate3D(-xtr,-ytr,0.));
925  fp4 = logo4.CreatePolyhedron();
926  /* Experiment with creating own polyhedron...
927  int nNodes = 4;
928  int nFaces = 4;
929  double xyz[][3] = {{0,0,0},{1*m,0,0},{0,1*m,0},{0,0,1*m}};
930  int faces[][4] = {{1,3,2,0},{1,2,4,0},{1,4,3,0},{2,3,4,0}};
931  fp4 = new G4Polyhedron();
932  fp4->createPolyhedron(nNodes,nFaces,xyz,faces);
933  */
934  fp4->SetVisAttributes(&fVisAtts);
935  fp4->Transform(G4Translate3D(0.55*h,0.,0.));
936}
937
938G4VisCommandSceneAddLogo::G4Logo::~G4Logo() {
939  delete fpG;
940  delete fp4;
941}
942
943void G4VisCommandSceneAddLogo::G4Logo::operator()
944  (G4VGraphicsScene& sceneHandler, const G4Transform3D& transform) {
945  sceneHandler.BeginPrimitives(transform);
946  sceneHandler.AddPrimitive(*fpG);
947  sceneHandler.AddPrimitive(*fp4);
948  sceneHandler.EndPrimitives();
949}
950
951////////////// /vis/scene/add/psHits ///////////////////////////////////////
952
953G4VisCommandSceneAddPSHits::G4VisCommandSceneAddPSHits () {
954  G4bool omitable;
955  fpCommand = new G4UIcmdWithAString ("/vis/scene/add/psHits", this);
956  fpCommand -> SetGuidance
957    ("Adds Primitive Scorer Hits (PSHits) to current scene.");
958  fpCommand -> SetGuidance
959    ("PSHits are drawn at end of run when the scene in which"
960     "\nthey are added is current.");
961  fpCommand -> SetGuidance
962    ("Optional parameter specifies name of scoring map.  By default all"
963     "\nscoring maps registered with the G4ScoringManager are drawn.");
964  fpCommand -> SetParameterName ("mapname", omitable = true);
965  fpCommand -> SetDefaultValue ("all");
966}
967
968G4VisCommandSceneAddPSHits::~G4VisCommandSceneAddPSHits () {
969  delete fpCommand;
970}
971
972G4String G4VisCommandSceneAddPSHits::GetCurrentValue (G4UIcommand*) {
973  return "";
974}
975
976void G4VisCommandSceneAddPSHits::SetNewValue
977(G4UIcommand*, G4String newValue)
978{
979  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
980  G4bool warn(verbosity >= G4VisManager::warnings);
981
982  G4Scene* pScene = fpVisManager->GetCurrentScene();
983  if (!pScene) {
984    if (verbosity >= G4VisManager::errors) {
985      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
986    }
987    return;
988  }
989
990  G4PSHitsModel* model = new G4PSHitsModel(newValue);
991  const G4String& currentSceneName = pScene -> GetName ();
992  G4bool successful = pScene -> AddEndOfRunModel (model, warn);
993  if (successful) {
994    if (verbosity >= G4VisManager::confirmations) {
995      if (newValue == "all") {
996        G4cout << "All Primitive Scorer hits";
997      } else {
998        G4cout << "Hits of Primitive Scorer \"" << newValue << '"';
999      }
1000      G4cout << " will be drawn at end of run in scene \""
1001             << currentSceneName << "\"."
1002             << G4endl;
1003    }
1004  }
1005  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1006  UpdateVisManagerScene (currentSceneName);
1007}
1008
1009////////////// /vis/scene/add/scale //////////////////////////////////
1010
1011G4VisCommandSceneAddScale::G4VisCommandSceneAddScale () {
1012  G4bool omitable;
1013  fpCommand = new G4UIcommand ("/vis/scene/add/scale", this);
1014  fpCommand -> SetGuidance
1015    ("Adds an annotated scale line to the current scene.");
1016  fpCommand -> SetGuidance (G4Scale::GetGuidanceString());
1017  G4UIparameter* parameter;
1018  parameter = new G4UIparameter ("length", 'd', omitable = true);
1019  parameter->SetDefaultValue (1.);
1020  fpCommand->SetParameter (parameter);
1021  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1022  parameter->SetDefaultValue ("m");
1023  fpCommand->SetParameter (parameter);
1024  parameter =  new G4UIparameter ("direction", 's', omitable = true);
1025  parameter->SetGuidance ("'x', 'y' or 'z' - otherwise defaults to 'x'.");
1026  parameter->SetDefaultValue ("x");
1027  fpCommand->SetParameter (parameter);
1028  parameter =  new G4UIparameter ("red", 'd', omitable = true);
1029  parameter->SetDefaultValue (1.);
1030  fpCommand->SetParameter (parameter);
1031  parameter =  new G4UIparameter ("green", 'd', omitable = true);
1032  parameter->SetDefaultValue (0.);
1033  fpCommand->SetParameter (parameter);
1034  parameter =  new G4UIparameter ("blue", 'd', omitable = true);
1035  parameter->SetDefaultValue (0.);
1036  fpCommand->SetParameter (parameter);
1037  parameter =  new G4UIparameter ("auto|manual", 's', omitable = true);
1038  parameter->SetGuidance
1039    ("Automatic placement or manual placement at (xmid,ymid,zmid).");
1040  parameter -> SetParameterCandidates("auto manual");
1041  parameter->SetDefaultValue  ("auto");
1042  fpCommand->SetParameter     (parameter);
1043  parameter =  new G4UIparameter ("xmid", 'd', omitable = true);
1044  parameter->SetDefaultValue (0.);
1045  fpCommand->SetParameter (parameter);
1046  parameter =  new G4UIparameter ("ymid", 'd', omitable = true);
1047  parameter->SetDefaultValue (0.);
1048  fpCommand->SetParameter (parameter);
1049  parameter =  new G4UIparameter ("zmid", 'd', omitable = true);
1050  parameter->SetDefaultValue (0.);
1051  fpCommand->SetParameter (parameter);
1052  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1053  parameter->SetDefaultValue ("m");
1054  fpCommand->SetParameter (parameter);
1055}
1056
1057G4VisCommandSceneAddScale::~G4VisCommandSceneAddScale () {
1058  delete fpCommand;
1059}
1060
1061G4String G4VisCommandSceneAddScale::GetCurrentValue (G4UIcommand*) {
1062  return "";
1063}
1064
1065void G4VisCommandSceneAddScale::SetNewValue (G4UIcommand*, G4String newValue) {
1066
1067  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1068  G4bool warn = verbosity >= G4VisManager::warnings;
1069
1070  G4Scene* pScene = fpVisManager->GetCurrentScene();
1071  if (!pScene) {
1072    if (verbosity >= G4VisManager::errors) {
1073      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1074    }
1075    return;
1076  }
1077
1078  G4double userLength, red, green, blue, xmid, ymid, zmid;
1079  G4String userLengthUnit, direction, auto_manual, positionUnit;
1080  std::istringstream is (newValue);
1081  is >> userLength >> userLengthUnit >> direction
1082     >> red >> green >> blue
1083     >> auto_manual
1084     >> xmid >> ymid >> zmid >> positionUnit;
1085
1086  G4double length = userLength * G4UIcommand::ValueOf(userLengthUnit);
1087  G4double unit = G4UIcommand::ValueOf(positionUnit);
1088  xmid *= unit; ymid *= unit; zmid *= unit;
1089
1090  std::ostringstream oss;
1091  oss << userLength << ' ' << userLengthUnit;
1092  G4String annotation(oss.str());
1093
1094  G4Scale::Direction scaleDirection (G4Scale::x);
1095  if (direction(0) == 'y') scaleDirection = G4Scale::y;
1096  if (direction(0) == 'z') scaleDirection = G4Scale::z;
1097
1098  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
1099  // Parameters read and interpreted.
1100
1101  // Useful constants, etc...
1102  const G4double halfLength(length / 2.);
1103  const G4double comfort(0.01);  // 0.15 seems too big.  0.05 might be better.
1104  const G4double onePlusComfort(1. + comfort);
1105  const G4double freeLengthFraction (1. + 2. * comfort);
1106
1107  const G4VisExtent& sceneExtent = pScene->GetExtent();  // Existing extent.
1108  const G4double xmin = sceneExtent.GetXmin();
1109  const G4double xmax = sceneExtent.GetXmax();
1110  const G4double ymin = sceneExtent.GetYmin();
1111  const G4double ymax = sceneExtent.GetYmax();
1112  const G4double zmin = sceneExtent.GetZmin();
1113  const G4double zmax = sceneExtent.GetZmax();
1114
1115  // Test existing extent and issue warnings...
1116  G4bool worried = false;
1117  if (sceneExtent.GetExtentRadius() == 0) {
1118    worried = true;
1119    if (verbosity >= G4VisManager::warnings) {
1120      G4cout <<
1121        "WARNING: Existing scene does not yet have any extent."
1122        "\n  Maybe you have not yet added any geometrical object."
1123             << G4endl;
1124    }
1125  }
1126  // Test existing scene for room...
1127  G4bool room  = true;
1128  switch (scaleDirection) {
1129  case G4Scale::x:
1130    if (freeLengthFraction * (xmax - xmin) < length) room = false; break;
1131  case G4Scale::y:
1132    if (freeLengthFraction * (ymax - ymin) < length) room = false; break;
1133  case G4Scale::z:
1134    if (freeLengthFraction * (zmax - zmin) < length) room = false; break;
1135  }
1136  if (!room) {
1137    worried = true;
1138    if (verbosity >= G4VisManager::warnings) {
1139      G4cout <<
1140        "WARNING: Not enough room in existing scene.  Maybe scale is too long."
1141             << G4endl;
1142    }
1143  }
1144  if (worried) {
1145    if (verbosity >= G4VisManager::warnings) {
1146      G4cout <<
1147        "WARNING: The scale you have asked for is bigger than the existing"
1148        "\n  scene.  Maybe you have added it too soon.  It is recommended that"
1149        "\n  you add the scale last so that it can be correctly auto-positioned"
1150        "\n  so as not to be obscured by any existing object and so that the"
1151        "\n  view parameters can be correctly recalculated."
1152             << G4endl;
1153    }
1154  }
1155
1156  // Let's go ahead a construct a scale and a scale model.  Since the
1157  // placing is done here, this G4Scale is *not* auto-placed...
1158  G4Scale scale(length, annotation, scaleDirection,
1159                false, xmid, ymid, zmid);
1160  G4VisAttributes* pVisAttr = new G4VisAttributes(G4Colour(red, green, blue));
1161  // Created of the heap because it needs a long lifetime.  This is a
1162  // mess.  The model determines the life but the vis atttributes are
1163  // associated with the scale.  There's no way of knowing when to
1164  // delete the vis atttributes!!!
1165  scale.SetVisAttributes(pVisAttr);
1166  G4VModel* model = new G4ScaleModel(scale);
1167
1168  // Now figure out the extent...
1169  //
1170  // From the G4Scale.hh:
1171  //
1172  // This creates a representation of annotated line in the specified
1173  // direction with tick marks at the end.  If autoPlacing is true it
1174  // is required to be centred at the front, right, bottom corner of
1175  // the world space, comfortably outside the existing bounding
1176  // box/sphere so that existing objects do not obscure it.  Otherwise
1177  // it is required to be drawn with mid-point at (xmid, ymid, zmid).
1178  //
1179  // The auto placing algorithm might be:
1180  //   x = xmin + (1 + comfort) * (xmax - xmin)
1181  //   y = ymin - comfort * (ymax - ymin)
1182  //   z = zmin + (1 + comfort) * (zmax - zmin)
1183  //   if direction == x then (x - length,y,z) to (x,y,z)
1184  //   if direction == y then (x,y,z) to (x,y + length,z)
1185  //   if direction == z then (x,y,z - length) to (x,y,z)
1186  //
1187  // End of clip from G4Scale.hh:
1188  //
1189  // Implement this in two parts.  Here, use the scale's extent to
1190  // "expand" the scene's extent.  Then rendering - in
1191  // G4VSceneHandler::AddPrimitive(const G4Scale&) - simply has to
1192  // ensure it's within the new extent.
1193  //
1194
1195  G4double sxmid(xmid), symid(ymid), szmid(zmid);
1196  if (autoPlacing) {
1197    sxmid = xmin + onePlusComfort * (xmax - xmin);
1198    symid = ymin - comfort * (ymax - ymin);
1199    szmid = zmin + onePlusComfort * (zmax - zmin);
1200    switch (scaleDirection) {
1201    case G4Scale::x:
1202      sxmid -= halfLength;
1203      break;
1204    case G4Scale::y:
1205      symid += halfLength;
1206      break;
1207    case G4Scale::z:
1208      szmid -= halfLength;
1209      break;
1210    }
1211  }
1212  G4double sxmin(sxmid), sxmax(sxmid);
1213  G4double symin(symid), symax(symid);
1214  G4double szmin(szmid), szmax(szmid);
1215  G4Transform3D transform;
1216  G4VisExtent scaleExtent;
1217  switch (scaleDirection) {
1218  case G4Scale::x:
1219    sxmin = sxmid - halfLength;
1220    sxmax = sxmid + halfLength;
1221    scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
1222    break;
1223  case G4Scale::y:
1224    symin = symid - halfLength;
1225    symax = symid + halfLength;
1226    transform = G4RotateZ3D(halfpi);
1227    scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
1228    break;
1229  case G4Scale::z:
1230    szmin = szmid - halfLength;
1231    szmax = szmid + halfLength;
1232    transform = G4RotateY3D(halfpi);
1233    scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
1234    break;
1235  }
1236  transform = G4Translate3D(sxmid,symid,szmid) * transform;
1237  //////////  G4VisExtent scaleExtent(sxmin, sxmax, symin, symax, szmin, szmax);
1238
1239
1240  model->SetTransformation(transform);
1241  // Note: it is the responsibility of the model to act upon this, but
1242  // the extent is in local coordinates...
1243  model->SetExtent(scaleExtent);
1244  // This extent gets "added" to existing scene extent in
1245  // AddRunDurationModel below.
1246
1247  const G4String& currentSceneName = pScene -> GetName ();
1248  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1249  if (successful) {
1250    if (verbosity >= G4VisManager::confirmations) {
1251      G4cout << "Scale of " << annotation
1252             << " added to scene \"" << currentSceneName << "\".";
1253      if (verbosity >= G4VisManager::parameters) {
1254        G4cout << "\n  with extent " << scaleExtent
1255               << "\n  at " << transform.getRotation()
1256               << transform.getTranslation();
1257      }
1258      G4cout << G4endl;
1259    }
1260  }
1261  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1262  UpdateVisManagerScene (currentSceneName);
1263}
1264
1265
1266////////////// /vis/scene/add/text //////////////////////////////////
1267
1268G4VisCommandSceneAddText::G4VisCommandSceneAddText () {
1269  G4bool omitable;
1270  fpCommand = new G4UIcommand ("/vis/scene/add/text", this);
1271  fpCommand -> SetGuidance
1272    ("Adds text to current scene.");
1273  G4UIparameter* parameter;
1274  parameter = new G4UIparameter ("x", 'd', omitable = true);
1275  parameter->SetDefaultValue (0);
1276  parameter->SetGuidance ("x");
1277  fpCommand->SetParameter (parameter);
1278  parameter =  new G4UIparameter ("y", 'd', omitable = true);
1279  parameter->SetDefaultValue (0);
1280  parameter->SetGuidance ("y");
1281  fpCommand->SetParameter (parameter);
1282  parameter =  new G4UIparameter ("z", 'd', omitable = true);
1283  parameter->SetDefaultValue (0);
1284  parameter->SetGuidance ("z");
1285  fpCommand->SetParameter (parameter);
1286  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1287  parameter->SetDefaultValue ("m");
1288  fpCommand->SetParameter     (parameter);
1289  parameter =  new G4UIparameter ("font_size", 'd', omitable = true);
1290  parameter->SetDefaultValue (12);
1291  parameter->SetGuidance ("pixels");
1292  fpCommand->SetParameter (parameter);
1293  parameter =  new G4UIparameter ("x_offset", 'd', omitable = true);
1294  parameter->SetDefaultValue (0);
1295  parameter->SetGuidance ("pixels");
1296  fpCommand->SetParameter (parameter);
1297  parameter =  new G4UIparameter ("y_offset", 'd', omitable = true);
1298  parameter->SetDefaultValue (0);
1299  parameter->SetGuidance ("pixels");
1300  fpCommand->SetParameter (parameter);
1301  parameter =  new G4UIparameter ("text", 's', omitable = true);
1302  parameter->SetGuidance ("The rest of the line is text.");
1303  parameter->SetDefaultValue ("Hello G4");
1304  fpCommand->SetParameter (parameter);
1305}
1306
1307G4VisCommandSceneAddText::~G4VisCommandSceneAddText () {
1308  delete fpCommand;
1309}
1310
1311G4String G4VisCommandSceneAddText::GetCurrentValue (G4UIcommand*) {
1312  return "";
1313}
1314
1315void G4VisCommandSceneAddText::SetNewValue (G4UIcommand*, G4String newValue) {
1316
1317  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1318  G4bool warn = verbosity >= G4VisManager::warnings;
1319
1320  G4Scene* pScene = fpVisManager->GetCurrentScene();
1321  if (!pScene) {
1322    if (verbosity >= G4VisManager::errors) {
1323      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1324    }
1325    return;
1326  }
1327
1328  G4Tokenizer next(newValue);
1329  G4double x = StoD(next());
1330  G4double y = StoD(next());
1331  G4double z = StoD(next());
1332  G4String unitString = next();
1333  G4double font_size = StoD(next());
1334  G4double x_offset = StoD(next());
1335  G4double y_offset = StoD(next());
1336  G4String text = next("\n");
1337
1338  G4double unit = G4UIcommand::ValueOf(unitString);
1339  x *= unit; y *= unit; z *= unit;
1340
1341  G4Text g4text(text, G4Point3D(x,y,z));
1342  g4text.SetScreenSize(font_size);
1343  g4text.SetOffset(x_offset,y_offset);
1344  G4VModel* model = new G4TextModel(g4text);
1345  const G4String& currentSceneName = pScene -> GetName ();
1346  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1347  if (successful) {
1348    if (verbosity >= G4VisManager::confirmations) {
1349      G4cout << "Text \"" << text
1350             << "\" has been added to scene \"" << currentSceneName << "\"."
1351             << G4endl;
1352    }
1353  }
1354  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1355  UpdateVisManagerScene (currentSceneName);
1356}
1357
1358
1359////////////// /vis/scene/add/trajectories ///////////////////////////////////
1360
1361G4VisCommandSceneAddTrajectories::G4VisCommandSceneAddTrajectories () {
1362  G4bool omitable;
1363  fpCommand = new G4UIcmdWithAString
1364    ("/vis/scene/add/trajectories", this);
1365  fpCommand -> SetGuidance
1366    ("Adds trajectories to current scene.");
1367  fpCommand -> SetGuidance
1368    ("Causes trajectories, if any, to be drawn at the end of processing an"
1369     "\nevent.  Switches on trajectory storing and sets the"
1370     "\ndefault trajectory type.");
1371  fpCommand -> SetGuidance
1372    ("The command line parameter list determines the default trajectory type."
1373     "\nIf it contains the string \"smooth\", auxiliary inter-step points will"
1374     "\nbe inserted to improve the smoothness of the drawing of a curved"
1375     "\ntrajectory."
1376     "\nIf it contains the string \"rich\", significant extra information will"
1377     "\nbe stored in the trajectory (G4RichTrajectory) amenable to modeling"
1378     "\nand filtering with \"/vis/modeling/trajectories/create/drawByAttribute\""
1379     "\nand \"/vis/filtering/trajectories/create/attributeFilter\" commands."
1380     "\nIt may contain both strings in any order.");
1381  fpCommand -> SetGuidance
1382    ("\nTo switch off trajectory storing: \"/tracking/storeTrajectory 0\"."
1383     "\nSee also \"/vis/scene/endOfEventAction\".");
1384  fpCommand -> SetGuidance
1385    ("Note:  This only sets the default.  Independently of the result of this"
1386     "\ncommand, a user may instantiate a trajectory that overrides this default"
1387     "\nin PreUserTrackingAction.");
1388  fpCommand -> SetParameterName ("default-trajectory-type", omitable = true);
1389  fpCommand -> SetDefaultValue ("");
1390}
1391
1392G4VisCommandSceneAddTrajectories::~G4VisCommandSceneAddTrajectories () {
1393  delete fpCommand;
1394}
1395
1396G4String G4VisCommandSceneAddTrajectories::GetCurrentValue (G4UIcommand*) {
1397  return "";
1398}
1399
1400void G4VisCommandSceneAddTrajectories::SetNewValue (G4UIcommand*,
1401                                                    G4String newValue) {
1402
1403  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1404  G4bool warn = verbosity >= G4VisManager::warnings;
1405
1406  G4Scene* pScene = fpVisManager->GetCurrentScene();
1407  if (!pScene) {
1408    if (verbosity >= G4VisManager::errors) {
1409      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1410    }
1411    return;
1412  }
1413
1414  G4bool smooth = false, rich = false;
1415  if (newValue.find("smooth") != std::string::npos) smooth = true;
1416  if (newValue.find("rich") != std::string::npos) rich = true;
1417
1418  G4UImanager* UImanager = G4UImanager::GetUIpointer();
1419  G4int keepVerbose = UImanager->GetVerboseLevel();
1420  G4int newVerbose = 2;
1421  UImanager->SetVerboseLevel(newVerbose);
1422  G4PropagatorInField* propagatorInField =
1423    G4TransportationManager::GetTransportationManager()->
1424    GetPropagatorInField();
1425  propagatorInField->SetTrajectoryFilter(0); // Switch off smooth trajectories.
1426  static G4IdentityTrajectoryFilter auxiliaryPointsFilter;
1427  G4String defaultTrajectoryType;
1428  G4bool i_mode_found = false;
1429  G4int i_mode = 0;
1430  if (smooth && rich) {
1431    UImanager->ApplyCommand("/tracking/storeTrajectory 3");
1432    propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
1433    defaultTrajectoryType = "G4RichTrajectory configured for smooth steps";
1434  } else if (smooth) {
1435    UImanager->ApplyCommand("/tracking/storeTrajectory 2");
1436    propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
1437    defaultTrajectoryType = "G4SmoothTrajectory";
1438  } else if (rich) {
1439    UImanager->ApplyCommand("/tracking/storeTrajectory 3");
1440    defaultTrajectoryType = "G4RichTrajectory";
1441  } else {
1442    if (!newValue.empty()) {
1443      std::istringstream iss(newValue);
1444      iss >> i_mode;
1445      if (iss) {
1446        i_mode_found = true;
1447        if (verbosity >= G4VisManager::warnings) {
1448          G4cout <<
1449  "WARNING: Integer parameter " << i_mode << " found."
1450  "\n  DEPRECATED - its use in this command will be removed at a future major"
1451  "\n  release.  Use \"/vis/modeling/trajectories\" commands."
1452                 << G4endl;
1453        }
1454      } else {
1455        if (verbosity >= G4VisManager::errors) {
1456          G4cout << "ERROR: Unrecognised parameter \"" << newValue << "\""
1457            "\n  No action taken."
1458                 << G4endl;
1459        }
1460        return;
1461      }
1462    }
1463    UImanager->ApplyCommand("/tracking/storeTrajectory 1");
1464    defaultTrajectoryType = "G4Trajectory";
1465  }
1466  UImanager->SetVerboseLevel(keepVerbose);
1467
1468  if (rich) {
1469    if (verbosity >= G4VisManager::warnings) {
1470      G4cout <<
1471        "Attributes available for modeling and filtering with"
1472        "\n\"/vis/modeling/trajectories/create/drawByAttribute\" and"
1473        "\n\"/vis/filtering/trajectories/create/attributeFilter\" commands:\n"
1474             << G4RichTrajectory().GetAttDefs()
1475             << G4RichTrajectoryPoint().GetAttDefs();
1476    }
1477  }
1478
1479  G4TrajectoriesModel* model = 0;
1480  if (i_mode_found) {
1481    model = new G4TrajectoriesModel(i_mode);
1482  } else {
1483    model = new G4TrajectoriesModel();
1484  }
1485  const G4String& currentSceneName = pScene -> GetName ();
1486  pScene -> AddEndOfEventModel (model, warn);
1487
1488  if (verbosity >= G4VisManager::confirmations) {
1489    G4cout << "Default trajectory type " << defaultTrajectoryType
1490           << "\n  will be used to store trajectories for scene \""
1491           << currentSceneName << "\"."
1492           << G4endl;
1493  }
1494
1495  if (verbosity >= G4VisManager::warnings) {
1496    G4cout <<
1497      "WARNING: Trajectory storing has been requested.  This action may be"
1498      "\n  reversed with \"/tracking/storeTrajectory 0\"."
1499           << G4endl;
1500  }
1501  UpdateVisManagerScene (currentSceneName);
1502}
1503
1504////////////// /vis/scene/add/userAction ///////////////////////////////////
1505
1506G4VisCommandSceneAddUserAction::G4VisCommandSceneAddUserAction () {
1507  G4bool omitable;
1508  fpCommand = new G4UIcommand("/vis/scene/add/userAction",this);
1509  fpCommand -> SetGuidance
1510    ("Add Vis User Action, if any, to current scene.");
1511  fpCommand -> SetGuidance
1512    ("Optional arguments define the extent of the callback drawing.  You may"
1513     "\nnot need this if the extent has been defined in the original"
1514     "\nSetUserAction or is defined by other components of the scene.  But if"
1515     "\nthe user action is the only component of the scene, you will certainly"
1516     "\nneed to set the extent either in SetUserAction or here.  A scene must"
1517     "\nhave an extent one way or another so that the viewer can calculate"
1518     "\nhow to point the camera.");
1519  G4UIparameter* parameter;
1520  parameter = new G4UIparameter ("xmin", 'd', omitable = true);
1521  parameter->SetDefaultValue (0.);
1522  fpCommand->SetParameter (parameter);
1523  parameter =  new G4UIparameter ("xmax", 'd', omitable = true);
1524  parameter->SetDefaultValue (0.);
1525  fpCommand->SetParameter (parameter);
1526  parameter =  new G4UIparameter ("ymin", 'd', omitable = true);
1527  parameter->SetDefaultValue (0.);
1528  fpCommand->SetParameter (parameter);
1529  parameter =  new G4UIparameter ("ymax", 'd', omitable = true);
1530  parameter->SetDefaultValue (0.);
1531  fpCommand->SetParameter (parameter);
1532  parameter =  new G4UIparameter ("zmin", 'd', omitable = true);
1533  parameter->SetDefaultValue (0.);
1534  fpCommand->SetParameter (parameter);
1535  parameter =  new G4UIparameter ("zmax", 'd', omitable = true);
1536  parameter->SetDefaultValue (0.);
1537  fpCommand->SetParameter (parameter);
1538  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1539  parameter->SetDefaultValue ("cm");
1540  fpCommand->SetParameter (parameter);
1541}
1542
1543G4VisCommandSceneAddUserAction::~G4VisCommandSceneAddUserAction () {
1544  delete fpCommand;
1545}
1546
1547G4String G4VisCommandSceneAddUserAction::GetCurrentValue (G4UIcommand*) {
1548  return "";
1549}
1550
1551void G4VisCommandSceneAddUserAction::SetNewValue (G4UIcommand*,
1552                                                    G4String newValue) {
1553
1554  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1555  G4bool warn = verbosity >= G4VisManager::warnings;
1556
1557  G4VUserVisAction* visAction = fpVisManager->GetUserAction();
1558  if (!visAction) {
1559    if (warn) {
1560      G4cout << "WARNING: No User Vis Action registered." << G4endl;
1561    }
1562    return;
1563  }
1564
1565  G4Scene* pScene = fpVisManager->GetCurrentScene();
1566  if (!pScene) {
1567    if (verbosity >= G4VisManager::errors) {
1568      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1569    }
1570    return;
1571  }
1572
1573  G4String unitString;
1574  G4double xmin, xmax, ymin, ymax, zmin, zmax;
1575  std::istringstream is (newValue);
1576  is >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax >> unitString;
1577  G4double unit = G4UIcommand::ValueOf(unitString);
1578  xmin *= unit; xmax *= unit;
1579  ymin *= unit; ymax *= unit;
1580  zmin *= unit; zmax *= unit;
1581  G4VisExtent commandExtent(xmin,xmax,ymin,ymax,zmin,zmax);
1582
1583  G4VisExtent extent;
1584  if (commandExtent.GetExtentRadius() > 0.) {
1585    extent = commandExtent;
1586  } else if (fpVisManager->GetUserActionExtent().GetExtentRadius() > 0.) {
1587    extent = fpVisManager->GetUserActionExtent();
1588  } else {
1589    if (warn) {
1590      G4cout << "WARNING: User Vis Action extent is null." << G4endl;
1591    }
1592  }
1593
1594  G4VModel* model = new G4CallbackModel<G4VUserVisAction>(visAction);
1595  model->SetGlobalDescription("Vis User Action");
1596  model->SetGlobalTag("Vis User Action");
1597  model->SetExtent(extent);
1598  const G4String& currentSceneName = pScene -> GetName ();
1599  pScene -> AddRunDurationModel (model, warn);
1600  if (verbosity >= G4VisManager::confirmations) {
1601    G4cout << "User Vis Action added to scene \""
1602           << currentSceneName << "\"";
1603    if (verbosity >= G4VisManager::parameters) {
1604      G4cout << "\n  with extent " << extent;
1605    }
1606    G4cout << G4endl;
1607  }
1608  UpdateVisManagerScene (currentSceneName);
1609}
1610
1611////////////// /vis/scene/add/volume ///////////////////////////////////////
1612
1613G4VisCommandSceneAddVolume::G4VisCommandSceneAddVolume () {
1614  G4bool omitable;
1615  fpCommand = new G4UIcommand ("/vis/scene/add/volume", this);
1616  fpCommand -> SetGuidance
1617   ("Adds a physical volume to current scene, with optional clipping volume.");
1618  fpCommand -> SetGuidance
1619    ("If physical-volume-name is \"world\" (the default), the top of the"
1620     "\nmain geometry tree (material world) is added.  If \"worlds\", the"
1621     "\ntop of all worlds - material world and parallel worlds, if any - are"
1622     "\nadded.  Otherwise a search of all worlds is made, taking the first"
1623     "\nmatching occurence only.  To see a representation of the geometry"
1624     "\nhierarchy of the worlds, try \"/vis/drawTree [worlds]\" or one of the"
1625     "\ndriver/browser combinations that have the required functionality, e.g., HepRep.");
1626  fpCommand -> SetGuidance
1627    ("If clip-volume-type is specified, the subsequent parameters are used to"
1628     "\nto define a clipping volume.  For example,"
1629     "\n\"vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1\" will draw the world"
1630     "\nwith the positive octant cut away.");
1631  fpCommand -> SetGuidance
1632    ("If clip-volume-type is prepended with '-', the clip-volume is subtracted"
1633     "\n(cutaway). (This is the default if there is no prepended character.)"
1634     "\nIf '*' is prepended, the intersection of the physical-volume and the"
1635     "\nclip-volume is made. (You can make a section/DCUT with a thin box, for"
1636     "\nexample).");
1637  fpCommand -> SetGuidance
1638    ("For \"box\", the parameters are xmin,xmax,ymin,ymax,zmin,zmax."
1639     "\nOnly \"box\" is programmed at present.");
1640  G4UIparameter* parameter;
1641  parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
1642  parameter -> SetDefaultValue ("world");
1643  fpCommand -> SetParameter (parameter);
1644  parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
1645  parameter -> SetGuidance
1646    ("If negative, matches any copy no.  First name match is taken.");
1647  parameter -> SetDefaultValue (-1);
1648  fpCommand -> SetParameter (parameter);
1649  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
1650  parameter -> SetGuidance
1651    ("Depth of descent of geometry hierarchy. Default = unlimited depth.");
1652  parameter -> SetDefaultValue (G4Scene::UNLIMITED);
1653  fpCommand -> SetParameter (parameter);
1654  parameter = new G4UIparameter ("clip-volume-type", 's', omitable = true);
1655  parameter -> SetParameterCandidates("none box -box *box");
1656  parameter -> SetDefaultValue ("none");
1657  parameter -> SetGuidance("[-|*]type.  See general guidance.");
1658  fpCommand -> SetParameter (parameter);
1659  parameter = new G4UIparameter ("parameter-unit", 's', omitable = true);
1660  parameter -> SetDefaultValue ("m");
1661  fpCommand -> SetParameter (parameter);
1662  parameter = new G4UIparameter ("parameter-1", 'd', omitable = true);
1663  parameter -> SetDefaultValue (0.);
1664  fpCommand -> SetParameter (parameter);
1665  parameter = new G4UIparameter ("parameter-2", 'd', omitable = true);
1666  parameter -> SetDefaultValue (0.);
1667  fpCommand -> SetParameter (parameter);
1668  parameter = new G4UIparameter ("parameter-3", 'd', omitable = true);
1669  parameter -> SetDefaultValue (0.);
1670  fpCommand -> SetParameter (parameter);
1671  parameter = new G4UIparameter ("parameter-4", 'd', omitable = true);
1672  parameter -> SetDefaultValue (0.);
1673  fpCommand -> SetParameter (parameter);
1674  parameter = new G4UIparameter ("parameter-5", 'd', omitable = true);
1675  parameter -> SetDefaultValue (0.);
1676  fpCommand -> SetParameter (parameter);
1677  parameter = new G4UIparameter ("parameter-6", 'd', omitable = true);
1678  parameter -> SetDefaultValue (0.);
1679  fpCommand -> SetParameter (parameter);
1680}
1681
1682G4VisCommandSceneAddVolume::~G4VisCommandSceneAddVolume () {
1683  delete fpCommand;
1684}
1685
1686G4String G4VisCommandSceneAddVolume::GetCurrentValue (G4UIcommand*) {
1687  return "world 0 -1";
1688}
1689
1690void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
1691                                              G4String newValue) {
1692
1693  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1694  G4bool warn = verbosity >= G4VisManager::warnings;
1695
1696  G4Scene* pScene = fpVisManager->GetCurrentScene();
1697  if (!pScene) {
1698    if (verbosity >= G4VisManager::errors) {
1699      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1700    }
1701    return;
1702  }
1703
1704  G4String name, clipVolumeType, parameterUnit;
1705  G4int copyNo, requestedDepthOfDescent;
1706  G4double param1, param2, param3, param4, param5, param6;
1707  std::istringstream is (newValue);
1708  is >> name >> copyNo >> requestedDepthOfDescent
1709     >> clipVolumeType >> parameterUnit
1710     >> param1 >> param2 >> param3 >> param4 >> param5 >> param6;
1711  G4PhysicalVolumeModel::ClippingMode clippingMode =
1712    G4PhysicalVolumeModel::subtraction;  // Default subtraction mode.
1713  if (clipVolumeType[size_t(0)] == '-') {
1714    clipVolumeType = clipVolumeType.substr(1);  // Remove first character.
1715  } else if (clipVolumeType[size_t(0)] == '*') {
1716    clippingMode = G4PhysicalVolumeModel::intersection;
1717    clipVolumeType = clipVolumeType.substr(1);
1718  }
1719  G4double unit = G4UIcommand::ValueOf(parameterUnit);
1720  param1 *= unit; param2 *= unit; param3 *= unit;
1721  param4 *= unit; param5 *= unit; param6 *= unit;
1722
1723  G4TransportationManager* transportationManager =
1724    G4TransportationManager::GetTransportationManager ();
1725
1726  size_t nWorlds = transportationManager->GetNoWorlds();
1727  if (nWorlds > 1) {  // Parallel worlds in operation...
1728    if (verbosity >= G4VisManager::warnings) {
1729      static G4bool warned = false;
1730      if (!warned && name != "worlds") {
1731        G4cout <<
1732          "WARNING: Parallel worlds in operation.  To visualise, specify"
1733          "\n  \"worlds\" or the parallel world volume or sub-volume name"
1734          "\n   and control visibility with /vis/geometry."
1735               << G4endl;
1736        std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1737          transportationManager->GetWorldsIterator();
1738        for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1739          G4cout << "  World " << i << ": " << (*iterWorld)->GetName()
1740                 << G4endl;
1741          warned = true;
1742        }
1743      }
1744    }
1745  }
1746
1747  G4VPhysicalVolume* world = *(transportationManager->GetWorldsIterator());
1748
1749  if (!world) {
1750    if (verbosity >= G4VisManager::errors) {
1751      G4cout <<
1752        "ERROR: G4VisCommandSceneAddVolume::SetNewValue:"
1753        "\n  No world.  Maybe the geometry has not yet been defined."
1754        "\n  Try \"/run/initialize\""
1755             << G4endl;
1756    }
1757    return;
1758  }
1759
1760  const std::vector<G4VModel*>& rdModelList = pScene -> GetRunDurationModelList();
1761  std::vector<G4VModel*>::const_iterator i;
1762  for (i = rdModelList.begin(); i != rdModelList.end(); ++i) {
1763    if ((*i) -> GetGlobalDescription().find("G4PhysicalVolumeModel")
1764        != std::string::npos) {
1765      if (((G4PhysicalVolumeModel*)(*i)) -> GetTopPhysicalVolume () == world) break;
1766    }
1767  }
1768  if (i != rdModelList.end()) {
1769    if (verbosity >= G4VisManager::warnings) {
1770      G4cout << "WARNING: There is already a volume, \""
1771             << (*i) -> GetGlobalDescription()
1772             << "\",\n in the run-duration model list of scene \""
1773             << pScene -> GetName()
1774             << "\".\n To get a clean scene:"
1775             << "\n  /vis/drawVolume " << name
1776             << "\n or"
1777             << "\n  /vis/scene/create"
1778             << "\n  /vis/scene/add/volume " << name
1779             << "\n  /vis/sceneHandler/attach"
1780             << "\n (and also, if necessary, /vis/viewer/flush)"
1781             << G4endl;
1782    }
1783    return;
1784  }
1785
1786  std::vector<G4PhysicalVolumeModel*> models;
1787  std::vector<G4VPhysicalVolume*> foundVolumes;
1788  G4VPhysicalVolume* foundWorld = 0;
1789  std::vector<G4int> foundDepths;
1790  std::vector<G4Transform3D> transformations;
1791
1792  if (name == "world") {
1793
1794    models.push_back
1795      (new G4PhysicalVolumeModel (world, requestedDepthOfDescent));
1796    foundVolumes.push_back(world);
1797    foundDepths.push_back(0);
1798    transformations.push_back(G4Transform3D());
1799
1800  } else if (name == "worlds") {
1801
1802    size_t nWorlds = transportationManager->GetNoWorlds();
1803    if (nWorlds == 0) {
1804      if (verbosity >= G4VisManager::warnings) {
1805        G4cout <<
1806          "WARNING: G4VisCommandSceneAddVolume::SetNewValue:"
1807          "\n  Parallel worlds requested but none exist."
1808          "\n  Just adding material world."
1809               << G4endl;
1810      }
1811    }
1812    std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1813      transportationManager->GetWorldsIterator();
1814    for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1815      models.push_back
1816        (new G4PhysicalVolumeModel (*iterWorld, requestedDepthOfDescent));
1817      foundVolumes.push_back(*iterWorld);
1818      foundDepths.push_back(0);
1819      transformations.push_back(G4Transform3D());
1820    }
1821
1822  } else {  // Search all worlds...
1823   
1824    size_t nWorlds = transportationManager->GetNoWorlds();
1825    std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1826      transportationManager->GetWorldsIterator();
1827    for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1828      G4PhysicalVolumeModel searchModel (*iterWorld);  // Unlimited depth.
1829      G4ModelingParameters mp;  // Default - no culling.
1830      searchModel.SetModelingParameters (&mp);
1831      G4PhysicalVolumeSearchScene searchScene (&searchModel, name, copyNo);
1832      searchModel.DescribeYourselfTo (searchScene);  // Initiate search.
1833      G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
1834      if (foundVolume) {
1835        foundWorld = *iterWorld;
1836        foundVolumes.push_back(foundVolume);
1837        foundDepths.push_back(searchScene.GetFoundDepth());
1838        transformations.push_back(searchScene.GetFoundTransformation());
1839        break;
1840      }
1841    }
1842
1843    if (foundVolumes.size()) {
1844      for (size_t i = 0; i < foundVolumes.size(); ++i) {
1845        models.push_back
1846          (new G4PhysicalVolumeModel
1847           (foundVolumes[i], requestedDepthOfDescent, transformations[i]));
1848      }
1849    } else {
1850      if (verbosity >= G4VisManager::errors) {
1851        G4cout << "ERROR: Volume \"" << name << "\"";
1852        if (copyNo >= 0) {
1853          G4cout << ", copy no. " << copyNo << ",";
1854        }
1855        G4cout << " not found." << G4endl;
1856      }
1857      return;
1858    }
1859  }
1860
1861  if (clipVolumeType == "box") {
1862    const G4double dX = (param2 - param1) / 2.;
1863    const G4double dY = (param4 - param3) / 2.;
1864    const G4double dZ = (param6 - param5) / 2.;
1865    const G4double x0 = (param2 + param1) / 2.;
1866    const G4double y0 = (param4 + param3) / 2.;
1867    const G4double z0 = (param6 + param5) / 2.;
1868    G4VSolid* clippingSolid =
1869      new G4DisplacedSolid
1870      ("_displaced_clipping_box",
1871       new G4Box("_clipping_box",dX,dY,dZ),
1872       G4Translate3D(x0,y0,z0));
1873    for (size_t i = 0; i < foundVolumes.size(); ++i) {
1874      models[i]->SetClippingSolid(clippingSolid);
1875      models[i]->SetClippingMode(clippingMode);
1876    }
1877  }  // If any other shape consider NumberOfRotationSides!!!!!!!!!!!
1878
1879  const G4String& currentSceneName = pScene -> GetName ();
1880  G4bool failure = true;
1881  for (size_t i = 0; i < foundVolumes.size(); ++i) {
1882    G4bool successful = pScene -> AddRunDurationModel (models[i], warn);
1883    if (successful) {
1884      failure = false;
1885      if (verbosity >= G4VisManager::confirmations) {
1886        G4cout << "First occurrence of \""
1887               << foundVolumes[i] -> GetName ()
1888               << "\"";
1889        if (copyNo >= 0) {
1890          G4cout << ", copy no. " << copyNo << ",";
1891        }
1892        G4cout << "\n  found ";
1893        if (foundWorld)
1894          G4cout << "in world \"" << foundWorld->GetName() << "\" ";
1895        G4cout << "at depth " << foundDepths[i]
1896               << ",\n  with a requested depth of further descent of ";
1897        if (requestedDepthOfDescent < 0) {
1898          G4cout << "<0 (unlimited)";
1899        }
1900        else {
1901          G4cout << requestedDepthOfDescent;
1902        }
1903        G4cout << ",\n  has been added to scene \"" << currentSceneName << "\"."
1904               << G4endl;
1905      }
1906    }
1907  }
1908
1909  if (failure) {
1910    G4VisCommandsSceneAddUnsuccessful(verbosity);
1911    return;
1912  }
1913
1914  UpdateVisManagerScene (currentSceneName);
1915}
Note: See TracBrowser for help on using the repository browser.