commit b338fa226363ab79eae82701daefdf348c0c1ce7
parent 9dc143856b3e88aa8d7ce724e90237b9e2338794
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date: Fri, 4 May 2018 10:05:36 +0200
branchement de solve_camera
Diffstat:
6 files changed, 325 insertions(+), 67 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -1,18 +1,23 @@
CC=gcc
SDIS_SDK=../Stardis-0.3.0-GNU-Linux64
+SDIS_SDK_DBG=/home/piaud/code/star-engine-stardis/local/
INC=-I$(SDIS_SDK)/include
+#CFLAGS=-std=c90
LDFLAGS=-lsdis -lsstl -lrsys -ltinyexpr -lm -L$(SDIS_SDK)/lib -Wl,-rpath=$(SDIS_SDK)/lib
+
+LDFLAGS_DBG=-lsdis-dbg -lsstl-dbg -lrsys-dbg -ltinyexpr -lm -L$(SDIS_SDK)/lib -Wl,-rpath=$(SDIS_SDK)/lib
+
SRC=main.c stardis-app.c stardis-compute.c
DEPS=args.h stardis-app.h
all: stardis-app
stardis-app: $(SRC) $(DEPS)
- $(CC) -o stardis-app $(SRC) $(INC) $(LDFLAGS)
+ $(CC) -o stardis-app $(SRC) $(INC) $(CFLAGS) $(LDFLAGS)
debug: $(SRC) $(DEPS)
- $(CC) -g -o stardis-app-dbg $(SRC) $(INC) $(LDFLAGS)
+ $(CC) -g -o stardis-app-dbg $(SRC) $(INC) $(CFLAGS) $(LDFLAGS_DBG)
clean:
rm -rf stardis-app stardis-app-dbg
diff --git a/src/args.h b/src/args.h
@@ -9,6 +9,7 @@
enum stardis_mode{
PROBE_COMPUTE,
+ IR_COMPUTE,
DUMP_VTK
};
@@ -21,8 +22,9 @@ struct args{
enum stardis_mode mode;
double scale_factor;
double radiative_temp[2];
+ char* camera;
};
-#define ARGS_DEFAULT__ {NULL, NULL, 10000, SDIS_NTHREADS_DEFAULT, {0,0,0,INF}, PROBE_COMPUTE, 1.0, {300,300}}
+#define ARGS_DEFAULT__ {NULL, NULL, 10000, SDIS_NTHREADS_DEFAULT, {0,0,0,INF}, PROBE_COMPUTE, 1.0, {300,300}, NULL}
static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
static void
@@ -62,9 +64,17 @@ print_help(char* prog)
printf(" AMBIENT_RAD_TEMP is the ambient radiative temperature .\n");
printf(" REFERENCE_TEMP is the temperature used for the linearization.\n");
printf(" of theradiative transfer.\n");
- printf(" default value : 300:300.\n");
+ printf("\n -R spp=SPP:fov=FOV:up=XUP,YUP,ZUP:pos=X,Y,Z:tgt=XT,YT,ZT:img=WxH :\n");
+ printf(" The infra-red rendering mode.\n");
+ printf(" spp is the number of samples per pixel (default: 4).\n");
+ printf(" fov is the field of view (default: 70 degrees).\n");
+ printf(" up is the up direction (default: 0,0,1).\n");
+ printf(" pos is the position of camera (default: 1,1,1).\n");
+ printf(" tgt is the target (default: 0,0,0).\n");
+ printf(" img is the resolution (default: 640x480).\n");
}
+
static res_T
parse_args(const int argc, char** argv, struct args* args)
{
@@ -78,7 +88,7 @@ parse_args(const int argc, char** argv, struct args* args)
goto error;
}
- while((opt = getopt(argc, argv, "hn:t:b:m:p:ds:r:")) != -1) {
+ while((opt = getopt(argc, argv, "hn:t:b:m:p:ds:r:R:")) != -1) {
switch(opt) {
case 'h':
print_help(argv[0]);
@@ -111,7 +121,7 @@ parse_args(const int argc, char** argv, struct args* args)
break;
case 'p':
- cstr_to_list_double(optarg, ':', args->probe, &len, 4);
+ cstr_to_list_double(optarg, ',', args->probe, &len, 4);
if(res == RES_OK && len != 4) res = RES_BAD_ARG;
if (res != RES_OK){
fprintf(stderr, "Invalid argument -p\n", optarg);
@@ -132,7 +142,7 @@ parse_args(const int argc, char** argv, struct args* args)
break;
case 'r':
- cstr_to_list_double(optarg, ':', args->radiative_temp, &len, 2);
+ cstr_to_list_double(optarg, ',', args->radiative_temp, &len, 2);
if(res == RES_OK && len != 2) res = RES_BAD_ARG;
if (res != RES_OK
|| args->radiative_temp[0] <=0
@@ -141,6 +151,11 @@ parse_args(const int argc, char** argv, struct args* args)
goto error;
}
break;
+
+ case 'R':
+ args->mode = IR_COMPUTE;
+ args->camera = optarg;
+ break;
}
}
diff --git a/src/main.c b/src/main.c
@@ -22,7 +22,7 @@ int main(int argc, char** argv){
goto exit;
}
- res = stardis_compute(&stardis);
+ res = stardis_compute(&stardis, args.mode);
if (res != RES_OK) goto error;
exit:
diff --git a/src/stardis-app.c b/src/stardis-app.c
@@ -31,6 +31,55 @@ read_line(char** pb, FILE* stream)
return b;
}
+char** split_line(char* a_str, const char a_delim)
+{
+ char** result = 0;
+ size_t count = 0;
+ char* tmp = a_str;
+ char* last_comma = 0;
+ char delim[2];
+ delim[0] = a_delim;
+ delim[1] = 0;
+
+ /* Count how many elements will be extracted. */
+ while (*tmp)
+ {
+ if (a_delim == *tmp)
+ {
+ count++;
+ last_comma = tmp;
+ }
+ tmp++;
+ }
+
+ /* Add space for trailing token. */
+ count += last_comma < (a_str + strlen(a_str) - 1);
+
+ /* Add space for terminating null string so caller
+ knows where the list of returned strings ends. */
+ count++;
+
+ result = malloc(sizeof(char*) * count);
+
+ if (result)
+ {
+ size_t idx = 0;
+ char* token = strtok(a_str, delim);
+
+ while (token)
+ {
+ assert(idx < count);
+ *(result + idx++) = strdup(token);
+ token = strtok(0, delim);
+ }
+ assert(idx == count - 1);
+ *(result + idx) = 0;
+ }
+
+ return result;
+}
+
+
static res_T
parse_medium_line(char* line, char** stl_filename, struct material* mat)
{
@@ -348,6 +397,66 @@ error:
goto exit;
}
+static res_T
+parse_camera
+(char* cam_param, struct camera* cam)
+{
+ char** line = NULL;
+ char** opt = NULL;
+ res_T res = RES_OK;
+
+ line = split_line(cam_param,':');
+
+ if (line)
+ {
+ int i = 0;
+ for (i = 0; *(line + i); i++)
+ {
+ size_t len = 0;
+ opt = split_line(line[i],'=');
+ if (strcmp(opt[0],"fov")==0){
+ res = cstr_to_double(opt[1], &cam->fov);
+ if (res != RES_OK) goto error;
+ } else if (strcmp(opt[0],"up")==0) {
+ res = cstr_to_list_double(opt[1], ',', cam->up, &len, 3);
+ if (res != RES_OK || len != 3) goto error;
+ } else if (strcmp(opt[0],"tgt")==0) {
+ res = cstr_to_list_double(opt[1], ',', cam->tgt, &len, 3);
+ if (res != RES_OK || len != 3) goto error;
+ } else if (strcmp(opt[0],"pos")==0) {
+ res = cstr_to_list_double(opt[1], ',', cam->pos, &len, 3);
+ if (res != RES_OK || len != 3) goto error;
+ } else if (strcmp(opt[0],"img")==0) {
+ res = cstr_to_list_uint(opt[1], 'x', cam->img, &len, 2);
+ if (res != RES_OK || len != 2) goto error;
+ } else if (strcmp(opt[0],"spp")==0) {
+ res = cstr_to_uint(opt[1], &cam->spp);
+ if (res != RES_OK) goto error;
+ }
+ }
+ }
+
+exit:
+ if (line){
+ int i = 0;
+ for (i=0; *(line+i);i++){
+ free(line[i]);
+ }
+ free(line);
+ }
+ if (opt){
+ int i = 0;
+ for (i=0; *(opt+i);i++){
+ free(opt[i]);
+ }
+ free(opt);
+ }
+
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
*
******************************************************************************/
@@ -381,6 +490,11 @@ stardis_init
if (res != RES_OK) goto error;
}
+ if (args->mode == IR_COMPUTE){
+ res = parse_camera(args->camera, &stardis->camera);
+ if (res != RES_OK) goto error;
+ }
+
exit:
return res;
error:
diff --git a/src/stardis-app.h b/src/stardis-app.h
@@ -38,7 +38,7 @@ struct triangle{
int medium_back;
int bound_id;
};
-#define NULL_TRIANGLE__ {{0, 0, 0}, {0, 0, 0}, 0, 0, -1}
+#define NULL_TRIANGLE__ {{0, 0, 0}, {0, 0, 0}, -1, -1, -1}
static const struct triangle NULL_TRIANGLE = NULL_TRIANGLE__;
static char
@@ -110,6 +110,16 @@ struct boundary{
#define NULL_BOUNDARY__ {-1, NULL, NULL}
static const struct boundary NULL_BOUNDARY = NULL_BOUNDARY__;
+struct camera{
+ double pos[3];
+ double tgt[3];
+ double up[3];
+ double fov;
+ unsigned spp;
+ unsigned img[2];
+};
+#define NULL_CAMERA__ {{1,1,1},{0,0,0},{0,0,1},70,4,{640,480}}
+static const struct camera NULL_CAMERA = NULL_CAMERA__;
struct stardis{
struct geometry geometry;
@@ -121,8 +131,9 @@ struct stardis{
double probe[4]; /*x,y,z,t of probe*/
double scale_factor;
double radiative_temp[2];
+ struct camera camera;
};
-#define NULL_STARDIS__ {NULL_GEOMETRY__, NULL, NULL, 0, 0, {0,0,0,0}, 0, {300,300}}
+#define NULL_STARDIS__ {NULL_GEOMETRY__, NULL, NULL, 0, 0, {0,0,0,0}, 0, {300,300}, NULL_CAMERA__}
static const struct stardis NULL_STARDIS = NULL_STARDIS__;
extern res_T
@@ -131,7 +142,7 @@ stardis_init
struct stardis* stardis);
extern res_T
-stardis_compute(struct stardis* stardis);
+stardis_compute(struct stardis* stardis, enum stardis_mode mode);
extern res_T
stardis_release(struct stardis* stardis);
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -4,6 +4,11 @@
#include <sdis.h>
#include <rsys/double3.h>
+#define IMG_WIDTH 640
+#define IMG_HEIGHT 480
+#define SPP 256
+#include <rsys/image.h>
+
static void
geometry_get_position
(const size_t ivert,
@@ -324,12 +329,72 @@ error:
goto exit;
}
+static void
+dump_image(const struct sdis_accum_buffer* buf)
+{
+ struct sdis_accum_buffer_layout layout = SDIS_ACCUM_BUFFER_LAYOUT_NULL;
+ struct image img;
+ double* temps = NULL;
+ const struct sdis_accum* accums = NULL;
+ double Tmax = -DBL_MAX;
+ double Tmin = DBL_MAX;
+ double norm;
+ size_t ix, iy;
+
+ CHK(buf != NULL);
+ CHK(sdis_accum_buffer_get_layout(buf, &layout) == RES_OK);
+
+ temps = mem_alloc(layout.width*layout.height*sizeof(double));
+ CHK(temps != NULL);
+
+ /* Compute the per pixel temperature */
+ CHK(sdis_accum_buffer_map(buf, &accums) == RES_OK);
+ FOR_EACH(iy, 0, layout.height) {
+ const struct sdis_accum* row_accums = accums + iy * layout.width;
+ double* row = temps + iy * layout.width;
+ FOR_EACH(ix, 0, layout.width) {
+ row[ix] = row_accums[ix].sum_weights / (double)row_accums[ix].nweights;
+ Tmax = MMAX(row[ix], Tmax);
+ Tmin = MMIN(row[ix], Tmin);
+ }
+ }
+ if(Tmax != Tmin) {
+ norm = Tmax - Tmin;
+ } else {
+ Tmin = 0;
+ norm = 1;
+ }
+
+ /* Allocate the image memory space */
+ CHK(image_init(NULL, &img) == RES_OK);
+ CHK(image_setup(&img, IMG_WIDTH, IMG_HEIGHT, IMG_WIDTH*3, IMAGE_RGB8, NULL)
+ == RES_OK);
+
+ FOR_EACH(iy, 0, layout.height) {
+ const double* src_row = temps + iy*layout.width;
+ char* dst_row = img.pixels + iy*img.pitch;
+ FOR_EACH(ix, 0, layout.width) {
+ unsigned char* pixels = (unsigned char*)
+ (dst_row + ix * sizeof_image_format(img.format));
+ const unsigned char T = (unsigned char)
+ ((src_row[ix] - Tmin)/ norm * 255.0);
+ pixels[0] = T;
+ pixels[1] = T;
+ pixels[2] = T;
+ }
+ }
+ CHK(image_write_ppm_stream(&img, 0/*binary?*/, stdout) == RES_OK);
+ image_release(&img);
+ mem_rm(temps);
+}
+
+
/*******************************************************************************
*
******************************************************************************/
res_T
-stardis_compute(struct stardis* stardis)
+stardis_compute(struct stardis* stardis, enum stardis_mode mode)
{
res_T res = RES_OK;
struct sdis_device* dev = NULL;
@@ -341,16 +406,22 @@ stardis_compute(struct stardis* stardis)
struct sdis_fluid_shader fluid_shader = SDIS_FLUID_SHADER_NULL;
struct sdis_medium** fluid_medium = NULL;
- struct sdis_interface_side_shader interface_shader_front = SDIS_INTERFACE_SIDE_SHADER_NULL;
- struct sdis_interface_side_shader interface_shader_back = SDIS_INTERFACE_SIDE_SHADER_NULL;
- struct sdis_interface_shader interface_shader_boundary = SDIS_INTERFACE_SHADER_NULL;
- struct sdis_interface_shader interface_shader_connection = SDIS_INTERFACE_SHADER_NULL;
+ struct sdis_interface_side_shader interface_shader_front =
+ SDIS_INTERFACE_SIDE_SHADER_NULL;
+ struct sdis_interface_side_shader interface_shader_back =
+ SDIS_INTERFACE_SIDE_SHADER_NULL;
+ struct sdis_interface_shader interface_shader_boundary =
+ SDIS_INTERFACE_SHADER_NULL;
+ struct sdis_interface_shader interface_shader_connection =
+ SDIS_INTERFACE_SHADER_NULL;
struct interface* interface_props = NULL;
struct sdis_interface** interfaces = NULL;
- struct sdis_scene* scn;
- struct sdis_estimator* estimator;
+ struct sdis_scene* scn = NULL;
+ struct sdis_estimator* estimator = NULL;
struct sdis_mc temperature;
+ struct sdis_accum_buffer* buf = NULL;
+ struct sdis_camera* cam = NULL;
int* bound2fluid = NULL;
double pos[3] = {0,0,0};
@@ -358,7 +429,7 @@ stardis_compute(struct stardis* stardis)
size_t nfailures;
int i = 0;
- SDIS(device_create(NULL, NULL, stardis->nthreads, 0, &dev));
+ SDIS(device_create(NULL, NULL, stardis->nthreads, 1, &dev));
/* Setup the fluid shader */
fluid_shader.calorific_capacity = fluid_get_calorific_capacity;
@@ -467,57 +538,97 @@ stardis_compute(struct stardis* stardis)
sa_size(stardis->geometry.vertex),
geometry_get_position, &stardis->geometry, &scn));
- /* Launch the probe simulation */
- pos[0] = stardis->probe[0];
- pos[1] = stardis->probe[1];
- pos[2] = stardis->probe[2];
- time = stardis->probe[3];
- {
- double uv[2] = {0,0};
- size_t iprim = -1;
-
- res = select_probe_type(scn,
- stardis->geometry.triangle,
- stardis->material,
- pos,
- &iprim,
- uv);
-
- if(iprim == -1){
- SDIS(solve_probe(scn,
- stardis->N,
- pos,time,
- stardis->scale_factor,
- stardis->radiative_temp[0],
- stardis->radiative_temp[1],
- &estimator));
- } else {
- SDIS(solve_probe_boundary(scn,
- stardis->N,
- iprim,
- uv,
- time,
- SDIS_FRONT,
+
+ if (mode == IR_COMPUTE){
+ size_t width = (size_t)stardis->camera.img[0];
+ size_t height = (size_t)stardis->camera.img[1];
+
+ /* Setup the camera */
+ SDIS(camera_create(dev, &cam));
+ SDIS(camera_set_proj_ratio(cam, (double)width/(double)height));
+ SDIS(camera_set_fov(cam, MDEG2RAD(stardis->camera.fov)));
+ SDIS(camera_look_at(cam,
+ stardis->camera.pos,
+ stardis->camera.tgt,
+ stardis->camera.up));
+
+ /* Create the accum buffer */
+ SDIS(accum_buffer_create(dev,
+ width,
+ height,
+ &buf));
+
+ /* Launch the simulation */
+ SDIS(solve_camera(scn,
+ cam,
+ INF,
stardis->scale_factor,
stardis->radiative_temp[0],
stardis->radiative_temp[1],
- &estimator));
- }
+ width,
+ height,
+ stardis->camera.spp,
+ sdis_accum_buffer_write,
+ buf));
+
+ /* Write the image */
+ dump_image(buf);
+ SDIS(camera_ref_put(cam));
+ SDIS(accum_buffer_ref_put(buf));
}
- /* Fetch the estimation data */
- SDIS(estimator_get_temperature(estimator, &temperature));
- SDIS(estimator_get_failure_count(estimator, &nfailures));
-
- /* Print the results */
- printf("Temperature at [%g, %g, %g, %g] = %g +/- %g\n",
- pos[0], pos[1], pos[2], time,
- temperature.E, /* Expected value */
- temperature.SE); /* Standard error */
- printf("#failures: %lu/%lu\n",
- (unsigned long)nfailures,
- (unsigned long)stardis->N);
+ if (mode == PROBE_COMPUTE){
+ /* Launch the probe simulation */
+ pos[0] = stardis->probe[0];
+ pos[1] = stardis->probe[1];
+ pos[2] = stardis->probe[2];
+ time = stardis->probe[3];
+ {
+ double uv[2] = {0,0};
+ size_t iprim = -1;
+
+ res = select_probe_type(scn,
+ stardis->geometry.triangle,
+ stardis->material,
+ pos,
+ &iprim,
+ uv);
+
+ if(iprim == -1){
+ SDIS(solve_probe(scn,
+ stardis->N,
+ pos,time,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ &estimator));
+ } else {
+ SDIS(solve_probe_boundary(scn,
+ stardis->N,
+ iprim,
+ uv,
+ time,
+ SDIS_FRONT,
+ stardis->scale_factor,
+ stardis->radiative_temp[0],
+ stardis->radiative_temp[1],
+ &estimator));
+ }
+ }
+ /* Fetch the estimation data */
+ SDIS(estimator_get_temperature(estimator, &temperature));
+ SDIS(estimator_get_failure_count(estimator, &nfailures));
+
+ /* Print the results */
+ printf("Temperature at [%g, %g, %g, %g] = %g +/- %g\n",
+ pos[0], pos[1], pos[2], time,
+ temperature.E, /* Expected value */
+ temperature.SE); /* Standard error */
+ printf("#failures: %lu/%lu\n",
+ (unsigned long)nfailures,
+ (unsigned long)stardis->N);
+ }
exit:
for (i=0; i<sa_size(solid_medium); ++i){
@@ -538,9 +649,11 @@ exit:
sa_release(bound2fluid);
- SDIS(estimator_ref_put(estimator));
- SDIS(scene_ref_put(scn));
- SDIS(device_ref_put(dev));
+ if (cam) SDIS(camera_ref_put(cam));
+ if (buf) SDIS(accum_buffer_ref_put(buf));
+ if (estimator) SDIS(estimator_ref_put(estimator));
+ if (scn) SDIS(scene_ref_put(scn));
+ if (dev) SDIS(device_ref_put(dev));
return res;
error:
goto exit;