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

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

update geant4.9.3 tag

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