commit 2f750b569caaadd75b76420ca50a8a07cb66b81d
parent 9f8f4c9b826a21cbd9de12cfb2a8222eeea6f8c9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 23 Apr 2021 17:27:52 +0200
Add writing of the geometry of the laser sheet
Diffstat:
5 files changed, 159 insertions(+), 18 deletions(-)
diff --git a/src/combustion/htrdr_combustion.c b/src/combustion/htrdr_combustion.c
@@ -218,7 +218,7 @@ setup_buffer
res_T res = RES_OK;
ASSERT(cmd && args);
- if(cmd->dump_volumetric_acceleration_structure) goto exit;
+ if(cmd->output_type != HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE) goto exit;
combustion_get_pixel_format(cmd, &pixfmt);
@@ -318,6 +318,106 @@ error:
goto exit;
}
+static double
+compute_laser_mesh_extent(const struct htrdr_combustion* cmd)
+{
+ double mdm_upp[3];
+ double mdm_low[3];
+ double laser_dir[3];
+ double laser_pos[3];
+ double t[2];
+ int max_axis;
+ ASSERT(cmd);
+
+ /* Retrieve the medium axis aligned bounding box */
+ atrstm_get_aabb(cmd->medium, mdm_low, mdm_upp);
+
+ /* Retrieve laser parameters */
+ htrdr_combustion_laser_get_position(cmd->laser, laser_pos);
+ htrdr_combustion_laser_get_direction(cmd->laser, laser_dir);
+
+ /* Compute the dominant axis of the laser direction */
+ max_axis =
+ fabs(laser_dir[0]) > fabs(laser_dir[1])
+ ? (fabs(laser_dir[0]) > fabs(laser_dir[2]) ? 0 : 2)
+ : (fabs(laser_dir[1]) > fabs(laser_dir[2]) ? 1 : 2);
+
+ /* Define the intersection of the laser along its dominant axis with the
+ * medium bounds along this axis */
+ t[0] = (mdm_low[max_axis] - laser_pos[max_axis]) / laser_dir[max_axis];
+ t[1] = (mdm_upp[max_axis] - laser_pos[max_axis]) / laser_dir[max_axis];
+ if(t[0] > t[1]) SWAP(double, t[0], t[1]);
+
+ /* Use the far intersection distance as the extent of the laser mesh */
+ return t[1];
+}
+
+static res_T
+dump_laser_sheet(const struct htrdr_combustion* cmd)
+{
+ struct htrdr_combustion_laser_mesh laser_mesh;
+ double extent;
+ unsigned i;
+ res_T res = RES_OK;
+ ASSERT(cmd);
+
+ /* Compute the extent of the geometry that will represent the laser sheet */
+ extent = compute_laser_mesh_extent(cmd);
+
+ /* Retreive the mesh of the laser sheet */
+ htrdr_combustion_laser_get_mesh(cmd->laser, extent, &laser_mesh);
+
+ #define FPRINTF(Fmt, Args) { \
+ const int err = fprintf(cmd->output, Fmt COMMA_##Args LIST_##Args); \
+ if(err < 0) { \
+ htrdr_log_err(cmd->htrdr, "Error writing data to `%s'.\n", \
+ str_cget(&cmd->output_name)); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+
+ /* Write header */
+ FPRINTF("# vtk DataFile Version 2.0\n", ARG0());
+ FPRINTF("Laser sheet\n", ARG0());
+ FPRINTF("ASCII\n", ARG0());
+ FPRINTF("DATASET POLYDATA\n", ARG0());
+
+ /* Write the vertices */
+ FPRINTF("POINTS %u double\n", ARG1(laser_mesh.nvertices));
+ FOR_EACH(i, 0, laser_mesh.nvertices) {
+ FPRINTF("%g %g %g\n", ARG3
+ (laser_mesh.vertices[i*3+0],
+ laser_mesh.vertices[i*3+1],
+ laser_mesh.vertices[i*3+2]));
+ }
+
+ /* Write the triangles */
+ FPRINTF("POLYGONS %u %u\n",ARG2
+ (laser_mesh.ntriangles,
+ laser_mesh.ntriangles*4));
+ FOR_EACH(i, 0, laser_mesh.ntriangles) {
+ FPRINTF("3 %u %u %u\n", ARG3
+ (laser_mesh.triangles[i*3+0],
+ laser_mesh.triangles[i*3+1],
+ laser_mesh.triangles[i*3+2]));
+ }
+
+ /* Write flux density */
+ FPRINTF("CELL_DATA %u\n", ARG1(laser_mesh.ntriangles));
+ FPRINTF("SCALARS Flux_density double 1\n", ARG0());
+ FPRINTF("LOOKUP_TABLE default\n", ARG0());
+ FOR_EACH(i, 0, laser_mesh.ntriangles) {
+ FPRINTF("%g\n", ARG1(htrdr_combustion_laser_get_flux_density(cmd->laser)));
+ }
+ #undef FPRINTF
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
static void
combustion_release(ref_T* ref)
{
@@ -368,8 +468,7 @@ htrdr_combustion_create
cmd->htrdr = htrdr;
cmd->spp = args->image.spp;
- cmd->dump_volumetric_acceleration_structure =
- args->dump_volumetric_acceleration_structure;
+ cmd->output_type = args->output_type;
res = setup_output(cmd, args);
if(res != RES_OK) goto error;
@@ -419,12 +518,20 @@ htrdr_combustion_run(struct htrdr_combustion* cmd)
res_T res = RES_OK;
ASSERT(cmd);
- if(cmd->dump_volumetric_acceleration_structure) {
- res = dump_volumetric_acceleration_structure(cmd);
- if(res != RES_OK) goto error;
- } else {
- res = combustion_draw_map(cmd);
- if(res != RES_OK) goto error;
+ switch(cmd->output_type) {
+ case HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE:
+ res = combustion_draw_map(cmd);
+ break;
+ case HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET:
+ res = dump_laser_sheet(cmd);
+ break;
+ case HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES:
+ res = dump_volumetric_acceleration_structure(cmd);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ if(res != RES_OK) {
+ goto error;
}
exit:
diff --git a/src/combustion/htrdr_combustion_args.c b/src/combustion/htrdr_combustion_args.c
@@ -47,8 +47,9 @@ print_help(const char* cmd)
" flux density is %g W/m^2.\n",
HTRDR_COMBUSTION_ARGS_DEFAULT.laser_flux_density);
printf(
-" -d dump volumetric acceleration structures to OUTPUT\n"
-" and exit.\n");
+" -d <octrees|laser>\n"
+" output the volumetric acceleration structures or the\n"
+" the geometry of the laser sheet and exit.\n");
printf(
" -F <fractal-coefs>\n"
" value of the fractal prefactor and fractal dimension\n"
@@ -197,6 +198,30 @@ error:
goto exit;
}
+static res_T
+parse_dump_parameter
+ (const char* str,
+ enum htrdr_combustion_args_output_type* output_type)
+{
+ res_T res = RES_OK;
+ ASSERT(str && output_type);
+
+ if(!strcmp(str, "octrees")) {
+ *output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES;
+ } else if(!strcmp(str, "laser")) {
+ *output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET;
+ } else {
+ fprintf(stderr, "Invalid dump parameter `%s'.\n", str);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -212,7 +237,7 @@ htrdr_combustion_args_init
*args = HTRDR_COMBUSTION_ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "C:D:dF:fg:hi:l:m:NO:o:p:r:T:t:V:vw:")) != -1) {
+ while((opt = getopt(argc, argv, "C:D:d:F:fg:hi:l:m:NO:o:p:r:T:t:V:vw:")) != -1) {
switch(opt) {
case 'C':
res = htrdr_args_camera_parse(&args->camera, optarg);
@@ -222,7 +247,7 @@ htrdr_combustion_args_init
if(res == RES_OK && args->laser_flux_density <= 0) res = RES_BAD_ARG;
break;
case 'd':
- args->dump_volumetric_acceleration_structure = 1;
+ res = parse_dump_parameter(optarg, &args->output_type);
break;
case 'F':
res = cstr_parse_list(optarg, ':', parse_fractal_parameters, args);
diff --git a/src/combustion/htrdr_combustion_args.h b/src/combustion/htrdr_combustion_args.h
@@ -23,9 +23,16 @@
#include <limits.h> /* UINT_MAX support */
+enum htrdr_combustion_args_output_type {
+ HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE,
+ HTRDR_COMBUSTION_ARGS_OUTPUT_LASER_SHEET,
+ HTRDR_COMBUSTION_ARGS_OUTPUT_OCTREES,
+ HTRDR_COMBUSTION_ARGS_OUTPUT_TYPES_COUNT__
+};
+
enum htrdr_combustion_args_grid_definition_type {
- HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_FIXED,
HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_AUTO,
+ HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_FIXED,
HTRDR_COMBUSTION_ARGS_GRID_DEFINITION_TYPES_COUNT__
};
@@ -72,9 +79,9 @@ struct htrdr_combustion_args {
/* Miscellaneous parameters */
unsigned nthreads; /* Hint on the number of threads to use */
+ enum htrdr_combustion_args_output_type output_type;
int precompute_normals; /* Pre-compute the tetrahedra normals */
int force_overwriting;
- int dump_volumetric_acceleration_structure;
int verbose; /* Verbosity level */
int quit; /* Stop the command */
};
@@ -105,9 +112,9 @@ struct htrdr_combustion_args {
1, /* Optical thickness */ \
\
UINT_MAX, /* #threads */ \
+ HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE, /* Output type */ \
0, /* Precompute normals */ \
0, /* Force overwriting */ \
- 0, /* dump volumetric acceleration structure */ \
0, /* Verbose flag */ \
0 /* Stop the command */ \
}
diff --git a/src/combustion/htrdr_combustion_c.h b/src/combustion/htrdr_combustion_c.h
@@ -18,6 +18,8 @@
#ifndef HTRDR_COMBUSTION_C_H
#define HTRDR_COMBUSTION_C_H
+#include "combustion/htrdr_combustion_args.h"
+
#include "core/htrdr_accum.h"
#include "core/htrdr_args.h"
#include "core/htrdr_buffer.h"
@@ -65,7 +67,7 @@ struct htrdr_combustion {
FILE* output; /* Output stream */
struct str output_name; /* Name of the output stream */
- int dump_volumetric_acceleration_structure;
+ enum htrdr_combustion_args_output_type output_type; /* Type of output data */
ref_T ref;
struct htrdr* htrdr;
diff --git a/src/combustion/htrdr_combustion_main.c b/src/combustion/htrdr_combustion_main.c
@@ -54,7 +54,7 @@ htrdr_combustion_main(int argc, char** argv)
res = htrdr_create(&mem_default_allocator, &htrdr_args, &htrdr);
if(res != RES_OK) goto error;
- if(cmd_args.dump_volumetric_acceleration_structure
+ if(cmd_args.output_type != HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE
&& htrdr_get_mpi_rank(htrdr) != 0) {
goto exit; /* Nothing to do except for the master process */
}