POV-Ray : Newsgroups : povray.general : troubles with isosurface /df3 Server Time
29 Nov 2024 23:47:25 EST (-0500)
  troubles with isosurface /df3 (Message 1 to 3 of 3)  
From: ialx
Subject: troubles with isosurface /df3
Date: 9 Mar 2005 06:30:00
Message: <web.422edd8d6f9549adfb6b79d70@news.povray.org>
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

From: Slime
Subject: Re: troubles with isosurface /df3
Date: 12 Mar 2005 23:17:42
Message: <4233bee6@news.povray.org>
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/ ]


Post a reply to this message

From: ialx
Subject: Re: troubles with isosurface /df3
Date: 16 Mar 2005 02:40:01
Message: <web.4237e183d60091b1fb6b79d70@news.povray.org>
"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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.