Files
geant4/source/visualization/OpenInventor/src/G4OpenInventorWinViewer.cc
T
2016-06-30 14:12:05 +02:00

329 lines
11 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: G4OpenInventorWinViewer.cc 97241 2016-05-30 12:06:54Z gcosmo $
//
/*
* jck : 05 Feb 1997 : Initial Implementation
* jck : 21 Apr 1997 : Mods for SoXtHepViewer
* gb : on Win32 use an SoXtExaminerViewer.
* gb : 05 April 2004 : creation.
* gb : 09 November 2004 : Pulldown menu with the escape menu item.
* gb 14 November 2004 : inherit G4OpenInventorViewer.
*/
#ifdef G4VIS_BUILD_OIWIN32_DRIVER
// this :
#include "G4OpenInventorWinViewer.hh"
#include <Inventor/nodes/SoSelection.h>
#include <Inventor/Win/SoWin.h>
#include <Inventor/Win/viewers/SoWinExaminerViewer.h>
#include "HEPVis/actions/SoGL2PSAction.h"
#include "G4OpenInventor.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4VInteractorManager.hh"
#include "G4VisManager.hh"
#include <windowsx.h>
// To have sizeChanged public :
class Geant4_SoWinExaminerViewer : public SoWinExaminerViewer {
public:
Geant4_SoWinExaminerViewer(HWND parent,const char* name,SbBool embed)
:SoWinExaminerViewer(parent,name,embed){}
virtual void sizeChanged(const SbVec2s & size){
SoWinExaminerViewer::sizeChanged(size);
}
};
// File :
#define ID_FILE_POSTSCRIPT 1
#define ID_FILE_PIXMAP_POSTSCRIPT 2
#define ID_FILE_INVENTOR 3
#define ID_FILE_ESCAPE 4
// Etc :
#define ID_ETC_ERASE_DETECTOR 101
#define ID_ETC_ERASE_EVENT 102
#define ID_ETC_SET_SOLID 103
#define ID_ETC_SET_WIRE_FRAME 104
#define ID_ETC_SET_REDUCED_WIRE_FRAME 105
#define ID_ETC_SET_FULL_WIRE_FRAME 106
#define ID_ETC_SET_PREVIEW 107
#define ID_ETC_SET_PREVIEW_AND_FULL 108
#define ID_ETC_UPDATE_SCENE 109
#define ID_ETC_STATS 110
// Help :
#define ID_HELP_CONTROLS 201
//static void SecondaryLoopPostAction ();
static const char className[] = "G4OpenInventorShellWindow";
G4OpenInventorWinViewer::G4OpenInventorWinViewer(
G4OpenInventorSceneHandler& sceneHandler
,const G4String& name)
:G4OpenInventorViewer (sceneHandler, name)
,fShell(0)
,fViewer(0)
{
if (G4VisManager::GetVerbosity() >= G4VisManager::confirmations)
G4cout << "Window name: " << fName << G4endl;
}
void G4OpenInventorWinViewer::Initialise() {
G4String wName = fName;
int width = 600;
int height = 600;
HWND parent = (HWND)fInteractorManager->GetParentInteractor ();
if(!parent) {
//Create a shell window :
G4String shellName = wName;
shellName += "_shell";
static SbBool done = FALSE;
if(done==FALSE) {
HBRUSH brush = (HBRUSH) GetSysColorBrush(COLOR_BTNFACE);
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ::GetModuleHandle(0);
wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = brush;
wc.lpszMenuName = className;
wc.lpszClassName = className;
::RegisterClass(&wc);
done = TRUE;
}
width = fVP.GetWindowSizeHintX();
height = fVP.GetWindowSizeHintX();
HMENU menuBar = CreateMenu();
{HMENU casc = CreatePopupMenu();
::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"File");
::AppendMenu(casc,MF_STRING,ID_FILE_POSTSCRIPT,"PS (gl2ps)");
::AppendMenu(casc,MF_STRING,ID_FILE_PIXMAP_POSTSCRIPT,"PS (pixmap)");
::AppendMenu(casc,MF_STRING,ID_FILE_INVENTOR,"IV");
::AppendMenu(casc,MF_STRING,ID_FILE_ESCAPE,"Escape");}
{HMENU casc = CreatePopupMenu();
::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"Etc");
::AppendMenu(casc,MF_STRING,ID_ETC_ERASE_DETECTOR,"Erase detector");
::AppendMenu(casc,MF_STRING,ID_ETC_ERASE_EVENT,"Erase event");
::AppendMenu(casc,MF_STRING,ID_ETC_SET_SOLID,"Set solid");
//::AppendMenu(casc,MF_STRING,ID_ETC_SET_WIRE_FRAME,"Set (G4) wire frame");
::AppendMenu(casc,MF_STRING,ID_ETC_SET_REDUCED_WIRE_FRAME,
"Set (G4) reduced wire frame");
::AppendMenu(casc,MF_STRING,ID_ETC_SET_FULL_WIRE_FRAME,
"Set (G4) full wire frame");
::AppendMenu(casc,MF_STRING,ID_ETC_SET_PREVIEW,
"Visible mothers + invisible daughters");
::AppendMenu(casc,MF_STRING,ID_ETC_SET_PREVIEW_AND_FULL,
"Visible mothers + visible daughters");
::AppendMenu(casc,MF_STRING,ID_ETC_UPDATE_SCENE,"Update scene");
::AppendMenu(casc,MF_STRING,ID_ETC_STATS,"Scene graph stats");}
{HMENU casc = CreatePopupMenu();
::AppendMenu(menuBar,MF_POPUP,(UINT)casc,"Help");
::AppendMenu(casc,MF_STRING,ID_HELP_CONTROLS,"Controls");}
fShell = ::CreateWindow(className, shellName.c_str(),
WS_OVERLAPPEDWINDOW |
WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
width,height,
0,menuBar,::GetModuleHandle(0),0);
// Retreive window and client sizez :
RECT wrect,crect;
GetWindowRect((HWND)fShell,&wrect);
GetClientRect((HWND)fShell,&crect);
int ww = wrect.right-wrect.left;
int wh = wrect.bottom-wrect.top;
int cw = crect.right-crect.left;
int ch = crect.bottom-crect.top;
// Compell client rect to be width height :
MoveWindow((HWND)fShell,wrect.left,wrect.top,width+ww-cw,height+wh-ch,TRUE);
::SetWindowLongPtr((HWND)fShell,GWLP_USERDATA,LONG(this));
::SetWindowText((HWND)fShell,shellName.c_str());
parent = fShell;
fInteractorManager->AddShell(fShell);
} else {
char* str = fInteractorManager->GetCreationString();
if(str!=0) wName = str;
}
fViewer = new Geant4_SoWinExaminerViewer(parent,wName.c_str(),TRUE);
// Have a GL2PS render action :
const SbViewportRegion& vpRegion = fViewer->getViewportRegion();
fGL2PSAction = new SoGL2PSAction(vpRegion);
fViewer->setGLRenderAction(fGL2PSAction);
fViewer->setSize(SbVec2s(width,height));
fViewer->setSceneGraph(fSoSelection);
fViewer->viewAll();
fViewer->saveHomePosition();
fViewer->setTitle(fName);
fViewer->show();
if(fShell) {
SoWin::show(fShell);
fInteractorManager->FlushAndWaitExecution ();
}
fInteractorManager->SetCreatedInteractor (fViewer -> getWidget());
fViewer->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_ADD);
}
G4OpenInventorWinViewer::~G4OpenInventorWinViewer () {
if(fShell) fInteractorManager->RemoveShell(fShell);
if(fViewer) {
fViewer->setSceneGraph(0);
delete fViewer;
}
if(fShell) {
::SetWindowLongPtr((HWND)fShell,GWLP_USERDATA,LONG(0));
::DestroyWindow((HWND)fShell);
}
}
void G4OpenInventorWinViewer::FinishView () {
if(!fViewer) return;
fViewer->viewAll();
fViewer->saveHomePosition();
}
void G4OpenInventorWinViewer::SetView () {
G4OpenInventorViewer::SetView ();
if(!fViewer) return;
// Background.
G4Colour b = fVP.GetBackgroundColour ();
fViewer->setBackgroundColor
(SbColor((float)b.GetRed(),(float)b.GetGreen(),(float)b.GetBlue()));
}
void G4OpenInventorWinViewer::ViewerRender () {
if(!fViewer) return;
fViewer->render();
}
SoCamera* G4OpenInventorWinViewer::GetCamera () {
if(!fViewer) return 0;
return fViewer->getCamera();
}
//////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK G4OpenInventorWinViewer::WindowProc (
HWND aWindow
,UINT aMessage
,WPARAM aWParam
,LPARAM aLParam
)
//////////////////////////////////////////////////////////////////////////////
// Below treatment of WM_SIZE, WM_SETFOCUS not necessary
// with TGS, but needed with SoFree. WM_DESTROY needed for
// 'main top level window' so that 'Close window' induces
// the end of the task.
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
switch (aMessage) {
case WM_SIZE:{ // Assume one child window !
int width = LOWORD(aLParam);
int height = HIWORD(aLParam);
//printf("debug : G4SoWindow : WMS_SIZE : %d %d\n",width,height);
G4OpenInventorWinViewer* This =
(G4OpenInventorWinViewer*)::GetWindowLongPtr(aWindow,GWLP_USERDATA);
if(This && This->fViewer) {
This->fViewer->sizeChanged(SbVec2s(width,height));
}
}return 0;
case WM_SETFOCUS:{ // Assume one child window !
HWND hwnd = ::GetFirstChild(aWindow);
if(hwnd!=0) ::SetFocus(hwnd);
}return 0;
case WM_DESTROY:{
//G4OpenInventorWinViewer* This =
// (G4OpenInventorWinViewer*)::GetWindowLongPtr(aWindow,GWLP_USERDATA);
//::PostQuitMessage(0);
}return 0;
case WM_COMMAND:{
G4OpenInventorWinViewer* This =
(G4OpenInventorWinViewer*)::GetWindowLongPtr(aWindow,GWLP_USERDATA);
if(This) {
if(aLParam==0) { //From menu.
// File :
if(aWParam==ID_FILE_POSTSCRIPT) {
This->WritePostScript();
} else if(aWParam==ID_FILE_PIXMAP_POSTSCRIPT) {
This->WritePixmapPostScript();
} else if(aWParam==ID_FILE_INVENTOR) {
This->WriteInventor();
} else if(aWParam==ID_FILE_ESCAPE) {
This->Escape();
// Etc :
} else if(aWParam==ID_ETC_ERASE_DETECTOR) {
This->EraseDetector();
} else if(aWParam==ID_ETC_ERASE_EVENT) {
This->EraseEvent();
} else if(aWParam==ID_ETC_SET_SOLID) {
This->SetSolid();
} else if(aWParam==ID_ETC_SET_WIRE_FRAME) {
This->SetWireFrame();
} else if(aWParam==ID_ETC_SET_REDUCED_WIRE_FRAME) {
This->SetReducedWireFrame(true);
} else if(aWParam==ID_ETC_SET_FULL_WIRE_FRAME) {
This->SetReducedWireFrame(false);
} else if(aWParam==ID_ETC_SET_PREVIEW) {
This->SetPreview();
} else if(aWParam==ID_ETC_SET_PREVIEW_AND_FULL) {
This->SetPreviewAndFull();
} else if(aWParam==ID_ETC_UPDATE_SCENE) {
This->UpdateScene();
} else if(aWParam==ID_ETC_STATS) {
This->SceneGraphStatistics();
// Help :
} else if(aWParam==ID_HELP_CONTROLS) {
G4cout << This->Help() << G4endl;
}
}
}
}return 0;
default:
return (::DefWindowProc(aWindow,aMessage,aWParam,aLParam));
}
}
#endif