source: tags/Visualization_after-vis09-02-01-tag/management/src/G4VisCommandsSceneAdd.cc @ 958

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

tag

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