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:
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);