ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4OpenInventorXtExtendedViewer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4OpenInventorXtExtendedViewer.cc
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 //
27 //
28 /*
29  * jck 05 Feb 1997 - Initial Implementation
30  * jck 21 Apr 1997
31  * Mods for SoXtHepViewer
32  * gb : on Win32 use an SoXtExaminerViewer.
33  * gb 05 April 2004 : revisit to separate Windows things.
34  * gb 09 November 2004 : restore the escape button.
35  * gb 09 November 2004 : have a menu bar in the viewer shell.
36  * gb 09 November 2004 : have gl2ps file production.
37  * gb 14 November 2004 : inherit G4OpenInventorViewer.
38  */
39 
40 #ifdef G4VIS_BUILD_OIX_DRIVER
41 
42 // this :
44 
45 #include <Inventor/nodes/SoSelection.h>
46 
47 #include <Inventor/Xt/SoXt.h>
48 
49 //Replaces inclusion of SoXtExaminerViewer.h
50 #include <Inventor/Xt/viewers/SoXtFlyViewer.h>
51 
52 #include <X11/StringDefs.h>
53 #include <X11/Shell.h>
54 
55 #include <Xm/Xm.h>
56 #include <Xm/PushB.h>
57 #include <Xm/Form.h>
58 #include <Xm/CascadeB.h>
59 #include <Xm/RowColumn.h>
60 #include <Xm/Text.h>
61 
62 #include <cstdio>
63 
65 
66 #include "G4OpenInventor.hh"
69 #include "G4VInteractorManager.hh"
70 #include "G4VisManager.hh"
71 #include "G4AttCheck.hh"
72 
73 G4OpenInventorXtExtendedViewer::G4OpenInventorXtExtendedViewer(
74  G4OpenInventorSceneHandler& sceneHandler
75 ,const G4String& name)
76 :G4OpenInventorViewer (sceneHandler, name)
77 ,fShell(0)
78 ,fViewer(0)
79 ,fHelpForm(0)
80 ,fHelpText(0)
81 {
83  G4cout << "Window name: " << fName << G4endl;
84 }
85 
86 
87 void G4OpenInventorXtExtendedViewer::Initialise() {
88 
89  G4String wName = fName;
90 
91  Widget parent = (Widget)fInteractorManager->GetParentInteractor ();
92  // G4cout << "DEBUG G4OpenInventorXtExtendedViewer: parent = " << parent << G4endl;
93  int width = 600;
94  int height = 600;
95 
96  if(!parent) {
97  // Check if user has specified an X-Windows-type geometry string...
98  char s[32];
99 
100  G4String sgeometry = fVP.GetXGeometryString();
101  if(sgeometry.empty()) {
102  G4cout << "ERROR: Geometry string \""
103  << sgeometry
104  << "\" is empty. Using \"600x600\"."
105  << G4endl;
106  width = 600;
107  height = 600;
108  sprintf(s,"%dx%d",width,height);
109  sgeometry = s;
110  } else {
111  width = fVP.GetWindowSizeHintX();
112  height = fVP.GetWindowSizeHintX();
113  }
114 
115  //Create a shell window :
116  G4String shellName = wName;
117  shellName += "_shell";
118  Arg args[10];
119  XtSetArg(args[0],XtNgeometry,XtNewString(sgeometry.c_str()));
120  XtSetArg(args[1],XtNborderWidth,0);
121  XtSetArg(args[2],XtNtitle,XtNewString(wName.c_str()));
122  fShell = XtAppCreateShell(shellName.c_str(),"Inventor",
123  topLevelShellWidgetClass,
124  SoXt::getDisplay(),
125  args,3);
126 
127  // G4cout << "DEBUG CREATING THE VIEWER WITH CREATED SHELL = " << fShell << G4endl;
128  fViewer = new G4OpenInventorXtExaminerViewer(fShell, wName.c_str(), TRUE);
129  fViewer->addEscapeCallback(EscapeFromKeyboardCbk, (void *)this);
130 
131  // FWJ (viewpoints don't work with this!)
132  // fViewer->setAutoClipping((SbBool)0);
133 
134  //XtSetArg(args[0],XmNtopAttachment ,XmATTACH_FORM);
135  //XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
136  //XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
137  //XtSetArg(args[3],XmNbottomAttachment,XmATTACH_FORM);
138  //Widget form = XmCreateForm (fShell,(char*)"form",args,4);
139  //XtManageChild (form);
140 
141  Widget menuBar = fViewer->getMenuBar();
142 
143  //XtSetArg(args[0],XmNtopAttachment ,XmATTACH_FORM);
144  //XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
145  //XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
146  //Widget menuBar = XmCreateMenuBar (form,(char*)"menuBar",args,3);
147  //XtManageChild(menuBar);
148 
149  {Widget menu = fViewer->getMenu();
150  //{Widget menu = AddMenu(menuBar,"File","File");
151  AddButton(menu,"Write PS (gl2ps)",PostScriptCbk);
152  AddButton(menu, "Write PDF (gl2ps)", PDFCbk);
153  AddButton(menu,"Write PS (pixmap)",PixmapPostScriptCbk);
154  AddButton(menu,"Write IV",WriteInventorCbk);
155  AddButton(menu,"Escape",EscapeCbk);}
156 
157  {Widget menu = AddMenu(menuBar,"Etc","Etc");
158  AddButton(menu,"Erase detector",EraseDetectorCbk);
159  AddButton(menu,"Erase event",EraseEventCbk);
160  AddButton(menu,"Set solid",SetSolidCbk);
161 /* AddButton(menu,"Set (G4) wire frame",SetWireFrameCbk);*/
162  AddButton(menu,"Set (G4) reduced wire frame",SetReducedWireFrameCbk);
163  AddButton(menu,"Set (G4) full wire frame",SetFullWireFrameCbk);
164  AddButton(menu,"Visible mothers + invisible daughters",SetPreviewCbk);
165  AddButton(menu,"Visible mothers + visible daughters",SetPreviewAndFullCbk);
166  AddButton(menu,"Update scene",UpdateSceneCbk);
167  AddButton(menu,"Scene graph stats",SceneGraphStatisticsCbk);
168  }
169 
170  {Widget menu = AddMenu(menuBar,"Help","Help");
171  AddButton(menu,"Controls",HelpCbk);}
172 
173  //fViewer = new SoXtExaminerViewer(form,wName.c_str(),TRUE);
174 
175  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_WIDGET);
176  XtSetArg(args[1],XmNtopWidget ,menuBar);
177  XtSetArg(args[2],XmNleftAttachment ,XmATTACH_FORM);
178  XtSetArg(args[3],XmNrightAttachment ,XmATTACH_FORM);
179  XtSetArg(args[4],XmNbottomAttachment,XmATTACH_FORM);
180  XtSetValues(fViewer->getWidget(),args,5);
181 
182  fHelpForm = XmCreateFormDialog(fShell,(char*)"help",NULL,0);
183  XtSetArg(args[0],XmNleftAttachment ,XmATTACH_FORM);
184  XtSetArg(args[1],XmNrightAttachment ,XmATTACH_FORM);
185  XtSetArg(args[2],XmNbottomAttachment,XmATTACH_FORM);
186  Widget cancel = XmCreatePushButton(fHelpForm,(char*)"helpCancel",args,3);
187  XtAddCallback(cancel,XmNactivateCallback,HelpCancelCbk,(XtPointer)this);
188  XtManageChild(cancel);
189  XtSetArg(args[0],XmNtopAttachment ,XmATTACH_FORM);
190  XtSetArg(args[1],XmNleftAttachment ,XmATTACH_FORM);
191  XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
192  XtSetArg(args[3],XmNbottomAttachment,XmATTACH_WIDGET);
193  XtSetArg(args[4],XmNbottomWidget ,cancel);
194  fHelpText = XmCreateScrolledText(fHelpForm,(char*)"helpText",args,5);
195  XtManageChild(fHelpText);
196 
197  fInteractorManager->AddShell(fShell);
198 
199  } else {
200  char* str = fInteractorManager->GetCreationString();
201  if(str!=0) wName = str;
202  // G4cout << "DEBUG CREATING THE VIEWER WITH parent = " << parent << G4endl;
203  fViewer = new G4OpenInventorXtExaminerViewer(parent, wName.c_str(), TRUE);
204  }
205 
206  // Use our own SelectionCB for the Xt viewer to allow for abbreviated output
207  // when picking a trajectory
208  fSoSelection->removeSelectionCallback(G4OpenInventorViewer::SelectionCB,
209  this);
210 // fSoSelection->addSelectionCallback(SelectionCB, this);
211 
212  fViewer->setSize(SbVec2s(width,height));
213 
214  // Have a GL2PS render action :
215  const SbViewportRegion& vpRegion = fViewer->getViewportRegion();
216  fGL2PSAction = new SoGL2PSAction(vpRegion);
217  fViewer->setGLRenderAction(fGL2PSAction);
218 
219  // Else :
220  fViewer->setSceneGraph(fSoSelection);
221  fViewer->viewAll();
222  fViewer->saveHomePosition();
223  fViewer->setTitle(fName);
224  fViewer->show();
225  if(fShell) {
226  SoXt::show(fShell);
227  fInteractorManager->FlushAndWaitExecution ();
228  }
229  fInteractorManager->SetCreatedInteractor (fViewer -> getWidget());
230  // TJR added:
231  fViewer->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_ADD);
232 }
233 
234 G4OpenInventorXtExtendedViewer::~G4OpenInventorXtExtendedViewer () {
235  if(fShell) fInteractorManager->RemoveShell(fShell);
236  if(fViewer) {
237  fViewer->setSceneGraph(0);
238  //FIXME : SGI : the below "delete" block things.
239  //FIXME : CoinXt : the below "delete" crashe in ~SoXtRenderArea.
240  //FIXME : delete fViewer;
241  }
242  if(fShell) XtDestroyWidget(fShell);
243 }
244 
245 void G4OpenInventorXtExtendedViewer::FinishView () {
246  if(!fViewer) return;
247  fViewer->viewAll();
248  fViewer->saveHomePosition();
249 }
250 
251 void G4OpenInventorXtExtendedViewer::SetView () {
252  G4OpenInventorViewer::SetView ();
253  if(!fViewer) return;
254  // Background.
255  G4Colour b = fVP.GetBackgroundColour ();
256  fViewer->setBackgroundColor
257  (SbColor((float)b.GetRed(),(float)b.GetGreen(),(float)b.GetBlue()));
258 }
259 
260 
261 void G4OpenInventorXtExtendedViewer::ViewerRender () {
262  if(!fViewer) return;
263  fViewer->render();
264 }
265 
266 SoCamera* G4OpenInventorXtExtendedViewer::GetCamera () {
267  if(!fViewer) return 0;
268  return fViewer->getCamera();
269 }
270 
271 Widget G4OpenInventorXtExtendedViewer::AddMenu(
272  Widget aMenuBar
273 ,const G4String& aName
274 ,const G4String& aLabel
275 )
276 {
277  // Pulldown menu :
278  Widget menu = XmCreatePulldownMenu(aMenuBar,(char*)aName.c_str(),NULL,0);
279  // Cascade button :
280  Arg args[2];
281  XmString cps =
282  XmStringLtoRCreate((char*)aLabel.c_str(),(char*)XmSTRING_DEFAULT_CHARSET);
283  XtSetArg (args[0],XmNlabelString,cps);
284  XtSetArg (args[1],XmNsubMenuId,menu);
285  Widget widget = XmCreateCascadeButton(aMenuBar,(char*)aName.c_str(),args,2);
286  XmStringFree (cps);
287  XtManageChild(widget);
288  return menu;
289 }
290 void G4OpenInventorXtExtendedViewer::AddButton (
291  Widget aMenu
292 ,const G4String& aLabel
293 ,XtCallbackProc aCallback
294 )
295 {
296  Widget widget = XmCreatePushButton(aMenu,(char*)aLabel.c_str(),NULL,0);
297  XtManageChild(widget);
298  XtAddCallback(widget,XmNactivateCallback,aCallback,(XtPointer)this);
299 }
300 
301 void G4OpenInventorXtExtendedViewer::HelpCancelCbk(
302  Widget,XtPointer aData,XtPointer) {
303  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
304  XtUnmanageChild(This->fHelpForm);
305 }
306 
307 
311 
312 void G4OpenInventorXtExtendedViewer::EscapeCbk(
313  Widget,XtPointer aData,XtPointer) {
314  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
315  This->Escape();
316 }
317 
318 // Allow escape from X event loop via key
319 void G4OpenInventorXtExtendedViewer::EscapeFromKeyboardCbk(void* o) {
320  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)o;
321  This->Escape();
322 }
323 
324 void G4OpenInventorXtExtendedViewer::PostScriptCbk(
325  Widget,XtPointer aData,XtPointer) {
326  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
327  // FWJ Workaround: avoids empty 2nd page in file
328  SbBool superimpState =
329  This->fViewer->getSuperimpositionEnabled(This->fViewer->superimposition);
330  This->fViewer->setSuperimpositionEnabled(This->fViewer->superimposition,
331  FALSE);
332  This->WritePostScript();
333  if (superimpState)
334  This->fViewer->setSuperimpositionEnabled(This->fViewer->superimposition,
335  TRUE);
336 }
337 void G4OpenInventorXtExtendedViewer::PDFCbk(
338  Widget,XtPointer aData,XtPointer) {
339  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
340  // FWJ Workaround: avoids empty 2nd page in file
341  SbBool superimpState =
342  This->fViewer->getSuperimpositionEnabled(This->fViewer->superimposition);
343  This->fViewer->setSuperimpositionEnabled(This->fViewer->superimposition,
344  FALSE);
345  This->WritePDF();
346  if (superimpState)
347  This->fViewer->setSuperimpositionEnabled(This->fViewer->superimposition,
348  TRUE);
349 }
350 
351 void G4OpenInventorXtExtendedViewer::PixmapPostScriptCbk(
352  Widget,XtPointer aData,XtPointer) {
353  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
354  This->WritePixmapPostScript();
355 }
356 
357 void G4OpenInventorXtExtendedViewer::SceneGraphStatisticsCbk(
358  Widget,XtPointer aData,XtPointer) {
359  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
360  This->SceneGraphStatistics();
361 }
362 
363 void G4OpenInventorXtExtendedViewer::WriteInventorCbk(
364  Widget,XtPointer aData,XtPointer) {
365  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
366  This->WriteInventor();
367 }
368 
369 void G4OpenInventorXtExtendedViewer::EraseDetectorCbk(
370  Widget,XtPointer aData,XtPointer) {
371  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
372  This->EraseDetector();
373 }
374 
375 void G4OpenInventorXtExtendedViewer::EraseEventCbk(
376  Widget,XtPointer aData,XtPointer) {
377  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
378  This->EraseEvent();
379 }
380 
381 void G4OpenInventorXtExtendedViewer::SetSolidCbk(
382  Widget,XtPointer aData,XtPointer) {
383  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
384  This->SetSolid();
385 }
386 
387 void G4OpenInventorXtExtendedViewer::SetWireFrameCbk(
388  Widget,XtPointer aData,XtPointer) {
389  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
390  This->SetWireFrame();
391 }
392 
393 void G4OpenInventorXtExtendedViewer::SetReducedWireFrameCbk(
394  Widget,XtPointer aData,XtPointer) {
395  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
396  This->SetReducedWireFrame(true);
397 }
398 
399 void G4OpenInventorXtExtendedViewer::SetFullWireFrameCbk(
400  Widget,XtPointer aData,XtPointer) {
401  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
402  This->SetReducedWireFrame(false);
403 }
404 
405 void G4OpenInventorXtExtendedViewer::UpdateSceneCbk(
406  Widget,XtPointer aData,XtPointer) {
407  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
408  This->UpdateScene();
409 }
410 
411 void G4OpenInventorXtExtendedViewer::SetPreviewCbk(
412  Widget,XtPointer aData,XtPointer) {
413  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
414  This->SetPreview();
415 }
416 
417 void G4OpenInventorXtExtendedViewer::SetPreviewAndFullCbk(
418  Widget,XtPointer aData,XtPointer) {
419  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
420  This->SetPreviewAndFull();
421 }
422 
423 void G4OpenInventorXtExtendedViewer::HelpCbk(
424  Widget,XtPointer aData,XtPointer) {
425  G4OpenInventorXtExtendedViewer* This = (G4OpenInventorXtExtendedViewer*)aData;
426  XtManageChild(This->fHelpForm);
427  XmTextSetString(This->fHelpText,(char*)This->Help().c_str());
428 }
429 
430 #endif