commit d3f57d495c3a457ae1e6020310556c742f9ef229
parent 5366b16fb09731a902a2a9f1c3b0b340f5513025
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 20 Dec 2019 10:33:06 +0100
Continue working on API
The bigger change is that callbacks for sg3_geometry_add are now grouped in a struct
Diffstat:
5 files changed, 281 insertions(+), 142 deletions(-)
diff --git a/src/sg3.h b/src/sg3.h
@@ -75,6 +75,14 @@ enum sg3_dump_content {
};
/*******************************************************************************
+ * A type to list the different qualifiers of C code variable output.
+ ******************************************************************************/
+enum sg3_cdump_qualifiers {
+ SG3_CDUMP_CONST = BIT(0),
+ SG3_CDUMP_STATIC = BIT(1)
+};
+
+/*******************************************************************************
* The value that should be used for properties attached to triangles (i.e.
* media or interface) when not defined.
* SG3_UNDEFINED_PROPERTY can be used for a property that has already been
@@ -82,6 +90,56 @@ enum sg3_dump_content {
******************************************************************************/
#define SG3_UNDEFINED_PROPERTY UINT_MAX
+ /*******************************************************************************
+ * A type to hold callbacks for sg3_geometry_add.
+ ******************************************************************************/
+struct sg3_geometry_add_callbacks {
+ /* User function that provides vertices ids for added triangles */
+ void(*get_indices)
+ (const unsigned itri, unsigned ids[3], void* context);
+ /* User function that provides properties for added triangles */
+ void(*get_properties) /* Can be NULL <=> SG3_UNDEFINED_PROPERTY used */
+ (const unsigned itri,
+ /* It is OK to have side and interface properties sharing the same IDs,
+ * i.e. side and interface IDs both starting from 0 */
+ unsigned properties[SG3_PROP_TYPES_COUNT__],
+ void* context);
+ /* User function that provides coordinates for added vertices */
+ void(*get_position)
+ (const unsigned ivert, double pos[3], void* context);
+ /* Called for each new triangle so that the client app can manage its own
+ * triangle data/properties/attributes.
+ * If return is not RES_OK, sg3_geometry_add stops immediately and returns
+ * whatever value add_triangle returned. */
+ res_T(*add_triangle) /* Can be NULL */
+ (const unsigned global_id, const unsigned itri, void* context);
+ /* Called if the itri_th triangle of the current sg3_geometry_add is equal
+ * to the global_id_th global triangle so that the client app can merge
+ * its own triangle data, rule merge validity, and possibly change the
+ * recorded properties.
+ * The reversed_triangle arg indicates if the triangle vertices' order is
+ * the same it was when the triangle was first added.
+ * The merge_conflict_status argument can be set to any value. Any non-0
+ * value is accounted for a conflict and is kept as-is in dumps, allowing
+ * different shades of conflict.
+ * The triangle_properties and merged_properties args contain the involved
+ * properties. */
+ res_T(*merge_triangle) /* Can be NULL */
+ (const unsigned global_id,
+ const unsigned itri,
+ const int reversed_triangle,
+ unsigned triangle_properties[SG3_PROP_TYPES_COUNT__],
+ const unsigned merged_properties[SG3_PROP_TYPES_COUNT__],
+ void* context,
+ int* merge_conflict_status);
+ /* Called if the itri_th triangle is degenerated. According to the value
+ * of abort, sg3_geometry_add will stop and return RES_BAD_ARG or continue
+ * silently. */
+ res_T(*degenerated_triangle) /* Can be NULL <=> Drop triangle, don't abort */
+ (const unsigned itri, void* context, int* abort);
+};
+#define SG3_ADD_CALLBACKS_NULL__ { NULL, NULL, NULL, NULL, NULL, NULL }
+
BEGIN_DECLS
/*******************************************************************************
@@ -128,6 +186,14 @@ sg3_geometry_create
(struct sg3_device* dev,
struct sg3_geometry** geometry);
+/* Reserve memory according to anticipated geometry size. */
+SG3_API res_T
+sg3_geometry_reserve
+ (struct sg3_geometry* geometry,
+ const unsigned vertices_count,
+ const unsigned triangles_count,
+ const unsigned properties_count);
+
/* Add a new set of 3D vertices and triangles to the geometry; triangles can
* be decorated with 3 properties (front and back media and interface) that can
* be let undefined using the SG3_UNDEFINED_PROPERTY special value.
@@ -159,46 +225,9 @@ sg3_geometry_create
SG3_API res_T
sg3_geometry_add
(struct sg3_geometry* geometry,
- /* Number of added triangles */
const unsigned triangles_count,
- /* User function that provides vertices ids for added triangles */
- void(*indices)(const unsigned itri, unsigned ids[3], void* context),
- /* User function that provides properties for added triangles */
- void(*properties) /* Can be NULL <=> SG3_UNDEFINED_PROPERTY used */
- (const unsigned itri,
- /* It is OK to have side and interface properties sharing the same IDs,
- * i.e. side and interface IDs both starting from 0 */
- unsigned properties[SG3_PROP_TYPES_COUNT__],
- void* context),
- /* Number of added vertices */
const unsigned vertices_count,
- /* User function that provides coordinates for added vertices */
- void(*position)(const unsigned ivert, double pos[3], void* context),
- /* Called for each new triangle so that the client app can manage its own
- * triangle data/properties/attributes.
- * If return is not RES_OK, sg3_geometry_add stops immediately and returns
- * whatever value add_triangle returned. */
- res_T(*add_triangle) /* Can be NULL */
- (const unsigned global_id, const unsigned itri, void* context),
- /* Called if the itri_th triangle of the current sg3_geometry_add is equal
- * to the global_id_th global triangle so that the client app can merge
- * its own triangle data, rule merge validity, and possibly change the
- * recorded properties.
- * The reversed_triangle arg indicates if the triangle vertices' order is
- * the same it was when the triangle was first added.
- * The merge_conflict_status argument can be set to any value. Any non-0
- * value is accounted for a conflict and is kept as-is in dumps, allowing
- * different shades of conflict.
- * The triangle_properties and merged_properties args contain the involved
- * properties. */
- res_T(*merge_triangle) /* Can be NULL */
- (const unsigned global_id,
- const unsigned itri,
- const int reversed_triangle,
- unsigned triangle_properties[SG3_PROP_TYPES_COUNT__],
- const unsigned merged_properties[SG3_PROP_TYPES_COUNT__],
- void* context,
- int* merge_conflict_status),
+ const struct sg3_geometry_add_callbacks* callbacks,
void* context); /* Can be NULL */
/* Apply a validation callback on each triangle included in this geometry that
@@ -322,15 +351,20 @@ sg3_geometry_dump_as_vtk
/* Dump the geometry as C code.
* The geometry cannot be empty and must be conflict-free.
* The C code defines the 3 variables:
- * - const double <name_prefix>_vertices[<N1>] = { .... };
- * - const unsigned <name_prefix>_triangles[<N2>] = { .... };
- * - const unsigned <name_prefix>_properties[<N2>] = { .... };
-* Where <N1> is 3 * vertices_count and <N2> is 3 * triangles_count. */
+ * - [static] [const] double <name_prefix>_vertices[<N1>] = { .... };
+ * - [static] [const] unsigned <name_prefix>_vertices_count = N1;
+ * - [static] [const] unsigned <name_prefix>_triangles[<N2>] = { .... };
+ * - [static] [const] unsigned <name_prefix>_triangles_count = N2;
+ * - [static] [const] unsigned <name_prefix>_properties[<N2>] = { .... };
+ * Where <N1> is 3 * vertices_count and <N2> is 3 * triangles_count.
+ * The two qualifiers static and const are output or not according to flags;
+ * flags must be ORed enum sg3_cdump_qualifiers values. */
SG3_API res_T
sg3_geometry_dump_as_C_code
(const struct sg3_geometry* geometry,
FILE* stream,
- const char* name_prefix); /* Can be NULL or "" */
+ const char* name_prefix, /* Can be NULL or "" */
+ const int flags);
SG3_API res_T
sg3_geometry_ref_get
diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c
@@ -331,17 +331,34 @@ error:
}
res_T
+sg3_geometry_reserve
+ (struct sg3_geometry* geom,
+ const unsigned vertices_count,
+ const unsigned triangles_count,
+ const unsigned properties_count)
+{
+ res_T res = RES_OK;
+ if(!geom) return RES_BAD_ARG;
+
+ ERR(darray_triangle_reserve(&geom->unique_triangles, triangles_count));
+ ERR(darray_vertex_reserve(&geom->unique_vertices, vertices_count));
+ ERR(htable_vrtx_reserve(&geom->unique_vertices_ids, vertices_count));
+ ERR(htable_trg_reserve(&geom->unique_triangles_ids, triangles_count));
+ ERR(darray_trg_descriptions_reserve(&geom->trg_descriptions,
+ properties_count));
+
+end:
+ return res;
+error:
+ goto end;
+}
+
+res_T
sg3_geometry_add
(struct sg3_geometry* geom,
const unsigned ntris,
- void(*indices)(const unsigned, unsigned*, void*),
- void(*properties)(const unsigned, unsigned*, void*), /* Can be NULL */
const unsigned nverts,
- void(*position)(const unsigned, double*, void*),
- res_T(*add_trg)(const unsigned, const unsigned, void*), /* Can be NULL */
- res_T(*merge_trg) /* Can be NULL */
- (const unsigned, const unsigned, const int, unsigned*, const unsigned*,
- void*, int*),
+ const struct sg3_geometry_add_callbacks* callbacks,
void* ctx) /* Can be NULL */
{
res_T res = RES_OK;
@@ -354,8 +371,10 @@ sg3_geometry_add
struct triangle* trg;
/* Tmp table of IDs to record unique IDs of the currently added vertices */
struct darray_uint unique_vertice_ids;
+ int unique_vertice_ids_initialized = 0;
- if(!geom || !indices || !position) {
+ if(!geom || !callbacks || !callbacks->get_indices || !callbacks->get_position)
+ {
res = RES_BAD_ARG;
goto error;
}
@@ -366,6 +385,7 @@ sg3_geometry_add
/* Make room for new geometry; suppose no more duplicates */
darray_uint_init(alloc, &unique_vertice_ids);
+ unique_vertice_ids_initialized = 1;
ERR(darray_uint_reserve(&unique_vertice_ids, nverts));
ERR(darray_vertex_reserve(&geom->unique_vertices, nuverts + nverts));
ERR(darray_triangle_reserve(&geom->unique_triangles, nutris + ntris));
@@ -378,7 +398,7 @@ sg3_geometry_add
unsigned* p_vrtx;
struct vertex tmp;
unsigned unique_v;
- position(i, tmp.coord, ctx);
+ callbacks->get_position(i, tmp.coord, ctx);
p_vrtx = htable_vrtx_find(&geom->unique_vertices_ids, &tmp);
if(p_vrtx) {
/* Duplicate vertex */
@@ -408,7 +428,7 @@ sg3_geometry_add
/* Triangle index in user world regardless of deduplication. */
tmp.global_id = (geom->triangle_count_including_duplicates + i);
- indices(i, tmp.vertex_ids, ctx);
+ callbacks->get_indices(i, tmp.vertex_ids, ctx);
FOR_EACH(j, 0, 3) {
if(tmp.vertex_ids[j] >= nverts) {
res = RES_BAD_ARG;
@@ -422,13 +442,23 @@ sg3_geometry_add
|| tmp.vertex_ids[0] == tmp.vertex_ids[2]
|| tmp.vertex_ids[1] == tmp.vertex_ids[2])
{
- log_err(geom->dev, "%s: triangle %u is degenerate.\n",
- FUNC_NAME, tmp.global_id);
- res = RES_BAD_ARG;
- goto error;
+ int abort = 0;
+ if(callbacks->degenerated_triangle) {
+ /* Let the client app rule. */
+ ERR(callbacks->degenerated_triangle(i, ctx, &abort));
+ } else {
+ log_warn(geom->dev, "%s: triangle %u is degenerated.\n",
+ FUNC_NAME, i);
+ }
+ if(abort) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ else continue;
}
/* Get properties */
- if(properties) properties(i, tmp.properties, ctx);
+ if(callbacks->get_properties)
+ callbacks->get_properties(i, tmp.properties, ctx);
/* Find duplicate triangles */
reversed = trg_make_key(&trg_key, tmp.vertex_ids);
p_trg = htable_trg_find(&geom->unique_triangles_ids, &trg_key);
@@ -446,10 +476,11 @@ sg3_geometry_add
if(!same)
SWAP(unsigned, tmp.properties[SG3_FRONT], tmp.properties[SG3_BACK]);
already_conflict = trg_descriptions[i].merge_conflict;
- if(merge_trg) {
+ if(callbacks->merge_triangle) {
/* Let the client app rule. */
- ERR(merge_trg(trg[*p_trg].global_id, i, same, trg[*p_trg].properties,
- tmp.properties, ctx, &trg_descriptions[i].merge_conflict));
+ ERR(callbacks->merge_triangle(trg[*p_trg].global_id, i, same,
+ trg[*p_trg].properties, tmp.properties, ctx,
+ &trg_descriptions[i].merge_conflict));
} else {
FOR_EACH(j, 0, SG3_PROP_TYPES_COUNT__) {
if(!sg3_compatible_property(trg[*p_trg].properties[j],
@@ -475,8 +506,8 @@ sg3_geometry_add
/* New triangle */
ASSERT(nutris + actual_nutris < UINT_MAX);
unique_id = (unsigned)(nutris + actual_nutris);
- if(add_trg)
- ERR(add_trg(tmp.global_id, i, ctx));
+ if(callbacks->add_triangle)
+ ERR(callbacks->add_triangle(tmp.global_id, i, ctx));
ERR(geometry_enlarge_trg_descriptions(geom, 1 + unique_id));
trg_descriptions
= darray_trg_descriptions_data_get(&geom->trg_descriptions);
@@ -502,10 +533,12 @@ sg3_geometry_add
ASSERT(nutris + actual_nutris
== htable_trg_size_get(&geom->unique_triangles_ids));
exit:
- geom->set_id++;
- darray_uint_release(&unique_vertice_ids);
- /* Update sizes */
- geom->triangle_count_including_duplicates += actual_ntris;
+ if(geom) {
+ geom->set_id++;
+ geom->triangle_count_including_duplicates += actual_ntris;
+ }
+ if(unique_vertice_ids_initialized)
+ darray_uint_release(&unique_vertice_ids);
return res;
error:
goto exit;
@@ -904,15 +937,18 @@ exit:
error:
goto exit;
}
+
res_T
sg3_geometry_dump_as_C_code
(const struct sg3_geometry* geom,
FILE* stream,
- const char* name_prefix)
+ const char* name_prefix,
+ const int flags)
{
res_T res = RES_OK;
const struct vertex* vertices;
const struct triangle* triangles;
+ const char* qualifiers;
size_t vsz, tsz, i;
if(!geom || !stream
|| geom->merge_conflict_count
@@ -934,7 +970,10 @@ sg3_geometry_dump_as_C_code
}
if(!name_prefix) name_prefix = "";
/* Headers */
- fprintf(stream, "/* Dump of star-geometry. */\n");
+ if(name_prefix && name_prefix[0] != '\0')
+ fprintf(stream, "/* Dump of star-geometry '%s'. */\n", name_prefix);
+ else
+ fprintf(stream, "/* Dump of star-geometry. */\n");
vsz = darray_vertex_size_get(&geom->unique_vertices);
ASSERT(3 * vsz <= UINT_MAX);
tsz = darray_triangle_size_get(&geom->unique_triangles);
@@ -949,11 +988,18 @@ sg3_geometry_dump_as_C_code
}
/* Dump vertices */
+ if(flags & SG3_CDUMP_CONST && flags & SG3_CDUMP_STATIC)
+ qualifiers = "static const ";
+ else if(flags & SG3_CDUMP_CONST)
+ qualifiers = "const ";
+ else if(flags & SG3_CDUMP_STATIC)
+ qualifiers = "static ";
+ else qualifiers = "";
vertices = darray_vertex_cdata_get(&geom->unique_vertices);
fprintf(stream,
- "const double %s_vertices[%u] =\n"
+ "%sdouble %s_vertices[%u] =\n"
" {\n",
- name_prefix, (unsigned)(3 * vsz));
+ qualifiers, name_prefix, (unsigned)(3 * vsz));
FOR_EACH(i, 0, vsz - 1)
fprintf(stream,
" %f, %f, %f,\n", SPLIT3(vertices[i].coord));
@@ -961,13 +1007,15 @@ sg3_geometry_dump_as_C_code
" %f, %f, %f\n", SPLIT3(vertices[vsz - 1].coord));
fprintf(stream,
"};\n");
+ fprintf(stream, "%sunsigned %s_vertices_count = %u;\n",
+ qualifiers, name_prefix, (unsigned)vsz);
/* Dump triangles */
triangles = darray_triangle_cdata_get(&geom->unique_triangles);
fprintf(stream,
- "const unsigned %s_triangles[%u] =\n"
+ "%sunsigned %s_triangles[%u] =\n"
" {\n",
- name_prefix, (unsigned)(3 * tsz));
+ qualifiers, name_prefix, (unsigned)(3 * tsz));
FOR_EACH(i, 0, tsz - 1)
fprintf(stream,
" %u, %u, %u,\n", SPLIT3(triangles[i].vertex_ids));
@@ -975,16 +1023,18 @@ sg3_geometry_dump_as_C_code
" %u, %u, %u\n", SPLIT3(triangles[tsz - 1].vertex_ids));
fprintf(stream,
"};\n");
+ fprintf(stream, "%sunsigned %s_triangles_count = %u;\n",
+ qualifiers, name_prefix, (unsigned)tsz);
/* Dump properties */
triangles = darray_triangle_cdata_get(&geom->unique_triangles);
fprintf(stream,
- "const unsigned %s_properties[%u] =\n"
+ "%sunsigned %s_properties[%u] =\n"
" {\n",
- name_prefix, (unsigned)(3 * tsz));
+ qualifiers, name_prefix, (unsigned)(3 * tsz));
FOR_EACH(i, 0, tsz - 1)
fprintf(stream,
- " %u, %u, %u\n", SPLIT3(triangles[i].properties));
+ " %u, %u, %u,\n", SPLIT3(triangles[i].properties));
fprintf(stream,
" %u, %u, %u\n", SPLIT3(triangles[tsz - 1].properties));
fprintf(stream,
diff --git a/src/test_sg3_geometry.c b/src/test_sg3_geometry.c
@@ -16,8 +16,6 @@
#include "sg3.h"
#include "test_sg3_utils.h"
-#include <rsys/double3.h>
-
#include <stdio.h>
static res_T
@@ -42,13 +40,26 @@ merge_trg
void* context,
int* merge_conflict)
{
- ASSERT(merge_conflict);
+ ASSERT(triangle_properties && merged_properties && merge_conflict);
(void)global_id; (void)reversed_triangle; (void)context;
(void)triangle_properties; (void)merged_properties; (void)merge_conflict;
*merge_conflict = (int)itri;
return RES_OK;
}
+static res_T
+degenerated_triangle
+ (const unsigned itri,
+ void* context,
+ int* abort)
+{
+ struct context* ctx = context;
+ ASSERT(abort && ctx);
+ (void)itri;
+ *abort = *(int*)ctx->custom;
+ return RES_OK;
+}
+
int
main(int argc, char** argv)
{
@@ -57,10 +68,12 @@ main(int argc, char** argv)
struct sg3_geometry* geom;
double coord[3];
unsigned indices[3];
+ const unsigned degenerated[3] = { 0 , 0, 0 };
unsigned properties[SG3_PROP_TYPES_COUNT__];
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
unsigned global_id;
unsigned count, i;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
(void)argc, (void)argv;
OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
@@ -130,34 +143,52 @@ main(int argc, char** argv)
/* BA because geometry is empty */
BA(sg3_geometry_dump_as_vtk(geom, stdout));
- BA(sg3_geometry_dump_as_C_code(NULL, NULL, NULL));
- BA(sg3_geometry_dump_as_C_code(geom, NULL, NULL));
- BA(sg3_geometry_dump_as_C_code(NULL, stdout, NULL));
- BA(sg3_geometry_dump_as_C_code(NULL, NULL, "test"));
- BA(sg3_geometry_dump_as_C_code(geom, NULL, "test"));
- BA(sg3_geometry_dump_as_C_code(NULL, stdout, "test"));
+ BA(sg3_geometry_dump_as_C_code(NULL, NULL, NULL, 0));
+ BA(sg3_geometry_dump_as_C_code(geom, NULL, NULL, 0));
+ BA(sg3_geometry_dump_as_C_code(NULL, stdout, NULL, 0));
+ BA(sg3_geometry_dump_as_C_code(NULL, NULL, "test", 0));
+ BA(sg3_geometry_dump_as_C_code(geom, NULL, "test", 0));
+ BA(sg3_geometry_dump_as_C_code(NULL, stdout, "test", 0));
/* BA because geometry is empty */
- BA(sg3_geometry_dump_as_C_code(geom, stdout, NULL));
- BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, NULL, 0));
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, "test", 0));
+
+ BA(sg3_geometry_add(NULL, 0, 0, &callbacks, NULL));
+ BA(sg3_geometry_add(geom, ntriangles, nvertices, NULL, NULL));
+ /* Mandatory callbacks are NULL */
+ callbacks.get_indices = NULL;
+ callbacks.get_position = get_position;
+ BA(sg3_geometry_add(geom, 0, 0, &callbacks, NULL));
+ callbacks.get_indices = get_indices;
+ callbacks.get_position = NULL;
+ BA(sg3_geometry_add(geom, 0, 0, &callbacks, NULL));
+ callbacks.get_indices = NULL;
+ callbacks.get_position = NULL;
+ BA(sg3_geometry_add(geom, 0, 0, &callbacks, NULL));
+ /* Add 0 items */
+ callbacks.get_indices = get_indices;
+ callbacks.get_position = get_position;
+ OK(sg3_geometry_add(geom, 0, 0, &callbacks, NULL));
/* A 3D cube.
* 2 enclosures (inside, outside) sharing the same triangles,
* but opposite sides */
ctx.positions = cube_vertices;
ctx.indices = cube_indices;
- ctx.scale = 1;
- d3(ctx.offset, 0, 0, 0);
ctx.front_media = medium0;
ctx.back_media = medium1;
ctx.intface = intface0;
- ctx.custom = NULL;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, NULL, NULL, &ctx));
+ callbacks.get_indices = get_indices;
+ callbacks.get_properties = get_properties;
+ callbacks.get_position = get_position;
+
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
OK(sg3_geometry_dump_as_vtk(geom, stdout));
- OK(sg3_geometry_dump_as_C_code(geom, stdout, NULL));
- OK(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, NULL, 0));
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "test",
+ SG3_CDUMP_STATIC | SG3_CDUMP_CONST));
BA(sg3_geometry_get_unique_vertex(NULL, ntriangles, NULL));
BA(sg3_geometry_get_unique_vertex(geom, ntriangles, NULL));
@@ -201,31 +232,43 @@ main(int argc, char** argv)
CHK(global_id == 0);
/* Conflicts with merge_trg callback */
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, NULL, merge_trg, &ctx));
+ callbacks.merge_triangle = merge_trg;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
OK(sg3_geometry_get_merge_conflict_count(geom, &count));
/* Due to merge_trg internals, all but the first triangle have conflict */
CHK(count == ntriangles - 1);
OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
OK(sg3_geometry_dump_as_vtk(geom, stdout));
/* BA because of conflicts */
- BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, "test", SG3_CDUMP_STATIC));
OK(sg3_geometry_ref_put(geom));
/* Conflicts without merge_trg callback */
OK(sg3_geometry_create(dev, &geom));
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, NULL, NULL, &ctx));
+ callbacks.merge_triangle = NULL;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
ctx.front_media = medium1_front0;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, NULL, NULL, &ctx));
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
OK(sg3_geometry_get_merge_conflict_count(geom, &count));
FOR_EACH(i, 0, ntriangles) if(medium0[i] != medium1_front0[i]) count--;
CHK(count == 0);
OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
OK(sg3_geometry_dump_as_vtk(geom, stdout));
/* BA because of conflicts */
- BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, "test", SG3_CDUMP_CONST));
+
+ /* Degenerated triangles */
+ ctx.indices = degenerated;
+ /* Without callback : OK */
+ OK(sg3_geometry_add(geom, 1, nvertices, &callbacks, &ctx));
+ /* With callback : OK */
+ callbacks.degenerated_triangle = degenerated_triangle;
+ ctx.custom = &i;
+ i = 0;
+ OK(sg3_geometry_add(geom, 1, nvertices, &callbacks, &ctx));
+ /* With callback : KO */
+ i= 1;
+ BA(sg3_geometry_add(geom, 1, nvertices, &callbacks, &ctx));
OK(sg3_geometry_ref_put(geom));
OK(sg3_device_ref_put(dev));
diff --git a/src/test_sg3_geometry_2.c b/src/test_sg3_geometry_2.c
@@ -16,8 +16,6 @@
#include "sg3.h"
#include "test_sg3_utils.h"
-#include <rsys/double3.h>
-
#include <stdio.h>
/* Manage add_geometry behaviour */
@@ -94,7 +92,8 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct sg3_device* dev;
struct sg3_geometry* geom;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
struct add_geom_ctx add_geom_ctx;
unsigned property[12];
unsigned i;
@@ -111,8 +110,6 @@ main(int argc, char** argv)
* but opposite sides */
ctx.positions = cube_vertices;
ctx.indices = cube_indices;
- ctx.scale = 1;
- d3(ctx.offset, 0, 0, 0);
ctx.custom = &add_geom_ctx;
add_geom_ctx.add_cpt = add_geom_ctx.merge_cpt = 0;
@@ -124,18 +121,23 @@ main(int argc, char** argv)
ctx.back_media = property;
ctx.intface = property;
+ callbacks.get_indices = get_indices;
+ callbacks.get_properties = get_properties;
+ callbacks.get_position = get_position;
+ callbacks.add_triangle = add_trg;
+ callbacks.merge_triangle = merge_trg;
+
/* If add fails, add geometry fails the same way */
add_geom_ctx.add_res = RES_BAD_ARG;
- BA(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+
+ BA(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.add_cpt == 0);
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
CHK(count == nvertices);
OK(sg3_geometry_get_unique_triangles_count(geom, &count));
CHK(count == 0);
add_geom_ctx.add_res = RES_MEM_ERR;
- ME(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ ME(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.add_cpt == 0);
CHK(count == 0);
OK(sg3_geometry_get_unique_triangles_count(geom, &count));
@@ -151,8 +153,7 @@ main(int argc, char** argv)
/* Successful add geometry with add callback */
add_geom_ctx.add_res = RES_OK;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.add_cpt == ntriangles);
CHK(add_geom_ctx.merge_cpt == 0);
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
@@ -174,8 +175,8 @@ main(int argc, char** argv)
/* Successful add geometry without add callback */
add_geom_ctx.add_cpt = 0;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, NULL, merge_trg, &ctx));
+ callbacks.add_triangle = NULL;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.add_cpt == 0);
CHK(add_geom_ctx.merge_cpt == 0);
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
@@ -193,12 +194,11 @@ main(int argc, char** argv)
/* If merge fails, add geometry fails the same way */
add_geom_ctx.merge_res = RES_BAD_ARG;
- BA(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ callbacks.add_triangle = add_trg;
+ BA(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == 0);
add_geom_ctx.merge_res = RES_MEM_ERR;
- ME(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ ME(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == 0);
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
CHK(count == nvertices);
@@ -214,8 +214,8 @@ main(int argc, char** argv)
CHK(count == 0);
/* Successful add geometry without merge callback */
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, NULL, &ctx));
+ callbacks.merge_triangle = NULL;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == 0);
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
CHK(count == nvertices);
@@ -232,8 +232,8 @@ main(int argc, char** argv)
/* Successful add geometry with merge callback */
add_geom_ctx.merge_res = RES_OK;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ callbacks.merge_triangle = merge_trg;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == ntriangles);
add_geom_ctx.merge_cpt = 0;
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
@@ -260,10 +260,8 @@ main(int argc, char** argv)
/* Successful add geometry with add callback
* First half of the triangles, then all of them */
add_geom_ctx.add_res = RES_OK;
- OK(sg3_geometry_add(geom, ntriangles / 2, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ OK(sg3_geometry_add(geom, ntriangles / 2, nvertices, &callbacks, &ctx));
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.add_cpt == ntriangles);
CHK(add_geom_ctx.merge_cpt == ntriangles / 2);
add_geom_ctx.add_cpt = 0;
@@ -288,8 +286,8 @@ main(int argc, char** argv)
/* Successful add geometry with add callback and no defined properties */
add_geom_ctx.add_res = RES_OK;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, NULL, nvertices,
- get_position, add_trg, merge_trg, &ctx));
+ callbacks.get_properties = NULL;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.add_cpt == ntriangles);
CHK(add_geom_ctx.merge_cpt == 0);
add_geom_ctx.add_cpt = 0;
@@ -311,8 +309,8 @@ main(int argc, char** argv)
/* Successful add geometry with merge callback and properties */
add_geom_ctx.merge_res = RES_OK;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ callbacks.get_properties = get_properties;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == ntriangles);
add_geom_ctx.merge_cpt = 0;
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
@@ -333,8 +331,8 @@ main(int argc, char** argv)
ctx.back_media = medium0;
/* Add geometry without merge callback and conflicts */
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, NULL, &ctx));
+ callbacks.merge_triangle = NULL;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == 0);
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
CHK(count == nvertices);
@@ -354,8 +352,8 @@ main(int argc, char** argv)
/* Successful add geometry with merge callback */
add_geom_ctx.merge_res = RES_OK;
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ callbacks.merge_triangle = merge_trg;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
CHK(add_geom_ctx.merge_cpt == ntriangles);
add_geom_ctx.merge_cpt = 0;
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
@@ -376,8 +374,7 @@ main(int argc, char** argv)
OK(sg3_geometry_create(dev, &geom));
/* Successful add geometry with merge callback */
- OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
OK(sg3_geometry_get_merge_conflict_count(geom, &count));
CHK(count == 0);
diff --git a/src/test_sg3_utils.h b/src/test_sg3_utils.h
@@ -53,6 +53,17 @@ static const double cube_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = {
1.0, 1.0, 1.0
};
static const unsigned nvertices = sizeof(cube_vertices) / sizeof(double[3]);
+/* Distorded cube */
+static const double box_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = {
+ 0.1, 0.0, 0.0,
+ 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 1.0, 1.0, 0.0,
+ 0.0, 0.0, 1.1,
+ 1.0, 0.0, 1.0,
+ 0.0, 1.0, 1.0,
+ 1.0, 1.1, 1.0
+};
/* The following array lists the indices toward the 3D vertices of each
* triangle.
@@ -85,7 +96,11 @@ struct context {
void* custom;
double offset[3];
double scale;
+ char reverse_vrtx, reverse_med;
};
+#define CONTEXT_NULL__ {\
+ NULL, NULL, NULL, NULL, NULL, NULL, {0,0,0}, 1, 0, 0\
+}
static const unsigned medium0[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static const unsigned medium1[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
@@ -103,8 +118,8 @@ get_indices(const unsigned itri, unsigned ids[3], void* context)
const struct context* ctx = context;
ASSERT(ids && ctx);
ids[0] = ctx->indices[itri * 3 + 0];
- ids[1] = ctx->indices[itri * 3 + 1];
- ids[2] = ctx->indices[itri * 3 + 2];
+ ids[ctx->reverse_vrtx ? 2 : 1] = ctx->indices[itri * 3 + 1];
+ ids[ctx->reverse_vrtx ? 1 : 2] = ctx->indices[itri * 3 + 2];
}
static INLINE void
@@ -122,8 +137,8 @@ get_properties(const unsigned itri, unsigned medium[3], void* context)
{
const struct context* ctx = context;
ASSERT(medium && ctx);
- medium[SG3_FRONT] = ctx->front_media[itri];
- medium[SG3_BACK] = ctx->back_media[itri];
+ medium[ctx->reverse_med ? SG3_BACK : SG3_FRONT] = ctx->front_media[itri];
+ medium[ctx->reverse_med ? SG3_FRONT : SG3_BACK] = ctx->back_media[itri];
medium[SG3_INTFACE] = ctx->intface[itri];
}