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

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

correction du ticket #41

  • Property svn:mime-type set to text/cpp
File size: 64.2 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  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1203  G4bool warn = verbosity >= G4VisManager::warnings;
1204
1205  G4Scene* pScene = fpVisManager->GetCurrentScene();
1206  if (!pScene) {
1207    if (verbosity >= G4VisManager::errors) {
1208      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1209    }
1210    return;
1211  }
1212
1213  G4Tokenizer next(newValue);
1214  G4double x = StoD(next());
1215  G4double y = StoD(next());
1216  G4double z = StoD(next());
1217  G4String unitString = next();
1218  G4double font_size = StoD(next());
1219  G4double x_offset = StoD(next());
1220  G4double y_offset = StoD(next());
1221  G4String text = next("\n");
1222
1223  G4double unit = G4UIcommand::ValueOf(unitString);
1224  x *= unit; y *= unit; z *= unit;
1225
1226  G4Text g4text(text, G4Point3D(x,y,z));
1227  g4text.SetScreenSize(font_size);
1228  g4text.SetOffset(x_offset,y_offset);
1229  G4VModel* model = new G4TextModel(g4text);
1230  const G4String& currentSceneName = pScene -> GetName ();
1231  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1232  if (successful) {
1233    if (verbosity >= G4VisManager::confirmations) {
1234      G4cout << "Text \"" << text
1235             << "\" has been added to scene \"" << currentSceneName << "\"."
1236             << G4endl;
1237    }
1238  }
1239  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1240  UpdateVisManagerScene (currentSceneName);
1241}
1242
1243
1244////////////// /vis/scene/add/trajectories ///////////////////////////////////
1245
1246G4VisCommandSceneAddTrajectories::G4VisCommandSceneAddTrajectories () {
1247  G4bool omitable;
1248  fpCommand = new G4UIcmdWithAString
1249    ("/vis/scene/add/trajectories", this);
1250  fpCommand -> SetGuidance
1251    ("Adds trajectories to current scene.");
1252  fpCommand -> SetGuidance
1253    ("Causes trajectories, if any, to be drawn at the end of processing an"
1254     "\nevent.  Switches on trajectory storing and sets the"
1255     "\ndefault trajectory type.");
1256  fpCommand -> SetGuidance
1257    ("The command line parameter list determines the default trajectory type."
1258     "\nIf it contains the string \"smooth\", auxiliary inter-step points will"
1259     "\nbe inserted to improve the smoothness of the drawing of a curved"
1260     "\ntrajectory."
1261     "\nIf it contains the string \"rich\", significant extra information will"
1262     "\nbe stored in the trajectory (G4RichTrajectory) amenable to modeling"
1263     "\nand filtering with \"/vis/modeling/trajectories/create/drawByAttribute\""
1264     "\nand \"/vis/filtering/trajectories/create/attributeFilter\" commands."
1265     "\nIt may contain both strings in any order.");
1266  fpCommand -> SetGuidance
1267    ("\nTo switch off trajectory storing: \"/tracking/storeTrajectory 0\"."
1268     "\nSee also \"/vis/scene/endOfEventAction\".");
1269  fpCommand -> SetGuidance
1270    ("Note:  This only sets the default.  Independently of the result of this"
1271     "\ncommand, a user may instantiate a trajectory that overrides this default"
1272     "\nin PreUserTrackingAction.");
1273  fpCommand -> SetParameterName ("default-trajectory-type", omitable = true);
1274  fpCommand -> SetDefaultValue ("");
1275}
1276
1277G4VisCommandSceneAddTrajectories::~G4VisCommandSceneAddTrajectories () {
1278  delete fpCommand;
1279}
1280
1281G4String G4VisCommandSceneAddTrajectories::GetCurrentValue (G4UIcommand*) {
1282  return "";
1283}
1284
1285void G4VisCommandSceneAddTrajectories::SetNewValue (G4UIcommand*,
1286                                                    G4String newValue) {
1287
1288  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1289  G4bool warn = verbosity >= G4VisManager::warnings;
1290
1291  G4Scene* pScene = fpVisManager->GetCurrentScene();
1292  if (!pScene) {
1293    if (verbosity >= G4VisManager::errors) {
1294      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1295    }
1296    return;
1297  }
1298
1299  G4bool smooth = false, rich = false;
1300  if (newValue.find("smooth") != std::string::npos) smooth = true;
1301  if (newValue.find("rich") != std::string::npos) rich = true;
1302
1303  G4UImanager* UImanager = G4UImanager::GetUIpointer();
1304  G4int keepVerbose = UImanager->GetVerboseLevel();
1305  G4int newVerbose = 2;
1306  UImanager->SetVerboseLevel(newVerbose);
1307  G4PropagatorInField* propagatorInField =
1308    G4TransportationManager::GetTransportationManager()->
1309    GetPropagatorInField();
1310  propagatorInField->SetTrajectoryFilter(0); // Switch off smooth trajectories.
1311  static G4IdentityTrajectoryFilter auxiliaryPointsFilter;
1312  G4String defaultTrajectoryType;
1313  G4int i_mode = 0;
1314  if (smooth && rich) {
1315    UImanager->ApplyCommand("/tracking/storeTrajectory 3");
1316    propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
1317    defaultTrajectoryType = "G4RichTrajectory configured for smooth steps";
1318  } else if (smooth) {
1319    UImanager->ApplyCommand("/tracking/storeTrajectory 2");
1320    propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
1321    defaultTrajectoryType = "G4SmoothTrajectory";
1322  } else if (rich) {
1323    UImanager->ApplyCommand("/tracking/storeTrajectory 3");
1324    defaultTrajectoryType = "G4RichTrajectory";
1325  } else {
1326    if (!newValue.empty()) {
1327      std::istringstream iss(newValue);
1328      iss >> i_mode;
1329      if (iss) {
1330        if (verbosity >= G4VisManager::warnings) {
1331          G4cout << "WARNING: Integer parameter " << i_mode << " found."
1332            "\n  DEPRECATED - will be removed at next major release."
1333            "\n  Use \"/vis/modeling/trajectories\" commands."
1334                 << G4endl;
1335        }
1336      } else {
1337        if (verbosity >= G4VisManager::errors) {
1338          G4cout << "ERROR: Unrecognised parameter \"" << newValue << "\""
1339            "\n  No action taken."
1340                 << G4endl;
1341        }
1342        return;
1343      }
1344    }
1345    UImanager->ApplyCommand("/tracking/storeTrajectory 1");
1346    defaultTrajectoryType = "G4Trajectory";
1347  }
1348  UImanager->SetVerboseLevel(keepVerbose);
1349
1350  if (rich) {
1351    if (verbosity >= G4VisManager::warnings) {
1352      G4cout <<
1353        "Attributes available for modeling and filtering with"
1354        "\n\"/vis/modeling/trajectories/create/drawByAttribute\" and"
1355        "\n\"/vis/filtering/trajectories/create/attributeFilter\" commands:\n"
1356             << G4RichTrajectory().GetAttDefs();
1357    }
1358  }
1359
1360  G4TrajectoriesModel* model = new G4TrajectoriesModel(i_mode);
1361  const G4String& currentSceneName = pScene -> GetName ();
1362  pScene -> AddEndOfEventModel (model, warn);
1363
1364  if (verbosity >= G4VisManager::confirmations) {
1365    G4cout << "Default trajectory type " << defaultTrajectoryType
1366           << "\n  will be used to store trajectories for scene \""
1367           << currentSceneName << "\"."
1368           << G4endl;
1369  }
1370
1371  if (verbosity >= G4VisManager::warnings) {
1372    G4cout <<
1373      "WARNING: Trajectory storing has been requested.  This action may be"
1374      "\n  reversed with \"/tracking/storeTrajectory 0\"."
1375           << G4endl;
1376  }
1377  UpdateVisManagerScene (currentSceneName);
1378}
1379
1380////////////// /vis/scene/add/userAction ///////////////////////////////////
1381
1382G4VisCommandSceneAddUserAction::G4VisCommandSceneAddUserAction () {
1383  G4bool omitable;
1384  fpCommand = new G4UIcommand("/vis/scene/add/userAction",this);
1385  fpCommand -> SetGuidance
1386    ("Add Vis User Action, if any, to current scene.");
1387  fpCommand -> SetGuidance
1388    ("Optional arguments define the extent of the callback drawing.  You may"
1389     "\nnot need this if the extent has been defined in the original"
1390     "\nSetUserAction or is defined by other components of the scene.  But if"
1391     "\nthe user action is the only component of the scene, you will certainly"
1392     "\nneed to set the extent either in SetUserAction or here.  A scene must"
1393     "\nhave an extent one way or another so that the viewer can calculate"
1394     "\nhow to point the camera.");
1395  G4UIparameter* parameter;
1396  parameter = new G4UIparameter ("xmin", 'd', omitable = true);
1397  parameter->SetDefaultValue (0.);
1398  fpCommand->SetParameter (parameter);
1399  parameter =  new G4UIparameter ("xmax", 'd', omitable = true);
1400  parameter->SetDefaultValue (0.);
1401  fpCommand->SetParameter (parameter);
1402  parameter =  new G4UIparameter ("ymin", 'd', omitable = true);
1403  parameter->SetDefaultValue (0.);
1404  fpCommand->SetParameter (parameter);
1405  parameter =  new G4UIparameter ("ymax", 'd', omitable = true);
1406  parameter->SetDefaultValue (0.);
1407  fpCommand->SetParameter (parameter);
1408  parameter =  new G4UIparameter ("zmin", 'd', omitable = true);
1409  parameter->SetDefaultValue (0.);
1410  fpCommand->SetParameter (parameter);
1411  parameter =  new G4UIparameter ("zmax", 'd', omitable = true);
1412  parameter->SetDefaultValue (0.);
1413  fpCommand->SetParameter (parameter);
1414  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1415  parameter->SetDefaultValue ("cm");
1416  fpCommand->SetParameter (parameter);
1417}
1418
1419G4VisCommandSceneAddUserAction::~G4VisCommandSceneAddUserAction () {
1420  delete fpCommand;
1421}
1422
1423G4String G4VisCommandSceneAddUserAction::GetCurrentValue (G4UIcommand*) {
1424  return "";
1425}
1426
1427void G4VisCommandSceneAddUserAction::SetNewValue (G4UIcommand*,
1428                                                    G4String newValue) {
1429
1430  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1431  G4bool warn = verbosity >= G4VisManager::warnings;
1432
1433  G4VUserVisAction* visAction = fpVisManager->GetUserAction();
1434  if (!visAction) {
1435    if (warn) {
1436      G4cout << "WARNING: No User Vis Action registered." << G4endl;
1437    }
1438    return;
1439  }
1440
1441  G4Scene* pScene = fpVisManager->GetCurrentScene();
1442  if (!pScene) {
1443    if (verbosity >= G4VisManager::errors) {
1444      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1445    }
1446    return;
1447  }
1448
1449  G4String unitString;
1450  G4double xmin, xmax, ymin, ymax, zmin, zmax;
1451  std::istringstream is (newValue);
1452  is >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax >> unitString;
1453  G4double unit = G4UIcommand::ValueOf(unitString);
1454  xmin *= unit; xmax *= unit;
1455  ymin *= unit; ymax *= unit;
1456  zmin *= unit; zmax *= unit;
1457  G4VisExtent commandExtent(xmin,xmax,ymin,ymax,zmin,zmax);
1458
1459  G4VisExtent extent;
1460  if (commandExtent.GetExtentRadius() > 0.) {
1461    extent = commandExtent;
1462  } else if (fpVisManager->GetUserActionExtent().GetExtentRadius() > 0.) {
1463    extent = fpVisManager->GetUserActionExtent();
1464  } else {
1465    if (warn) {
1466      G4cout << "WARNING: User Vis Action extent is null." << G4endl;
1467    }
1468  }
1469
1470  G4VModel* model = new G4CallbackModel<G4VUserVisAction>(visAction);
1471  model->SetGlobalDescription("Vis User Action");
1472  model->SetGlobalTag("Vis User Action");
1473  model->SetExtent(extent);
1474  const G4String& currentSceneName = pScene -> GetName ();
1475  pScene -> AddRunDurationModel (model, warn);
1476  if (verbosity >= G4VisManager::confirmations) {
1477    G4cout << "User Vis Action added to scene \""
1478           << currentSceneName << "\"";
1479    if (verbosity >= G4VisManager::parameters) {
1480      G4cout << "\n  with extent " << extent;
1481    }
1482    G4cout << G4endl;
1483  }
1484  UpdateVisManagerScene (currentSceneName);
1485}
1486
1487////////////// /vis/scene/add/volume ///////////////////////////////////////
1488
1489G4VisCommandSceneAddVolume::G4VisCommandSceneAddVolume () {
1490  G4bool omitable;
1491  fpCommand = new G4UIcommand ("/vis/scene/add/volume", this);
1492  fpCommand -> SetGuidance
1493   ("Adds a physical volume to current scene, with optional clipping volume.");
1494  fpCommand -> SetGuidance
1495    ("If physical-volume-name is \"world\" (the default), the top of the"
1496     "\nmain geometry tree (material world) is added.  If \"worlds\", the"
1497     "\ntop of all worlds - material world and parallel worlds, if any - are"
1498     "\nadded.  Otherwise a search of all worlds is made, taking the first"
1499     "\nmatching occurence only.  To see a representation of the geometry"
1500     "\nhierarchy of the worlds, try \"/vis/drawTree [worlds]\" or one of the"
1501     "\ndriver/browser combinations that have the required functionality, e.g., HepRep.");
1502  fpCommand -> SetGuidance
1503    ("If clip-volume-type is specified, the subsequent parameters are used to"
1504     "\nto define a clipping volume.  For example,"
1505     "\n\"vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1\" will draw the world"
1506     "\nwith the positive octant cut away.");
1507  fpCommand -> SetGuidance
1508    ("If clip-volume-type is prepended with '-', the clip-volume is subtracted"
1509     "\n(cutaway). (This is the default if there is no prepended character.)"
1510     "\nIf '*' is prepended, the intersection of the physical-volume and the"
1511     "\nclip-volume is made. (You can make a section/DCUT with a thin box, for"
1512     "\nexample).");
1513  fpCommand -> SetGuidance
1514    ("For \"box\", the parameters are xmin,xmax,ymin,ymax,zmin,zmax."
1515     "\nOnly \"box\" is programmed at present.");
1516  G4UIparameter* parameter;
1517  parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
1518  parameter -> SetDefaultValue ("world");
1519  fpCommand -> SetParameter (parameter);
1520  parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
1521  parameter -> SetGuidance
1522    ("If negative, matches any copy no.  First name match is taken.");
1523  parameter -> SetDefaultValue (-1);
1524  fpCommand -> SetParameter (parameter);
1525  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
1526  parameter -> SetGuidance
1527    ("Depth of descent of geometry hierarchy. Default = unlimited depth.");
1528  parameter -> SetDefaultValue (G4Scene::UNLIMITED);
1529  fpCommand -> SetParameter (parameter);
1530  parameter = new G4UIparameter ("clip-volume-type", 's', omitable = true);
1531  parameter -> SetParameterCandidates("none box -box *box");
1532  parameter -> SetDefaultValue ("none");
1533  parameter -> SetGuidance("[-|*]type.  See general guidance.");
1534  fpCommand -> SetParameter (parameter);
1535  parameter = new G4UIparameter ("parameter-unit", 's', omitable = true);
1536  parameter -> SetDefaultValue ("m");
1537  fpCommand -> SetParameter (parameter);
1538  parameter = new G4UIparameter ("parameter-1", 'd', omitable = true);
1539  parameter -> SetDefaultValue (0.);
1540  fpCommand -> SetParameter (parameter);
1541  parameter = new G4UIparameter ("parameter-2", 'd', omitable = true);
1542  parameter -> SetDefaultValue (0.);
1543  fpCommand -> SetParameter (parameter);
1544  parameter = new G4UIparameter ("parameter-3", 'd', omitable = true);
1545  parameter -> SetDefaultValue (0.);
1546  fpCommand -> SetParameter (parameter);
1547  parameter = new G4UIparameter ("parameter-4", 'd', omitable = true);
1548  parameter -> SetDefaultValue (0.);
1549  fpCommand -> SetParameter (parameter);
1550  parameter = new G4UIparameter ("parameter-5", 'd', omitable = true);
1551  parameter -> SetDefaultValue (0.);
1552  fpCommand -> SetParameter (parameter);
1553  parameter = new G4UIparameter ("parameter-6", 'd', omitable = true);
1554  parameter -> SetDefaultValue (0.);
1555  fpCommand -> SetParameter (parameter);
1556}
1557
1558G4VisCommandSceneAddVolume::~G4VisCommandSceneAddVolume () {
1559  delete fpCommand;
1560}
1561
1562G4String G4VisCommandSceneAddVolume::GetCurrentValue (G4UIcommand*) {
1563  return "world 0 -1";
1564}
1565
1566void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
1567                                              G4String newValue) {
1568
1569  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1570  G4bool warn = verbosity >= G4VisManager::warnings;
1571
1572  G4Scene* pScene = fpVisManager->GetCurrentScene();
1573  if (!pScene) {
1574    if (verbosity >= G4VisManager::errors) {
1575      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1576    }
1577    return;
1578  }
1579
1580  G4String name, clipVolumeType, parameterUnit;
1581  G4int copyNo, requestedDepthOfDescent;
1582  G4double param1, param2, param3, param4, param5, param6;
1583  std::istringstream is (newValue);
1584  is >> name >> copyNo >> requestedDepthOfDescent
1585     >> clipVolumeType >> parameterUnit
1586     >> param1 >> param2 >> param3 >> param4 >> param5 >> param6;
1587  G4PhysicalVolumeModel::ClippingMode clippingMode =
1588    G4PhysicalVolumeModel::subtraction;  // Default subtraction mode.
1589  if (clipVolumeType[size_t(0)] == '-') {
1590    clipVolumeType = clipVolumeType.substr(1);  // Remove first character.
1591  } else if (clipVolumeType[size_t(0)] == '*') {
1592    clippingMode = G4PhysicalVolumeModel::intersection;
1593    clipVolumeType = clipVolumeType.substr(1);
1594  }
1595  G4double unit = G4UIcommand::ValueOf(parameterUnit);
1596  param1 *= unit; param2 *= unit; param3 *= unit;
1597  param4 *= unit; param5 *= unit; param6 *= unit;
1598
1599  G4TransportationManager* transportationManager =
1600    G4TransportationManager::GetTransportationManager ();
1601
1602  size_t nWorlds = transportationManager->GetNoWorlds();
1603  if (nWorlds > 1) {  // Parallel worlds in operation...
1604    if (verbosity >= G4VisManager::warnings) {
1605      static G4bool warned = false;
1606      if (!warned && name != "worlds") {
1607        G4cout <<
1608          "WARNING: Parallel worlds in operation.  To visualise, specify"
1609          "\n  \"worlds\" or the parallel world volume or sub-volume name"
1610          "\n   and control visibility with /vis/geometry."
1611               << G4endl;
1612        std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1613          transportationManager->GetWorldsIterator();
1614        for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1615          G4cout << "  World " << i << ": " << (*iterWorld)->GetName()
1616                 << G4endl;
1617          warned = true;
1618        }
1619      }
1620    }
1621  }
1622
1623  G4VPhysicalVolume* world = *(transportationManager->GetWorldsIterator());
1624
1625  if (!world) {
1626    if (verbosity >= G4VisManager::errors) {
1627      G4cout <<
1628        "ERROR: G4VisCommandSceneAddVolume::SetNewValue:"
1629        "\n  No world.  Maybe the geometry has not yet been defined."
1630        "\n  Try \"/run/initialize\""
1631             << G4endl;
1632    }
1633    return;
1634  }
1635
1636  const std::vector<G4VModel*>& rdModelList = pScene -> GetRunDurationModelList();
1637  std::vector<G4VModel*>::const_iterator i;
1638  for (i = rdModelList.begin(); i != rdModelList.end(); ++i) {
1639    if ((*i) -> GetGlobalDescription().find("G4PhysicalVolumeModel")
1640        != std::string::npos) {
1641      if (((G4PhysicalVolumeModel*)(*i)) -> GetTopPhysicalVolume () == world) break;
1642    }
1643  }
1644  if (i != rdModelList.end()) {
1645    if (verbosity >= G4VisManager::warnings) {
1646      G4cout << "WARNING: There is already a volume, \""
1647             << (*i) -> GetGlobalDescription()
1648             << "\",\n in the run-duration model list of scene \""
1649             << pScene -> GetName()
1650             << "\".\n To get a clean scene:"
1651             << "\n  /vis/drawVolume " << name
1652             << "\n or"
1653             << "\n  /vis/scene/create"
1654             << "\n  /vis/scene/add/volume " << name
1655             << "\n  /vis/sceneHandler/attach"
1656             << "\n (and also, if necessary, /vis/viewer/flush)"
1657             << G4endl;
1658    }
1659    return;
1660  }
1661
1662  std::vector<G4PhysicalVolumeModel*> models;
1663  std::vector<G4VPhysicalVolume*> foundVolumes;
1664  G4VPhysicalVolume* foundWorld = 0;
1665  std::vector<G4int> foundDepths;
1666  std::vector<G4Transform3D> transformations;
1667
1668  if (name == "world") {
1669
1670    models.push_back
1671      (new G4PhysicalVolumeModel (world, requestedDepthOfDescent));
1672    foundVolumes.push_back(world);
1673    foundDepths.push_back(0);
1674    transformations.push_back(G4Transform3D());
1675
1676  } else if (name == "worlds") {
1677
1678    size_t nWorlds = transportationManager->GetNoWorlds();
1679    if (nWorlds == 0) {
1680      if (verbosity >= G4VisManager::warnings) {
1681        G4cout <<
1682          "WARNING: G4VisCommandSceneAddVolume::SetNewValue:"
1683          "\n  Parallel worlds requested but none exist."
1684          "\n  Just adding material world."
1685               << G4endl;
1686      }
1687    }
1688    std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1689      transportationManager->GetWorldsIterator();
1690    for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1691      models.push_back
1692        (new G4PhysicalVolumeModel (*iterWorld, requestedDepthOfDescent));
1693      foundVolumes.push_back(*iterWorld);
1694      foundDepths.push_back(0);
1695      transformations.push_back(G4Transform3D());
1696    }
1697
1698  } else {  // Search all worlds...
1699   
1700    size_t nWorlds = transportationManager->GetNoWorlds();
1701    std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1702      transportationManager->GetWorldsIterator();
1703    for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1704      G4PhysicalVolumeModel searchModel (*iterWorld);  // Unlimited depth.
1705      G4ModelingParameters mp;  // Default - no culling.
1706      searchModel.SetModelingParameters (&mp);
1707      G4PhysicalVolumeSearchScene searchScene (&searchModel, name, copyNo);
1708      searchModel.DescribeYourselfTo (searchScene);  // Initiate search.
1709      G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
1710      if (foundVolume) {
1711        foundWorld = *iterWorld;
1712        foundVolumes.push_back(foundVolume);
1713        foundDepths.push_back(searchScene.GetFoundDepth());
1714        transformations.push_back(searchScene.GetFoundTransformation());
1715        break;
1716      }
1717    }
1718
1719    if (foundVolumes.size()) {
1720      for (size_t i = 0; i < foundVolumes.size(); ++i) {
1721        models.push_back
1722          (new G4PhysicalVolumeModel
1723           (foundVolumes[i], requestedDepthOfDescent, transformations[i]));
1724      }
1725    } else {
1726      if (verbosity >= G4VisManager::errors) {
1727        G4cout << "ERROR: Volume \"" << name << "\"";
1728        if (copyNo >= 0) {
1729          G4cout << ", copy no. " << copyNo << ",";
1730        }
1731        G4cout << " not found." << G4endl;
1732      }
1733      return;
1734    }
1735  }
1736
1737  if (clipVolumeType == "box") {
1738    const G4double dX = (param2 - param1) / 2.;
1739    const G4double dY = (param4 - param3) / 2.;
1740    const G4double dZ = (param6 - param5) / 2.;
1741    const G4double x0 = (param2 + param1) / 2.;
1742    const G4double y0 = (param4 + param3) / 2.;
1743    const G4double z0 = (param6 + param5) / 2.;
1744    G4Box clippingBox("_clipping_box",dX,dY,dZ);
1745    G4Polyhedron* clippingPolyhedron =
1746      new G4PolyhedronBox(dX,dY,dZ);  // The model deletes.
1747    clippingPolyhedron->Transform(G4Translate3D(x0,y0,z0));
1748    for (size_t i = 0; i < foundVolumes.size(); ++i) {
1749      models[i]->SetClippingPolyhedron(clippingPolyhedron);
1750      models[i]->SetClippingMode(clippingMode);
1751    }
1752  }  // If any other shape consider NumberOfRotationSides!!!!!!!!!!!
1753
1754  const G4String& currentSceneName = pScene -> GetName ();
1755  G4bool failure = true;
1756  for (size_t i = 0; i < foundVolumes.size(); ++i) {
1757    G4bool successful = pScene -> AddRunDurationModel (models[i], warn);
1758    if (successful) {
1759      failure = false;
1760      if (verbosity >= G4VisManager::confirmations) {
1761        G4cout << "First occurrence of \""
1762               << foundVolumes[i] -> GetName ()
1763               << "\"";
1764        if (copyNo >= 0) {
1765          G4cout << ", copy no. " << copyNo << ",";
1766        }
1767        G4cout << "\n  found ";
1768        if (foundWorld)
1769          G4cout << "in world \"" << foundWorld->GetName() << "\" ";
1770        G4cout << "at depth " << foundDepths[i]
1771               << ",\n  with a requested depth of further descent of ";
1772        if (requestedDepthOfDescent < 0) {
1773          G4cout << "<0 (unlimited)";
1774        }
1775        else {
1776          G4cout << requestedDepthOfDescent;
1777        }
1778        G4cout << ",\n  has been added to scene \"" << currentSceneName << "\"."
1779               << G4endl;
1780      }
1781    }
1782  }
1783
1784  if (failure) {
1785    G4VisCommandsSceneAddUnsuccessful(verbosity);
1786    return;
1787  }
1788
1789  UpdateVisManagerScene (currentSceneName);
1790}
Note: See TracBrowser for help on using the repository browser.