2 // Category: visualization
4 // Author: I. Hrivnacova, A. Gheata
8 // See the class description in the header file.
9 // According to visualization/management/include/MyVisManager.*
10 // John Allison 24th January 1998.
11 // I. Hrivnacova 12.5.98
13 // Renamed to TG4VisManager
14 // I. Hrivnacova, 3.9.99
16 // Added AliMC implementation
19 // Added OpenGL*Win32, RayTracer (as replacement of RayX) drivers
20 // based on G4 suggestions.
21 // I. Gonzalez, 4.4.2000
23 // Example Visualization Manager description:
24 // Implements virtual function RegisterGraphicsSystems.
25 // Exploits C-pre-processor variables G4VIS_USE_DAWN, etc.,
26 // which are set by the G4 makefiles if
27 // environment variables of the same name are set.
29 // So all you have to do is set environment variables and compile and
30 // instantiate this in your main().
32 // Alternatively, you can implement an empty function here and just
33 // register the systems you want in your main(), e.g.:
34 // G4VisManager* myVisManager = new MyVisManager;
35 // myVisManager -> RegisterGraphicsSystem (new MyGraphicsSystem);
40 #include "TG4VisManager.h"
41 #include "TG4Globals.h"
43 #include <G4LogicalVolumeStore.hh>
44 #include <G4PhysicalVolumeStore.hh>
45 #include <G4TransportationManager.hh>
46 #include <G4Material.hh>
47 #include <G4PhysicalVolumeModel.hh>
48 #include <G4VVisManager.hh>
50 // Supported drivers...
53 #include <G4FukuiRenderer.hh>
56 #ifdef G4VIS_USE_DAWNFILE
57 #include <G4DAWNFILE.hh>
60 #ifdef G4VIS_USE_OPACS
65 #ifdef G4VIS_USE_OPENGLX
66 #include <G4OpenGLImmediateX.hh>
67 #include <G4OpenGLStoredX.hh>
70 #ifdef G4VIS_USE_OPENGLXM
71 #include <G4OpenGLImmediateXm.hh>
72 #include <G4OpenGLStoredXm.hh>
75 #ifdef G4VIS_USE_OPENGLWIN32
76 #include "G4OpenGLImmediateWin32.hh"
77 #include "G4OpenGLStoredWin32.hh"
81 #include <G4OpenInventorX.hh>
84 #ifdef G4VIS_USE_OIWIN32
85 #include <G4OpenInventorWin32.hh>
88 #ifdef G4VIS_USE_RAYTRACER
89 #include "G4RayTracer.hh"
97 #ifdef G4VIS_USE_VRMLFILE
98 #include <G4VRML1File.hh>
99 #include <G4VRML2File.hh>
102 //_____________________________________________________________________________
103 TG4VisManager::TG4VisManager(G4int verboseLevel) {
105 fVerbose = verboseLevel;
109 //_____________________________________________________________________________
110 TG4VisManager::TG4VisManager(const TG4VisManager& right) {
112 TG4Globals::Exception(
113 "Attempt to copy TG4VisManager singleton.");
116 //_____________________________________________________________________________
117 TG4VisManager::~TG4VisManager() {
123 //_____________________________________________________________________________
124 TG4VisManager& TG4VisManager::operator=(const TG4VisManager& right)
126 // check assignement to self
127 if (this == &right) return *this;
129 TG4Globals::Exception(
130 "Attempt to assign TG4VisManager singleton.");
137 //_____________________________________________________________________________
138 void TG4VisManager::RegisterGraphicsSystems()
140 // Registers the graphics systems.
143 // all created graphics system instances are
144 // deleted in G4VisManager::~G4VisManager()
145 #ifdef G4VIS_USE_DAWN
146 RegisterGraphicsSystem(new G4FukuiRenderer);
149 #ifdef G4VIS_USE_DAWNFILE
150 RegisterGraphicsSystem(new G4DAWNFILE);
153 #ifdef G4VIS_USE_OPACS
154 RegisterGraphicsSystem(new G4Wo);
155 RegisterGraphicsSystem(new G4Xo);
158 #ifdef G4VIS_USE_OPENGLX
159 RegisterGraphicsSystem(new G4OpenGLImmediateX);
160 RegisterGraphicsSystem(new G4OpenGLStoredX);
163 #ifdef G4VIS_USE_OPENGLXM
164 RegisterGraphicsSystem(new G4OpenGLImmediateXm);
165 RegisterGraphicsSystem(new G4OpenGLStoredXm);
168 #ifdef G4VIS_USE_OPENGLWIN32
169 RegisterGraphicsSystem (new G4OpenGLImmediateWin32);
170 RegisterGraphicsSystem (new G4OpenGLStoredWin32);
174 RegisterGraphicsSystem(new G4OpenInventorX);
177 #ifdef G4VIS_USE_OIWIN32
178 RegisterGraphicsSystem(new G4OpenInventorWin32);
181 #ifdef G4VIS_USE_RAYTRACER
182 RegisterGraphicsSystem (new G4RayTracer);
185 #ifdef G4VIS_USE_VRML
186 RegisterGraphicsSystem(new G4VRML1);
187 RegisterGraphicsSystem(new G4VRML2);
190 #ifdef G4VIS_USE_VRMLFILE
191 RegisterGraphicsSystem(new G4VRML1File);
192 RegisterGraphicsSystem(new G4VRML2File);
197 "\nYou have successfully chosen to use the following graphics systems."
199 PrintAvailableGraphicsSystems();
203 //---------------------------------------------------------------
205 //---------------------------------------------------------------
208 //_____________________________________________________________________________
209 G4RWTPtrOrderedVector<G4LogicalVolume> TG4VisManager::GetLVList(G4String name)
211 // Get function returning the list of logical volumes
212 // associated to NAME; G4 built clones of a G3 volume (identified
213 // with NAME_NUMBER will be added to the list)
214 // NAME can be the name of a logical or physical volume
217 G4RWTPtrOrderedVector <G4LogicalVolume> lvList;
218 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
219 G4LogicalVolume* pLV = 0;
222 for (G4int i=0; i<pLVStore->size(); i++)
224 pLV = (*pLVStore)[i];
225 if (CaseInsensitiveEqual(name,pLV->GetName()))
227 if (!lvList.contains(pLV)) lvList.append(pLV);
231 if (!lvList.isEmpty()) return lvList;
232 G4PhysicalVolumeStore* pPVStore = G4PhysicalVolumeStore::GetInstance();
233 G4VPhysicalVolume* pPV = 0;
236 for (G4int i=0; i<pPVStore->size(); i++)
238 pPV = (*pPVStore)[i];
239 if (CaseInsensitiveEqual(name,pPV->GetName()))
241 pLV = pPV->GetLogicalVolume();
242 if (!lvList.contains(pLV)) lvList.append(pLV);
250 //_____________________________________________________________________________
251 G4RWTPtrOrderedVector<G4VPhysicalVolume> TG4VisManager::GetPVList(G4String name)
253 // Get function returning the physical volume pointer for NAME
256 G4RWTPtrOrderedVector <G4VPhysicalVolume> pvList;
257 G4PhysicalVolumeStore* pPVStore = G4PhysicalVolumeStore::GetInstance();
260 TG4Globals::Warning("TG4VisManager::Gdraw : No volume store !");
263 G4VPhysicalVolume* pPV = 0;
264 for (G4int i=0; i<pPVStore->size(); i++)
266 pPV = (*pPVStore)[i];
267 if (CaseInsensitiveEqual(name,pPV->GetName()))
269 if (!pvList.contains(pPV)) pvList.append(pPV);
276 //_____________________________________________________________________________
277 G4bool TG4VisManager::CaseInsensitiveEqual(const G4String string1,
278 const G4String string2)
280 // Case insensitive comparison of 2 strings
284 if (string1 == string2) return true;
285 // if (string1.length() != string2.length()) return false;
286 for (i=0; i<string1.length(); i++)
288 G4int diff = abs((G4int)string1(i)-(G4int)string2(i));
289 if (diff && (diff!=32)) return false;
291 if (string2.length() > string1.length())
293 if (string2(i) == '_') return true;
300 //_____________________________________________________________________________
301 void TG4VisManager::SetAtt4Daughters(G4LogicalVolume* const lv,
302 const TG4G3Attribute att, const G4int val)
304 // Iterator for setting a visual attribute for all daughters
307 SetG4Attribute(lv,att,val);
309 G4String lvName = lv->GetName();
310 G4int nOfDaughters = lv->GetNoDaughters();
313 G4String previousName = "";
314 for (G4int i=0; i<nOfDaughters; i++)
316 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
317 G4String currentName = lvd->GetName();
318 if (currentName != lvName && currentName != previousName)
320 SetAtt4Daughters(lvd, att, val);
321 previousName = currentName;
328 //_____________________________________________________________________________
329 G4bool TG4VisManager::IsSharedVisAttributes(const G4LogicalVolume* pLV)
331 // Function seeking if the volume's visible attributes are shared with
335 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
336 G4LogicalVolume* pLVCurrent = 0;
337 const G4VisAttributes* pVisAtt = pLV->GetVisAttributes();
338 if (!pVisAtt) return false;
339 for (G4int i=0; i<pLVStore->size(); i++)
341 pLVCurrent = (*pLVStore)[i];
342 if (pLVCurrent != pLV)
344 if (pLVCurrent->GetVisAttributes() == pVisAtt)
354 //_____________________________________________________________________________
355 void TG4VisManager::SetG4Attribute(G4LogicalVolume* const lv,
356 const TG4G3Attribute att, const G4int val)
358 // Set the G4 attribute fo volume LV accordingly to the G3 description
363 // Dupplicating old vis. attributes
364 const G4VisAttributes* visAttributes = lv->GetVisAttributes();
365 G4VisAttributes* newVisAttributes;
367 newVisAttributes = new G4VisAttributes(false);
369 G4bool visibility = visAttributes->IsVisible();
370 G4Colour colour = visAttributes->GetColour();
371 newVisAttributes = new G4VisAttributes(visibility, colour);
374 const G4int kAbsVal = abs(val); // the functionality is given by the abs value
376 // Default visible attributes
377 G4double red(0),green(0),blue(0); // default is black
378 G4bool isVisible(false);
379 G4bool isDaughtersInvisible(false);
380 G4VisAttributes::LineStyle lineStyle = G4VisAttributes::unbroken;
381 G4double lineWidth = 1.0;
382 G4bool isForceDrawingStyle(false);
383 G4VisAttributes::ForcedDrawingStyle drawingStyle = G4VisAttributes::wireframe;
385 // a 'hardcopy' of old vis attributes is needed because the copy constructor
386 // resets to defaults some of the data members of G4VisAttributes class
389 isVisible = visAttributes->IsVisible();
390 isDaughtersInvisible = visAttributes->IsDaughtersInvisible();
391 red = visAttributes->GetColour().GetRed();
392 green = visAttributes->GetColour().GetGreen();
393 blue = visAttributes->GetColour().GetBlue(); // old RGB components
394 lineStyle = visAttributes->GetLineStyle();
395 lineWidth = visAttributes->GetLineWidth();
396 isForceDrawingStyle = visAttributes->IsForceDrawingStyle();
397 if (isForceDrawingStyle)
398 drawingStyle = visAttributes->GetForcedDrawingStyle();
401 G4double luminosityBin(0.04), // bin for luminosity
402 luminosity(0); // colour luminosity
404 // Delete old vis. attributes if they are not shared
405 if (visAttributes && !IsSharedVisAttributes(lv)) delete visAttributes;
407 // Set the required attribute
433 lineStyle = G4VisAttributes::unbroken; break;
435 lineStyle = G4VisAttributes::dashed; break;
437 lineStyle = G4VisAttributes::dotted; break;
440 G4cout << "TG4VisManager::Gsatt() Usage of LSTY :" << G4endl
441 << "ATT = 1,2,3 means line unbroken, dashed or dotted" << G4endl
442 << "any other value resets to the default : unbroken" << G4endl;
443 lineStyle = G4VisAttributes::unbroken;
448 if (lineWidth > 7) lineWidth = 7;
450 G4cout << "TG4VisManager::Gsatt() Usage for LWID :" << G4endl
451 << " The VAL you supply means the width of lines in pixels "
452 << "for the screen and in 0.1*mm for paper." << G4endl
453 << " Negative values means the same, but for all daughters"
457 if (kAbsVal < 8) // G3 base colours
462 red=0; green=0; blue=0; //black
465 red=1; green=0; blue=0; //red
468 red=0; green=1; blue=0; //green
471 red=0; green=0; blue=1; //blue
474 red=1; green=1; blue=0; //yellow
477 red=1; green=0; blue=1; //violet
480 red=0; green=1; blue=1; //lightblue (almost !)
484 if (kAbsVal>=8 && kAbsVal<=16)
486 red=0; green=0; blue=0;
487 luminosity = (kAbsVal-7)*luminosityBin;
489 if (kAbsVal>=17 && kAbsVal<=41)
491 red=1; green=0; blue=0;
492 luminosity = (kAbsVal-16)*luminosityBin;
494 if (kAbsVal>=67 && kAbsVal<=91)
496 red=0; green=1; blue=0;
497 luminosity = (kAbsVal-66)*luminosityBin;
499 if (kAbsVal>=117 && kAbsVal<=141)
501 red=0; green=0; blue=1;
502 luminosity = (kAbsVal-116)*luminosityBin;
504 if (kAbsVal>=42 && kAbsVal<=66)
506 red=1; green=1; blue=0;
507 luminosity = (kAbsVal-41)*luminosityBin;
509 if (kAbsVal>=142 && kAbsVal<=166)
511 red=1; green=0; blue=1;
512 luminosity = (kAbsVal-141)*luminosityBin;
514 if (kAbsVal>=92 && kAbsVal<=116)
516 red=0; green=1; blue=1;
517 luminosity = (kAbsVal-91)*luminosityBin;
519 if (red < luminosityBin) red += luminosity;
520 if (green < luminosityBin) green += luminosity;
521 if (blue < luminosityBin) blue += luminosity;
524 isForceDrawingStyle = true;
528 drawingStyle = G4VisAttributes::wireframe;
531 drawingStyle = G4VisAttributes::solid;
535 G4cout << "TG4VisManager::Gsatt() FILL usage :" << G4endl
536 << " The FILL values you can supply are only :" << G4endl
537 << "+/- 1 : forces wireframe drawing (default)" << G4endl
538 << "+/- 2 : forces solid drawing" << G4endl
539 << "other values sets the drawing style to solid"
541 drawingStyle = G4VisAttributes::solid;
544 // Register vis. attributes
545 newVisAttributes->SetVisibility(isVisible);
546 newVisAttributes->SetDaughtersInvisible(isDaughtersInvisible);
547 newVisAttributes->SetColour(red,green,blue);
548 newVisAttributes->SetLineStyle(lineStyle);
549 newVisAttributes->SetLineWidth(lineWidth);
550 if (drawingStyle == G4VisAttributes::wireframe)
551 newVisAttributes->SetForceWireframe(isForceDrawingStyle);
552 if (drawingStyle == G4VisAttributes::solid)
553 newVisAttributes->SetForceSolid(isForceDrawingStyle);
555 lv->SetVisAttributes(newVisAttributes);
558 //-----------------------------------------------------------------
559 // functions for drawing
560 //-----------------------------------------------------------------
563 //_____________________________________________________________________________
564 void TG4VisManager::DrawOneSpec(const char* name)
566 // Function called when one double-clicks on a volume name
567 // in a TPaveLabel drawn by Gdtree
570 G4cout << "TG4VisManager::DrawOneSpec() Not yet implemented";
574 //_____________________________________________________________________________
575 void TG4VisManager::SetColors()
577 // Function for setting default volume colours
580 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
581 const G4LogicalVolume* pLV = 0;
584 TG4Globals::Warning("TG4VisManager::SetColors : Ignored, geometry not built.");
587 // parse the LV tree and set colours according to material density
588 for (G4int i=0; i<pLVStore->size(); i++)
590 pLV = (*pLVStore)[i];
591 // G4cout << "VOLUME : " << pLV->GetName() << G4endl;
592 const G4Material* pMaterial = pLV->GetMaterial();
593 const G4State kState = pMaterial->GetState();
594 G4double density = (pMaterial->GetDensity())*cm3/g;
595 G4String nState = "Undefined";
596 G4int colour = 1; //black by default
597 G4double luminosity = 0.;
598 if (kState == kStateUndefined)
600 nState = "Undefined";
602 if (kState == kStateSolid)
608 luminosity = 25 - 25*density/2;
610 else if (density < 3)
613 luminosity = 25 - 25*(density-2);
615 else if (density < 10)
618 luminosity = 25 - 25*(density-5)/5;
620 else if (density < 15)
623 luminosity = 25 - 25*(density-10)/5;
625 else if (density < 20)
628 luminosity = 9 - 9*(density-15)/5;
631 if (kState == kStateLiquid)
634 colour = 142; //violet
635 luminosity = 25 - 25*density/2;
637 if (kState == kStateGas)
640 if (density < 0.001) {colour = 42;} //yellow
641 else if (density < 0.002) {colour = 27;} //light red
642 else if (density < 0.003) {colour = 77;} //light green
643 else {colour = 102;} //light cyan
646 if (luminosity < 0) luminosity=0;
647 colour += (G4int)luminosity;
648 // Setting the corresponding colour
649 Gsatt(pLV->GetName(),"COLO",colour);
654 //_____________________________________________________________________________
655 void TG4VisManager::Gsatt(const char* name, const char* att, Int_t val)
657 // Geant3 description :
660 // IOPT Name of the attribute to be set
661 // IVAL Value to which the attribute is to be set
663 // name= "*" stands for all the volumes.
664 // iopt can be chosen among the following :
665 // kWORK, kSEEN, kLSTY, kLWID, kCOLO, kFILL, kSET, kDET, kDTYP
669 G4LogicalVolume* lv = 0;
670 G4RWTPtrOrderedVector<G4LogicalVolume> lvList;
671 G4String sname(name),
674 // seek for known attributes
675 TG4G3Attribute attribute = kUNKNOWN;
676 if (CaseInsensitiveEqual(att,"WORK"))
678 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
679 message += satt + " not used in G4";
680 TG4Globals::Warning(message);
683 if (CaseInsensitiveEqual(att,"SEEN")) attribute = kSEEN;
684 if (CaseInsensitiveEqual(att,"LSTY")) attribute = kLSTY;
685 if (CaseInsensitiveEqual(att,"LWID")) attribute = kLWID;
686 if (CaseInsensitiveEqual(att,"COLO")) attribute = kCOLO;
687 if (CaseInsensitiveEqual(att,"FILL")) attribute = kFILL;
688 if (CaseInsensitiveEqual(att,"SET"))
690 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
691 message += satt + " not used in G4";
692 TG4Globals::Warning(message);
695 if (CaseInsensitiveEqual(att,"DET"))
697 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
698 message += satt + " not used in G4";
699 TG4Globals::Warning(message);
702 if (CaseInsensitiveEqual(att,"DTYP"))
704 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
705 message += satt + " not used in G4";
706 TG4Globals::Warning(message);
709 if (attribute == kUNKNOWN)
711 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
712 message += satt + " unknown";
713 TG4Globals::Warning(message);
716 G4bool doForDaughters(false), // tree iterator flag
717 doForAll(false), // activated if NAME is "*"
718 topVisible(false); // activated for kSEEN/-2
719 if (sname == "*") doForAll = true;
720 if (val < 0 && sname!="*") doForDaughters = true;
721 if (attribute==kSEEN && val==-2) topVisible = true;
723 // parse all the tree
726 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
727 for (G4int i=0; i<pLVStore->size(); i++)
730 SetG4Attribute(lv,attribute,ival);
735 // get the logical volume pointer corresponding to NAME
736 lvList = GetLVList(name);
737 if (lvList.isEmpty())
739 G4String message = "TG4VisManager::Gsatt(): Ignored\n";
740 message += " Logical volume " + sname + " has not been found.\n";
741 TG4Globals::Warning(message);
744 // set attribute for all descendents
747 for (G4int i=0; i<lvList.entries(); i++)
750 SetAtt4Daughters(lv,attribute,ival);
755 for (G4int i=0; i<lvList.entries(); i++)
758 SetG4Attribute(lv,attribute,ival);
763 for (G4int i=0; i<lvList.entries(); i++)
766 SetG4Attribute(lv,attribute,1);
772 //_____________________________________________________________________________
773 void TG4VisManager::Gdraw(const char *name,Float_t theta, Float_t phi, Float_t psi,
774 Float_t u0,Float_t v0,Float_t ul,Float_t vl)
776 // Draw the physical volume NAME and all descendents;
777 // Mandatory : the graphics system, scene and view must be
778 // initialized, e.g. "/vis~/create_view/new_graphics_system OGLSX";
779 // Any call of Gdraw() will use the current graphics system and
780 // the current window.
781 // The result will be a centered view drawing of the designated volume,
782 // lights moving with camera, viewpoint direction given by theta/phi
783 // and rotation on the screen given by psi;
784 // The u0, v0, ul, vl factors are ignored since the object will be
785 // automatically centered and will be confortable in the window
786 // at any viewing angle.
788 // check if G4 graphics is ready for drawing
791 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
794 "TG4VisManager::Gdraw: Ignored - No graphics driver is built. ");
797 if (NeedSetColours())
800 SetColourFlag(false);
803 const G4double kRad = M_PI/180.;
804 G4RWTPtrOrderedVector<G4VPhysicalVolume> pvList;
805 G4String sname(name);
806 G4bool successful = false;
808 pvList = GetPVList(name);
809 if (pvList.isEmpty())
811 G4String message = "TG4VisManager::Gdraw() :\n";
812 message += "Volume " + sname + " not found. Bailing out";
813 TG4Globals::Warning(message);
817 G4VPhysicalVolume *pPV = 0;
819 // clear the current scene if not empty
820 if (!fpScene->IsEmpty()) fpScene->Clear();
822 // create and add object's model list to the runtime-duration model
824 // (it is deleted in the VisManager destructor within
825 // all the RWTPtrOrderedVectors of the scene)
826 for (G4int i=0; i<pvList.entries(); i++)
829 G4LogicalVolume* pLV = pPV->GetLogicalVolume();
830 G4VSolid* pSolid = pLV->GetSolid();
831 successful = fpScene->AddRunDurationModel(new G4PhysicalVolumeModel(pPV));
834 G4String message = "TG4VisManager::Gdraw() Could not add ";
835 message += pPV->GetName() + " to the drawing list. Probably ";
836 message += "it is already in the list.";
837 TG4Globals::Warning(message);
840 // get the standard target point of the scene
841 const G4Point3D kTargetPoint = fpScene->GetStandardTargetPoint();
843 // set the viewpoint and the rotation on the screen
844 G4Vector3D viewpointDirection(sin(theta*kRad)*cos(phi*kRad),
845 sin(theta*kRad)*sin(phi*kRad), cos(theta*kRad));
846 G4Vector3D upVector(sin(psi*kRad), cos(psi*kRad),0);
848 // set and register view parameters to the viewer
850 fVP.SetLightsMoveWithCamera(true);
853 fVP.UnsetViewDigis();
854 fVP.SetNoOfSides(48);
855 fVP.SetCurrentTargetPoint(kTargetPoint);
856 fVP.SetViewpointDirection(viewpointDirection);
857 fVP.SetUpVector(upVector);
858 fVP.SetDensityCulling(true);
859 fpViewer->SetViewParameters(fVP);
863 fpSceneHandler->SetScene(fpScene);
864 fpSceneHandler->SetCurrentViewer(fpViewer);
865 fpViewer->DrawView();
866 fpViewer->ShowView();
868 else TG4Globals::Warning(
869 "TG4VisManager::Gdraw: Ignored - Failed to register volume");