Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // Created by Stewart Boogert on 13/11/2021. 27 // 28 29 #include "G4VtkStore.hh" 30 31 #include "G4Circle.hh" 32 #include "G4Mesh.hh" 33 #include "G4Plane3D.hh" 34 #include "G4Polyhedron.hh" 35 #include "G4Polyline.hh" 36 #include "G4Square.hh" 37 #include "G4Text.hh" 38 #include "G4VSceneHandler.hh" 39 #include "G4VisAttributes.hh" 40 #include "G4VtkUtility.hh" 41 #include "G4VtkViewer.hh" 42 #include "G4VtkVisContext.hh" 43 // #include "G4VtkClipperClosedPipeline.hh" 44 #include "G4VtkClipClosedSurfacePipeline.hh" 45 #include "G4VtkClipOpenPipeline.hh" 46 #include "G4VtkCutterPipeline.hh" 47 #include "G4VtkImagePipeline.hh" 48 #include "G4VtkPolydataInstanceAppendPipeline.hh" 49 #include "G4VtkPolydataInstanceBakePipeline.hh" 50 #include "G4VtkPolydataInstanceTensorPipeline.hh" 51 #include "G4VtkPolydataPipeline.hh" 52 #include "G4VtkPolydataPolygonPipeline.hh" 53 #include "G4VtkPolydataPolyline2DPipeline.hh" 54 #include "G4VtkPolydataPolylinePipeline.hh" 55 #include "G4VtkPolydataSpherePipeline.hh" 56 #include "G4VtkText2DPipeline.hh" 57 #include "G4VtkTextPipeline.hh" 58 #include "G4VtkUnstructuredGridPipeline.hh" 59 60 #ifndef WIN32 61 #pragma GCC diagnostic push 62 #pragma GCC diagnostic ignored "-Wextra-semi" 63 #endif 64 65 #include <vtkNew.h> 66 #include <vtkSmartPointer.h> 67 #include <vtkBillboardTextActor3D.h> 68 #include <vtkLine.h> 69 #include <vtkMatrix3x3.h> 70 #include <vtkOBJReader.h> 71 #include <vtkPLYReader.h> 72 #include <vtkSTLReader.h> 73 #include <vtkPolyDataReader.h> 74 #include <vtkProperty.h> 75 #include <vtkProperty2D.h> 76 #include <vtkRegularPolygonSource.h> 77 #include <vtkTextProperty.h> 78 79 #ifndef WIN32 80 #pragma GCC diagnostic pop 81 #endif 82 83 G4VtkStore::G4VtkStore(G4String nameIn) : name(nameIn) {} 84 85 G4VtkStore::~G4VtkStore() 86 { 87 Clear(); 88 } 89 90 void G4VtkStore::Modified() 91 { 92 #ifdef G4VTKDEBUG 93 G4cout << "G4VtkStore::Modified() " << name << G4endl; 94 #endif 95 96 for (const auto& it : polylinePipeMap) 97 it.second->Modified(); 98 99 for (const auto& it : polyline2DPipeMap) 100 it.second->Modified(); 101 102 for (const auto& it : circlePipeMap) 103 it.second->Modified(); 104 105 for (const auto& it : squarePipeMap) 106 it.second->Modified(); 107 108 for (const auto& it : textPipeMap) 109 it.second->Modified(); 110 111 for (const auto& it : text2DPipeMap) 112 it.second->Modified(); 113 114 for (const auto& it : separatePipeMap) 115 it.second->Modified(); 116 117 for (const auto& it : tensorGlyphPipeMap) 118 it.second->Modified(); 119 120 for (const auto& it : appendPipeMap) 121 it.second->Modified(); 122 123 for (const auto& it : bakePipeMap) 124 it.second->Modified(); 125 } 126 127 void G4VtkStore::Clear() 128 { 129 #ifdef G4VTKDEBUG 130 G4cout << "G4VtkStore::Clear() " << name << G4endl; 131 #endif 132 133 for (const auto& v : polylinePipeMap) { 134 v.second->Clear(); 135 } 136 polylinePipeMap.clear(); 137 138 for (const auto& v : polyline2DPipeMap) { 139 v.second->Clear(); 140 } 141 polyline2DPipeMap.clear(); 142 143 for (const auto& v : circlePipeMap) { 144 v.second->Clear(); 145 } 146 circlePipeMap.clear(); 147 148 for (const auto& v : squarePipeMap) { 149 v.second->Clear(); 150 } 151 squarePipeMap.clear(); 152 153 for (const auto& v : textPipeMap) { 154 v.second->Clear(); 155 } 156 textPipeMap.clear(); 157 158 for (const auto& v : text2DPipeMap) { 159 v.second->Clear(); 160 } 161 text2DPipeMap.clear(); 162 163 for (const auto& v : separatePipeMap) { 164 v.second->Clear(); 165 } 166 separatePipeMap.clear(); 167 168 for (const auto& v : tensorGlyphPipeMap) { 169 v.second->Clear(); 170 } 171 tensorGlyphPipeMap.clear(); 172 173 for (const auto& v : appendPipeMap) { 174 v.second->Clear(); 175 } 176 appendPipeMap.clear(); 177 178 for (const auto& v : bakePipeMap) { 179 v.second->Clear(); 180 } 181 bakePipeMap.clear(); 182 } 183 184 void G4VtkStore::ClearNonG4() 185 { 186 #ifdef G4VTKDEBUG 187 G4cout << "G4VtkStore::Clear() " << name << G4endl; 188 #endif 189 190 for (const auto& v : imagePipeMap) { 191 v.second->Clear(); 192 } 193 imagePipeMap.clear(); 194 195 for (const auto& v : sideloadPipeMap) { 196 v.second->Clear(); 197 } 198 sideloadPipeMap.clear(); 199 } 200 201 void G4VtkStore::Print() 202 { 203 G4cout << "G4VtkStore::Print() " << name << std::endl; 204 G4cout << "G4VtkStore::Print() polylinePipeMap size > " << polylinePipeMap.size() 205 << G4endl; 206 G4cout << "G4VtkStore::Print() polyline2DPipeMap size > " << polyline2DPipeMap.size() 207 << G4endl; 208 G4cout << "G4VtkStore::Print() circlePipeMap size > " << circlePipeMap.size() << G4endl; 209 G4cout << "G4VtkStore::Print() squarePipeMap size > " << squarePipeMap.size() << G4endl; 210 G4cout << "G4VtkStore::Print() textPipeMap size > " << textPipeMap.size() << G4endl; 211 G4cout << "G4VtkStore::Print() text2DPipeMap size > " << text2DPipeMap.size() << G4endl; 212 G4cout << "G4VtkStore::Print() separatePipeMap size > " << separatePipeMap.size() 213 << G4endl; 214 G4cout << "G4VtkStore::Print() tensorGlyphPipeMap size > " << tensorGlyphPipeMap.size() 215 << G4endl; 216 G4cout << "G4VtkStore::Print() transformAppendPipeMap size > " << appendPipeMap.size() << G4endl; 217 G4cout << "G4VtkStore::Print() bakePipeMap size > " << bakePipeMap.size() << G4endl; 218 G4cout << "G4VtkStore::Print() ugridPipeMap size > " << ugridPipeMap.size() << G4endl; 219 G4cout << "G4VtkStore::Print() imagePipeMap size > " << imagePipeMap.size() << G4endl; 220 221 for (const auto& it : polylinePipeMap) 222 it.second->Print(); 223 224 for (const auto& it : polyline2DPipeMap) 225 it.second->Print(); 226 227 for (const auto& it : circlePipeMap) 228 it.second->Print(); 229 230 for (const auto& it : squarePipeMap) 231 it.second->Print(); 232 233 for (const auto& it : separatePipeMap) 234 it.second->Print(); 235 236 for (const auto& it : tensorGlyphPipeMap) 237 it.second->Print(); 238 239 for (const auto& it : appendPipeMap) 240 it.second->Print(); 241 242 for (const auto& it : bakePipeMap) 243 it.second->Print(); 244 245 for (const auto& it : ugridPipeMap) { 246 G4cout << it.first << G4endl; 247 it.second->Print(); 248 } 249 250 for (const auto& it : imagePipeMap) 251 it.second->Print(); 252 } 253 254 void G4VtkStore::AddPrimitive(const G4Polyline& polyline, const G4VtkVisContext& vc) 255 { 256 G4VSceneHandler::MarkerSizeType sizeType; 257 if (vc.fProcessing2D) { 258 sizeType = G4VSceneHandler::MarkerSizeType::screen; 259 } 260 else { 261 sizeType = G4VSceneHandler::MarkerSizeType::world; 262 } 263 264 // Get vis attributes - pick up defaults if none. 265 const G4VisAttributes* pVA = vc.fViewer->GetApplicableVisAttributes(polyline.GetVisAttributes()); 266 267 if (sizeType == G4VSceneHandler::MarkerSizeType::world) { 268 std::size_t hash = G4VtkPolydataPolylinePipeline::MakeHash(pVA); 269 std::shared_ptr<G4VtkPolydataPolylinePipeline> pl; 270 271 if (polylinePipeMap.find(hash) == polylinePipeMap.end()) { 272 // Create new pipeline 273 pl = std::make_shared<G4VtkPolydataPolylinePipeline>(G4String("name"), vc, pVA); 274 275 // Add to map 276 polylinePipeMap.insert(std::make_pair(hash, pl)); 277 } 278 else { 279 pl = polylinePipeMap[hash]; 280 } 281 pl->SetPolydata(polyline); 282 } 283 284 else if (sizeType == G4VSceneHandler::MarkerSizeType::screen) { 285 std::size_t hash = G4VtkPolydataPolyline2DPipeline::MakeHash(pVA); 286 std::shared_ptr<G4VtkPolydataPolyline2DPipeline> pl; 287 288 if (polyline2DPipeMap.find(hash) == polyline2DPipeMap.end()) { 289 // Create new pipeline 290 pl = std::make_shared<G4VtkPolydataPolyline2DPipeline>(G4String("name"), vc, pVA); 291 292 // Add to map 293 polyline2DPipeMap.insert(std::make_pair(hash, pl)); 294 } 295 else { 296 pl = polyline2DPipeMap[hash]; 297 } 298 pl->SetPolydata(polyline); 299 } 300 } 301 302 void G4VtkStore::AddPrimitive(const G4Text& text, const G4VtkVisContext& vc) 303 { 304 G4VSceneHandler::MarkerSizeType sizeType; 305 if (vc.fProcessing2D) { 306 sizeType = G4VSceneHandler::MarkerSizeType::screen; 307 } 308 else { 309 sizeType = G4VSceneHandler::MarkerSizeType::world; 310 } 311 312 auto pVA = vc.fViewer->GetApplicableVisAttributes(text.GetVisAttributes()); 313 314 switch (sizeType) { 315 default: 316 case (G4VSceneHandler::MarkerSizeType::screen): { 317 std::size_t hash = G4VtkTextPipeline::MakeHash(text, vc, pVA); 318 auto pl = std::make_shared<G4VtkText2DPipeline>(text, vc, pVA); 319 text2DPipeMap.insert(std::make_pair(hash, pl)); 320 break; 321 } 322 case G4VSceneHandler::MarkerSizeType::world: { 323 std::size_t hash = G4VtkTextPipeline::MakeHash(text, vc, pVA); 324 auto pl = std::make_shared<G4VtkTextPipeline>(text, vc, pVA); 325 textPipeMap.insert(std::make_pair(hash, pl)); 326 break; 327 } 328 } 329 } 330 331 void G4VtkStore::AddPrimitive(const G4Circle& circle, const G4VtkVisContext& vc) 332 { 333 G4VSceneHandler::MarkerSizeType sizeType; 334 335 if (vc.fProcessing2D) { 336 sizeType = G4VSceneHandler::MarkerSizeType::screen; 337 } 338 else { 339 sizeType = G4VSceneHandler::MarkerSizeType::world; 340 } 341 342 // Get vis attributes - pick up defaults if none. 343 const G4VisAttributes* pVA = vc.fViewer->GetApplicableVisAttributes(circle.GetVisAttributes()); 344 345 if (sizeType == G4VSceneHandler::MarkerSizeType::world) { 346 std::size_t hash = G4VtkPolydataSpherePipeline::MakeHash(pVA); 347 std::shared_ptr<G4VtkPolydataSpherePipeline> pl; 348 349 if (circlePipeMap.find(hash) == circlePipeMap.end()) { 350 // Create new pipeline 351 pl = std::make_shared<G4VtkPolydataSpherePipeline>(G4String("name"), vc, pVA); 352 353 // add to map 354 circlePipeMap.insert(std::make_pair(hash, pl)); 355 } 356 else { 357 pl = circlePipeMap[hash]; 358 } 359 360 // Data data point 361 const CLHEP::HepRotation rot = vc.fTransform.getRotation(); 362 G4Point3D posPrime = rot * circle.GetPosition(); 363 pl->SetPolydataData(vc.fTransform.dx() + posPrime.x(), vc.fTransform.dy() + posPrime.y(), 364 vc.fTransform.dz() + posPrime.z()); 365 } 366 } 367 368 void G4VtkStore::AddPrimitive(const G4Square& square, const G4VtkVisContext& vc) 369 { 370 G4VSceneHandler::MarkerSizeType sizeType; 371 372 if (vc.fProcessing2D) { 373 sizeType = G4VSceneHandler::MarkerSizeType::screen; 374 } 375 else { 376 sizeType = G4VSceneHandler::MarkerSizeType::world; 377 } 378 379 // Get vis attributes - pick up defaults if none. 380 const G4VisAttributes* pVA = vc.fViewer->GetApplicableVisAttributes(square.GetVisAttributes()); 381 382 if (sizeType == G4VSceneHandler::MarkerSizeType::world) { 383 std::size_t hash = std::hash<G4VisAttributes>{}(*pVA); 384 385 std::shared_ptr<G4VtkPolydataPolygonPipeline> pl; 386 if (squarePipeMap.find(hash) == squarePipeMap.end()) { 387 // Create new pipeline 388 pl = std::make_shared<G4VtkPolydataPolygonPipeline>(G4String("name"), vc, pVA); 389 390 // add to map 391 squarePipeMap.insert(std::make_pair(hash, pl)); 392 } 393 else { 394 pl = squarePipeMap[hash]; 395 } 396 397 // Data data point 398 const CLHEP::HepRotation rot = vc.fTransform.getRotation(); 399 G4Point3D posPrime = rot * square.GetPosition(); 400 pl->SetPolydataData(vc.fTransform.dx() + posPrime.x(), vc.fTransform.dy() + posPrime.y(), 401 vc.fTransform.dz() + posPrime.z()); 402 } 403 } 404 405 void G4VtkStore::AddPrimitiveSeparate(const G4Polyhedron& polyhedron, const G4VtkVisContext& vc) 406 { 407 // Return if empty polyhedron 408 if (polyhedron.GetNoFacets() == 0) { 409 return; 410 } 411 412 auto hash = G4VtkPolydataPipeline::MakeHash(polyhedron, vc); 413 414 auto pl = std::make_shared<G4VtkPolydataPipeline>(G4String("name"), vc); 415 pl->SetPolydata(polyhedron); 416 417 separatePipeMap.insert(std::make_pair(hash, pl)); 418 419 const G4VisAttributes* pVA = 420 vc.fViewer->GetApplicableVisAttributes(polyhedron.GetVisAttributes()); 421 G4Color colour = pVA->GetColour(); 422 G4Transform3D fInvObjTrans = vc.fTransform.inverse(); 423 424 pl->SetActorTransform(vc.fTransform.dx(), vc.fTransform.dy(), vc.fTransform.dz(), 425 fInvObjTrans.xx(), fInvObjTrans.xy(), fInvObjTrans.xz(), 426 fInvObjTrans.yx(), fInvObjTrans.yy(), fInvObjTrans.yz(), 427 fInvObjTrans.zx(), fInvObjTrans.zy(), fInvObjTrans.zz()); 428 pl->SetActorColour(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha()); 429 } 430 431 void G4VtkStore::AddPrimitiveTensorGlyph(const G4Polyhedron& polyhedron, const G4VtkVisContext& vc) 432 { 433 // Return if empty polyhedron 434 if (polyhedron.GetNoFacets() == 0) { 435 return; 436 } 437 438 // Possible the polyhedron already has a transform baked in (definitely the case 439 // for scoring meshes. Remove them here 440 auto centre = polyhedron.vertexUnweightedMean(); 441 auto transform = G4Translate3D(-centre.x(), -centre.y(), -centre.z()); 442 443 auto polyhedronNew = G4Polyhedron(polyhedron); 444 auto fTransformNew = G4Transform3D(vc.fTransform*transform.inverse()); 445 446 polyhedronNew.Transform(transform); 447 448 auto hash = G4VtkPolydataInstanceTensorPipeline::MakeHash(polyhedronNew, vc); 449 std::shared_ptr<G4VtkPolydataInstanceTensorPipeline> pl; 450 451 if (tensorGlyphPipeMap.find(hash) == tensorGlyphPipeMap.end()) { 452 pl = std::make_shared<G4VtkPolydataInstanceTensorPipeline>(G4String("name"), vc); 453 pl->SetPolydata(polyhedronNew); 454 tensorGlyphPipeMap.insert(std::make_pair(hash, pl)); 455 } 456 else { 457 pl = tensorGlyphPipeMap[hash]; 458 } 459 460 G4Transform3D fInvObjTrans = fTransformNew.inverse(); 461 const G4VisAttributes* pVA = 462 vc.fViewer->GetApplicableVisAttributes(polyhedron.GetVisAttributes()); 463 G4Color colour = pVA->GetColour(); 464 465 pl->addInstance(fTransformNew.dx(), fTransformNew.dy(), fTransformNew.dz(), 466 fInvObjTrans.xx(), fInvObjTrans.xy(), fInvObjTrans.xz(), 467 fInvObjTrans.yx(), fInvObjTrans.yy(), fInvObjTrans.yz(), 468 fInvObjTrans.zx(), fInvObjTrans.zy(), fInvObjTrans.zz(), 469 colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha(), 470 G4String("null")); 471 } 472 473 void G4VtkStore::AddPrimitiveAppend(const G4Polyhedron& polyhedron, const G4VtkVisContext& vc) 474 { 475 // Empty polyhedron 476 if (polyhedron.GetNoFacets() == 0) { 477 return; 478 } 479 480 // Possible the polyhedron already has a transform baked in (definitely the case 481 // for scoring meshes. Remove them here 482 auto centre = polyhedron.vertexUnweightedMean(); 483 auto transform = G4Translate3D(-centre.x(), -centre.y(), -centre.z()); 484 485 auto polyhedronNew = G4Polyhedron(polyhedron); 486 auto fTransformNew = G4Transform3D(vc.fTransform*transform.inverse()); 487 488 polyhedronNew.Transform(transform); 489 490 auto hash = G4VtkPolydataInstanceAppendPipeline::MakeHash(polyhedronNew, vc); 491 std::shared_ptr<G4VtkPolydataInstanceAppendPipeline> pl; 492 493 if (appendPipeMap.find(hash) == appendPipeMap.end()) { 494 pl = std::make_shared<G4VtkPolydataInstanceAppendPipeline>(G4String("name"), vc); 495 pl->SetPolydata(polyhedronNew); 496 appendPipeMap.insert(std::make_pair(hash, pl)); 497 } 498 else { 499 pl = appendPipeMap[hash]; 500 } 501 502 G4Transform3D fInvObjTrans = fTransformNew.inverse(); 503 504 pl->addInstance(fTransformNew.dx(), fTransformNew.dy(), fTransformNew.dz(), 505 fInvObjTrans.xx(), fInvObjTrans.xy(), fInvObjTrans.xz(), 506 fInvObjTrans.yx(), fInvObjTrans.yy(), fInvObjTrans.yz(), 507 fInvObjTrans.zx(), fInvObjTrans.zy(), fInvObjTrans.zz(), 508 0, 0, 0, 0, G4String("null")); 509 }; 510 511 void G4VtkStore::AddPrimitiveTransformBake(const G4Polyhedron& polyhedron, 512 const G4VtkVisContext& vc) 513 { 514 // Empty polyhedron 515 if (polyhedron.GetNoFacets() == 0) { 516 return; 517 } 518 519 // Possible the polyhedron already has a transform baked in (definitely the case 520 // for scoring meshes. Remove them here 521 auto centre = polyhedron.vertexUnweightedMean(); 522 auto transform = G4Translate3D(-centre.x(), -centre.y(), -centre.z()); 523 524 auto polyhedronNew = G4Polyhedron(polyhedron); 525 auto fTransformNew = G4Transform3D(vc.fTransform*transform.inverse()); 526 527 polyhedronNew.Transform(transform); 528 529 // Get vis attributes - pick up defaults if none. 530 const G4VisAttributes* pVA = 531 vc.fViewer->GetApplicableVisAttributes(polyhedron.GetVisAttributes()); 532 533 // Polyhedron colour 534 G4Colour colour = pVA->GetColour(); 535 536 // Hash the vis (alpha) attributes and polyhedron 537 std::size_t hash = G4VtkPolydataInstanceBakePipeline::MakeHash(polyhedronNew, vc); 538 539 std::shared_ptr<G4VtkPolydataInstanceBakePipeline> pl; 540 if (bakePipeMap.find(hash) == bakePipeMap.end()) { 541 pl = std::make_shared<G4VtkPolydataInstanceBakePipeline>(G4String("none"), vc); 542 543 bakePipeMap.insert(std::make_pair(hash, pl)); 544 } 545 else { 546 pl = bakePipeMap[hash]; 547 } 548 549 G4Transform3D fInvObjTrans = fTransformNew.inverse(); 550 pl->SetPolydata(polyhedronNew); 551 552 pl->addInstance(fTransformNew.dx(), fTransformNew.dy(), fTransformNew.dz(), 553 fInvObjTrans.xx(), fInvObjTrans.xy(), fInvObjTrans.xz(), 554 fInvObjTrans.yx(), fInvObjTrans.yy(), fInvObjTrans.yz(), 555 fInvObjTrans.zx(), fInvObjTrans.zy(), fInvObjTrans.zz(), 556 colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha(), 557 G4String("null")); 558 }; 559 560 void G4VtkStore::AddCompound(const G4Mesh& mesh, const G4VtkVisContext& vc) { 561 const auto& container = mesh.GetContainerVolume(); 562 auto& containerName = const_cast<G4String&>(container->GetName()); 563 564 auto pl = std::make_shared<G4VtkUnstructuredGridPipeline>(containerName,vc); 565 pl->SetUnstructuredGridData(mesh); 566 ugridPipeMap.insert(std::make_pair(G4String("test"), pl)); 567 } 568 569 void G4VtkStore::UpdatePlanePipelines(G4String nameIn, G4String type, const G4Plane3D plane) 570 { 571 if (type == "clipper") { 572 UpdateClipper(nameIn, plane); 573 } 574 else if (type == "cutter") { 575 UpdateCutter(nameIn, plane); 576 } 577 } 578 579 void G4VtkStore::AddClipper(G4String nameIn, const G4Plane3D& plane) 580 { 581 for (const auto& v : separatePipeMap) { 582 auto clip_pl = new G4VtkClipClosedSurfacePipeline(nameIn, v.second->GetVtkVisContext(), 583 v.second->GetFinalFilter(), true); 584 clip_pl->SetPlane(plane); 585 v.second->AddChildPipeline(clip_pl); 586 } 587 588 for (const auto& v : tensorGlyphPipeMap) { 589 auto clip_pl = new G4VtkClipClosedSurfacePipeline(nameIn, v.second->GetVtkVisContext(), 590 v.second->GetFinalFilter()); 591 clip_pl->SetPlane(plane); 592 v.second->AddChildPipeline(clip_pl); 593 } 594 595 for (const auto& v : appendPipeMap) { 596 auto clip_pl = new G4VtkClipClosedSurfacePipeline(nameIn, v.second->GetVtkVisContext(), 597 v.second->GetFinalFilter(), true); 598 clip_pl->SetPlane(plane); 599 v.second->AddChildPipeline(clip_pl); 600 } 601 602 for (const auto& v : bakePipeMap) { 603 auto clip_pl = new G4VtkClipClosedSurfacePipeline(nameIn, v.second->GetVtkVisContext(), 604 v.second->GetFinalFilter(), true); 605 clip_pl->SetPlane(plane); 606 v.second->AddChildPipeline(clip_pl); 607 } 608 } 609 610 void G4VtkStore::UpdateClipper(G4String nameIn, const G4Plane3D& plane) 611 { 612 for (const auto& v : separatePipeMap) { 613 auto children = v.second->GetChildPipelines(); 614 for (auto c : children) { 615 if (c->GetName() == nameIn) { 616 auto cc = dynamic_cast<G4VtkClipClosedSurfacePipeline*>(c); 617 cc->SetPlane(plane); 618 } 619 } 620 } 621 622 for (const auto& v : tensorGlyphPipeMap) { 623 auto children = v.second->GetChildPipelines(); 624 for (auto c : children) { 625 if (c->GetName() == nameIn) { 626 auto cc = dynamic_cast<G4VtkClipClosedSurfacePipeline*>(c); 627 cc->SetPlane(plane); 628 } 629 } 630 } 631 632 for (const auto& v : appendPipeMap) { 633 auto children = v.second->GetChildPipelines(); 634 for (auto c : children) { 635 if (c->GetName() == nameIn) { 636 auto cc = dynamic_cast<G4VtkClipClosedSurfacePipeline*>(c); 637 cc->SetPlane(plane); 638 } 639 } 640 } 641 642 for (const auto& v : bakePipeMap) { 643 auto children = v.second->GetChildPipelines(); 644 for (auto c : children) { 645 if (c->GetName() == nameIn) { 646 auto cc = dynamic_cast<G4VtkClipClosedSurfacePipeline*>(c); 647 cc->SetPlane(plane); 648 } 649 } 650 } 651 } 652 653 void G4VtkStore::RemoveClipper(G4String /*nameIn*/) {} 654 655 void G4VtkStore::AddCutter(G4String nameIn, const G4Plane3D& plane) 656 { 657 for (const auto& v : separatePipeMap) { 658 auto cut_pl = new G4VtkCutterPipeline(nameIn, v.second->GetVtkVisContext(), 659 v.second->GetFinalFilter(), true); 660 cut_pl->SetPlane(plane); 661 v.second->AddChildPipeline(cut_pl); 662 } 663 664 for (const auto& v : tensorGlyphPipeMap) { 665 auto cut_pl = 666 new G4VtkCutterPipeline(nameIn, v.second->GetVtkVisContext(), v.second->GetFinalFilter()); 667 cut_pl->SetPlane(plane); 668 v.second->AddChildPipeline(cut_pl); 669 } 670 671 for (const auto& v : appendPipeMap) { 672 auto cut_pl = 673 new G4VtkCutterPipeline(nameIn, v.second->GetVtkVisContext(), v.second->GetFinalFilter()); 674 cut_pl->SetPlane(plane); 675 v.second->AddChildPipeline(cut_pl); 676 } 677 678 for (const auto& v : bakePipeMap) { 679 auto cut_pl = 680 new G4VtkCutterPipeline(nameIn, v.second->GetVtkVisContext(), v.second->GetFinalFilter()); 681 cut_pl->SetPlane(plane); 682 v.second->AddChildPipeline(cut_pl); 683 } 684 } 685 686 void G4VtkStore::UpdateCutter(G4String nameIn, const G4Plane3D& plane) 687 { 688 for (const auto& v : separatePipeMap) { 689 auto children = v.second->GetChildPipelines(); 690 for (auto c : children) { 691 if (c->GetName() == nameIn) { 692 auto cc = dynamic_cast<G4VtkCutterPipeline*>(c); 693 cc->SetPlane(plane); 694 } 695 } 696 } 697 698 for (const auto& v : tensorGlyphPipeMap) { 699 auto children = v.second->GetChildPipelines(); 700 for (auto c : children) { 701 if (c->GetName() == nameIn) { 702 auto cc = dynamic_cast<G4VtkCutterPipeline*>(c); 703 cc->SetPlane(plane); 704 } 705 } 706 } 707 708 for (const auto& v : appendPipeMap) { 709 auto children = v.second->GetChildPipelines(); 710 for (auto c : children) { 711 if (c->GetName() == nameIn) { 712 auto cc = dynamic_cast<G4VtkCutterPipeline*>(c); 713 cc->SetPlane(plane); 714 } 715 } 716 } 717 718 for (const auto& v : bakePipeMap) { 719 auto children = v.second->GetChildPipelines(); 720 for (auto c : children) { 721 if (c->GetName() == nameIn) { 722 auto cc = dynamic_cast<G4VtkCutterPipeline*>(c); 723 cc->SetPlane(plane); 724 } 725 } 726 } 727 } 728 729 void G4VtkStore::RemoveCutter(G4String /*nameIn*/) {} 730 731 void G4VtkStore::AddNonG4ObjectImage(const G4String& fileName, const G4VtkVisContext& vc) 732 { 733 auto pl = std::make_shared<G4VtkImagePipeline>(G4String("name"), vc); 734 pl->SetImage(fileName); 735 imagePipeMap.insert(std::make_pair(fileName, pl)); 736 } 737 738 void G4VtkStore::AddNonG4ObjectPolydata(const G4String fileName, const G4VtkVisContext& vc) 739 { 740 741 vtkSmartPointer<vtkPolyData> pd; 742 743 if (fileName.find("obj") != G4String::npos) { 744 vtkNew<vtkOBJReader> objReader; 745 objReader->SetFileName(fileName.c_str()); 746 objReader->Update(); 747 pd = objReader->GetOutput(); 748 } 749 else if (fileName.find("ply") != G4String::npos) { 750 vtkNew<vtkPLYReader> plyReader; 751 plyReader->SetFileName(fileName.c_str()); 752 plyReader->Update(); 753 pd = plyReader->GetOutput(); 754 } 755 else if (fileName.find("stl") != G4String::npos) { 756 vtkNew<vtkSTLReader> stlReader; 757 stlReader->SetFileName(fileName.c_str()); 758 stlReader->Update(); 759 pd = stlReader->GetOutput(); 760 } 761 else if (fileName.find("vtp") != G4String::npos && fileName.find("vtu") != G4String::npos) { 762 G4cout << "G4VtkStore::AddNonG4ObjectPolydata> vtp/vtu Warning not yet implemented" << G4endl; 763 } 764 765 auto pl = std::make_shared<G4VtkPolydataPipeline>(G4String("name"), vc); 766 767 768 G4Transform3D fInvObjTrans = vc.fTransform.inverse(); 769 pl->SetPolydata(pd); 770 pl->SetActorTransform(vc.fTransform.dx(), vc.fTransform.dy(), vc.fTransform.dz(), 771 fInvObjTrans.xx(), fInvObjTrans.xy(), fInvObjTrans.xz(), 772 fInvObjTrans.yx(), fInvObjTrans.yy(), fInvObjTrans.yz(), 773 fInvObjTrans.zx(), fInvObjTrans.zy(), fInvObjTrans.zz()); 774 pl->SetActorColour(vc.red, vc.green, vc.blue, vc.alpha); 775 } 776 777 void G4VtkStore::GetBounds(G4double maxBoundIn[6]) 778 { 779 G4double maxBound[6] = {1e99, -1e99, 1e99, -1e99, 1e99, -1e99}; 780 781 for (const auto& v : separatePipeMap) { 782 auto b = v.second->GetBounds(); 783 MaxBounds(maxBound, b); 784 } 785 786 for (const auto& v : tensorGlyphPipeMap) { 787 auto b = v.second->GetBounds(); 788 MaxBounds(maxBound, b); 789 } 790 791 for (const auto& v : appendPipeMap) { 792 auto b = v.second->GetBounds(); 793 MaxBounds(maxBound, b); 794 } 795 796 for (const auto& v : bakePipeMap) { 797 auto b = v.second->GetBounds(); 798 MaxBounds(maxBound, b); 799 } 800 801 maxBoundIn[0] = maxBound[0]; 802 maxBoundIn[1] = maxBound[1]; 803 maxBoundIn[2] = maxBound[2]; 804 maxBoundIn[3] = maxBound[3]; 805 maxBoundIn[4] = maxBound[4]; 806 maxBoundIn[5] = maxBound[5]; 807 } 808 809 void G4VtkStore::AddToRenderer(vtkRenderer* renderer) 810 { 811 for (const auto& it : polylinePipeMap) 812 renderer->AddActor(it.second->GetActor()); 813 for (const auto& it : polyline2DPipeMap) 814 renderer->AddActor(it.second->GetActor()); 815 for (const auto& it : circlePipeMap) 816 renderer->AddActor(it.second->GetActor()); 817 for (const auto& it : squarePipeMap) 818 renderer->AddActor(it.second->GetActor()); 819 for (const auto& it : textPipeMap) 820 renderer->AddActor(it.second->GetActor()); 821 for (const auto& it : text2DPipeMap) 822 renderer->AddActor(it.second->GetActor()); 823 for (const auto& it : separatePipeMap) 824 renderer->AddActor(it.second->GetActor()); 825 for (const auto& it : tensorGlyphPipeMap) 826 renderer->AddActor(it.second->GetActor()); 827 for (const auto& it : appendPipeMap) 828 renderer->AddActor(it.second->GetActor()); 829 for (const auto& it : bakePipeMap) 830 renderer->AddActor(it.second->GetActor()); 831 } 832