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

Last change on this file since 1348 was 1348, checked in by garnier, 13 years ago

update

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