2 // Category: visualization
4 // According to visualization/management/include/MyVisManager.*
5 // John Allison 24th January 1998.
6 // I. Hrivnacova 12.5.98
8 // Renamed to TG4VisManager
9 // I. Hrivnacova, 3.9.99
11 // Added AliMC implementation
14 // Added OpenGL*Win32, RayTracer (as replacement of RayX) drivers
15 // based on G4 suggestions.
16 // I. Gonzalez, 4.4.2000
18 // Example Visualization Manager description:
19 // Implements virtual function RegisterGraphicsSystems.
20 // Exploits C-pre-processor variables G4VIS_USE_DAWN, etc.,
21 // which are set by the G4 makefiles if
22 // environment variables of the same name are set.
24 // So all you have to do is set environment variables and compile and
25 // instantiate this in your main().
27 // Alternatively, you can implement an empty function here and just
28 // register the systems you want in your main(), e.g.:
29 // G4VisManager* myVisManager = new MyVisManager;
30 // myVisManager -> RegisterGraphicsSystem (new MyGraphicsSystem);
35 #include "TG4VisManager.h"
36 #include "TG4Globals.h"
38 #include <G4LogicalVolumeStore.hh>
39 #include <G4PhysicalVolumeStore.hh>
40 #include <G4TransportationManager.hh>
41 #include <G4Material.hh>
42 #include <G4PhysicalVolumeModel.hh>
43 #include <G4VVisManager.hh>
45 // Supported drivers...
48 #include <G4FukuiRenderer.hh>
51 #ifdef G4VIS_USE_DAWNFILE
52 #include <G4DAWNFILE.hh>
55 #ifdef G4VIS_USE_OPACS
60 #ifdef G4VIS_USE_OPENGLX
61 #include <G4OpenGLImmediateX.hh>
62 #include <G4OpenGLStoredX.hh>
65 #ifdef G4VIS_USE_OPENGLXM
66 #include <G4OpenGLImmediateXm.hh>
67 #include <G4OpenGLStoredXm.hh>
70 #ifdef G4VIS_USE_OPENGLWIN32
71 #include "G4OpenGLImmediateWin32.hh"
72 #include "G4OpenGLStoredWin32.hh"
76 #include <G4OpenInventorX.hh>
79 #ifdef G4VIS_USE_OIWIN32
80 #include <G4OpenInventorWin32.hh>
83 #ifdef G4VIS_USE_RAYTRACER
84 #include "G4RayTracer.hh"
92 #ifdef G4VIS_USE_VRMLFILE
93 #include <G4VRML1File.hh>
94 #include <G4VRML2File.hh>
97 TG4VisManager::TG4VisManager(G4int verboseLevel) {
99 fVerbose = verboseLevel;
103 TG4VisManager::TG4VisManager(const TG4VisManager& right) {
105 TG4Globals::Exception(
106 "Attempt to copy TG4VisManager singleton.");
109 TG4VisManager::~TG4VisManager() {
115 TG4VisManager& TG4VisManager::operator=(const TG4VisManager& right)
117 // check assignement to self
118 if (this == &right) return *this;
120 TG4Globals::Exception(
121 "Attempt to assign TG4VisManager singleton.");
128 void TG4VisManager::RegisterGraphicsSystems()
130 // Registers the graphics systems.
133 // all created graphics system instances are
134 // deleted in G4VisManager::~G4VisManager()
135 #ifdef G4VIS_USE_DAWN
136 RegisterGraphicsSystem(new G4FukuiRenderer);
139 #ifdef G4VIS_USE_DAWNFILE
140 RegisterGraphicsSystem(new G4DAWNFILE);
143 #ifdef G4VIS_USE_OPACS
144 RegisterGraphicsSystem(new G4Wo);
145 RegisterGraphicsSystem(new G4Xo);
148 #ifdef G4VIS_USE_OPENGLX
149 RegisterGraphicsSystem(new G4OpenGLImmediateX);
150 RegisterGraphicsSystem(new G4OpenGLStoredX);
153 #ifdef G4VIS_USE_OPENGLXM
154 RegisterGraphicsSystem(new G4OpenGLImmediateXm);
155 RegisterGraphicsSystem(new G4OpenGLStoredXm);
158 #ifdef G4VIS_USE_OPENGLWIN32
159 RegisterGraphicsSystem (new G4OpenGLImmediateWin32);
160 RegisterGraphicsSystem (new G4OpenGLStoredWin32);
164 RegisterGraphicsSystem(new G4OpenInventorX);
167 #ifdef G4VIS_USE_OIWIN32
168 RegisterGraphicsSystem(new G4OpenInventorWin32);
171 #ifdef G4VIS_USE_RAYTRACER
172 RegisterGraphicsSystem (new G4RayTracer);
175 #ifdef G4VIS_USE_VRML
176 RegisterGraphicsSystem(new G4VRML1);
177 RegisterGraphicsSystem(new G4VRML2);
180 #ifdef G4VIS_USE_VRMLFILE
181 RegisterGraphicsSystem(new G4VRML1File);
182 RegisterGraphicsSystem(new G4VRML2File);
187 "\nYou have successfully chosen to use the following graphics systems."
189 PrintAvailableGraphicsSystems();
193 //---------------------------------------------------------------
195 //---------------------------------------------------------------
198 G4RWTPtrOrderedVector<G4LogicalVolume> TG4VisManager::GetLVList(G4String name)
200 // Get function returning the list of logical volumes
201 // associated to NAME; G4 built clones of a G3 volume (identified
202 // with NAME_NUMBER will be added to the list)
203 // NAME can be the name of a logical or physical volume
206 G4RWTPtrOrderedVector <G4LogicalVolume> lvList;
207 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
208 G4LogicalVolume* pLV = 0;
211 for (G4int i=0; i<pLVStore->entries(); i++)
213 pLV = pLVStore->at(i);
214 if (CaseInsensitiveEqual(name,pLV->GetName()))
216 if (!lvList.contains(pLV)) lvList.append(pLV);
220 if (!lvList.isEmpty()) return lvList;
221 G4PhysicalVolumeStore* pPVStore = G4PhysicalVolumeStore::GetInstance();
222 G4VPhysicalVolume* pPV = 0;
225 for (G4int i=0; i<pPVStore->entries(); i++)
227 pPV = pPVStore->at(i);
228 if (CaseInsensitiveEqual(name,pPV->GetName()))
230 pLV = pPV->GetLogicalVolume();
231 if (!lvList.contains(pLV)) lvList.append(pLV);
239 G4RWTPtrOrderedVector<G4VPhysicalVolume> TG4VisManager::GetPVList(G4String name)
241 // Get function returning the physical volume pointer for NAME
244 G4RWTPtrOrderedVector <G4VPhysicalVolume> pvList;
245 G4PhysicalVolumeStore* pPVStore = G4PhysicalVolumeStore::GetInstance();
248 TG4Globals::Warning("TG4VisManager::Gdraw : No volume store !");
251 G4VPhysicalVolume* pPV = 0;
252 for (G4int i=0; i<pPVStore->entries(); i++)
254 pPV = pPVStore->at(i);
255 if (CaseInsensitiveEqual(name,pPV->GetName()))
257 if (!pvList.contains(pPV)) pvList.append(pPV);
264 G4bool TG4VisManager::CaseInsensitiveEqual(const G4String string1,
265 const G4String string2)
267 // Case insensitive comparison of 2 strings
271 if (string1 == string2) return true;
272 // if (string1.length() != string2.length()) return false;
273 for (i=0; i<string1.length(); i++)
275 G4int diff = abs((G4int)string1(i)-(G4int)string2(i));
276 if (diff && (diff!=32)) return false;
278 if (string2.length() > string1.length())
280 if (string2(i) == '_') return true;
287 void TG4VisManager::SetAtt4Daughters(G4LogicalVolume* const lv,
288 const TG3Attribute att, const G4int val)
290 // Iterator for setting a visual attribute for all daughters
293 SetG4Attribute(lv,att,val);
295 G4String lvName = lv->GetName();
296 G4int nOfDaughters = lv->GetNoDaughters();
299 G4String previousName = "";
300 for (G4int i=0; i<nOfDaughters; i++)
302 G4LogicalVolume* lvd = lv->GetDaughter(i)->GetLogicalVolume();
303 G4String currentName = lvd->GetName();
304 if (currentName != lvName && currentName != previousName)
306 SetAtt4Daughters(lvd, att, val);
307 previousName = currentName;
314 G4bool TG4VisManager::IsSharedVisAttributes(const G4LogicalVolume* pLV)
316 // Function seeking if the volume's visible attributes are shared with
320 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
321 G4LogicalVolume* pLVCurrent = 0;
322 const G4VisAttributes* pVisAtt = pLV->GetVisAttributes();
323 if (!pVisAtt) return false;
324 for (G4int i=0; i<pLVStore->entries(); i++)
326 pLVCurrent = pLVStore->at(i);
327 if (pLVCurrent != pLV)
329 if (pLVCurrent->GetVisAttributes() == pVisAtt)
339 void TG4VisManager::SetG4Attribute(G4LogicalVolume* const lv,
340 const TG3Attribute att, const G4int val)
342 // Set the G4 attribute fo volume LV accordingly to the G3 description
347 // Dupplicating old vis. attributes
348 const G4VisAttributes* visAttributes = lv->GetVisAttributes();
349 G4VisAttributes* newVisAttributes;
351 newVisAttributes = new G4VisAttributes(false);
353 newVisAttributes = new G4VisAttributes(visAttributes);
355 const G4int kAbsVal = abs(val); // the functionality is given by the abs value
357 // Default visible attributes
358 G4double red(0),green(0),blue(0); // default is black
359 G4bool isVisible(false);
360 G4bool isDaughtersInvisible(false);
361 G4VisAttributes::LineStyle lineStyle = G4VisAttributes::unbroken;
362 G4double lineWidth = 1.0;
363 G4bool isForceDrawingStyle(false);
364 G4VisAttributes::ForcedDrawingStyle drawingStyle = G4VisAttributes::wireframe;
366 // a 'hardcopy' of old vis attributes is needed because the copy constructor
367 // resets to defaults some of the data members of G4VisAttributes class
370 isVisible = visAttributes->IsVisible();
371 isDaughtersInvisible = visAttributes->IsDaughtersInvisible();
372 red = visAttributes->GetColour().GetRed();
373 green = visAttributes->GetColour().GetGreen();
374 blue = visAttributes->GetColour().GetBlue(); // old RGB components
375 lineStyle = visAttributes->GetLineStyle();
376 lineWidth = visAttributes->GetLineWidth();
377 isForceDrawingStyle = visAttributes->IsForceDrawingStyle();
378 if (isForceDrawingStyle)
379 drawingStyle = visAttributes->GetForcedDrawingStyle();
382 G4double luminosityBin(0.04), // bin for luminosity
383 luminosity(0); // colour luminosity
385 // Delete old vis. attributes if they are not shared
386 if (visAttributes && !IsSharedVisAttributes(lv)) delete visAttributes;
388 // Set the required attribute
414 lineStyle = G4VisAttributes::unbroken; break;
416 lineStyle = G4VisAttributes::dashed; break;
418 lineStyle = G4VisAttributes::dotted; break;
421 G4cout << "TG4VisManager::Gsatt() Usage of LSTY :" << G4endl
422 << "ATT = 1,2,3 means line unbroken, dashed or dotted" << G4endl
423 << "any other value resets to the default : unbroken" << G4endl;
424 lineStyle = G4VisAttributes::unbroken;
429 if (lineWidth > 7) lineWidth = 7;
431 G4cout << "TG4VisManager::Gsatt() Usage for LWID :" << G4endl
432 << " The VAL you supply means the width of lines in pixels "
433 << "for the screen and in 0.1*mm for paper." << G4endl
434 << " Negative values means the same, but for all daughters"
438 if (kAbsVal < 8) // G3 base colours
443 red=0; green=0; blue=0; //black
446 red=1; green=0; blue=0; //red
449 red=0; green=1; blue=0; //green
452 red=0; green=0; blue=1; //blue
455 red=1; green=1; blue=0; //yellow
458 red=1; green=0; blue=1; //violet
461 red=0; green=1; blue=1; //lightblue (almost !)
465 if (kAbsVal>=8 && kAbsVal<=16)
467 red=0; green=0; blue=0;
468 luminosity = (kAbsVal-7)*luminosityBin;
470 if (kAbsVal>=17 && kAbsVal<=41)
472 red=1; green=0; blue=0;
473 luminosity = (kAbsVal-16)*luminosityBin;
475 if (kAbsVal>=67 && kAbsVal<=91)
477 red=0; green=1; blue=0;
478 luminosity = (kAbsVal-66)*luminosityBin;
480 if (kAbsVal>=117 && kAbsVal<=141)
482 red=0; green=0; blue=1;
483 luminosity = (kAbsVal-116)*luminosityBin;
485 if (kAbsVal>=42 && kAbsVal<=66)
487 red=1; green=1; blue=0;
488 luminosity = (kAbsVal-41)*luminosityBin;
490 if (kAbsVal>=142 && kAbsVal<=166)
492 red=1; green=0; blue=1;
493 luminosity = (kAbsVal-141)*luminosityBin;
495 if (kAbsVal>=92 && kAbsVal<=116)
497 red=0; green=1; blue=1;
498 luminosity = (kAbsVal-91)*luminosityBin;
500 if (red < luminosityBin) red += luminosity;
501 if (green < luminosityBin) green += luminosity;
502 if (blue < luminosityBin) blue += luminosity;
505 isForceDrawingStyle = true;
509 drawingStyle = G4VisAttributes::wireframe;
512 drawingStyle = G4VisAttributes::solid;
516 G4cout << "TG4VisManager::Gsatt() FILL usage :" << G4endl
517 << " The FILL values you can supply are only :" << G4endl
518 << "+/- 1 : forces wireframe drawing (default)" << G4endl
519 << "+/- 2 : forces solid drawing" << G4endl
520 << "other values sets the drawing style to solid"
522 drawingStyle = G4VisAttributes::solid;
525 // Register vis. attributes
526 newVisAttributes->SetVisibility(isVisible);
527 newVisAttributes->SetDaughtersInvisible(isDaughtersInvisible);
528 newVisAttributes->SetColour(red,green,blue);
529 newVisAttributes->SetLineStyle(lineStyle);
530 newVisAttributes->SetLineWidth(lineWidth);
531 if (drawingStyle == G4VisAttributes::wireframe)
532 newVisAttributes->SetForceWireframe(isForceDrawingStyle);
533 if (drawingStyle == G4VisAttributes::solid)
534 newVisAttributes->SetForceSolid(isForceDrawingStyle);
536 lv->SetVisAttributes(newVisAttributes);
539 //-----------------------------------------------------------------
540 // functions for drawing
541 //-----------------------------------------------------------------
543 void TG4VisManager::DrawOneSpec(const char* name)
545 // Function called when one double-clicks on a volume name
546 // in a TPaveLabel drawn by Gdtree
549 G4cout << "TG4VisManager::DrawOneSpec() Not yet implemented";
553 void TG4VisManager::SetColors()
555 // Function for setting default volume colours
558 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
559 const G4LogicalVolume* pLV = 0;
562 TG4Globals::Warning("TG4VisManager::SetColors : Ignored, geometry not built.");
565 // parse the LV tree and set colours according to material density
566 for (G4int i=0; i<pLVStore->entries(); i++)
568 pLV = pLVStore->at(i);
569 // G4cout << "VOLUME : " << pLV->GetName() << G4endl;
570 const G4Material* pMaterial = pLV->GetMaterial();
571 const G4State kState = pMaterial->GetState();
572 G4double density = (pMaterial->GetDensity())*cm3/g;
573 G4String nState = "Undefined";
574 G4int colour = 1; //black by default
575 G4double luminosity = 0.;
576 if (kState == kStateUndefined)
578 nState = "Undefined";
580 if (kState == kStateSolid)
586 luminosity = 25 - 25*density/2;
588 else if (density < 3)
591 luminosity = 25 - 25*(density-2);
593 else if (density < 10)
596 luminosity = 25 - 25*(density-5)/5;
598 else if (density < 15)
601 luminosity = 25 - 25*(density-10)/5;
603 else if (density < 20)
606 luminosity = 9 - 9*(density-15)/5;
609 if (kState == kStateLiquid)
612 colour = 142; //violet
613 luminosity = 25 - 25*density/2;
615 if (kState == kStateGas)
618 if (density < 0.001) {colour = 42;} //yellow
619 else if (density < 0.002) {colour = 27;} //light red
620 else if (density < 0.003) {colour = 77;} //light green
621 else {colour = 102;} //light cyan
624 if (luminosity < 0) luminosity=0;
625 colour += (G4int)luminosity;
626 // Setting the corresponding colour
627 Gsatt(pLV->GetName(),"COLO",colour);
632 void TG4VisManager::Gsatt(const char* name, const char* att, Int_t val)
634 // Geant3 description :
637 // IOPT Name of the attribute to be set
638 // IVAL Value to which the attribute is to be set
640 // name= "*" stands for all the volumes.
641 // iopt can be chosen among the following :
642 // kWORK, kSEEN, kLSTY, kLWID, kCOLO, kFILL, kSET, kDET, kDTYP
646 G4LogicalVolume* lv = 0;
647 G4RWTPtrOrderedVector<G4LogicalVolume> lvList;
648 G4String sname(name),
651 // seek for known attributes
652 TG3Attribute attribute = kUNKNOWN;
653 if (CaseInsensitiveEqual(att,"WORK"))
655 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
656 message += satt + " not used in G4";
657 TG4Globals::Warning(message);
660 if (CaseInsensitiveEqual(att,"SEEN")) attribute = kSEEN;
661 if (CaseInsensitiveEqual(att,"LSTY")) attribute = kLSTY;
662 if (CaseInsensitiveEqual(att,"LWID")) attribute = kLWID;
663 if (CaseInsensitiveEqual(att,"COLO")) attribute = kCOLO;
664 if (CaseInsensitiveEqual(att,"FILL")) attribute = kFILL;
665 if (CaseInsensitiveEqual(att,"SET"))
667 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
668 message += satt + " not used in G4";
669 TG4Globals::Warning(message);
672 if (CaseInsensitiveEqual(att,"DET"))
674 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
675 message += satt + " not used in G4";
676 TG4Globals::Warning(message);
679 if (CaseInsensitiveEqual(att,"DTYP"))
681 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
682 message += satt + " not used in G4";
683 TG4Globals::Warning(message);
686 if (attribute == kUNKNOWN)
688 G4String message = "TG4VisManager::Gsatt: G3Attribute ";
689 message += satt + " unknown";
690 TG4Globals::Warning(message);
693 G4bool doForDaughters(false), // tree iterator flag
694 doForAll(false), // activated if NAME is "*"
695 topVisible(false); // activated for kSEEN/-2
696 if (sname == "*") doForAll = true;
697 if (val < 0 && sname!="*") doForDaughters = true;
698 if (attribute==kSEEN && val==-2) topVisible = true;
700 // parse all the tree
703 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
704 for (G4int i=0; i<pLVStore->entries(); i++)
706 lv = pLVStore->at(i);
707 SetG4Attribute(lv,attribute,ival);
712 // get the logical volume pointer corresponding to NAME
713 lvList = GetLVList(name);
714 if (lvList.isEmpty())
716 G4String message = "TG4VisManager::Gsatt(): Ignored\n";
717 message += " Logical volume " + sname + " has not been found.\n";
718 TG4Globals::Warning(message);
721 // set attribute for all descendents
724 for (G4int i=0; i<lvList.entries(); i++)
727 SetAtt4Daughters(lv,attribute,ival);
732 for (G4int i=0; i<lvList.entries(); i++)
735 SetG4Attribute(lv,attribute,ival);
740 for (G4int i=0; i<lvList.entries(); i++)
743 SetG4Attribute(lv,attribute,1);
749 void TG4VisManager::Gdraw(const char *name,Float_t theta, Float_t phi, Float_t psi,
750 Float_t u0,Float_t v0,Float_t ul,Float_t vl)
752 // Draw the physical volume NAME and all descendents;
753 // Mandatory : the graphics system, scene and view must be
754 // initialized, e.g. "/vis~/create_view/new_graphics_system OGLSX";
755 // Any call of Gdraw() will use the current graphics system and
756 // the current window.
757 // The result will be a centered view drawing of the designated volume,
758 // lights moving with camera, viewpoint direction given by theta/phi
759 // and rotation on the screen given by psi;
760 // The u0, v0, ul, vl factors are ignored since the object will be
761 // automatically centered and will be confortable in the window
762 // at any viewing angle.
764 // check if G4 graphics is ready for drawing
767 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
770 "TG4VisManager::Gdraw: Ignored - No graphics driver is built. ");
773 if (NeedSetColours())
776 SetColourFlag(false);
779 const G4double kRad = M_PI/180.;
780 G4RWTPtrOrderedVector<G4VPhysicalVolume> pvList;
781 G4String sname(name);
782 G4bool successful = false;
784 pvList = GetPVList(name);
785 if (pvList.isEmpty())
787 G4String message = "TG4VisManager::Gdraw() :\n";
788 message += "Volume " + sname + " not found. Bailing out";
789 TG4Globals::Warning(message);
793 G4VPhysicalVolume *pPV = 0;
795 // clear the current scene if not empty
796 if (!fpScene->IsEmpty()) fpScene->Clear();
798 // create and add object's model list to the runtime-duration model
800 // (it is deleted in the VisManager destructor within
801 // all the RWTPtrOrderedVectors of the scene)
802 for (G4int i=0; i<pvList.entries(); i++)
805 G4LogicalVolume* pLV = pPV->GetLogicalVolume();
806 G4VSolid* pSolid = pLV->GetSolid();
807 successful = fpScene->AddRunDurationModel(new G4PhysicalVolumeModel(pPV));
810 G4String message = "TG4VisManager::Gdraw() Could not add ";
811 message += pPV->GetName() + " to the drawing list. Probably ";
812 message += "it is already in the list.";
813 TG4Globals::Warning(message);
816 // get the standard target point of the scene
817 const G4Point3D kTargetPoint = fpScene->GetStandardTargetPoint();
819 // set the viewpoint and the rotation on the screen
820 G4Vector3D viewpointDirection(sin(theta*kRad)*cos(phi*kRad),
821 sin(theta*kRad)*sin(phi*kRad), cos(theta*kRad));
822 G4Vector3D upVector(sin(psi*kRad), cos(psi*kRad),0);
824 // set and register view parameters to the viewer
826 fVP.SetLightsMoveWithCamera(true);
829 fVP.UnsetViewDigis();
830 fVP.SetNoOfSides(48);
831 fVP.SetCurrentTargetPoint(kTargetPoint);
832 fVP.SetViewpointDirection(viewpointDirection);
833 fVP.SetUpVector(upVector);
834 fVP.SetDensityCulling(true);
835 fpViewer->SetViewParameters(fVP);
839 fpSceneHandler->SetScene(fpScene);
840 fpSceneHandler->SetCurrentViewer(fpViewer);
841 fpViewer->DrawView();
842 fpViewer->ShowView();
844 else TG4Globals::Warning(
845 "TG4VisManager::Gdraw: Ignored - Failed to register volume");