G4VisCommandSceneAddScale Class Reference

#include <G4VisCommandsSceneAdd.hh>

Inheritance diagram for G4VisCommandSceneAddScale:

G4VVisCommandScene G4VVisCommand G4UImessenger

Public Member Functions

 G4VisCommandSceneAddScale ()
virtual ~G4VisCommandSceneAddScale ()
G4String GetCurrentValue (G4UIcommand *command)
void SetNewValue (G4UIcommand *command, G4String newValue)

Detailed Description

Definition at line 312 of file G4VisCommandsSceneAdd.hh.


Constructor & Destructor Documentation

G4VisCommandSceneAddScale::G4VisCommandSceneAddScale (  ) 

Definition at line 1711 of file G4VisCommandsSceneAdd.cc.

References G4Scale::GetGuidanceString(), G4UIparameter::SetDefaultValue(), G4UIparameter::SetGuidance(), and G4UIcommand::SetParameter().

01711                                                       {
01712   G4bool omitable;
01713   fpCommand = new G4UIcommand ("/vis/scene/add/scale", this);
01714   fpCommand -> SetGuidance 
01715     ("Adds an annotated scale line to the current scene.");
01716   fpCommand -> SetGuidance (G4Scale::GetGuidanceString());
01717   G4UIparameter* parameter;
01718   parameter = new G4UIparameter ("length", 'd', omitable = true);
01719   parameter->SetDefaultValue (1.);
01720   fpCommand->SetParameter (parameter);
01721   parameter =  new G4UIparameter ("unit", 's', omitable = true);
01722   parameter->SetGuidance
01723   ("auto or valid length unit - defaults to auto."
01724    "\nIf auto, length is roughly one tenth of the scene extent.");
01725   parameter->SetDefaultValue ("auto");
01726   fpCommand->SetParameter (parameter);
01727   parameter =  new G4UIparameter ("direction", 's', omitable = true);
01728   parameter->SetGuidance
01729   ("auto|x|y|z - defaults to auto."
01730    "\nIf auto, scale is roughly in the plane of the current view.");
01731   parameter->SetDefaultValue ("auto");
01732   fpCommand->SetParameter (parameter);
01733   parameter =  new G4UIparameter ("red", 'd', omitable = true);
01734   parameter->SetDefaultValue (1.);
01735   fpCommand->SetParameter (parameter);
01736   parameter =  new G4UIparameter ("green", 'd', omitable = true);
01737   parameter->SetDefaultValue (0.);
01738   fpCommand->SetParameter (parameter);
01739   parameter =  new G4UIparameter ("blue", 'd', omitable = true);
01740   parameter->SetDefaultValue (0.);
01741   fpCommand->SetParameter (parameter);
01742   parameter =  new G4UIparameter ("auto|manual", 's', omitable = true);
01743   parameter->SetGuidance
01744   ("Automatic placement or manual placement at (xmid,ymid,zmid)."
01745    "\nIf automatic, scale is placed at bottom left of current view.");
01746   parameter -> SetParameterCandidates("auto manual");
01747   parameter->SetDefaultValue  ("auto");
01748   fpCommand->SetParameter     (parameter);
01749   parameter =  new G4UIparameter ("xmid", 'd', omitable = true);
01750   parameter->SetDefaultValue (0.);
01751   fpCommand->SetParameter (parameter);
01752   parameter =  new G4UIparameter ("ymid", 'd', omitable = true);
01753   parameter->SetDefaultValue (0.);
01754   fpCommand->SetParameter (parameter);
01755   parameter =  new G4UIparameter ("zmid", 'd', omitable = true);
01756   parameter->SetDefaultValue (0.);
01757   fpCommand->SetParameter (parameter);
01758   parameter =  new G4UIparameter ("unit", 's', omitable = true);
01759   parameter->SetDefaultValue ("m");
01760   fpCommand->SetParameter (parameter);
01761 }

G4VisCommandSceneAddScale::~G4VisCommandSceneAddScale (  )  [virtual]

Definition at line 1763 of file G4VisCommandsSceneAdd.cc.

01763                                                        {
01764   delete fpCommand;
01765 }


Member Function Documentation

G4String G4VisCommandSceneAddScale::GetCurrentValue ( G4UIcommand command  )  [virtual]

Reimplemented from G4UImessenger.

Definition at line 1767 of file G4VisCommandsSceneAdd.cc.

01767                                                                  {
01768   return "";
01769 }

void G4VisCommandSceneAddScale::SetNewValue ( G4UIcommand command,
G4String  newValue 
) [virtual]

Reimplemented from G4UImessenger.

Definition at line 1771 of file G4VisCommandsSceneAdd.cc.

References G4VisManager::confirmations, G4VisManager::errors, G4VVisCommand::fpVisManager, G4BestUnit, G4cout, G4endl, G4VisManager::GetCurrentScene(), G4VisManager::GetCurrentViewer(), G4Scene::GetExtent(), G4VisExtent::GetExtentRadius(), G4ViewParameters::GetUpVector(), G4VisManager::GetVerbosity(), G4VViewer::GetViewParameters(), G4ViewParameters::GetViewpointDirection(), G4VisExtent::GetXmax(), G4VisExtent::GetXmin(), G4VisExtent::GetYmax(), G4VisExtent::GetYmin(), G4VisExtent::GetZmax(), G4VisExtent::GetZmin(), G4VisManager::parameters, G4VModel::SetExtent(), G4VModel::SetTransformation(), G4Visible::SetVisAttributes(), G4VVisCommand::UpdateVisManagerScene(), G4UIcommand::ValueOf(), G4VisManager::warnings, G4Scale::x, G4Scale::y, and G4Scale::z.

01771                                                                             {
01772 
01773   G4VisManager::Verbosity verbosity = fpVisManager->GetVerbosity();
01774   G4bool warn = verbosity >= G4VisManager::warnings;
01775 
01776   G4Scene* pScene = fpVisManager->GetCurrentScene();
01777   if (!pScene) {
01778     if (verbosity >= G4VisManager::errors) {
01779       G4cout << "ERROR: No current scene.  Please create one." << G4endl;
01780     }
01781     return;
01782   }
01783 
01784   G4double userLength, red, green, blue, xmid, ymid, zmid;
01785   G4String userLengthUnit, direction, auto_manual, positionUnit;
01786   std::istringstream is (newValue);
01787   is >> userLength >> userLengthUnit >> direction
01788      >> red >> green >> blue
01789      >> auto_manual
01790      >> xmid >> ymid >> zmid >> positionUnit;
01791 
01792   G4double length = userLength;
01793   const G4VisExtent& sceneExtent = pScene->GetExtent();  // Existing extent.
01794   if (userLengthUnit == "auto") {
01795     length *= sceneExtent.GetExtentRadius();
01796     G4double intLog10Length = std::floor(std::log10(length));
01797     length = std::pow(10,intLog10Length);
01798   } else {
01799     length *= G4UIcommand::ValueOf(userLengthUnit);
01800   }
01801   G4String annotation = G4BestUnit(length,"Length");
01802 
01803   G4double unit = G4UIcommand::ValueOf(positionUnit);
01804   xmid *= unit; ymid *= unit; zmid *= unit;
01805 
01806   G4Scale::Direction scaleDirection (G4Scale::x);
01807   if (direction(0) == 'y') scaleDirection = G4Scale::y;
01808   if (direction(0) == 'z') scaleDirection = G4Scale::z;
01809 
01810   G4VViewer* pViewer = fpVisManager->GetCurrentViewer();
01811   if (!pViewer) {
01812     if (verbosity >= G4VisManager::errors) {
01813       G4cout << 
01814         "ERROR: G4VisCommandSceneAddScale::SetNewValue: no viewer."
01815         "\n  Auto direction needs a viewer."
01816              << G4endl;
01817     }
01818     return;
01819   }
01820 
01821   const G4Vector3D& vp =
01822     pViewer->GetViewParameters().GetViewpointDirection();
01823   const G4Vector3D& up =
01824     pViewer->GetViewParameters().GetUpVector();
01825 
01826   if (direction == "auto") {  // Takes cue from viewer.
01827     if (std::abs(vp.x()) > std::abs(vp.y()) &&
01828         std::abs(vp.x()) > std::abs(vp.z())) {  // x viewpoint
01829       if (std::abs(up.y()) > std::abs(up.z())) scaleDirection = G4Scale::z;
01830           else scaleDirection = G4Scale::y;
01831     }
01832     else if (std::abs(vp.y()) > std::abs(vp.x()) &&
01833              std::abs(vp.y()) > std::abs(vp.z())) {  // y viewpoint
01834       if (std::abs(up.x()) > std::abs(up.z())) scaleDirection = G4Scale::z;
01835           else scaleDirection = G4Scale::x;
01836     }
01837     else if (std::abs(vp.z()) > std::abs(vp.x()) &&
01838              std::abs(vp.z()) > std::abs(vp.y())) {  // z viewpoint
01839       if (std::abs(up.y()) > std::abs(up.x())) scaleDirection = G4Scale::x;
01840           else scaleDirection = G4Scale::y;
01841     }
01842   }
01843 
01844   G4bool autoPlacing = false; if (auto_manual == "auto") autoPlacing = true;
01845   // Parameters read and interpreted.
01846 
01847   // Useful constants, etc...
01848   const G4double halfLength(length / 2.);
01849   const G4double comfort(0.01);  // 0.15 seems too big.  0.05 might be better.
01850   const G4double freeLengthFraction (1. + 2. * comfort);
01851 
01852   const G4double xmin = sceneExtent.GetXmin();
01853   const G4double xmax = sceneExtent.GetXmax();
01854   const G4double ymin = sceneExtent.GetYmin();
01855   const G4double ymax = sceneExtent.GetYmax();
01856   const G4double zmin = sceneExtent.GetZmin();
01857   const G4double zmax = sceneExtent.GetZmax();
01858 
01859   // Test existing extent and issue warnings...
01860   G4bool worried = false;
01861   if (sceneExtent.GetExtentRadius() == 0) {
01862     worried = true;
01863     if (verbosity >= G4VisManager::warnings) {
01864       G4cout <<
01865         "WARNING: Existing scene does not yet have any extent."
01866         "\n  Maybe you have not yet added any geometrical object."
01867              << G4endl;
01868     }
01869   }
01870   // Test existing scene for room...
01871   G4bool room  = true;
01872   switch (scaleDirection) {
01873   case G4Scale::x:
01874     if (freeLengthFraction * (xmax - xmin) < length) room = false; break;
01875   case G4Scale::y:
01876     if (freeLengthFraction * (ymax - ymin) < length) room = false; break;
01877   case G4Scale::z:
01878     if (freeLengthFraction * (zmax - zmin) < length) room = false; break;
01879   }
01880   if (!room) {
01881     worried = true;
01882     if (verbosity >= G4VisManager::warnings) {
01883       G4cout <<
01884         "WARNING: Not enough room in existing scene.  Maybe scale is too long."
01885              << G4endl;
01886     }
01887   }
01888   if (worried) {
01889     if (verbosity >= G4VisManager::warnings) {
01890       G4cout <<
01891         "WARNING: The scale you have asked for is bigger than the existing"
01892         "\n  scene.  Maybe you have added it too soon.  It is recommended that"
01893         "\n  you add the scale last so that it can be correctly auto-positioned"
01894         "\n  so as not to be obscured by any existing object and so that the"
01895         "\n  view parameters can be correctly recalculated."
01896              << G4endl;
01897     }
01898   }
01899 
01900   // Let's go ahead a construct a scale and a scale model.  Since the
01901   // placing is done here, this G4Scale is *not* auto-placed...
01902   G4Scale scale(length, annotation, scaleDirection,
01903                 false, xmid, ymid, zmid);
01904   G4VisAttributes* pVisAttr = new G4VisAttributes(G4Colour(red, green, blue));
01905   // Created of the heap because it needs a long lifetime.  This is a
01906   // mess.  The model determines the life but the vis atttributes are
01907   // associated with the scale.  There's no way of knowing when to
01908   // delete the vis atttributes!!!
01909   scale.SetVisAttributes(pVisAttr);
01910   G4VModel* model = new G4ScaleModel(scale);
01911 
01912   // Now figure out the extent...
01913   //
01914   // From the G4Scale.hh:
01915   //
01916   // This creates a representation of annotated line in the specified
01917   // direction with tick marks at the end.  If autoPlacing is true it
01918   // is required to be centred at the front, right, bottom corner of
01919   // the world space, comfortably outside the existing bounding
01920   // box/sphere so that existing objects do not obscure it.  Otherwise
01921   // it is required to be drawn with mid-point at (xmid, ymid, zmid).
01922   //
01923   // The auto placing algorithm might be:
01924   //   x = xmin + (1 + comfort) * (xmax - xmin)
01925   //   y = ymin - comfort * (ymax - ymin)
01926   //   z = zmin + (1 + comfort) * (zmax - zmin)
01927   //   if direction == x then (x - length,y,z) to (x,y,z)
01928   //   if direction == y then (x,y,z) to (x,y + length,z)
01929   //   if direction == z then (x,y,z - length) to (x,y,z)
01930   //
01931   // End of clip from G4Scale.hh:
01932   //
01933   // Implement this in two parts.  Here, use the scale's extent to
01934   // "expand" the scene's extent.  Then rendering - in
01935   // G4VSceneHandler::AddPrimitive(const G4Scale&) - simply has to
01936   // ensure it's within the new extent.
01937   //
01938 
01939   G4double sxmid(xmid), symid(ymid), szmid(zmid);
01940   if (autoPlacing) {
01941     // Aim to place at bottom right of screen in current view.
01942     // Give some comfort zone.
01943     const G4double xComfort = comfort * (xmax - xmin);
01944     const G4double yComfort = comfort * (ymax - ymin);
01945     const G4double zComfort = comfort * (zmax - zmin);
01946     switch (scaleDirection) {
01947     case G4Scale::x:
01948       if (vp.z() > 0.) {
01949         sxmid = xmax + xComfort;
01950         symid = ymin - yComfort;
01951         szmid = zmin - zComfort;
01952       } else {
01953         sxmid = xmin - xComfort;
01954         symid = ymin - yComfort;
01955         szmid = zmax + zComfort;
01956       }
01957       break;
01958     case G4Scale::y:
01959       if (vp.x() > 0.) {
01960         sxmid = xmin - xComfort;
01961         symid = ymax + yComfort;
01962         szmid = zmin - zComfort;
01963       } else {
01964         sxmid = xmax + xComfort;
01965         symid = ymin - yComfort;
01966         szmid = zmin - zComfort;
01967       }
01968       break;
01969     case G4Scale::z:
01970       if (vp.x() > 0.) {
01971         sxmid = xmax + xComfort;
01972         symid = ymin - yComfort;
01973         szmid = zmax + zComfort;
01974       } else {
01975         sxmid = xmin - xComfort;
01976         symid = ymin - yComfort;
01977         szmid = zmax + zComfort;
01978       }
01979       break;
01980     }
01981   }
01982 
01983   /* Old code - kept for future reference.
01984   G4double sxmid(xmid), symid(ymid), szmid(zmid);
01985   if (autoPlacing) {
01986     sxmid = xmin + onePlusComfort * (xmax - xmin);
01987     symid = ymin - comfort * (ymax - ymin);
01988     szmid = zmin + onePlusComfort * (zmax - zmin);
01989     switch (scaleDirection) {
01990     case G4Scale::x:
01991       sxmid -= halfLength;
01992       break;
01993     case G4Scale::y:
01994       symid += halfLength;
01995       break;
01996     case G4Scale::z:
01997       szmid -= halfLength;
01998       break;
01999     }
02000   }
02001   */
02002 
02003   /* sxmin, etc., not actually used.  Comment out to prevent compiler
02004      warnings but keep in case need in future.  Extract transform and
02005      scaleExtent into reduced code below.
02006   G4double sxmin(sxmid), sxmax(sxmid);
02007   G4double symin(symid), symax(symid);
02008   G4double szmin(szmid), szmax(szmid);
02009   G4Transform3D transform;
02010   G4VisExtent scaleExtent;
02011   switch (scaleDirection) {
02012   case G4Scale::x:
02013     sxmin = sxmid - halfLength;
02014     sxmax = sxmid + halfLength;
02015     scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
02016     break;
02017   case G4Scale::y:
02018     symin = symid - halfLength;
02019     symax = symid + halfLength;
02020     transform = G4RotateZ3D(halfpi);
02021     scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
02022     break;
02023   case G4Scale::z:
02024     szmin = szmid - halfLength;
02025     szmax = szmid + halfLength;
02026     transform = G4RotateY3D(halfpi);
02027     scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
02028     break;
02029   }
02030   */
02031   G4Transform3D transform;
02032   G4VisExtent scaleExtent;
02033   switch (scaleDirection) {
02034   case G4Scale::x:
02035     scaleExtent = G4VisExtent(-halfLength,halfLength,0,0,0,0);
02036     break;
02037   case G4Scale::y:
02038     transform = G4RotateZ3D(halfpi);
02039     scaleExtent = G4VisExtent(0,0,-halfLength,halfLength,0,0);
02040     break;
02041   case G4Scale::z:
02042     transform = G4RotateY3D(halfpi);
02043     scaleExtent = G4VisExtent(0,0,0,0,-halfLength,halfLength);
02044     break;
02045   }
02046   transform = G4Translate3D(sxmid,symid,szmid) * transform;
02048 
02049 
02050   model->SetTransformation(transform);
02051   // Note: it is the responsibility of the model to act upon this, but
02052   // the extent is in local coordinates...
02053   model->SetExtent(scaleExtent);
02054   // This extent gets "added" to existing scene extent in
02055   // AddRunDurationModel below.
02056 
02057   const G4String& currentSceneName = pScene -> GetName ();
02058   G4bool successful = pScene -> AddRunDurationModel (model, warn);
02059   if (successful) {
02060     if (verbosity >= G4VisManager::confirmations) {
02061       G4cout << "Scale of " << annotation
02062              << " added to scene \"" << currentSceneName << "\".";
02063       if (verbosity >= G4VisManager::parameters) {
02064         G4cout << "\n  with extent " << scaleExtent
02065                << "\n  at " << transform.getRotation()
02066                << transform.getTranslation();
02067       }
02068       G4cout << G4endl;
02069     }
02070   }
02071   else G4VisCommandsSceneAddUnsuccessful(verbosity);
02072   UpdateVisManagerScene (currentSceneName);
02073 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:45 2013 for Geant4 by  doxygen 1.4.7