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

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

update contre CVS

  • Property svn:mime-type set to text/cpp
File size: 66.2 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4VisCommandsSceneAdd.cc,v 1.77 2009/11/04 13:15:02 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  G4bool omitable;
901  fpCommand = new G4UIcmdWithAString ("/vis/scene/add/psHits", this);
902  fpCommand -> SetGuidance
903    ("Adds Primitive Scorer Hits (PSHits) to current scene.");
904  fpCommand -> SetGuidance
905    ("PSHits are drawn at end of run when the scene in which"
906     "\nthey are added is current.");
907  fpCommand -> SetGuidance
908    ("Optional parameter specifies name of scoring map.  By default all"
909     "\nscoring maps registered with the G4ScoringManager are drawn.");
910  fpCommand -> SetParameterName ("mapname", omitable = true);
911  fpCommand -> SetDefaultValue ("all");
912}
913
914G4VisCommandSceneAddPSHits::~G4VisCommandSceneAddPSHits () {
915  delete fpCommand;
916}
917
918G4String G4VisCommandSceneAddPSHits::GetCurrentValue (G4UIcommand*) {
919  return "";
920}
921
922void G4VisCommandSceneAddPSHits::SetNewValue
923(G4UIcommand*, G4String newValue)
924{
925  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
926  G4bool warn(verbosity >= G4VisManager::warnings);
927
928  G4Scene* pScene = fpVisManager->GetCurrentScene();
929  if (!pScene) {
930    if (verbosity >= G4VisManager::errors) {
931      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
932    }
933    return;
934  }
935
936  G4PSHitsModel* model = new G4PSHitsModel(newValue);
937  const G4String& currentSceneName = pScene -> GetName ();
938  G4bool successful = pScene -> AddEndOfRunModel (model, warn);
939  if (successful) {
940    if (verbosity >= G4VisManager::confirmations) {
941      if (newValue == "all") {
942        G4cout << "All Primitive Scorer hits";
943      } else {
944        G4cout << "Hits of Primitive Scorer \"" << newValue << '"';
945      }
946      G4cout << " will be drawn at end of run in scene \""
947             << currentSceneName << "\"."
948             << G4endl;
949    }
950  }
951  else G4VisCommandsSceneAddUnsuccessful(verbosity);
952  UpdateVisManagerScene (currentSceneName);
953}
954
955////////////// /vis/scene/add/scale //////////////////////////////////
956
957G4VisCommandSceneAddScale::G4VisCommandSceneAddScale () {
958  G4bool omitable;
959  fpCommand = new G4UIcommand ("/vis/scene/add/scale", this);
960  fpCommand -> SetGuidance
961    ("Adds an annotated scale line to the current scene.");
962  fpCommand -> SetGuidance (G4Scale::GetGuidanceString());
963  G4UIparameter* parameter;
964  parameter = new G4UIparameter ("length", 'd', omitable = true);
965  parameter->SetDefaultValue (1.);
966  fpCommand->SetParameter (parameter);
967  parameter =  new G4UIparameter ("unit", 's', omitable = true);
968  parameter->SetDefaultValue ("m");
969  fpCommand->SetParameter (parameter);
970  parameter =  new G4UIparameter ("direction", 's', omitable = true);
971  parameter->SetGuidance ("'x', 'y' or 'z' - otherwise defaults to 'x'.");
972  parameter->SetDefaultValue ("x");
973  fpCommand->SetParameter (parameter);
974  parameter =  new G4UIparameter ("red", 'd', omitable = true);
975  parameter->SetDefaultValue (1.);
976  fpCommand->SetParameter (parameter);
977  parameter =  new G4UIparameter ("green", 'd', omitable = true);
978  parameter->SetDefaultValue (0.);
979  fpCommand->SetParameter (parameter);
980  parameter =  new G4UIparameter ("blue", 'd', omitable = true);
981  parameter->SetDefaultValue (0.);
982  fpCommand->SetParameter (parameter);
983  parameter =  new G4UIparameter ("auto|manual", 's', omitable = true);
984  parameter->SetGuidance
985    ("Automatic placement or manual placement at (xmid,ymid,zmid).");
986  parameter -> SetParameterCandidates("auto manual");
987  parameter->SetDefaultValue  ("auto");
988  fpCommand->SetParameter     (parameter);
989  parameter =  new G4UIparameter ("xmid", 'd', omitable = true);
990  parameter->SetDefaultValue (0.);
991  fpCommand->SetParameter (parameter);
992  parameter =  new G4UIparameter ("ymid", 'd', omitable = true);
993  parameter->SetDefaultValue (0.);
994  fpCommand->SetParameter (parameter);
995  parameter =  new G4UIparameter ("zmid", 'd', omitable = true);
996  parameter->SetDefaultValue (0.);
997  fpCommand->SetParameter (parameter);
998  parameter =  new G4UIparameter ("unit", 's', omitable = true);
999  parameter->SetDefaultValue ("m");
1000  fpCommand->SetParameter (parameter);
1001}
1002
1003G4VisCommandSceneAddScale::~G4VisCommandSceneAddScale () {
1004  delete fpCommand;
1005}
1006
1007G4String G4VisCommandSceneAddScale::GetCurrentValue (G4UIcommand*) {
1008  return "";
1009}
1010
1011void G4VisCommandSceneAddScale::SetNewValue (G4UIcommand*, G4String newValue) {
1012
1013  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1014  G4bool warn = verbosity >= G4VisManager::warnings;
1015
1016  G4Scene* pScene = fpVisManager->GetCurrentScene();
1017  if (!pScene) {
1018    if (verbosity >= G4VisManager::errors) {
1019      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1020    }
1021    return;
1022  }
1023
1024  G4double userLength, red, green, blue, xmid, ymid, zmid;
1025  G4String userLengthUnit, direction, auto_manual, positionUnit;
1026  std::istringstream is (newValue);
1027  is >> userLength >> userLengthUnit >> direction
1028     >> red >> green >> blue
1029     >> auto_manual
1030     >> xmid >> ymid >> zmid >> positionUnit;
1031
1032  G4double length = userLength * G4UIcommand::ValueOf(userLengthUnit);
1033  G4double unit = G4UIcommand::ValueOf(positionUnit);
1034  xmid *= unit; ymid *= unit; zmid *= unit;
1035
1036  std::ostringstream oss;
1037  oss << userLength << ' ' << userLengthUnit;
1038  G4String annotation(oss.str());
1039
1040  G4Scale::Direction scaleDirection (G4Scale::x);
1041  if (direction(0) == 'y') scaleDirection = G4Scale::y;
1042  if (direction(0) == 'z') scaleDirection = G4Scale::z;
1043
1044  G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
1045  // Parameters read and interpreted.
1046
1047  // Useful constants, etc...
1048  const G4double halfLength(length / 2.);
1049  const G4double comfort(0.01);  // 0.15 seems too big.  0.05 might be better.
1050  const G4double onePlusComfort(1. + comfort);
1051  const G4double freeLengthFraction (1. + 2. * comfort);
1052
1053  const G4VisExtent& sceneExtent = pScene->GetExtent();  // Existing extent.
1054  const G4double xmin = sceneExtent.GetXmin();
1055  const G4double xmax = sceneExtent.GetXmax();
1056  const G4double ymin = sceneExtent.GetYmin();
1057  const G4double ymax = sceneExtent.GetYmax();
1058  const G4double zmin = sceneExtent.GetZmin();
1059  const G4double zmax = sceneExtent.GetZmax();
1060
1061  // Test existing extent and issue warnings...
1062  G4bool worried = false;
1063  if (sceneExtent.GetExtentRadius() == 0) {
1064    worried = true;
1065    if (verbosity >= G4VisManager::warnings) {
1066      G4cout <<
1067        "WARNING: Existing scene does not yet have any extent."
1068        "\n  Maybe you have not yet added any geometrical object."
1069             << G4endl;
1070    }
1071  }
1072  // Test existing scene for room...
1073  G4bool room  = true;
1074  switch (scaleDirection) {
1075  case G4Scale::x:
1076    if (freeLengthFraction * (xmax - xmin) < length) room = false; break;
1077  case G4Scale::y:
1078    if (freeLengthFraction * (ymax - ymin) < length) room = false; break;
1079  case G4Scale::z:
1080    if (freeLengthFraction * (zmax - zmin) < length) room = false; break;
1081  }
1082  if (!room) {
1083    worried = true;
1084    if (verbosity >= G4VisManager::warnings) {
1085      G4cout <<
1086        "WARNING: Not enough room in existing scene.  Maybe scale is too long."
1087             << G4endl;
1088    }
1089  }
1090  if (worried) {
1091    if (verbosity >= G4VisManager::warnings) {
1092      G4cout <<
1093        "WARNING: The scale you have asked for is bigger than the existing"
1094        "\n  scene.  Maybe you have added it too soon.  It is recommended that"
1095        "\n  you add the scale last so that it can be correctly auto-positioned"
1096        "\n  so as not to be obscured by any existing object and so that the"
1097        "\n  view parameters can be correctly recalculated."
1098             << G4endl;
1099    }
1100  }
1101
1102  // Let's go ahead a construct a scale and a scale model.  Since the
1103  // placing is done here, this G4Scale is *not* auto-placed...
1104  G4Scale scale(length, annotation, scaleDirection,
1105                false, xmid, ymid, zmid);
1106  G4VisAttributes* pVisAttr = new G4VisAttributes(G4Colour(red, green, blue));
1107  // Created of the heap because it needs a long lifetime.  This is a
1108  // mess.  The model determines the life but the vis atttributes are
1109  // associated with the scale.  There's no way of knowing when to
1110  // delete the vis atttributes!!!
1111  scale.SetVisAttributes(pVisAttr);
1112  G4VModel* model = new G4ScaleModel(scale);
1113
1114  // Now figure out the extent...
1115  //
1116  // From the G4Scale.hh:
1117  //
1118  // This creates a representation of annotated line in the specified
1119  // direction with tick marks at the end.  If autoPlacing is true it
1120  // is required to be centred at the front, right, bottom corner of
1121  // the world space, comfortably outside the existing bounding
1122  // box/sphere so that existing objects do not obscure it.  Otherwise
1123  // it is required to be drawn with mid-point at (xmid, ymid, zmid).
1124  //
1125  // The auto placing algorithm might be:
1126  //   x = xmin + (1 + comfort) * (xmax - xmin)
1127  //   y = ymin - comfort * (ymax - ymin)
1128  //   z = zmin + (1 + comfort) * (zmax - zmin)
1129  //   if direction == x then (x - length,y,z) to (x,y,z)
1130  //   if direction == y then (x,y,z) to (x,y + length,z)
1131  //   if direction == z then (x,y,z - length) to (x,y,z)
1132  //
1133  // End of clip from G4Scale.hh:
1134  //
1135  // Implement this in two parts.  Here, use the scale's extent to
1136  // "expand" the scene's extent.  Then rendering - in
1137  // G4VSceneHandler::AddPrimitive(const G4Scale&) - simply has to
1138  // ensure it's within the new extent.
1139  //
1140
1141  G4double sxmid(xmid), symid(ymid), szmid(zmid);
1142  if (autoPlacing) {
1143    sxmid = xmin + onePlusComfort * (xmax - xmin);
1144    symid = ymin - comfort * (ymax - ymin);
1145    szmid = zmin + onePlusComfort * (zmax - zmin);
1146    switch (scaleDirection) {
1147    case G4Scale::x:
1148      sxmid -= halfLength;
1149      break;
1150    case G4Scale::y:
1151      symid += halfLength;
1152      break;
1153    case G4Scale::z:
1154      szmid -= halfLength;
1155      break;
1156    }
1157  }
1158  G4double sxmin(sxmid), sxmax(sxmid);
1159  G4double symin(symid), symax(symid);
1160  G4double szmin(szmid), szmax(szmid);
1161  G4Transform3D transform;
1162  G4VisExtent scaleExtent;
1163  switch (scaleDirection) {
1164  case G4Scale::x:
1165    sxmin = sxmid - halfLength;
1166    sxmax = sxmid + halfLength;
1167    scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
1168    break;
1169  case G4Scale::y:
1170    symin = symid - halfLength;
1171    symax = symid + halfLength;
1172    transform = G4RotateZ3D(halfpi);
1173    scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
1174    break;
1175  case G4Scale::z:
1176    szmin = szmid - halfLength;
1177    szmax = szmid + halfLength;
1178    transform = G4RotateY3D(halfpi);
1179    scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
1180    break;
1181  }
1182  transform = G4Translate3D(sxmid,symid,szmid) * transform;
1183  //////////  G4VisExtent scaleExtent(sxmin, sxmax, symin, symax, szmin, szmax);
1184
1185
1186  model->SetTransformation(transform);
1187  // Note: it is the responsibility of the model to act upon this, but
1188  // the extent is in local coordinates...
1189  model->SetExtent(scaleExtent);
1190  // This extent gets "added" to existing scene extent in
1191  // AddRunDurationModel below.
1192
1193  const G4String& currentSceneName = pScene -> GetName ();
1194  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1195  if (successful) {
1196    if (verbosity >= G4VisManager::confirmations) {
1197      G4cout << "Scale of " << annotation
1198             << " added to scene \"" << currentSceneName << "\".";
1199      if (verbosity >= G4VisManager::parameters) {
1200        G4cout << "\n  with extent " << scaleExtent
1201               << "\n  at " << transform.getRotation()
1202               << transform.getTranslation();
1203      }
1204      G4cout << G4endl;
1205    }
1206  }
1207  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1208  UpdateVisManagerScene (currentSceneName);
1209}
1210
1211
1212////////////// /vis/scene/add/text //////////////////////////////////
1213
1214G4VisCommandSceneAddText::G4VisCommandSceneAddText () {
1215  G4bool omitable;
1216  fpCommand = new G4UIcommand ("/vis/scene/add/text", this);
1217  fpCommand -> SetGuidance
1218    ("Adds text to current scene.");
1219  G4UIparameter* parameter;
1220  parameter = new G4UIparameter ("x", 'd', omitable = true);
1221  parameter->SetDefaultValue (0);
1222  parameter->SetGuidance ("x");
1223  fpCommand->SetParameter (parameter);
1224  parameter =  new G4UIparameter ("y", 'd', omitable = true);
1225  parameter->SetDefaultValue (0);
1226  parameter->SetGuidance ("y");
1227  fpCommand->SetParameter (parameter);
1228  parameter =  new G4UIparameter ("z", 'd', omitable = true);
1229  parameter->SetDefaultValue (0);
1230  parameter->SetGuidance ("z");
1231  fpCommand->SetParameter (parameter);
1232  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1233  parameter->SetDefaultValue ("m");
1234  fpCommand->SetParameter     (parameter);
1235  parameter =  new G4UIparameter ("font_size", 'd', omitable = true);
1236  parameter->SetDefaultValue (12);
1237  parameter->SetGuidance ("pixels");
1238  fpCommand->SetParameter (parameter);
1239  parameter =  new G4UIparameter ("x_offset", 'd', omitable = true);
1240  parameter->SetDefaultValue (0);
1241  parameter->SetGuidance ("pixels");
1242  fpCommand->SetParameter (parameter);
1243  parameter =  new G4UIparameter ("y_offset", 'd', omitable = true);
1244  parameter->SetDefaultValue (0);
1245  parameter->SetGuidance ("pixels");
1246  fpCommand->SetParameter (parameter);
1247  parameter =  new G4UIparameter ("text", 's', omitable = true);
1248  parameter->SetGuidance ("The rest of the line is text.");
1249  parameter->SetDefaultValue ("Hello G4");
1250  fpCommand->SetParameter (parameter);
1251}
1252
1253G4VisCommandSceneAddText::~G4VisCommandSceneAddText () {
1254  delete fpCommand;
1255}
1256
1257G4String G4VisCommandSceneAddText::GetCurrentValue (G4UIcommand*) {
1258  return "";
1259}
1260
1261void G4VisCommandSceneAddText::SetNewValue (G4UIcommand*, G4String newValue) {
1262
1263  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1264  G4bool warn = verbosity >= G4VisManager::warnings;
1265
1266  G4Scene* pScene = fpVisManager->GetCurrentScene();
1267  if (!pScene) {
1268    if (verbosity >= G4VisManager::errors) {
1269      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1270    }
1271    return;
1272  }
1273
1274  G4Tokenizer next(newValue);
1275  G4double x = StoD(next());
1276  G4double y = StoD(next());
1277  G4double z = StoD(next());
1278  G4String unitString = next();
1279  G4double font_size = StoD(next());
1280  G4double x_offset = StoD(next());
1281  G4double y_offset = StoD(next());
1282  G4String text = next("\n");
1283
1284  G4double unit = G4UIcommand::ValueOf(unitString);
1285  x *= unit; y *= unit; z *= unit;
1286
1287  G4Text g4text(text, G4Point3D(x,y,z));
1288  g4text.SetScreenSize(font_size);
1289  g4text.SetOffset(x_offset,y_offset);
1290  G4VModel* model = new G4TextModel(g4text);
1291  const G4String& currentSceneName = pScene -> GetName ();
1292  G4bool successful = pScene -> AddRunDurationModel (model, warn);
1293  if (successful) {
1294    if (verbosity >= G4VisManager::confirmations) {
1295      G4cout << "Text \"" << text
1296             << "\" has been added to scene \"" << currentSceneName << "\"."
1297             << G4endl;
1298    }
1299  }
1300  else G4VisCommandsSceneAddUnsuccessful(verbosity);
1301  UpdateVisManagerScene (currentSceneName);
1302}
1303
1304
1305////////////// /vis/scene/add/trajectories ///////////////////////////////////
1306
1307G4VisCommandSceneAddTrajectories::G4VisCommandSceneAddTrajectories () {
1308  G4bool omitable;
1309  fpCommand = new G4UIcmdWithAString
1310    ("/vis/scene/add/trajectories", this);
1311  fpCommand -> SetGuidance
1312    ("Adds trajectories to current scene.");
1313  fpCommand -> SetGuidance
1314    ("Causes trajectories, if any, to be drawn at the end of processing an"
1315     "\nevent.  Switches on trajectory storing and sets the"
1316     "\ndefault trajectory type.");
1317  fpCommand -> SetGuidance
1318    ("The command line parameter list determines the default trajectory type."
1319     "\nIf it contains the string \"smooth\", auxiliary inter-step points will"
1320     "\nbe inserted to improve the smoothness of the drawing of a curved"
1321     "\ntrajectory."
1322     "\nIf it contains the string \"rich\", significant extra information will"
1323     "\nbe stored in the trajectory (G4RichTrajectory) amenable to modeling"
1324     "\nand filtering with \"/vis/modeling/trajectories/create/drawByAttribute\""
1325     "\nand \"/vis/filtering/trajectories/create/attributeFilter\" commands."
1326     "\nIt may contain both strings in any order.");
1327  fpCommand -> SetGuidance
1328    ("\nTo switch off trajectory storing: \"/tracking/storeTrajectory 0\"."
1329     "\nSee also \"/vis/scene/endOfEventAction\".");
1330  fpCommand -> SetGuidance
1331    ("Note:  This only sets the default.  Independently of the result of this"
1332     "\ncommand, a user may instantiate a trajectory that overrides this default"
1333     "\nin PreUserTrackingAction.");
1334  fpCommand -> SetParameterName ("default-trajectory-type", omitable = true);
1335  fpCommand -> SetDefaultValue ("");
1336}
1337
1338G4VisCommandSceneAddTrajectories::~G4VisCommandSceneAddTrajectories () {
1339  delete fpCommand;
1340}
1341
1342G4String G4VisCommandSceneAddTrajectories::GetCurrentValue (G4UIcommand*) {
1343  return "";
1344}
1345
1346void G4VisCommandSceneAddTrajectories::SetNewValue (G4UIcommand*,
1347                                                    G4String newValue) {
1348
1349  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1350  G4bool warn = verbosity >= G4VisManager::warnings;
1351
1352  G4Scene* pScene = fpVisManager->GetCurrentScene();
1353  if (!pScene) {
1354    if (verbosity >= G4VisManager::errors) {
1355      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1356    }
1357    return;
1358  }
1359
1360  G4bool smooth = false, rich = false;
1361  if (newValue.find("smooth") != std::string::npos) smooth = true;
1362  if (newValue.find("rich") != std::string::npos) rich = true;
1363
1364  G4UImanager* UImanager = G4UImanager::GetUIpointer();
1365  G4int keepVerbose = UImanager->GetVerboseLevel();
1366  G4int newVerbose = 2;
1367  UImanager->SetVerboseLevel(newVerbose);
1368  G4PropagatorInField* propagatorInField =
1369    G4TransportationManager::GetTransportationManager()->
1370    GetPropagatorInField();
1371  propagatorInField->SetTrajectoryFilter(0); // Switch off smooth trajectories.
1372  static G4IdentityTrajectoryFilter auxiliaryPointsFilter;
1373  G4String defaultTrajectoryType;
1374  G4int i_mode = 0;
1375  if (smooth && rich) {
1376    UImanager->ApplyCommand("/tracking/storeTrajectory 3");
1377    propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
1378    defaultTrajectoryType = "G4RichTrajectory configured for smooth steps";
1379  } else if (smooth) {
1380    UImanager->ApplyCommand("/tracking/storeTrajectory 2");
1381    propagatorInField->SetTrajectoryFilter(&auxiliaryPointsFilter);
1382    defaultTrajectoryType = "G4SmoothTrajectory";
1383  } else if (rich) {
1384    UImanager->ApplyCommand("/tracking/storeTrajectory 3");
1385    defaultTrajectoryType = "G4RichTrajectory";
1386  } else {
1387    if (!newValue.empty()) {
1388      std::istringstream iss(newValue);
1389      iss >> i_mode;
1390      if (iss) {
1391        if (verbosity >= G4VisManager::warnings) {
1392          G4cout << "WARNING: Integer parameter " << i_mode << " found."
1393            "\n  DEPRECATED - will be removed at next major release."
1394            "\n  Use \"/vis/modeling/trajectories\" commands."
1395                 << G4endl;
1396        }
1397      } else {
1398        if (verbosity >= G4VisManager::errors) {
1399          G4cout << "ERROR: Unrecognised parameter \"" << newValue << "\""
1400            "\n  No action taken."
1401                 << G4endl;
1402        }
1403        return;
1404      }
1405    }
1406    UImanager->ApplyCommand("/tracking/storeTrajectory 1");
1407    defaultTrajectoryType = "G4Trajectory";
1408  }
1409  UImanager->SetVerboseLevel(keepVerbose);
1410
1411  if (rich) {
1412    if (verbosity >= G4VisManager::warnings) {
1413      G4cout <<
1414        "Attributes available for modeling and filtering with"
1415        "\n\"/vis/modeling/trajectories/create/drawByAttribute\" and"
1416        "\n\"/vis/filtering/trajectories/create/attributeFilter\" commands:\n"
1417             << G4RichTrajectory().GetAttDefs();
1418    }
1419  }
1420
1421  G4TrajectoriesModel* model = new G4TrajectoriesModel(i_mode);
1422  const G4String& currentSceneName = pScene -> GetName ();
1423  pScene -> AddEndOfEventModel (model, warn);
1424
1425  if (verbosity >= G4VisManager::confirmations) {
1426    G4cout << "Default trajectory type " << defaultTrajectoryType
1427           << "\n  will be used to store trajectories for scene \""
1428           << currentSceneName << "\"."
1429           << G4endl;
1430  }
1431
1432  if (verbosity >= G4VisManager::warnings) {
1433    G4cout <<
1434      "WARNING: Trajectory storing has been requested.  This action may be"
1435      "\n  reversed with \"/tracking/storeTrajectory 0\"."
1436           << G4endl;
1437  }
1438  UpdateVisManagerScene (currentSceneName);
1439}
1440
1441////////////// /vis/scene/add/userAction ///////////////////////////////////
1442
1443G4VisCommandSceneAddUserAction::G4VisCommandSceneAddUserAction () {
1444  G4bool omitable;
1445  fpCommand = new G4UIcommand("/vis/scene/add/userAction",this);
1446  fpCommand -> SetGuidance
1447    ("Add Vis User Action, if any, to current scene.");
1448  fpCommand -> SetGuidance
1449    ("Optional arguments define the extent of the callback drawing.  You may"
1450     "\nnot need this if the extent has been defined in the original"
1451     "\nSetUserAction or is defined by other components of the scene.  But if"
1452     "\nthe user action is the only component of the scene, you will certainly"
1453     "\nneed to set the extent either in SetUserAction or here.  A scene must"
1454     "\nhave an extent one way or another so that the viewer can calculate"
1455     "\nhow to point the camera.");
1456  G4UIparameter* parameter;
1457  parameter = new G4UIparameter ("xmin", 'd', omitable = true);
1458  parameter->SetDefaultValue (0.);
1459  fpCommand->SetParameter (parameter);
1460  parameter =  new G4UIparameter ("xmax", 'd', omitable = true);
1461  parameter->SetDefaultValue (0.);
1462  fpCommand->SetParameter (parameter);
1463  parameter =  new G4UIparameter ("ymin", 'd', omitable = true);
1464  parameter->SetDefaultValue (0.);
1465  fpCommand->SetParameter (parameter);
1466  parameter =  new G4UIparameter ("ymax", 'd', omitable = true);
1467  parameter->SetDefaultValue (0.);
1468  fpCommand->SetParameter (parameter);
1469  parameter =  new G4UIparameter ("zmin", 'd', omitable = true);
1470  parameter->SetDefaultValue (0.);
1471  fpCommand->SetParameter (parameter);
1472  parameter =  new G4UIparameter ("zmax", 'd', omitable = true);
1473  parameter->SetDefaultValue (0.);
1474  fpCommand->SetParameter (parameter);
1475  parameter =  new G4UIparameter ("unit", 's', omitable = true);
1476  parameter->SetDefaultValue ("cm");
1477  fpCommand->SetParameter (parameter);
1478}
1479
1480G4VisCommandSceneAddUserAction::~G4VisCommandSceneAddUserAction () {
1481  delete fpCommand;
1482}
1483
1484G4String G4VisCommandSceneAddUserAction::GetCurrentValue (G4UIcommand*) {
1485  return "";
1486}
1487
1488void G4VisCommandSceneAddUserAction::SetNewValue (G4UIcommand*,
1489                                                    G4String newValue) {
1490
1491  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1492  G4bool warn = verbosity >= G4VisManager::warnings;
1493
1494  G4VUserVisAction* visAction = fpVisManager->GetUserAction();
1495  if (!visAction) {
1496    if (warn) {
1497      G4cout << "WARNING: No User Vis Action registered." << G4endl;
1498    }
1499    return;
1500  }
1501
1502  G4Scene* pScene = fpVisManager->GetCurrentScene();
1503  if (!pScene) {
1504    if (verbosity >= G4VisManager::errors) {
1505      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1506    }
1507    return;
1508  }
1509
1510  G4String unitString;
1511  G4double xmin, xmax, ymin, ymax, zmin, zmax;
1512  std::istringstream is (newValue);
1513  is >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax >> unitString;
1514  G4double unit = G4UIcommand::ValueOf(unitString);
1515  xmin *= unit; xmax *= unit;
1516  ymin *= unit; ymax *= unit;
1517  zmin *= unit; zmax *= unit;
1518  G4VisExtent commandExtent(xmin,xmax,ymin,ymax,zmin,zmax);
1519
1520  G4VisExtent extent;
1521  if (commandExtent.GetExtentRadius() > 0.) {
1522    extent = commandExtent;
1523  } else if (fpVisManager->GetUserActionExtent().GetExtentRadius() > 0.) {
1524    extent = fpVisManager->GetUserActionExtent();
1525  } else {
1526    if (warn) {
1527      G4cout << "WARNING: User Vis Action extent is null." << G4endl;
1528    }
1529  }
1530
1531  G4VModel* model = new G4CallbackModel<G4VUserVisAction>(visAction);
1532  model->SetGlobalDescription("Vis User Action");
1533  model->SetGlobalTag("Vis User Action");
1534  model->SetExtent(extent);
1535  const G4String& currentSceneName = pScene -> GetName ();
1536  pScene -> AddRunDurationModel (model, warn);
1537  if (verbosity >= G4VisManager::confirmations) {
1538    G4cout << "User Vis Action added to scene \""
1539           << currentSceneName << "\"";
1540    if (verbosity >= G4VisManager::parameters) {
1541      G4cout << "\n  with extent " << extent;
1542    }
1543    G4cout << G4endl;
1544  }
1545  UpdateVisManagerScene (currentSceneName);
1546}
1547
1548////////////// /vis/scene/add/volume ///////////////////////////////////////
1549
1550G4VisCommandSceneAddVolume::G4VisCommandSceneAddVolume () {
1551  G4bool omitable;
1552  fpCommand = new G4UIcommand ("/vis/scene/add/volume", this);
1553  fpCommand -> SetGuidance
1554   ("Adds a physical volume to current scene, with optional clipping volume.");
1555  fpCommand -> SetGuidance
1556    ("If physical-volume-name is \"world\" (the default), the top of the"
1557     "\nmain geometry tree (material world) is added.  If \"worlds\", the"
1558     "\ntop of all worlds - material world and parallel worlds, if any - are"
1559     "\nadded.  Otherwise a search of all worlds is made, taking the first"
1560     "\nmatching occurence only.  To see a representation of the geometry"
1561     "\nhierarchy of the worlds, try \"/vis/drawTree [worlds]\" or one of the"
1562     "\ndriver/browser combinations that have the required functionality, e.g., HepRep.");
1563  fpCommand -> SetGuidance
1564    ("If clip-volume-type is specified, the subsequent parameters are used to"
1565     "\nto define a clipping volume.  For example,"
1566     "\n\"vis/scene/add/volume ! ! ! -box km 0 1 0 1 0 1\" will draw the world"
1567     "\nwith the positive octant cut away.");
1568  fpCommand -> SetGuidance
1569    ("If clip-volume-type is prepended with '-', the clip-volume is subtracted"
1570     "\n(cutaway). (This is the default if there is no prepended character.)"
1571     "\nIf '*' is prepended, the intersection of the physical-volume and the"
1572     "\nclip-volume is made. (You can make a section/DCUT with a thin box, for"
1573     "\nexample).");
1574  fpCommand -> SetGuidance
1575    ("For \"box\", the parameters are xmin,xmax,ymin,ymax,zmin,zmax."
1576     "\nOnly \"box\" is programmed at present.");
1577  G4UIparameter* parameter;
1578  parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
1579  parameter -> SetDefaultValue ("world");
1580  fpCommand -> SetParameter (parameter);
1581  parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
1582  parameter -> SetGuidance
1583    ("If negative, matches any copy no.  First name match is taken.");
1584  parameter -> SetDefaultValue (-1);
1585  fpCommand -> SetParameter (parameter);
1586  parameter = new G4UIparameter ("depth-of-descent", 'i', omitable = true);
1587  parameter -> SetGuidance
1588    ("Depth of descent of geometry hierarchy. Default = unlimited depth.");
1589  parameter -> SetDefaultValue (G4Scene::UNLIMITED);
1590  fpCommand -> SetParameter (parameter);
1591  parameter = new G4UIparameter ("clip-volume-type", 's', omitable = true);
1592  parameter -> SetParameterCandidates("none box -box *box");
1593  parameter -> SetDefaultValue ("none");
1594  parameter -> SetGuidance("[-|*]type.  See general guidance.");
1595  fpCommand -> SetParameter (parameter);
1596  parameter = new G4UIparameter ("parameter-unit", 's', omitable = true);
1597  parameter -> SetDefaultValue ("m");
1598  fpCommand -> SetParameter (parameter);
1599  parameter = new G4UIparameter ("parameter-1", 'd', omitable = true);
1600  parameter -> SetDefaultValue (0.);
1601  fpCommand -> SetParameter (parameter);
1602  parameter = new G4UIparameter ("parameter-2", 'd', omitable = true);
1603  parameter -> SetDefaultValue (0.);
1604  fpCommand -> SetParameter (parameter);
1605  parameter = new G4UIparameter ("parameter-3", 'd', omitable = true);
1606  parameter -> SetDefaultValue (0.);
1607  fpCommand -> SetParameter (parameter);
1608  parameter = new G4UIparameter ("parameter-4", 'd', omitable = true);
1609  parameter -> SetDefaultValue (0.);
1610  fpCommand -> SetParameter (parameter);
1611  parameter = new G4UIparameter ("parameter-5", 'd', omitable = true);
1612  parameter -> SetDefaultValue (0.);
1613  fpCommand -> SetParameter (parameter);
1614  parameter = new G4UIparameter ("parameter-6", 'd', omitable = true);
1615  parameter -> SetDefaultValue (0.);
1616  fpCommand -> SetParameter (parameter);
1617}
1618
1619G4VisCommandSceneAddVolume::~G4VisCommandSceneAddVolume () {
1620  delete fpCommand;
1621}
1622
1623G4String G4VisCommandSceneAddVolume::GetCurrentValue (G4UIcommand*) {
1624  return "world 0 -1";
1625}
1626
1627void G4VisCommandSceneAddVolume::SetNewValue (G4UIcommand*,
1628                                              G4String newValue) {
1629
1630  G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
1631  G4bool warn = verbosity >= G4VisManager::warnings;
1632
1633  G4Scene* pScene = fpVisManager->GetCurrentScene();
1634  if (!pScene) {
1635    if (verbosity >= G4VisManager::errors) {
1636      G4cout << "ERROR: No current scene.  Please create one." << G4endl;
1637    }
1638    return;
1639  }
1640
1641  G4String name, clipVolumeType, parameterUnit;
1642  G4int copyNo, requestedDepthOfDescent;
1643  G4double param1, param2, param3, param4, param5, param6;
1644  std::istringstream is (newValue);
1645  is >> name >> copyNo >> requestedDepthOfDescent
1646     >> clipVolumeType >> parameterUnit
1647     >> param1 >> param2 >> param3 >> param4 >> param5 >> param6;
1648  G4PhysicalVolumeModel::ClippingMode clippingMode =
1649    G4PhysicalVolumeModel::subtraction;  // Default subtraction mode.
1650  if (clipVolumeType[size_t(0)] == '-') {
1651    clipVolumeType = clipVolumeType.substr(1);  // Remove first character.
1652  } else if (clipVolumeType[size_t(0)] == '*') {
1653    clippingMode = G4PhysicalVolumeModel::intersection;
1654    clipVolumeType = clipVolumeType.substr(1);
1655  }
1656  G4double unit = G4UIcommand::ValueOf(parameterUnit);
1657  param1 *= unit; param2 *= unit; param3 *= unit;
1658  param4 *= unit; param5 *= unit; param6 *= unit;
1659
1660  G4TransportationManager* transportationManager =
1661    G4TransportationManager::GetTransportationManager ();
1662
1663  size_t nWorlds = transportationManager->GetNoWorlds();
1664  if (nWorlds > 1) {  // Parallel worlds in operation...
1665    if (verbosity >= G4VisManager::warnings) {
1666      static G4bool warned = false;
1667      if (!warned && name != "worlds") {
1668        G4cout <<
1669          "WARNING: Parallel worlds in operation.  To visualise, specify"
1670          "\n  \"worlds\" or the parallel world volume or sub-volume name"
1671          "\n   and control visibility with /vis/geometry."
1672               << G4endl;
1673        std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1674          transportationManager->GetWorldsIterator();
1675        for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1676          G4cout << "  World " << i << ": " << (*iterWorld)->GetName()
1677                 << G4endl;
1678          warned = true;
1679        }
1680      }
1681    }
1682  }
1683
1684  G4VPhysicalVolume* world = *(transportationManager->GetWorldsIterator());
1685
1686  if (!world) {
1687    if (verbosity >= G4VisManager::errors) {
1688      G4cout <<
1689        "ERROR: G4VisCommandSceneAddVolume::SetNewValue:"
1690        "\n  No world.  Maybe the geometry has not yet been defined."
1691        "\n  Try \"/run/initialize\""
1692             << G4endl;
1693    }
1694    return;
1695  }
1696
1697  const std::vector<G4VModel*>& rdModelList = pScene -> GetRunDurationModelList();
1698  std::vector<G4VModel*>::const_iterator i;
1699  for (i = rdModelList.begin(); i != rdModelList.end(); ++i) {
1700    if ((*i) -> GetGlobalDescription().find("G4PhysicalVolumeModel")
1701        != std::string::npos) {
1702      if (((G4PhysicalVolumeModel*)(*i)) -> GetTopPhysicalVolume () == world) break;
1703    }
1704  }
1705  if (i != rdModelList.end()) {
1706    if (verbosity >= G4VisManager::warnings) {
1707      G4cout << "WARNING: There is already a volume, \""
1708             << (*i) -> GetGlobalDescription()
1709             << "\",\n in the run-duration model list of scene \""
1710             << pScene -> GetName()
1711             << "\".\n To get a clean scene:"
1712             << "\n  /vis/drawVolume " << name
1713             << "\n or"
1714             << "\n  /vis/scene/create"
1715             << "\n  /vis/scene/add/volume " << name
1716             << "\n  /vis/sceneHandler/attach"
1717             << "\n (and also, if necessary, /vis/viewer/flush)"
1718             << G4endl;
1719    }
1720    return;
1721  }
1722
1723  std::vector<G4PhysicalVolumeModel*> models;
1724  std::vector<G4VPhysicalVolume*> foundVolumes;
1725  G4VPhysicalVolume* foundWorld = 0;
1726  std::vector<G4int> foundDepths;
1727  std::vector<G4Transform3D> transformations;
1728
1729  if (name == "world") {
1730
1731    models.push_back
1732      (new G4PhysicalVolumeModel (world, requestedDepthOfDescent));
1733    foundVolumes.push_back(world);
1734    foundDepths.push_back(0);
1735    transformations.push_back(G4Transform3D());
1736
1737  } else if (name == "worlds") {
1738
1739    size_t nWorlds = transportationManager->GetNoWorlds();
1740    if (nWorlds == 0) {
1741      if (verbosity >= G4VisManager::warnings) {
1742        G4cout <<
1743          "WARNING: G4VisCommandSceneAddVolume::SetNewValue:"
1744          "\n  Parallel worlds requested but none exist."
1745          "\n  Just adding material world."
1746               << G4endl;
1747      }
1748    }
1749    std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1750      transportationManager->GetWorldsIterator();
1751    for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1752      models.push_back
1753        (new G4PhysicalVolumeModel (*iterWorld, requestedDepthOfDescent));
1754      foundVolumes.push_back(*iterWorld);
1755      foundDepths.push_back(0);
1756      transformations.push_back(G4Transform3D());
1757    }
1758
1759  } else {  // Search all worlds...
1760   
1761    size_t nWorlds = transportationManager->GetNoWorlds();
1762    std::vector<G4VPhysicalVolume*>::iterator iterWorld =
1763      transportationManager->GetWorldsIterator();
1764    for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
1765      G4PhysicalVolumeModel searchModel (*iterWorld);  // Unlimited depth.
1766      G4ModelingParameters mp;  // Default - no culling.
1767      searchModel.SetModelingParameters (&mp);
1768      G4PhysicalVolumeSearchScene searchScene (&searchModel, name, copyNo);
1769      searchModel.DescribeYourselfTo (searchScene);  // Initiate search.
1770      G4VPhysicalVolume* foundVolume = searchScene.GetFoundVolume ();
1771      if (foundVolume) {
1772        foundWorld = *iterWorld;
1773        foundVolumes.push_back(foundVolume);
1774        foundDepths.push_back(searchScene.GetFoundDepth());
1775        transformations.push_back(searchScene.GetFoundTransformation());
1776        break;
1777      }
1778    }
1779
1780    if (foundVolumes.size()) {
1781      for (size_t i = 0; i < foundVolumes.size(); ++i) {
1782        models.push_back
1783          (new G4PhysicalVolumeModel
1784           (foundVolumes[i], requestedDepthOfDescent, transformations[i]));
1785      }
1786    } else {
1787      if (verbosity >= G4VisManager::errors) {
1788        G4cout << "ERROR: Volume \"" << name << "\"";
1789        if (copyNo >= 0) {
1790          G4cout << ", copy no. " << copyNo << ",";
1791        }
1792        G4cout << " not found." << G4endl;
1793      }
1794      return;
1795    }
1796  }
1797
1798  if (clipVolumeType == "box") {
1799    const G4double dX = (param2 - param1) / 2.;
1800    const G4double dY = (param4 - param3) / 2.;
1801    const G4double dZ = (param6 - param5) / 2.;
1802    const G4double x0 = (param2 + param1) / 2.;
1803    const G4double y0 = (param4 + param3) / 2.;
1804    const G4double z0 = (param6 + param5) / 2.;
1805    G4Box clippingBox("_clipping_box",dX,dY,dZ);
1806    G4Polyhedron* clippingPolyhedron =
1807      new G4PolyhedronBox(dX,dY,dZ);  // The model deletes.
1808    clippingPolyhedron->Transform(G4Translate3D(x0,y0,z0));
1809    for (size_t i = 0; i < foundVolumes.size(); ++i) {
1810      models[i]->SetClippingPolyhedron(clippingPolyhedron);
1811      models[i]->SetClippingMode(clippingMode);
1812    }
1813  }  // If any other shape consider NumberOfRotationSides!!!!!!!!!!!
1814
1815  const G4String& currentSceneName = pScene -> GetName ();
1816  G4bool failure = true;
1817  for (size_t i = 0; i < foundVolumes.size(); ++i) {
1818    G4bool successful = pScene -> AddRunDurationModel (models[i], warn);
1819    if (successful) {
1820      failure = false;
1821      if (verbosity >= G4VisManager::confirmations) {
1822        G4cout << "First occurrence of \""
1823               << foundVolumes[i] -> GetName ()
1824               << "\"";
1825        if (copyNo >= 0) {
1826          G4cout << ", copy no. " << copyNo << ",";
1827        }
1828        G4cout << "\n  found ";
1829        if (foundWorld)
1830          G4cout << "in world \"" << foundWorld->GetName() << "\" ";
1831        G4cout << "at depth " << foundDepths[i]
1832               << ",\n  with a requested depth of further descent of ";
1833        if (requestedDepthOfDescent < 0) {
1834          G4cout << "<0 (unlimited)";
1835        }
1836        else {
1837          G4cout << requestedDepthOfDescent;
1838        }
1839        G4cout << ",\n  has been added to scene \"" << currentSceneName << "\"."
1840               << G4endl;
1841      }
1842    }
1843  }
1844
1845  if (failure) {
1846    G4VisCommandsSceneAddUnsuccessful(verbosity);
1847    return;
1848  }
1849
1850  UpdateVisManagerScene (currentSceneName);
1851}
Note: See TracBrowser for help on using the repository browser.