Key listeners and menus for ROOT's GL Viewer?

Hello all,

(Newbie warning: this is my first post)

I’m hacking up a 3-D visualization package for a vertex detector using ROOT’s OpenGL display (TGeoVolume and friends). It’s going remarkably smoothly thus far, but I want to add some functionality to the user interface specific to my application to make certain features more accessible. I’d like to be able to tie certain commands to single keystrokes using key listeners, and add items to the menu bar.

Also, I’m trying to determine how I can change the contents of my scene and then update the display in the window. I want the user to be able to toggle the display of certain elements in the scene.

Can anyone explain the standard means of doing these things or point me to the relevant documentation on it? Examples demonstrating the techniques would also be especially helpful.

Thanks,
Matthew Lockner

Hi Matthew,

Have a look at EVE - The Event Visualization Environment of ROOT :slight_smile:
root.cern.ch/root/htmldoc/GRAF3D_EVE_Index.html

EVE is, in its essence, an object-manager layer over ROOT GUI and GL with several components required for event-display provided for you.
Also, display of TGeo geometries (either full geometry trees or individual shapes) is fully supported.

EVE demos can be found in $ROOTSYS/tutorials/eve/.

Now, to be able to answer to you direct questions, can you tell us in some more detail how you populate the GL viewers - do you use the TPad interface or you fill TGLScenes yourself?

TGLViewer event-handling is done via the TGLEventHandler class - this can be subclassed and modified to suit your needs. For example see TEveLegoEventHandler and its usage in tutorials/eve/cms_calo.C.

Best,
Matevz

[quote=“matevz”]Hi Matthew,

Have a look at EVE - The Event Visualization Environment of ROOT :slight_smile:
root.cern.ch/root/htmldoc/GRAF3D_EVE_Index.html

EVE is, in its essence, an object-manager layer over ROOT GUI and GL with several components required for event-display provided for you.
Also, display of TGeo geometries (either full geometry trees or individual shapes) is fully supported.

EVE demos can be found in $ROOTSYS/tutorials/eve/.[/quote]

That’s been on my to-do list… our installations don’t include EVE so I’d have to do it at home. It does look nice though.

Well, I copied and pasted someone else’s code I found online :slight_smile: The example I found defined functions addPoint(), addLine(), etc. taking a TGeoVolume as an argument and then using the TGeoManager to do the hard work, e.g. for points represented as spheres:

  TGeoMedium *solid = gGeoManager->GetMedium(2);
  TGeoVolume *point = gGeoManager->MakeSphere("Point",solid,0.,0.1,0.,180.,0.,360.);
  point->SetLineColor(color);

  top->AddNode(point,ID++,new TGeoTranslation(offs[0],offs[1],offs[2]));

So I’m reading the detector geometry from a text file and representing sensitive volumes as thin boxes, and then displaying hits as tiny spheres and tracks as a bunch of conjoined line segments (makeTube).

[quote]TGLViewer event-handling is done via the TGLEventHandler class - this can be subclassed and modified to suit your needs. For example see TEveLegoEventHandler and its usage in tutorials/eve/cms_calo.C.

Best,
Matevz[/quote]

Excellent. I figured the capabilities had to be in ROOT somewhere!

About the redraw … I assume you a have a TPad* pad somewhere in your code. After you’re done with updates, do:

If you also want to reset the camera(s), call before that:

This is meaningful if the scene bounding-box changes significantly - but changing camera without a very good reason is annoying to the user.

How come your ROOT distribution does not include EVE?[/code]

[quote=“matevz”]About the redraw … I assume you a have a TPad* pad somewhere in your code. After you’re done with updates, do:

Actually I don’t, at least not directly. I do have an instance of TApplication, though; does that have a TPad member somewhere? (Sorry, I know, it’s in the online docs somewhere…)

[quote]If you also want to reset the camera(s), call before that:

This is meaningful if the scene bounding-box changes significantly - but changing camera without a very good reason is annoying to the user.

How come your ROOT distribution does not include EVE?[/code][/quote]

As one of the project code gurus colorfully stated it, some “ancient sin” committed in some file prevents us from upgrading (and to a lesser degree, there is a fear of instability in newer versions). Someone wrote something version-dependent and it became entrenched (I presume the author is also long gone). I’ve run into some questionable cases myself, where i.e. the names of publically-exported constants change from one version to the next. Largely a fact of life in software though.

OK … so you seem to have very old root :slight_smile: The GL infrastructure has changed significantly in the last two years.

What version of root do you have?

Can you post a code showing how you draw, say, a simple sphere.

Cheers,
Matevz

[quote=“matevz”]OK … so you seem to have very old root :slight_smile: The GL infrastructure has changed significantly in the last two years.

What version of root do you have?[/quote]

Thus sayeth ROOT:

[quote=“matevz”]Can you post a code showing how you draw, say, a simple sphere.

Cheers,
Matevz[/quote]

I think at this point I have to post my acknowledgements - this is based on the file decay.cc I found at https://twiki.cern.ch/twiki/bin/viewfile/LHCb/WeeklyMeetings?rev=1;filename=decay.cc.

{
  gSystem->Load("libGeom");

  TCanvas *c1 = new TCanvas("glcanvas","sphere",0,0,1131,800);

  // delete previous geometry objects in case this script is reexecuted

  if(gGeoManager) delete gGeoManager;
  new TGeoManager("geom","display");

  // define materials and media

  TGeoMaterial *Glas  = new TGeoMaterial("Glas", 0., 0, 0.);
  TGeoMaterial *Solid = new TGeoMaterial("Solid",0., 0 ,0.);
  TGeoMaterial *Air   = new TGeoMaterial("Air", 0.,0.,0.);

  Glas->SetTransparency(80);

  TGeoMedium   *air   = new TGeoMedium("Air",1,Air);
  TGeoMedium   *solid = new TGeoMedium("Solid",2,Solid);
  TGeoMedium   *glas  = new TGeoMedium("Glas",3,Glas);

  // define the top volume where to build the geometry

  TGeoVolume   *top  = gGeoManager->MakeBox("Top",air,100,100,100);


  // construct the geometry, define the initial view and draw everything

  TGeoVolume   *view  = gGeoManager->MakeBox("View",air,1000,1000,1000);

  TGeoVolume *point = gGeoManager->MakeSphere("Point",solid,0.,0.5,0.,180.,0.,360.);
  point->SetLineColor(7);

  view->AddNode(point, 0, new TGeoTranslation(0, 0, 0));

  gGeoManager->SetTopVolume(view);
  gGeoManager->CloseGeometry();
  view->Draw("gl");

  return;
}

OK, with root-5.17 you should forget everything I said so far :slight_smile:

  1. To do the redraw, I’d go for: // after view->Draw("gl"); TVirtualPad* p = gPad; // when you need redraw p->Modified(); p->Update();

  2. The event-handling was still very much inside the TGL[SA]Viewer so it will be hard to override. One could in principle sub-class the TGLSAViewer and override the key-handling methods, but then the question is what was the state of the plugin system - Draw() would have to instantiate your viewer class, not the default one. Check if directory $ROOTSYS/etc/plugins/TVirtualViewer3D/ is there - otherwise we’ll have to look for another solution.

Cheers,
Matevz

Thanks, I think I might be able to work with this. I see a ProcessGUIEvent() method here, pretty straightforward.

Out installation doesn’t have $ROOTSYS/etc/plugins, though.

(EDIT: Never mind, I think I see why you were mentioning plugins now. It looked easy on first glance, anyway…)

OK, keep me posted.

If you get into trouble, I can always install 5.17 and give it a try :slight_smile:

Good luck,
Matevz