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

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

tag geant4.9.4 beta 1 + modifs locales

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