star-phor-input

File format for describing photoreactor configurations
git clone https://www.edstar.cnrs.fr/git/star-phor-input.git
Log | Files | Refs | README | LICENSE

commit 7f9d5ba080359fba78bc21641ad301aefda4e685
parent 19d4f0f6d329078dfd74e5ee0d3e48b7c384f7be
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 26 Mar 2025 14:50:12 +0100

Merge remote-tracking branch 'origin/master'

Diffstat:
Mdoc/star-phor-input.scd | 7++++++-
Msrc/sphin_geometry.c | 13++++++++++++-
Msrc/test_sphin_load_geometry.c | 40++++++++++++++++++++++++++++++++++++----
3 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/doc/star-phor-input.scd b/doc/star-phor-input.scd @@ -60,6 +60,7 @@ tabs, spaces, or combinations of both are used, they will be ignored. Please note that in the following lines, the percent symbol (%) is used to introduce a comment in the file format description. It should not be taken into + account when writing these files, nor should anything that comes after it. Text enclosed in single quotation marks (') must be included in the entry as is, @@ -85,10 +86,14 @@ The file format describing a photoreactive system is as follows: | <sensor> | <surface-source> -<geometry> ::= 'geometry:' <side> <geom-file> +<geometry> ::= 'geometry:' <side> <geom-file> [<geom-unit>] <side> ::= 'FRONT' | 'BACK' <geom-file> ::= path % STL files only % Spaces not allowed +<geom-unit> ::= 'm' % if no unit is specified, + | 'cm' % meter is assumed + | 'mm' + | 'km' <sensor> ::= 'sensor:' 'response_function:' real diff --git a/src/sphin_geometry.c b/src/sphin_geometry.c @@ -104,10 +104,12 @@ geometry_parse char* side = NULL; char* filename = NULL; char* token_ptr = NULL; + char* unit = NULL; struct sphin_geometry* geom = NULL; struct sstl* sstl = NULL; struct sstl_desc sstl_desc; double* coords = NULL; + double scaling_factor; size_t* indices = NULL; res_T res = RES_OK; @@ -133,6 +135,15 @@ geometry_parse filename = strtok_r(NULL, " \t", &token_ptr); if (NULL == filename){ res = RES_BAD_ARG; goto error; } + /* Parse unit and evaluate scaling factor*/ + unit = strtok_r(NULL, " \t", &token_ptr); + if (NULL == unit + || 0 == strcmp(unit, "m")){scaling_factor = 1e+00;} + else if (0 == strcmp(unit, "cm")){scaling_factor = 1e-02;} + else if (0 == strcmp(unit, "mm")){scaling_factor = 1e-03;} + else if (0 == strcmp(unit, "km")){scaling_factor = 1e+03;} + else { res = RES_BAD_ARG; goto error; } + /* Create geometry */ res = geometry_create(sphin, filename, &geom); if (RES_OK != res) { goto error; } @@ -154,7 +165,7 @@ geometry_parse indices = darray_size_t_data_get(&geom->indices); FOR_EACH(i, 0, sstl_desc.vertices_count*3) { - coords[i] = (double)sstl_desc.vertices[i]; + coords[i] = (double)sstl_desc.vertices[i]*scaling_factor; } FOR_EACH(i, 0, sstl_desc.triangles_count*3) { indices[i] = (size_t)sstl_desc.indices[i]; diff --git a/src/test_sphin_load_geometry.c b/src/test_sphin_load_geometry.c @@ -25,6 +25,7 @@ #include "sphin.h" #include "test_sphin_utils.h" +#include <rsys/math.h> #include <rsys/mem_allocator.h> #include <string.h> @@ -48,8 +49,8 @@ write_stl_test_files " facet normal 0.0 0.0 -1.0\n" " outer loop\n" " vertex 0.0 0.0 0.0\n" - " vertex 1.0 0.0 0.0\n" - " vertex 0.0 1.0 0.0\n" + " vertex 1.935 0.0 0.0\n" + " vertex 0.0 0.0 3.142\n" " endloop\n" " endfacet\n" "endsolid"; @@ -168,8 +169,11 @@ test_geometry_api CHK(fp = fopen(path, "w+")); fprintf(fp, "\t\t surface : \"surface name\"\n"); fprintf(fp, "\tgeometry: FRONT test_0.stl\t\n"); - fprintf(fp, "\tgeometry: BACK test_1.stl \t\n"); + fprintf(fp, "\tgeometry: BACK test_1.stl\t\n"); fprintf(fp, "\tgeometry: BACK test_2.stl\n"); + fprintf(fp, "\tgeometry: BACK test_1.stl cm\t\n"); + fprintf(fp, "\tgeometry: BACK test_1.stl mm\t\n"); + fprintf(fp, "\tgeometry: BACK test_1.stl km\t\n"); fclose(fp); CHK(sphin_load(sphin, path, &config) == RES_OK); @@ -178,7 +182,7 @@ test_geometry_api CHK(sphin_config_get_surface(config, 0, &surface) == RES_OK); CHK(sphin_surface_get_geometry_count(NULL, &ngeometries) == RES_BAD_ARG); CHK(sphin_surface_get_geometry_count(surface, &ngeometries) == RES_OK); - CHK(ngeometries == 3); + CHK(ngeometries == 6); igeometry = 0; CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); @@ -204,6 +208,34 @@ test_geometry_api CHK(desc.mesh.vertex_count == 8); CHK(strcmp(desc.filename, "test_2.stl") == 0); + /* Test geometry units */ + + /* In the following assertions, we use an epsilon (tolerable error) of 1e-6 + * instead of the 1e-15 used elsewhere in sphin. This is because, although + * sphin performs all computations using doubles, the third-party library + * star-stl, which is used to parse STL files, handles mesh coordinates + * using floats (even though those are exposed as doubles by sphin). + * As a result, the precision of geometrical coordinates is + * limited to approximately six digits. */ + + igeometry++; + CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); + CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); + CHK(eq_eps(desc.mesh.coords[3], 0.01935, 1e-9)); + CHK(eq_eps(desc.mesh.coords[8], 0.03142, 1e-9)); + + igeometry++; + CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); + CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); + CHK(eq_eps(desc.mesh.coords[3], 0.001935, 1e-8)); + CHK(eq_eps(desc.mesh.coords[8], 0.003142, 1e-8)); + + igeometry++; + CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); + CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); + CHK(eq_eps(desc.mesh.coords[3], 1935, 1e-3)); + CHK(eq_eps(desc.mesh.coords[8], 3142, 1e-3)); + CHK(sphin_geometry_ref_get(NULL) == RES_BAD_ARG); CHK(sphin_geometry_ref_put(NULL) == RES_BAD_ARG); CHK(sphin_geometry_ref_get(geom) == RES_OK);