Geant4 Cross Reference |
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