commit 6c0027c4484695de150618eabd70c2005032240e
parent 929065804bbd102cc7fed988630c2925eb9d59e0
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date: Fri, 28 Feb 2025 12:39:41 +0100
Refactor code for geometry
The new sphin_geometry struct replaces the old geometry struct, now
storing geometry data as two arrays: one for vertices coordinates and
one for its indices.
This change is essential for upcoming features in the sphin library,
including the computation of quantities dependent on geometry, such as
the total flux emitted by a source (which depends on its area for
surface sources or volume for volume sources).
Additionally, this refactor abstracts the storage format, making the
library caller agnostic of how geometry is stored on disk. Instead of
handling a simple file path, the library now provides all necessary data
directly in array form.
Diffstat:
5 files changed, 191 insertions(+), 68 deletions(-)
diff --git a/src/sphin.h b/src/sphin.h
@@ -137,6 +137,31 @@ static const struct sphin_source_direction_distribution
SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL =
SPHIN_SOURCE_DIRECTION_DISTRIBUTION_NULL__;
+struct sphin_mesh {
+ const double* coords; //TODO comment
+ const size_t* indices;
+ size_t triangle_count;
+ size_t vertex_count;
+};
+#define SPHIN_MESH_NULL__ {NULL, NULL, 0, 0}
+
+static const struct sphin_mesh SPHIN_MESH_NULL = SPHIN_MESH_NULL__;
+
+struct sphin_geometry_descriptor {
+ const char* filename;
+ enum sphin_side side; // TODO comment
+ struct sphin_mesh mesh;
+};
+#define SPHIN_GEOMETRY_DESCRIPTOR_NULL__ { \
+ NULL, \
+ SPHIN_SIDE_NONE__, \
+ SPHIN_MESH_NULL__ \
+}
+static const struct sphin_geometry_descriptor
+ SPHIN_GEOMETRY_DESCRIPTOR_NULL =
+ SPHIN_GEOMETRY_DESCRIPTOR_NULL__;
+
+
/* Forward declaration
* We declare the structure sphin, but its representation remains opaque to the
* users of the programming interface exposed by star-phor-input. Thus, the user
@@ -144,6 +169,7 @@ static const struct sphin_source_direction_distribution
struct sphin; /* Library handler */
struct sphin_brdf;
struct sphin_config; /* Physical configuration */
+struct sphin_geometry;
struct sphin_sensor;
struct sphin_source;
struct sphin_source_power;
@@ -305,6 +331,22 @@ SPHIN_API res_T
sphin_sensor_ref_put
(struct sphin_sensor* sensor);
+/*******************************************************************************
+ * API of the geometry
+ ******************************************************************************/
+SPHIN_API res_T
+sphin_geometry_ref_get
+ (struct sphin_geometry* geometry);
+
+SPHIN_API res_T
+sphin_geometry_ref_put
+ (struct sphin_geometry* geometry);
+
+SPHIN_API res_T
+sphin_geometry_get_desc
+ (const struct sphin_geometry* geometry,
+ struct sphin_geometry_descriptor* desc);
+
END_DECLS
#endif /* SPHIN_H */
diff --git a/src/sphin_geometry.c b/src/sphin_geometry.c
@@ -23,65 +23,156 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define _POSIX_C_SOURCE 200112L /* for strtok_r support */
+#include "sphin_c.h"
#include "sphin_geometry.h"
+#include <star/sstl.h>
+
/*******************************************************************************
- * Local functions
+ * Helper functions
******************************************************************************/
-void
-geometry_init
- (struct mem_allocator* allocator,
- struct geometry* geom)
-{
- ASSERT(NULL != geom);
- str_init(allocator, &geom->stl_filename);
- geom->side = SPHIN_SIDE_NONE__;
-}
-void
-geometry_release
- (struct geometry* geom)
+static void
+release_geometry(ref_T* address)
{
- ASSERT(NULL != geom);
- str_release(&geom->stl_filename);
+ struct sphin_geometry* geometry = NULL;
+ struct sphin* sphin = NULL;
+
+ ASSERT(NULL != address);
+
+ geometry = CONTAINER_OF(address, struct sphin_geometry, ref);
+ str_release(&geometry->stl_filename);
+ darray_double_release(&geometry->coords);
+ darray_size_t_release(&geometry->indices);
+ sphin = geometry->sphin;
+ MEM_RM(sphin->allocator, geometry);
+ SPHIN(ref_put(sphin));
}
-res_T
-geometry_copy
- (struct geometry* dst,
- const struct geometry* src)
+static res_T
+geometry_create
+ (struct sphin* sphin,
+ const char* stl_filename,
+ struct sphin_geometry** out_geometry)
{
- ASSERT(NULL != dst);
- ASSERT(NULL != src);
- dst->side = src->side;
- return str_copy(&dst->stl_filename, &src->stl_filename);
+ struct sphin_geometry* geom = NULL;
+ res_T res = RES_OK;
+
+ ASSERT(NULL != sphin);
+ ASSERT(NULL != out_geometry);
+ ASSERT(NULL != stl_filename);
+ ASSERT('\0' != stl_filename[0]); /* Name can't be empty */
+
+ geom = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_geometry));
+ if (NULL == geom) { res = RES_MEM_ERR; goto error; }
+ ref_init(&geom->ref);
+ SPHIN(ref_get(sphin));
+ geom->sphin = sphin;
+ darray_double_init(sphin->allocator, &geom->coords);
+ darray_size_t_init(sphin->allocator, &geom->indices);
+
+ str_init(sphin->allocator, &geom->stl_filename);
+ res = str_set(&geom->stl_filename, stl_filename);
+ if (RES_OK != res) { goto error; }
+
+exit:
+ *out_geometry = geom;
+ return res;
+error:
+ if (NULL != geom) {
+ SPHIN(geometry_ref_put(geom));
+ geom = NULL;
+ }
+ goto exit;
}
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+
res_T
geometry_parse
- (struct geometry* geom,
- char* value)
+ (struct sphin* sphin,
+ char* value,
+ struct sphin_geometry** out_geom)
{
+ size_t i;
char* side = NULL;
char* filename = NULL;
char* token_ptr = NULL;
res_T res = RES_OK;
+ struct sphin_geometry* geom = NULL;
+ struct sstl* sstl = NULL;
+ struct sstl_desc sstl_desc;
+ double* coords = NULL;
+ size_t* indices = NULL;
- /* Parse side */
+ /* Create the sstl device with the same allocator and logger as the sphin
+ * handler. TODO Comment*/
+ res = sstl_create(sphin->logger, sphin->allocator, 1, &sstl);
+ if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+
+ /* Parse filename */
+ filename = strtok_r(NULL, " \t", &token_ptr);
+ if (NULL == filename){ res = RES_BAD_ARG; goto error; }
+
+ /* Create geometry */
+ res = geometry_create(sphin, filename, &geom);
+ if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+
+ coords = darray_double_data_get(&geom->coords);
+ indices = darray_size_t_data_get(&geom->indices); /* Parse side */
side = strtok_r(value, " \t", &token_ptr);
if (NULL == side){ res = RES_BAD_ARG; goto error; }
if (0 == strcmp(side, "FRONT")){ geom->side = SPHIN_SIDE_FRONT; }
else if (0 == strcmp(side, "BACK")){ geom->side = SPHIN_SIDE_BACK; }
else { res = RES_BAD_ARG; goto error; }
- /* Parse filename */
- filename = strtok_r(NULL, " \t", &token_ptr);
- if (NULL == filename){ res = RES_BAD_ARG; goto error; }
- res = str_set(&geom->stl_filename, filename);
- if (RES_OK != res) { goto error; }
+ /* Load the stl */
+ res = sstl_load(sstl, filename);
+ if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+ res = sstl_get_desc(sstl, &sstl_desc);
+ if (RES_OK != res) { res = RES_BAD_ARG; goto error; }
+ darray_double_resize(&geom->coords, sstl_desc.vertices_count*3);
+ darray_size_t_resize(&geom->indices, sstl_desc.triangles_count*3);
+ FOR_EACH(i, 0, sstl_desc.vertices_count) {
+ coords[i] = (double)sstl_desc.vertices[i];
+ }
+ FOR_EACH(i, 0, sstl_desc.triangles_count) {
+ indices[i] = (size_t)sstl_desc.indices[i];
+ }
exit:
+ sstl_ref_put(sstl);
+ *out_geom = geom;
return res;
error:
+ if (NULL != geom) {
+ SPHIN(geometry_ref_put(geom));
+ geom = NULL;
+ }
goto exit;
}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sphin_geometry_ref_get(struct sphin_geometry* geometry)
+{
+ if (NULL == geometry) {
+ return RES_BAD_ARG;
+ }
+ ref_get(&geometry->ref);
+ return RES_OK;
+}
+
+res_T
+sphin_geometry_ref_put(struct sphin_geometry* geometry)
+{
+ if (NULL == geometry) {
+ return RES_BAD_ARG;
+ }
+ ref_put(&geometry->ref, release_geometry);
+ return RES_OK;
+}
diff --git a/src/sphin_geometry.h b/src/sphin_geometry.h
@@ -28,43 +28,35 @@
#include "sphin.h"
#include <rsys/dynamic_array.h>
+#include <rsys/dynamic_array_double.h>
+#include <rsys/dynamic_array_size_t.h>
+#include <rsys/ref_count.h>
#include <rsys/str.h>
struct mem_allocator;
-struct geometry {
+struct sphin_geometry {
struct str stl_filename;
enum sphin_side side;
-};
-
-extern LOCAL_SYM void
-geometry_init
- (struct mem_allocator* allocator,
- struct geometry* geom);
-extern LOCAL_SYM void
-geometry_release
- (struct geometry* geom);
+ /* Mesh data */
+ struct darray_double coords;
+ struct darray_size_t indices;
-extern LOCAL_SYM res_T
-geometry_copy
- (struct geometry* dst,
- const struct geometry* src);
+ struct sphin* sphin;
+ ref_T ref;
+};
extern LOCAL_SYM res_T
geometry_parse
- (struct geometry* geom,
- char* value);
+ (struct sphin* sphin,
+ char* value,
+ struct sphin_geometry** out_geom);
/* Generate the dynamic array for the structure geometry and its API */
-#define DARRAY_NAME geometry /* Prefix for api functions and structures:
+#define DARRAY_NAME sphin_geometry_ptr /* Prefix for api functions and structures:
darray_geometry */
-#define DARRAY_DATA struct geometry
-/* Define the default functions for init, release and copy elements of the
- * dynamic array */
-#define DARRAY_FUNCTOR_INIT geometry_init
-#define DARRAY_FUNCTOR_RELEASE geometry_release
-#define DARRAY_FUNCTOR_COPY geometry_copy
+#define DARRAY_DATA struct sphin_geometry*
/* Generate the code */
#include <rsys/dynamic_array.h>
diff --git a/src/sphin_surface.c b/src/sphin_surface.c
@@ -41,7 +41,7 @@ struct sphin_surface {
struct str name;
struct sphin* sphin;
struct sphin_brdf* brdf;
- struct darray_geometry geometries; /* dynamic array of struct geometry. see
+ struct darray_sphin_geometry_ptr geometries; /* dynamic array of struct geometry. see
rsys/dynamic_array.h */
struct sphin_sensor* sensor;
struct sphin_source* source;
@@ -122,22 +122,22 @@ parse_geometry
struct txtrdr* txtrdr,
char* value)
{
- struct geometry geom;
+ struct sphin_geometry* geom;
res_T res = RES_OK;
ASSERT(NULL != surface);
(void) txtrdr; /* Disable unused variable warning */
- geometry_init(surface->sphin->allocator, &geom);
- res = geometry_parse(&geom, value);
+ //res = geometry_parse(&geom, value);
+ res = geometry_parse(surface->sphin, value, &geom);
if (RES_OK != res) { goto error; }
/* Append a new element (geom) to the end of the volume->geometries dynamic array */
- res = darray_geometry_push_back(&surface->geometries, &geom);
+ res = darray_sphin_geometry_ptr_push_back(&surface->geometries, &geom);
if (RES_OK != res) { goto error; }
exit:
- geometry_release(&geom);
+ // geometry_release(&geom);
return res;
error:
goto exit;
diff --git a/src/sphin_volume.c b/src/sphin_volume.c
@@ -38,7 +38,7 @@
struct sphin_volume {
struct str name;
double ka;
- struct darray_geometry geometries; /* dynamic array of struct geometry. see
+ struct darray_sphin_geometry_ptr geometries; /* dynamic array of struct geometry. see
rsys/dynamic_array.h */
struct sphin_sensor* sensor;
struct sphin* sphin;
@@ -70,7 +70,7 @@ volume_create
volume->sensor = NULL;
str_init(sphin->allocator, &volume->name);
- darray_geometry_init(sphin->allocator, &volume->geometries);
+ darray_sphin_geometry_ptr_init(sphin->allocator, &volume->geometries);
res = str_set(&volume->name, name);
if (RES_OK != res) { goto error; }
@@ -95,7 +95,7 @@ release_volume(ref_T* address)
volume = CONTAINER_OF(address, struct sphin_volume, ref);
str_release(&volume->name);
- darray_geometry_release(&volume->geometries);
+ darray_sphin_geometry_ptr_release(&volume->geometries);
sphin = volume->sphin;
sensor = volume->sensor;
MEM_RM(sphin->allocator, volume);
@@ -111,22 +111,20 @@ parse_geometry
struct txtrdr* txtrdr,
char* value)
{
- struct geometry geom;
+ struct sphin_geometry* geom;
res_T res = RES_OK;
ASSERT(NULL != volume);
(void) txtrdr; /* Disable unused variable warning */
- geometry_init(volume->sphin->allocator, &geom);
- res = geometry_parse(&geom, value);
+ res = geometry_parse(volume->sphin, value, &geom);
if (RES_OK != res) { goto error; }
/* Append a new element (geom) to the end of the volume->geometries dynamic array */
- res = darray_geometry_push_back(&volume->geometries, &geom);
+ res = darray_sphin_geometry_ptr_push_back(&volume->geometries, &geom);
if (RES_OK != res) { goto error; }
exit:
- geometry_release(&geom);
return res;
error:
goto exit;