Commit e2a154dd authored by Thomas White's avatar Thomas White
Browse files

Move POV-ray stuff to a new file

parent ac5c6c8b
......@@ -5,5 +5,6 @@ EXTRA_DIST = configure src/cell.h src/hdf5-file.h src/image.h \
data/displaywindow.ui src/dirax.h src/peaks.h src/index.h \
src/filters.h src/diffraction-gpu.h src/cl-utils.h \
data/defs.h src/parameters-lcls.tmp \
data/diffraction.cl data/sfac src/likelihood.h src/symmetry.h
data/diffraction.cl data/sfac src/likelihood.h src/symmetry.h \
src/povray.h
SUBDIRS = src data
......@@ -202,7 +202,8 @@ EXTRA_DIST = configure src/cell.h src/hdf5-file.h src/image.h \
data/displaywindow.ui src/dirax.h src/peaks.h src/index.h \
src/filters.h src/diffraction-gpu.h src/cl-utils.h \
data/defs.h src/parameters-lcls.tmp \
data/diffraction.cl data/sfac src/likelihood.h src/symmetry.h
data/diffraction.cl data/sfac src/likelihood.h src/symmetry.h \
src/povray.h
SUBDIRS = src data
all: config.h
......
......@@ -46,7 +46,7 @@ powder_plot_SOURCES = powder_plot.c cell.c utils.c image.c hdf5-file.c \
detector.c
powder_plot_LDADD = @LIBS@
render_hkl_SOURCES = render_hkl.c cell.c reflections.c utils.c
render_hkl_SOURCES = render_hkl.c cell.c reflections.c utils.c povray.c
render_hkl_LDADD = @LIBS@
calibrate_detector_SOURCES = calibrate_detector.c utils.c hdf5-file.c image.c \
......
......@@ -108,7 +108,7 @@ am_process_hkl_OBJECTS = process_hkl.$(OBJEXT) sfac.$(OBJEXT) \
process_hkl_OBJECTS = $(am_process_hkl_OBJECTS)
process_hkl_DEPENDENCIES =
am_render_hkl_OBJECTS = render_hkl.$(OBJEXT) cell.$(OBJEXT) \
reflections.$(OBJEXT) utils.$(OBJEXT)
reflections.$(OBJEXT) utils.$(OBJEXT) povray.$(OBJEXT)
render_hkl_OBJECTS = $(am_render_hkl_OBJECTS)
render_hkl_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
......@@ -261,7 +261,7 @@ powder_plot_SOURCES = powder_plot.c cell.c utils.c image.c hdf5-file.c \
detector.c
powder_plot_LDADD = @LIBS@
render_hkl_SOURCES = render_hkl.c cell.c reflections.c utils.c
render_hkl_SOURCES = render_hkl.c cell.c reflections.c utils.c povray.c
render_hkl_LDADD = @LIBS@
calibrate_detector_SOURCES = calibrate_detector.c utils.c hdf5-file.c image.c \
filters.c peaks.c detector.c cell.c diffraction.c \
......@@ -393,6 +393,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/likelihood.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pattern_sim.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peaks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/povray.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/powder_plot.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_hkl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reflections.Po@am__quote@
......
/*
* povray.c
*
* Invoke POV-ray
*
* (c) 2006-2010 Thomas White <taw@physics.org>
*
* Part of CrystFEL - crystallography with a FEL
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "cell.h"
#include "utils.h"
#define MAX_PROC (256)
int povray_render_animation(UnitCell *cell, double *ref,
unsigned int *c, unsigned int nproc)
{
FILE *fh;
double asx, asy, asz;
double bsx, bsy, bsz;
double csx, csy, csz;
pid_t pids[MAX_PROC];
float max;
int i;
signed int h, k, l;
if ( (nproc > MAX_PROC) || (nproc < 1) ) {
ERROR("Number of processes must be a number between 1 and %i\n",
MAX_PROC);
return 1;
}
fh = fopen("render.pov", "w");
fprintf(fh, "/* POV-Ray scene written by CrystFEL */\n\n");
fprintf(fh, "#include \"colors.inc\"\n");
fprintf(fh, "#include \"textures.inc\"\n\n");
fprintf(fh, "global_settings {\n");
fprintf(fh, " assumed_gamma 1.0\n");
fprintf(fh, " ambient_light 5.0\n");
fprintf(fh, "}\n\n");
/* First quarter */
fprintf(fh, "#if ( (clock >= 0) & (clock <= 124) )\n");
fprintf(fh, "camera { location <0.0, -3.0, 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
/* Second quarter */
fprintf(fh, "#if ( (clock >= 125) & (clock <= 249) )\n");
fprintf(fh, "camera { location <0.0,"
" -(2.0+cos(radians((clock-125)*(180/125)))), 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
/* Third quarter */
fprintf(fh, "#if ( (clock >= 250) & (clock <= 374) )\n");
fprintf(fh, "camera { location <0.0, -1.0, 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
/* Fourth quarter */
fprintf(fh, "#if ( (clock >= 375) & (clock <= 500) )\n");
fprintf(fh, "camera { location <0.0,"
" -(2.0+cos(radians((clock-375)*(180/125)+180))), 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
fprintf(fh, "light_source { <-3.0 -3.0 3.0> White }\n");
fprintf(fh, "light_source { <+3.0 -3.0 3.0> White }\n");
fprintf(fh, "light_source { <0.0, -3.0, 0.0> 2*White }\n");
fprintf(fh, "plane {z,-2.0 pigment { rgb <0.0, 0.0, 0.1> } }\n");
fprintf(fh, "plane {-z,-2.0 pigment { rgb <0.0, 0.0, 0.05> } }\n\n");
cell_get_reciprocal(cell, &asx, &asy, &asz,
&bsx, &bsy, &bsz,
&csx, &csy, &csz);
fprintf(fh, "#declare WCA = (720/19);\n");
fprintf(fh, "#declare WCL = (360/8.5);\n");
fprintf(fh, "#declare TA = (4.875);\n");
fprintf(fh, "#declare TB = (1.125);\n");
fprintf(fh, "#declare TRANS = \n");
fprintf(fh, "transform {\n");
/* First half */
/* Acceleration */
fprintf(fh, "#if ( clock <= 24 )\n"
"rotate <0, 0, 0.5*WCA*(clock/25)*(clock/25)>\n"
"#end\n"
/* Cruise */
"#if ( (clock >= 25) & (clock <= 224) )\n"
"rotate <0, 0, (WCA/2)+WCA*((clock-25)/25)>\n"
"#end\n"
/* Overlap */
/* Deceleration */
"#if ( (clock >= 225) & (clock <= 274) )\n"
"rotate <0, 0, 360-WCA + WCA*((clock-225)/25) "
" - 0.5*(WCA/2)*((clock-225)/25)*((clock-225)/25) >\n"
"#end\n"
/* Acceleration */
"#if ( (clock >= 225) & (clock <= 274) )\n"
"rotate <0.5*(WCL/2)*((clock-225)/25)*((clock-225)/25), 0, 0>\n"
"#end\n"
/* Second half */
/* Cruise */
"#if ( (clock >= 275) & (clock <= 396) )\n"
"rotate <WCL + WCL*((clock-275)/25), 0, 0>\n"
"#end\n"
/* Deceleration to pause */
"#if ( (clock >= 397) & (clock <= 421) )\n"
"rotate <(1+TA)*WCL+ WCL*((clock-397)/25) "
" - 0.5*WCL*((clock-397)/25)*((clock-397)/25), 0, 0 >\n"
"#end\n"
/* Acceleration after pause */
"#if ( (clock >= 422) & (clock <= 446) )\n"
"rotate <(1.5+TA)*WCL"
" + 0.5*WCL*((clock-422)/25)*((clock-422)/25), 0, 0>\n"
"#end\n"
/* Final Cruise */
"#if ( (clock >= 447) & (clock <= 474) )\n"
"rotate <(2+TA)*WCL + WCL*((clock-447)/25), 0, 0>\n"
"#end\n"
/* Final Deceleration */
"#if ( (clock >= 475) & (clock <= 499) )\n"
"rotate <(2+TA+TB)*WCL + WCL*((clock-475)/25) "
" - 0.5*WCL*((clock-475)/25)*((clock-475)/25), 0, 0 >\n"
"#end\n");
fprintf(fh, "}\n");
max = 0.5e6;
for ( h=-INDMAX; h<INDMAX; h++ ) {
for ( k=-INDMAX; k<INDMAX; k++ ) {
for ( l=-INDMAX; l<INDMAX; l++ ) {
float radius, x, y, z;
int s;
float val, p, r, g, b, trans;
if ( !lookup_count(c, h, k, l) ) continue;
val = lookup_intensity(ref, h, k, l);
val = max-val;
s = val / (max/6);
p = fmod(val, max/6);
p /= (max/6);
r = 0; g = 0; b = 0;
if ( (val < 0.0) ) {
s = 0;
p = 1.0;
}
if ( (val > max) ) {
s = 6;
}
switch ( s ) {
case 0 : /* Black to blue */
r = 0.0; g = 0.0; b = p;
break;
case 1 : /* Blue to green */
r = 0.0; g = p; b = 1.0-p;
break;
case 2 : /* Green to red */
r =p; g = 1.0-p; b = 0.0;
break;
case 3 : /* Red to Orange */
r = 1.0; g = 0.5*p; b = 0.0;
break;
case 4 : /* Orange to Yellow */
r = 1.0; g = 0.5 + 0.5*p; b = 0.0;
break;
case 5 : /* Yellow to White */
r = 1.0; g = 1.0; b = 1.0*p;
break;
case 6 : /* Pixel has hit the maximum value */
r = 1.0; g = 1.0; b = 1.0;
break;
}
val = max-val;
if ( val <= 0.0 ) continue;
radius = 0.1 * sqrt(sqrt(val))/1e2;
radius -= 0.005;
if ( radius > 0.03 ) radius = 0.03;
if ( radius <= 0.0 ) continue;
trans = (0.03-radius)/0.03;
radius += 0.002;
x = asx*h + bsx*k + csx*l;
y = asy*h + bsy*k + csy*l;
z = asz*h + bsz*k + csz*l;
fprintf(fh, "sphere { <%.5f, %.5f, %.5f>, %.5f "
"texture{pigment{color rgb <%f, %f, %f>"
" transmit %f} "
"finish { reflection 0.1 } } \n"
"transform { TRANS }\n"
"}\n",
x/1e9, y/1e9, z/1e9, radius, r, g, b, trans);
}
}
}
fprintf(fh, "\n");
fclose(fh);
for ( i=0; i<nproc; i++ ) {
pids[i] = fork();
if ( !( (pids[i] != 0) && (pids[i] != -1) ) ) {
if ( pids[i] == -1 ) {
ERROR("fork() failed.\n");
} else {
char minf[256];
char maxf[256];
float nf, xf, nsec;
nsec = 500.0 / (float)nproc;
nf = nsec * (float)i;
xf = (nsec * (float)i + nsec) - 1.0;
snprintf(minf, 255, "+SF%i", (int)nf);
snprintf(maxf, 255, "+EF%i", (int)xf);
/* Forked successfully, child process */
execlp("povray", "", "+W1024", "+H768",
"+Irender.pov", "+Orender.png",
"+KFI0", "+KFF499", "+KI0", "+KF499",
minf, maxf, "-D", NULL);
}
} /* else start the next one */
}
for ( i=0; i<nproc; i++ ) {
int r;
waitpid(pids[i], &r, 0);
}
return 0;
}
/*
* povray.c
*
* Invoke POV-ray
*
* (c) 2006-2010 Thomas White <taw@physics.org>
*
* Part of CrystFEL - crystallography with a FEL
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef POVRAY_H
#define POVRAY_H
extern int povray_render_animation(UnitCell *cell, double *ref,
unsigned int *c, unsigned int nproc);
#endif /* POVRAY_H */
......@@ -20,23 +20,19 @@
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cairo.h>
#include <cairo-pdf.h>
#include "utils.h"
#include "reflections.h"
#define MAX_PROC (256)
#include "povray.h"
static void show_help(const char *s)
{
printf("Syntax: %s [options] <file.hkl>\n\n", s);
printf(
"Render intensity lists using POV-ray.\n"
"Render intensity lists in various ways.\n"
"\n"
" -h, --help Display this help message.\n"
" --povray Render a 3D animation using POV-ray.\n"
......@@ -172,253 +168,6 @@ out:
}
static void povray_render_animation(UnitCell *cell, double *ref,
unsigned int *c, unsigned int nproc)
{
FILE *fh;
double asx, asy, asz;
double bsx, bsy, bsz;
double csx, csy, csz;
pid_t pids[MAX_PROC];
float max;
int i;
signed int h, k, l;
fh = fopen("render.pov", "w");
fprintf(fh, "/* POV-Ray scene written by CrystFEL */\n\n");
fprintf(fh, "#include \"colors.inc\"\n");
fprintf(fh, "#include \"textures.inc\"\n\n");
fprintf(fh, "global_settings {\n");
fprintf(fh, " assumed_gamma 1.0\n");
fprintf(fh, " ambient_light 5.0\n");
fprintf(fh, "}\n\n");
/* First quarter */
fprintf(fh, "#if ( (clock >= 0) & (clock <= 124) )\n");
fprintf(fh, "camera { location <0.0, -3.0, 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
/* Second quarter */
fprintf(fh, "#if ( (clock >= 125) & (clock <= 249) )\n");
fprintf(fh, "camera { location <0.0,"
" -(2.0+cos(radians((clock-125)*(180/125)))), 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
/* Third quarter */
fprintf(fh, "#if ( (clock >= 250) & (clock <= 374) )\n");
fprintf(fh, "camera { location <0.0, -1.0, 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
/* Fourth quarter */
fprintf(fh, "#if ( (clock >= 375) & (clock <= 500) )\n");
fprintf(fh, "camera { location <0.0,"
" -(2.0+cos(radians((clock-375)*(180/125)+180))), 0.0>"
" sky z direction 1.1*y\n"
" right -x*(image_width/image_height)\n"
" look_at <0.0, 0.0, 0.0> }\n\n");
fprintf(fh, "#end\n");
fprintf(fh, "light_source { <-3.0 -3.0 3.0> White }\n");
fprintf(fh, "light_source { <+3.0 -3.0 3.0> White }\n");
fprintf(fh, "light_source { <0.0, -3.0, 0.0> 2*White }\n");
fprintf(fh, "plane {z,-2.0 pigment { rgb <0.0, 0.0, 0.1> } }\n");
fprintf(fh, "plane {-z,-2.0 pigment { rgb <0.0, 0.0, 0.05> } }\n\n");
cell_get_reciprocal(cell, &asx, &asy, &asz,
&bsx, &bsy, &bsz,
&csx, &csy, &csz);
fprintf(fh, "#declare WCA = (720/19);\n");
fprintf(fh, "#declare WCL = (360/8.5);\n");
fprintf(fh, "#declare TA = (4.875);\n");
fprintf(fh, "#declare TB = (1.125);\n");
fprintf(fh, "#declare TRANS = \n");
fprintf(fh, "transform {\n");
/* First half */
/* Acceleration */
fprintf(fh, "#if ( clock <= 24 )\n"
"rotate <0, 0, 0.5*WCA*(clock/25)*(clock/25)>\n"
"#end\n"
/* Cruise */
"#if ( (clock >= 25) & (clock <= 224) )\n"
"rotate <0, 0, (WCA/2)+WCA*((clock-25)/25)>\n"
"#end\n"
/* Overlap */
/* Deceleration */
"#if ( (clock >= 225) & (clock <= 274) )\n"
"rotate <0, 0, 360-WCA + WCA*((clock-225)/25) "
" - 0.5*(WCA/2)*((clock-225)/25)*((clock-225)/25) >\n"
"#end\n"
/* Acceleration */
"#if ( (clock >= 225) & (clock <= 274) )\n"
"rotate <0.5*(WCL/2)*((clock-225)/25)*((clock-225)/25), 0, 0>\n"
"#end\n"
/* Second half */
/* Cruise */
"#if ( (clock >= 275) & (clock <= 396) )\n"
"rotate <WCL + WCL*((clock-275)/25), 0, 0>\n"
"#end\n"
/* Deceleration to pause */
"#if ( (clock >= 397) & (clock <= 421) )\n"
"rotate <(1+TA)*WCL+ WCL*((clock-397)/25) "
" - 0.5*WCL*((clock-397)/25)*((clock-397)/25), 0, 0 >\n"
"#end\n"
/* Acceleration after pause */
"#if ( (clock >= 422) & (clock <= 446) )\n"
"rotate <(1.5+TA)*WCL"
" + 0.5*WCL*((clock-422)/25)*((clock-422)/25), 0, 0>\n"
"#end\n"
/* Final Cruise */
"#if ( (clock >= 447) & (clock <= 474) )\n"
"rotate <(2+TA)*WCL + WCL*((clock-447)/25), 0, 0>\n"
"#end\n"
/* Final Deceleration */
"#if ( (clock >= 475) & (clock <= 499) )\n"
"rotate <(2+TA+TB)*WCL + WCL*((clock-475)/25) "
" - 0.5*WCL*((clock-475)/25)*((clock-475)/25), 0, 0 >\n"
"#end\n");
fprintf(fh, "}\n");
max = 0.5e6;
for ( h=-INDMAX; h<INDMAX; h++ ) {
for ( k=-INDMAX; k<INDMAX; k++ ) {
for ( l=-INDMAX; l<INDMAX; l++ ) {
float radius, x, y, z;
int s;
float val, p, r, g, b, trans;
if ( !lookup_count(c, h, k, l) ) continue;
val = lookup_intensity(ref, h, k, l);
val = max-val;
s = val / (max/6);
p = fmod(val, max/6);
p /= (max/6);
r = 0; g = 0; b = 0;
if ( (val < 0.0) ) {
s = 0;
p = 1.0;
}
if ( (val > max) ) {
s = 6;
}
switch ( s ) {
case 0 : /* Black to blue */
r = 0.0; g = 0.0; b = p;
break;
case 1 : /* Blue to green */
r = 0.0; g = p; b = 1.0-p;
break;
case 2 : /* Green to red */
r =p; g = 1.0-p; b = 0.0;
break;
case 3 : /* Red to Orange */
r = 1.0; g = 0.5*p; b = 0.0;
break;
case 4 : /* Orange to Yellow */
r = 1.0; g = 0.5 + 0.5*p; b = 0.0;
break;
case 5 : /* Yellow to White */
r = 1.0; g = 1.0; b = 1.0*p;
break;
case 6 : /* Pixel has hit the maximum value */
r = 1.0; g = 1.0; b = 1.0;
break;
}
val = max-val;
if ( val <= 0.0 ) continue;
radius = 0.1 * sqrt(sqrt(val))/1e2;
radius -= 0.005;
if ( radius > 0.03 ) radius = 0.03;
if ( radius <= 0.0 ) continue;
trans = (0.03-radius)/0.03;
radius += 0.002;
x = asx*h + bsx*k + csx*l;
y = asy*h + bsy*k + csy*l;
z = asz*h + bsz*k + csz*l;
fprintf(fh, "sphere { <%.5f, %.5f, %.5f>, %.5f "
"texture{pigment{color rgb <%f, %f, %f>"
" transmit %f} "
"finish { reflection 0.1 } } \n"
"transform { TRANS }\n"
"}\n",
x/1e9, y/1e9, z/1e9, radius, r, g, b, trans);
}
}
}
fprintf(fh, "\n");
fclose(fh);
for ( i=0; i<nproc; i++ ) {
pids[i] = fork();
if ( !( (pids[i] != 0) && (pids[i] != -1) ) ) {
if ( pids[i] == -1 ) {
ERROR("fork() failed.\n");
} else {
char minf[256];
char maxf[256];
float nf, xf, nsec;
nsec = 500.0 / (float)nproc;
nf = nsec * (float)i;
xf = (nsec * (float)i + nsec) - 1.0;
snprintf(minf, 255, "+SF%i", (int)nf);
snprintf(maxf, 255, "+EF%i", (int)xf);
/* Forked successfully, child process */
execlp("povray", "", "+W1024", "+H768",
"+Irender.pov", "+Orender.png",
"+KFI0", "+KFF499", "+KI0", "+KF499",
minf, maxf, "-D", NULL);