commit e4d1fb74cbb9621d625adfed182c990f1a72c554
parent ec8bd77a3b42a4c7e397d09c7ac5f16faf327f80
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 4 Dec 2019 16:44:43 +0100
Improve tests
Diffstat:
9 files changed, 595 insertions(+), 51 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -123,6 +123,7 @@ if(NOT NO_TEST)
new_test(test_sg3_device)
new_test(test_sg3_geometry)
new_test(test_sg3_report)
+ new_test(test_sg3_report_2)
endif()
################################################################################
diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c
@@ -37,7 +37,6 @@ geometry_release(ref_T* ref)
sg3_report_ref_put(geometry->report);
/* Don't reset geometry->report->associated!!! */
}
-
MEM_RM(geometry->dev->allocator, geometry);
}
@@ -355,7 +354,7 @@ exit:
geom->set_id++;
darray_uint_release(&unique_vertice_ids);
/* Update sizes */
- geom->triangle_count_including_duplicates += ntris;
+ geom->triangle_count_including_duplicates += actual_ntris;
return res;
error:
goto exit;
diff --git a/src/sg3_report.c b/src/sg3_report.c
@@ -30,7 +30,6 @@ report_release(ref_T* ref)
ASSERT(ref);
report = CONTAINER_OF(ref, struct sg3_report, ref);
v_n_t_ref_put(report->v_n_t);
- darray_accumulated_set_release(&report->accumulated_sets);
darray_trg_descriptions_release(&report->trg_descriptions);
MEM_RM(report->dev->allocator, report);
}
@@ -44,15 +43,27 @@ report_record_triangle
const struct triangle* triangle,
const unsigned triangle_unique_id,
const unsigned set_id,
+ /* The conflict code as returned by user callback; if no callback provided
+ * set_id is 0 or 1 according to media equality / SG3_UNDEFINED_PROPERTY */
const int merge_conflict)
{
res_T res = RES_OK;
struct trg_descriptions* trg_d;
+ size_t sz;
int i;
+ char keep_prop_def[SG3_PROP_TYPES_COUNT__];
- ASSERT(report && triangle
- && set_id < darray_accumulated_set_size_get(&report->accumulated_sets));
+ ASSERT(report && triangle);
+ sz = darray_trg_descriptions_size_get(&report->trg_descriptions);
+ if(triangle_unique_id >= sz) {
+ ERR(darray_trg_descriptions_resize(&report->trg_descriptions,
+ 1 + triangle_unique_id));
+ ASSERT(0 <= 1 + triangle_unique_id - sz
+ && 1 + triangle_unique_id - sz < UINT_MAX);
+ report->undef_side_count += (unsigned)(1 + triangle_unique_id - sz);
+ report->undef_intface_count += (unsigned)(1 + triangle_unique_id - sz);
+ }
trg_d = (darray_trg_descriptions_data_get(&report->trg_descriptions)
+ triangle_unique_id);
/* Record information */
@@ -61,14 +72,18 @@ report_record_triangle
struct definition* defs;
int done = 0;
size_t j;
- if(triangle->properties[i] == SG3_UNDEFINED_PROPERTY) continue;
+ keep_prop_def[i] = trg_d->property_defined[i];
+ if (triangle->properties[i] == SG3_UNDEFINED_PROPERTY)
+ trg_d->defs_include_undefined = 1;
+ else trg_d->property_defined[i] = 1;
definitions = trg_d->defs + i;
defs = darray_definition_data_get(definitions);
FOR_EACH(j, 0, darray_definition_size_get(definitions)) {
if(defs[j].property_value == triangle->properties[i]) {
- /* Property already there without conflict; just add set_id */
+ /* This property_value is already registered: no conflict */
const unsigned* ids = darray_uint_cdata_get(&defs[j].set_ids);
size_t k;
+ /* Search if property_value already includes set_id */
FOR_EACH(k, 0, darray_uint_size_get(&defs[j].set_ids)) {
if(ids[k] == set_id) {
/* Same value+set_id was there already */
@@ -77,25 +92,22 @@ report_record_triangle
}
}
if(!done) {
- /* Need to add the set_id for this value */
+ /* Need to add the set_id for this property_value */
ERR(darray_uint_push_back(&defs[j].set_ids, &set_id));
done = 1;
}
break;
}
}
- ASSERT(merge_conflict|| done);
if(!done) {
- /* This value was not listed already */
- struct definition new_def;
- new_def.property_value = triangle->properties[i];
- ASSERT(merge_conflict == (darray_definition_size_get(definitions) > 0));
- darray_uint_init(report->dev->allocator, &new_def.set_ids);
- ERR(darray_uint_push_back(&new_def.set_ids, &set_id));
- darray_definition_push_back(definitions, &new_def);
- if(!trg_d->merge_conflict
- && (darray_definition_size_get(definitions) > 1))
- {
+ /* This property_value was not recorded already */
+ size_t defs_sz = darray_definition_size_get(definitions);
+ struct definition* new_def;
+ ERR(darray_definition_resize(definitions, 1 + defs_sz));
+ new_def = darray_definition_data_get(definitions) + defs_sz;
+ ERR(darray_uint_push_back(&new_def->set_ids, &set_id));
+ new_def->property_value = triangle->properties[i];
+ if(!trg_d->merge_conflict && merge_conflict) {
/* If more than 1 merge_conflict occur, the first one remains */
trg_d->merge_conflict = merge_conflict;
report->merge_conflict_count++;
@@ -103,6 +115,20 @@ report_record_triangle
}
}
+ if ((!keep_prop_def[SG3_FRONT] || !keep_prop_def[SG3_BACK])
+ && trg_d->property_defined[SG3_FRONT] && trg_d->property_defined[SG3_BACK])
+ {
+ /* Both sides are now defined */
+ ASSERT(report->undef_side_count > 0);
+ report->undef_side_count--;
+ }
+
+ if (!keep_prop_def[SG3_INTFACE] && trg_d->property_defined[SG3_INTFACE]) {
+ /* Interface is now defined */
+ ASSERT(report->undef_intface_count > 0);
+ report->undef_intface_count--;
+ }
+
exit:
return res;
error:
@@ -136,11 +162,15 @@ dump_partition
else if(partition == SG3_MERGE_CONFLICTS)
dump = trg_descriptions[i].merge_conflict;
else {
- ASSERT(partition == SG3_MERGE_CONFLICTS);
+ ASSERT(partition == SG3_PROPERTY_CONFLICTS);
dump = trg_descriptions[i].properties_conflict;
}
if(!dump) continue;
- fprintf(stream, "f %u %u %u\n", SPLIT3(triangles[i].vertex_ids));
+ fprintf(stream, "f %u %u %u\n",
+ /* OBJ indexing starts at 1 */
+ 1 + triangles[i].vertex_ids[0],
+ 1 + triangles[i].vertex_ids[1],
+ 1 + triangles[i].vertex_ids[2]);
}
}
@@ -168,10 +198,11 @@ sg3_report_create
goto error;
}
report->dev = dev;
+ report->undef_side_count = 0;
+ report->undef_intface_count = 0;
report->merge_conflict_count = 0;
report->properties_conflict_count = 0;
report->associated = 0;
- darray_accumulated_set_init(dev->allocator, &report->accumulated_sets);
darray_trg_descriptions_init(dev->allocator, &report->trg_descriptions);
ref_init(&report->ref);
@@ -237,6 +268,96 @@ error:
}
res_T
+sg3_report_get_unique_vertices_count
+ (const struct sg3_report* report,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ size_t sz;
+ if(!report || !count || !report->associated) {
+ if(report && !report->associated)
+ log_err(report->dev,
+ "%s: report is not associated to a geometry\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ sz = darray_vertex_size_get(&report->v_n_t->unique_vertices);
+ ASSERT(sz <= UINT_MAX);
+ *count = (unsigned)sz;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sg3_report_get_unique_triangles_count
+ (const struct sg3_report* report,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ size_t sz;
+ if(!report || !count || !report->associated) {
+ if(report && !report->associated)
+ log_err(report->dev,
+ "%s: report is not associated to a geometry\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ sz = darray_triangle_size_get(&report->v_n_t->unique_triangles);
+ ASSERT(sz <= UINT_MAX);
+ *count = (unsigned)sz;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sg3_report_get_triangle_with_undefined_side_count
+ (const struct sg3_report* report,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ if(!report || !count || !report->associated) {
+ if(report && !report->associated)
+ log_err(report->dev,
+ "%s: report is not associated to a geometry\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *count = report->undef_side_count;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sg3_report_get_triangle_with_undefined_interface_count
+ (const struct sg3_report* report,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ if(!report || !count || !report->associated) {
+ if(report && !report->associated)
+ log_err(report->dev,
+ "%s: report is not associated to a geometry\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *count = report->undef_intface_count;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
sg3_report_get_merge_conflict_count
(const struct sg3_report* report,
unsigned* count)
@@ -286,7 +407,7 @@ sg3_report_dump_as_obj
{
res_T res = RES_OK;
const struct vertex* vertices;
- size_t sz, i;
+ size_t vsz, tsz, i;
if(!report || !stream || !flags || !report->associated) {
if(report && !report->associated)
log_err(report->dev,
@@ -295,16 +416,15 @@ sg3_report_dump_as_obj
res = RES_BAD_ARG;
goto error;
}
- vertices = darray_vertex_cdata_get(&report->v_n_t->unique_vertices);
/* Headers */
fprintf(stream, "# Dump of star-geometry report\n");
fprintf(stream, "# Geometry counts:\n");
- sz = darray_vertex_size_get(&report->v_n_t->unique_vertices);
- ASSERT(sz <= UINT_MAX);
- fprintf(stream, "# . %u vertices\n", (unsigned)0000000000);
- sz = darray_triangle_size_get(&report->v_n_t->unique_triangles);
- ASSERT(sz <= UINT_MAX);
- fprintf(stream, "# . %u triangles\n", (unsigned)sz);
+ vsz = darray_vertex_size_get(&report->v_n_t->unique_vertices);
+ ASSERT(vsz <= UINT_MAX);
+ fprintf(stream, "# . %u vertices\n", (unsigned)vsz);
+ tsz = darray_triangle_size_get(&report->v_n_t->unique_triangles);
+ ASSERT(tsz <= UINT_MAX);
+ fprintf(stream, "# . %u triangles\n", (unsigned)tsz);
fprintf(stream,
"# . %u triangles flagged with a merge conflict\n",
report->merge_conflict_count);
@@ -313,7 +433,8 @@ sg3_report_dump_as_obj
report->merge_conflict_count);
/* Dump vertices */
- FOR_EACH(i, 0, sz)
+ vertices = darray_vertex_cdata_get(&report->v_n_t->unique_vertices);
+ FOR_EACH(i, 0, vsz)
fprintf(stream, "v %f %f %f\n", SPLIT3(vertices[i].coord));
/* Dump triangles by groups */
diff --git a/src/sg3_report.h b/src/sg3_report.h
@@ -93,6 +93,8 @@ struct trg_descriptions {
struct darray_definition defs[SG3_PROP_TYPES_COUNT__];
int merge_conflict;
int properties_conflict;
+ char defs_include_undefined;
+ char property_defined[SG3_PROP_TYPES_COUNT__];
};
static FINLINE void
@@ -102,9 +104,11 @@ init_trg_descriptions
{
int i;
ASSERT(alloc && data);
- FOR_EACH(i, 0, 3)
- darray_definition_init(alloc, data->defs + i);
+ FOR_EACH(i, 0, 3) darray_definition_init(alloc, data->defs + i);
data->merge_conflict = 0;
+ data->properties_conflict = 0;
+ data->defs_include_undefined = 0;
+ FOR_EACH(i, 0, 3) data->property_defined[i] = 0;
}
static INLINE res_T
@@ -117,6 +121,10 @@ copy_trg_descriptions
ASSERT(dst && src);
FOR_EACH(i, 0, SG3_PROP_TYPES_COUNT__)
ERR(darray_definition_copy(&dst->defs[i], &src->defs[i]));
+ dst->merge_conflict = src->merge_conflict;
+ dst->properties_conflict = src->properties_conflict;
+ dst->defs_include_undefined = src->defs_include_undefined;
+ FOR_EACH(i, 0, 3) dst->property_defined[i] = src->property_defined[i];
exit:
return res;
error:
@@ -209,13 +217,13 @@ error:
* Types to store reports amid sg3_accumulate_stl_file calls.
******************************************************************************/
struct sg3_report {
- /* Record the name + property of accumulated sets */
- struct darray_accumulated_set accumulated_sets;
/* Record which set defined what */
struct darray_trg_descriptions trg_descriptions;
/* Record unique (i.e. deduplicated) vertices and triangles */
struct v_n_t* v_n_t;
/* Counts */
+ unsigned undef_side_count;
+ unsigned undef_intface_count;
unsigned merge_conflict_count;
unsigned properties_conflict_count;
int associated;
diff --git a/src/star-geometry.h b/src/star-geometry.h
@@ -65,7 +65,7 @@ enum sg3_property_type {
};
/*******************************************************************************
- * A type to list the different user properties attached to triangles.
+ * A type to list the different possible partitions of triangles.
******************************************************************************/
enum sg3_report_dump_content {
SG3_MERGE_CONFLICTS = BIT(0),
@@ -134,6 +134,30 @@ sg3_report_validate_properties
int* properties_conflict),
void* context); /* Can be NULL */
+/* Get the number of unique vertices. */
+SG3_API res_T
+sg3_report_get_unique_vertices_count
+ (const struct sg3_report* report,
+ unsigned* count);
+
+/* Get the number of unique triangles. */
+SG3_API res_T
+sg3_report_get_unique_triangles_count
+ (const struct sg3_report* report,
+ unsigned* count);
+
+/* Get the number of triangle with (at least) one undefined side. */
+SG3_API res_T
+sg3_report_get_triangle_with_undefined_side_count
+ (const struct sg3_report* report,
+ unsigned* count);
+
+/* Get the number of triangle with undefined interface. */
+SG3_API res_T
+sg3_report_get_triangle_with_undefined_interface_count
+ (const struct sg3_report* report,
+ unsigned* count);
+
/* Get the number of triangle flagged with a merge conflict. */
SG3_API res_T
sg3_report_get_merge_conflict_count
diff --git a/src/test_sg3_geometry.c b/src/test_sg3_geometry.c
@@ -16,8 +16,6 @@
#include "star-geometry.h"
#include "test_sg3_utils.h"
-#include <rsys/logger.h>
-
int
main(int argc, char** argv)
{
diff --git a/src/test_sg3_report.c b/src/test_sg3_report.c
@@ -16,8 +16,6 @@
#include "star-geometry.h"
#include "test_sg3_utils.h"
-#include <rsys/logger.h>
-
#include <stdio.h>
static res_T
@@ -61,6 +59,30 @@ main(int argc, char** argv)
/* Not associated to a geometry */
BA(sg3_report_validate_properties(report, validate, NULL));
+ BA(sg3_report_get_unique_vertices_count(NULL, NULL));
+ BA(sg3_report_get_unique_vertices_count(report, NULL));
+ BA(sg3_report_get_unique_vertices_count(NULL, &count));
+ /* Not associated to a geometry */
+ BA(sg3_report_get_unique_vertices_count(report, &count));
+
+ BA(sg3_report_get_unique_triangles_count(NULL, NULL));
+ BA(sg3_report_get_unique_triangles_count(report, NULL));
+ BA(sg3_report_get_unique_triangles_count(NULL, &count));
+ /* Not associated to a geometry */
+ BA(sg3_report_get_unique_triangles_count(report, &count));
+
+ BA(sg3_report_get_triangle_with_undefined_side_count(NULL, NULL));
+ BA(sg3_report_get_triangle_with_undefined_side_count(report, NULL));
+ BA(sg3_report_get_triangle_with_undefined_side_count(NULL, &count));
+ /* Not associated to a geometry */
+ BA(sg3_report_get_triangle_with_undefined_side_count(report, &count));
+
+ BA(sg3_report_get_triangle_with_undefined_interface_count(NULL, NULL));
+ BA(sg3_report_get_triangle_with_undefined_interface_count(report, NULL));
+ BA(sg3_report_get_triangle_with_undefined_interface_count(NULL, &count));
+ /* Not associated to a geometry */
+ BA(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
+
BA(sg3_report_get_merge_conflict_count(NULL, NULL));
BA(sg3_report_get_merge_conflict_count(report, NULL));
BA(sg3_report_get_merge_conflict_count(NULL, &count));
@@ -85,6 +107,14 @@ main(int argc, char** argv)
OK(sg3_geometry_create(dev, report, &geometry));
OK(sg3_report_validate_properties(report, validate, NULL));
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == 0);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == 0);
+ OK(sg3_report_get_triangle_with_undefined_side_count(report, &count));
+ CHK(count == 0);
+ OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
+ CHK(count == 0);
OK(sg3_report_get_merge_conflict_count(report, &count));
CHK(count == 0);
OK(sg3_report_get_properties_conflict_count(report, &count));
@@ -92,16 +122,7 @@ main(int argc, char** argv)
OK(sg3_report_dump_as_obj(report, stdout, SG3_ALL_TRIANGLES));
OK(sg3_geometry_ref_put(geometry));
OK(sg3_report_ref_put(report));
-
- OK(sg3_report_create(dev, &report));
- OK(sg3_geometry_create(dev, report, &geometry));
-
-
-
-
- OK(sg3_geometry_ref_put(geometry));
- OK(sg3_report_ref_put(report));
-
+
OK(sg3_device_ref_put(dev));
check_memory_allocator(&allocator);
diff --git a/src/test_sg3_report_2.c b/src/test_sg3_report_2.c
@@ -0,0 +1,276 @@
+/* Copyright (C) 2016-2019 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "star-geometry.h"
+#include "test_sg3_utils.h"
+
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+ /* Manage add_geometry behaviour */
+struct add_geom_ctx {
+ unsigned add_cpt, merge_cpt;
+ res_T add_res, merge_res;
+};
+
+static res_T
+add_trg
+ (const unsigned global_id,
+ const unsigned iseg,
+ void* context)
+{
+ struct context* ctx = context;
+ struct add_geom_ctx* add_geom_ctx;
+ ASSERT(ctx); (void)global_id; (void)iseg;
+ add_geom_ctx = ctx->custom;
+ if(add_geom_ctx->add_res == RES_OK) ++add_geom_ctx->add_cpt;
+ return add_geom_ctx->add_res;
+}
+
+static res_T
+merge_trg
+ (const unsigned global_id,
+ const unsigned itri,
+ const int reversed_triangle,
+ const unsigned triangle_properties[3],
+ const unsigned merged_properties[3],
+ void* context,
+ int* merge_conflict)
+{
+ struct context* ctx = context;
+ struct add_geom_ctx* add_geom_ctx;
+ ASSERT(ctx && triangle_properties && merged_properties && merge_conflict);
+ (void)global_id; (void)itri; (void)reversed_triangle;
+ (void)triangle_properties; (void)merged_properties; (void)merge_conflict;
+ add_geom_ctx = ctx->custom;
+ if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt;
+ return add_geom_ctx->merge_res;
+}
+
+static res_T
+validate
+ (const unsigned itri,
+ const unsigned properties[3],
+ void* context,
+ int* properties_conflict)
+{
+ (void)itri; (void)properties; (void)context;
+ *properties_conflict = 0;
+ return RES_OK;
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_report* report;
+ struct sg3_geometry* geometry;
+ struct context ctx;
+ struct add_geom_ctx add_geom_ctx;
+ unsigned property[12];
+ unsigned i;
+ const unsigned property_count = sizeof(property) / sizeof(*property);
+ unsigned count;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(sg3_device_create(NULL, &allocator, 1, &dev));
+ OK(sg3_report_create(dev, &report));
+ OK(sg3_geometry_create(dev, report, &geometry));
+
+ /* 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;
+ ctx.reverse_vrtx = 0;
+ ctx.reverse_med = 0;
+ d3(ctx.offset, 0, 0, 0);
+ ctx.custom = &add_geom_ctx;
+
+ add_geom_ctx.add_cpt = add_geom_ctx.merge_cpt = 0;
+ add_geom_ctx.add_res = add_geom_ctx.merge_res = RES_OK;
+
+ /* Geometry with no media information on both sides */
+ for(i = 0; i < property_count; i++) property[i] = SG3_UNDEFINED_PROPERTY;
+ ctx.front_media = property;
+ ctx.back_media = property;
+ ctx.intface = property;
+
+ /* If add fails, add geometry fails the same way */
+ add_geom_ctx.add_res = RES_BAD_ARG;
+ BA(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.add_cpt == 0);
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == nvertices);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == 0);
+ add_geom_ctx.add_res = RES_MEM_ERR;
+ ME(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.add_cpt == 0);
+ CHK(count == 0);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == 0);
+
+ /* Successful add geometry with add callback */
+ add_geom_ctx.add_res = RES_OK;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.add_cpt == ntriangles);
+ CHK(add_geom_ctx.merge_cpt == 0);
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == nvertices);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == ntriangles);
+
+ OK(sg3_report_get_triangle_with_undefined_side_count(report, &count));
+ CHK(count == ntriangles);
+ OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
+ CHK(count == ntriangles);
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geometry));
+ /* Report has been already associated*/
+ BA(sg3_geometry_create(dev, report, &geometry));
+ OK(sg3_report_ref_put(report));
+ OK(sg3_report_create(dev, &report));
+ OK(sg3_geometry_create(dev, report, &geometry));
+
+ /* Successful add geometry without add callback */
+ add_geom_ctx.add_cpt = 0;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, NULL, merge_trg, &ctx));
+ CHK(add_geom_ctx.add_cpt == 0);
+ CHK(add_geom_ctx.merge_cpt == 0);
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == nvertices);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == ntriangles);
+
+ /* If merge fails, add geometry fails the same way */
+ add_geom_ctx.merge_res = RES_BAD_ARG;
+ BA(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.merge_cpt == 0);
+ add_geom_ctx.merge_res = RES_MEM_ERR;
+ ME(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.merge_cpt == 0);
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == nvertices);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == ntriangles);
+
+ /* Successful add geometry without merge callback */
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, NULL, &ctx));
+ CHK(add_geom_ctx.merge_cpt == 0);
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == nvertices);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == ntriangles);
+
+ /* Successful add geometry with merge callback */
+ add_geom_ctx.merge_res = RES_OK;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_media,
+ get_intface, nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.merge_cpt == ntriangles);
+ add_geom_ctx.merge_cpt = 0;
+ OK(sg3_report_get_unique_vertices_count(report, &count));
+ CHK(count == nvertices);
+ OK(sg3_report_get_unique_triangles_count(report, &count));
+ CHK(count == ntriangles);
+
+ /* Geometry with media information on both sides */
+ ctx.front_media = medium0;
+ ctx.back_media = medium1;
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geometry));
+ OK(sg3_report_ref_put(report));
+ OK(sg3_report_create(dev, &report));
+ OK(sg3_geometry_create(dev, report, &geometry));
+
+ /* Successful add geometry with add callback */
+ add_geom_ctx.add_res = RES_OK;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, NULL, NULL,
+ nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.add_cpt == ntriangles);
+ CHK(add_geom_ctx.merge_cpt == 0);
+ add_geom_ctx.add_cpt = 0;
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geometry));
+ OK(sg3_report_ref_put(report));
+ OK(sg3_report_create(dev, &report));
+ OK(sg3_geometry_create(dev, report, &geometry));
+
+ /* Successful add geometry with add callback */
+ add_geom_ctx.add_res = RES_OK;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, NULL, NULL,
+ nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.add_cpt == ntriangles);
+ CHK(add_geom_ctx.merge_cpt == 0);
+ add_geom_ctx.add_cpt = 0;
+
+ /* Successful add geometry with merge callback */
+ add_geom_ctx.merge_res = RES_OK;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, NULL, NULL,
+ nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.merge_cpt == ntriangles);
+ add_geom_ctx.merge_cpt = 0;
+
+ /* Geometry with incompatible media information on both sides */
+ ctx.front_media = medium1;
+ ctx.back_media = medium0;
+
+ /* Unsuccessful add geometry without merge callback */
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, NULL, NULL,
+ nvertices, get_position, add_trg, NULL, &ctx));
+ CHK(add_geom_ctx.merge_cpt == 0);
+
+ /* Successful add geometry with merge callback */
+ add_geom_ctx.merge_res = RES_OK;
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, NULL, NULL,
+ nvertices, get_position, add_trg, merge_trg, &ctx));
+ CHK(add_geom_ctx.merge_cpt == ntriangles);
+ add_geom_ctx.merge_cpt = 0;
+
+
+
+
+ OK(sg3_report_validate_properties(report, validate, NULL));
+ count = 1;
+ OK(sg3_report_get_merge_conflict_count(report, &count));
+ CHK(count == 0);
+ count = 1;
+ OK(sg3_report_get_properties_conflict_count(report, &count));
+ CHK(count == 0);
+ OK(sg3_report_dump_as_obj(report, stdout, SG3_ALL_TRIANGLES));
+
+ OK(sg3_geometry_ref_put(geometry));
+ OK(sg3_report_ref_put(report));
+ OK(sg3_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_sg3_utils.h b/src/test_sg3_utils.h
@@ -21,6 +21,7 @@
#define OK(Cond) CHK((Cond) == RES_OK)
#define BA(Cond) CHK((Cond) == RES_BAD_ARG)
+#define ME(Cond) CHK((Cond) == RES_MEM_ERR)
/*******************************************************************************
@@ -30,12 +31,107 @@ static INLINE void
check_memory_allocator(struct mem_allocator* allocator)
{
if(MEM_ALLOCATED_SIZE(allocator)) {
- char dump[1024];
+ char dump[80192];
MEM_DUMP(allocator, dump, sizeof(dump));
fprintf(stderr, "%s\n", dump);
FATAL("Memory leaks.\n");
}
}
+/*******************************************************************************
+ * Geometry
+ ******************************************************************************/
+/* 3D cube */
+static const double cube_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = {
+ 0.0, 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.0,
+ 1.0, 0.0, 1.0,
+ 0.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0
+};
+static const unsigned nvertices = sizeof(cube_vertices) / sizeof(double[3]);
+
+/* The following array lists the indices toward the 3D vertices of each
+ * triangle.
+ * ,2---,3 ,2----3
+ * ,' | ,'/| ,'/| \ |
+ * 6----7' / | 6' / | \ | Y
+ * |', | / ,1 | / ,0---,1 |
+ * | ',|/,' |/,' | ,' o--X
+ * 4----5' 4----5' /
+ * Front, right Back, left and Z
+ * and Top faces bottom faces */
+static const unsigned
+cube_indices[12/*#triangles*/ * 3/*#indices per triangle*/] = {
+ 0, 2, 1, 1, 2, 3, /* Front face */
+ 0, 4, 2, 2, 4, 6, /* Left face*/
+ 4, 5, 6, 6, 5, 7, /* Back face */
+ 3, 7, 1, 1, 7, 5, /* Right face */
+ 2, 6, 3, 3, 6, 7, /* Top face */
+ 0, 1, 4, 4, 1, 5 /* Bottom face */
+};
+static const unsigned
+ntriangles = sizeof(cube_indices) / (3 * sizeof(*cube_indices));
+
+struct context {
+ const double* positions;
+ const unsigned* indices;
+ const unsigned* front_media;
+ const unsigned* back_media;
+ const unsigned* intface;
+ void* custom;
+ double offset[3];
+ double scale;
+ char reverse_vrtx, reverse_med;
+};
+
+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 };
+static const unsigned medium2[12] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
+static const unsigned medium1_3[12] = { 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1 };
+static const unsigned medium1_back0[12] = { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 };
+static const unsigned medium1_front0[12] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+static const unsigned intface0[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static INLINE void
+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[ctx->reverse_vrtx ? 2 : 1] = ctx->indices[itri * 3 + 1];
+ ids[ctx->reverse_vrtx ? 1 : 2] = ctx->indices[itri * 3 + 2];
+}
+
+static INLINE void
+get_position(const unsigned ivert, double pos[3], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(pos && ctx);
+ pos[0] = ctx->positions[ivert * 3 + 0] * ctx->scale + ctx->offset[0];
+ pos[1] = ctx->positions[ivert * 3 + 1] * ctx->scale + ctx->offset[1];
+ pos[2] = ctx->positions[ivert * 3 + 2] * ctx->scale + ctx->offset[2];
+}
+
+static INLINE void
+get_media(const unsigned itri, unsigned medium[2], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(medium && ctx);
+ medium[ctx->reverse_med ? 1 : 0] = ctx->front_media[itri];
+ medium[ctx->reverse_med ? 0 : 1] = ctx->back_media[itri];
+}
+
+static INLINE void
+get_intface(const unsigned itri, unsigned* intface, void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(intface && ctx);
+ *intface = ctx->intface[itri];
+}
#endif /* TEST_SG3_UTILS_H */