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

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

cvs update

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