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

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

update to CVS

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