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

Last change on this file since 1136 was 1136, checked in by garnier, 15 years ago

debug updates

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