Import Geant4 6.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 10:56:29 +02:00
parent 1d812b78b1
commit e083ffb441
1415 changed files with 111223 additions and 21207 deletions
@@ -21,23 +21,22 @@
// ********************************************************************
//
//
// $Id: G4OpenInventor.cc,v 1.9 2003/10/29 10:02:06 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4OpenInventor.cc,v 1.11 2004/06/14 09:27:38 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
#ifdef G4VIS_BUILD_OI_DRIVER
//#include <HEPVis/SoDB.h>
#include <HEPVis/nodes/SoG4Box.h>
#include <HEPVis/nodes/SoG4Tubs.h>
#include <HEPVis/nodes/SoG4Cons.h>
#include <HEPVis/nodes/SoG4Trd.h>
#include <HEPVis/nodes/SoG4Trap.h>
#include <HEPVis/nodekits/SoDetectorTreeKit.h>
// this :
#include "G4OpenInventor.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4OpenInventorViewer.hh"
#include "HEPVis/nodes/SoBox.h"
#include "HEPVis/nodes/SoTubs.h"
#include "HEPVis/nodes/SoCons.h"
#include "HEPVis/nodes/SoTrd.h"
#include "HEPVis/nodes/SoTrap.h"
#include "HEPVis/nodekits/SoDetectorTreeKit.h"
#include "G4OpenInventorSceneHandler.hh"
G4OpenInventor::G4OpenInventor (
const G4String name
@@ -64,23 +63,13 @@ G4VSceneHandler* G4OpenInventor::CreateSceneHandler (const G4String& name) {
return p;
}
G4VViewer* G4OpenInventor::CreateViewer (G4VSceneHandler& scene, const G4String& name)
void G4OpenInventor::InitNodes()
{
G4OpenInventorSceneHandler* pScene = (G4OpenInventorSceneHandler*)&scene;
G4OpenInventorViewer* pView = new G4OpenInventorViewer (*pScene, name);
return pView;
}
void G4OpenInventor::InitHEPVis()
{
// The below is too much for most loaders :
// HEPVis_SoDB::init();
SoG4Box::initClass();
SoG4Tubs::initClass();
SoG4Cons::initClass();
SoG4Trd::initClass();
SoG4Trap::initClass();
SoBox::initClass();
SoTubs::initClass();
SoCons::initClass();
SoTrd::initClass();
SoTrap::initClass();
SoDetectorTreeKit::initClass();
}
@@ -21,14 +21,17 @@
// ********************************************************************
//
//
// $Id: G4OpenInventorSceneHandler.cc,v 1.15 2003/10/29 10:01:36 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4OpenInventorSceneHandler.cc,v 1.17 2004/06/14 09:27:38 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
//
// Jeff Kallenbach 01 Aug 1996
// OpenInventor stored scene - creates OpenInventor display lists.
#ifdef G4VIS_BUILD_OI_DRIVER
// this :
#include "G4OpenInventorSceneHandler.hh"
#include <Inventor/SoPath.h>
#include <Inventor/SoNodeKitPath.h>
#include <Inventor/nodes/SoCoordinate3.h>
@@ -54,18 +57,16 @@
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoResetTransform.h>
#include <HEPVis/nodes/SoG4Box.h>
#include <HEPVis/nodes/SoG4Tubs.h>
#include <HEPVis/nodes/SoG4Cons.h>
#include <HEPVis/nodes/SoG4Trd.h>
#include <HEPVis/nodes/SoG4Trap.h>
#include <HEPVis/nodekits/SoDetectorTreeKit.h>
#include "HEPVis/nodes/SoBox.h"
#include "HEPVis/nodes/SoTubs.h"
#include "HEPVis/nodes/SoCons.h"
#include "HEPVis/nodes/SoTrd.h"
#include "HEPVis/nodes/SoTrap.h"
#include "HEPVis/nodekits/SoDetectorTreeKit.h"
#include "G4Scene.hh"
#include "G4NURBS.hh"
#include "G4OpenInventor.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4OpenInventorViewer.hh"
#include "G4OpenInventorTransform3D.hh"
#include "G4ThreeVector.hh"
#include "G4Point3D.hh"
@@ -88,7 +89,7 @@
#include "G4Material.hh"
#include "G4VisAttributes.hh"
typedef SoDetectorTreeKit SoG4DetectorTreeKit;
typedef SoDetectorTreeKit SoDetectorTreeKit;
G4Point3D translation;
G4OpenInventorSceneHandler::G4OpenInventorSceneHandler (G4OpenInventor& system,
@@ -548,7 +549,7 @@ void G4OpenInventorSceneHandler::AddThis (const G4Box & Box) {
}
void G4OpenInventorSceneHandler::AddThis (const G4Tubs & Tubs) {
if(currentSeparator==0) return;
SoG4Tubs *g4Tubs = new SoG4Tubs();
SoTubs *g4Tubs = new SoTubs();
g4Tubs->pRMin = Tubs.GetRMin();
g4Tubs->pRMax = Tubs.GetRMax();
g4Tubs->pDz = Tubs.GetDz();
@@ -558,7 +559,7 @@ void G4OpenInventorSceneHandler::AddThis (const G4Tubs & Tubs) {
}
void G4OpenInventorSceneHandler::AddThis (const G4Cons &cons) {
if(currentSeparator==0) return;
SoG4Cons *g4Cons = new SoG4Cons();
SoCons *g4Cons = new SoCons();
g4Cons->fRmin1 = cons.GetRmin1();
g4Cons->fRmin2 = cons.GetRmin2();
g4Cons->fRmax1 = cons.GetRmax1();
@@ -572,7 +573,7 @@ void G4OpenInventorSceneHandler::AddThis (const G4Cons &cons) {
void G4OpenInventorSceneHandler::AddThis (const G4Trap &trap) {
if(currentSeparator==0) return;
G4ThreeVector SymAxis=trap.GetSymAxis();
SoG4Trap *g4Trap = new SoG4Trap();
SoTrap *g4Trap = new SoTrap();
g4Trap->pDz = trap.GetZHalfLength();
g4Trap->pPhi = atan2(SymAxis(kYAxis),SymAxis(kXAxis));
g4Trap->pTheta = acos(SymAxis(kZAxis));
@@ -587,7 +588,7 @@ void G4OpenInventorSceneHandler::AddThis (const G4Trap &trap) {
void G4OpenInventorSceneHandler::AddThis (const G4Trd &trd) {
if(currentSeparator==0) return;
SoG4Trd *g4Trd = new SoG4Trd();
SoTrd *g4Trd = new SoTrd();
g4Trd->fDx1 = trd.GetXHalfLength1();
g4Trd->fDx2 = trd.GetXHalfLength2();
g4Trd->fDy1 = trd.GetYHalfLength1();
@@ -650,7 +651,7 @@ void G4OpenInventorSceneHandler::PreAddThis
//
// Make the detector tree kit:
//
SoG4DetectorTreeKit* g4DetectorTreeKit = new SoG4DetectorTreeKit();
SoDetectorTreeKit* g4DetectorTreeKit = new SoDetectorTreeKit();
SoSeparator* previewSeparator =
(SoSeparator*) g4DetectorTreeKit->getPart("previewSeparator",TRUE);
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4OpenInventorTransform3D.cc,v 1.4 2001/07/11 10:09:01 gunter Exp $
// GEANT4 tag $Name: geant4-05-02-patch-01 $
// $Id: G4OpenInventorTransform3D.cc,v 1.5 2004/04/08 09:41:11 gbarrand Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
//
// jck 17 Dec 1996
@@ -31,10 +31,11 @@
#ifdef G4VIS_BUILD_OI_DRIVER
#include <Inventor/fields/SoSFMatrix.h>
// this :
#include "G4OpenInventorTransform3D.hh"
#include <Inventor/fields/SoSFMatrix.h>
G4OpenInventorTransform3D::G4OpenInventorTransform3D (const G4Transform3D &t)
: G4Transform3D (t) {
m[0] = xx;
@@ -21,36 +21,42 @@
// ********************************************************************
//
//
// $Id: G4OpenInventorWin32.cc,v 1.5 2001/07/11 10:09:01 gunter Exp $
// GEANT4 tag $Name: geant4-05-02-patch-01 $
// $Id: G4OpenInventorWin.cc,v 1.4 2004/04/08 10:49:57 gbarrand Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// OpenInventor graphics system factory.
#ifdef G4VIS_BUILD_OIWIN32_DRIVER
#include <Inventor/Xt/SoXt.h>
// this :
#include "G4OpenInventorWin.hh"
#include "G4OpenInventorWin32.hh"
#include <Inventor/Win/SoWin.h>
#include "G4OpenInventorSceneHandler.hh"
#include "G4OpenInventorViewer.hh"
#include "G4OpenInventorWinViewer.hh"
#include "G4Win32.hh"
G4OpenInventorWin32::G4OpenInventorWin32 ()
:G4OpenInventor("OpenInventorWin32","OIWIN32",G4VGraphicsSystem::threeD)
G4OpenInventorWin::G4OpenInventorWin ()
:G4OpenInventor("OpenInventorWin","OIWin32",G4VGraphicsSystem::threeD)
{
SetInteractorManager (G4Win32::getInstance());
GetInteractorManager () -> RemoveDispatcher((G4DispatchFunction)G4Win32::dispatchWin32Event);
GetInteractorManager () -> AddDispatcher ((G4DispatchFunction)SoXt::dispatchEvent);
GetInteractorManager () -> AddDispatcher((G4DispatchFunction)SoWin::dispatchEvent);
Widget toplevel = (Widget)GetInteractorManager()->GetMainInteractor();
HWND toplevel = (HWND)GetInteractorManager()->GetMainInteractor();
SoXt::init(toplevel);
SoWin::init(toplevel);
InitHEPVis();
InitNodes();
}
G4OpenInventorWin::~G4OpenInventorWin () {}
G4VViewer* G4OpenInventorWin::CreateViewer (G4VSceneHandler& scene, const G4String& name)
{
G4OpenInventorSceneHandler* pScene = (G4OpenInventorSceneHandler*)&scene;
return new G4OpenInventorWinViewer (*pScene, name);
}
G4OpenInventorWin32::~G4OpenInventorWin32 () {}
#endif
@@ -0,0 +1,271 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4OpenInventorWinViewer.cc,v 1.2 2004/04/08 10:49:57 gbarrand Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*
* jck 05 Feb 1997 - Initial Implementation
* jck 21 Apr 1997
* Mods for SoXtHepViewer
* gb : on Win32 use an SoXtExaminerViewer.
* gb 05 April 2004 : creation.
*/
#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 "G4OpenInventor.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4VInteractorManager.hh"
#include <windowsx.h>
//
// Global variables
//
//static void SecondaryLoopPostAction ();
static LRESULT CALLBACK WindowProc (HWND,UINT,WPARAM,LPARAM);
static const char className[] = "G4OpenInventorShellWindow";
void G4OpenInventorWinViewer::FinishView () {
if(!fViewer) return;
fViewer->viewAll();
fViewer->saveHomePosition();
}
void G4OpenInventorWinViewer::KernelVisitDecision () {
// If there's a significant difference with the last view parameters
// of either the scene handler or this viewer, trigger a rebuild.
if (
//??fG4OpenInventorSceneHandler.fPODLList.size() == 0 ||
// We need a test for empty scene graph, such as
// staticRoot.size() or something?????????? See temporary fix
// in contructor. (John Allison Aug 2001)
CompareForKernelVisit(fG4OpenInventorSceneHandler.fLastVP) ||
CompareForKernelVisit(fLastVP)) {
NeedKernelVisit ();
}
fLastVP = fVP;
fG4OpenInventorSceneHandler.fLastVP = fVP;
}
G4bool G4OpenInventorWinViewer::CompareForKernelVisit
(G4ViewParameters&) {
if (
(fLastVP.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
(fLastVP.GetRepStyle () != fVP.GetRepStyle ()) ||
(fLastVP.IsCulling () != fVP.IsCulling ()) ||
(fLastVP.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
(fLastVP.IsDensityCulling () != fVP.IsDensityCulling ()) ||
(fLastVP.IsCullingCovered () != fVP.IsCullingCovered ()) ||
(fLastVP.IsSection () != fVP.IsSection ()) ||
// No need to visit kernel if section plane changes.
(fLastVP.IsCutaway () != fVP.IsCutaway ()) ||
(fLastVP.GetCutawayPlanes ().size () !=
fVP.GetCutawayPlanes ().size ()) ||
// No need to visit kernel if cutaway planes change.
(fLastVP.IsExplode () != fVP.IsExplode ()) ||
(fLastVP.GetNoOfSides () != fVP.GetNoOfSides ())
) {
return true;;
}
if (fLastVP.IsDensityCulling () &&
(fLastVP.GetVisibleDensity () != fVP.GetVisibleDensity ()))
return true;
if (fLastVP.IsExplode () &&
(fLastVP.GetExplodeFactor () != fVP.GetExplodeFactor ()))
return true;
return false;
}
G4OpenInventorWinViewer::G4OpenInventorWinViewer
(G4OpenInventorSceneHandler& sceneHandler,
const G4String& name)
:G4VViewer (sceneHandler, sceneHandler.IncrementViewCount(), name)
,fG4OpenInventorSceneHandler(sceneHandler)
,fShell(0)
,fViewer(0)
,fSelection(0)
,fInteractorManager(0)
{
fNeedKernelVisit = true; //?? Temporary, until KernelVisitDecision fixed.
fInteractorManager =
((G4OpenInventor*)fG4OpenInventorSceneHandler.GetGraphicsSystem())->
GetInteractorManager();
//Widget toplevel = (Widget)fInteractorManager->GetMainInteractor ();
//fInteractorManager->
//AddSecondaryLoopPostAction((G4SecondaryLoopAction)SecondaryLoopPostAction);
G4cout << "Window name: " << fName << G4endl;
//
// Selection
//
fSelection = new SoSelection;
fSelection->policy = SoSelection::SINGLE;
fSelection->ref();
fSelection->addChild(fG4OpenInventorSceneHandler.root);
G4String wName = fName;
#define SIZE 400
HWND parent = (HWND)fInteractorManager->GetParentInteractor ();
if(!parent) {
//Create a shell window :
G4String shellName = wName;
shellName += "_shell";
static SbBool done = FALSE;
if(done==FALSE) {
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 = 0;
wc.lpszMenuName = className;
wc.lpszClassName = className;
::RegisterClass(&wc);
done = TRUE;
}
// Compell window to be created at 0,0 to bypass
// the 'black border' problem.
fShell = ::CreateWindow(className, shellName.c_str(),
WS_OVERLAPPEDWINDOW,
//CW_USEDEFAULT, CW_USEDEFAULT,
0,0,400,400,0, 0,::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 400 400 :
MoveWindow((HWND)fShell,wrect.left,wrect.top,400+ww-cw,400+wh-ch,TRUE);
::SetWindowLong((HWND)fShell,GWL_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 SoWinExaminerViewer(parent,wName.c_str(),TRUE);
fViewer->setSize(SbVec2s(SIZE,SIZE));
fViewer->setSceneGraph(fSelection);
fViewer->viewAll();
fViewer->saveHomePosition();
fViewer->setTitle(fName);
fViewer->show();
if(fShell) {
SoWin::show(fShell);
fInteractorManager->FlushAndWaitExecution ();
}
fInteractorManager->SetCreatedInteractor (fViewer -> getWidget());
}
G4OpenInventorWinViewer::~G4OpenInventorWinViewer () {
if(fShell) fInteractorManager->RemoveShell(fShell);
if(fViewer) delete fViewer;
if(fShell) {
::SetWindowLong((HWND)fShell,GWL_USERDATA,LONG(0));
::DestroyWindow((HWND)fShell);
}
if(fSelection) fSelection->unref();
}
void G4OpenInventorWinViewer::ClearView () {
}
void G4OpenInventorWinViewer::SetView () {
}
void G4OpenInventorWinViewer::DrawView () {
G4cout << "debug Iv::DrawViewer " <<G4endl;
KernelVisitDecision();
ProcessView();
FinishView();
}
void G4OpenInventorWinViewer::ShowView () {
fInteractorManager -> SecondaryLoop ();
}
//////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK 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);
HWND hwnd = ::GetFirstChild(aWindow);
if(hwnd!=0) {
::MoveWindow(hwnd,0,0,width,height,TRUE);
}
}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*)::GetWindowLong(aWindow,GWL_USERDATA);
//::PostQuitMessage(0);
}return 0;
default:
return (::DefWindowProc(aWindow,aMessage,aWParam,aLParam));
}
}
#endif
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4OpenInventorX.cc,v 1.5 2001/07/11 10:09:01 gunter Exp $
// GEANT4 tag $Name: geant4-05-02-patch-01 $
// $Id: G4OpenInventorXt.cc,v 1.1 2004/04/08 09:41:11 gbarrand Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
//
// Jeff Kallenbach 01 Aug 1996
@@ -30,16 +30,17 @@
#ifdef G4VIS_BUILD_OIX_DRIVER
// this :
#include "G4OpenInventorXt.hh"
#include <Inventor/Xt/SoXt.h>
#include "G4OpenInventorX.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4OpenInventorViewer.hh"
#include "G4Xt.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4OpenInventorXtViewer.hh"
G4OpenInventorX::G4OpenInventorX ()
:G4OpenInventor("OpenInventorX","OIX",G4VGraphicsSystem::threeD)
G4OpenInventorXt::G4OpenInventorXt ()
:G4OpenInventor("OpenInventorXt","OIX",G4VGraphicsSystem::threeD)
{
SetInteractorManager (G4Xt::getInstance ());
GetInteractorManager () ->
@@ -48,12 +49,17 @@ G4OpenInventorX::G4OpenInventorX ()
AddDispatcher ((G4DispatchFunction)SoXt::dispatchEvent);
Widget toplevel = (Widget)GetInteractorManager()->GetMainInteractor();
SoXt::init(toplevel);
SoXt::init (toplevel);
InitHEPVis();
InitNodes();
}
G4OpenInventorXt::~G4OpenInventorXt () {}
G4VViewer* G4OpenInventorXt::CreateViewer (G4VSceneHandler& scene, const G4String& name)
{
G4OpenInventorSceneHandler* pScene = (G4OpenInventorSceneHandler*)&scene;
return new G4OpenInventorXtViewer (*pScene, name);
}
G4OpenInventorX::~G4OpenInventorX () {}
#endif
@@ -21,33 +21,29 @@
// ********************************************************************
//
//
// $Id: G4OpenInventorViewer.cc,v 1.10 2003/08/28 11:44:22 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4OpenInventorXtViewer.cc,v 1.1 2004/04/08 09:41:11 gbarrand Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*
* jck 05 Feb 1997 - Initial Implementation
* jck 21 Apr 1997
* Mods for SoXtHepViewer
* gb : on Win32 use an SoXtExaminerViewer.
* gb 05 April 2004 : revisit to separate Windows things.
*/
#ifdef G4VIS_BUILD_OI_DRIVER
#ifdef G4VIS_BUILD_OIX_DRIVER
// this :
#include "G4OpenInventorXtViewer.hh"
#include <Inventor/nodes/SoSelection.h>
#include <Inventor/Xt/SoXt.h>
#include <Inventor/nodes/SoSelection.h>
#include <Inventor/nodes/SoSelection.h>
#include "G4SoWindow.hh"
#ifdef WIN32
#include <Inventor/Xt/viewers/SoXtExaminerViewer.h>
#else
#include <HEPVis/Xt/viewers/SoXtHepViewer.h>
#endif
#include <X11/StringDefs.h>
#include "G4OpenInventor.hh"
#include "G4OpenInventorViewer.hh"
#include "G4OpenInventorSceneHandler.hh"
#include "G4VInteractorManager.hh"
//
@@ -56,24 +52,10 @@
//static void SecondaryLoopPostAction ();
void G4OpenInventorViewer::FinishView () {
if(fViewer==0) return;
#ifdef WIN32
((SoXtViewer*)fViewer)->viewAll();
((SoXtViewer*)fViewer)->saveHomePosition();
#else
((SoXtHepViewer*)fViewer)->getCurrentViewer()->viewAll();
((SoXtHepViewer*)fViewer)->getCurrentViewer()->saveHomePosition();
#endif
}
//
// Exit
//
int quitCB(void* interactorManager) {
((G4VInteractorManager*)interactorManager) ->
RequireExitSecondaryLoop (OIV_EXIT_CODE);
return 0;
void G4OpenInventorXtViewer::FinishView () {
if(!fViewer) return;
fViewer->viewAll();
fViewer->saveHomePosition();
}
//static void SecondaryLoopPostAction ()
@@ -85,7 +67,7 @@ int quitCB(void* interactorManager) {
// }
//}
void G4OpenInventorViewer::KernelVisitDecision () {
void G4OpenInventorXtViewer::KernelVisitDecision () {
// If there's a significant difference with the last view parameters
// of either the scene handler or this viewer, trigger a rebuild.
@@ -103,7 +85,7 @@ void G4OpenInventorViewer::KernelVisitDecision () {
fG4OpenInventorSceneHandler.fLastVP = fVP;
}
G4bool G4OpenInventorViewer::CompareForKernelVisit
G4bool G4OpenInventorXtViewer::CompareForKernelVisit
(G4ViewParameters&) {
if (
@@ -135,13 +117,12 @@ G4bool G4OpenInventorViewer::CompareForKernelVisit
return false;
}
G4OpenInventorViewer::G4OpenInventorViewer
G4OpenInventorXtViewer::G4OpenInventorXtViewer
(G4OpenInventorSceneHandler& sceneHandler,
const G4String& name)
:G4VViewer (sceneHandler, sceneHandler.IncrementViewCount(), name)
,fG4OpenInventorSceneHandler(sceneHandler)
,fShell(0)
,fWindow(0)
,fViewer(0)
,fSelection(0)
,fInteractorManager(0)
@@ -151,10 +132,10 @@ G4OpenInventorViewer::G4OpenInventorViewer
fInteractorManager =
((G4OpenInventor*)fG4OpenInventorSceneHandler.GetGraphicsSystem())->
GetInteractorManager();
//Widget toplevel = (Widget)fInteractorManager->GetMainInteractor ();
//Widget toplevel = (Widget)fInteractorManager->GetMainInteractor ();
//fInteractorManager->
//AddSecondaryLoopPostAction ((G4SecondaryLoopAction)SecondaryLoopPostAction);
//fInteractorManager->
//AddSecondaryLoopPostAction((G4SecondaryLoopAction)SecondaryLoopPostAction);
G4cout << "Window name: " << fName << G4endl;
//
@@ -165,78 +146,68 @@ G4OpenInventorViewer::G4OpenInventorViewer
fSelection->ref();
fSelection->addChild(fG4OpenInventorSceneHandler.root);
Widget parent = (Widget)fInteractorManager->GetParentInteractor ();
G4String wName = fName;
const char* wname = wName.data();
#define SIZE 400
if(parent==0) { //Create a shell window :
fWindow = new G4SoWindow(wname);
fWindow->setTitle(wname);
fWindow->setSize(SbVec2s(SIZE,SIZE));
fShell = parent = fWindow->getWidget();
Widget parent = (Widget)fInteractorManager->GetParentInteractor ();
if(!parent) {
//Create a shell window :
G4String shellName = wName;
shellName += "_shell";
Arg args[3];
char s[32];
sprintf(s,"%dx%d",SIZE,SIZE);
XtSetArg(args[0],XtNgeometry,XtNewString(s));
XtSetArg(args[1],XtNborderWidth,0);
XtSetArg(args[2],XtNtitle,XtNewString(wName.c_str()));
fShell = XtAppCreateShell(shellName.c_str(),"Inventor",
topLevelShellWidgetClass,
SoXt::getDisplay(),
args,3);
parent = fShell;
fInteractorManager->AddShell(fShell);
} else {
char* str = fInteractorManager->GetCreationString ();
if(str!=0) wname = str;
char* str = fInteractorManager->GetCreationString();
if(str!=0) wName = str;
}
//
// Create and Customize the Viewer
//
#ifdef WIN32
fViewer = new SoXtExaminerViewer(parent,wname,TRUE);
fViewer = new SoXtExaminerViewer(parent,wName.c_str(),TRUE);
fViewer->setSize(SbVec2s(SIZE,SIZE));
((SoXtViewer*)fViewer)->setSceneGraph(fSelection);
((SoXtViewer*)fViewer)->viewAll();
((SoXtViewer*)fViewer)->saveHomePosition();
#else
fViewer = new SoXtHepViewer (parent,wname,TRUE);
((SoXtHepViewer*)fViewer)->hideTextArea();
((SoXtHepViewer*)fViewer)->resizeMain(SIZE,SIZE);
((SoXtHepViewer*)fViewer)->setQuitCallback(quitCB, fInteractorManager);
((SoXtHepViewer*)fViewer)->setSceneGraph(fSelection);
((SoXtHepViewer*)fViewer)->getCurrentViewer()->viewAll();
((SoXtHepViewer*)fViewer)->getCurrentViewer()->saveHomePosition();
#endif
fViewer->setSceneGraph(fSelection);
fViewer->viewAll();
fViewer->saveHomePosition();
fViewer->setTitle(fName);
fViewer->show();
if(fWindow!=0) {
fWindow->show();
if(fShell) {
SoXt::show(fShell);
fInteractorManager->FlushAndWaitExecution ();
}
fInteractorManager->SetCreatedInteractor (fViewer -> getWidget());
}
G4OpenInventorViewer::~G4OpenInventorViewer () {
if(fShell!=0) fInteractorManager -> RemoveShell (fShell);
if(fViewer!=0) {
#ifdef WIN32
delete ((SoXtExaminerViewer*)fViewer);
#else
delete ((SoXtHepViewer*)fViewer);
#endif
}
if(fWindow!=0) delete fWindow;
if(fSelection!=0) fSelection->unref();
G4OpenInventorXtViewer::~G4OpenInventorXtViewer () {
if(fShell) fInteractorManager->RemoveShell(fShell);
if(fViewer) delete fViewer;
if(fShell) XtDestroyWidget(fShell);
if(fSelection) fSelection->unref();
}
void G4OpenInventorViewer::ClearView () {
void G4OpenInventorXtViewer::ClearView () {
}
void G4OpenInventorViewer::SetView () {
void G4OpenInventorXtViewer::SetView () {
}
void G4OpenInventorViewer::DrawView () {
void G4OpenInventorXtViewer::DrawView () {
G4cout << "debug Iv::DrawViewer " <<G4endl;
KernelVisitDecision ();
ProcessView ();
FinishView ();
KernelVisitDecision();
ProcessView();
FinishView();
}
void G4OpenInventorViewer::ShowView () {
void G4OpenInventorXtViewer::ShowView () {
fInteractorManager -> SecondaryLoop ();
}
@@ -1,403 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define SbWarn printf
#include <HEPVis/SbBasic.h>
// For backward compatibility :
#ifdef HEPVisWin
#define HEPVisWin32
#endif
#ifdef CDF
#ifndef LINUX
#define u_long unsigned long
#endif
#endif
#ifdef HEPVisXt
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#endif
#ifdef HEPVisWin32
#include <windowsx.h> //For GetWindowInstance.
#endif
#include <Inventor/SbString.h>
#include <Inventor/SbDict.h>
#include "G4SoWindow.hh"
#ifdef HEPVisXt
static XtTranslations trans_table = 0;
static XtActionsRec closeAction =
{(String)"CloseG4SoWindow",G4SoWindow::closeWindow};
//static void XWidgetSetDimension(Widget,Dimension,Dimension);
#endif
#ifdef HEPVisWin32
static LRESULT CALLBACK WindowProc (HWND,UINT,WPARAM,LPARAM);
static const char className[] = "G4SoWindow";
#endif
SbDict* G4SoWindow::fWidgetDictionary = 0;
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::clearClass (
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(fWidgetDictionary!=0) delete fWidgetDictionary;
fWidgetDictionary = 0;
}
//////////////////////////////////////////////////////////////////////////////
G4SoWindow::G4SoWindow(
const char* aName
,SbBool aWMClose
)
:fWidget(0)
,fWMClose(aWMClose)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
#ifdef HEPVisXt
if(trans_table==0) {
trans_table =
XtParseTranslationTable("<Message>WM_PROTOCOLS:CloseG4SoWindow()");
XtAppAddActions(SoXt::getAppContext(),&closeAction,1);
}
SbString shellName = aName;
shellName += "_shell";
Arg args[2];
XtSetArg(args[0],XtNgeometry,XtNewString("400x400"));
XtSetArg(args[1],XtNborderWidth,0);
fWidget = XtAppCreateShell(shellName.getString(),"Inventor",
topLevelShellWidgetClass,
SoXt::getDisplay(),
args,2);
if(fWidget!=0) {
XtOverrideTranslations(fWidget,trans_table);
XtAddCallback(fWidget,XtNdestroyCallback,
(XtCallbackProc)G4SoWindow::widgetDestroyedCB,0);
}
#endif
#ifdef HEPVisWin32
static SbBool done = FALSE;
if(done==FALSE) {
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 = 0;
wc.lpszMenuName = className;
wc.lpszClassName = className;
::RegisterClass(&wc);
done = TRUE;
}
// Compell window to be created at 0,0 to bypass
// the 'black border' problem.
fWidget = ::CreateWindow(className, aName,
WS_OVERLAPPEDWINDOW,
//CW_USEDEFAULT, CW_USEDEFAULT,
0,0,
400,400,
0, 0,
::GetModuleHandle(0),
0);
// Retreive window and client sizez :
RECT wrect,crect;
GetWindowRect((HWND)fWidget,&wrect);
GetClientRect((HWND)fWidget,&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 400 400 :
MoveWindow((HWND)fWidget,wrect.left,wrect.top,400+ww-cw,400+wh-ch,TRUE);
//
::SetWindowLong((HWND)fWidget,GWL_USERDATA,LONG(this));
#endif
registerWidget(fWidget);
}
//////////////////////////////////////////////////////////////////////////////
G4SoWindow::~G4SoWindow(
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(fWidget==0) return;
unregisterWidget(fWidget);
#ifdef HEPVisXt
XtDestroyWidget(fWidget);
#endif
#ifdef HEPVisWin32
::SetWindowLong((HWND)fWidget,GWL_USERDATA,LONG(0));
::DestroyWindow((HWND)fWidget);
#endif
}
//////////////////////////////////////////////////////////////////////////////
Widget G4SoWindow::getWidget(
) const
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
return fWidget;
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::setWMClose(
SbBool aValue
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
fWMClose = aValue;
}
//////////////////////////////////////////////////////////////////////////////
SbBool G4SoWindow::getWMClose(
) const
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
return fWMClose;
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::show(
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(fWidget==0) return;
SoXt::show(fWidget);
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::hide(
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(fWidget==0) return;
SoXt::hide(fWidget);
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::setTitle(
const char* aString
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(aString==0) return;
#ifdef HEPVisXt
Arg args[1];
XtSetArg(args[0],XtNtitle,XtNewString(aString));
XtSetValues(fWidget,args,1);
#endif
#ifdef HEPVisWin32
::SetWindowText((HWND)fWidget,aString);
#endif
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::setSize(
const SbVec2s& aSize
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(fWidget==0) return;
#ifdef HEPVisXt
Arg args[1];
char s[32];
sprintf(s,"%dx%d",aSize[0],aSize[1]);
XtSetArg(args[0],XtNgeometry,XtNewString(s));
XtSetValues(fWidget,args,1);
//XWidgetSetDimension(fWidget,aSize[0],aSize[1]);
#endif
#ifdef HEPVisWin32
// Retreive window and client sizez :
RECT wrect,crect;
GetWindowRect((HWND)fWidget,&wrect);
GetClientRect((HWND)fWidget,&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 400 400 :
MoveWindow((HWND)fWidget,
wrect.left,wrect.top,
aSize[0]+ww-cw,aSize[1]+wh-ch,TRUE);
#endif
}
//////////////////////////////////////////////////////////////////////////////
SbVec2s G4SoWindow::getSize(
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(fWidget==0) return SbVec2s();
#ifdef HEPVisXt
Dimension width,height;
Arg args[2];
XtSetArg(args[0],XtNwidth ,&width);
XtSetArg(args[1],XtNheight,&height);
XtGetValues(fWidget,args,2);
return SbVec2s(width,height);
#endif
#ifdef HEPVisWin32
RECT rect;
::GetClientRect((HWND)fWidget,&rect);
return SbVec2s((short)(rect.right-rect.left),(short)(rect.bottom-rect.top));
#endif
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::registerWidget(
Widget aWidget
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(aWidget==0) return;
if(fWidgetDictionary==0) fWidgetDictionary = new SbDict;
fWidgetDictionary->enter((unsigned long)aWidget,this);
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::unregisterWidget(
Widget aWidget
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(aWidget==0) return;
if(fWidgetDictionary==0) return;
fWidgetDictionary->remove((unsigned long)aWidget);
}
//////////////////////////////////////////////////////////////////////////////
G4SoWindow* G4SoWindow::getWindow(
Widget aWidget
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
if(aWidget==0) return 0;
if(fWidgetDictionary==0) return 0;
void* value;
SbBool found = fWidgetDictionary->find((unsigned long)aWidget,value);
return (G4SoWindow*)(found==FALSE ? 0 : value);
}
#ifdef HEPVisXt
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::widgetDestroyedCB(
Widget aWidget
,XtPointer
,XtPointer
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
G4SoWindow* This = G4SoWindow::getWindow(aWidget);
if(This==0) return; // XtDestroyWidget called from ~G4SoWindow.
//printf("debug : G4SoWindow::widgetDestroyCB\n");
This->unregisterWidget(aWidget);
}
//////////////////////////////////////////////////////////////////////////////
void G4SoWindow::closeWindow(
Widget aWidget
,XEvent* /*aEvent*/
,char** /*aArgs*/
,Cardinal* /*aNarg*/
)
//////////////////////////////////////////////////////////////////////////////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
{
G4SoWindow* This = G4SoWindow::getWindow(aWidget);
if( (This!=0) && (This->getWMClose()==TRUE) ) {
//SbWarn ("debug : CloseWindow : close\n");
#ifdef SoFreePackage
SoXt::sendExit ();
#else
exit (EXIT_SUCCESS);
#endif
} else {
// Should destroy G4SoWindow.
XtUnmapWidget(aWidget);
}
}
/*
#include <X11/IntrinsicP.h> //Dangerous.
void XWidgetSetDimension(Widget aWidget,Dimension a_width,Dimension a_height){
if(aWidget==0) return;
if((a_width<=0)||(a_height<=0)) return;
XtResizeWidget (aWidget,a_width,a_height,aWidget->core.border_width);
}
*/
#endif
#ifdef HEPVisWin32
//////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK 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);
HWND hwnd = ::GetFirstChild(aWindow);
if(hwnd!=0) {
::MoveWindow(hwnd,0,0,width,height,TRUE);
}
}return 0;
case WM_SETFOCUS:{ // Assume one child window !
HWND hwnd = ::GetFirstChild(aWindow);
if(hwnd!=0) ::SetFocus(hwnd);
}return 0;
case WM_DESTROY:{
G4SoWindow* This = (G4SoWindow*)::GetWindowLong(aWindow,GWL_USERDATA);
if( (This!=0) && (This->getWMClose()==TRUE) ) {
::PostQuitMessage(0);
}
}return 0;
default:
return (::DefWindowProc(aWindow,aMessage,aWParam,aLParam));
}
}
#endif
@@ -0,0 +1,273 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: SoBox.cc,v 1.2 2004/06/14 09:27:39 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*----------------------------Hepvis----------------------------------------*/
/* */
/* Node: SoBox */
/* Description: Represents the G4Box Geant Geometry entity */
/* Author: Joe Boudreau Nov 11 1996 */
/* */
/*--------------------------------------------------------------------------*/
#include <assert.h>
#include <math.h>
#include <Inventor/SbBox.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/misc/SoChildList.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoScale.h>
#include <Inventor/actions/SoAction.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/SoPrimitiveVertex.h>
#include <Inventor/elements/SoTextureCoordinateElement.h>
#include "HEPVis/nodes/SoBox.h"
// This statement is required
SO_NODE_SOURCE(SoBox)
// Constructor
SoBox::SoBox() {
// This statement is required
SO_NODE_CONSTRUCTOR(SoBox);
// Data fields are initialized like this:
SO_NODE_ADD_FIELD(fDx, (1.0));
SO_NODE_ADD_FIELD(fDy, (1.0));
SO_NODE_ADD_FIELD(fDz, (1.0));
SO_NODE_ADD_FIELD(alternateRep, (NULL));
children = new SoChildList(this);
}
// Destructor
SoBox::~SoBox() {
delete children;
}
// initClass
void SoBox::initClass(){
// This statement is required.
SO_NODE_INIT_CLASS(SoBox,SoShape,"Shape");
}
// generatePrimitives
void SoBox::generatePrimitives(SoAction *action) {
// This variable is used to store each vertex
SoPrimitiveVertex pv;
// Access the stat from the action
SoState *state = action->getState();
// See if we have to use a texture coordinate function,
// rather than generating explicit texture coordinates.
SbBool useTexFunction=
(SoTextureCoordinateElement::getType(state) ==
SoTextureCoordinateElement::FUNCTION);
// If we need to generate texture coordinates with a function,
// we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
// set up the coordinates directly.
const SoTextureCoordinateElement *tce = NULL;
SbVec4f texCoord;
if (useTexFunction) {
tce = SoTextureCoordinateElement::getInstance(state);
}
else {
texCoord[2] = 0.0;
texCoord[3] = 1.0;
}
SbVec3f point, normal;
//////////////////////////////////////////
//----------------------------------------
#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
point.setValue(x,y,z); \
normal.setValue(nx,ny,nz); \
if (useTexFunction) { \
texCoord=tce->get(point,normal); \
} \
else { \
texCoord[0]=s; \
texCoord[1]=t; \
} \
pv.setPoint(point); \
pv.setNormal(normal); \
pv.setTextureCoords(texCoord); \
shapeVertex(&pv);
//----------------------------------------
//////////////////////////////////////////
const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, //z back.
4,5,6,7, SO_END_FACE_INDEX, //z front.
0,1,5,4, SO_END_FACE_INDEX, //y up.
1,2,6,5, SO_END_FACE_INDEX, //x left.
2,3,7,6, SO_END_FACE_INDEX, //y down.
3,0,4,7, SO_END_FACE_INDEX}; //x right.
// points for the eight vertices
float points[NPOINTS][3];
points[0][0] = fDx.getValue();
points[0][1] = fDy.getValue();
points[0][2] = -fDz.getValue();
points[1][0] = -fDx.getValue();
points[1][1] = fDy.getValue();
points[1][2] = -fDz.getValue();
points[2][0] = -fDx.getValue();
points[2][1] = -fDy.getValue();
points[2][2] = -fDz.getValue();
points[3][0] = fDx.getValue();
points[3][1] = -fDy.getValue();
points[3][2] = -fDz.getValue();
points[4][0] = fDx.getValue();
points[4][1] = fDy.getValue();
points[4][2] = fDz.getValue();
points[5][0] = -fDx.getValue();
points[5][1] = fDy.getValue();
points[5][2] = fDz.getValue();
points[6][0] = -fDx.getValue();
points[6][1] = -fDy.getValue();
points[6][2] = fDz.getValue();
points[7][0] = fDx.getValue();
points[7][1] = -fDy.getValue();
points[7][2] = fDz.getValue();
float normals[NFACES][3];
//z back.
normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
//z front.
normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
//y up.
normals[2][0] = 0 ; normals[2][1] = 1; normals [2][2] = 0;
//x left.
normals[3][0] = -1 ; normals[3][1] = 0; normals [3][2] = 0;
//y down.
normals[4][0] = 0 ; normals[4][1] = -1; normals [4][2] = 0;
//x right.
normals[5][0] = 1 ; normals[5][1] = 0; normals [5][2] = 0;
float x,y,z;
int index;
for (int nf=0;nf<NFACES;nf++) {
beginShape(action,TRIANGLE_FAN);
index = indices[nf * 5];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 1];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 2];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 3];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
endShape();
}
}
// getChildren
SoChildList *SoBox::getChildren() const {
return children;
}
// computeBBox
void SoBox::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
SbVec3f vmin(-fDx.getValue(),-fDy.getValue(),-fDz.getValue()),
vmax( fDx.getValue(), fDy.getValue(), fDz.getValue());
center.setValue(0,0,0);
box.setBounds(vmin,vmax);
}
// updateChildren
void SoBox::updateChildren() {
// Redraw the G4Box....
assert(children->getLength()==1);
SoSeparator *sep = (SoSeparator *) ( *children)[0];
SoScale *scale = (SoScale *)( sep->getChild(0));
//SoCube *cube = (SoCube *)( sep->getChild(1));
scale->scaleFactor.setValue(fDx.getValue(), fDy.getValue(), fDz.getValue());
}
// generateChildren
void SoBox::generateChildren() {
// A box consists of a set of scale factors and a
// cube.
assert(children->getLength() ==0);
SoSeparator *sep = new SoSeparator();
SoScale *scale = new SoScale();
SoCube *cube = new SoCube();
sep->addChild(scale);
sep->addChild(cube);
children->append(sep);
}
// generateAlternateRep
void SoBox::generateAlternateRep() {
// This routine sets the alternate representation to the child
// list of this mode.
if (children->getLength() == 0) generateChildren();
updateChildren();
alternateRep.setValue((SoSeparator *) ( *children)[0]);
}
// clearAlternateRep
void SoBox::clearAlternateRep() {
alternateRep.setValue(NULL);
}
@@ -0,0 +1,436 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: SoCons.cc,v 1.2 2004/06/14 09:27:39 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*-----------------------------Hepvis---------------------------------------*/
/* */
/* Node: SoCons */
/* Description: Represents the G4Cons Geant Geometry entity */
/* Author: Joe Boudreau Nov 11 1996 */
/* */
/*--------------------------------------------------------------------------*/
#include <assert.h>
#include <math.h>
#include <Inventor/SbBox.h>
#include <Inventor/actions/SoAction.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/misc/SoChildList.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/nodes/SoNormal.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoNormalBinding.h>
#include <Inventor/SoPrimitiveVertex.h>
#include <Inventor/elements/SoTextureCoordinateElement.h>
#include "HEPVis/SbMath.h"
#include "HEPVis/nodes/SoCons.h"
// This statement is required
SO_NODE_SOURCE(SoCons)
// Constructor
SoCons::SoCons() {
// This statement is required
SO_NODE_CONSTRUCTOR(SoCons);
// Data fields are initialized like this:
SO_NODE_ADD_FIELD(fRmin1, (0.0));
SO_NODE_ADD_FIELD(fRmin2, (0.0));
SO_NODE_ADD_FIELD(fRmax1, (1.0));
SO_NODE_ADD_FIELD(fRmax2, (1.0));
SO_NODE_ADD_FIELD(fDz, (10.0));
SO_NODE_ADD_FIELD(fSPhi, (0.0));
SO_NODE_ADD_FIELD(fDPhi, ((float)(2*M_PI)));
SO_NODE_ADD_FIELD(smoothDraw, (TRUE));
SO_NODE_ADD_FIELD(alternateRep, (NULL));
children = new SoChildList(this);
}
// Destructor
SoCons::~SoCons() {
delete children;
}
// initClass
void SoCons::initClass(){
// This statement is required.
SO_NODE_INIT_CLASS(SoCons,SoShape,"Shape");
}
// generatePrimitives
void SoCons::generatePrimitives(SoAction *action) {
// This variable is used to store each vertex
SoPrimitiveVertex pv;
// Access the stat from the action
SoState *state = action->getState();
// See if we have to use a texture coordinate function,
// rather than generating explicit texture coordinates.
SbBool useTexFunction=
(SoTextureCoordinateElement::getType(state) ==
SoTextureCoordinateElement::FUNCTION);
// If we need to generate texture coordinates with a function,
// we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
// set up the coordinates directly.
const SoTextureCoordinateElement *tce = NULL;
SbVec4f texCoord;
if (useTexFunction) {
tce = SoTextureCoordinateElement::getInstance(state);
} else {
texCoord[2] = 0.0;
texCoord[3] = 1.0;
}
SbVec3f point, normal;
///////////////////////////////////////////////////////
//-----------------------------------------------------
#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
point.setValue((float)(x),(float)(y),(float)(z)); \
normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
if (useTexFunction) { \
texCoord=tce->get(point,normal); \
} else { \
texCoord[0]=(float)(s); \
texCoord[1]=(float)(t); \
} \
pv.setPoint(point); \
pv.setNormal(normal); \
pv.setTextureCoords(texCoord); \
shapeVertex(&pv);
//-----------------------------------------------------
///////////////////////////////////////////////////////
int NPHI = (int)(2+22*fabs(fDPhi.getValue()/(2.0*M_PI)));
double deltaPhi = fDPhi.getValue()/NPHI;
double phi0 = fSPhi.getValue();
double phi1 = phi0 + fDPhi.getValue();
double rMax1 = fRmax1.getValue();
double rMin1 = fRmin1.getValue();
double rMax2 = fRmax2.getValue();
double rMin2 = fRmin2.getValue();
double zMax = fDz.getValue();
double zMin = -zMax;
double cosPhi0 = cos(phi0);
double sinPhi0 = sin(phi0);
double cosPhi1 = cos(phi1);
double sinPhi1 = sin(phi1);
double cosDeltaPhi = cos(deltaPhi);
double sinDeltaPhi = sin(deltaPhi);
//
// The outer surface!
//
beginShape(action,TRIANGLE_STRIP);
int i;
double sinPhi=sinPhi0;
double cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);
GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
//
// The inner surface!
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);
GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
if (fabs(deltaPhi)<2.0*M_PI) {
//
// The end
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
endShape();
//
// The other end
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi1;
cosPhi=cosPhi1;
GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
endShape();
}
//
// The outer surface at z=+PDZ
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMin2*cosPhi,rMin2*sinPhi,zMax,0.0,0.0,0,0,1);
GEN_VERTEX(pv,rMax2*cosPhi,rMax2*sinPhi,zMax,1.0,1.0,0,0,1);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
//
// The outer surface at z=-PDZ
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMin1*cosPhi,rMin1*sinPhi,zMin,0.0,0.0,0,0,-1);
GEN_VERTEX(pv,rMax1*cosPhi,rMax1*sinPhi,zMin,1.0,1.0,0,0,-1);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
}
// getChildren
SoChildList *SoCons::getChildren() const {
return children;
}
// computeBBox
void SoCons::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
float fRmax= fRmax1.getValue();
if (fRmax2.getValue() > fRmax) fRmax = fRmax2.getValue();
SbVec3f vmin(-fRmax,-fRmax,-fDz.getValue()),
vmax( fRmax, fRmax, fDz.getValue());
center.setValue(0,0,0);
box.setBounds(vmin,vmax);
}
// updateChildren
void SoCons::updateChildren() {
// Redraw the G4Cons....
assert(children->getLength()==1);
SoSeparator *sep = (SoSeparator *) ( *children)[0];
SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
const int NPHI=24, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
float points[NPOINTS][3], normals[NFACES][3];
#ifdef INVENTOR2_0
static long indices[NINDICES];
#else
static int32_t indices[NINDICES];
#endif
static int init=0;
double phi, pp, DeltaPhi;
// Indices need to be generated once! This is here to keep it close to the point
// generation, since otherwise it will be confusing.
int i;
if (!init) {
init = 1;
// Outer face
for (i = 0; i< NPHI; i++) {
// 0 1 3 2;
indices[5*i+0] = 2*i+0;
indices[5*i+1] = 2*i+1;
indices[5*i+2] = 2*i+3;
indices[5*i+3] = 2*i+2;
indices[5*i+4] = SO_END_FACE_INDEX;
}
// the inner face
for (i=0;i<NPHI;i++) {
indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;
indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
}
// the top side
for (i=0;i<NPHI;i++) {
indices[5*2*NPHI + 5*i+0] = 2*i+0;
indices[5*2*NPHI + 5*i+1] = 2*i+2;
indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
}
// the bottom side
for (i=0;i<NPHI;i++) {
indices[5*3*NPHI + 5*i+0] = 2*i+1;
indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
indices[5*3*NPHI + 5*i+3] = 2*i+3;
indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
}
// the odd side
indices[5*4*NPHI +0] = 2*NPHI;
indices[5*4*NPHI +1] = 2*NPHI+1;
indices[5*4*NPHI +2] = 2*NPHI+3;
indices[5*4*NPHI +3] = 2*NPHI+2;
indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
// aother odd side
indices[5*4*NPHI +5 +0] = 0;
indices[5*4*NPHI +5 +1] = NPOINTS-2;
indices[5*4*NPHI +5 +2] = NPOINTS-1;
indices[5*4*NPHI +5 +3] = 1;
indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
}
// Points need to be generated each time:
// The outer surface
DeltaPhi = fDPhi.getValue()/NPHI, phi = fSPhi.getValue();
float t,st,ct;
t = FATAN((fRmax2.getValue()-fRmax1.getValue())/(2*fDz.getValue()));
st = FSIN(t);
ct = FCOS(t);
for (i = 0; i<=NPHI; i++) {
points[2*i+0][0] = fRmax2.getValue()*FCOS(phi);
points[2*i+0][1] = fRmax2.getValue()*FSIN(phi);
points[2*i+0][2] = +fDz.getValue();
points[2*i+1][0] = fRmax1.getValue()*FCOS(phi);
points[2*i+1][1] = fRmax1.getValue()*FSIN(phi);
points[2*i+1][2] = -fDz.getValue();
pp = phi+DeltaPhi/2.0;
if (i!=NPHI) {
normals[i][0] = ct * FCOS(pp);
normals[i][1] = ct * FSIN(pp);
normals[i][2] = -st;
}
phi+=DeltaPhi;
}
// The inner surface
phi = fSPhi.getValue() + fDPhi.getValue();
t = FATAN((fRmin2.getValue()-fRmin1.getValue())/(2*fDz.getValue()));
st = FSIN(t);
ct = FCOS(t);
for (i = 0; i<=NPHI; i++) {
points[2*NPHI+2+2*i+0][0] = fRmin2.getValue()*FCOS(phi);
points[2*NPHI+2+2*i+0][1] = fRmin2.getValue()*FSIN(phi);
points[2*NPHI+2+2*i+0][2] = +fDz.getValue();
points[2*NPHI+2+2*i+1][0] = fRmin1.getValue()*FCOS(phi);
points[2*NPHI+2+2*i+1][1] = fRmin1.getValue()*FSIN(phi);
points[2*NPHI+2+2*i+1][2] = -fDz.getValue();
pp = phi-DeltaPhi/2.0;
if (i!=NPHI) {
normals[NPHI+i][0] = -ct*FCOS(pp);
normals[NPHI+i][1] = -ct*FSIN(pp);
normals[NPHI+i][2] = st;
}
phi-=DeltaPhi;
}
// The top side
for (i=0;i<NPHI;i++) {
normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0;
normals[2*NPHI+i][2]= 1.0;
}
// The bottom side
for (i=0;i<NPHI;i++) {
normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0;
normals[3*NPHI+i][2]= -1.0;
}
// The odd side
phi = fSPhi.getValue();
normals[4*NPHI+0][0]= FSIN(phi);
normals[4*NPHI+0][1]= -FCOS(phi);
normals[4*NPHI+0][2]= 0;
// Another odd side
phi = fSPhi.getValue()+fDPhi.getValue();
normals[4*NPHI+1][0]= -FSIN(phi);
normals[4*NPHI+1][1]= +FCOS(phi);
normals[4*NPHI+1][2]=0;
for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
theFaceSet->coordIndex.setValues(0,NINDICES,indices);
if (smoothDraw.getValue()) {
// This Line is replaced by the next one because of an apparent Bug in Inventor (mem. leak).
// theNormals->vector.deleteValues(0);
for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
theNormalBinding->value=SoNormalBinding::PER_FACE;
}
else {
for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
theNormalBinding->value=SoNormalBinding::PER_FACE;
}
}
// generateChildren
void SoCons::generateChildren() {
// This routines creates one SoSeparator, one SoCoordinate3, and
// one SoLineSet, and puts it in the child list. This is done only
// once, whereas redrawing the position of the coordinates occurs each
// time an update is necessary, in the updateChildren routine.
assert(children->getLength() ==0);
SoSeparator *sep = new SoSeparator();
SoCoordinate3 *theCoordinates = new SoCoordinate3();
SoNormal *theNormals = new SoNormal();
SoNormalBinding *theNormalBinding = new SoNormalBinding();
SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
//
// This line costs some in render quality! but gives speed.
//
sep->addChild(theCoordinates);
sep->addChild(theNormals);
sep->addChild(theNormalBinding);
sep->addChild(theFaceSet);
children->append(sep);
}
// generateAlternateRep
void SoCons::generateAlternateRep() {
// This routine sets the alternate representation to the child
// list of this mode.
if (children->getLength() == 0) generateChildren();
updateChildren();
alternateRep.setValue((SoSeparator *) ( *children)[0]);
}
// clearAlternateRep
void SoCons::clearAlternateRep() {
alternateRep.setValue(NULL);
}
@@ -0,0 +1,214 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: SoDetectorTreeKit.cc,v 1.2 2004/06/14 09:27:40 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*-----------------------------Hepvis----------------------------------------*/
/* */
/* Node: SoDetectorTreeKit */
/* Description: Represents a single sided silicon strip detector */
/* Author: Joe Boudreau Nov 11 1996 */
/* */
/*---------------------------------------------------------------------------*/
#include <math.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/events/SoMouseButtonEvent.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodekits/SoAppearanceKit.h>
#include <Inventor/nodekits/SoNodeKitListPart.h>
#include <Inventor/nodekits/SoBaseKit.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodekits/SoSeparatorKit.h>
#include <Inventor/nodekits/SoShapeKit.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/actions/SoHandleEventAction.h>
#include <Inventor/nodes/SoUnits.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoTexture2Transform.h>
#include "HEPVis/nodekits/SoDetectorTreeKit.h"
// This statement is required
SO_KIT_SOURCE(SoDetectorTreeKit)
// initClass
void SoDetectorTreeKit::initClass(){
SO_KIT_INIT_CLASS(SoDetectorTreeKit,SoBaseKit,"BaseKit");
}
// Constructor
SoDetectorTreeKit::SoDetectorTreeKit() {
SO_KIT_CONSTRUCTOR(SoDetectorTreeKit);
SO_NODE_ADD_FIELD(alternateRep, (NULL));
SO_KIT_ADD_CATALOG_ENTRY ( topSeparator, SoSeparator, FALSE, this,\0, FALSE);
SO_KIT_ADD_CATALOG_ENTRY ( pickStyle, SoSeparator, TRUE , topSeparator,\0, TRUE);
SO_KIT_ADD_CATALOG_ENTRY ( appearance, SoAppearanceKit, TRUE, topSeparator ,\0, TRUE);
SO_KIT_ADD_CATALOG_ENTRY ( units, SoUnits, TRUE, topSeparator ,\0, TRUE);
SO_KIT_ADD_CATALOG_ENTRY ( transform, SoTransform, TRUE , topSeparator,\0, TRUE);
SO_KIT_ADD_CATALOG_ENTRY (texture2Transform, SoTexture2Transform, TRUE, topSeparator ,\0, TRUE);
SO_KIT_ADD_CATALOG_ENTRY ( childList, SoSwitch, FALSE, topSeparator,\0, FALSE);
SO_KIT_ADD_CATALOG_ENTRY ( previewSeparator, SoSeparator, FALSE, childList,\0, TRUE);
SO_KIT_ADD_CATALOG_ENTRY ( fullSeparator, SoSeparator, FALSE, childList,\0, TRUE);
SO_KIT_INIT_INSTANCE();
createInitialTree();
}
// Destructor
SoDetectorTreeKit::~SoDetectorTreeKit() {
}
SbBool SoDetectorTreeKit::affectsState() const {
return FALSE;
}
void SoDetectorTreeKit::createInitialTree() {
SoEventCallback *myCallback = new SoEventCallback();
myCallback->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
SoDetectorTreeKit::expand,
this);
myCallback->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
SoDetectorTreeKit::contract ,
this);
if(setPart("callbackList[0]",myCallback)==FALSE) myCallback->unref();
SoSwitch *theChildList = (SoSwitch *) childList.getValue();
theChildList->whichChild.setValue(0);
}
void SoDetectorTreeKit::expand(void *userData, SoEventCallback *eventCB){
// Was the event previously handled? Is it the right kind?
if (eventCB->isHandled()) return;
const SoMouseButtonEvent *event= (SoMouseButtonEvent *) eventCB->getEvent();
if (!SoMouseButtonEvent::isButtonPressEvent(event,SoMouseButtonEvent::BUTTON1)) return;
if (!event->wasCtrlDown()) return;
if (event->wasShiftDown()) return;
// Which Strip Detector is this being called for?
SoDetectorTreeKit *This = (SoDetectorTreeKit *) userData;
// Find out whether that's the one that has been picked. This is the lowest detector
// tree kit in the hierarchy.
SoHandleEventAction *handleEventAction = eventCB->getAction();
const SoPickedPoint *pickedPoint = handleEventAction->getPickedPoint();
if (!pickedPoint) return;
SoFullPath *path = (SoFullPath *) pickedPoint->getPath();
SoNode *ancestorNode=NULL;
for (int i=0;i<path->getLength();i++) {
ancestorNode = path->getNodeFromTail(i);
if (ancestorNode->isOfType(SoDetectorTreeKit::getClassTypeId())) break;
}
if (This!=ancestorNode) return;
// if (!ancestorNode->isOfType(SoDetectorTreeKit::getClassTypeId())) return;
// Deactivate the Preview
This->setPreview(FALSE);
eventCB->setHandled();
}
void SoDetectorTreeKit::contract(void *userData, SoEventCallback *eventCB){
// Was the event previously handled? Is it the right kind?
if (eventCB->isHandled()) return;
const SoMouseButtonEvent *event= (SoMouseButtonEvent *) eventCB->getEvent();
if (!SoMouseButtonEvent::isButtonPressEvent(event,SoMouseButtonEvent::BUTTON1)) return;
if (event->wasCtrlDown()) return;
if (!event->wasShiftDown()) return;
// Which Strip Detector is this being called for?
SoDetectorTreeKit *This = (SoDetectorTreeKit *) userData;
// Find out whether that's the one that has been picked
SoHandleEventAction *handleEventAction = eventCB->getAction();
const SoPickedPoint *pickedPoint = handleEventAction->getPickedPoint();
if (!pickedPoint) return;
// Find out whether that's the one that has been picked. This is the lowest detector
// tree kit in the hierarchy.
SoFullPath *path = (SoFullPath *) pickedPoint->getPath();
SoNode *ancestorNode=NULL;
SbBool firstTreeFound=FALSE;
for (int i=0;i<path->getLength();i++) {
ancestorNode = path->getNodeFromTail(i);
if (ancestorNode->isOfType(SoDetectorTreeKit::getClassTypeId())) {
if (!firstTreeFound) {
if (This!=ancestorNode) return;
firstTreeFound=TRUE;
}
SoDetectorTreeKit *That = (SoDetectorTreeKit *) ancestorNode;
if (!That->getPreview()) {
That->setPreview(TRUE);
eventCB->setHandled();
return;
}
}
}
}
void SoDetectorTreeKit::setPreview(SbBool Flag) {
SoSwitch *theChildList = (SoSwitch *) childList.getValue();
if (Flag) {
theChildList->whichChild.setValue(0);
}
else {
theChildList->whichChild.setValue(1);
}
}
SbBool SoDetectorTreeKit::getPreview() const {
SoSwitch *theChildList = (SoSwitch *) childList.getValue();
if (theChildList->whichChild.getValue()==0) return TRUE;
return FALSE;
}
SoSeparator *SoDetectorTreeKit::getPreviewSeparator() const {
return (SoSeparator *) previewSeparator.getValue();
}
SoSeparator *SoDetectorTreeKit::getFullSeparator() const {
return (SoSeparator *) fullSeparator.getValue();
}
// generateAlternateRep
void SoDetectorTreeKit::generateAlternateRep() {
alternateRep.setValue(topSeparator.getValue());
}
void SoDetectorTreeKit::clearAlternateRep() {
alternateRep.setValue(NULL);
}
@@ -0,0 +1,403 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: SoTrap.cc,v 1.2 2004/06/14 09:27:40 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*-----------------------------Hepvis----------------------------------------*/
/* */
/* Node: SoTrap */
/* Description: Represents the G4Trap Geant Geometry entity */
/* Author: Joe Boudreau Nov 11 1996 */
/* */
/* */
/*---------------------------------------------------------------------------*/
#include <assert.h>
#include <math.h>
#include <Inventor/SbBox.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/actions/SoAction.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/misc/SoChildList.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/nodes/SoNormal.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoNormalBinding.h>
#include <Inventor/SoPrimitiveVertex.h>
#include <Inventor/elements/SoTextureCoordinateElement.h>
#include "HEPVis/SbMath.h"
#include "HEPVis/nodes/SoTrap.h"
// This statement is required
SO_NODE_SOURCE(SoTrap)
// Constructor
SoTrap::SoTrap() {
// This statement is required
SO_NODE_CONSTRUCTOR(SoTrap);
// Data fields are initialized like this:
SO_NODE_ADD_FIELD(pDz, (1.0));
SO_NODE_ADD_FIELD(pTheta, (0.0));
SO_NODE_ADD_FIELD(pPhi, (0.0));
SO_NODE_ADD_FIELD(pDy1, (1.0));
SO_NODE_ADD_FIELD(pDx1, (1.0));
SO_NODE_ADD_FIELD(pDx2, (1.0));
SO_NODE_ADD_FIELD(pDy2, (1.0));
SO_NODE_ADD_FIELD(pDx3, (1.0));
SO_NODE_ADD_FIELD(pDx4, (1.0));
SO_NODE_ADD_FIELD(pAlp1, (0.0));
SO_NODE_ADD_FIELD(pAlp2, (0.0));
SO_NODE_ADD_FIELD(alternateRep, (NULL));
children = new SoChildList(this);
}
// Destructor
SoTrap::~SoTrap() {
delete children;
}
// initClass
void SoTrap::initClass(){
// This statement is required.
SO_NODE_INIT_CLASS(SoTrap,SoShape,"Shape");
}
// generatePrimitives
void SoTrap::generatePrimitives(SoAction *action) {
// This variable is used to store each vertex
SoPrimitiveVertex pv;
// Access the stat from the action
SoState *state = action->getState();
// See if we have to use a texture coordinate function,
// rather than generating explicit texture coordinates.
SbBool useTexFunction=
(SoTextureCoordinateElement::getType(state) ==
SoTextureCoordinateElement::FUNCTION);
// If we need to generate texture coordinates with a function,
// we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
// set up the coordinates directly.
const SoTextureCoordinateElement *tce = NULL;
SbVec4f texCoord;
if (useTexFunction) {
tce = SoTextureCoordinateElement::getInstance(state);
}
else {
texCoord[2] = 0.0;
texCoord[3] = 1.0;
}
SbVec3f point, normal;
//////////////////////////////////////////
//----------------------------------------
#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
point.setValue(x,y,z); \
normal.setValue(nx,ny,nz); \
if (useTexFunction) { \
texCoord=tce->get(point,normal); \
} \
else { \
texCoord[0]=s; \
texCoord[1]=t; \
} \
pv.setPoint(point); \
pv.setNormal(normal); \
pv.setTextureCoords(texCoord); \
shapeVertex(&pv);
//----------------------------------------
//////////////////////////////////////////
const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, //z back.
4,5,6,7, SO_END_FACE_INDEX, //z front.
0,1,5,4, SO_END_FACE_INDEX, //y up.
1,2,6,5, SO_END_FACE_INDEX, //x left.
2,3,7,6, SO_END_FACE_INDEX, //y down.
3,0,4,7, SO_END_FACE_INDEX}; //x right.
// points for the eight vertices
float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
float Talp1 = FTAN(pAlp1.getValue());
float Talp2 = FTAN(pAlp2.getValue());
float points[NPOINTS][3];
points[0][0] = pDx2.getValue()+pDy1.getValue()*Talp1;
points[0][1] = pDy1.getValue();
points[0][2] = -pDz.getValue();
points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
points[1][1] = pDy1.getValue();
points[1][2] = -pDz.getValue();
points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
points[2][1] = -pDy1.getValue();
points[2][2] = -pDz.getValue();
points[3][0] = pDx1.getValue()-pDy1.getValue()*Talp1;
points[3][1] = -pDy1.getValue();
points[3][2] = -pDz.getValue();
points[4][0] = pDx4.getValue()+pDy2.getValue()*Talp2;
points[4][1] = pDy2.getValue();
points[4][2] = pDz.getValue();
points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
points[5][1] = pDy2.getValue();
points[5][2] = pDz.getValue();
points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
points[6][1] = -pDy2.getValue();
points[6][2] = pDz.getValue();
points[7][0] = pDx3.getValue()-pDy2.getValue()*Talp2;
points[7][1] = -pDy2.getValue();
points[7][2] = pDz.getValue();
int i;
for (i=0;i<4;i++) {
points[i][0] -= pDz.getValue()*TthetaCphi;
points[i][1] -= pDz.getValue()*TthetaSphi;
}
for (i=4;i<8;i++) {
points[i][0] += pDz.getValue()*TthetaCphi;
points[i][1] += pDz.getValue()*TthetaSphi;
}
SbVec3f normals[NFACES];
int nf;
for (nf=0;nf<NFACES;nf++) {
int j0 = indices[5*nf + 0];
int j1 = indices[5*nf + 1];
int j2 = indices[5*nf + 2];
SbVec3f p0(points[j0][0],points[j0][1],points[j0][2]);
SbVec3f p1(points[j1][0],points[j1][1],points[j1][2]);
SbVec3f p2(points[j2][0],points[j2][1],points[j2][2]);
normals[nf] = (p1-p0).cross(p2-p0);
normals[nf].normalize();
}
float x,y,z;
int index;
for (nf=0;nf<NFACES;nf++) {
beginShape(action,TRIANGLE_FAN);
index = indices[nf * 5];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 1];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 2];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 3];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
endShape();
}
}
// getChildren
SoChildList *SoTrap::getChildren() const {
return children;
}
// computeBBox
void SoTrap::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
float pDx= pDx1.getValue(),pDy=pDy1.getValue();
if (pDx2.getValue() > pDx) pDx = pDx2.getValue();
if (pDx3.getValue() > pDx) pDx = pDx3.getValue();
if (pDx4.getValue() > pDx) pDx = pDx4.getValue();
if (pDy2.getValue() > pDy) pDy = pDy2.getValue();
float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
float Xalp = FFABS(tan(pAlp1.getValue())*pDy1.getValue());
float Xalp2 = FFABS(tan(pAlp2.getValue())*pDy2.getValue());
if (Xalp< Xalp2) Xalp=Xalp2;
pDx += FFABS(TthetaCphi*pDz.getValue());
pDx += Xalp;
pDy += FFABS(TthetaSphi*pDz.getValue());
center.setValue(0,0,0);
box.setBounds(SbVec3f(-pDx,-pDy,-pDz.getValue()),
SbVec3f( pDx, pDy, pDz.getValue()));
}
// updateChildren
void SoTrap::updateChildren() {
// Redraw the G4Trap....
assert(children->getLength()==1);
SoSeparator *sep = (SoSeparator *) ( *children)[0];
SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
float points[NPOINTS][3];
// Indices for the eight faces
#ifdef INVENTOR2_0
static long
#else
static int32_t
#endif
indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, // bottom
4,5,6,7, SO_END_FACE_INDEX, // top
0,1,5,4, SO_END_FACE_INDEX,
1,2,6,5, SO_END_FACE_INDEX,
2,3,7,6, SO_END_FACE_INDEX,
3,0,4,7, SO_END_FACE_INDEX};
// points for the eight vertices
float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
float Talp1 = FTAN(pAlp1.getValue());
float Talp2 = FTAN(pAlp2.getValue());
points[0][0] = pDx2.getValue()+pDy1.getValue()*Talp1;
points[0][1] = pDy1.getValue();
points[0][2] = -pDz.getValue();
points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
points[1][1] = pDy1.getValue();
points[1][2] = -pDz.getValue();
points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
points[2][1] = -pDy1.getValue();
points[2][2] = -pDz.getValue();
points[3][0] = pDx1.getValue()-pDy1.getValue()*Talp1;
points[3][1] = -pDy1.getValue();
points[3][2] = -pDz.getValue();
points[4][0] = pDx4.getValue()+pDy2.getValue()*Talp2;
points[4][1] = pDy2.getValue();
points[4][2] = pDz.getValue();
points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
points[5][1] = pDy2.getValue();
points[5][2] = pDz.getValue();
points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
points[6][1] = -pDy2.getValue();
points[6][2] = pDz.getValue();
points[7][0] = pDx3.getValue()-pDy2.getValue()*Talp2;
points[7][1] = -pDy2.getValue();
points[7][2] = pDz.getValue();
int i;
for (i=0;i<4;i++) {
points[i][0] -= pDz.getValue()*TthetaCphi;
points[i][1] -= pDz.getValue()*TthetaSphi;
}
for (i=4;i<8;i++) {
points[i][0] += pDz.getValue()*TthetaCphi;
points[i][1] += pDz.getValue()*TthetaSphi;
}
for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
theFaceSet->coordIndex.setValues(0,NINDICES,indices);
theNormals->vector.deleteValues(0);
theNormals->vector.insertSpace(0,6);
for (int n=0;n<6;n++) {
int i0 = 5*n+0,i1=5*n+1,i2=5*n+2;
int j0 = theFaceSet->coordIndex[i0];
int j1 = theFaceSet->coordIndex[i1];
int j2 = theFaceSet->coordIndex[i2];
SbVec3f p0= theCoordinates->point[j0];
SbVec3f p1= theCoordinates->point[j1];
SbVec3f p2= theCoordinates->point[j2];
SbVec3f normal = (p1-p0).cross(p2-p0);
normal.normalize();
theNormals->vector.set1Value(n,normal);
}
theNormalBinding->value=SoNormalBinding::PER_FACE;
}
// generateChildren
void SoTrap::generateChildren() {
// This routines creates one SoSeparator, one SoCoordinate3, and
// one SoLineSet, and puts it in the child list. This is done only
// once, whereas redrawing the position of the coordinates occurs each
// time an update is necessary, in the updateChildren routine.
assert(children->getLength() ==0);
SoSeparator *sep = new SoSeparator();
SoCoordinate3 *theCoordinates = new SoCoordinate3();
SoNormal *theNormals = new SoNormal();
SoNormalBinding *theNormalBinding = new SoNormalBinding();
SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
//
// This line costs some in render quality! but gives speed.
//
sep->addChild(theCoordinates);
sep->addChild(theNormals);
sep->addChild(theNormalBinding);
sep->addChild(theFaceSet);
children->append(sep);
}
// generateAlternateRep
void SoTrap::generateAlternateRep() {
// This routine sets the alternate representation to the child
// list of this mode.
if (children->getLength() == 0) generateChildren();
updateChildren();
alternateRep.setValue((SoSeparator *) ( *children)[0]);
}
// clearAlternateRep
void SoTrap::clearAlternateRep() {
alternateRep.setValue(NULL);
}
@@ -0,0 +1,339 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: SoTrd.cc,v 1.2 2004/06/14 09:27:41 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*-----------------------------Hepvis---------------------------------------*/
/* */
/* Node: SoTrd */
/* Description: Represents the G4Trd Geant Geometry entity */
/* Author: Joe Boudreau Nov 11 1996 */
/* */
/*--------------------------------------------------------------------------*/
#include <assert.h>
#include <math.h>
#include <Inventor/SbBox.h>
#include <Inventor/actions/SoAction.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/misc/SoChildList.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/nodes/SoNormal.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoNormalBinding.h>
#include <Inventor/SoPrimitiveVertex.h>
#include <Inventor/elements/SoTextureCoordinateElement.h>
#include "HEPVis/SbMath.h"
#include "HEPVis/nodes/SoTrd.h"
// This statement is required
SO_NODE_SOURCE(SoTrd)
// initClass
void SoTrd::initClass(){
SO_NODE_INIT_CLASS(SoTrd,SoShape,"Shape");
}
// Constructor
SoTrd::SoTrd() {
// This statement is required
SO_NODE_CONSTRUCTOR(SoTrd);
// Data fields are initialized like this:
SO_NODE_ADD_FIELD(fDx1,(1.0));
SO_NODE_ADD_FIELD(fDx2,(1.0));
SO_NODE_ADD_FIELD(fDy1,(1.0));
SO_NODE_ADD_FIELD(fDy2,(1.0));
SO_NODE_ADD_FIELD(fDz,(1.0));
SO_NODE_ADD_FIELD(alternateRep,(NULL));
children = new SoChildList(this);
}
// Destructor
SoTrd::~SoTrd() {
delete children;
}
// generatePrimitives
void SoTrd::generatePrimitives(SoAction *action) {
// This variable is used to store each vertex
SoPrimitiveVertex pv;
// Access the stat from the action
SoState *state = action->getState();
// See if we have to use a texture coordinate function,
// rather than generating explicit texture coordinates.
SbBool useTexFunction=
(SoTextureCoordinateElement::getType(state) ==
SoTextureCoordinateElement::FUNCTION);
// If we need to generate texture coordinates with a function,
// we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
// set up the coordinates directly.
const SoTextureCoordinateElement *tce = NULL;
SbVec4f texCoord;
if (useTexFunction) {
tce = SoTextureCoordinateElement::getInstance(state);
}
else {
texCoord[2] = 0.0;
texCoord[3] = 1.0;
}
SbVec3f point, normal;
//////////////////////////////////////////
//----------------------------------------
#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
point.setValue(x,y,z); \
normal.setValue(nx,ny,nz); \
if (useTexFunction) { \
texCoord=tce->get(point,normal); \
} \
else { \
texCoord[0]=s; \
texCoord[1]=t; \
} \
pv.setPoint(point); \
pv.setNormal(normal); \
pv.setTextureCoords(texCoord); \
shapeVertex(&pv);
//----------------------------------------
//////////////////////////////////////////
const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, //z back.
4,5,6,7, SO_END_FACE_INDEX, //z front.
0,1,5,4, SO_END_FACE_INDEX, //y up.
1,2,6,5, SO_END_FACE_INDEX, //x left.
2,3,7,6, SO_END_FACE_INDEX, //y down.
3,0,4,7, SO_END_FACE_INDEX}; //x right.
// points for the eight vertices
float points[NPOINTS][3];
points[0][0] = fDx1.getValue();
points[0][1] = fDy1.getValue();
points[0][2] = -fDz.getValue();
points[1][0] = -fDx1.getValue();
points[1][1] = fDy1.getValue();
points[1][2] = -fDz.getValue();
points[2][0] = -fDx1.getValue();
points[2][1] = -fDy1.getValue();
points[2][2] = -fDz.getValue();
points[3][0] = fDx1.getValue();
points[3][1] = -fDy1.getValue();
points[3][2] = -fDz.getValue();
points[4][0] = fDx2.getValue();
points[4][1] = fDy2.getValue();
points[4][2] = fDz.getValue();
points[5][0] = -fDx2.getValue();
points[5][1] = fDy2.getValue();
points[5][2] = fDz.getValue();
points[6][0] = -fDx2.getValue();
points[6][1] = -fDy2.getValue();
points[6][2] = fDz.getValue();
points[7][0] = fDx2.getValue();
points[7][1] = -fDy2.getValue();
points[7][2] = fDz.getValue();
float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
float st1 = FSIN(t1);
float st2 = FSIN(t2);
float ct1 = FCOS(t1);
float ct2 = FCOS(t2);
float normals[NFACES][3];
//z back.
normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
//z front.
normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
//y up.
normals[2][0] = 0 ; normals[2][1] = ct2; normals [2][2] = -st2;
//x left.
normals[3][0] = -ct1; normals[3][1] = 0; normals [3][2] = -st1;
//y down.
normals[4][0] = 0 ; normals[4][1] = -ct2; normals [4][2] = -st2;
//x right.
normals[5][0] = ct1; normals[5][1] = 0; normals [5][2] = -st1;
float x,y,z;
int index;
for (int nf=0;nf<NFACES;nf++) {
beginShape(action,TRIANGLE_FAN);
index = indices[nf * 5];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 1];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 2];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
index = indices[nf * 5 + 3];
x = points[index][0];
y = points[index][1];
z = points[index][2];
GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);
endShape();
}
}
// getChildren
SoChildList *SoTrd::getChildren() const {
return children;
}
// computeBBox
void SoTrd::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
float fDx= fDx1.getValue(),fDy=fDy1.getValue();
if (fDx2.getValue() > fDx) fDx = fDx2.getValue();
if (fDy2.getValue() > fDy) fDy = fDy2.getValue();
SbVec3f vmin(-fDx,-fDy,-fDz.getValue()),
vmax( fDx, fDy, fDz.getValue());
center.setValue(0,0,0);
box.setBounds(vmin,vmax);
}
// updateChildren
void SoTrd::updateChildren() {
// Redraw the G4Trd....
assert(children->getLength()==1);
SoSeparator *sep = (SoSeparator *) ( *children)[0];
SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
float points[NPOINTS][3];
float normals[NFACES][3]= {{0,0,-1}, {0,0,1}, {0,1,0}, {-1, 0, 0}, {0, -1, 0}, {1,0,0}};
// Indices for the eight faces
#ifdef INVENTOR2_0
static long
#else
static int32_t
#endif
indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, // bottom
4,5,6,7, SO_END_FACE_INDEX, // top
0,1,5,4, SO_END_FACE_INDEX,
1,2,6,5, SO_END_FACE_INDEX,
2,3,7,6, SO_END_FACE_INDEX,
3,0,4,7, SO_END_FACE_INDEX};
// points for the eight vertices
points[0][0] = fDx1.getValue(); points[0][1] = fDy1.getValue(); points[0][2] = -fDz.getValue();
points[1][0] = -fDx1.getValue(); points[1][1] = fDy1.getValue(); points[1][2] = -fDz.getValue();
points[2][0] = -fDx1.getValue(); points[2][1] = -fDy1.getValue(); points[2][2] = -fDz.getValue();
points[3][0] = fDx1.getValue(); points[3][1] = -fDy1.getValue(); points[3][2] = -fDz.getValue();
points[4][0] = fDx2.getValue(); points[4][1] = fDy2.getValue(); points[4][2] = fDz.getValue();
points[5][0] = -fDx2.getValue(); points[5][1] = fDy2.getValue(); points[5][2] = fDz.getValue();
points[6][0] = -fDx2.getValue(); points[6][1] = -fDy2.getValue(); points[6][2] = fDz.getValue();
points[7][0] = fDx2.getValue(); points[7][1] = -fDy2.getValue(); points[7][2] = fDz.getValue();
float t1 = FATAN((fDx2.getValue()-fDx1.getValue())/(2*fDz.getValue()));
float t2 = FATAN((fDy2.getValue()-fDy1.getValue())/(2*fDz.getValue()));
float st1 = FSIN(t1);
float st2 = FSIN(t2);
float ct1 = FCOS(t1);
float ct2 = FCOS(t2);
normals[0][0] = 0 ; normals[0][1] = 0; normals [0][2] = -1;
normals[1][0] = 0 ; normals[1][1] = 0; normals [1][2] = 1;
normals[2][0] = 0 ; normals[2][1] = ct2; normals [2][2] = -st2;
normals[3][0] = -ct1; normals[3][1] = 0; normals [3][2] = -st1;
normals[4][0] = 0 ; normals[4][1] = -ct2; normals [4][2] = -st2;
normals[5][0] = ct1; normals[5][1] = 0; normals [5][2] = -st1;
for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
theFaceSet->coordIndex.setValues(0,NINDICES,indices);
for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
theNormalBinding->value=SoNormalBinding::PER_FACE;
}
// generateChildren
void SoTrd::generateChildren() {
// This routines creates one SoSeparator, one SoCoordinate3, and
// one SoLineSet, and puts it in the child list. This is done only
// once, whereas redrawing the position of the coordinates occurs each
// time an update is necessary, in the updateChildren routine.
assert(children->getLength() ==0);
SoSeparator *sep = new SoSeparator();
SoCoordinate3 *theCoordinates = new SoCoordinate3();
SoNormal *theNormals = new SoNormal();
SoNormalBinding *theNormalBinding = new SoNormalBinding();
SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
//
// This line costs some in render quality! but gives speed.
//
sep->addChild(theCoordinates);
sep->addChild(theNormals);
sep->addChild(theNormalBinding);
sep->addChild(theFaceSet);
children->append(sep);
}
// generateAlternateRep
void SoTrd::generateAlternateRep() {
// This routine sets the alternate representation to the child
// list of this mode.
if (children->getLength() == 0) generateChildren();
updateChildren();
alternateRep.setValue((SoSeparator *) ( *children)[0]);
}
// clearAlternateRep
void SoTrd::clearAlternateRep() {
alternateRep.setValue(NULL);
}
@@ -0,0 +1,462 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: SoTubs.cc,v 1.2 2004/06/14 09:27:41 gcosmo Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
/*-----------------------------Hepvis---------------------------------------*/
/* */
/* Node: SoTubs */
/* Description: Represents the G4Tubs Geant Geometry entity */
/* Author: Joe Boudreau Nov 11 1996 */
/* */
/*--------------------------------------------------------------------------*/
#include <assert.h>
#include <math.h>
#include <Inventor/SbBox.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/fields/SoSFFloat.h>
#include <Inventor/misc/SoChildList.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/nodes/SoNormal.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoNormalBinding.h>
#include <Inventor/SoPrimitiveVertex.h>
#include <Inventor/elements/SoTextureCoordinateElement.h>
#include "HEPVis/SbMath.h"
#include "HEPVis/nodes/SoTubs.h"
// This statement is required
SO_NODE_SOURCE(SoTubs)
// Constructor
SoTubs::SoTubs() {
// This statement is required
SO_NODE_CONSTRUCTOR(SoTubs);
// Data fields are initialized like this:
SO_NODE_ADD_FIELD(pRMin, (0));
SO_NODE_ADD_FIELD(pRMax, (1));
SO_NODE_ADD_FIELD(pDz, (10));
SO_NODE_ADD_FIELD(pSPhi, (0));
SO_NODE_ADD_FIELD(pDPhi, ((float)(2*M_PI)));
SO_NODE_ADD_FIELD(alternateRep, (NULL));
children = new SoChildList(this);
}
// Destructor
SoTubs::~SoTubs() {
delete children;
}
// initClass
void SoTubs::initClass(){
// This statement is required.
SO_NODE_INIT_CLASS(SoTubs,SoShape,"Shape");
}
// generatePrimitives
void SoTubs::generatePrimitives(SoAction *action) {
// This variable is used to store each vertex
SoPrimitiveVertex pv;
// Access the stat from the action
SoState *state = action->getState();
// See if we have to use a texture coordinate function,
// rather than generating explicit texture coordinates.
SbBool useTexFunction=
(SoTextureCoordinateElement::getType(state) ==
SoTextureCoordinateElement::FUNCTION);
// If we need to generate texture coordinates with a function,
// we'll need an SoGLTextureCoordinateElement. Otherwise, we'll
// set up the coordinates directly.
const SoTextureCoordinateElement* tce = NULL;
SbVec4f texCoord;
if (useTexFunction) {
tce = SoTextureCoordinateElement::getInstance(state);
}
else {
texCoord[2] = 0.0;
texCoord[3] = 1.0;
}
SbVec3f point, normal;
///////////////////////////////////////////////////////
//-----------------------------------------------------
#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz) \
point.setValue((float)(x),(float)(y),(float)(z)); \
normal.setValue((float)(nx),(float)(ny),(float)(nz)); \
if (useTexFunction) { \
texCoord=tce->get(point,normal); \
} else { \
texCoord[0]=(float)(s); \
texCoord[1]=(float)(t); \
} \
pv.setPoint(point); \
pv.setNormal(normal); \
pv.setTextureCoords(texCoord); \
shapeVertex(&pv);
//-----------------------------------------------------
///////////////////////////////////////////////////////
int NPHI = (int)(2+22*fabs(pDPhi.getValue()/(2.0*M_PI)));
double deltaPhi = pDPhi.getValue()/NPHI, phi0 = pSPhi.getValue(),phi1=phi0+pDPhi.getValue();
double rMax=pRMax.getValue(),rMin=pRMin.getValue();
double zMax=pDz.getValue(),zMin=-zMax;
double cosPhi0=cos(phi0), sinPhi0=sin(phi0);
double cosPhi1=cos(phi1), sinPhi1=sin(phi1);
double cosDeltaPhi=cos(deltaPhi),sinDeltaPhi=sin(deltaPhi);
//
// The outer surface!
//
int i;
double sinPhi,cosPhi;
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,cosPhi,sinPhi,0);
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,cosPhi,sinPhi,0);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
//
// The inner surface!
//
if(rMin!=0.F) {
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,-cosPhi,-sinPhi,0);
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,1.0,1.0,-cosPhi,-sinPhi,0);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
}
if (fabs(deltaPhi)<2.0*M_PI) {
//
// The end
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,0.0,0.0,sinPhi,-cosPhi,0);
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,sinPhi,-cosPhi,0);
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,1.0,0.0,sinPhi,-cosPhi,0);
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,1.0,sinPhi,-cosPhi,0);
endShape();
//
// The other end
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi1;
cosPhi=cosPhi1;
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi, zMax,0.0,0.0,-sinPhi,+cosPhi,0);
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi, zMin,1.0,1.0,-sinPhi,+cosPhi,0);
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi, zMax,1.0,0.0,-sinPhi,+cosPhi,0);
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi, zMin,0.0,1.0,-sinPhi,+cosPhi,0);
endShape();
}
//
// The outer surface at z=+PDZ
//
if(rMin==0.F) {
beginShape(action,TRIANGLE_FAN);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
GEN_VERTEX(pv,0,0,zMax,0.0,0.0,0,0,1);
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
//
// The outer surface at z=-PDZ
//
beginShape(action,TRIANGLE_FAN);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
GEN_VERTEX(pv,0,0,zMin,0.0,0.0,0,0,-1);
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
} else {
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMax,0.0,0.0,0,0,1);
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMax,1.0,1.0,0,0,1);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
//
// The outer surface at z=-PDZ
//
beginShape(action,TRIANGLE_STRIP);
sinPhi=sinPhi0;
cosPhi=cosPhi0;
for (i = 0; i<=NPHI; i++) {
GEN_VERTEX(pv,rMin*cosPhi,rMin*sinPhi,zMin,0.0,0.0,0,0,-1);
GEN_VERTEX(pv,rMax*cosPhi,rMax*sinPhi,zMin,1.0,1.0,0,0,-1);
inc(sinPhi, cosPhi, sinDeltaPhi, cosDeltaPhi);
}
endShape();
}
}
// getChildren
SoChildList *SoTubs::getChildren() const {
return children;
}
// computeBBox
void SoTubs::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
SbVec3f vmin(-pRMax.getValue(),-pRMax.getValue(),-pDz.getValue()),
vmax( pRMax.getValue(), pRMax.getValue(), pDz.getValue());
center.setValue(0,0,0);
box.setBounds(vmin,vmax);
}
// updateChildren
void SoTubs::updateChildren() {
// Redraw the G4Tubs....
assert(children->getLength()==1);
SoSeparator *sep = (SoSeparator *) ( *children)[0];
SoCoordinate3 *theCoordinates = (SoCoordinate3 *) ( sep->getChild(0));
SoNormal *theNormals = (SoNormal *) ( sep->getChild(1));
SoNormalBinding *theNormalBinding = (SoNormalBinding *) ( sep->getChild(2));
SoIndexedFaceSet *theFaceSet = (SoIndexedFaceSet *) ( sep->getChild(3));
const int NPHI=24, NPOINTS=2*(2*NPHI+2), NFACES=4*NPHI+2, NINDICES = NFACES*5;
float points[NPOINTS][3],normals[NFACES][3];
#ifdef INVENTOR2_0
static long indices[NINDICES];
#else
static int32_t indices[NINDICES];
#endif
static int init=0;
double phi, pp, DeltaPhi;
// Indices need to be generated once! This is here to keep it close to the point
// generation, since otherwise it will be confusing.
int i;
if (!init) {
init = 1;
// Outer face
for (i = 0; i< NPHI; i++) {
// 0 1 3 2;
indices[5*i+0] = 2*i+0;
indices[5*i+1] = 2*i+1;
indices[5*i+2] = 2*i+3;
indices[5*i+3] = 2*i+2;
indices[5*i+4] = SO_END_FACE_INDEX;
}
// the inner face
for (i=0;i<NPHI;i++) {
indices[5*1*NPHI + 5*i+0] = 2*NPHI+2 + 2*i+0;
indices[5*1*NPHI + 5*i+1] = 2*NPHI+2 + 2*i+1;
indices[5*1*NPHI + 5*i+2] = 2*NPHI+2 + 2*i+3;
indices[5*1*NPHI + 5*i+3] = 2*NPHI+2 + 2*i+2;
indices[5*1*NPHI + 5*i+4] = SO_END_FACE_INDEX;
}
// the top side
for (i=0;i<NPHI;i++) {
indices[5*2*NPHI + 5*i+0] = 2*i+0;
indices[5*2*NPHI + 5*i+1] = 2*i+2;
indices[5*2*NPHI + 5*i+2] = NPOINTS - (2*i+4);
indices[5*2*NPHI + 5*i+3] = NPOINTS - (2*i+2);
indices[5*2*NPHI + 5*i+4] = SO_END_FACE_INDEX;
}
// the bottom side
for (i=0;i<NPHI;i++) {
indices[5*3*NPHI + 5*i+0] = 2*i+1;
indices[5*3*NPHI + 5*i+1] = NPOINTS - (2*i+1);
indices[5*3*NPHI + 5*i+2] = NPOINTS - (2*i+3);
indices[5*3*NPHI + 5*i+3] = 2*i+3;
indices[5*3*NPHI + 5*i+4] = SO_END_FACE_INDEX;
}
// the odd side
indices[5*4*NPHI +0] = 2*NPHI;
indices[5*4*NPHI +1] = 2*NPHI+1;
indices[5*4*NPHI +2] = 2*NPHI+3;
indices[5*4*NPHI +3] = 2*NPHI+2;
indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
// aother odd side
indices[5*4*NPHI +5 +0] = 0;
indices[5*4*NPHI +5 +1] = NPOINTS-2;
indices[5*4*NPHI +5 +2] = NPOINTS-1;
indices[5*4*NPHI +5 +3] = 1;
indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
}
// Points need to be generated each time:
if (pDPhi.getValue()<2*M_PI) {
// the odd side
indices[5*4*NPHI +0] = 2*NPHI;
indices[5*4*NPHI +1] = 2*NPHI+1;
indices[5*4*NPHI +2] = 2*NPHI+3;
indices[5*4*NPHI +3] = 2*NPHI+2;
indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
// aother odd side
indices[5*4*NPHI +5 +0] = 0;
indices[5*4*NPHI +5 +1] = NPOINTS-2;
indices[5*4*NPHI +5 +2] = NPOINTS-1;
indices[5*4*NPHI +5 +3] = 1;
indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
}
else {
// the odd side
indices[5*4*NPHI +0] = SO_END_FACE_INDEX;
indices[5*4*NPHI +1] = SO_END_FACE_INDEX;
indices[5*4*NPHI +2] = SO_END_FACE_INDEX;
indices[5*4*NPHI +3] = SO_END_FACE_INDEX;
indices[5*4*NPHI +4] = SO_END_FACE_INDEX;
// aother odd side
indices[5*4*NPHI +5 +0] = SO_END_FACE_INDEX;
indices[5*4*NPHI +5 +1] = SO_END_FACE_INDEX;
indices[5*4*NPHI +5 +2] = SO_END_FACE_INDEX;
indices[5*4*NPHI +5 +3] = SO_END_FACE_INDEX;
indices[5*4*NPHI +5 +4] = SO_END_FACE_INDEX;
}
// The outer surface
DeltaPhi = pDPhi.getValue()/NPHI, phi = pSPhi.getValue();
for (i = 0; i<=NPHI; i++) {
points[2*i+0][0] = pRMax.getValue()*FCOS(phi);
points[2*i+0][1]= pRMax.getValue()*FSIN(phi);
points[2*i+0][2] = +pDz.getValue();
points[2*i+1][0] = pRMax.getValue()*FCOS(phi);
points[2*i+1][1]= pRMax.getValue()*FSIN(phi);
points[2*i+1][2] = -pDz.getValue();
pp = phi+DeltaPhi/2.0;
if (i!=NPHI) {
normals[i][0] = FCOS(pp);
normals[i][1] = FSIN(pp);
normals[i][2] = 0;
}
phi+=DeltaPhi;
}
// The inner surface
phi = pSPhi.getValue() + pDPhi.getValue();
for (i = 0; i<=NPHI; i++) {
points[2*NPHI+2+2*i+0][0] = pRMin.getValue()*FCOS(phi);
points[2*NPHI+2+2*i+0][1] = pRMin.getValue()*FSIN(phi);
points[2*NPHI+2+2*i+0][2] = +pDz.getValue();
points[2*NPHI+2+2*i+1][0] = pRMin.getValue()*FCOS(phi);
points[2*NPHI+2+2*i+1][1] = pRMin.getValue()*FSIN(phi);
points[2*NPHI+2+2*i+1][2] = -pDz.getValue();
pp = phi-DeltaPhi/2.0;
if (i!=NPHI) {
normals[NPHI+i][0] = -FCOS(pp);
normals[NPHI+i][1] = -FSIN(pp);
normals[NPHI+i][2] = 0;
}
phi-=DeltaPhi;
}
// The top side
for (i=0;i<NPHI;i++) {
normals[2*NPHI+i][0]=normals[2*NPHI+i][1]=0;
normals[2*NPHI+i][2]= 1.0;
}
// The bottom side
for (i=0;i<NPHI;i++) {
normals[3*NPHI+i][0]=normals[3*NPHI+i][1]=0;
normals[3*NPHI+i][2]= -1.0;
}
// The odd side
phi = pSPhi.getValue();
normals[4*NPHI+0][0]= FSIN(phi);
normals[4*NPHI+0][1]= -FCOS(phi);
normals[4*NPHI+0][2]=0;
// Another odd side
phi = pSPhi.getValue()+pDPhi.getValue();
normals[4*NPHI+1][0]= -FSIN(phi);
normals[4*NPHI+1][1]= +FCOS(phi);
normals[4*NPHI+1][2]=0;
for (int np=0;np<NPOINTS; np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
for (int ni=0;ni<NINDICES;ni++) theFaceSet->coordIndex.set1Value(ni,indices[ni]);
for (int nf=0;nf<NFACES;nf++) theNormals->vector.set1Value(nf,normals[nf][0],normals[nf][1],normals[nf][2]);
theNormalBinding->value=SoNormalBinding::PER_FACE;
}
// generateChildren
void SoTubs::generateChildren() {
// This routines creates one SoSeparator, one SoCoordinate3, and
// one SoLineSet, and puts it in the child list. This is done only
// once, whereas redrawing the position of the coordinates occurs each
// time an update is necessary, in the updateChildren routine.
assert(children->getLength() ==0);
SoSeparator *sep = new SoSeparator();
SoCoordinate3 *theCoordinates = new SoCoordinate3();
SoNormal *theNormals = new SoNormal();
SoNormalBinding *theNormalBinding = new SoNormalBinding();
SoIndexedFaceSet *theFaceSet = new SoIndexedFaceSet();
//
// This line costs some in render quality! but gives speed.
//
sep->addChild(theCoordinates);
sep->addChild(theNormals);
sep->addChild(theNormalBinding);
sep->addChild(theFaceSet);
children->append(sep);
}
// generateAlternateRep
void SoTubs::generateAlternateRep() {
// This routine sets the alternate representation to the child
// list of this mode.
if (children->getLength() == 0) generateChildren();
updateChildren();
alternateRep.setValue((SoSeparator *) ( *children)[0]);
}
// clearAlternateRep
void SoTubs::clearAlternateRep() {
alternateRep.setValue(NULL);
}