Import Geant4 9.3.0 source tree
This commit is contained in:
@@ -24,8 +24,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4OpenGLViewer.cc,v 1.41 2008/10/24 13:49:19 lgarnier Exp $
|
||||
// GEANT4 tag $Name: geant4-09-02 $
|
||||
// $Id: G4OpenGLViewer.cc,v 1.59 2009/10/20 12:47:45 lgarnier Exp $
|
||||
// GEANT4 tag $Name: geant4-09-03 $
|
||||
//
|
||||
//
|
||||
// Andrew Walkden 27th March 1996
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "G4OpenGLViewer.hh"
|
||||
#include "G4OpenGLSceneHandler.hh"
|
||||
#include "G4OpenGLTransform3D.hh"
|
||||
#include "G4OpenGL2PSAction.hh"
|
||||
|
||||
#include "G4Scene.hh"
|
||||
#include "G4VisExtent.hh"
|
||||
@@ -47,43 +48,16 @@
|
||||
#include "G4Plane3D.hh"
|
||||
#include "G4AttHolder.hh"
|
||||
#include "G4AttCheck.hh"
|
||||
#include <sstream>
|
||||
|
||||
static const char* gouraudtriangleEPS[] =
|
||||
{
|
||||
"/bd{bind def}bind def /triangle { aload pop setrgbcolor aload pop 5 3",
|
||||
"roll 4 2 roll 3 2 roll exch moveto lineto lineto closepath fill } bd",
|
||||
"/computediff1 { 2 copy sub abs threshold ge {pop pop pop true} { exch 2",
|
||||
"index sub abs threshold ge { pop pop true} { sub abs threshold ge } ifelse",
|
||||
"} ifelse } bd /computediff3 { 3 copy 0 get 3 1 roll 0 get 3 1 roll 0 get",
|
||||
"computediff1 {true} { 3 copy 1 get 3 1 roll 1 get 3 1 roll 1 get",
|
||||
"computediff1 {true} { 3 copy 2 get 3 1 roll 2 get 3 1 roll 2 get",
|
||||
"computediff1 } ifelse } ifelse } bd /middlecolor { aload pop 4 -1 roll",
|
||||
"aload pop 4 -1 roll add 2 div 5 1 roll 3 -1 roll add 2 div 3 1 roll add 2",
|
||||
"div 3 1 roll exch 3 array astore } bd /gouraudtriangle { computediff3 { 4",
|
||||
"-1 roll aload 7 1 roll 6 -1 roll pop 3 -1 roll pop add 2 div 3 1 roll add",
|
||||
"2 div exch 3 -1 roll aload 7 1 roll exch pop 4 -1 roll pop add 2 div 3 1",
|
||||
"roll add 2 div exch 3 -1 roll aload 7 1 roll pop 3 -1 roll pop add 2 div 3",
|
||||
"1 roll add 2 div exch 7 3 roll 10 -3 roll dup 3 index middlecolor 4 1 roll",
|
||||
"2 copy middlecolor 4 1 roll 3 copy pop middlecolor 4 1 roll 13 -1 roll",
|
||||
"aload pop 17 index 6 index 15 index 19 index 6 index 17 index 6 array",
|
||||
"astore 10 index 10 index 14 index gouraudtriangle 17 index 5 index 17",
|
||||
"index 19 index 5 index 19 index 6 array astore 10 index 9 index 13 index",
|
||||
"gouraudtriangle 13 index 16 index 5 index 15 index 18 index 5 index 6",
|
||||
"array astore 12 index 12 index 9 index gouraudtriangle 17 index 16 index",
|
||||
"15 index 19 index 18 index 17 index 6 array astore 10 index 12 index 14",
|
||||
"index gouraudtriangle 18 {pop} repeat } { aload pop 5 3 roll aload pop 7 3",
|
||||
"roll aload pop 9 3 roll 4 index 6 index 4 index add add 3 div 10 1 roll 7",
|
||||
"index 5 index 3 index add add 3 div 10 1 roll 6 index 4 index 2 index add",
|
||||
"add 3 div 10 1 roll 9 {pop} repeat 3 array astore triangle } ifelse } bd",
|
||||
NULL
|
||||
};
|
||||
// GL2PS
|
||||
#include "Geant4_gl2ps.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
G4OpenGLViewer::G4OpenGLViewer (G4OpenGLSceneHandler& scene):
|
||||
G4VViewer (scene, -1),
|
||||
pointSize (0),
|
||||
print_colour (true),
|
||||
vectored_ps (true),
|
||||
fPrintColour (true),
|
||||
fVectoredPs (true),
|
||||
fOpenGLSceneHandler(scene),
|
||||
background (G4Colour(0.,0.,0.)),
|
||||
transparency_enabled (true),
|
||||
@@ -106,19 +80,26 @@ fDisplayLightFrontZ(0.),
|
||||
fDisplayLightFrontT(0.),
|
||||
fDisplayLightFrontRed(0.),
|
||||
fDisplayLightFrontGreen(1.),
|
||||
fDisplayLightFrontBlue(0.)
|
||||
fDisplayLightFrontBlue(0.),
|
||||
fPrintSizeX(-1),
|
||||
fPrintSizeY(-1),
|
||||
fPrintFilename ("G4OpenGL"),
|
||||
fPrintFilenameIndex(0),
|
||||
fPointSize (0),
|
||||
fSizeHasChanged(0)
|
||||
{
|
||||
// Make changes to view parameters for OpenGL...
|
||||
fVP.SetAutoRefresh(true);
|
||||
fDefaultVP.SetAutoRefresh(true);
|
||||
|
||||
fGL2PSAction = new G4OpenGL2PSAction();
|
||||
|
||||
// glClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
// glClearDepth (1.0);
|
||||
// glDisable (GL_BLEND);
|
||||
// glDisable (GL_LINE_SMOOTH);
|
||||
// glDisable (GL_POLYGON_SMOOTH);
|
||||
|
||||
strcpy (print_string, "G4OpenGL.eps");
|
||||
}
|
||||
|
||||
G4OpenGLViewer::~G4OpenGLViewer () {}
|
||||
@@ -130,9 +111,15 @@ void G4OpenGLViewer::InitializeGLView ()
|
||||
glDisable (GL_BLEND);
|
||||
glDisable (GL_LINE_SMOOTH);
|
||||
glDisable (GL_POLYGON_SMOOTH);
|
||||
|
||||
fWinSize_x = fVP.GetWindowSizeHintX();
|
||||
fWinSize_y = fVP.GetWindowSizeHintY();
|
||||
}
|
||||
|
||||
void G4OpenGLViewer::ClearView () {
|
||||
#ifdef G4DEBUG_VIS_OGL
|
||||
printf("G4OpenGLViewer::ClearView\n");
|
||||
#endif
|
||||
glClearColor (background.GetRed(),
|
||||
background.GetGreen(),
|
||||
background.GetBlue(),
|
||||
@@ -143,13 +130,88 @@ void G4OpenGLViewer::ClearView () {
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
glClear (GL_DEPTH_BUFFER_BIT);
|
||||
glClear (GL_STENCIL_BUFFER_BIT);
|
||||
#ifdef G4DEBUG_VIS_OGL
|
||||
printf("G4OpenGLViewer::ClearView flush\n");
|
||||
#endif
|
||||
glFlush ();
|
||||
}
|
||||
|
||||
|
||||
void G4OpenGLViewer::ResizeWindow(unsigned int aWidth, unsigned int aHeight) {
|
||||
if ((fWinSize_x != aWidth) || (fWinSize_y != aHeight)) {
|
||||
fWinSize_x = aWidth;
|
||||
fWinSize_y = aHeight;
|
||||
fSizeHasChanged = true;
|
||||
} else {
|
||||
fSizeHasChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the viewport of the scene
|
||||
* MAXIMUM SIZE is :
|
||||
* GLint dims[2];
|
||||
* glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
|
||||
*/
|
||||
void G4OpenGLViewer::ResizeGLView()
|
||||
{
|
||||
#ifdef G4DEBUG_VIS_OGL
|
||||
printf("G4OpenGLViewer::ResizeGLView %d %d\n",fWinSize_x,fWinSize_y);
|
||||
#endif
|
||||
// Check size
|
||||
GLint dims[2];
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
|
||||
if (fWinSize_x > (unsigned)dims[0]) {
|
||||
G4cerr << "Try to resize view greater than max X viewport dimension. Desired size "<<dims[0] <<" is resize to "<< dims[0] << G4endl;
|
||||
fWinSize_x = dims[0];
|
||||
}
|
||||
if (fWinSize_y > (unsigned)dims[1]) {
|
||||
G4cerr << "Try to resize view greater than max Y viewport dimension. Desired size "<<dims[0] <<" is resize to "<< dims[1] << G4endl;
|
||||
fWinSize_y = dims[1];
|
||||
}
|
||||
GLsizei side = fWinSize_x;
|
||||
if (fWinSize_y < fWinSize_x) side = fWinSize_y;
|
||||
|
||||
// SPECIAL CASE if fWinSize_x is even (69 for example)
|
||||
// Ex : X: 69 Y: 26
|
||||
// side = 26
|
||||
// width / 2 = 21,5
|
||||
// height / 2 = 0
|
||||
// Should be fixed to closed : 21 0 for ex
|
||||
// Then size must by change to :
|
||||
// X:68 Y: 26
|
||||
|
||||
// SPECIAL CASE
|
||||
if ((fWinSize_x - side)%2) {
|
||||
// fWinSize_x --;
|
||||
|
||||
side = fWinSize_x;
|
||||
if (fWinSize_y < fWinSize_x) side = fWinSize_y;
|
||||
}
|
||||
if ((fWinSize_y - side)%2) {
|
||||
// fWinSize_y --;
|
||||
|
||||
side = fWinSize_x;
|
||||
if (fWinSize_y < fWinSize_x) side = fWinSize_y;
|
||||
}
|
||||
|
||||
GLint X = (fWinSize_x - side) / 2;
|
||||
GLint Y = (fWinSize_y - side) / 2;
|
||||
|
||||
#ifdef G4DEBUG_VIS_OGL
|
||||
printf("G4OpenGLViewer::ResizeGLView X:%d Y:%d W:%d H:%d --side%d\n",(fWinSize_x - side) / 2,(fWinSize_y - side) / 2,fWinSize_x,fWinSize_y,side);
|
||||
#endif
|
||||
glViewport(X, Y, side, side);
|
||||
// glViewport(0, 0, fWinSize_x,fWinSize_y);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4OpenGLViewer::SetView () {
|
||||
|
||||
if (!fSceneHandler.GetScene()) {
|
||||
G4cerr << "G4OpenGLStoredQtViewer: Creating a Viewer without a scene is not allowed. \nPlease use /vis/scene/create before /vis/open/.... "
|
||||
G4cerr << "G4OpenGLStoredViewer: Creating a Viewer without a scene is not allowed. \nPlease use /vis/scene/create before /vis/open/.... "
|
||||
<< G4endl;
|
||||
return;
|
||||
}
|
||||
@@ -180,26 +242,30 @@ void G4OpenGLViewer::SetView () {
|
||||
const G4double cameraDistance = fVP.GetCameraDistance (radius);
|
||||
const G4Point3D cameraPosition =
|
||||
targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
|
||||
const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
|
||||
const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
|
||||
const GLdouble pnear = fVP.GetNearDistance (cameraDistance, radius);
|
||||
const GLdouble pfar = fVP.GetFarDistance (cameraDistance, pnear, radius);
|
||||
const GLdouble right = fVP.GetFrontHalfHeight (pnear, radius);
|
||||
const GLdouble left = -right;
|
||||
const GLdouble bottom = left;
|
||||
const GLdouble top = right;
|
||||
|
||||
// FIXME
|
||||
ResizeGLView();
|
||||
//SHOULD SetWindowsSizeHint()...
|
||||
|
||||
glMatrixMode (GL_PROJECTION); // set up Frustum.
|
||||
glLoadIdentity();
|
||||
|
||||
const G4Vector3D scale = fVP.GetScaleFactor();
|
||||
glScaled(scale.x(),scale.y(),scale.z());
|
||||
const G4Vector3D scaleFactor = fVP.GetScaleFactor();
|
||||
glScaled(scaleFactor.x(),scaleFactor.y(),scaleFactor.z());
|
||||
|
||||
if (fVP.GetFieldHalfAngle() == 0.) {
|
||||
glOrtho (left, right, bottom, top, pnear, pfar);
|
||||
}
|
||||
else {
|
||||
glFrustum (left, right, bottom, top, pnear, pfar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glMatrixMode (GL_MODELVIEW); // apply further transformations to scene.
|
||||
glLoadIdentity();
|
||||
|
||||
@@ -216,7 +282,7 @@ void G4OpenGLViewer::SetView () {
|
||||
gluLookAt (pCamera.x(), pCamera.y(), pCamera.z(), // Viewpoint.
|
||||
gltarget.x(), gltarget.y(), gltarget.z(), // Target point.
|
||||
upVector.x(), upVector.y(), upVector.z()); // Up vector.
|
||||
|
||||
|
||||
// Light position is "true" light direction, so must come after gluLookAt.
|
||||
glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
|
||||
|
||||
@@ -371,359 +437,296 @@ void G4OpenGLViewer::Pick(GLdouble x, GLdouble y)
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void G4OpenGLViewer::print() {
|
||||
|
||||
// Print vectored PostScript
|
||||
|
||||
G4int size = 5000000;
|
||||
GLfloat* feedback_buffer = new GLfloat[size];
|
||||
glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
|
||||
glRenderMode (GL_FEEDBACK);
|
||||
|
||||
DrawView();
|
||||
|
||||
GLint returned;
|
||||
returned = glRenderMode (GL_RENDER);
|
||||
|
||||
GLubyte* G4OpenGLViewer::grabPixels (int inColor, unsigned int width, unsigned int height) {
|
||||
|
||||
FILE* file;
|
||||
if (print_string) {
|
||||
file = fopen (print_string, "w");
|
||||
if (file) {
|
||||
spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
|
||||
} else {
|
||||
printf("Could not open %s\n", print_string);
|
||||
}
|
||||
GLubyte* buffer;
|
||||
GLint swapbytes, lsbfirst, rowlength;
|
||||
GLint skiprows, skippixels, alignment;
|
||||
GLenum format;
|
||||
int size;
|
||||
|
||||
if (inColor) {
|
||||
format = GL_RGB;
|
||||
size = width*height*3;
|
||||
} else {
|
||||
printBuffer (returned, feedback_buffer);
|
||||
format = GL_LUMINANCE;
|
||||
size = width*height*1;
|
||||
}
|
||||
|
||||
delete[] feedback_buffer;
|
||||
}
|
||||
buffer = new GLubyte[size];
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
void G4OpenGLViewer::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer)
|
||||
{
|
||||
G4int i;
|
||||
glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
|
||||
glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
|
||||
glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
|
||||
|
||||
printf(" ");
|
||||
for (i = 0; i < 7; i++) {
|
||||
printf("%4.2f ", buffer[size - (*count)]);
|
||||
*count = *count - 1;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
|
||||
glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
|
||||
glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
|
||||
|
||||
void G4OpenGLViewer::spewWireframeEPS (FILE* file, GLint size, GLfloat* buffer, const char* cr) {
|
||||
glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
GLfloat EPS_GOURAUD_THRESHOLD=0.1;
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
GLfloat clearColor[4], viewport[4];
|
||||
GLfloat lineWidth;
|
||||
G4int i;
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels (0, 0, (GLsizei)width, (GLsizei)height, format, GL_UNSIGNED_BYTE, (GLvoid*) buffer);
|
||||
|
||||
glGetFloatv (GL_VIEWPORT, viewport);
|
||||
glGetFloatv (GL_COLOR_CLEAR_VALUE, clearColor);
|
||||
glGetFloatv (GL_LINE_WIDTH, &lineWidth);
|
||||
glGetFloatv (GL_POINT_SIZE, &pointSize);
|
||||
|
||||
fputs ("%!PS-Adobe-2.0 EPSF-2.0\n", file);
|
||||
fprintf (file, "%%%%Creator: %s (using OpenGL feedback)\n", cr);
|
||||
fprintf (file, "%%%%BoundingBox: %g %g %g %g\n", viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
fputs ("%%EndComments\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("gsave\n", file);
|
||||
fputs ("\n", file);
|
||||
|
||||
fputs ("% the gouraudtriangle PostScript fragment below is free\n", file);
|
||||
fputs ("% written by Frederic Delhoume (delhoume@ilog.fr)\n", file);
|
||||
fprintf (file, "/threshold %g def\n", EPS_GOURAUD_THRESHOLD);
|
||||
for (i=0; gouraudtriangleEPS[i]; i++) {
|
||||
fprintf (file, "%s\n", gouraudtriangleEPS[i]);
|
||||
}
|
||||
|
||||
fprintf(file, "\n%g setlinewidth\n", lineWidth);
|
||||
glPixelStorei (GL_UNPACK_SWAP_BYTES, swapbytes);
|
||||
glPixelStorei (GL_UNPACK_LSB_FIRST, lsbfirst);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, rowlength);
|
||||
|
||||
fprintf (file, "%g %g %g setrgbcolor\n", clearColor[0], clearColor[1], clearColor[2]);
|
||||
fprintf (file, "%g %g %g %g rectfill\n\n", viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
|
||||
spewSortedFeedback (file, size, buffer);
|
||||
|
||||
fputs ("grestore\n\n", file);
|
||||
fputs ("showpage\n", file);
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void G4OpenGLViewer::printBuffer (GLint size, GLfloat* buffer) {
|
||||
|
||||
GLint count;
|
||||
G4int token, nvertices;
|
||||
|
||||
count=size;
|
||||
while(count) {
|
||||
token=G4int (buffer[size-count]);
|
||||
count--;
|
||||
switch (token) {
|
||||
|
||||
case GL_PASS_THROUGH_TOKEN:
|
||||
printf ("GL_PASS_THROUGH_TOKEN\n");
|
||||
printf (" %4.2f\n", buffer[size-count]);
|
||||
count--;
|
||||
break;
|
||||
|
||||
case GL_POINT_TOKEN:
|
||||
printf ("GL_POINT_TOKEN\n");
|
||||
print3DcolorVertex (size, &count, buffer);
|
||||
break;
|
||||
|
||||
case GL_LINE_TOKEN:
|
||||
printf ("GL_LINE_TOKEN\n");
|
||||
print3DcolorVertex (size, &count, buffer);
|
||||
print3DcolorVertex (size, &count, buffer);
|
||||
break;
|
||||
|
||||
case GL_LINE_RESET_TOKEN:
|
||||
printf ("GL_LINE_RESET_TOKEN\n");
|
||||
print3DcolorVertex (size, &count, buffer);
|
||||
print3DcolorVertex (size, &count, buffer);
|
||||
break;
|
||||
|
||||
case GL_POLYGON_TOKEN:
|
||||
printf ("GL_POLYGON_TOKEN\n");
|
||||
nvertices=G4int (buffer[size-count]);
|
||||
count--;
|
||||
for (; nvertices>0; nvertices--) {
|
||||
print3DcolorVertex (size, &count, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4float* G4OpenGLViewer::spewPrimitiveEPS (FILE* file, GLfloat* loc) {
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, skiprows);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, skippixels);
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
|
||||
|
||||
G4int token;
|
||||
G4int nvertices, i;
|
||||
GLfloat red, green, blue, intensity;
|
||||
G4int smooth;
|
||||
GLfloat dx, dy, dr, dg, db, absR, absG, absB, colormax;
|
||||
G4int steps;
|
||||
Feedback3Dcolor *vertex;
|
||||
GLfloat xstep(0.), ystep(0.), rstep(0.), gstep(0.), bstep(0.);
|
||||
GLfloat xnext(0.), ynext(0.), rnext(0.), gnext(0.), bnext(0.), distance(0.);
|
||||
|
||||
token=G4int (*loc);
|
||||
loc++;
|
||||
switch (token) {
|
||||
case GL_LINE_RESET_TOKEN:
|
||||
case GL_LINE_TOKEN:
|
||||
vertex=(Feedback3Dcolor*)loc;
|
||||
dr=vertex[1].red - vertex[0].red;
|
||||
dg=vertex[1].green - vertex[0].green;
|
||||
db=vertex[1].blue - vertex[0].blue;
|
||||
|
||||
if (!print_colour) {
|
||||
dr+=(dg+db);
|
||||
dr/=3.0;
|
||||
dg=dr;
|
||||
db=dr;
|
||||
}
|
||||
|
||||
if (dr!=0 || dg!=0 || db!=0) {
|
||||
dx=vertex[1].x - vertex[0].x;
|
||||
dy=vertex[1].y - vertex[0].y;
|
||||
distance=std::sqrt(dx*dx + dy*dy);
|
||||
|
||||
absR=std::fabs(dr);
|
||||
absG=std::fabs(dg);
|
||||
absB=std::fabs(db);
|
||||
|
||||
#define Max(a, b) (((a)>(b))?(a):(b))
|
||||
|
||||
#define EPS_SMOOTH_LINE_FACTOR 0.06
|
||||
|
||||
colormax=Max(absR, Max(absG, absB));
|
||||
steps=Max(1, G4int (colormax*distance*EPS_SMOOTH_LINE_FACTOR));
|
||||
|
||||
xstep=dx/steps;
|
||||
ystep=dy/steps;
|
||||
|
||||
rstep=dr/steps;
|
||||
gstep=dg/steps;
|
||||
bstep=db/steps;
|
||||
|
||||
xnext=vertex[0].x;
|
||||
ynext=vertex[0].y;
|
||||
rnext=vertex[0].red;
|
||||
gnext=vertex[0].green;
|
||||
bnext=vertex[0].blue;
|
||||
|
||||
if (!print_colour) {
|
||||
rnext+=(gnext+bnext);
|
||||
rnext/=3.0;
|
||||
gnext=rnext;
|
||||
bnext=rnext;
|
||||
}
|
||||
|
||||
xnext -= xstep/2.0;
|
||||
ynext -= ystep/2.0;
|
||||
rnext -= rstep/2.0;
|
||||
gnext -= gstep/2.0;
|
||||
bnext -= bstep/2.0;
|
||||
} else {
|
||||
steps=0;
|
||||
}
|
||||
if (print_colour) {
|
||||
fprintf (file, "%g %g %g setrgbcolor\n",
|
||||
vertex[0].red, vertex[0].green, vertex[0].blue);
|
||||
} else {
|
||||
intensity = (vertex[0].red + vertex[0].green + vertex[0].blue) / 3.0;
|
||||
fprintf (file, "%g %g %g setrgbcolor\n",
|
||||
intensity, intensity, intensity);
|
||||
}
|
||||
fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y);
|
||||
|
||||
for (i=0; i<steps; i++) {
|
||||
|
||||
xnext += xstep;
|
||||
ynext += ystep;
|
||||
rnext += rstep;
|
||||
gnext += gstep;
|
||||
bnext += bstep;
|
||||
|
||||
fprintf (file, "%g %g lineto stroke\n", xnext, ynext);
|
||||
fprintf (file, "%g %g %g setrgbcolor\n", rnext, gnext, bnext);
|
||||
fprintf (file, "%g %g moveto\n", xnext, ynext);
|
||||
}
|
||||
fprintf (file, "%g %g lineto stroke\n", vertex[1].x, vertex[1].y);
|
||||
|
||||
loc += 14;
|
||||
break;
|
||||
|
||||
case GL_POLYGON_TOKEN:
|
||||
nvertices = G4int (*loc);
|
||||
loc++;
|
||||
vertex=(Feedback3Dcolor*)loc;
|
||||
if (nvertices>0) {
|
||||
red=vertex[0].red;
|
||||
green=vertex[0].green;
|
||||
blue=vertex[0].blue;
|
||||
smooth=0;
|
||||
|
||||
if (!print_colour) {
|
||||
red+=(green+blue);
|
||||
red/=3.0;
|
||||
green=red;
|
||||
blue=red;
|
||||
}
|
||||
|
||||
if (print_colour) {
|
||||
for (i=1; i<nvertices; i++) {
|
||||
if (red!=vertex[i].red || green!=vertex[i].green || blue!=vertex[i].blue) {
|
||||
smooth=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=1; i<nvertices; i++) {
|
||||
intensity = vertex[i].red + vertex[i].green + vertex[i].blue;
|
||||
intensity/=3.0;
|
||||
if (red!=intensity) {
|
||||
smooth=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (smooth) {
|
||||
G4int triOffset;
|
||||
for (i=0; i<nvertices-2; i++) {
|
||||
triOffset = i*7;
|
||||
fprintf (file, "[%g %g %g %g %g %g]",
|
||||
vertex[0].x, vertex[i+1].x, vertex[i+2].x,
|
||||
vertex[0].y, vertex[i+1].y, vertex[i+2].y);
|
||||
if (print_colour) {
|
||||
fprintf (file, " [%g %g %g] [%g %g %g] [%g %g %g] gouraudtriangle\n",
|
||||
vertex[0].red, vertex[0].green, vertex[0].blue,
|
||||
vertex[i+1].red, vertex[i+1].green, vertex[i+1].blue,
|
||||
vertex[i+2].red, vertex[i+2].green, vertex[i+2].blue);
|
||||
} else {
|
||||
|
||||
intensity = vertex[0].red + vertex[0].green + vertex[0].blue;
|
||||
intensity/=3.0;
|
||||
fprintf (file, " [%g %g %g]", intensity, intensity, intensity);
|
||||
|
||||
intensity = vertex[1].red + vertex[1].green + vertex[1].blue;
|
||||
intensity/=3.0;
|
||||
fprintf (file, " [%g %g %g]", intensity, intensity, intensity);
|
||||
|
||||
intensity = vertex[2].red + vertex[2].green + vertex[2].blue;
|
||||
intensity/=3.0;
|
||||
fprintf (file, " [%g %g %g] gouraudtriangle\n", intensity, intensity, intensity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf (file, "newpath\n");
|
||||
fprintf (file, "%g %g %g setrgbcolor\n", red, green, blue);
|
||||
fprintf (file, "%g %g moveto\n", vertex[0].x, vertex[0].y);
|
||||
for (i=1; i<nvertices; i++) {
|
||||
fprintf (file, "%g %g lineto\n", vertex[i].x, vertex[i].y);
|
||||
}
|
||||
fprintf (file, "closepath fill\n\n");
|
||||
}
|
||||
}
|
||||
loc += nvertices*7;
|
||||
break;
|
||||
|
||||
case GL_POINT_TOKEN:
|
||||
vertex=(Feedback3Dcolor*)loc;
|
||||
if (print_colour) {
|
||||
fprintf (file, "%g %g %g setrgbcolor\n", vertex[0].red, vertex[0].green, vertex[0].blue);
|
||||
} else {
|
||||
intensity = vertex[0].red + vertex[0].green + vertex[0].blue;
|
||||
intensity/=3.0;
|
||||
fprintf (file, "%g %g %g setrgbcolor\n", intensity, intensity, intensity);
|
||||
}
|
||||
fprintf(file, "%g %g %g 0 360 arc fill\n\n", vertex[0].x, vertex[0].y, pointSize / 2.0);
|
||||
loc += 7; /* Each vertex element in the feedback
|
||||
buffer is 7 GLfloats. */
|
||||
break;
|
||||
default:
|
||||
/* XXX Left as an excersie to the reader. */
|
||||
static G4bool spewPrimitiveEPSWarned = false;
|
||||
if (!spewPrimitiveEPSWarned) {
|
||||
std::ostringstream oss;
|
||||
oss <<
|
||||
"Incomplete implementation. Unexpected token (" << token << ")."
|
||||
"\n (Seems to be caused by text.)";
|
||||
G4Exception("G4OpenGLViewer::spewPrimitiveEPS",
|
||||
"Unexpected token",
|
||||
JustWarning,
|
||||
oss.str().c_str());
|
||||
spewPrimitiveEPSWarned = true;
|
||||
}
|
||||
}
|
||||
return loc;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
typedef struct G4OpenGLViewerDepthIndex {
|
||||
GLfloat *ptr;
|
||||
GLfloat depth;
|
||||
} DepthIndex;
|
||||
void G4OpenGLViewer::printEPS() {
|
||||
bool res;
|
||||
#ifdef G4DEBUG_VIS_OGL
|
||||
printf("G4OpenGLViewer::printEPS file:%s Vec:%d Name:%s\n",getRealPrintFilename().c_str(),fVectoredPs,GetName().c_str());
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
int G4OpenGLViewercompare(const void *a, const void *b)
|
||||
{
|
||||
const DepthIndex *p1 = (DepthIndex *) a;
|
||||
const DepthIndex *p2 = (DepthIndex *) b;
|
||||
GLfloat diff = p2->depth - p1->depth;
|
||||
|
||||
if (diff > 0.0) {
|
||||
return 1;
|
||||
} else if (diff < 0.0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
// Change the LC_NUMERIC value in order to have "." separtor and not ","
|
||||
// This case is only useful for French, Canadien...
|
||||
char *oldLocale = strdup(setlocale(LC_NUMERIC,NULL));
|
||||
setlocale(LC_NUMERIC,"C");
|
||||
|
||||
if (fVectoredPs) {
|
||||
res = printVectoredEPS();
|
||||
} else {
|
||||
res = printNonVectoredEPS();
|
||||
}
|
||||
|
||||
// restore the local
|
||||
if (oldLocale) {
|
||||
setlocale(LC_NUMERIC,oldLocale);
|
||||
free(oldLocale);
|
||||
}
|
||||
|
||||
if (res == false) {
|
||||
G4cerr << "Error while saving file... "<<getRealPrintFilename().c_str()<< G4endl;
|
||||
} else {
|
||||
G4cout << "File "<<getRealPrintFilename().c_str()<<" has been saved " << G4endl;
|
||||
}
|
||||
|
||||
// increment index if necessary
|
||||
if ( fPrintFilenameIndex != -1) {
|
||||
fPrintFilenameIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool G4OpenGLViewer::printVectoredEPS() {
|
||||
return printGl2PS();
|
||||
}
|
||||
|
||||
bool G4OpenGLViewer::printNonVectoredEPS () {
|
||||
|
||||
int width = getRealPrintSizeX();
|
||||
int height = getRealPrintSizeY();
|
||||
|
||||
#ifdef G4DEBUG_VIS_OGL
|
||||
printf("G4OpenGLViewer::printNonVectoredEPS file:%s Vec:%d X:%d Y:%d col:%d\n",getRealPrintFilename().c_str(),fVectoredPs,width,height,fPrintColour);
|
||||
#endif
|
||||
FILE* fp;
|
||||
GLubyte* pixels;
|
||||
GLubyte* curpix;
|
||||
int components, pos, i;
|
||||
|
||||
pixels = grabPixels (fPrintColour, width, height);
|
||||
|
||||
if (pixels == NULL) {
|
||||
G4cerr << "Failed to get pixels from OpenGl viewport" << G4endl;
|
||||
return false;
|
||||
}
|
||||
if (fPrintColour) {
|
||||
components = 3;
|
||||
} else {
|
||||
components = 1;
|
||||
}
|
||||
std::string name = getRealPrintFilename();
|
||||
fp = fopen (name.c_str(), "w");
|
||||
if (fp == NULL) {
|
||||
G4cerr << "Can't open filename " << name.c_str() << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
|
||||
fprintf (fp, "%%%%Title: %s\n", name.c_str());
|
||||
fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
|
||||
fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
|
||||
fprintf (fp, "%%%%EndComments\n");
|
||||
fprintf (fp, "gsave\n");
|
||||
fprintf (fp, "/bwproc {\n");
|
||||
fprintf (fp, " rgbproc\n");
|
||||
fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
|
||||
fprintf (fp, " 5 -1 roll {\n");
|
||||
fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
|
||||
fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
|
||||
fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
|
||||
fprintf (fp, " { 2 1 roll } ifelse\n");
|
||||
fprintf (fp, " }forall\n");
|
||||
fprintf (fp, " pop pop pop\n");
|
||||
fprintf (fp, "} def\n");
|
||||
fprintf (fp, "systemdict /colorimage known not {\n");
|
||||
fprintf (fp, " /colorimage {\n");
|
||||
fprintf (fp, " pop\n");
|
||||
fprintf (fp, " pop\n");
|
||||
fprintf (fp, " /rgbproc exch def\n");
|
||||
fprintf (fp, " { bwproc } image\n");
|
||||
fprintf (fp, " } def\n");
|
||||
fprintf (fp, "} if\n");
|
||||
fprintf (fp, "/picstr %d string def\n", width * components);
|
||||
fprintf (fp, "%d %d scale\n", width, height);
|
||||
fprintf (fp, "%d %d %d\n", width, height, 8);
|
||||
fprintf (fp, "[%d 0 0 %d 0 0]\n", width, height);
|
||||
fprintf (fp, "{currentfile picstr readhexstring pop}\n");
|
||||
fprintf (fp, "false %d\n", components);
|
||||
fprintf (fp, "colorimage\n");
|
||||
|
||||
curpix = (GLubyte*) pixels;
|
||||
pos = 0;
|
||||
for (i = width*height*components; i>0; i--) {
|
||||
fprintf (fp, "%02hx ", *(curpix++));
|
||||
if (++pos >= 32) {
|
||||
fprintf (fp, "\n");
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
if (pos)
|
||||
fprintf (fp, "\n");
|
||||
|
||||
fprintf (fp, "grestore\n");
|
||||
fprintf (fp, "showpage\n");
|
||||
delete pixels;
|
||||
fclose (fp);
|
||||
|
||||
// Reset for next time (useful is size change)
|
||||
// fPrintSizeX = -1;
|
||||
// fPrintSizeY = -1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool G4OpenGLViewer::printGl2PS() {
|
||||
|
||||
int width = getRealPrintSizeX();
|
||||
int height = getRealPrintSizeY();
|
||||
|
||||
if (!fGL2PSAction) return false;
|
||||
|
||||
fGL2PSAction->setFileName(getRealPrintFilename().c_str());
|
||||
// try to resize
|
||||
int X = fWinSize_x;
|
||||
int Y = fWinSize_y;
|
||||
|
||||
fWinSize_x = width;
|
||||
fWinSize_y = height;
|
||||
ResizeGLView();
|
||||
if (fGL2PSAction->enableFileWriting()) {
|
||||
|
||||
// By default, we choose the line width (trajectories...)
|
||||
fGL2PSAction->setLineWidth(1);
|
||||
// By default, we choose the point size (markers...)
|
||||
fGL2PSAction->setPointSize(2);
|
||||
|
||||
DrawView ();
|
||||
fGL2PSAction->disableFileWriting();
|
||||
}
|
||||
|
||||
fWinSize_x = X;
|
||||
fWinSize_y = Y;
|
||||
ResizeGLView();
|
||||
|
||||
// Reset for next time (useful is size change)
|
||||
// fPrintSizeX = 0;
|
||||
// fPrintSizeY = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int G4OpenGLViewer::getWinWidth() {
|
||||
return fWinSize_x;
|
||||
}
|
||||
|
||||
unsigned int G4OpenGLViewer::getWinHeight() {
|
||||
return fWinSize_y;
|
||||
}
|
||||
|
||||
G4bool G4OpenGLViewer::sizeHasChanged() {
|
||||
return fSizeHasChanged;
|
||||
}
|
||||
|
||||
G4int G4OpenGLViewer::getRealPrintSizeX() {
|
||||
if (fPrintSizeX == -1) {
|
||||
return fWinSize_x;
|
||||
}
|
||||
GLint dims[2];
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
|
||||
if (fPrintSizeX > dims[0]){
|
||||
return dims[0];
|
||||
}
|
||||
if (fPrintSizeX < -1){
|
||||
return 0;
|
||||
}
|
||||
return fPrintSizeX;
|
||||
}
|
||||
|
||||
G4int G4OpenGLViewer::getRealPrintSizeY() {
|
||||
if (fPrintSizeY == -1) {
|
||||
return fWinSize_y;
|
||||
}
|
||||
GLint dims[2];
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
|
||||
if (fPrintSizeY > dims[1]){
|
||||
return dims[1];
|
||||
}
|
||||
if (fPrintSizeY < -1){
|
||||
return 0;
|
||||
}
|
||||
return fPrintSizeY;
|
||||
}
|
||||
|
||||
void G4OpenGLViewer::setPrintSize(G4int X, G4int Y) {
|
||||
fPrintSizeX = X;
|
||||
fPrintSizeY = Y;
|
||||
}
|
||||
|
||||
void G4OpenGLViewer::setPrintFilename(G4String name,G4bool inc) {
|
||||
if (name != "") {
|
||||
fPrintFilename = name;
|
||||
} else {
|
||||
fPrintFilename = "G4OpenGL"; // by default
|
||||
}
|
||||
if (inc) {
|
||||
fPrintFilenameIndex=0;
|
||||
} else {
|
||||
fPrintFilenameIndex=-1;
|
||||
}
|
||||
}
|
||||
|
||||
std::string G4OpenGLViewer::getRealPrintFilename() {
|
||||
std::string temp = fPrintFilename;
|
||||
if (fPrintFilenameIndex != -1) {
|
||||
temp += std::string("_");
|
||||
std::ostringstream os;
|
||||
os << fPrintFilenameIndex;
|
||||
std::string nb_str = os.str();
|
||||
temp += nb_str;
|
||||
}
|
||||
temp += ".eps";
|
||||
return temp;
|
||||
}
|
||||
|
||||
GLdouble G4OpenGLViewer::getSceneNearWidth()
|
||||
@@ -765,124 +768,12 @@ GLdouble G4OpenGLViewer::getSceneDepth()
|
||||
}
|
||||
|
||||
|
||||
void G4OpenGLViewer::spewSortedFeedback(FILE * file, GLint size, GLfloat * buffer)
|
||||
{
|
||||
int token;
|
||||
GLfloat *loc, *end;
|
||||
Feedback3Dcolor *vertex;
|
||||
GLfloat depthSum;
|
||||
int nprimitives, item;
|
||||
DepthIndex *prims;
|
||||
int nvertices, i;
|
||||
|
||||
end = buffer + size;
|
||||
|
||||
/* Count how many primitives there are. */
|
||||
nprimitives = 0;
|
||||
loc = buffer;
|
||||
while (loc < end) {
|
||||
token = int (*loc);
|
||||
loc++;
|
||||
switch (token) {
|
||||
case GL_LINE_TOKEN:
|
||||
case GL_LINE_RESET_TOKEN:
|
||||
loc += 14;
|
||||
nprimitives++;
|
||||
break;
|
||||
case GL_POLYGON_TOKEN:
|
||||
nvertices = int (*loc);
|
||||
loc++;
|
||||
loc += (7 * nvertices);
|
||||
nprimitives++;
|
||||
break;
|
||||
case GL_POINT_TOKEN:
|
||||
loc += 7;
|
||||
nprimitives++;
|
||||
break;
|
||||
default:
|
||||
/* XXX Left as an excersie to the reader. */
|
||||
static G4bool spewSortedFeedbackWarned = false;
|
||||
if (!spewSortedFeedbackWarned) {
|
||||
std::ostringstream oss;
|
||||
oss <<
|
||||
"Incomplete implementation. Unexpected token (" << token << ")."
|
||||
"\n (Seems to be caused by text.)";
|
||||
G4Exception("G4OpenGLViewer::spewSortedFeedback",
|
||||
"Unexpected token",
|
||||
JustWarning,
|
||||
oss.str().c_str());
|
||||
spewSortedFeedbackWarned = true;
|
||||
}
|
||||
nprimitives++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate an array of pointers that will point back at
|
||||
primitives in the feedback buffer. There will be one
|
||||
entry per primitive. This array is also where we keep the
|
||||
primitive's average depth. There is one entry per
|
||||
primitive in the feedback buffer. */
|
||||
prims = (DepthIndex *) malloc(sizeof(DepthIndex) * nprimitives);
|
||||
|
||||
item = 0;
|
||||
loc = buffer;
|
||||
while (loc < end) {
|
||||
prims[item].ptr = loc; /* Save this primitive's location. */
|
||||
token = int (*loc);
|
||||
loc++;
|
||||
switch (token) {
|
||||
case GL_LINE_TOKEN:
|
||||
case GL_LINE_RESET_TOKEN:
|
||||
vertex = (Feedback3Dcolor *) loc;
|
||||
depthSum = vertex[0].z + vertex[1].z;
|
||||
prims[item].depth = depthSum / 2.0;
|
||||
loc += 14;
|
||||
break;
|
||||
case GL_POLYGON_TOKEN:
|
||||
nvertices = int (*loc);
|
||||
loc++;
|
||||
vertex = (Feedback3Dcolor *) loc;
|
||||
depthSum = vertex[0].z;
|
||||
for (i = 1; i < nvertices; i++) {
|
||||
depthSum += vertex[i].z;
|
||||
}
|
||||
prims[item].depth = depthSum / nvertices;
|
||||
loc += (7 * nvertices);
|
||||
break;
|
||||
case GL_POINT_TOKEN:
|
||||
vertex = (Feedback3Dcolor *) loc;
|
||||
prims[item].depth = vertex[0].z;
|
||||
loc += 7;
|
||||
break;
|
||||
default:
|
||||
/* XXX Left as an excersie to the reader. */
|
||||
assert(1);
|
||||
}
|
||||
item++;
|
||||
}
|
||||
assert(item == nprimitives);
|
||||
|
||||
/* Sort the primitives back to front. */
|
||||
qsort(prims, nprimitives, sizeof(DepthIndex), G4OpenGLViewercompare);
|
||||
|
||||
/* Understand that sorting by a primitives average depth
|
||||
doesn't allow us to disambiguate some cases like self
|
||||
intersecting polygons. Handling these cases would require
|
||||
breaking up the primitives. That's too involved for this
|
||||
example. Sorting by depth is good enough for lots of
|
||||
applications. */
|
||||
|
||||
/* Emit the Encapsulated PostScript for the primitives in
|
||||
back to front order. */
|
||||
for (item = 0; item < nprimitives; item++) {
|
||||
(void) spewPrimitiveEPS(file, prims[item].ptr);
|
||||
}
|
||||
|
||||
free(prims);
|
||||
}
|
||||
|
||||
void G4OpenGLViewer::rotateScene(G4double dx, G4double dy,G4double deltaRotation)
|
||||
{
|
||||
if (!fSceneHandler.GetScene()) {
|
||||
return;
|
||||
}
|
||||
|
||||
G4Vector3D vp;
|
||||
G4Vector3D up;
|
||||
|
||||
Reference in New Issue
Block a user