Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/ToolsSG/src/G4ToolsSGSceneHandler.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 ]

Diff markup

Differences between /visualization/ToolsSG/src/G4ToolsSGSceneHandler.cc (Version 11.3.0) and /visualization/ToolsSG/src/G4ToolsSGSceneHandler.cc (Version 11.0)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // John Allison  6th October 2020                  26 // John Allison  6th October 2020
 27                                                    27 
 28 #include "G4ToolsSGSceneHandler.hh"                28 #include "G4ToolsSGSceneHandler.hh"
 29                                                    29 
 30 #include "G4ToolsSGNode.hh"                        30 #include "G4ToolsSGNode.hh"
 31                                                    31 
 32 #include "G4TransportationManager.hh"              32 #include "G4TransportationManager.hh"
 33 #include "G4Polyline.hh"                           33 #include "G4Polyline.hh"
 34 #include "G4Polymarker.hh"                         34 #include "G4Polymarker.hh"
 35 #include "G4Circle.hh"                             35 #include "G4Circle.hh"
 36 #include "G4Square.hh"                             36 #include "G4Square.hh"
 37 #include "G4Polyhedron.hh"                         37 #include "G4Polyhedron.hh"
 38 #include "G4Text.hh"                               38 #include "G4Text.hh"
 39 #include "G4Mesh.hh"                           << 
 40 #include "G4PlotterManager.hh"                     39 #include "G4PlotterManager.hh"
 41                                                    40 
 42 #include <tools/sg/separator>                      41 #include <tools/sg/separator>
 43 #include <tools/sg/matrix>                         42 #include <tools/sg/matrix>
 44 #include <tools/sg/rgba>                           43 #include <tools/sg/rgba>
 45 #include <tools/sg/draw_style>                     44 #include <tools/sg/draw_style>
 46 #include <tools/sg/atb_vertices>                   45 #include <tools/sg/atb_vertices>
 47 #include <tools/sg/markers>                        46 #include <tools/sg/markers>
 48 #ifdef TOOLS_USE_FREETYPE                          47 #ifdef TOOLS_USE_FREETYPE
 49 #include <toolx/sg/text_freetype>              <<  48 #include <tools/sg/text_freetype>
 50 #include <tools/sg/strings>                        49 #include <tools/sg/strings>
 51 #include <tools/font/lato_regular_ttf>             50 #include <tools/font/lato_regular_ttf>
 52 #include <tools/font/roboto_bold_ttf>              51 #include <tools/font/roboto_bold_ttf>
 53 #include <toolx/sg/text_freetype_marker>       <<  52 #include <tools/sg/text_freetype_marker>
 54 #else                                              53 #else
 55 #include <tools/sg/dummy_freetype>                 54 #include <tools/sg/dummy_freetype>
 56 #include <tools/sg/text_hershey_marker>            55 #include <tools/sg/text_hershey_marker>
 57 #endif                                             56 #endif
 58                                                    57 
 59 //for plotting:                                    58 //for plotting:
 60 #include <tools/sg/dummy_freetype>                 59 #include <tools/sg/dummy_freetype>
 61 #include <tools/sg/light_off>                      60 #include <tools/sg/light_off>
 62 #include <tools/sg/plots>                          61 #include <tools/sg/plots>
 63 #include <tools/sg/h2plot_cp>                      62 #include <tools/sg/h2plot_cp>
 64 #include <tools/sg/plotter_style>                  63 #include <tools/sg/plotter_style>
 65 #include <tools/sg/event_dispatcher>               64 #include <tools/sg/event_dispatcher>
 66 #include <tools/sg/path>                           65 #include <tools/sg/path>
 67 #include <tools/sg/search>                         66 #include <tools/sg/search>
 68 #include <tools/histo/h1d>                         67 #include <tools/histo/h1d>
 69 #include <tools/histo/h2d>                         68 #include <tools/histo/h2d>
 70 #include <tools/sg/plotter_some_styles>            69 #include <tools/sg/plotter_some_styles>
 71                                                    70 
 72 #include <utility>                                 71 #include <utility>
 73                                                    72 
 74 G4int G4ToolsSGSceneHandler::fSceneIdCount = 0     73 G4int G4ToolsSGSceneHandler::fSceneIdCount = 0;
 75                                                    74 
 76 G4ToolsSGSceneHandler::G4ToolsSGSceneHandler       75 G4ToolsSGSceneHandler::G4ToolsSGSceneHandler
 77 (G4VGraphicsSystem& system, const G4String& na     76 (G4VGraphicsSystem& system, const G4String& name)
 78 :parent(system, fSceneIdCount++, name)             77 :parent(system, fSceneIdCount++, name)
 79 ,fFreetypeNode(0)                                  78 ,fFreetypeNode(0)
 80 {                                                  79 {
 81   //::printf("debug : G4ToolsSGSceneHandler :      80   //::printf("debug : G4ToolsSGSceneHandler : %lu, %s\n",this,name.c_str());
 82   EstablishBaseNodes();                            81   EstablishBaseNodes();
 83 #if defined(TOOLS_USE_FREETYPE)                    82 #if defined(TOOLS_USE_FREETYPE)
 84   fFreetypeNode = new toolx::sg::text_freetype <<  83   fFreetypeNode = new tools::sg::text_freetype();
 85   fFreetypeNode->add_embedded_font(tools::sg::     84   fFreetypeNode->add_embedded_font(tools::sg::font_lato_regular_ttf(),tools::font::lato_regular_ttf);
 86   fFreetypeNode->add_embedded_font(tools::sg::     85   fFreetypeNode->add_embedded_font(tools::sg::font_roboto_bold_ttf(),tools::font::roboto_bold_ttf);
 87 #else                                              86 #else  
 88   fFreetypeNode = new tools::sg::dummy_freetyp     87   fFreetypeNode = new tools::sg::dummy_freetype();
 89 #endif                                             88 #endif
 90   Messenger::Create();                             89   Messenger::Create();
 91 }                                                  90 }
 92                                                    91 
 93 G4ToolsSGSceneHandler::~G4ToolsSGSceneHandler(     92 G4ToolsSGSceneHandler::~G4ToolsSGSceneHandler()
 94 {                                                  93 {
 95   //::printf("debug : ~G4ToolsSGSceneHandler :     94   //::printf("debug : ~G4ToolsSGSceneHandler : %lu\n",this);
 96   //WARNING : nodes may refer graphics manager     95   //WARNING : nodes may refer graphics managers (as tools/sg/[GL_manager,gl2ps_manager,zb_manager]
 97   //          used by viewers) to handle gstos     96   //          used by viewers) to handle gstos (for GPU) or textures, then we have to delete them first.
 98   //          It is assumed that we pass here      97   //          It is assumed that we pass here BEFORE the attached/managed viewers are deleted.
 99   fpTransient2DObjects.clear();                    98   fpTransient2DObjects.clear();
100   fpPersistent2DObjects.clear();                   99   fpPersistent2DObjects.clear();
101   fpTransient3DObjects.clear();                   100   fpTransient3DObjects.clear();
102   fpPersistent3DObjects.clear();                  101   fpPersistent3DObjects.clear();
103   delete fFreetypeNode;                           102   delete fFreetypeNode;
104 }                                                 103 }
105                                                   104 
106 void G4ToolsSGSceneHandler::EstablishBaseNodes    105 void G4ToolsSGSceneHandler::EstablishBaseNodes()
107 {                                                 106 {
108   // Physical volume objects for each world ha    107   // Physical volume objects for each world hang from POs
109   G4TransportationManager* transportationManag    108   G4TransportationManager* transportationManager = G4TransportationManager::GetTransportationManager ();
110   size_t nWorlds = transportationManager->GetN    109   size_t nWorlds = transportationManager->GetNoWorlds();
111   std::vector<G4VPhysicalVolume*>::iterator it    110   std::vector<G4VPhysicalVolume*>::iterator iterWorld = transportationManager->GetWorldsIterator();
112   fpPhysicalVolumeObjects.resize(nWorlds);        111   fpPhysicalVolumeObjects.resize(nWorlds);
113   for (size_t i = 0; i < nWorlds; ++i, ++iterW    112   for (size_t i = 0; i < nWorlds; ++i, ++iterWorld) {
114     G4VPhysicalVolume* _world = (*iterWorld);     113     G4VPhysicalVolume* _world = (*iterWorld);
115     auto entity = new G4ToolsSGNode;              114     auto entity = new G4ToolsSGNode;
116     fpPersistent3DObjects.add(entity);            115     fpPersistent3DObjects.add(entity);
117     entity->SetPVNodeID(G4PhysicalVolumeModel:    116     entity->SetPVNodeID(G4PhysicalVolumeModel::G4PhysicalVolumeNodeID(_world));
118     fpPhysicalVolumeObjects[i] = entity;          117     fpPhysicalVolumeObjects[i] = entity;
119   }                                               118   }
120 }                                                 119 }
121                                                   120 
122 tools::sg::separator* G4ToolsSGSceneHandler::G    121 tools::sg::separator* G4ToolsSGSceneHandler::GetOrCreateNode()
123 { // Retrieve or create a G4ToolsSGNode node s    122 { // Retrieve or create a G4ToolsSGNode node suitable for next solid or primitive
124                                                   123 
125   // For time being, avoid errors in MT mode -    124   // For time being, avoid errors in MT mode - see G4ToolsSGViewer::SwitchToMasterThread
                                                   >> 125 #ifdef G4MULTITHREADED
126   if (!G4Threading::IsMasterThread()) return n    126   if (!G4Threading::IsMasterThread()) return nullptr;
                                                   >> 127 #endif
127                                                   128 
128   if (fReadyForTransients) {  // All transient    129   if (fReadyForTransients) {  // All transients hang from this node
129     tools::sg::separator* sep = new tools::sg:    130     tools::sg::separator* sep = new tools::sg::separator;
130     fpTransient3DObjects.add(sep);                131     fpTransient3DObjects.add(sep);
131     return sep;                                   132     return sep;
132   }                                               133   }
133                                                   134 
134   auto* pPVModel = dynamic_cast<G4PhysicalVolu    135   auto* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
135                                                   136 
136   if (!pPVModel) {  // Persistent objects (e.g    137   if (!pPVModel) {  // Persistent objects (e.g., axes)
137     tools::sg::separator* sep = new tools::sg:    138     tools::sg::separator* sep = new tools::sg::separator;
138     fpPersistent3DObjects.add(sep);               139     fpPersistent3DObjects.add(sep);
139     return sep;                                   140     return sep;
140   }                                               141   }
141                                                   142 
142   // So this is a G4PhysicalVolumeModel           143   // So this is a G4PhysicalVolumeModel
143   typedef G4PhysicalVolumeModel::G4PhysicalVol    144   typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
144   typedef std::vector<PVNodeID> PVPath;           145   typedef std::vector<PVNodeID> PVPath;
145   //const PVPath& drawnPVPath = pPVModel->GetD    146   //const PVPath& drawnPVPath = pPVModel->GetDrawnPVPath();
146   const PVPath& fullPVPath  = pPVModel->GetFul    147   const PVPath& fullPVPath  = pPVModel->GetFullPVPath();
147   //G4int currentDepth = pPVModel->GetCurrentD    148   //G4int currentDepth = pPVModel->GetCurrentDepth();
148   //G4VPhysicalVolume* pCurrentPV = pPVModel->    149   //G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
149   //G4LogicalVolume* pCurrentLV = pPVModel->Ge    150   //G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
150   //G4Material* pCurrentMaterial = pPVModel->G    151   //G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
151   // Note: pCurrentMaterial may be zero (paral    152   // Note: pCurrentMaterial may be zero (parallel world).
152                                                   153 
153   // Find appropriate root                        154   // Find appropriate root
154   const size_t nWorlds = fpPhysicalVolumeObjec    155   const size_t nWorlds = fpPhysicalVolumeObjects.size();
155   size_t iWorld = 0;                              156   size_t iWorld = 0;
156   for (; iWorld < nWorlds; ++iWorld) {            157   for (; iWorld < nWorlds; ++iWorld) {
157     if (fullPVPath[0].GetPhysicalVolume() ==      158     if (fullPVPath[0].GetPhysicalVolume() ==
158         fpPhysicalVolumeObjects[iWorld]->GetPV    159         fpPhysicalVolumeObjects[iWorld]->GetPVNodeID().GetPhysicalVolume()) break;
159   }                                               160   }
160   if (iWorld == nWorlds) {                        161   if (iWorld == nWorlds) {
161     G4Exception("G4ToolsSGSceneHandler::GetOrC    162     G4Exception("G4ToolsSGSceneHandler::GetOrCreateNode", "ToolsSG-0000", FatalException,
162                 "World mis-match - not possibl    163                 "World mis-match - not possible(!?)");
163   }                                               164   }
164                                                   165 
165   // (Re-)establish pv path of root entity        166   // (Re-)establish pv path of root entity
166   G4ToolsSGNode* _world = fpPhysicalVolumeObje    167   G4ToolsSGNode* _world = fpPhysicalVolumeObjects[iWorld];
167   _world->SetPVNodeID(fullPVPath[0]);             168   _world->SetPVNodeID(fullPVPath[0]);
168                                                   169 
169   // Provide nodes as required - may be a new     170   // Provide nodes as required - may be a new node or a pre-existing node
170   G4ToolsSGNode* node = _world;  // Working va    171   G4ToolsSGNode* node = _world;  // Working variable - default to world
171   const size_t depth = fullPVPath.size();         172   const size_t depth = fullPVPath.size();
172   size_t iDepth = 1;                              173   size_t iDepth = 1;
173   while (iDepth < depth) {                        174   while (iDepth < depth) {
174     const auto& children = node->children();      175     const auto& children = node->children();
175     const G4int nChildren = (G4int)children.si << 176     const G4int nChildren = children.size();
176     G4int iChild = 0;                             177     G4int iChild = 0;
177     G4ToolsSGNode* child = nullptr;               178     G4ToolsSGNode* child = nullptr;
178     for (; iChild < nChildren; ++iChild) {        179     for (; iChild < nChildren; ++iChild) {
179       child = static_cast<G4ToolsSGNode*>(chil    180       child = static_cast<G4ToolsSGNode*>(children[iChild]);
180       if (child->GetPVNodeID() == fullPVPath[i    181       if (child->GetPVNodeID() == fullPVPath[iDepth]) break;
181     }                                             182     }
182     if (iChild != nChildren) {  // Existing no    183     if (iChild != nChildren) {  // Existing node found
183       node = child;  // Must be the ancestor o    184       node = child;  // Must be the ancestor of new node (subsequent iteration)
184     } else {                                      185     } else {
185       // Add a new node as child of node          186       // Add a new node as child of node
186       G4ToolsSGNode* newNode = new G4ToolsSGNo    187       G4ToolsSGNode* newNode = new G4ToolsSGNode;
187       node->add(newNode);                         188       node->add(newNode);
188       newNode->SetPVNodeID(fullPVPath[iDepth])    189       newNode->SetPVNodeID(fullPVPath[iDepth]);
189       node = newNode;                             190       node = newNode;
190     }                                             191     }
191     ++iDepth;                                     192     ++iDepth;
192   }                                               193   }
193   return node;                                    194   return node;
194 }                                                 195 }
195                                                   196 
196 void G4ToolsSGSceneHandler::ClearStore ()         197 void G4ToolsSGSceneHandler::ClearStore ()
197 {                                                 198 {
198   fpTransient2DObjects.clear();                   199   fpTransient2DObjects.clear();
199   fpPersistent2DObjects.clear();                  200   fpPersistent2DObjects.clear();
200   fpTransient3DObjects.clear();                   201   fpTransient3DObjects.clear();
201   fpPersistent3DObjects.clear();                  202   fpPersistent3DObjects.clear();
202   EstablishBaseNodes();                           203   EstablishBaseNodes();
203 }                                                 204 }
204                                                   205 
205 void G4ToolsSGSceneHandler::ClearTransientStor    206 void G4ToolsSGSceneHandler::ClearTransientStore ()
206 {                                                 207 {
207   fpTransient2DObjects.clear();                   208   fpTransient2DObjects.clear();
208   fpTransient3DObjects.clear();                   209   fpTransient3DObjects.clear();
209 }                                                 210 }
210                                                   211 
211 void G4ToolsSGSceneHandler::AddPrimitive(const    212 void G4ToolsSGSceneHandler::AddPrimitive(const G4Polyline& a_polyline)
212 {                                                 213 {
213   //G4cout << "debug : G4ToolsSGSceneHandler::    214   //G4cout << "debug : G4ToolsSGSceneHandler::AddPrimitive(const G4Polyline&) : \n" << a_polyline << G4endl;
214   if (a_polyline.size() == 0) return;             215   if (a_polyline.size() == 0) return;
215                                                   216 
216   tools::sg::separator* parentNode = 0;           217   tools::sg::separator* parentNode = 0;
217   if(fProcessing2D) {                             218   if(fProcessing2D) {
218     parentNode = new tools::sg::separator;        219     parentNode = new tools::sg::separator;
219     if (fReadyForTransients) {                    220     if (fReadyForTransients) {
220       fpTransient2DObjects.add(parentNode);       221       fpTransient2DObjects.add(parentNode);
221     } else {                                      222     } else {
222       fpPersistent2DObjects.add(parentNode);      223       fpPersistent2DObjects.add(parentNode);
223     }                                             224     }
224                                                   225 
225   } else {                                        226   } else {
226     parentNode = GetOrCreateNode();               227     parentNode = GetOrCreateNode();
227     if(!parentNode) return;                       228     if(!parentNode) return;
228                                                   229 
229     tools::sg::matrix* mtx = new tools::sg::ma    230     tools::sg::matrix* mtx = new tools::sg::matrix;
230     G4Transform3D& elem = fObjectTransformatio    231     G4Transform3D& elem = fObjectTransformation;
231     mtx->mtx.value().set_matrix(elem(0,0),elem    232     mtx->mtx.value().set_matrix(elem(0,0),elem(0,1),elem(0,2),elem(0,3),
232                                 elem(1,0),elem    233                                 elem(1,0),elem(1,1),elem(1,2),elem(1,3),
233                                 elem(2,0),elem    234                                 elem(2,0),elem(2,1),elem(2,2),elem(2,3),
234                                         0,        235                                         0,        0,        0,        1);
235     parentNode->add(mtx);                         236     parentNode->add(mtx);
236   }                                               237   }
237                                                   238 
238  {const auto& colour = GetColour(a_polyline);     239  {const auto& colour = GetColour(a_polyline);
239   tools::sg::rgba* mat = new tools::sg::rgba()    240   tools::sg::rgba* mat = new tools::sg::rgba();
240   mat->color =                                    241   mat->color =
241     tools::colorf(float(colour.GetRed()),         242     tools::colorf(float(colour.GetRed()),
242                   float(colour.GetGreen()),       243                   float(colour.GetGreen()),
243                   float(colour.GetBlue()),        244                   float(colour.GetBlue()),
244                   float(colour.GetAlpha()));      245                   float(colour.GetAlpha()));
245   parentNode->add(mat);}                          246   parentNode->add(mat);}
246                                                   247 
247  {tools::sg::draw_style* ds = new tools::sg::d    248  {tools::sg::draw_style* ds = new tools::sg::draw_style;
248   ds->style = tools::sg::draw_lines;              249   ds->style = tools::sg::draw_lines;
249   ds->line_width = 1;                             250   ds->line_width = 1;
250   parentNode->add(ds);}                           251   parentNode->add(ds);}
251                                                   252 
252   tools::sg::vertices* vtxs = new tools::sg::v    253   tools::sg::vertices* vtxs = new tools::sg::vertices;
253   vtxs->mode = tools::gl::line_strip();  //pol    254   vtxs->mode = tools::gl::line_strip();  //polyline
254   parentNode->add(vtxs);                          255   parentNode->add(vtxs);
255                                                   256   
256  {for (size_t i = 0; i < a_polyline.size(); ++    257  {for (size_t i = 0; i < a_polyline.size(); ++i) {
257     vtxs->add(float(a_polyline[i].x()),float(a    258     vtxs->add(float(a_polyline[i].x()),float(a_polyline[i].y()),float(a_polyline[i].z()));
258   }}                                              259   }}
259                                                   260   
260 }                                                 261 }
261                                                   262 
262 void G4ToolsSGSceneHandler::AddPrimitive (cons    263 void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
263 {                                                 264 {
264   //::printf("debug G4ToolsSGSceneHandler::Add    265   //::printf("debug G4ToolsSGSceneHandler::AddPrimitive(const G4Polymarker&) : %lu, type %d\n",
265   //     a_polymarker.size(),a_polymarker.GetM    266   //     a_polymarker.size(),a_polymarker.GetMarkerType());
266   if (a_polymarker.size() == 0) return;           267   if (a_polymarker.size() == 0) return;
267   auto currentNode = GetOrCreateNode();           268   auto currentNode = GetOrCreateNode();
268   if (!currentNode) return;  // Node not avail    269   if (!currentNode) return;  // Node not available
269                                                   270 
270   // Transformation                               271   // Transformation
271  {tools::sg::matrix* mtx = new tools::sg::matr    272  {tools::sg::matrix* mtx = new tools::sg::matrix;
272   G4Transform3D& elem = fObjectTransformation;    273   G4Transform3D& elem = fObjectTransformation;
273   mtx->mtx.value().set_matrix(elem(0,0),elem(0    274   mtx->mtx.value().set_matrix(elem(0,0),elem(0,1),elem(0,2),elem(0,3),
274                               elem(1,0),elem(1    275                               elem(1,0),elem(1,1),elem(1,2),elem(1,3),
275                               elem(2,0),elem(2    276                               elem(2,0),elem(2,1),elem(2,2),elem(2,3),
276                                       0,          277                                       0,        0,        0,        1);
277   currentNode->add(mtx);}                         278   currentNode->add(mtx);}
278                                                   279 
279  {const auto& colour = GetColour(a_polymarker)    280  {const auto& colour = GetColour(a_polymarker);
280   tools::sg::rgba* mat = new tools::sg::rgba()    281   tools::sg::rgba* mat = new tools::sg::rgba();
281   mat->color =                                    282   mat->color =
282     tools::colorf(float(colour.GetRed()),         283     tools::colorf(float(colour.GetRed()),
283                   float(colour.GetGreen()),       284                   float(colour.GetGreen()),
284                   float(colour.GetBlue()),        285                   float(colour.GetBlue()),
285                   float(colour.GetAlpha()));      286                   float(colour.GetAlpha()));
286   currentNode->add(mat);}                         287   currentNode->add(mat);}
287                                                   288 
288   MarkerSizeType markerSizeType;               << 
289   G4double markerSize = GetMarkerSize(a_polyma << 
290                                                << 
291   switch (a_polymarker.GetMarkerType()) {         289   switch (a_polymarker.GetMarkerType()) {
292     default:                                      290     default:
293     case G4Polymarker::dots:{                     291     case G4Polymarker::dots:{
294       //::printf("debug : GB : Add Markers : +    292       //::printf("debug : GB : Add Markers : +++++++++++++++++++++++++++++++++++++++++++ : dots\n");
295       tools::sg::draw_style* ds = new tools::s    293       tools::sg::draw_style* ds = new tools::sg::draw_style;
296       ds->style = tools::sg::draw_points;         294       ds->style = tools::sg::draw_points;
297       ds->point_size = 1;                      << 295       ds->point_size = 10;
298       currentNode->add(ds);                       296       currentNode->add(ds);
                                                   >> 297 
299       tools::sg::vertices* vtxs = new tools::s    298       tools::sg::vertices* vtxs = new tools::sg::vertices;
300       vtxs->mode = tools::gl::points();           299       vtxs->mode = tools::gl::points();
301      {for (size_t i = 0; i < a_polymarker.size    300      {for (size_t i = 0; i < a_polymarker.size(); ++i) {
302         vtxs->add(float(a_polymarker[i].x()),f    301         vtxs->add(float(a_polymarker[i].x()),float(a_polymarker[i].y()),float(a_polymarker[i].z()));
303       }}                                          302       }}
304       currentNode->add(vtxs);                     303       currentNode->add(vtxs);
305     }break;                                       304     }break;
306     case G4Polymarker::circles:{                  305     case G4Polymarker::circles:{
307       //::printf("debug : GB : Add Markers : +    306       //::printf("debug : GB : Add Markers : +++++++++++++++++++++++++++++++++++++++++++ : circles\n");
308      {tools::sg::markers* markers = new tools:    307      {tools::sg::markers* markers = new tools::sg::markers;
309       G4double diameter = markerSize;  // OK f << 308       markers->size = 10;
310       if (markerSizeType == G4VSceneHandler::w << 
311         const G4double scale = 200.;  // Rough << 
312         diameter *= fpScene->GetExtent().GetEx << 
313       }                                        << 
314       markers->size = diameter;                << 
315       markers->style = tools::sg::marker_circl    309       markers->style = tools::sg::marker_circle_line;
316       for (size_t i = 0; i < a_polymarker.size    310       for (size_t i = 0; i < a_polymarker.size(); ++i) {
317         markers->add(float(a_polymarker[i].x()    311         markers->add(float(a_polymarker[i].x()),float(a_polymarker[i].y()),float(a_polymarker[i].z()));
318       }                                           312       }
319       currentNode->add(markers);}                 313       currentNode->add(markers);}
320     }break;                                       314     }break;
321   case G4Polymarker::squares:{                    315   case G4Polymarker::squares:{
322     //::printf("debug : GB : Add Markers : +++    316     //::printf("debug : GB : Add Markers : +++++++++++++++++++++++++++++++++++++++++++ : square\n");
323      {tools::sg::markers* markers = new tools:    317      {tools::sg::markers* markers = new tools::sg::markers;
324       G4double side = markerSize;  // OK for " << 318       markers->size = 10;
325       if (markerSizeType == G4VSceneHandler::w << 
326         const G4double scale = 200.;  // Rough << 
327         side *= fpScene->GetExtent().GetExtent << 
328       }                                        << 
329       markers->size = side;                    << 
330       markers->style = tools::sg::marker_squar    319       markers->style = tools::sg::marker_square_line;
331       for (size_t i = 0; i < a_polymarker.size    320       for (size_t i = 0; i < a_polymarker.size(); ++i) {
332         markers->add(float(a_polymarker[i].x()    321         markers->add(float(a_polymarker[i].x()),float(a_polymarker[i].y()),float(a_polymarker[i].z()));
333       }                                           322       }
334       currentNode->add(markers);}                 323       currentNode->add(markers);}
335   }break;                                         324   }break;
336   }                                               325   }
337 }                                                 326 }
338                                                   327 
339 void G4ToolsSGSceneHandler::AddPrimitive(const    328 void G4ToolsSGSceneHandler::AddPrimitive(const G4Text& a_text)
340 {                                                 329 {
341   //::printf("debug : G4ToolsSGSceneHandler::A    330   //::printf("debug : G4ToolsSGSceneHandler::AddPrimitive(const G4Text&) : 000 : \"%s\"\n",a_text.GetText().c_str());
342   //::printf("debug : G4ToolsSGSceneHandler::A    331   //::printf("debug : G4ToolsSGSceneHandler::AddPrimitive(const G4Text&) : 2D ? %d\n",fProcessing2D);
343   auto pos = a_text.GetPosition();                332   auto pos = a_text.GetPosition();
344   //::printf("debug : Add Text : pos %g %g %g\    333   //::printf("debug : Add Text : pos %g %g %g\n",pos.x(),pos.y(),pos.z());
345                                                   334 
346   tools::sg::separator* parentNode = 0;           335   tools::sg::separator* parentNode = 0;
347   if(fProcessing2D) {                             336   if(fProcessing2D) {
348     parentNode = new tools::sg::separator;        337     parentNode = new tools::sg::separator;
349     if (fReadyForTransients) {                    338     if (fReadyForTransients) {
350       fpTransient2DObjects.add(parentNode);       339       fpTransient2DObjects.add(parentNode);
351     } else {                                      340     } else {
352       fpPersistent2DObjects.add(parentNode);      341       fpPersistent2DObjects.add(parentNode);
353     }                                             342     }
354                                                   343 
355     tools::sg::matrix* mtx = new tools::sg::ma    344     tools::sg::matrix* mtx = new tools::sg::matrix;
356     mtx->set_translate(pos.x(),pos.y(),pos.z()    345     mtx->set_translate(pos.x(),pos.y(),pos.z());
357     parentNode->add(mtx);                         346     parentNode->add(mtx);
358                                                   347 
359   } else {                                        348   } else {
360     parentNode = GetOrCreateNode();               349     parentNode = GetOrCreateNode();
361     if (!parentNode) return;                      350     if (!parentNode) return;
362                                                   351 
363     tools::sg::matrix* mtx = new tools::sg::ma    352     tools::sg::matrix* mtx = new tools::sg::matrix;
364     auto elem = fObjectTransformation*G4Transl    353     auto elem = fObjectTransformation*G4Translate3D(pos);
365     mtx->mtx.value().set_matrix(elem(0,0),elem    354     mtx->mtx.value().set_matrix(elem(0,0),elem(0,1),elem(0,2),elem(0,3),
366                                 elem(1,0),elem    355                                 elem(1,0),elem(1,1),elem(1,2),elem(1,3),
367                                 elem(2,0),elem    356                                 elem(2,0),elem(2,1),elem(2,2),elem(2,3),
368                                         0,        357                                         0,        0,        0,        1);
369     parentNode->add(mtx);                         358     parentNode->add(mtx);
370   }                                               359   }
371                                                   360 
372   MarkerSizeType sizeType;                        361   MarkerSizeType sizeType;
373   G4double size = GetMarkerSize(a_text, sizeTy    362   G4double size = GetMarkerSize(a_text, sizeType);
374                                                   363   
375  {const auto& colour = GetTextColour(a_text);     364  {const auto& colour = GetTextColour(a_text);
376   tools::sg::rgba* mat = new tools::sg::rgba()    365   tools::sg::rgba* mat = new tools::sg::rgba();
377   mat->color =                                    366   mat->color =
378     tools::colorf(float(colour.GetRed()),         367     tools::colorf(float(colour.GetRed()),
379                   float(colour.GetGreen()),       368                   float(colour.GetGreen()),
380                   float(colour.GetBlue()),        369                   float(colour.GetBlue()),
381                   float(colour.GetAlpha()));      370                   float(colour.GetAlpha()));
382   parentNode->add(mat);}                          371   parentNode->add(mat);}
383                                                   372  
384 #ifdef TOOLS_USE_FREETYPE                         373 #ifdef TOOLS_USE_FREETYPE
385   toolx::sg::text_freetype_marker* text = new  << 374   tools::sg::text_freetype_marker* text = new tools::sg::text_freetype_marker;
386   text->add_embedded_font(tools::sg::font_lato    375   text->add_embedded_font(tools::sg::font_lato_regular_ttf(),tools::font::lato_regular_ttf);
387   text->font = tools::sg::font_lato_regular_tt    376   text->font = tools::sg::font_lato_regular_ttf();
388   text->front_face = tools::sg::winding_cw;       377   text->front_face = tools::sg::winding_cw;
389 //text->modeling = tools::sg::font_pixmap; //p    378 //text->modeling = tools::sg::font_pixmap; //problem with Qt/GL. It slows rendering!
390 #else                                             379 #else
391   tools::sg::text_hershey_marker* text = new t    380   tools::sg::text_hershey_marker* text = new tools::sg::text_hershey_marker;
392 //text->encoding.value(a_encoding);               381 //text->encoding.value(a_encoding);
393 #endif                                            382 #endif
394   text->height = float(size); //pixels            383   text->height = float(size); //pixels
395   text->strings.add(a_text.GetText());            384   text->strings.add(a_text.GetText());
396  {switch (a_text.GetLayout()) {                   385  {switch (a_text.GetLayout()) {
397   default:                                        386   default:
398   case G4Text::left:                              387   case G4Text::left:
399     text->hjust = tools::sg::left;                388     text->hjust = tools::sg::left;
400     break;                                        389     break;
401   case G4Text::centre:                            390   case G4Text::centre:
402     text->hjust = tools::sg::center;              391     text->hjust = tools::sg::center;
403     break;                                        392     break;
404   case G4Text::right:                             393   case G4Text::right:
405     text->hjust = tools::sg::right;               394     text->hjust = tools::sg::right;
406     break;                                        395     break;
407   }}                                              396   }}
408 //text->vjust.value(a_vjust);                     397 //text->vjust.value(a_vjust);
409   parentNode->add(text);                          398   parentNode->add(text);
410                                                   399 
411 }                                                 400 }
412                                                   401 
413 void G4ToolsSGSceneHandler::AddPrimitive(const    402 void G4ToolsSGSceneHandler::AddPrimitive(const G4Circle& a_circle)
414 {                                                 403 {
415   G4Polymarker oneCircle(a_circle);               404   G4Polymarker oneCircle(a_circle);
416   oneCircle.push_back(a_circle.GetPosition());    405   oneCircle.push_back(a_circle.GetPosition());
417   oneCircle.SetMarkerType(G4Polymarker::circle    406   oneCircle.SetMarkerType(G4Polymarker::circles);
418   // Call this AddPrimitive to avoid re-doing     407   // Call this AddPrimitive to avoid re-doing sub-class code.
419   G4ToolsSGSceneHandler::AddPrimitive(oneCircl    408   G4ToolsSGSceneHandler::AddPrimitive(oneCircle);
420 }                                                 409 }
421                                                   410 
422 void G4ToolsSGSceneHandler::AddPrimitive(const    411 void G4ToolsSGSceneHandler::AddPrimitive(const G4Square& a_square)
423 {                                                 412 {
424   G4Polymarker oneSquare(a_square);               413   G4Polymarker oneSquare(a_square);
425   oneSquare.push_back(a_square.GetPosition());    414   oneSquare.push_back(a_square.GetPosition());
426   oneSquare.SetMarkerType(G4Polymarker::square    415   oneSquare.SetMarkerType(G4Polymarker::squares);
427   // Call this AddPrimitive to avoid re-doing     416   // Call this AddPrimitive to avoid re-doing sub-class code.
428   G4ToolsSGSceneHandler::AddPrimitive(oneSquar    417   G4ToolsSGSceneHandler::AddPrimitive(oneSquare);
429 }                                                 418 }
430                                                   419 
431 void G4ToolsSGSceneHandler::AddPrimitive(const    420 void G4ToolsSGSceneHandler::AddPrimitive(const G4Polyhedron& a_polyhedron)
432 {                                                 421 {
433   if (a_polyhedron.GetNoFacets() == 0) return;    422   if (a_polyhedron.GetNoFacets() == 0) return;
434                                                   423 
435   //::printf("debug : G4ToolsSGSceneHandler::A    424   //::printf("debug : G4ToolsSGSceneHandler::AddPrimitive(const G4Polyhedron&) : %d\n",a_polyhedron.GetNoFacets());
436                                                   425   
437   fpVisAttribs = fpViewer->GetApplicableVisAtt    426   fpVisAttribs = fpViewer->GetApplicableVisAttributes(a_polyhedron.GetVisAttributes());
438                                                   427 
439   // Roll out vertices and normals for the fac    428   // Roll out vertices and normals for the faces. Note that this means vertices
440   // are duplicated. For example a box has 8 v    429   // are duplicated. For example a box has 8 vertices, but to define 6 faces
441   // you need 12 triangles and 36 vertices. If    430   // you need 12 triangles and 36 vertices. If it was just a matter of vertices
442   // we could restrict the number to 8 and use    431   // we could restrict the number to 8 and use the indices to define the
443   // triangles, but we also have to consider t    432   // triangles, but we also have to consider the normals. A vertex can be have
444   // more than one normal, depending on which     433   // more than one normal, depending on which face it is being used to define.
445   // So we roll out all the vertices and norma    434   // So we roll out all the vertices and normals for each triangle.
446   std::vector<G4Point3D> vertices;                435   std::vector<G4Point3D> vertices;
447   std::vector<G4Normal3D> normals;                436   std::vector<G4Normal3D> normals;
448                                                   437 
449   // Also roll out edges (as lines) for wirefr    438   // Also roll out edges (as lines) for wireframe. Avoid duplicate lines,
450   // including those that differ only in the o    439   // including those that differ only in the order of vertices.
451   typedef std::pair<G4Point3D,G4Point3D> Line;    440   typedef std::pair<G4Point3D,G4Point3D> Line;
452   std::vector<Line> lines;                        441   std::vector<Line> lines;
453   auto insertIfNew = [&lines](const Line& newL    442   auto insertIfNew = [&lines](const Line& newLine) {
454 //    for (const auto& line: lines) {          << 443     for (const auto& line: lines) {
455 //      if ((newLine.first==line.first && newL << 444       if ((newLine.first==line.first && newLine.second==line.second) ||
456 //          (newLine.first==line.second && new << 445           (newLine.first==line.second && newLine.second==line.first))
457 //      return;                                << 446       return;
458 //    }                                        << 447     }
459     lines.push_back(newLine);                     448     lines.push_back(newLine);
460   };                                              449   };
461                                                   450 
462   G4bool isAuxilaryEdgeVisible = fpViewer->Get    451   G4bool isAuxilaryEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible();
463   G4bool notLastFace;                             452   G4bool notLastFace;
464   do {                                            453   do {
465     G4int      nEdges;                            454     G4int      nEdges;
466     G4Point3D  vertex  [4];                       455     G4Point3D  vertex  [4];
467     G4int      edgeFlag[4];                       456     G4int      edgeFlag[4];
468     G4Normal3D normal  [4];                       457     G4Normal3D normal  [4];
469     notLastFace = a_polyhedron.GetNextFacet(nE    458     notLastFace = a_polyhedron.GetNextFacet(nEdges, vertex, edgeFlag, normal);
470     vertices.push_back(vertex[0]);                459     vertices.push_back(vertex[0]);
471     vertices.push_back(vertex[1]);                460     vertices.push_back(vertex[1]);
472     vertices.push_back(vertex[2]);                461     vertices.push_back(vertex[2]);
473     normals.push_back(normal[0]);                 462     normals.push_back(normal[0]);
474     normals.push_back(normal[1]);                 463     normals.push_back(normal[1]);
475     normals.push_back(normal[2]);                 464     normals.push_back(normal[2]);
476     if(isAuxilaryEdgeVisible||edgeFlag[0]>0)in    465     if(isAuxilaryEdgeVisible||edgeFlag[0]>0)insertIfNew(Line(vertex[0],vertex[1]));
477     if(isAuxilaryEdgeVisible||edgeFlag[1]>0)in    466     if(isAuxilaryEdgeVisible||edgeFlag[1]>0)insertIfNew(Line(vertex[1],vertex[2]));
478     if (nEdges == 3) {                            467     if (nEdges == 3) {
479       // Face is a triangle                       468       // Face is a triangle
480       // One more line for wireframe, triangle    469       // One more line for wireframe, triangles for surfaces are complete
481       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)    470       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)insertIfNew(Line(vertex[2],vertex[0]));
482     } else if (nEdges == 4) {                     471     } else if (nEdges == 4) {
483       // Face is a quadrilateral                  472       // Face is a quadrilateral
484       // Create another triangle for surfaces,    473       // Create another triangle for surfaces, add two more lines for wireframe
485       vertices.push_back(vertex[2]);              474       vertices.push_back(vertex[2]);
486       vertices.push_back(vertex[3]);              475       vertices.push_back(vertex[3]);
487       vertices.push_back(vertex[0]);              476       vertices.push_back(vertex[0]);
488       normals.push_back(normal[2]);               477       normals.push_back(normal[2]);
489       normals.push_back(normal[3]);               478       normals.push_back(normal[3]);
490       normals.push_back(normal[0]);               479       normals.push_back(normal[0]);
491       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)    480       if(isAuxilaryEdgeVisible||edgeFlag[2]>0)insertIfNew(Line(vertex[2],vertex[3]));
492       if(isAuxilaryEdgeVisible||edgeFlag[3]>0)    481       if(isAuxilaryEdgeVisible||edgeFlag[3]>0)insertIfNew(Line(vertex[3],vertex[0]));
493     } else {                                      482     } else {
494       G4cerr                                      483       G4cerr
495       << "ERROR: polyhedron face with unexpect    484       << "ERROR: polyhedron face with unexpected number of edges (" << nEdges << ')'
496       << "\n  Tag: " << fpModel->GetCurrentTag    485       << "\n  Tag: " << fpModel->GetCurrentTag()
497       << G4endl;                                  486       << G4endl;
498       return;                                     487       return;
499     }                                             488     }
500   } while (notLastFace);                          489   } while (notLastFace);
501                                                   490 
502   G4ViewParameters::DrawingStyle drawing_style    491   G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (fpVisAttribs);
503   switch (drawing_style) {                        492   switch (drawing_style) {
504     case G4ViewParameters::wireframe:             493     case G4ViewParameters::wireframe:
505       //vertices.clear();                         494       //vertices.clear();
506       break;                                      495       break;
507     case G4ViewParameters::hlr:                   496     case G4ViewParameters::hlr:
508       break;                                      497       break;
509     case G4ViewParameters::hsr:                   498     case G4ViewParameters::hsr:
510       //lines.clear();                            499       //lines.clear();
511       break;                                      500       break;
512     case G4ViewParameters::hlhsr:                 501     case G4ViewParameters::hlhsr:
513       break;                                      502       break;
514     case G4ViewParameters::cloud:                 503     case G4ViewParameters::cloud:
515       // Shouldn't happen in this function (it    504       // Shouldn't happen in this function (it's a polyhedron!) - ignore
516       return;                                     505       return;
517   }                                               506   }
518                                                   507 
519   auto currentNode = GetOrCreateNode();           508   auto currentNode = GetOrCreateNode();
520   if (!currentNode) return;  // Node not avail    509   if (!currentNode) return;  // Node not available
521                                                   510   
522   tools::sg::separator* sep = new tools::sg::s    511   tools::sg::separator* sep = new tools::sg::separator;
523   currentNode->add(sep);                          512   currentNode->add(sep);
524                                                   513 
525   // Transformation                               514   // Transformation
526  {tools::sg::matrix* mtx = new tools::sg::matr    515  {tools::sg::matrix* mtx = new tools::sg::matrix;
527   G4Transform3D& elem = fObjectTransformation;    516   G4Transform3D& elem = fObjectTransformation;
528   mtx->mtx.value().set_matrix(elem(0,0),elem(0    517   mtx->mtx.value().set_matrix(elem(0,0),elem(0,1),elem(0,2),elem(0,3),
529                               elem(1,0),elem(1    518                               elem(1,0),elem(1,1),elem(1,2),elem(1,3),
530                               elem(2,0),elem(2    519                               elem(2,0),elem(2,1),elem(2,2),elem(2,3),
531                                       0,          520                                       0,        0,        0,        1);
532   sep->add(mtx);}                                 521   sep->add(mtx);}
533                                                   522 
534  {const auto& colour = GetColour(a_polyhedron)    523  {const auto& colour = GetColour(a_polyhedron);
535   tools::sg::rgba* mat = new tools::sg::rgba()    524   tools::sg::rgba* mat = new tools::sg::rgba();
536   mat->color =                                    525   mat->color =
537     tools::colorf(float(colour.GetRed()),         526     tools::colorf(float(colour.GetRed()),
538                   float(colour.GetGreen()),       527                   float(colour.GetGreen()),
539                   float(colour.GetBlue()),        528                   float(colour.GetBlue()),
540                   float(colour.GetAlpha()));      529                   float(colour.GetAlpha()));
541   sep->add(mat);}                                 530   sep->add(mat);}
542                                                   531 
543   if (drawing_style == G4ViewParameters::hlr |    532   if (drawing_style == G4ViewParameters::hlr ||
544       drawing_style == G4ViewParameters::hsr |    533       drawing_style == G4ViewParameters::hsr ||
545       drawing_style == G4ViewParameters::hlhsr    534       drawing_style == G4ViewParameters::hlhsr) {
546                                                   535 
547    {tools::sg::draw_style* ds = new tools::sg:    536    {tools::sg::draw_style* ds = new tools::sg::draw_style;
548     ds->style = tools::sg::draw_filled;           537     ds->style = tools::sg::draw_filled;
549   //ds->cull_face = true;                         538   //ds->cull_face = true;
550     sep->add(ds);}                                539     sep->add(ds);}
551                                                   540 
552     tools::sg::atb_vertices* vtxs = new tools:    541     tools::sg::atb_vertices* vtxs = new tools::sg::atb_vertices;
553     vtxs->mode = tools::gl::triangles();          542     vtxs->mode = tools::gl::triangles();
554     sep->add(vtxs);                               543     sep->add(vtxs);
555                                                   544     
556     const auto nVerts = vertices.size();          545     const auto nVerts = vertices.size();
557     for (size_t i = 0; i < nVerts; i++) {         546     for (size_t i = 0; i < nVerts; i++) {
558       vtxs->add(float(vertices[i].x()),float(v    547       vtxs->add(float(vertices[i].x()),float(vertices[i].y()),float(vertices[i].z()));
559       vtxs->add_normal(float(normals[i].x()),f    548       vtxs->add_normal(float(normals[i].x()),float(normals[i].y()),float(normals[i].z()));
560     }                                             549     }
561   }                                               550   }
562                                                   551 
563   if (drawing_style == G4ViewParameters::wiref    552   if (drawing_style == G4ViewParameters::wireframe ||
564       drawing_style == G4ViewParameters::hlr |    553       drawing_style == G4ViewParameters::hlr ||
565       drawing_style == G4ViewParameters::hlhsr    554       drawing_style == G4ViewParameters::hlhsr) {
566                                                   555 
567    {tools::sg::draw_style* ds = new tools::sg:    556    {tools::sg::draw_style* ds = new tools::sg::draw_style;
568     ds->style = tools::sg::draw_lines;            557     ds->style = tools::sg::draw_lines;
569     ds->line_width = 1;                           558     ds->line_width = 1;
570     sep->add(ds);}                                559     sep->add(ds);}
571                                                   560 
572     tools::sg::vertices* vtxs = new tools::sg:    561     tools::sg::vertices* vtxs = new tools::sg::vertices;
573     vtxs->mode = tools::gl::lines();  //segmen    562     vtxs->mode = tools::gl::lines();  //segments
574     sep->add(vtxs);                               563     sep->add(vtxs);
575                                                   564     
576     for (const auto& line: lines) {               565     for (const auto& line: lines) {
577       vtxs->add(float(line.first.x()),float(li    566       vtxs->add(float(line.first.x()),float(line.first.y()),float(line.first.z()));
578       vtxs->add(float(line.second.x()),float(l    567       vtxs->add(float(line.second.x()),float(line.second.y()),float(line.second.z()));
579     }                                             568     }
580                                                   569   
581   }                                               570   }
582 }                                                 571 }
583                                                   572 
584 void G4ToolsSGSceneHandler::AddCompound(const  << 
585 {                                              << 
586   StandardSpecialMeshRendering(mesh);          << 
587 }                                              << 
588                                                << 
589 //plotting:                                       573 //plotting:
590 inline void SetRegionStyles(tools::xml::styles    574 inline void SetRegionStyles(tools::xml::styles& a_styles,
591                 tools::sg::plots& a_plots,        575                 tools::sg::plots& a_plots,
592                 tools::sg::plotter& a_plotter,    576                 tools::sg::plotter& a_plotter,
593                             const G4String& a_    577                             const G4String& a_style) {
594   if(a_style=="reset") {                          578   if(a_style=="reset") {
595     a_plotter.reset_style(true);                  579     a_plotter.reset_style(true);
596     a_plots.touch(); //to apply indirectly plo    580     a_plots.touch(); //to apply indirectly plots::set_plotter_layout() on _plotter.
597   } else if( (a_style=="inlib_default")|| (a_s    581   } else if( (a_style=="inlib_default")|| (a_style=="default")) {
598     tools::sg::set_inlib_default_style(G4cout,    582     tools::sg::set_inlib_default_style(G4cout,a_styles.cmaps(),a_plotter,tools::sg::font_hershey());
599   } else if(a_style=="ROOT_default") {            583   } else if(a_style=="ROOT_default") {
600     tools::sg::set_ROOT_default_style(G4cout,a    584     tools::sg::set_ROOT_default_style(G4cout,a_styles.cmaps(),a_plotter,tools::sg::font_roboto_bold_ttf());
601   } else if(a_style=="hippodraw") {               585   } else if(a_style=="hippodraw") {
602     tools::sg::set_hippodraw_style(G4cout,a_st    586     tools::sg::set_hippodraw_style(G4cout,a_styles.cmaps(),a_plotter,tools::sg::font_lato_regular_ttf());
603   } else {                                        587   } else {
604     tools::sg::style_from_res(a_styles,a_style    588     tools::sg::style_from_res(a_styles,a_style,a_plotter,false);
605   }                                               589   }
606 }                                                 590 }
607                                                   591 
608 inline tools::xml::styles::style_t* find_style    592 inline tools::xml::styles::style_t* find_style(tools::xml::styles& a_styles,const std::string& a_name) {
609   tools_vforit(tools::xml::styles::named_style    593   tools_vforit(tools::xml::styles::named_style_t,a_styles.named_styles(),it){
610     if((*it).first==a_name) return &((*it).sec    594     if((*it).first==a_name) return &((*it).second);
611   }                                               595   }
612   return 0;                                       596   return 0;
613 }                                                 597 }
614                                                   598 
615 inline void SetPlotterStyles(tools::sg::plots&    599 inline void SetPlotterStyles(tools::sg::plots& a_plots,
616                              const std::vector    600                              const std::vector<G4String>& a_plotter_styles,
617                              const std::vector    601                              const std::vector<G4Plotter::RegionStyle>& a_region_styles) {
618                                                   602 
619   G4PlotterManager::Styles& _styles = G4Plotte    603   G4PlotterManager::Styles& _styles = G4PlotterManager::GetInstance().GetStyles();
620                                                   604  
621   tools::xml::styles _tools_styles(G4cout);       605   tools::xml::styles _tools_styles(G4cout);
622   _tools_styles.add_colormap("default",tools::    606   _tools_styles.add_colormap("default",tools::sg::style_default_colormap());
623   _tools_styles.add_colormap("ROOT",tools::sg:    607   _tools_styles.add_colormap("ROOT",tools::sg::style_ROOT_colormap());
624                                                   608   
625  {tools_vforcit(G4PlotterManager::NamedStyle,_    609  {tools_vforcit(G4PlotterManager::NamedStyle,_styles,it) {
626     tools::xml::styles::style_t _tools_style;     610     tools::xml::styles::style_t _tools_style;
627     tools_vforcit(G4PlotterManager::StyleItem,    611     tools_vforcit(G4PlotterManager::StyleItem,(*it).second,its) {
628       const G4String& param = (*its).first;       612       const G4String& param = (*its).first;
629       if(param.find('.')==std::string::npos) {    613       if(param.find('.')==std::string::npos) {
630         const G4String& value = (*its).second;    614         const G4String& value = (*its).second;
631         _tools_style.push_back(tools::xml::sty    615         _tools_style.push_back(tools::xml::styles::style_item_t(param,value));
632       }                                           616       }
633     }                                             617     }
634     _tools_styles.add_style((*it).first,_tools    618     _tools_styles.add_style((*it).first,_tools_style);
635   }}                                              619   }}
636                                                   620 
637   // sub styles:                                  621   // sub styles:
638  {tools_vforcit(G4PlotterManager::NamedStyle,_    622  {tools_vforcit(G4PlotterManager::NamedStyle,_styles,it) {
639     tools_vforcit(G4PlotterManager::StyleItem,    623     tools_vforcit(G4PlotterManager::StyleItem,(*it).second,its) {
640       const G4String& param = (*its).first;       624       const G4String& param = (*its).first;
641       std::string::size_type pos = param.rfind    625       std::string::size_type pos = param.rfind('.');
642       if(pos!=std::string::npos) {                626       if(pos!=std::string::npos) {
643   std::string sub_style = (*it).first+"."+para    627   std::string sub_style = (*it).first+"."+param.substr(0,pos);
644         G4String parameter = param.substr(pos+    628         G4String parameter = param.substr(pos+1,param.size()-pos);
645         const G4String& value = (*its).second;    629         const G4String& value = (*its).second;
646         tools::xml::styles::style_t* _tools_st    630         tools::xml::styles::style_t* _tools_style = find_style(_tools_styles,sub_style);
647   if(_tools_style) {                              631   if(_tools_style) {
648           _tools_style->push_back(tools::xml::    632           _tools_style->push_back(tools::xml::styles::style_item_t(parameter,value));
649   } else {                                        633   } else {
650           tools::xml::styles::style_t _tools_s    634           tools::xml::styles::style_t _tools_style_2;
651           _tools_style_2.push_back(tools::xml:    635           _tools_style_2.push_back(tools::xml::styles::style_item_t(parameter,value));
652           _tools_styles.add_style(sub_style,_t    636           _tools_styles.add_style(sub_style,_tools_style_2);
653   }                                               637   }
654       }                                           638       }
655     }                                             639     }
656   }}                                              640   }}
657                                                   641 
658  {unsigned int number = a_plots.number();         642  {unsigned int number = a_plots.number();
659   for(unsigned int index=0;index<number;index+    643   for(unsigned int index=0;index<number;index++) {
660     tools::sg::plotter* _plotter = a_plots.fin    644     tools::sg::plotter* _plotter = a_plots.find_plotter(index);
661     if(_plotter) {                                645     if(_plotter) {
662       tools_vforcit(G4String,a_plotter_styles,    646       tools_vforcit(G4String,a_plotter_styles,it) {
663         SetRegionStyles(_tools_styles,a_plots,    647         SetRegionStyles(_tools_styles,a_plots,*_plotter,*it);
664       }                                           648       }
665     }                                             649     }
666   }}                                              650   }}
667  {tools_vforcit(G4Plotter::RegionStyle,a_regio    651  {tools_vforcit(G4Plotter::RegionStyle,a_region_styles,it) {
668     tools::sg::plotter* _plotter = a_plots.fin    652     tools::sg::plotter* _plotter = a_plots.find_plotter((*it).first);
669     if(_plotter) {                                653     if(_plotter) {
670       SetRegionStyles(_tools_styles,a_plots,*_    654       SetRegionStyles(_tools_styles,a_plots,*_plotter,(*it).second);
671     }                                             655     }
672   }}                                              656   }}
673 }                                                 657 }
674                                                   658 
675 inline void SetPlotterParameters(tools::sg::cm    659 inline void SetPlotterParameters(tools::sg::cmaps_t& a_cmaps,tools::sg::plots& a_plots,
676                                  const std::ve    660                                  const std::vector<G4Plotter::RegionParameter>& a_region_parameters) {
677   // parameter/field examples :                   661   // parameter/field examples :
678   //   title_automated                            662   //   title_automated
679   //   title                                      663   //   title
680   //   bins_style.0.color                         664   //   bins_style.0.color
681   //   x_axis.divisions                           665   //   x_axis.divisions
682   //   x_axis.line_style.color                    666   //   x_axis.line_style.color
683   //   background_style.back_color                667   //   background_style.back_color
684   tools_vforcit(G4Plotter::RegionParameter,a_r    668   tools_vforcit(G4Plotter::RegionParameter,a_region_parameters,it) {
685     tools::sg::plotter* _plotter = a_plots.fin    669     tools::sg::plotter* _plotter = a_plots.find_plotter((*it).first);
686     if(_plotter) {                                670     if(_plotter) {
687       const G4String& parameter = (*it).second    671       const G4String& parameter = (*it).second.first;
688       const G4String& value = (*it).second.sec    672       const G4String& value = (*it).second.second;
689       tools::sg::field* fd = _plotter->find_fi    673       tools::sg::field* fd = _plotter->find_field_by_name(parameter);
690       if(!fd) fd = _plotter->find_field_by_nam    674       if(!fd) fd = _plotter->find_field_by_name(_plotter->s_cls()+"."+parameter);
691       if(fd) {if(fd->s2value(value)) continue;    675       if(fd) {if(fd->s2value(value)) continue;}
692       // look for sf_enum for which value is g    676       // look for sf_enum for which value is given with a string, or
693       // for sf<bool> for which value given wi    677       // for sf<bool> for which value given with true/false, or
694       // for a style, for example: bins_style.    678       // for a style, for example: bins_style.0.color:
695       if(!_plotter->set_from_string(G4cout,a_c    679       if(!_plotter->set_from_string(G4cout,a_cmaps,parameter,value)) {
696         G4cout << "G4ToolsSGSceneHandler::SetP    680         G4cout << "G4ToolsSGSceneHandler::SetPlotterParameters: plotter.set_from_string() failed for field "
697                << tools::sout(parameter) << ",    681                << tools::sout(parameter) << ", and value " << tools::sout(value) << "."
698                << std::endl;                      682                << std::endl;
699       }                                           683       }
700     }                                             684     }
701   }                                               685   }
702 }                                                 686 }
703                                                   687 
704 #include "G4UImanager.hh"                         688 #include "G4UImanager.hh"
705                                                   689 
706 void G4ToolsSGSceneHandler::SetPlotterHistogra    690 void G4ToolsSGSceneHandler::SetPlotterHistograms(tools::sg::plots& a_plots) {
707   a_plots.clear();                                691   a_plots.clear();
708   G4UImanager* UI = G4UImanager::GetUIpointer(    692   G4UImanager* UI = G4UImanager::GetUIpointer();
709   if(UI==NULL) return;                            693   if(UI==NULL) return;
710  {tools_vforcit(Region_h1,fRegionH1s,it) {        694  {tools_vforcit(Region_h1,fRegionH1s,it) {
711     tools::sg::plotter* _plotter = a_plots.fin    695     tools::sg::plotter* _plotter = a_plots.find_plotter((*it).first);
712     if(_plotter) {                                696     if(_plotter) {
713       int hid = (*it).second;                     697       int hid = (*it).second;
714       std::ostringstream os;                      698       std::ostringstream os;
715       os << hid;                                  699       os << hid;
716       std::string cmd("/analysis/h1/get ");       700       std::string cmd("/analysis/h1/get ");
717       cmd += std::string(os.str());               701       cmd += std::string(os.str());
718       auto keepControlVerbose = UI->GetVerbose << 
719       UI->SetVerboseLevel(0);                  << 
720       G4int status = UI->ApplyCommand(cmd.c_st    702       G4int status = UI->ApplyCommand(cmd.c_str());
721       UI->SetVerboseLevel(keepControlVerbose); << 
722       if(status==G4UIcommandStatus::fCommandSu    703       if(status==G4UIcommandStatus::fCommandSucceeded) {
723         G4String hexString = UI->GetCurrentVal    704         G4String hexString = UI->GetCurrentValues("/analysis/h1/get");
724         if(hexString.size()) {                    705         if(hexString.size()) {
725           void* ptr;                              706           void* ptr;
726           std::istringstream is(hexString);       707           std::istringstream is(hexString);
727           is >> ptr;                              708           is >> ptr;
728           tools::histo::h1d* _h = (tools::hist    709           tools::histo::h1d* _h = (tools::histo::h1d*)ptr;
729           tools::sg::plottable* p = new tools:    710           tools::sg::plottable* p = new tools::sg::h1d2plot_cp(*_h);
730           _plotter->add_plottable(p); //give o    711           _plotter->add_plottable(p); //give ownership of p to sg::plotter.
731         }                                         712         }
732       } else {                                 << 
733         G4cerr <<                              << 
734         "G4ToolsSGSceneHandler::SetPlotterHist << 
735         "\n  Maybe this app does not do analys << 
736         << G4endl;                             << 
737       }                                           713       }
738     }                                             714     }
739   }}                                              715   }}
740  {tools_vforcit(Region_h2,fRegionH2s,it) {        716  {tools_vforcit(Region_h2,fRegionH2s,it) {
741     tools::sg::plotter* _plotter = a_plots.fin    717     tools::sg::plotter* _plotter = a_plots.find_plotter((*it).first);
742     if(_plotter) {                                718     if(_plotter) {
743       int hid = (*it).second;                     719       int hid = (*it).second;
744       std::ostringstream os;                      720       std::ostringstream os;
745       os << hid;                                  721       os << hid;
746       std::string cmd("/analysis/h2/get ");       722       std::string cmd("/analysis/h2/get ");
747       cmd += std::string(os.str());               723       cmd += std::string(os.str());
748       auto keepControlVerbose = UI->GetVerbose << 
749       UI->SetVerboseLevel(0);                  << 
750       G4int status = UI->ApplyCommand(cmd.c_st    724       G4int status = UI->ApplyCommand(cmd.c_str());
751       UI->SetVerboseLevel(keepControlVerbose); << 
752       if(status==G4UIcommandStatus::fCommandSu    725       if(status==G4UIcommandStatus::fCommandSucceeded) {
753         G4String hexString = UI->GetCurrentVal    726         G4String hexString = UI->GetCurrentValues("/analysis/h2/get");
754         if(hexString.size()) {                    727         if(hexString.size()) {
755           void* ptr;                              728           void* ptr;
756           std::istringstream is(hexString);       729           std::istringstream is(hexString);
757           is >> ptr;                              730           is >> ptr;
758           tools::histo::h2d* _h = (tools::hist    731           tools::histo::h2d* _h = (tools::histo::h2d*)ptr;
759           tools::sg::plottable* p = new tools:    732           tools::sg::plottable* p = new tools::sg::h2d2plot_cp(*_h);
760           _plotter->add_plottable(p); //give o    733           _plotter->add_plottable(p); //give ownership of p to sg::plotter.
761         }                                         734         }
762       } else {                                 << 
763         G4cerr <<                              << 
764         "G4ToolsSGSceneHandler::SetPlotterHist << 
765         "\n  Maybe this app does not do analys << 
766         << G4endl;                             << 
767       }                                           735       }
768     }                                             736     }
769   }}                                              737   }}
770 }                                                 738 }
771                                                   739 
772 class plots_cbk : public tools::sg::ecbk {        740 class plots_cbk : public tools::sg::ecbk {
773   TOOLS_CBK(plots_cbk,plots_cbk,tools::sg::ecb    741   TOOLS_CBK(plots_cbk,plots_cbk,tools::sg::ecbk)
774 public:                                           742 public:
775   virtual tools::sg::return_action action() {     743   virtual tools::sg::return_action action() {
776     if(const tools::sg::size_event* sz_evt = t    744     if(const tools::sg::size_event* sz_evt = tools::sg::event_cast<tools::sg::event,tools::sg::size_event>(*m_event)){
777       m_plots.adjust_size(sz_evt->width(),sz_e    745       m_plots.adjust_size(sz_evt->width(),sz_evt->height());
778       m_event_action->set_done(true);             746       m_event_action->set_done(true);
779       return tools::sg::return_to_render;         747       return tools::sg::return_to_render;
780     }                                             748     }
781     return tools::sg::return_none;                749     return tools::sg::return_none;
782   }                                               750   }
783 public:                                           751 public:
784   plots_cbk(tools::sg::plots& a_plots)            752   plots_cbk(tools::sg::plots& a_plots)
785   :parent()                                       753   :parent()
786   ,m_plots(a_plots)                               754   ,m_plots(a_plots)
787   {}                                              755   {}
788   virtual ~plots_cbk(){}                          756   virtual ~plots_cbk(){}
789 public:                                           757 public:
790   plots_cbk(const plots_cbk& a_from)              758   plots_cbk(const plots_cbk& a_from)
791   :parent(a_from)                                 759   :parent(a_from)
792   ,m_plots(a_from.m_plots)                        760   ,m_plots(a_from.m_plots)
793   {}                                              761   {}
794   plots_cbk& operator=(const plots_cbk& a_from    762   plots_cbk& operator=(const plots_cbk& a_from){
795     parent::operator=(a_from);                    763     parent::operator=(a_from);
796     return *this;                                 764     return *this;
797   }                                               765   }
798 protected:                                        766 protected:
799   tools::sg::plots& m_plots;                      767   tools::sg::plots& m_plots;
800 };                                                768 };
801                                                   769 
802 void G4ToolsSGSceneHandler::TouchPlotters(tool    770 void G4ToolsSGSceneHandler::TouchPlotters(tools::sg::node& a_sg) {
803   tools::sg::search_action sa(G4cout);            771   tools::sg::search_action sa(G4cout);
804   const tools::sg::search_action::paths_t& pat    772   const tools::sg::search_action::paths_t& paths = tools::sg::find_paths<tools::sg::plots>(sa,a_sg);
805   tools_vforcit(tools::sg::path_t,paths,it) {     773   tools_vforcit(tools::sg::path_t,paths,it) {
806     tools::sg::plots* _plots = tools::sg::tail    774     tools::sg::plots* _plots = tools::sg::tail<tools::sg::plots>(*it);    
807     if(_plots) {                                  775     if(_plots) {
808       SetPlotterHistograms(*_plots);              776       SetPlotterHistograms(*_plots);
809     }                                             777     }
810   }                                               778   }
811 }                                                 779 }
812                                                   780 
813 void G4ToolsSGSceneHandler::AddPrimitive(const    781 void G4ToolsSGSceneHandler::AddPrimitive(const G4Plotter& a_plotter)
814 {                                                 782 {
815 //G4cout << "debug : G4ToolsSGSceneHandler::Ad    783 //G4cout << "debug : G4ToolsSGSceneHandler::AddPrimitive : 004" << std::endl;
816   if(!fpViewer) return;                           784   if(!fpViewer) return;
817                                                   785   
818   auto currentNode = GetOrCreateNode();           786   auto currentNode = GetOrCreateNode();
819   if (!currentNode) return;  // Node not avail    787   if (!currentNode) return;  // Node not available
820                                                   788 
821   currentNode->add(new tools::sg::light_off())    789   currentNode->add(new tools::sg::light_off());
822                                                   790   
823   tools::sg::plots* _plots = new tools::sg::pl    791   tools::sg::plots* _plots = new tools::sg::plots(*fFreetypeNode);
824   currentNode->add(_plots);                       792   currentNode->add(_plots);
825                                                   793   
826   _plots->view_border = false;                    794   _plots->view_border = false;
827   _plots->set_regions(a_plotter.GetColumns(),a    795   _plots->set_regions(a_plotter.GetColumns(),a_plotter.GetRows());
828                                                   796 
829  {tools::sg::event_dispatcher* dpt = new tools    797  {tools::sg::event_dispatcher* dpt = new tools::sg::event_dispatcher;
830   dpt->add_callback(new plots_cbk(*_plots));      798   dpt->add_callback(new plots_cbk(*_plots));
831   currentNode->add(dpt);}                         799   currentNode->add(dpt);}
832                                                   800 
833   SetPlotterStyles(*_plots,a_plotter.GetStyles    801   SetPlotterStyles(*_plots,a_plotter.GetStyles(),a_plotter.GetRegionStyles());
834                                                   802 
835   tools::sg::cmaps_t _cmaps;                      803   tools::sg::cmaps_t _cmaps;
836   _cmaps["default"] = tools::sg::style_default    804   _cmaps["default"] = tools::sg::style_default_colormap();
837   _cmaps["ROOT"] = tools::sg::style_ROOT_color    805   _cmaps["ROOT"] = tools::sg::style_ROOT_colormap();
838                                                   806   
839   SetPlotterParameters(_cmaps,*_plots,a_plotte    807   SetPlotterParameters(_cmaps,*_plots,a_plotter.GetRegionParameters());
840                                                   808 
841   fRegionH1s = a_plotter.GetRegionH1s();          809   fRegionH1s = a_plotter.GetRegionH1s();
842   fRegionH2s = a_plotter.GetRegionH2s();          810   fRegionH2s = a_plotter.GetRegionH2s();
843                                                   811 
844   SetPlotterHistograms(*_plots);                  812   SetPlotterHistograms(*_plots);
845 }                                                 813 }
846                                                   814 
847 void G4ToolsSGSceneHandler::Messenger::SetNewV    815 void G4ToolsSGSceneHandler::Messenger::SetNewValue(G4UIcommand* a_cmd,G4String) {
848   G4VSceneHandler* pSceneHandler = GetVisManag << 816   G4VSceneHandler* pSceneHandler = fpVisManager->GetCurrentSceneHandler();
849   if (!pSceneHandler) {                           817   if (!pSceneHandler) {
850     G4cout << "G4ToolsSGSceneHandler::Messenge    818     G4cout << "G4ToolsSGSceneHandler::Messenger::SetNewValue: no current sceneHandler.  Please create one." << G4endl;
851     return;                                       819     return;
852   }                                               820   }
853   auto* tsg_scene_handler = dynamic_cast<G4Too    821   auto* tsg_scene_handler = dynamic_cast<G4ToolsSGSceneHandler*>(pSceneHandler);
854   if(!tsg_scene_handler) {                        822   if(!tsg_scene_handler) {
855     G4cout << "G4ToolsSGSceneHandler::Messenge    823     G4cout << "G4ToolsSGSceneHandler::Messenger::SetNewValue: current sceneHandler not a G4ToolsSGSceneHandler." << G4endl;
856     return;                                       824     return;
857   }                                               825   }
858   if(a_cmd==print_plotter_params) {               826   if(a_cmd==print_plotter_params) {
859     tools::sg::dummy_freetype _ttf;               827     tools::sg::dummy_freetype _ttf;
860     tools::sg::plotter _plotter(_ttf);            828     tools::sg::plotter _plotter(_ttf);
861     _plotter.print_available_customization(G4c    829     _plotter.print_available_customization(G4cout);
862   }                                               830   }
863 }                                                 831 }
864                                                   832