ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4OpenInventorWinViewer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4OpenInventorWinViewer.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 : Mods for SoXtHepViewer
31  * gb : on Win32 use an SoXtExaminerViewer.
32  * gb : 05 April 2004 : creation.
33  * gb : 09 November 2004 : Pulldown menu with the escape menu item.
34  * gb 14 November 2004 : inherit G4OpenInventorViewer.
35  */
36 
37 #ifdef G4VIS_BUILD_OIWIN32_DRIVER
38 
39 // this :
41 
42 #include <Inventor/nodes/SoSelection.h>
43 
44 #include <Inventor/Win/SoWin.h>
45 #include <Inventor/Win/viewers/SoWinExaminerViewer.h>
46 
48 
49 #include "G4OpenInventor.hh"
51 #include "G4VInteractorManager.hh"
52 #include "G4VisManager.hh"
53 
54 #include <windowsx.h>
55 
56 // To have sizeChanged public :
57 class Geant4_SoWinExaminerViewer : public SoWinExaminerViewer {
58 public:
59  Geant4_SoWinExaminerViewer(HWND parent,const char* name,SbBool embed)
60  :SoWinExaminerViewer(parent,name,embed){}
61  virtual void sizeChanged(const SbVec2s & size){
62  SoWinExaminerViewer::sizeChanged(size);
63  }
64 };
65 
66 // File :
67 #define ID_FILE_POSTSCRIPT 1
68 #define ID_FILE_PIXMAP_POSTSCRIPT 2
69 #define ID_FILE_INVENTOR 3
70 #define ID_FILE_ESCAPE 4
71 // Etc :
72 #define ID_ETC_ERASE_DETECTOR 101
73 #define ID_ETC_ERASE_EVENT 102
74 #define ID_ETC_SET_SOLID 103
75 #define ID_ETC_SET_WIRE_FRAME 104
76 #define ID_ETC_SET_REDUCED_WIRE_FRAME 105
77 #define ID_ETC_SET_FULL_WIRE_FRAME 106
78 #define ID_ETC_SET_PREVIEW 107
79 #define ID_ETC_SET_PREVIEW_AND_FULL 108
80 #define ID_ETC_UPDATE_SCENE 109
81 #define ID_ETC_STATS 110
82 // Help :
83 #define ID_HELP_CONTROLS 201
84 
85 //static void SecondaryLoopPostAction ();
86 
87 static const char className[] = "G4OpenInventorShellWindow";
88 
89 G4OpenInventorWinViewer::G4OpenInventorWinViewer(
90  G4OpenInventorSceneHandler& sceneHandler
91 ,const G4String& name)
92 :G4OpenInventorViewer (sceneHandler, name)
93 ,fShell(0)
94 ,fViewer(0)
95 {
97  G4cout << "Window name: " << fName << G4endl;
98 }
99 
100 
101 void G4OpenInventorWinViewer::Initialise() {
102 
103  G4String wName = fName;
104 
105  int width = 600;
106  int height = 600;
107 
108  HWND parent = (HWND)fInteractorManager->GetParentInteractor ();
109  if(!parent) {
110  //Create a shell window :
111  G4String shellName = wName;
112  shellName += "_shell";
113  static SbBool done = FALSE;
114  if(done==FALSE) {
115  HBRUSH brush = (HBRUSH) GetSysColorBrush(COLOR_BTNFACE);
116  WNDCLASS wc;
117  wc.style = CS_HREDRAW | CS_VREDRAW;
118  wc.lpfnWndProc = (WNDPROC)WindowProc;
119  wc.cbClsExtra = 0;
120  wc.cbWndExtra = 0;
121  wc.hInstance = ::GetModuleHandle(0);
122  wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
123  wc.hCursor = ::LoadCursor(0, IDC_ARROW);
124  wc.hbrBackground = brush;
125  wc.lpszMenuName = className;
126  wc.lpszClassName = className;
127  ::RegisterClass(&wc);
128  done = TRUE;
129  }
130 
131  width = fVP.GetWindowSizeHintX();
132  height = fVP.GetWindowSizeHintX();
133 
134  HMENU menuBar = CreateMenu();
135 
136  {HMENU casc = CreatePopupMenu();
137  ::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"File");
138  ::AppendMenu(casc,MF_STRING,ID_FILE_POSTSCRIPT,"PS (gl2ps)");
139  ::AppendMenu(casc,MF_STRING,ID_FILE_PIXMAP_POSTSCRIPT,"PS (pixmap)");
140  ::AppendMenu(casc,MF_STRING,ID_FILE_INVENTOR,"IV");
141  ::AppendMenu(casc,MF_STRING,ID_FILE_ESCAPE,"Escape");}
142 
143  {HMENU casc = CreatePopupMenu();
144  ::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"Etc");
145  ::AppendMenu(casc,MF_STRING,ID_ETC_ERASE_DETECTOR,"Erase detector");
146  ::AppendMenu(casc,MF_STRING,ID_ETC_ERASE_EVENT,"Erase event");
147  ::AppendMenu(casc,MF_STRING,ID_ETC_SET_SOLID,"Set solid");
148  //::AppendMenu(casc,MF_STRING,ID_ETC_SET_WIRE_FRAME,"Set (G4) wire frame");
149  ::AppendMenu(casc,MF_STRING,ID_ETC_SET_REDUCED_WIRE_FRAME,
150  "Set (G4) reduced wire frame");
151  ::AppendMenu(casc,MF_STRING,ID_ETC_SET_FULL_WIRE_FRAME,
152  "Set (G4) full wire frame");
153  ::AppendMenu(casc,MF_STRING,ID_ETC_SET_PREVIEW,
154  "Visible mothers + invisible daughters");
155  ::AppendMenu(casc,MF_STRING,ID_ETC_SET_PREVIEW_AND_FULL,
156  "Visible mothers + visible daughters");
157  ::AppendMenu(casc,MF_STRING,ID_ETC_UPDATE_SCENE,"Update scene");
158  ::AppendMenu(casc,MF_STRING,ID_ETC_STATS,"Scene graph stats");}
159 
160  {HMENU casc = CreatePopupMenu();
161  ::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"Help");
162  ::AppendMenu(casc,MF_STRING,ID_HELP_CONTROLS,"Controls");}
163 
164  fShell = ::CreateWindow(className, shellName.c_str(),
165  WS_OVERLAPPEDWINDOW |
166  WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
167  CW_USEDEFAULT, CW_USEDEFAULT,
168  width,height,
169  0,menuBar,::GetModuleHandle(0),0);
170  // Retreive window and client sizez :
171  RECT wrect,crect;
172  GetWindowRect((HWND)fShell,&wrect);
173  GetClientRect((HWND)fShell,&crect);
174  int ww = wrect.right-wrect.left;
175  int wh = wrect.bottom-wrect.top;
176  int cw = crect.right-crect.left;
177  int ch = crect.bottom-crect.top;
178  // Compell client rect to be width height :
179  MoveWindow((HWND)fShell,wrect.left,wrect.top,width+ww-cw,height+wh-ch,TRUE);
180  ::SetWindowLongPtr((HWND)fShell,GWLP_USERDATA,LONG(this));
181  ::SetWindowText((HWND)fShell,shellName.c_str());
182  parent = fShell;
183  fInteractorManager->AddShell(fShell);
184  } else {
185  char* str = fInteractorManager->GetCreationString();
186  if(str!=0) wName = str;
187  }
188  fViewer = new Geant4_SoWinExaminerViewer(parent,wName.c_str(),TRUE);
189 
190  // Have a GL2PS render action :
191  const SbViewportRegion& vpRegion = fViewer->getViewportRegion();
192  fGL2PSAction = new SoGL2PSAction(vpRegion);
193  fViewer->setGLRenderAction(fGL2PSAction);
194 
195  fViewer->setSize(SbVec2s(width,height));
196  fViewer->setSceneGraph(fSoSelection);
197  fViewer->viewAll();
198  fViewer->saveHomePosition();
199  fViewer->setTitle(fName);
200  fViewer->show();
201  if(fShell) {
202  SoWin::show(fShell);
203  fInteractorManager->FlushAndWaitExecution ();
204  }
205  fInteractorManager->SetCreatedInteractor (fViewer -> getWidget());
206  fViewer->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_ADD);
207 }
208 
209 G4OpenInventorWinViewer::~G4OpenInventorWinViewer () {
210  if(fShell) fInteractorManager->RemoveShell(fShell);
211  if(fViewer) {
212  fViewer->setSceneGraph(0);
213  delete fViewer;
214  }
215  if(fShell) {
216  ::SetWindowLongPtr((HWND)fShell,GWLP_USERDATA,LONG(0));
217  ::DestroyWindow((HWND)fShell);
218  }
219 }
220 
221 void G4OpenInventorWinViewer::FinishView () {
222  if(!fViewer) return;
223  fViewer->viewAll();
224  fViewer->saveHomePosition();
225 }
226 
227 void G4OpenInventorWinViewer::SetView () {
228  G4OpenInventorViewer::SetView ();
229  if(!fViewer) return;
230  // Background.
231  G4Colour b = fVP.GetBackgroundColour ();
232  fViewer->setBackgroundColor
233  (SbColor((float)b.GetRed(),(float)b.GetGreen(),(float)b.GetBlue()));
234 }
235 void G4OpenInventorWinViewer::ViewerRender () {
236  if(!fViewer) return;
237  fViewer->render();
238 }
239 
240 SoCamera* G4OpenInventorWinViewer::GetCamera () {
241  if(!fViewer) return 0;
242  return fViewer->getCamera();
243 }
244 
245 
247 LRESULT CALLBACK G4OpenInventorWinViewer::WindowProc (
248  HWND aWindow
249 ,UINT aMessage
250 ,WPARAM aWParam
251 ,LPARAM aLParam
252 )
254 // Below treatment of WM_SIZE, WM_SETFOCUS not necessary
255 // with TGS, but needed with SoFree. WM_DESTROY needed for
256 // 'main top level window' so that 'Close window' induces
257 // the end of the task.
259 {
260  switch (aMessage) {
261  case WM_SIZE:{ // Assume one child window !
262  int width = LOWORD(aLParam);
263  int height = HIWORD(aLParam);
264  //printf("debug : G4SoWindow : WMS_SIZE : %d %d\n",width,height);
265  G4OpenInventorWinViewer* This =
266  (G4OpenInventorWinViewer*)::GetWindowLongPtr(aWindow,GWLP_USERDATA);
267  if(This && This->fViewer) {
268  This->fViewer->sizeChanged(SbVec2s(width,height));
269  }
270  }return 0;
271  case WM_SETFOCUS:{ // Assume one child window !
272  HWND hwnd = ::GetFirstChild(aWindow);
273  if(hwnd!=0) ::SetFocus(hwnd);
274  }return 0;
275  case WM_DESTROY:{
276  //G4OpenInventorWinViewer* This =
277  // (G4OpenInventorWinViewer*)::GetWindowLongPtr(aWindow,GWLP_USERDATA);
278  //::PostQuitMessage(0);
279  }return 0;
280  case WM_COMMAND:{
281  G4OpenInventorWinViewer* This =
282  (G4OpenInventorWinViewer*)::GetWindowLongPtr(aWindow,GWLP_USERDATA);
283  if(This) {
284  if(aLParam==0) { //From menu.
285  // File :
286  if(aWParam==ID_FILE_POSTSCRIPT) {
287  This->WritePostScript();
288  } else if(aWParam==ID_FILE_PIXMAP_POSTSCRIPT) {
289  This->WritePixmapPostScript();
290  } else if(aWParam==ID_FILE_INVENTOR) {
291  This->WriteInventor();
292  } else if(aWParam==ID_FILE_ESCAPE) {
293  This->Escape();
294  // Etc :
295  } else if(aWParam==ID_ETC_ERASE_DETECTOR) {
296  This->EraseDetector();
297  } else if(aWParam==ID_ETC_ERASE_EVENT) {
298  This->EraseEvent();
299  } else if(aWParam==ID_ETC_SET_SOLID) {
300  This->SetSolid();
301  } else if(aWParam==ID_ETC_SET_WIRE_FRAME) {
302  This->SetWireFrame();
303  } else if(aWParam==ID_ETC_SET_REDUCED_WIRE_FRAME) {
304  This->SetReducedWireFrame(true);
305  } else if(aWParam==ID_ETC_SET_FULL_WIRE_FRAME) {
306  This->SetReducedWireFrame(false);
307  } else if(aWParam==ID_ETC_SET_PREVIEW) {
308  This->SetPreview();
309  } else if(aWParam==ID_ETC_SET_PREVIEW_AND_FULL) {
310  This->SetPreviewAndFull();
311  } else if(aWParam==ID_ETC_UPDATE_SCENE) {
312  This->UpdateScene();
313  } else if(aWParam==ID_ETC_STATS) {
314  This->SceneGraphStatistics();
315  // Help :
316  } else if(aWParam==ID_HELP_CONTROLS) {
317  G4cout << This->Help() << G4endl;
318  }
319  }
320  }
321  }return 0;
322  default:
323  return (::DefWindowProc(aWindow,aMessage,aWParam,aLParam));
324  }
325 }
326 
327 #endif