Files
geant4/source/visualization/OpenGL/src/G4OpenGLXmViewer.cc
T
2016-06-09 15:16:48 +02:00

667 lines
20 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4OpenGLXmViewer.cc,v 1.23 2006/06/29 21:20:16 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
//
//
// Andrew Walkden 10th February 1997
// G4OpenGLXmViewer : Class derived from G4OpenGLXViewer, to provide
// (Motif) widget OpenGL functionality for GEANT4.
#ifdef G4VIS_BUILD_OPENGLXM_DRIVER
#include "globals.hh"
#include "G4OpenGLXmViewer.hh"
#include "G4VisExtent.hh"
#include "G4LogicalVolume.hh"
#include "G4VSolid.hh"
#include "G4Point3D.hh"
#include "G4Normal3D.hh"
#include "G4OpenGLXmSliderBar.hh"
#include "G4Xt.hh"
#include <X11/Shell.h>
#include <sstream>
void G4OpenGLXmViewer::ShowView () {
G4Xt::getInstance () -> SecondaryLoop ();
}
void G4OpenGLXmViewer::GetXmConnection () {
G4Xt* interactorManager = G4Xt::getInstance ();
toplevel = (Widget)interactorManager->GetMainInteractor();
app = XtWidgetToApplicationContext(toplevel);
if (!toplevel) {
fViewId = -1; // This flags an error.
G4cerr << "G4OpenGLXmViewer::GetXmConnection unable to Initialize"
" application context." << G4endl;
return;
}
// Better to put this in an X11 resource file !!!
std::ostringstream oss;
oss <<
"*glxarea*width: " << fVP.GetWindowSizeHintX() << "\n"
"*glxarea*height: " << fVP.GetWindowSizeHintY() << "\n"
/*
// Tried this as a replacement for the above two lines, but
// sub-windows (rotation, etc.) came same size!!
"*geometry: " << fVP.GetXGeometryString() << "\n"
*/
"*frame*x: 10\n"
"*frame*y: 10\n"
"*frame*topOffset: 10\n"
"*frame*bottomOffset: 10\n"
"*frame*rightOffset: 10\n"
"*frame*leftOffset: 10\n"
"*frame*shadowType: SHADOW_IN\n"
"*frame*useColorObj: False\n"
"*frame*primaryColorSetId: 3\n"
"*frame*secondaryColorSetId: 3\n"
"*menubar*useColorObj: False\n"
"*menubar*primaryColorSetId: 3\n"
"*menubar*secondaryColorSetId: 3\n"
"*toplevel*useColorObj: False\n"
"*toplevel*primaryColorSetId: 3\n"
"*toplevel*secondaryColorSetId: 3\n";
interactorManager->PutStringInResourceDatabase ((char*)oss.str().c_str());
// interactorManager->AddSecondaryLoopPostAction ((G4SecondaryLoopAction)G4OpenGLXmViewerSecondaryLoopPostAction);
shell = XtAppCreateShell ((String)fName.data(),(String)fName.data(),topLevelShellWidgetClass,XtDisplay(toplevel),NULL,0);
interactorManager->AddShell (shell);
dpy = XtDisplay (shell);
if (!dpy) {
fViewId = -1; // This flags an error.
G4cerr << "G4OpenGLXmViewer::GetXmConnection unable to connect to display."
<< G4endl;
return;
}
if (!glXQueryExtension (dpy, &errorBase, &eventBase)) {
fViewId = -1; // This flags an error.
G4cerr << "G4OpenGLXmViewer::GetXmConnection. X Server has no GLX extension."
<< G4endl;;
return;
}
}
void G4OpenGLXmViewer::CreateMainWindow () {
bgnd = XWhitePixelOfScreen (XtScreen(shell));
borcol = XBlackPixelOfScreen (XtScreen(shell));
XtVaSetValues (shell,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, &borcol,
XtNbackground, &bgnd,
XmNtitle, fName.data(),
NULL);
main_win = XtVaCreateManagedWidget ("main_win",
xmMainWindowWidgetClass,
shell,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
//*********Create a menu bar for the window********
style_str = XmStringCreateLocalized ((char*)"Style");
actions_str = XmStringCreateLocalized ((char*)"Actions");
misc_str = XmStringCreateLocalized ((char*)"Miscellany");
spec_str = XmStringCreateLocalized ((char*)"Special");
menubar = XmVaCreateSimpleMenuBar (main_win,
(char*)"menubar",
XmVaCASCADEBUTTON, style_str, 'S',
XmVaCASCADEBUTTON, actions_str, 'A',
XmVaCASCADEBUTTON, misc_str, 'M',
XmVaCASCADEBUTTON, spec_str, 'p',
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
XmStringFree (style_str);
XmStringFree (actions_str);
XmStringFree (misc_str);
XmStringFree (spec_str);
G4cout << "Created menubar" << G4endl;
//*********Create style pulldown menu on menubar*********
rep_str = XmStringCreateLocalized ((char*)"Representation");
draw_str = XmStringCreateLocalized ((char*)"Drawing");
bgnd_str = XmStringCreateLocalized ((char*)"Background color");
style_cascade = XmVaCreateSimplePulldownMenu
(menubar,
(char*)"style",
0,
NULL,
XmVaCASCADEBUTTON, rep_str, 'R',
XmVaCASCADEBUTTON, draw_str, 'D',
XmVaCASCADEBUTTON, bgnd_str, 'B',
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
XmStringFree (rep_str);
XmStringFree (draw_str);
XmStringFree (bgnd_str);
// G4cout << "Created Style pulldown menu" << G4endl;
//Add Representation pullright menu to style cascade...
polyhedron_str = XmStringCreateLocalized ((char*)"Polyhedron");
nurbs_str = XmStringCreateLocalized ((char*)"NURBS");
rep_style_pullright = XmVaCreateSimplePulldownMenu
(style_cascade,
(char*)"rep_style",
0,
rep_style_callback,
XmVaRADIOBUTTON, polyhedron_str, 'P', NULL, NULL,
XmVaRADIOBUTTON, nurbs_str, 'N', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
Widget special_widget;
G4ViewParameters::RepStyle style;
style = fVP.GetRepStyle();
if (style == G4ViewParameters::polyhedron) {
special_widget = XtNameToWidget(rep_style_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (style == G4ViewParameters::nurbs) {
special_widget = XtNameToWidget(rep_style_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
G4Exception("Invalid Representation style in G4OpenGLXmViewer::CreateContext");
}
XmStringFree (polyhedron_str);
XmStringFree (nurbs_str);
// G4cout << "Created Representation pulldown menu" << G4endl;
//Add Drawing pullright menu to style cascade...
wireframe_str = XmStringCreateLocalized ((char*)"Wireframe");
hlr_str = XmStringCreateLocalized ((char*)"Hidden line removal");
hsr_str = XmStringCreateLocalized ((char*)"Hidden surface removal");
hlhsr_str = XmStringCreateLocalized ((char*)"Hidden line and surface removal");
drawing_style_pullright = XmVaCreateSimplePulldownMenu
(style_cascade,
(char*)"drawing_style",
1,
drawing_style_callback,
XmVaRADIOBUTTON, wireframe_str, 'W', NULL, NULL,
XmVaRADIOBUTTON, hlr_str, 'L', NULL, NULL,
XmVaRADIOBUTTON, hsr_str, 'S', NULL, NULL,
XmVaRADIOBUTTON, hlhsr_str, 'H', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
G4ViewParameters::DrawingStyle d_style;
d_style = fVP.GetDrawingStyle();
if (d_style == G4ViewParameters::wireframe) {
special_widget = XtNameToWidget(drawing_style_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (d_style == G4ViewParameters::hlr) {
special_widget = XtNameToWidget(drawing_style_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (d_style == G4ViewParameters::hsr) {
special_widget = XtNameToWidget(drawing_style_pullright, "button_2");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (d_style == G4ViewParameters::hlhsr) {
special_widget = XtNameToWidget(drawing_style_pullright, "button_3");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
G4Exception("Invalid Drawing style in G4OpenGLXmViewer::CreateContext");
}
XmStringFree (wireframe_str);
XmStringFree (hlr_str);
XmStringFree (hsr_str);
XmStringFree (hlhsr_str);
// G4cout << "Created Drawing pullright menu" << G4endl;
//Add Drawing pullright menu to style cascade...
white_str = XmStringCreateLocalized ((char*)"White");
black_str = XmStringCreateLocalized ((char*)"Black");
background_color_pullright = XmVaCreateSimplePulldownMenu
(style_cascade,
(char*)"background_color",
2,
background_color_callback,
XmVaRADIOBUTTON, white_str, 'W', NULL, NULL,
XmVaRADIOBUTTON, black_str, 'B', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
if (background.GetRed() == 1. &&
background.GetGreen() == 1. &&
background.GetBlue() == 1.) {
special_widget = XtNameToWidget(background_color_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
special_widget = XtNameToWidget(background_color_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
}
XmStringFree (white_str);
XmStringFree (black_str);
// G4cout << "Created Background color pullright menu" << G4endl;
//*********Create actions pulldown menu on menubar*********
rot_str = XmStringCreateLocalized ((char*)"Rotation control panel");
pan_str = XmStringCreateLocalized ((char*)"Panning control panel");
set_str = XmStringCreateLocalized ((char*)"Set control panel limits");
actions_cascade = XmVaCreateSimplePulldownMenu
(menubar,
(char*)"actions",
1,
actions_callback,
XmVaPUSHBUTTON, rot_str, 'R', NULL, NULL,
XmVaPUSHBUTTON, pan_str, 'P', NULL, NULL,
XmVaPUSHBUTTON, set_str, 'S', NULL, NULL,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
XmStringFree (rot_str);
XmStringFree (pan_str);
XmStringFree (set_str);
G4cout << "Created Actions pulldown menu" << G4endl;
misc_str = XmStringCreateLocalized ((char*)"Miscellany control panel");
exit_str = XmStringCreateLocalized ((char*)"Exit to G4Vis>");
print_str = XmStringCreateLocalized ((char*)"Create .eps file");
//*********Create miscellany pulldown menu on menubar*********
misc_cascade = XmVaCreateSimplePulldownMenu
(menubar,
(char*)"miscellany",
2,
misc_callback,
XmVaPUSHBUTTON, misc_str, 'M', NULL, NULL,
XmVaPUSHBUTTON, exit_str, 'E', NULL, NULL,
XmVaPUSHBUTTON, print_str, 'P', NULL, NULL,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
XmStringFree (misc_str);
XmStringFree (exit_str);
XmStringFree (print_str);
G4cout << "Created Miscellany pulldown menu" << G4endl;
trans_str = XmStringCreateLocalized ((char*)"Transparency");
anti_str = XmStringCreateLocalized ((char*)"Antialiasing");
halo_str = XmStringCreateLocalized ((char*)"Haloing");
aux_edge_str = XmStringCreateLocalized ((char*)"Auxiliary edges");
//*********Create special pulldown menu on menubar*********
spec_cascade = XmVaCreateSimplePulldownMenu
(menubar,
(char*)"special",
3,
NULL,
XmVaCASCADEBUTTON, trans_str, 'T',
XmVaCASCADEBUTTON, anti_str, 'A',
XmVaCASCADEBUTTON, halo_str, 'H',
XmVaCASCADEBUTTON, aux_edge_str, 'E',
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
XmStringFree (trans_str);
XmStringFree (anti_str);
XmStringFree (halo_str);
XmStringFree (aux_edge_str);
// G4cout << "Created Special pulldown menu" << G4endl;
//Add Transparency pullright menu to special cascade...
off_str = XmStringCreateLocalized ((char*)"Off");
on_str = XmStringCreateLocalized ((char*)"On");
transparency_pullright = XmVaCreateSimplePulldownMenu
(spec_cascade,
(char*)"transparency",
0,
transparency_callback,
XmVaRADIOBUTTON, off_str, 'f', NULL, NULL,
XmVaRADIOBUTTON, on_str, 'n', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
if (transparency_enabled == false) {
special_widget = XtNameToWidget(transparency_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (transparency_enabled == true) {
special_widget = XtNameToWidget(transparency_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
G4Exception("transparency_enabled in G4OpenGLXmViewer is neither true nor false!!");
}
//Add antialias pullright menu to special cascade...
antialias_pullright = XmVaCreateSimplePulldownMenu
(spec_cascade,
(char*)"antialias",
1,
antialias_callback,
XmVaRADIOBUTTON, off_str, 'f', NULL, NULL,
XmVaRADIOBUTTON, on_str, 'n', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
if (antialiasing_enabled == false) {
special_widget = XtNameToWidget(antialias_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (antialiasing_enabled == true) {
special_widget = XtNameToWidget(antialias_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
G4Exception("antialiasing_enabled in G4OpenGLXmViewer is neither true nor false!!");
}
//Add Haloing pullright menu to special cascade...
haloing_pullright = XmVaCreateSimplePulldownMenu
(spec_cascade,
(char*)"haloing",
2,
haloing_callback,
XmVaRADIOBUTTON, off_str, 'f', NULL, NULL,
XmVaRADIOBUTTON, on_str, 'n', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
if (haloing_enabled == false) {
special_widget = XtNameToWidget(haloing_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else if (haloing_enabled == true) {
special_widget = XtNameToWidget(haloing_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
G4Exception("haloing_enabled in G4OpenGLXmViewer is neither true nor false!!");
}
//Add Aux_Edge pullright menu to special cascade...
aux_edge_pullright = XmVaCreateSimplePulldownMenu
(spec_cascade,
(char*)"aux_edge",
3,
aux_edge_callback,
XmVaRADIOBUTTON, off_str, 'f', NULL, NULL,
XmVaRADIOBUTTON, on_str, 'n', NULL, NULL,
XmNradioBehavior, True,
XmNradioAlwaysOne, True,
XmNuserData, this,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
if (!fVP.IsAuxEdgeVisible()) {
special_widget = XtNameToWidget(aux_edge_pullright, "button_0");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
} else {
special_widget = XtNameToWidget(aux_edge_pullright, "button_1");
if(special_widget) {
XtVaSetValues (special_widget, XmNset, True, NULL);
}
}
XtManageChild (menubar);
frame = XtVaCreateManagedWidget ((char*)"frame",
xmFrameWidgetClass, main_win,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
glxarea = XtVaCreateManagedWidget ((char*)"glxarea",
xmDrawingAreaWidgetClass,
frame,
XtNvisual, vi -> visual,
XtNdepth, vi -> depth,
XtNcolormap, cmap,
XtNborderColor, borcol,
XtNbackground, bgnd,
NULL);
XtAddCallback (glxarea,
XmNexposeCallback,
expose_callback,
this);
XtAddCallback (glxarea,
XmNresizeCallback,
resize_callback,
this);
XmMainWindowSetAreas (main_win, // main widget, children are specified
menubar, // widget to use as menu bar
NULL, // widget to use as command window
NULL, // widget for horizontal scroll bar
NULL, // widget for vertical scroll bar
frame // widget to be used for work window
);
XtRealizeWidget(shell);
// Once widget is realized (ie, associated with a created X window), we
// can bind the OpenGL rendering context to the window.
Dimension width, height;
XtVaGetValues (glxarea,XmNwidth,&width,XmNheight,&height,NULL);
WinSize_x = (G4int) width;
WinSize_y = (G4int) height;
win = XtWindow (glxarea);
glXMakeCurrent (dpy, win, cx);
}
G4OpenGLXmViewer::G4OpenGLXmViewer (G4OpenGLSceneHandler& scene):
G4VViewer (scene, -1),
G4OpenGLViewer (scene),
G4OpenGLXViewer (scene),
zoom_high (fVP.GetZoomFactor() * 10.0),
zoom_low (fVP.GetZoomFactor() / 10.0),
dolly_low (fVP.GetDolly() - 1000.0),
dolly_high (fVP.GetDolly() + 1000.0),
fov (0.0),
rot_sens_limit (90.),
pan_sens_limit (100.),
rot_sens (4.),
wob_sens (20.),
original_vp(fVP.GetViewpointDirection()),
frameNo (0),
fprotation_top (0),
fprotation_slider (0),
fppanning_top (0),
fppanning_slider (0),
fpzoom_slider (0),
fpdolly_slider (0),
fpsetting_top (0),
fpmiscellany_top (0),
fpprint_top (0)
{
WinSize_x = 100;
WinSize_y = 100;
GetXmConnection ();
if (fViewId < 0) return;
}
G4OpenGLXmViewer::~G4OpenGLXmViewer ()
{
XtDestroyWidget (shell);
win = 0; // ...to avoid XDestroyWindow in G4OpenGLXViewer base class
// because XtDestroyWidget has already destroyed it.
G4Xt::getInstance () ->RemoveShell (shell);
/******************************
if (fprotation_top) {
delete fprotation_top;
}
if (fppanning_top) {
delete fppanning_top;
}
if (fpsetting_top) {
delete fpsetting_top;
}
if (fpmiscellany_top) {
delete fpmiscellany_top;
}
******************************/
}
#endif