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 9.2.p4)


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