|
|
main.c creates a df3 file (t.dat, 100x100x100) containing a spherical
function x^2 +y^2 +z^2 centered at <0.5,0.5,0.5>. test.pov should draw a
sphere with radius 0.4472 (the same as the sphere{} that is commented out).
i sort of get the spehre but the unit cube is "filled with dust". what am i
doing wrong here??
camera { location <11, 10.5, -15> look_at <0.5, 0.5, 0.5> angle 14}
light_source {<-100,200,-100> colour rgb 1}
sky_sphere { pigment {
function{abs(y)}
color_map { [0.0 color blue 0.6] [1.0 color rgb 1] }
}
}
#declare F=function{
pattern{
density_file df3 "t.dat"
interpolate 2
}
}
//sphere { <0.5,0.5,0.5> .4472 // sqrt(0.2)=0.4472
// pigment {
// rgb 0.1
// }
// finish {
// phong 0.5 phong_size 10
// }
//}
isosurface {
function {
F(x,y,z)
}
threshold 0.2
max_gradient 50
contained_by {
box {
0,1
}
}
pigment {
rgb 0.1
}
finish {
phong 0.5 phong_size 10
}
}
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
void minmax_data(int nx, int ny, int nz, float ***data, float *max,
float *min)
/*
* determine minimum value of data. values are returned as min and max.
*/
{
int i, j, k;
*min = 1e200;
*max = -1e200;
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
for (k = 0; k < nz; k++) {
*max = MAX(*max, data[i][j][k]);
*min = MIN(*min, data[i][j][k]);
}
}
}
}
void normalize_data(int nx, int ny, int nz, float ***data, float max,
float min)
/*
* normalize data according to min and max values
*/
{
int i, j, k;
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
for (k = 0; k < nz; k++) {
data[i][j][k] = (data[i][j][k] - min) / (max - min);
}
}
}
}
void df3_write_header(int nx, int ny, int nz, FILE * out)
{
/*float
* write header of df3 file
*/
fputc(nx >> 8, out);
fputc(nx & 0xff, out);
fputc(ny >> 8, out);
fputc(ny & 0xff, out);
fputc(nz >> 8, out);
fputc(nz & 0xff, out);
}
void df3_write_data_8(int nx, int ny, int nz, float ***data, FILE * out)
/*
* write data as unsigned char (8bit). data is assumed to be normalized.
* wrap around occurs if the actual range is larger than 0..1. (??)
*/
{
int i, j, k;
float tmp;
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
for (k = 0; k < nz; k++) {
tmp = UCHAR_MAX * data[i][j][k];
fputc((int)tmp, out);
}
}
}
}
int main(int argc, char **argv)
{
int i, j, k, l, m;
int nx = 100, ny = 100, nz = 100;
float ***data;
float min, max;
FILE *out;
/*
* malloc the data volume
* data[nx][ny][nz]
*/
data = (float ***) malloc(nx * sizeof(float **));
if (data == NULL)
return EXIT_FAILURE;
for (i = 0; i < nx; i++) {
data[i] = (float **) malloc(ny * sizeof(float *));
if (data[i] == NULL) {
for (l = 0; l < i; l++) {
free(data[l]);
}
free(data);
return EXIT_FAILURE;
}
}
for (i = 0; i < nx; i++)
for (j = 0; j < ny; j++) {
data[i][j] = (float *) malloc(nz * sizeof(float));
if (data[i][j] == NULL) {
for (l = 0; l <= i; l++) {
for (m = 0; m < j; m++) {
free(data[i][j]);
}
}
for (l = 0; l < nx; l++)
free(data[l]);
free(data);
return EXIT_FAILURE;
}
}
out = fopen("t.dat", "w");
/*
* fill in data
*/
for (i = 0; i < nx; i++)
for (j = 0; j < ny; j++)
for (k = 0; k < nz; k++)
data[i][j][k] = (i-50) * (i-50)
+ (j-50) * (j-50)
+ (k-50) * (k-50);
minmax_data(nx, ny, nz, data, &min, &max);
normalize_data(nx, ny, nz, data, min, max);
df3_write_header(nx, ny, nz, out);
df3_write_data_8(nx, ny, nz, data, out);
/*
* free data
*/
for (i = 0; i < nx; i++)
for (j = 0; j < ny; j++)
free(data[i][j]);
for (i = 0; i < nx; i++)
free(data[i]);
free(data);
fclose(out);
return EXIT_SUCCESS;
}
Post a reply to this message
|
|
|
|
"Slime" <fak### [at] emailaddress> wrote:
> Alright, just a hunch, but I believe that density files only write values
> from 0 to 1 (er, 0 to 255, but those are scaled down to 0 to 1). Since
> you're not modifying your density file function from that, all of the area
> "outside" the sphere has a function value of 0. But in an isosurface, where
> the function is zero is the *surface* of the object. So maybe that's what's
> causing your problem.
>
> Try using F(x,y,z)*2 - 1 so that the function goes from -1 to 1, and what
> used to be F = 0.5 is now F = 0: the surface.
>
> (I didn't look too heavily at your code so I'm not sure if that's really
> what's going on or not, but no one's answered so I wanted to at least try to
> help.)
>
> - Slime
> [ http://www.slimeland.com/ ]
i tried this but the outcome is exactly the same. i get a sphere (different
size of course) but the whole <0,0,0> <1,1,1> cube is filled with speckles.
well the code to write the df3 file does normalize the data for
x^2+y^2+z^2 and then scales it to the range 0..255. so this should be ok.
the way i read the documentation the isofunction draws the surface given by
F(x,y,z)-threshold=0. i have threshold=0.2 in my case. so i have three
explanations
1) my c-code does not produce a correct df3 file.
2) my pov command file is wrong (but it is almost a copy of the example
given with spiral.df3)
3) my version of povray has a bug (Persistence of Vision(tm) Ray Tracer
Version 3.6.1 (g++ 3.4.1 @ i686-pc-linux-gnu)
well thanks for the help anyway
Post a reply to this message
|
|