Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/management/src/G4VisCommandsTouchable.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 28 // /vis/touchable commands - John Allison  14th May 2014
 29 
 30 #include "G4VisCommandsTouchable.hh"
 31 
 32 #include "G4UImanager.hh"
 33 #include "G4UIcmdWithAString.hh"
 34 #include "G4UIcmdWithoutParameter.hh"
 35 #include "G4UIcmdWithABool.hh"
 36 #include "G4TransportationManager.hh"
 37 #include "G4TouchableUtils.hh"
 38 #include "G4PhysicalVolumesSearchScene.hh"
 39 #include "G4AttDef.hh"
 40 #include "G4AttValue.hh"
 41 #include "G4AttCheck.hh"
 42 #include "G4AxesModel.hh"
 43 
 44 #define G4warn G4cout
 45 
 46 G4VisCommandsTouchable::G4VisCommandsTouchable()
 47 {
 48   G4bool omitable;
 49 
 50   fpCommandCentreAndZoomInOn = new G4UIcmdWithoutParameter("/vis/touchable/centreAndZoomInOn",this);
 51   fpCommandCentreAndZoomInOn->SetGuidance ("Centre and zoom in on the current touchable.");
 52   fpCommandCentreAndZoomInOn->SetGuidance
 53   ("Use \"/vis/set/touchable\" to set current touchable.");
 54   fpCommandCentreAndZoomInOn->SetGuidance
 55   ("You may also need \"/vis/touchable/findPath\".");
 56   fpCommandCentreAndZoomInOn->SetGuidance
 57   ("Use \"/vis/touchable/set\" to set attributes.");
 58 
 59   fpCommandCentreOn = new G4UIcmdWithoutParameter("/vis/touchable/centreOn",this);
 60   fpCommandCentreOn->SetGuidance ("Centre the view on the current touchable.");
 61   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
 62   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandCentreOn,1);
 63 
 64   fpCommandDraw = new G4UIcmdWithABool("/vis/touchable/draw",this);
 65   fpCommandDraw->SetGuidance("Draw touchable.");
 66   fpCommandDraw->SetGuidance
 67   ("If parameter == true, also draw extent as a white wireframe box.");
 68   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
 69   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandDraw,1);
 70   fpCommandDraw->SetParameterName("extent", omitable = true);
 71   fpCommandDraw->SetDefaultValue(false);
 72 
 73   fpCommandDump = new G4UIcmdWithoutParameter("/vis/touchable/dump",this);
 74   fpCommandDump->SetGuidance("Dump touchable attributes.");
 75   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
 76   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandDump,1);
 77 
 78   fpCommandExtentForField = new G4UIcmdWithABool("/vis/touchable/extentForField",this);
 79   fpCommandExtentForField->SetGuidance("Set extent for field.");
 80   fpCommandExtentForField->SetGuidance("If parameter == true, also draw.");
 81   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
 82   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandExtentForField,1);
 83   fpCommandExtentForField->SetParameterName("draw", omitable = true);
 84   fpCommandExtentForField->SetDefaultValue(false);
 85 
 86   fpCommandFindPath = new G4UIcommand("/vis/touchable/findPath",this);
 87   fpCommandFindPath->SetGuidance
 88   ("Prints the path to touchable and its logical volume mother"
 89    "\ngiven a physical volume name and copy no.");
 90   fpCommandFindPath -> SetGuidance
 91   ("A search of all worlds is made and all physical volume names are"
 92    "\nmatched against the argument of this command.  If this is of the"
 93    "\nform \"/regexp/\", where regexp is a regular expression (see C++ regex),"
 94    "\nthe physical volume name is matched against regexp by the usual rules"
 95    "\nof regular expression matching. Otherwise an exact match is required."
 96    "\nFor example, \"/Shap/\" matches \"Shape1\" and \"Shape2\".");
 97   fpCommandFindPath -> SetGuidance
 98   ("It may help to see a textual representation of the geometry hierarchy of"
 99    "\nthe worlds. Try \"/vis/drawTree [worlds]\" or one of the driver/browser"
100    "\ncombinations that have the required functionality, e.g., HepRep.");
101   G4UIparameter* parameter;
102   parameter = new G4UIparameter ("physical-volume-name", 's', omitable = true);
103   parameter -> SetDefaultValue ("world");
104   fpCommandFindPath -> SetParameter (parameter);
105   parameter = new G4UIparameter ("copy-no", 'i', omitable = true);
106   parameter -> SetGuidance ("If negative, matches any copy no.");
107   parameter -> SetDefaultValue (-1);
108   fpCommandFindPath -> SetParameter (parameter);
109 
110   fpCommandLocalAxes = new G4UIcmdWithoutParameter("/vis/touchable/localAxes",this);
111   fpCommandLocalAxes->SetGuidance("Draw local axes.");
112   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
113   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandLocalAxes,1);
114 
115   fpCommandShowExtent = new G4UIcmdWithABool("/vis/touchable/showExtent",this);
116   fpCommandShowExtent->SetGuidance("Print extent of touchable.");
117   fpCommandShowExtent->SetGuidance("If parameter == true, also draw.");
118   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
119   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandShowExtent,1);
120   fpCommandShowExtent->SetParameterName("draw", omitable = true);
121   fpCommandShowExtent->SetDefaultValue(false);
122 
123   fpCommandTwinkle = new G4UIcmdWithoutParameter("/vis/touchable/twinkle",this);
124   fpCommandTwinkle->SetGuidance("Cause touchable to twinkle.");
125   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
126   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandTwinkle,1);
127 
128   fpCommandVolumeForField = new G4UIcmdWithABool("/vis/touchable/volumeForField",this);
129   fpCommandVolumeForField->SetGuidance("Set volume for field.");
130   fpCommandVolumeForField->SetGuidance("If parameter == true, also draw.");
131   // Pick up additional guidance from /vis/viewer/centreAndZoomInOn
132   CopyGuidanceFrom(fpCommandCentreAndZoomInOn,fpCommandVolumeForField,1);
133   fpCommandVolumeForField->SetParameterName("draw", omitable = true);
134   fpCommandVolumeForField->SetDefaultValue(false);
135 }
136 
137 G4VisCommandsTouchable::~G4VisCommandsTouchable() {
138   delete fpCommandVolumeForField;
139   delete fpCommandTwinkle;
140   delete fpCommandShowExtent;
141   delete fpCommandLocalAxes;
142   delete fpCommandFindPath;
143   delete fpCommandExtentForField;
144   delete fpCommandDump;
145   delete fpCommandDraw;
146   delete fpCommandCentreAndZoomInOn;
147   delete fpCommandCentreOn;
148 }
149 
150 G4String G4VisCommandsTouchable::GetCurrentValue(G4UIcommand*) {
151   return "";
152 }
153 
154 void G4VisCommandsTouchable::SetNewValue
155 (G4UIcommand* command, G4String newValue)
156 {
157   G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
158   G4bool warn = verbosity >= G4VisManager::warnings;
159 
160   G4UImanager* UImanager = G4UImanager::GetUIpointer();
161 
162   G4TransportationManager* transportationManager =
163   G4TransportationManager::GetTransportationManager ();
164 
165   size_t nWorlds = transportationManager->GetNoWorlds();
166 
167   G4VPhysicalVolume* world = *(transportationManager->GetWorldsIterator());
168   if (!world) {
169     if (verbosity >= G4VisManager::errors) {
170       G4warn <<
171       "ERROR: G4VisCommandsTouchable::SetNewValue:"
172       "\n  No world.  Maybe the geometry has not yet been defined."
173       "\n  Try \"/run/initialize\""
174       << G4endl;
175     }
176     return;
177   }
178 
179   if (command == fpCommandDump) {
180 
181     G4PhysicalVolumeModel::TouchableProperties properties =
182     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
183     if (properties.fpTouchablePV) {
184       // To handle parameterisations we have to set the copy number
185       properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
186       G4PhysicalVolumeModel tempPVModel
187       (properties.fpTouchablePV,
188        G4PhysicalVolumeModel::UNLIMITED,
189        properties.fTouchableGlobalTransform,
190        nullptr, // Modelling parameters (not used)
191        true, // use full extent (prevents calculating own extent, which crashes)
192        properties.fTouchableBaseFullPVPath);
193       const std::map<G4String,G4AttDef>* attDefs = tempPVModel.GetAttDefs();
194       std::vector<G4AttValue>* attValues = tempPVModel.CreateCurrentAttValues();
195       G4cout << G4AttCheck(attValues,attDefs);
196       delete attValues;
197       const auto lv = properties.fpTouchablePV->GetLogicalVolume();
198       const auto polyhedron = lv->GetSolid()->GetPolyhedron();
199       if (polyhedron) {
200         polyhedron->SetVisAttributes(lv->GetVisAttributes());
201         G4cout << "\nLocal polyhedron coordinates:\n" << *polyhedron;
202         const G4Transform3D& transform = tempPVModel.GetCurrentTransform();
203         polyhedron->Transform(transform);
204         G4cout << "\nGlobal polyhedron coordinates:\n" << *polyhedron;
205       }
206     } else {
207       G4warn << "Touchable not found." << G4endl;
208     }
209     return;
210 
211   } else if (command == fpCommandFindPath) {
212     
213     G4String pvName;
214     G4int copyNo;
215     std::istringstream iss(newValue);
216     iss >> pvName >> copyNo;
217     std::vector<G4PhysicalVolumesSearchScene::Findings> findingsVector;
218     std::vector<G4VPhysicalVolume*>::iterator iterWorld =
219     transportationManager->GetWorldsIterator();
220     for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
221       G4PhysicalVolumeModel searchModel (*iterWorld);  // Unlimited depth.
222       G4ModelingParameters mp;  // Default - no culling.
223       searchModel.SetModelingParameters (&mp);
224       // Find all instances at any position in the tree
225       G4PhysicalVolumesSearchScene searchScene (&searchModel, pvName, copyNo);
226       searchModel.DescribeYourselfTo (searchScene);  // Initiate search.
227       for (const auto& findings: searchScene.GetFindings()) {
228         findingsVector.push_back(findings);
229       }
230     }
231     for (const auto& findings: findingsVector) {
232       G4cout
233       <<  findings.fFoundBasePVPath
234       << ' ' << findings.fpFoundPV->GetName()
235       << ' ' <<  findings.fFoundPVCopyNo
236       << " (mother logical volume: "
237       << findings.fpFoundPV->GetMotherLogical()->GetName()
238       << ')'
239       << G4endl;
240     }
241     if (findingsVector.size()) {
242       G4cout
243       << "Use this to set a particular touchable with \"/vis/set/touchable <path>\""
244       << "\nor to see overlaps: \"/vis/drawLogicalVolume <mother-logical-volume-name>\""
245       << G4endl;
246     } else {
247       G4warn << pvName;
248       if (copyNo >= 0) G4warn << ':' << copyNo;
249       G4warn << " not found" << G4endl;
250     }
251     return;
252   }
253 
254   G4VViewer* currentViewer = fpVisManager -> GetCurrentViewer ();
255   if (!currentViewer) {
256     if (verbosity >= G4VisManager::errors) {
257       G4warn <<
258       "ERROR: No current viewer - \"/vis/viewer/list\" to see possibilities."
259       << G4endl;
260     }
261     return;
262   }
263 
264   G4Scene* currentScene = fpVisManager->GetCurrentScene();
265   if (!currentScene) {
266     if (verbosity >= G4VisManager::errors) {
267       G4warn <<
268       "ERROR: No current scene - \"/vis/scene/list\" to see possibilities."
269       << G4endl;
270     }
271     return;
272   }
273 
274   if (command == fpCommandCentreOn || command == fpCommandCentreAndZoomInOn) {
275 
276     // For twinkling...
277     std::vector<std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>> touchables;
278 
279     G4PhysicalVolumeModel::TouchableProperties properties =
280     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
281     if (properties.fpTouchablePV) {
282       // To handle parameterisations, set copy number
283       properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
284       G4PhysicalVolumeModel tempPVModel
285       (properties.fpTouchablePV,
286        G4PhysicalVolumeModel::UNLIMITED,
287        properties.fTouchableGlobalTransform,
288        nullptr, // Modelling parameters (not used)
289        true, // use full extent (prevents calculating own extent, which crashes)
290        properties.fTouchableBaseFullPVPath);
291       touchables.push_back(properties.fTouchableFullPVPath);  // Only one in this case
292       // Use a temporary scene in order to find vis extent
293       G4Scene tempScene("Centre Scene");
294       G4bool successful = tempScene.AddRunDurationModel(&tempPVModel,warn);
295       if (!successful) return;
296       if (verbosity >= G4VisManager::parameters) {
297         G4cout
298         << "Touchable " << fCurrentTouchableProperties.fTouchablePath
299         << ",\n  has been added to temporary scene \"" << tempScene.GetName() << "\"."
300         << G4endl;
301       }
302 
303       const G4VisExtent& newExtent = tempScene.GetExtent();
304       const G4ThreeVector& newTargetPoint = newExtent.GetExtentCentre();
305       G4ViewParameters saveVP = currentViewer->GetViewParameters();
306       G4ViewParameters newVP = saveVP;
307       if (command == fpCommandCentreAndZoomInOn) {
308         // Calculate the new zoom factor
309         const G4double zoomFactor
310         = currentScene->GetExtent().GetExtentRadius()/newExtent.GetExtentRadius();
311         newVP.SetZoomFactor(zoomFactor);
312       }
313       // Change the target point
314       const G4Point3D& standardTargetPoint = currentScene->GetStandardTargetPoint();
315       newVP.SetCurrentTargetPoint(newTargetPoint - standardTargetPoint);
316 
317       // Interpolate
318       auto keepVisVerbose = fpVisManager->GetVerbosity();
319       fpVisManager->SetVerboseLevel(G4VisManager::errors);
320       if (newVP != saveVP) InterpolateToNewView(currentViewer, saveVP, newVP);
321       // ...and twinkle
322       Twinkle(currentViewer,newVP,touchables);
323       fpVisManager->SetVerboseLevel(keepVisVerbose);
324 
325       if (verbosity >= G4VisManager::confirmations) {
326         G4cout
327         << "Viewer \"" << currentViewer->GetName()
328         << "\" centred ";
329         if (fpCommandCentreAndZoomInOn) {
330           G4cout << "and zoomed in";
331         }
332         G4cout << " on touchable\n" << fCurrentTouchableProperties.fTouchablePath
333         << G4endl;
334       }
335       SetViewParameters(currentViewer, newVP);
336     } else {
337       G4warn << "Touchable not found." << G4endl;
338     }
339     return;
340     
341   } else if (command == fpCommandDraw) {
342 
343     G4PhysicalVolumeModel::TouchableProperties properties =
344     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
345     if (properties.fpTouchablePV) {
346       // To handle parameterisations we have to set the copy number
347       properties.fpTouchablePV->SetCopyNo(properties.fCopyNo);
348       G4PhysicalVolumeModel* pvModel = new G4PhysicalVolumeModel
349       (properties.fpTouchablePV,
350        G4PhysicalVolumeModel::UNLIMITED,
351        properties.fTouchableGlobalTransform,
352        nullptr, // Modelling parameters (not used)
353        true, // use full extent (prevents calculating own extent, which crashes)
354        properties.fTouchableBaseFullPVPath);
355 
356       UImanager->ApplyCommand("/vis/scene/create");
357       currentScene = fpVisManager->GetCurrentScene();  // New current scene
358       G4bool successful = currentScene->AddRunDurationModel(pvModel,warn);
359       UImanager->ApplyCommand("/vis/sceneHandler/attach");
360 
361       if (successful) {
362         if (fpCommandDraw->GetNewBoolValue(newValue)) {
363           const auto& extent = pvModel->GetExtent();
364           const G4double halfX = (extent.GetXmax()-extent.GetXmin())/2.;
365           const G4double halfY = (extent.GetYmax()-extent.GetYmin())/2.;
366           const G4double halfZ = (extent.GetZmax()-extent.GetZmin())/2.;
367           G4Box extentBox("extent",halfX,halfY,halfZ);
368           G4VisAttributes extentVA;
369           extentVA.SetForceWireframe();
370           fpVisManager->Draw(extentBox,extentVA,G4Translate3D(extent.GetExtentCentre()));
371         }
372         if (verbosity >= G4VisManager::confirmations) {
373           G4cout << "\"" << properties.fpTouchablePV->GetName()
374           << "\", copy no. " << properties.fCopyNo << " drawn";
375           if (fpCommandDraw->GetNewBoolValue(newValue)) {
376             G4cout << " with extent box";
377           }
378           G4cout << '.' << G4endl;
379         }
380       } else {
381         G4VisCommandsSceneAddUnsuccessful(verbosity);
382       }
383     } else {
384       G4warn << "Touchable not found." << G4endl;
385     }
386     return;
387 
388   } else if (command == fpCommandExtentForField) {
389 
390     G4PhysicalVolumeModel::TouchableProperties properties =
391     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
392     if (properties.fpTouchablePV) {
393       G4VisExtent extent
394       = properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
395       extent.Transform(properties.fTouchableGlobalTransform);
396       fCurrentExtentForField = extent;
397       fCurrrentPVFindingsForField.clear();
398       if (verbosity >= G4VisManager::confirmations) {
399         G4cout << "Extent for field set to " << extent
400         << "\nVolume for field has been cleared."
401         << G4endl;
402       }
403       if (fpCommandExtentForField->GetNewBoolValue(newValue)) {
404         DrawExtent(extent);
405       }
406     } else {
407       G4warn << "Touchable not found." << G4endl;
408     }
409     return;
410 
411   } else if (command == fpCommandLocalAxes) {
412 
413     G4PhysicalVolumeModel::TouchableProperties properties =
414     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
415     if (properties.fpTouchablePV) {
416       const auto& transform = fCurrentTouchableProperties.fTouchableGlobalTransform;
417       const auto& extent = fCurrentTouchableProperties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
418       const G4double lengthMax = extent.GetExtentRadius()/2.;
419       const G4double intLog10LengthMax = std::floor(std::log10(lengthMax));
420       G4double length = std::pow(10,intLog10LengthMax);
421       if (5.*length < lengthMax) length *= 5.;
422       else if (2.*length < lengthMax) length *= 2.;
423       G4AxesModel axesModel(0.,0.,0.,length,transform);
424       axesModel.SetGlobalTag("LocalAxesModel");
425       axesModel.DescribeYourselfTo(*fpVisManager->GetCurrentSceneHandler());
426       G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/refresh");
427     } else {
428       G4warn << "Touchable not found." << G4endl;
429     }
430     return;
431 
432   } else if (command == fpCommandShowExtent) {
433 
434     G4PhysicalVolumeModel::TouchableProperties properties =
435     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
436     if (properties.fpTouchablePV) {
437       G4VisExtent extent
438       = properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
439       extent.Transform(properties.fTouchableGlobalTransform);
440       G4cout << extent << G4endl;
441       if (fpCommandShowExtent->GetNewBoolValue(newValue)) DrawExtent(extent);
442     } else {
443       G4warn << "Touchable not found." << G4endl;
444     }
445     return;
446 
447   } else if (command == fpCommandTwinkle) {
448 
449     G4PhysicalVolumeModel::TouchableProperties properties =
450     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
451     if (properties.fpTouchablePV) {
452       std::vector<std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>> touchables;
453       touchables.push_back(properties.fTouchableFullPVPath);
454       auto keepVisVerbose = fpVisManager->GetVerbosity();
455       fpVisManager->SetVerboseLevel(G4VisManager::errors);
456       auto keepVP = currentViewer->GetViewParameters();
457       Twinkle(currentViewer,currentViewer->GetViewParameters(),touchables);
458       SetViewParameters(currentViewer, keepVP);
459       fpVisManager->SetVerboseLevel(keepVisVerbose);
460     } else {
461       G4warn << "Touchable not found." << G4endl;
462     }
463     return;
464 
465   } else if (command == fpCommandVolumeForField) {
466 
467     G4PhysicalVolumeModel::TouchableProperties properties =
468     G4TouchableUtils::FindTouchableProperties(fCurrentTouchableProperties.fTouchablePath);
469     if (properties.fpTouchablePV) {
470       G4VisExtent extent
471       = properties.fpTouchablePV->GetLogicalVolume()->GetSolid()->GetExtent();
472       extent.Transform(properties.fTouchableGlobalTransform);
473       fCurrentExtentForField = extent;
474       fCurrrentPVFindingsForField.clear();
475       fCurrrentPVFindingsForField.push_back
476       (G4PhysicalVolumesSearchScene::Findings(properties));
477       if (verbosity >= G4VisManager::confirmations) {
478         G4cout
479         << "Volume for field set to " << properties.fpTouchablePV->GetName()
480         << ':' << properties.fCopyNo
481         << " at " << properties.fTouchableBaseFullPVPath
482         << G4endl;
483       }
484       if (fpCommandVolumeForField->GetNewBoolValue(newValue)) {
485         DrawExtent(extent);
486       }
487     } else {
488       G4warn << "Touchable not found." << G4endl;
489     }
490     return;
491 
492   } else {
493 
494     if (verbosity >= G4VisManager::errors) {
495       G4warn <<
496       "ERROR: G4VisCommandsTouchable::SetNewValue: unrecognised command."
497       << G4endl;
498     }
499     return;
500   }
501 }
502