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