commit b905addcb8c666b5384ae7a24182affbdacc557c
parent 0966c671e2044a5b6aa3857300ab3bb912a11606
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 12 Dec 2019 16:12:28 +0100
Merge sg3_report in sg3_geometry
Diffstat:
| M | cmake/CMakeLists.txt | | | 12 | ++++-------- |
| M | src/sg3_geometry.c | | | 611 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
| A | src/sg3_geometry.h | | | 291 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | src/sg3_geometry_c.h | | | 138 | ------------------------------------------------------------------------------- |
| D | src/sg3_report.c | | | 544 | ------------------------------------------------------------------------------- |
| D | src/sg3_report.h | | | 266 | ------------------------------------------------------------------------------- |
| M | src/star-geometry.h | | | 210 | +++++++++++++++++++++++++++++++++++-------------------------------------------- |
| M | src/test_sg3_geometry.c | | | 156 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
| A | src/test_sg3_geometry_2.c | | | 399 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/test_sg3_report.c | | | 79 | ++++++------------------------------------------------------------------------- |
| D | src/test_sg3_report_2.c | | | 412 | ------------------------------------------------------------------------------- |
11 files changed, 1406 insertions(+), 1712 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -37,11 +37,10 @@ include(rcmake_runtime)
include_directories(
${RSys_INCLUDE_DIR}
- ${StarEnc_INCLUDE_DIR}
- ${StarSTL_INCLUDE_DIR})
+ ${StarEnc_INCLUDE_DIR})
rcmake_append_runtime_dirs(_runtime_dirs
- RSys StarEnc StarSTL)
+ RSys StarEnc)
################################################################################
# Configure and define targets
@@ -54,7 +53,6 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SG3_FILES_SRC
sg3_device.c
sg3_geometry.c
- sg3_report.c
)
set(SG3_FILES_INC_API
@@ -62,9 +60,8 @@ set(SG3_FILES_INC_API
set(SG3_FILES_INC
sg3_device.h
- sg3_geometry_c.h
+ sg3_geometry.h
sg3_misc.h
- sg3_report.h
)
set(SG3_FILES_DOC COPYING README.md)
@@ -121,8 +118,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)
+ new_test(test_sg3_geometry_2)
endif()
################################################################################
diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c
@@ -14,9 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "star-geometry.h"
-#include "sg3_geometry_c.h"
+#include "sg3_geometry.h"
#include "sg3_device.h"
-#include "sg3_report.h"
#include <limits.h>
@@ -26,30 +25,17 @@
static void
geometry_release(ref_T* ref)
{
- struct sg3_geometry* geometry;
+ struct sg3_geometry* geom;
ASSERT(ref);
- geometry = CONTAINER_OF(ref, struct sg3_geometry, ref);
-
- v_n_t_ref_put(geometry->v_n_t);
- htable_trg_release(&geometry->unique_triangles_ids);
- htable_vrtx_release(&geometry->unique_vertices_ids);
- if(geometry->report) {
- sg3_report_ref_put(geometry->report);
- /* Don't reset geometry->report->associated!!! */
- }
- MEM_RM(geometry->dev->allocator, geometry);
-}
+ geom = CONTAINER_OF(ref, struct sg3_geometry, ref);
-static void
-v_n_t_release(ref_T* ref)
-{
- struct v_n_t* v_n_t;
- ASSERT(ref);
- v_n_t = CONTAINER_OF(ref, struct v_n_t, ref);
+ darray_triangle_release(&geom->unique_triangles);
+ darray_vertex_release(&geom->unique_vertices);
+ htable_trg_release(&geom->unique_triangles_ids);
+ htable_vrtx_release(&geom->unique_vertices_ids);
+ darray_trg_descriptions_release(&geom->trg_descriptions);
- darray_triangle_release(&v_n_t->unique_triangles);
- darray_vertex_release(&v_n_t->unique_vertices);
- MEM_RM(v_n_t->dev->allocator, v_n_t);
+ MEM_RM(geom->dev->allocator, geom);
}
static FINLINE int /* Return 1 if reversed */
@@ -108,57 +94,182 @@ trg_make_key(struct unsigned3* k, const unsigned t[3])
}
/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+geometry_register_triangle
+ (struct sg3_geometry* geom,
+ 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;
+ int i;
+ char keep_prop_def[SG3_PROP_TYPES_COUNT__];
+
+ ASSERT(geom && triangle);
+
+ ERR(geometry_enlarge_trg_descriptions(geom, triangle_unique_id + 1));
+ trg_d = (darray_trg_descriptions_data_get(&geom->trg_descriptions)
+ + triangle_unique_id);
+ /* Record information */
+ FOR_EACH(i, 0, SG3_PROP_TYPES_COUNT__) {
+ struct darray_definition* definitions;
+ struct definition* defs;
+ int done = 0;
+ size_t j;
+ 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]) {
+ /* 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 */
+ done = 1;
+ break;
+ }
+ }
+ if(!done) {
+ /* Need to add the set_id for this property_value */
+ ERR(darray_uint_push_back(&defs[j].set_ids, &set_id));
+ done = 1;
+ }
+ break;
+ }
+ }
+ if(!done) {
+ /* 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;
+ geom->merge_conflict_count++;
+ }
+ }
+ }
+
+ 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(geom->trg_with_undef_sides_count > 0);
+ geom->trg_with_undef_sides_count--;
+ }
+
+ if(!keep_prop_def[SG3_INTFACE] && trg_d->property_defined[SG3_INTFACE]) {
+ /* Interface is now defined */
+ ASSERT(geom->trg_with_undef_intface_count > 0);
+ geom->trg_with_undef_intface_count--;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static void
+dump_partition
+ (const struct sg3_geometry* geom,
+ FILE* stream,
+ const char* group_name,
+ enum sg3_dump_content partition)
+{
+ const struct trg_descriptions* trg_descriptions;
+ const struct triangle* triangles;
+ size_t sz, i;
+ ASSERT(geom && stream && group_name);
+ ASSERT(partition == SG3_MERGE_CONFLICTS
+ || partition == SG3_PROPERTY_CONFLICTS
+ || partition == SG3_VALID_TRIANGLE);
+ trg_descriptions
+ = darray_trg_descriptions_cdata_get(&geom->trg_descriptions);
+ sz = darray_trg_descriptions_size_get(&geom->trg_descriptions);
+ triangles = darray_triangle_cdata_get(&geom->unique_triangles);
+ fprintf(stream, "g %s\n", group_name);
+ FOR_EACH(i, 0, sz) {
+ int dump;
+ if(partition == SG3_VALID_TRIANGLE)
+ dump = !(trg_descriptions[i].merge_conflict
+ || trg_descriptions[i].properties_conflict);
+ else if(partition == SG3_MERGE_CONFLICTS)
+ dump = trg_descriptions[i].merge_conflict;
+ else {
+ ASSERT(partition == SG3_PROPERTY_CONFLICTS);
+ dump = trg_descriptions[i].properties_conflict;
+ }
+ if(!dump) continue;
+ 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]);
+ }
+}
+/*******************************************************************************
* Exported functions
******************************************************************************/
res_T
sg3_geometry_create
(struct sg3_device* dev,
- struct sg3_report* report, /* Can be NULL */
struct sg3_geometry** out_geometry)
{
- struct sg3_geometry* geometry = NULL;
+ struct sg3_geometry* geom = NULL;
res_T res = RES_OK;
- if(!dev || !out_geometry || (report && report->associated)) {
+ if(!dev || !out_geometry) {
res = RES_BAD_ARG;
goto error;
}
- geometry = MEM_CALLOC(dev->allocator, 1, sizeof(struct sg3_geometry));
- if(!geometry) {
+ geom = MEM_CALLOC(dev->allocator, 1, sizeof(struct sg3_geometry));
+ if(!geom) {
log_err(dev,
"%s: could not allocate the sg3_geometry.\n", FUNC_NAME);
res = RES_MEM_ERR;
goto error;
}
- geometry->dev = dev;
-
- ERR(v_n_t_create(dev, &geometry->v_n_t));
- htable_trg_init(dev->allocator, &geometry->unique_triangles_ids);
- htable_vrtx_init(dev->allocator, &geometry->unique_vertices_ids);
- geometry->triangle_count_including_duplicates = 0;
- geometry->sides_with_defined_medium_count = 0;
- geometry->set_id = 0;
- geometry->report = report;
-
- ref_init(&geometry->ref);
-
- if(report) {
- report->associated = 1;
- report->v_n_t = geometry->v_n_t;
- sg3_report_ref_get(report);
- /* The report has a reference on v_n_t */
- v_n_t_ref_get(geometry->v_n_t);
- }
+
+ darray_triangle_init(dev->allocator, &geom->unique_triangles);
+ darray_vertex_init(dev->allocator, &geom->unique_vertices);
+ htable_trg_init(dev->allocator, &geom->unique_triangles_ids);
+ htable_vrtx_init(dev->allocator, &geom->unique_vertices_ids);
+ darray_trg_descriptions_init(dev->allocator, &geom->trg_descriptions);
+ geom->triangle_count_including_duplicates = 0;
+ geom->sides_with_defined_medium_count = 0;
+ geom->set_id = 0;
+ geom->trg_with_undef_sides_count = 0;
+ geom->trg_with_undef_intface_count = 0;
+ geom->merge_conflict_count = 0;
+ geom->properties_conflict_count = 0;
+ geom->dev = dev;
+
+ ref_init(&geom->ref);
exit:
- if(out_geometry) *out_geometry = geometry;
+ if(out_geometry) *out_geometry = geom;
return res;
error:
- if(geometry) {
- if(geometry->v_n_t) v_n_t_ref_put(geometry->v_n_t);
- SG3(geometry_ref_put(geometry));
- geometry = NULL;
+ if(geom) {
+ SG3(geometry_ref_put(geom));
+ geom = NULL;
}
goto exit;
}
@@ -185,7 +296,6 @@ sg3_geometry_add
unsigned actual_nutris = 0;
unsigned i;
struct triangle* trg;
- int found_inconsistency = 0;
/* Tmp table of IDs to record unique IDs of the currently added vertices */
struct darray_uint unique_vertice_ids;
@@ -195,22 +305,18 @@ sg3_geometry_add
}
alloc = geom->dev->allocator;
- nuverts = darray_vertex_size_get(&geom->v_n_t->unique_vertices);
- nutris = darray_triangle_size_get(&geom->v_n_t->unique_triangles);
+ nuverts = darray_vertex_size_get(&geom->unique_vertices);
+ nutris = darray_triangle_size_get(&geom->unique_triangles);
/* Make room for new geometry; suppose no more duplicates */
darray_uint_init(alloc, &unique_vertice_ids);
ERR(darray_uint_reserve(&unique_vertice_ids, nverts));
- ERR(darray_vertex_reserve(&geom->v_n_t->unique_vertices, nuverts + nverts));
- ERR(darray_triangle_reserve(&geom->v_n_t->unique_triangles, nutris + ntris));
+ ERR(darray_vertex_reserve(&geom->unique_vertices, nuverts + nverts));
+ ERR(darray_triangle_reserve(&geom->unique_triangles, nutris + ntris));
ERR(htable_vrtx_reserve(&geom->unique_vertices_ids, nuverts + nverts));
ERR(htable_trg_reserve(&geom->unique_triangles_ids, nutris + ntris));
- if(geom->report) {
- ASSERT(nutris
- == darray_trg_descriptions_size_get(&geom->report->trg_descriptions));
- ERR(darray_trg_descriptions_reserve(&geom->report->trg_descriptions,
- nutris + ntris));
- }
+ ASSERT(nutris == darray_trg_descriptions_size_get(&geom->trg_descriptions));
+ ERR(darray_trg_descriptions_reserve(&geom->trg_descriptions, nutris + ntris));
/* Get vertices and deduplicate */
FOR_EACH(i, 0, nverts) {
unsigned* p_vrtx;
@@ -226,7 +332,7 @@ sg3_geometry_add
ASSERT(nuverts + actual_nuverts < UINT_MAX);
unique_v = (unsigned)(nuverts + actual_nuverts);
ASSERT(unique_v == htable_vrtx_size_get(&geom->unique_vertices_ids));
- ERR(darray_vertex_push_back(&geom->v_n_t->unique_vertices, &tmp));
+ ERR(darray_vertex_push_back(&geom->unique_vertices, &tmp));
ERR(htable_vrtx_set(&geom->unique_vertices_ids, &tmp, &unique_v));
++actual_nuverts;
}
@@ -235,15 +341,14 @@ sg3_geometry_add
}
/* Get triangles and deduplicate */
- trg = darray_triangle_data_get(&geom->v_n_t->unique_triangles);
+ trg = darray_triangle_data_get(&geom->unique_triangles);
FOR_EACH(i, 0, ntris) {
int j, reversed;
struct unsigned3 trg_key;
struct triangle tmp = TRG_UNDEF__;
unsigned* p_trg;
+ struct trg_descriptions* trg_descriptions = NULL;
unsigned unique_id;
- struct trg_descriptions trgd;
- struct trg_descriptions* p_trgd;
/* Triangle index in user world regardless of deduplication. */
tmp.global_id = (geom->triangle_count_including_duplicates + i);
@@ -279,36 +384,28 @@ sg3_geometry_add
int already_conflict;
ASSERT(trg_key_eq(&trg_key, &utrg_key));
unique_id = *p_trg;
- /* Use report or tmp storage for merge_conflict status */
- if(geom->report) {
- struct trg_descriptions* trg_descriptions;
- ERR(report_enlarge_trg_descriptions(geom->report, 1 + unique_id));
- trg_descriptions
- = darray_trg_descriptions_data_get(&geom->report->trg_descriptions);
- p_trgd = trg_descriptions + i;
- }
- else p_trgd = &trgd;
+ ERR(geometry_enlarge_trg_descriptions(geom, 1 + unique_id));
+ trg_descriptions
+ = darray_trg_descriptions_data_get(&geom->trg_descriptions);
if(!same)
SWAP(unsigned, tmp.properties[SG3_FRONT], tmp.properties[SG3_BACK]);
- already_conflict = p_trgd->merge_conflict;
+ already_conflict = trg_descriptions[i].merge_conflict;
if(merge_trg) {
/* Let the client app rule. */
ERR(merge_trg(trg[*p_trg].global_id, i, same, trg[*p_trg].properties,
- tmp.properties, ctx, &p_trgd->merge_conflict));
+ 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],
tmp.properties[j]))
{
- p_trgd->merge_conflict = 1;
+ trg_descriptions[i].merge_conflict = 1;
break;
}
}
}
- if(p_trgd->merge_conflict && !already_conflict) {
- if(geom->report) geom->report->merge_conflict_count++;
- found_inconsistency = 1;
- }
+ if(trg_descriptions[i].merge_conflict && !already_conflict)
+ geom->merge_conflict_count++;
/* Replace SG3_UNDEFINED_PROPERTY properties */
FOR_EACH(j, 0, SG3_PROP_TYPES_COUNT__) {
if(trg[*p_trg].properties[j] == SG3_UNDEFINED_PROPERTY
@@ -324,15 +421,10 @@ sg3_geometry_add
unique_id = (unsigned)(nutris + actual_nutris);
if(add_trg)
ERR(add_trg(tmp.global_id, i, ctx));
- /* Use report or tmp storage for merge_conflict status */
- if(geom->report) {
- struct trg_descriptions* trg_descriptions;
- ERR(report_enlarge_trg_descriptions(geom->report, 1 + unique_id));
- trg_descriptions
- = darray_trg_descriptions_data_get(&geom->report->trg_descriptions);
- p_trgd = trg_descriptions + i;
- } else p_trgd = &trgd;
- ERR(darray_triangle_push_back(&geom->v_n_t->unique_triangles, &tmp));
+ ERR(geometry_enlarge_trg_descriptions(geom, 1 + unique_id));
+ trg_descriptions
+ = darray_trg_descriptions_data_get(&geom->trg_descriptions);
+ ERR(darray_triangle_push_back(&geom->unique_triangles, &tmp));
FOR_EACH(j, 0, SG3_PROP_TYPES_COUNT__) {
if((j == SG3_FRONT || j == SG3_BACK)
&& tmp.properties[j] != SG3_UNDEFINED_PROPERTY)
@@ -343,14 +435,10 @@ sg3_geometry_add
++actual_nutris;
}
++actual_ntris;
- /* Register triangle in report */
- if(geom->report) {
- ERR(report_record_triangle(geom->report, &tmp, unique_id, geom->set_id,
- p_trgd->properties_conflict));
- if(p_trgd->properties_conflict) {
- geom->report->merge_conflict_count++;
- }
- }
+ ERR(geometry_register_triangle(geom, &tmp, unique_id, geom->set_id,
+ trg_descriptions[i].properties_conflict));
+ if(trg_descriptions[i].properties_conflict)
+ geom->merge_conflict_count++;
}
ASSERT(nuverts + actual_nuverts
@@ -362,76 +450,320 @@ exit:
darray_uint_release(&unique_vertice_ids);
/* Update sizes */
geom->triangle_count_including_duplicates += actual_ntris;
- return found_inconsistency ? RES_BAD_ARG : res;
+ return res;
error:
goto exit;
}
res_T
-sg3_geometry_ref_get(struct sg3_geometry* geometry)
+sg3_geometry_validate_properties
+ (struct sg3_geometry* geom,
+ res_T(*validate)(const unsigned, const unsigned*, void*, int*),
+ void* ctx)
{
- if(!geometry) return RES_BAD_ARG;
- ref_get(&geometry->ref);
- return RES_OK;
+ size_t sz__;
+ unsigned i, sz;
+ struct trg_descriptions* trg_descriptions;
+ res_T res = RES_OK;
+
+ if(!geom || !validate) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ sz__ = darray_trg_descriptions_size_get(&geom->trg_descriptions);
+ ASSERT(sz__ <= UINT_MAX);
+ sz = (unsigned)sz__;
+ trg_descriptions
+ = darray_trg_descriptions_data_get(&geom->trg_descriptions);
+ geom->properties_conflict_count = 0; /* Reset count */
+ FOR_EACH(i, 0, sz) {
+ unsigned props[3] = {
+ SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY };
+ struct trg_descriptions* trgd = trg_descriptions + i;
+ /* Validate only triangle not flagged with merge_conflict */
+ if(trgd->merge_conflict) {
+ trgd->properties_conflict = 0;
+ continue;
+ }
+ /* Get non-conflicting properties */
+ /* Call vaildation */
+ ERR(validate(i, props, ctx, &trgd->properties_conflict));
+ if(trgd->properties_conflict)
+ geom->properties_conflict_count++;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
}
res_T
-sg3_geometry_ref_put(struct sg3_geometry* geometry)
+sg3_geometry_get_unique_vertices_count
+ (const struct sg3_geometry* geom,
+ unsigned* count)
{
- if(!geometry) return RES_BAD_ARG;
- ref_put(&geometry->ref, geometry_release);
- return RES_OK;
+ res_T res = RES_OK;
+ size_t sz;
+ if(!geom || !count) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ sz = darray_vertex_size_get(&geom->unique_vertices);
+ ASSERT(sz <= UINT_MAX);
+ *count = (unsigned)sz;
+exit:
+ return res;
+error:
+ goto exit;
}
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
res_T
-v_n_t_create
- (struct sg3_device* dev,
- struct v_n_t** out_v_n_t)
+sg3_geometry_get_unique_triangles_count
+ (const struct sg3_geometry* geom,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ size_t sz;
+ if(!geom || !count) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ sz = darray_triangle_size_get(&geom->unique_triangles);
+ ASSERT(sz <= UINT_MAX);
+ *count = (unsigned)sz;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sg3_geometry_get_triangle_with_undefined_side_count
+ (const struct sg3_geometry* geom,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ if(!geom || !count) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *count = geom->trg_with_undef_sides_count;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sg3_geometry_get_triangle_with_undefined_interface_count
+ (const struct sg3_geometry* geom,
+ unsigned* count)
{
- struct v_n_t* v_n_t = NULL;
res_T res = RES_OK;
+ if(!geom || !count) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *count = geom->trg_with_undef_intface_count;
+exit:
+ return res;
+error:
+ goto exit;
+}
- if(!dev || !out_v_n_t) {
+res_T
+sg3_geometry_get_merge_conflict_count
+ (const struct sg3_geometry* geom,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ if(!geom || !count) {
res = RES_BAD_ARG;
goto error;
}
+ *count = geom->merge_conflict_count;
+exit:
+ return res;
+error:
+ goto exit;
+}
- v_n_t = MEM_CALLOC(dev->allocator, 1, sizeof(struct v_n_t));
- if(!v_n_t) {
- log_err(dev,
- "%s: could not allocate the star-geometry v_n_t.\n", FUNC_NAME);
- res = RES_MEM_ERR;
+res_T
+sg3_geometry_get_properties_conflict_count
+ (const struct sg3_geometry* geom,
+ unsigned* count)
+{
+ res_T res = RES_OK;
+ if(!geom || !count) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ *count = geom->properties_conflict_count;
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sg3_geometry_dump_as_obj
+ (const struct sg3_geometry* geom,
+ FILE* stream,
+ int flags)
+{
+ res_T res = RES_OK;
+ const struct vertex* vertices;
+ size_t vsz, tsz, i;
+ if(!geom || !stream || !flags
+ || !geom->triangle_count_including_duplicates)
+ {
+ if(geom && !geom->triangle_count_including_duplicates)
+ log_err(geom->dev,
+ "%s: cannot dump empty geometries as OBJ\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
goto error;
}
- v_n_t->dev = dev;
- darray_triangle_init(dev->allocator, &v_n_t->unique_triangles);
- darray_vertex_init(dev->allocator, &v_n_t->unique_vertices);
- ref_init(&v_n_t->ref);
+ /* Headers */
+ fprintf(stream, "# Dump of star-geometry\n");
+ fprintf(stream, "# Geometry counts:\n");
+ vsz = darray_vertex_size_get(&geom->unique_vertices);
+ ASSERT(vsz <= UINT_MAX);
+ fprintf(stream, "# . %u vertices\n", (unsigned)vsz);
+ tsz = darray_triangle_size_get(&geom->unique_triangles);
+ ASSERT(tsz <= UINT_MAX);
+ fprintf(stream, "# . %u triangles\n", (unsigned)tsz);
+ fprintf(stream,
+ "# . %u triangles flagged with a merge conflict\n",
+ geom->merge_conflict_count);
+ fprintf(stream,
+ "# . %u triangles flagged with a property conflict\n",
+ geom->merge_conflict_count);
+
+ /* Dump vertices */
+ vertices = darray_vertex_cdata_get(&geom->unique_vertices);
+ FOR_EACH(i, 0, vsz)
+ fprintf(stream, "v %f %f %f\n", SPLIT3(vertices[i].coord));
+
+ /* Dump triangles by groups */
+ dump_partition(geom, stream, "Valid triangles", SG3_VALID_TRIANGLE);
+ dump_partition(geom, stream, "Merge conflicts", SG3_MERGE_CONFLICTS);
+ dump_partition(geom, stream, "Property conflicts", SG3_PROPERTY_CONFLICTS);
exit:
- if(out_v_n_t) *out_v_n_t = v_n_t;
return res;
error:
- if(v_n_t) {
- v_n_t_ref_put(v_n_t);
- v_n_t = NULL;
+ goto exit;
+}
+
+res_T
+sg3_geometry_dump_as_C_code
+ (const struct sg3_geometry* geom,
+ FILE* stream,
+ const char* name_prefix)
+{
+ res_T res = RES_OK;
+ const struct vertex* vertices;
+ const struct triangle* triangles;
+ size_t vsz, tsz, i;
+ if(!geom || !stream || !name_prefix
+ || geom->merge_conflict_count
+ || geom->properties_conflict_count
+ || !geom->triangle_count_including_duplicates)
+ {
+ if(geom
+ && (geom->merge_conflict_count
+ || geom->properties_conflict_count))
+ log_err(geom->dev,
+ "%s: cannot dump geometries with conflict as C code\n",
+ FUNC_NAME);
+ if(geom && !geom->triangle_count_including_duplicates)
+ log_err(geom->dev,
+ "%s: cannot dump empty geometries as C code\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* Headers */
+ fprintf(stream, "/* Dump of star-geometry. */\n");
+ vsz = darray_vertex_size_get(&geom->unique_vertices);
+ ASSERT(vsz <= UINT_MAX);
+ tsz = darray_triangle_size_get(&geom->unique_triangles);
+ ASSERT(tsz <= UINT_MAX);
+
+ if(vsz == 0 || tsz == 0) {
+ log_err(geom->dev,
+ "%s: no geometry to dump\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
}
+
+ /* Dump vertices */
+ vertices = darray_vertex_cdata_get(&geom->unique_vertices);
+ fprintf(stream,
+ "const double %s_vertices[%u][3] =\n"
+ " {\n",
+ name_prefix, (unsigned)vsz);
+ FOR_EACH(i, 0, vsz - 1)
+ fprintf(stream,
+ " { %f, %f, %f },\n", SPLIT3(vertices[i].coord));
+ fprintf(stream,
+ " { %f, %f, %f }\n", SPLIT3(vertices[vsz - 1].coord));
+ fprintf(stream,
+ " }"
+ "}\n");
+
+ /* Dump triangles */
+ triangles = darray_triangle_cdata_get(&geom->unique_triangles);
+ fprintf(stream,
+ "const unsigned %s_triangles[%u][3] =\n"
+ " {\n",
+ name_prefix, (unsigned)tsz);
+ FOR_EACH(i, 0, tsz - 1)
+ fprintf(stream,
+ " { %u, %u, %u },\n", SPLIT3(triangles[i].vertex_ids));
+ fprintf(stream,
+ " { %u, %u, %u }\n", SPLIT3(triangles[tsz - 1].vertex_ids));
+ fprintf(stream,
+ " }"
+ "}\n");
+
+ /* Dump properties */
+ triangles = darray_triangle_cdata_get(&geom->unique_triangles);
+ fprintf(stream,
+ "const unsigned %s_properties[%u][3] =\n"
+ " {\n",
+ name_prefix, (unsigned)tsz);
+ FOR_EACH(i, 0, tsz - 1)
+ fprintf(stream,
+ " { %u, %u, %u },\n", SPLIT3(triangles[i].properties));
+ fprintf(stream,
+ " { %u, %u, %u }\n", SPLIT3(triangles[tsz - 1].properties));
+ fprintf(stream,
+ " }"
+ "}\n");
+
+exit:
+ return res;
+error:
goto exit;
}
-void
-v_n_t_ref_get(struct v_n_t* dev)
+res_T
+sg3_geometry_ref_get(struct sg3_geometry* geom)
{
- ASSERT(dev);
- ref_get(&dev->ref);
+ if(!geom) return RES_BAD_ARG;
+ ref_get(&geom->ref);
+ return RES_OK;
}
-void
-v_n_t_ref_put(struct v_n_t* dev)
+res_T
+sg3_geometry_ref_put(struct sg3_geometry* geom)
{
- ASSERT(dev);
- ref_put(&dev->ref, v_n_t_release);
-}
-\ No newline at end of file
+ if(!geom) return RES_BAD_ARG;
+ ref_put(&geom->ref, geometry_release);
+ return RES_OK;
+}
diff --git a/src/sg3_geometry.h b/src/sg3_geometry.h
@@ -0,0 +1,291 @@
+/* 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/>. */
+
+#ifndef SG3_GEOMETRY_H__
+#define SG3_GEOMETRY_H__
+
+#include "star-geometry.h"
+#include "sg3_misc.h"
+
+#include <rsys/ref_count.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/hash_table.h>
+
+/* Forward declaration of external opaque data types */
+
+/*******************************************************************************
+ * A type to store triangles
+ ******************************************************************************/
+struct triangle {
+ unsigned vertex_ids[3];
+ /* FRONT/BACK/INTERFACE property */
+ unsigned properties[SG3_PROP_TYPES_COUNT__];
+ /* ID of the triangle in user world, i.e. without deduplication */
+ unsigned global_id;
+};
+#define TRG_UNDEF__ {\
+ { SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY },\
+ { SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY },\
+ SG3_UNDEFINED_PROPERTY\
+}
+#define DARRAY_NAME triangle
+#define DARRAY_DATA struct triangle
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * A type to store vertices
+ ******************************************************************************/
+struct vertex {
+ double coord[3];
+};
+#define DARRAY_NAME vertex
+#define DARRAY_DATA struct vertex
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * A type to map triangle vertices to IDs in unique_triangles
+ ******************************************************************************/
+struct unsigned3 { unsigned x[3]; };
+
+static FINLINE int
+trg_key_eq(const struct unsigned3* k1, const struct unsigned3* k2)
+{
+ ASSERT(k1 && k2);
+ ASSERT(k1->x[0] < k1->x[1] && k1->x[1] < k1->x[2]);
+ ASSERT(k2->x[0] < k2->x[1] && k2->x[1] < k2->x[2]);
+ return (k1->x[0] == k2->x[0])
+ && (k1->x[1] == k2->x[1])
+ && (k1->x[2] == k2->x[2]);
+}
+
+#define HTABLE_NAME trg
+#define HTABLE_KEY struct unsigned3
+#define HTABLE_DATA unsigned
+#define HTABLE_KEY_FUNCTOR_EQ trg_key_eq
+#include <rsys/hash_table.h>
+
+ /*******************************************************************************
+ * A type to map vertex coordinates to IDs in unique_vertices
+ ******************************************************************************/
+static FINLINE int
+vrtx_eq(const struct vertex* v1, const struct vertex* v2)
+{
+ int i;
+ ASSERT(v1 && v2);
+ FOR_EACH(i, 0, 3) if(v1->coord[i] != v2->coord[i]) return 0;
+ return 1;
+}
+
+#define HTABLE_NAME vrtx
+#define HTABLE_KEY struct vertex
+#define HTABLE_DATA unsigned
+#define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
+#include <rsys/hash_table.h>
+
+/*******************************************************************************
+ * Types to record sources and values of triangle descriptions.
+ ******************************************************************************/
+
+ /* A type to store a value and the files defining this value
+ * (usualy a single file) */
+struct definition {
+ /* The value */
+ unsigned property_value;
+ /* The IDs of the geometry sets that defined the value */
+ struct darray_uint set_ids;
+};
+
+static FINLINE void
+init_definition
+(struct mem_allocator* alloc,
+ struct definition* data)
+{
+ ASSERT(alloc && data);
+ data->property_value = SG3_UNDEFINED_PROPERTY;
+ darray_uint_init(alloc, &data->set_ids);
+}
+
+static INLINE res_T
+copy_definition
+(struct definition* dst,
+ const struct definition* src)
+{
+ res_T res = RES_OK;
+ ASSERT(dst && src);
+ dst->property_value = src->property_value;
+ ERR(darray_uint_copy(&dst->set_ids, &src->set_ids));
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static FINLINE void
+release_definition
+(struct definition* data)
+{
+ ASSERT(data);
+ darray_uint_release(&data->set_ids);
+}
+
+#define DARRAY_NAME definition
+#define DARRAY_DATA struct definition
+#define DARRAY_FUNCTOR_INIT init_definition
+#define DARRAY_FUNCTOR_COPY copy_definition
+#define DARRAY_FUNCTOR_RELEASE release_definition
+#include <rsys/dynamic_array.h>
+
+/* A type to accumulate information for a triangle.
+ * If there is more than 1 definition / field, it is a conflict */
+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
+init_trg_descriptions
+(struct mem_allocator* alloc,
+ struct trg_descriptions* data)
+{
+ int i;
+ ASSERT(alloc && data);
+ 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
+copy_trg_descriptions
+(struct trg_descriptions* dst,
+ const struct trg_descriptions* src)
+{
+ res_T res = RES_OK;
+ int i;
+ 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:
+ goto exit;
+}
+
+static FINLINE void
+release_trg_descriptions
+(struct trg_descriptions* data)
+{
+ int i;
+ ASSERT(data);
+ FOR_EACH(i, 0, SG3_PROP_TYPES_COUNT__)
+ darray_definition_release(data->defs + i);
+}
+
+#define DARRAY_NAME trg_descriptions
+#define DARRAY_DATA struct trg_descriptions
+#define DARRAY_FUNCTOR_INIT init_trg_descriptions
+#define DARRAY_FUNCTOR_COPY copy_trg_descriptions
+#define DARRAY_FUNCTOR_RELEASE release_trg_descriptions
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * A type to store interface IDs, as star-enclosures doesn't manage them.
+ ******************************************************************************/
+static FINLINE void
+init_trg_intfaceid
+(struct mem_allocator* alloc,
+ unsigned* data)
+{
+ ASSERT(data); (void)alloc;
+ *data = SG3_UNDEFINED_PROPERTY;
+}
+
+#define DARRAY_NAME intface_id
+#define DARRAY_DATA unsigned
+#define DARRAY_FUNCTOR_INIT init_trg_intfaceid
+#include <rsys/dynamic_array.h>
+
+/*******************************************************************************
+ * Types to store geometry amid sg3_geometry_add calls.
+ ******************************************************************************/
+struct sg3_geometry {
+ /* Record unique (i.e. deduplicated) triangles */
+ struct darray_triangle unique_triangles;
+ /* Record coordinates for unique (i.e. deduplicated) vertices */
+ struct darray_vertex unique_vertices;
+
+ /* A table to map triangle vertices to IDs in unique_triangles */
+ struct htable_trg unique_triangles_ids;
+ /* A table to map vertex coordinates to IDs in unique_vertices */
+ struct htable_vrtx unique_vertices_ids;
+
+ /* Record which set defined what */
+ struct darray_trg_descriptions trg_descriptions;
+
+ /* Counts */
+ unsigned set_id;
+ unsigned triangle_count_including_duplicates;
+ unsigned sides_with_defined_medium_count;
+ unsigned trg_with_undef_sides_count;
+ unsigned trg_with_undef_intface_count;
+ unsigned merge_conflict_count;
+ unsigned properties_conflict_count;
+
+ struct sg3_device* dev;
+ ref_T ref;
+};
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+
+extern res_T
+geometry_register_triangle
+ (struct sg3_geometry* geometry,
+ const struct triangle* triangle,
+ const unsigned triangle_unique_id,
+ const unsigned set_id,
+ const int merge_conflict);
+
+/* Add new undefined triangle descriptions to a geometry */
+static res_T
+geometry_enlarge_trg_descriptions
+ (struct sg3_geometry* geom,
+ const size_t sz)
+{
+ res_T res = RES_OK;
+ size_t old_sz =
+ darray_trg_descriptions_size_get(&geom->trg_descriptions);
+ if(sz <= old_sz) return RES_OK;
+ ASSERT(sz - old_sz < UINT_MAX);
+ ERR(darray_trg_descriptions_resize(&geom->trg_descriptions, sz));
+ geom->trg_with_undef_sides_count += (unsigned)(sz - old_sz);
+ geom->trg_with_undef_intface_count += (unsigned)(sz - old_sz);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+#endif /* SG3_GEOMETRY_H__ */
diff --git a/src/sg3_geometry_c.h b/src/sg3_geometry_c.h
@@ -1,138 +0,0 @@
-/* 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/>. */
-
-#ifndef SG3_GEOMETRY_C_H__
-#define SG3_GEOMETRY_C_H__
-
-#include "star-geometry.h"
-#include "sg3_misc.h"
-
-#include <rsys/ref_count.h>
-#include <rsys/dynamic_array.h>
-#include <rsys/hash_table.h>
-
-/* Forward declaration of external opaque data types */
-
-/*******************************************************************************
- * A type to store triangles
- ******************************************************************************/
-struct triangle {
- unsigned vertex_ids[3];
- /* FRONT/BACK/INTERFACE property */
- unsigned properties[SG3_PROP_TYPES_COUNT__];
- /* ID of the triangle in user world, i.e. without deduplication */
- unsigned global_id;
-};
-#define TRG_UNDEF__ {\
- { SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY },\
- { SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY },\
- SG3_UNDEFINED_PROPERTY\
-}
-#define DARRAY_NAME triangle
-#define DARRAY_DATA struct triangle
-#include <rsys/dynamic_array.h>
-
-/*******************************************************************************
- * A type to store vertices
- ******************************************************************************/
-struct vertex {
- double coord[3];
-};
-#define DARRAY_NAME vertex
-#define DARRAY_DATA struct vertex
-#include <rsys/dynamic_array.h>
-
-/*******************************************************************************
- * A type to share vertices and triangles with reports
- ******************************************************************************/
-struct v_n_t {
- /* Record unique (i.e. deduplicated) triangles */
- struct darray_triangle unique_triangles;
- /* Record coordinates for unique (i.e. deduplicated) vertices */
- struct darray_vertex unique_vertices;
-
- struct sg3_device* dev;
- ref_T ref;
-};
-
-extern res_T
-v_n_t_create(struct sg3_device* dev, struct v_n_t** v_n_t);
-
-extern void
-v_n_t_ref_get(struct v_n_t* dev);
-
-extern void
-v_n_t_ref_put(struct v_n_t* dev);
-
-/*******************************************************************************
- * A type to map triangle vertices to IDs in unique_triangles
- ******************************************************************************/
-struct unsigned3 { unsigned x[3]; };
-
-static FINLINE int
-trg_key_eq(const struct unsigned3* k1, const struct unsigned3* k2)
-{
- ASSERT(k1 && k2);
- ASSERT(k1->x[0] < k1->x[1] && k1->x[1] < k1->x[2]);
- ASSERT(k2->x[0] < k2->x[1] && k2->x[1] < k2->x[2]);
- return (k1->x[0] == k2->x[0])
- && (k1->x[1] == k2->x[1])
- && (k1->x[2] == k2->x[2]);
-}
-
-#define HTABLE_NAME trg
-#define HTABLE_KEY struct unsigned3
-#define HTABLE_DATA unsigned
-#define HTABLE_KEY_FUNCTOR_EQ trg_key_eq
-#include <rsys/hash_table.h>
-
- /*******************************************************************************
- * A type to map vertex coordinates to IDs in unique_vertices
- ******************************************************************************/
-static FINLINE int
-vrtx_eq(const struct vertex* v1, const struct vertex* v2)
-{
- int i;
- ASSERT(v1 && v2);
- FOR_EACH(i, 0, 3) if(v1->coord[i] != v2->coord[i]) return 0;
- return 1;
-}
-
-#define HTABLE_NAME vrtx
-#define HTABLE_KEY struct vertex
-#define HTABLE_DATA unsigned
-#define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
-#include <rsys/hash_table.h>
-
-struct sg3_geometry {
- /* Record unique (i.e. deduplicated) vertices and triangles */
- struct v_n_t* v_n_t;
-
- /* A table to map triangle vertices to IDs in unique_triangles */
- struct htable_trg unique_triangles_ids;
- /* A table to map vertex coordinates to IDs in unique_vertices */
- struct htable_vrtx unique_vertices_ids;
-
- /* Counts */
- unsigned set_id;
- unsigned triangle_count_including_duplicates;
- unsigned sides_with_defined_medium_count;
-
- struct sg3_report* report;
- struct sg3_device* dev;
- ref_T ref;
-};
-
-#endif /* SG3_GEOMETRY_C_H__ */
diff --git a/src/sg3_report.c b/src/sg3_report.c
@@ -1,544 +0,0 @@
-/* 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 "sg3_geometry_c.h"
-#include "sg3_report.h"
-#include "sg3_device.h"
-
-#include <limits.h>
-
- /*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static void
-report_release(ref_T* ref)
-{
- struct sg3_report* report;
- ASSERT(ref);
- report = CONTAINER_OF(ref, struct sg3_report, ref);
- v_n_t_ref_put(report->v_n_t);
- darray_trg_descriptions_release(&report->trg_descriptions);
- MEM_RM(report->dev->allocator, report);
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-res_T
-report_record_triangle
- (struct sg3_report* report,
- 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;
- int i;
- char keep_prop_def[SG3_PROP_TYPES_COUNT__];
-
- ASSERT(report && triangle);
-
- ERR(report_enlarge_trg_descriptions(report, triangle_unique_id + 1));
- trg_d = (darray_trg_descriptions_data_get(&report->trg_descriptions)
- + triangle_unique_id);
- /* Record information */
- FOR_EACH(i, 0, SG3_PROP_TYPES_COUNT__) {
- struct darray_definition* definitions;
- struct definition* defs;
- int done = 0;
- size_t j;
- 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]) {
- /* 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 */
- done = 1;
- break;
- }
- }
- if(!done) {
- /* Need to add the set_id for this property_value */
- ERR(darray_uint_push_back(&defs[j].set_ids, &set_id));
- done = 1;
- }
- break;
- }
- }
- if(!done) {
- /* 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++;
- }
- }
- }
-
- 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->trg_with_undef_sides_count > 0);
- report->trg_with_undef_sides_count--;
- }
-
- if(!keep_prop_def[SG3_INTFACE] && trg_d->property_defined[SG3_INTFACE]) {
- /* Interface is now defined */
- ASSERT(report->trg_with_undef_intface_count > 0);
- report->trg_with_undef_intface_count--;
- }
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static void
-dump_partition
- (const struct sg3_report* report,
- FILE* stream,
- const char* group_name,
- enum sg3_report_dump_content partition)
-{
- const struct trg_descriptions* trg_descriptions;
- const struct triangle* triangles;
- size_t sz, i;
- ASSERT(report && stream && group_name);
- ASSERT(partition == SG3_MERGE_CONFLICTS
- || partition == SG3_PROPERTY_CONFLICTS
- || partition == SG3_VALID_TRIANGLE);
- trg_descriptions
- = darray_trg_descriptions_cdata_get(&report->trg_descriptions);
- sz = darray_trg_descriptions_size_get(&report->trg_descriptions);
- triangles = darray_triangle_cdata_get(&report->v_n_t->unique_triangles);
- fprintf(stream, "g %s\n", group_name);
- FOR_EACH(i, 0, sz) {
- int dump;
- if(partition == SG3_VALID_TRIANGLE)
- dump = !(trg_descriptions[i].merge_conflict
- || trg_descriptions[i].properties_conflict);
- else if(partition == SG3_MERGE_CONFLICTS)
- dump = trg_descriptions[i].merge_conflict;
- else {
- ASSERT(partition == SG3_PROPERTY_CONFLICTS);
- dump = trg_descriptions[i].properties_conflict;
- }
- if(!dump) continue;
- 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]);
- }
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-sg3_report_create
- (struct sg3_device* dev,
- struct sg3_report** out_report)
-{
- struct sg3_report* report = NULL;
- res_T res = RES_OK;
-
- if(!dev || !out_report) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- report = MEM_CALLOC(dev->allocator, 1, sizeof(struct sg3_report));
- if(!report) {
- log_err(dev,
- "%s: could not allocate the star-geometry device.\n", FUNC_NAME);
- res = RES_MEM_ERR;
- goto error;
- }
- report->dev = dev;
- report->trg_with_undef_sides_count = 0;
- report->trg_with_undef_intface_count = 0;
- report->merge_conflict_count = 0;
- report->properties_conflict_count = 0;
- report->associated = 0;
- darray_trg_descriptions_init(dev->allocator, &report->trg_descriptions);
- ref_init(&report->ref);
-
-exit:
- if(out_report) *out_report = report;
- return res;
-error:
- if(report) {
- SG3(report_ref_put(report));
- report = NULL;
- }
- goto exit;
-}
-
-res_T
-sg3_report_validate_properties
- (struct sg3_report* report,
- res_T(*validate)(const unsigned, const unsigned*, void*, int*),
- void* ctx)
-{
- size_t sz__;
- unsigned i, sz;
- struct trg_descriptions* trg_descriptions;
- res_T res = RES_OK;
-
- if(!report || !validate || !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_trg_descriptions_size_get(&report->trg_descriptions);
- ASSERT(sz__ <= UINT_MAX);
- sz = (unsigned)sz__;
- trg_descriptions
- = darray_trg_descriptions_data_get(&report->trg_descriptions);
- report->properties_conflict_count = 0; /* Reset count */
- FOR_EACH(i, 0, sz) {
- unsigned props[3] = {
- SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY };
- struct trg_descriptions* trgd = trg_descriptions + i;
- /* Validate only triangle not flagged with merge_conflict */
- if(trgd->merge_conflict) {
- trgd->properties_conflict = 0;
- continue;
- }
- /* Get non-conflicting properties */
- /* Call vaildation */
- ERR(validate(i, props, ctx, &trgd->properties_conflict));
- if(trgd->properties_conflict)
- report->properties_conflict_count++;
- }
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-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->trg_with_undef_sides_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->trg_with_undef_intface_count;
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-sg3_report_get_merge_conflict_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->merge_conflict_count;
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-sg3_report_get_properties_conflict_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->properties_conflict_count;
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-sg3_report_dump_as_obj
- (const struct sg3_report* report,
- FILE* stream,
- int flags)
-{
- res_T res = RES_OK;
- const struct vertex* vertices;
- size_t vsz, tsz, i;
- if(!report || !stream || !flags || !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;
- }
- /* Headers */
- fprintf(stream, "# Dump of star-geometry report\n");
- fprintf(stream, "# Geometry counts:\n");
- 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);
- fprintf(stream,
- "# . %u triangles flagged with a property conflict\n",
- report->merge_conflict_count);
-
- /* Dump vertices */
- 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 */
- dump_partition(report, stream, "Merge conflicts", SG3_MERGE_CONFLICTS);
- dump_partition(report, stream, "Property conflicts", SG3_PROPERTY_CONFLICTS);
- dump_partition(report, stream, "Valid triangles", SG3_VALID_TRIANGLE);
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-sg3_report_dump_as_C_code
- (const struct sg3_report* report,
- FILE* stream,
- const char* name_prefix)
-{
- res_T res = RES_OK;
- const struct vertex* vertices;
- const struct triangle* triangles;
- size_t vsz, tsz, i;
- if(!report || !stream || !name_prefix || !report->associated
- || report->merge_conflict_count > 0 || report->properties_conflict_count)
- {
- if(report && !report->associated)
- log_err(report->dev,
- "%s: report is not associated to a geometry\n",
- FUNC_NAME);
- if(report->merge_conflict_count > 0 || report->properties_conflict_count)
- log_err(report->dev,
- "%s: cannot dump geometries with conflict as C code\n",
- FUNC_NAME);
- res = RES_BAD_ARG;
- goto error;
- }
- /* Headers */
- fprintf(stream, "/* Dump of star-geometry report. */\n");
- vsz = darray_vertex_size_get(&report->v_n_t->unique_vertices);
- ASSERT(vsz <= UINT_MAX);
- tsz = darray_triangle_size_get(&report->v_n_t->unique_triangles);
- ASSERT(tsz <= UINT_MAX);
-
- if(vsz == 0 || tsz == 0) {
- log_err(report->dev,
- "%s: no geometry to dump\n",
- FUNC_NAME);
- res = RES_BAD_ARG;
- goto error;
- }
-
- /* Dump vertices */
- vertices = darray_vertex_cdata_get(&report->v_n_t->unique_vertices);
- fprintf(stream,
- "const double %s_vertices[%u][3] =\n"
- " {\n",
- name_prefix, (unsigned)vsz);
- FOR_EACH(i, 0, vsz-1)
- fprintf(stream,
- " { %f, %f, %f },\n", SPLIT3(vertices[i].coord));
- fprintf(stream,
- " { %f, %f, %f }\n", SPLIT3(vertices[vsz - 1].coord));
- fprintf(stream,
- " }"
- "}\n");
-
- /* Dump triangles */
- triangles = darray_triangle_cdata_get(&report->v_n_t->unique_triangles);
- fprintf(stream,
- "const unsigned %s_triangles[%u][3] =\n"
- " {\n",
- name_prefix, (unsigned)tsz);
- FOR_EACH(i, 0, tsz-1)
- fprintf(stream,
- " { %u, %u, %u },\n", SPLIT3(triangles[i].vertex_ids));
- fprintf(stream,
- " { %u, %u, %u }\n", SPLIT3(triangles[tsz - 1].vertex_ids));
- fprintf(stream,
- " }"
- "}\n");
-
- /* Dump properties */
- triangles = darray_triangle_cdata_get(&report->v_n_t->unique_triangles);
- fprintf(stream,
- "const unsigned %s_properties[%u][3] =\n"
- " {\n",
- name_prefix, (unsigned)tsz);
- FOR_EACH(i, 0, tsz - 1)
- fprintf(stream,
- " { %u, %u, %u },\n", SPLIT3(triangles[i].properties));
- fprintf(stream,
- " { %u, %u, %u }\n", SPLIT3(triangles[tsz - 1].properties));
- fprintf(stream,
- " }"
- "}\n");
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-sg3_report_ref_get(struct sg3_report* report)
-{
- if(!report) return RES_BAD_ARG;
- ref_get(&report->ref);
- return RES_OK;
-}
-
-res_T
-sg3_report_ref_put(struct sg3_report* report)
-{
- if(!report) return RES_BAD_ARG;
- ref_put(&report->ref, report_release);
- return RES_OK;
-}
diff --git a/src/sg3_report.h b/src/sg3_report.h
@@ -1,266 +0,0 @@
-/* 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/>. */
-
-#ifndef SG3_REPORT_H__
-#define SG3_REPORT_H__
-
-#include "star-geometry.h"
-#include "sg3_misc.h"
-
-#include <rsys/rsys.h>
-#include <rsys/ref_count.h>
-#include <rsys/str.h>
-#include <rsys/dynamic_array_uint.h>
-#include <rsys/dynamic_array.h>
-
- /* Forward declarations */
-struct mem_allocator;
-struct sg3_device;
-struct sg3_report;
-struct darray_description;
-struct triangle;
-struct sg3_geometry;
-struct v_n_t;
-
-/*******************************************************************************
- * Types to record sources and values of triangle descriptions.
- ******************************************************************************/
-
-/* A type to store a value and the files defining this value
- * (usualy a single file) */
-struct definition {
- /* The value */
- unsigned property_value;
- /* The IDs of the geometry sets that defined the value */
- struct darray_uint set_ids;
-};
-
-static FINLINE void
-init_definition
- (struct mem_allocator* alloc,
- struct definition* data)
-{
- ASSERT(alloc && data);
- data->property_value = SG3_UNDEFINED_PROPERTY;
- darray_uint_init(alloc, &data->set_ids);
-}
-
-static INLINE res_T
-copy_definition
- (struct definition* dst,
- const struct definition* src)
-{
- res_T res = RES_OK;
- ASSERT(dst && src);
- dst->property_value = src->property_value;
- ERR(darray_uint_copy(&dst->set_ids, &src->set_ids));
-exit:
- return res;
-error:
- goto exit;
-}
-
-static FINLINE void
-release_definition
- (struct definition* data)
-{
- ASSERT(data);
- darray_uint_release(&data->set_ids);
-}
-
-#define DARRAY_NAME definition
-#define DARRAY_DATA struct definition
-#define DARRAY_FUNCTOR_INIT init_definition
-#define DARRAY_FUNCTOR_COPY copy_definition
-#define DARRAY_FUNCTOR_RELEASE release_definition
-#include <rsys/dynamic_array.h>
-
-/* A type to accumulate information for a triangle.
- * If there is more than 1 definition / field, it is a conflict */
-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
-init_trg_descriptions
- (struct mem_allocator* alloc,
- struct trg_descriptions* data)
-{
- int i;
- ASSERT(alloc && data);
- 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
-copy_trg_descriptions
- (struct trg_descriptions* dst,
- const struct trg_descriptions* src)
-{
- res_T res = RES_OK;
- int i;
- 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:
- goto exit;
-}
-
-static FINLINE void
-release_trg_descriptions
- (struct trg_descriptions* data)
-{
- int i;
- ASSERT(data);
- FOR_EACH(i, 0, SG3_PROP_TYPES_COUNT__)
- darray_definition_release(data->defs + i);
-}
-
-#define DARRAY_NAME trg_descriptions
-#define DARRAY_DATA struct trg_descriptions
-#define DARRAY_FUNCTOR_INIT init_trg_descriptions
-#define DARRAY_FUNCTOR_COPY copy_trg_descriptions
-#define DARRAY_FUNCTOR_RELEASE release_trg_descriptions
-#include <rsys/dynamic_array.h>
-
-/*******************************************************************************
- * A type to store interface IDs, as star-enclosures doesn't manage them.
- ******************************************************************************/
-static FINLINE void
-init_trg_intfaceid
- (struct mem_allocator* alloc,
- unsigned* data)
-{
- ASSERT(data); (void)alloc;
- *data = SG3_UNDEFINED_PROPERTY;
-}
-
-#define DARRAY_NAME intface_id
-#define DARRAY_DATA unsigned
-#define DARRAY_FUNCTOR_INIT init_trg_intfaceid
-#include <rsys/dynamic_array.h>
-
-/*******************************************************************************
- * A type to associate a file and accumulated propeties
- ******************************************************************************/
-struct accumulated_set {
- struct str set_name;
- unsigned prop_value;
-};
-
-static FINLINE void
-init_accumulated_set
- (struct mem_allocator* alloc,
- struct accumulated_set* set)
-{
- ASSERT(alloc && set);
- str_init(alloc, &set->set_name);
- set->prop_value = SG3_UNDEFINED_PROPERTY;
-}
-
-static FINLINE void
-release_accumulated_set
- (struct accumulated_set* set)
-{
- ASSERT(set);
- str_release(&set->set_name);
-}
-
-static INLINE res_T
-copy_accumulated_set
- (struct accumulated_set* dst,
- const struct accumulated_set* src)
-{
- res_T res = RES_OK;
- ASSERT(dst && src);
- ERR(str_copy(&dst->set_name, &src->set_name));
- dst->prop_value = src->prop_value;
-exit:
- return res;
-error:
- goto exit;
-}
-
-#define DARRAY_NAME accumulated_set
-#define DARRAY_DATA struct accumulated_set
-#define DARRAY_FUNCTOR_INIT init_accumulated_set
-#define DARRAY_FUNCTOR_COPY copy_accumulated_set
-#define DARRAY_FUNCTOR_RELEASE release_accumulated_set
-#include <rsys/dynamic_array.h>
-
-/*******************************************************************************
- * Types to store reports amid sg3_accumulate_stl_file calls.
- ******************************************************************************/
-struct sg3_report {
- /* 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 trg_with_undef_sides_count;
- unsigned trg_with_undef_intface_count;
- unsigned merge_conflict_count;
- unsigned properties_conflict_count;
- int associated;
-
- ref_T ref;
- struct sg3_device* dev;
-};
-
-/* Add new undefined triangle descriptions to a report */
-static res_T
-report_enlarge_trg_descriptions
- (struct sg3_report* report,
- const size_t sz)
-{
- res_T res = RES_OK;
- size_t old_sz =
- darray_trg_descriptions_size_get(&report->trg_descriptions);
- if(sz <= old_sz) return RES_OK;
- ASSERT(sz - old_sz < UINT_MAX);
- ERR(darray_trg_descriptions_resize(&report->trg_descriptions, sz));
- report->trg_with_undef_sides_count += (unsigned)(sz - old_sz);
- report->trg_with_undef_intface_count += (unsigned)(sz - old_sz);
-exit:
- return res;
-error:
- goto exit;
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-extern res_T
-report_record_triangle
- (struct sg3_report* report,
- const struct triangle* triangle,
- const unsigned triangle_unique_id,
- const unsigned set_id,
- const int merge_conflict);
-
-#endif /* SG3_REPORT_H__ */
diff --git a/src/star-geometry.h b/src/star-geometry.h
@@ -52,7 +52,6 @@ struct senc_scene;
* the object is silently destroyed and cannot be used anymore. */
struct sg3_device;
struct sg3_geometry;
-struct sg3_report;
/*******************************************************************************
* A type to list the different user properties attached to triangles.
@@ -67,7 +66,7 @@ enum sg3_property_type {
/*******************************************************************************
* A type to list the different possible partitions of triangles.
******************************************************************************/
-enum sg3_report_dump_content {
+enum sg3_dump_content {
SG3_MERGE_CONFLICTS = BIT(0),
SG3_PROPERTY_CONFLICTS = BIT(1),
SG3_VALID_TRIANGLE = BIT(2),
@@ -117,111 +116,16 @@ sg3_device_ref_put
(struct sg3_device* dev);
/*******************************************************************************
- * star-geometry report. Associated to a geometry, it stores information
- * related to it, including conflicts. A report cannot be associated to more
- * than one geometry, even after geometry release.
- * Reports main purpose is to be dumped.
- ******************************************************************************/
-/* Create a report that can be used to accumulate information on a geometry. */
-SG3_API res_T
-sg3_report_create
- (struct sg3_device* dev,
- struct sg3_report** report);
-
-/* Apply a validation callback on each triangle included in this report that
- * is not already flagged with a merge error. If validate returns a non-RES_OK
- * value, the validation stops and returns the same error value; on the other
- * hand, validation goes to the end regardless of properties conflicts.
- * The properties_conflict argument can be set to any value. Any non-0 value
- * is accounted for a conflict and is kept as-is in report dumps, allowing
- * different shades of conflict to be reported.
- * If validation is processed again, the properties conflict count is reset,
- * as well as the properties_conflict of the triangles. */
-SG3_API res_T
-sg3_report_validate_properties
- (struct sg3_report* report,
- res_T(*validate)
- (const unsigned itri, const unsigned properties[3], void* context,
- 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
- (const struct sg3_report* report,
- unsigned* count);
-
-/* Get the number of triangle flagged with a property conflict. Only meaningful
- * after sg3_report_validate_properties has been called. */
-SG3_API res_T
-sg3_report_get_properties_conflict_count
- (const struct sg3_report* report,
- unsigned* count);
-
-/* Dump a report in the provided stream in the OBJ format. The report must have
- * been associated to a geometry or dump will end in error.
- * The OBJ dump is made of the vertices and triangles, without properties, that
- * have been added to the geometry associated with this report.
- * The part of the report that is dumped is defined by the flags argument,
- * that should be ORed enum sg3_report_dump_content values.
- * If more than 1 flag is used, triangle partitions are dumped in different
- * OBJ groups. */
-SG3_API res_T
-sg3_report_dump_as_obj
- (const struct sg3_report* report,
- FILE* stream,
- int flags);
-
-/* Dump the report as C code.
- * The associated geometry cannot be empty and must be conflict-free */
-SG3_API res_T
-sg3_report_dump_as_C_code
- (const struct sg3_report* report,
- FILE* stream,
- const char* name_prefix);
-
-SG3_API res_T
-sg3_report_ref_get
- (struct sg3_report* report);
-
-SG3_API res_T
-sg3_report_ref_put
- (struct sg3_report* report);
-
-/*******************************************************************************
* star-geometry geometry.
- * It stores decorated geometry accumulated through calls to sg3_geometry_add.
- * If report is provided, it stores informations related to this geometry and
- * its creation process, including merge conflicts.
+ * It stores decorated geometry accumulated through calls to sg3_geometry_add,
+ * information related to this geometry and its creation process, including merge
+ * conflicts.
******************************************************************************/
+/* Create a geometry that can be used to accumulate vertices and triangles
+ * decorated with properties. */
SG3_API res_T
sg3_geometry_create
(struct sg3_device* dev,
- struct sg3_report* report, /* Can be NULL */
struct sg3_geometry** geometry);
/* Add a new set of 3D vertices and triangles to the geometry; triangles can
@@ -229,26 +133,25 @@ sg3_geometry_create
* be let undefined using the SG3_UNDEFINED_PROPERTY special value.
* Vertices can be duplicates and are silently deduplicated, always valid.
* Triangles can be duplicates, but this can be ruled invalid due to property
- * inconsistency. Consistency is to be understood as the consistency of the
+ * inconsistency. Triangle duplicates are silently deduplicated, even if
+ * invalid. Consistency is to be understood as the consistency of the
* successive values for the same property across calls of sg3_geometry_add,
* not as the consistency of the values of the 3 properties of a triangle at
* some given time (this question has its own callback (validate) in the
- * sg3_report_validate_properties API call). Triangle duplicates are silently
- * deduplicated, even if invalid.
+ * sg3_geometry_validate_properties API call).
* Duplicate triangles validity is either ruled by the user-provided
* merge_triangle callback, or is just a matter of properties consistency if no
* callback is provided. In either case, sg3_geometry_add never stops
- * prematurely due to a merge conflict and sg3_geometry_add return code is
- * RES_BAD_ARG if no other error code is encountered through the process and an
- * inconsistency is found.
- * - if provided, the callback must return the consistency status using the
+ * prematurely nor returns an error code due to a merge conflict.
+ * - if provided, the callback must return the consistency status using the
* merge_conflict int* paramater (0 for consistent; any other value for
- * inconsistent, this value being recorded in the report); regardless of the
+ * inconsistent, this value being recorded); regardless of the
* merge_conflict status, the callback can change the properties of the
* triangle before the SG3_UNDEFINED_PROPERTY overwriting step;
* - if not, a non-SG3_UNDEFINED_PROPERTY is only consistent with itself and
- * with SG3_UNDEFINED_PROPERTY; regardless of the merge_conflict status,
- * a non-SG3_UNDEFINED_PROPERTY property is never overridden.
+ * with SG3_UNDEFINED_PROPERTY (if inconsistent, the merge_conflict status is
+ * set to 1 and recorded) ; regardless of the merge_conflict status, a
+ * non-SG3_UNDEFINED_PROPERTY property is never overridden.
* When deduplicating triangles, the first occurence remains (with its
* original index in user world). After consistency being computed, a final
* step consists in rewriting SG3_UNDEFINED_PROPERTY properties if the merged
@@ -256,7 +159,6 @@ sg3_geometry_create
SG3_API res_T
sg3_geometry_add
(struct sg3_geometry* geometry,
- /* The ID associated to this set of geometry in report */
/* Number of added triangles */
const unsigned triangles_count,
/* User function that provides vertices ids for added triangles */
@@ -281,9 +183,9 @@ sg3_geometry_add
* The reversed_triangle arg indicates if the triangle vertices' order is
* the same it was when the triangle was first added.
* The merge_conflict argument can be set to any value. Any non-0 value
- * is accounted for a conflict and is kept as-is in report dumps, allowing
- * different shades of conflict to be reported.
- * triangle_properties and merged_properties contain the involved
+ * 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,
@@ -291,6 +193,82 @@ sg3_geometry_add
void* context, int* merge_conflict),
void* context); /* Can be NULL */
+/* Apply a validation callback on each triangle included in this geometry that
+ * is not already flagged with a merge error. If validate returns a non-RES_OK
+ * value, the validation stops and returns the same error value; on the other
+ * hand, validation goes to the end regardless of properties conflicts.
+ * The properties_conflict 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.
+ * If validation is processed again, the properties conflict count is reset,
+ * as well as the properties_conflict status of the triangles. */
+SG3_API res_T
+sg3_geometry_validate_properties
+ (struct sg3_geometry* geometry,
+ res_T(*validate)
+ (const unsigned itri, const unsigned properties[3], void* context,
+ int* properties_conflict),
+ void* context); /* Can be NULL */
+
+/* Get the number of unique vertices. */
+SG3_API res_T
+sg3_geometry_get_unique_vertices_count
+ (const struct sg3_geometry* geometry,
+ unsigned* count);
+
+/* Get the number of unique triangles. */
+SG3_API res_T
+sg3_geometry_get_unique_triangles_count
+ (const struct sg3_geometry* geometry,
+ unsigned* count);
+
+/* Get the number of triangle with (at least) one undefined side. */
+SG3_API res_T
+sg3_geometry_get_triangle_with_undefined_side_count
+ (const struct sg3_geometry* geometry,
+ unsigned* count);
+
+/* Get the number of triangle with undefined interface. */
+SG3_API res_T
+sg3_geometry_get_triangle_with_undefined_interface_count
+ (const struct sg3_geometry* geometry,
+ unsigned* count);
+
+/* Get the number of triangle flagged with a merge conflict. */
+SG3_API res_T
+sg3_geometry_get_merge_conflict_count
+ (const struct sg3_geometry* geometry,
+ unsigned* count);
+
+/* Get the number of triangle flagged with a property conflict. Only meaningful
+ * after sg3_geometry_validate_properties has been called. */
+SG3_API res_T
+sg3_geometry_get_properties_conflict_count
+ (const struct sg3_geometry* geometry,
+ unsigned* count);
+
+/* Dump a geometry in the provided stream in the OBJ format.
+ * The geometry can include conflicts, but cannot be empty.
+ * The OBJ dump is made of the vertices and triangles, without properties, that
+ * have been added to the geometry.
+ * The part of the geometry that is dumped is defined by the flags argument,
+ * that should be ORed enum sg3_dump_content values.
+ * If more than 1 flag is used, triangle partitions are dumped in different
+ * OBJ groups. */
+SG3_API res_T
+sg3_geometry_dump_as_obj
+ (const struct sg3_geometry* geometry,
+ FILE* stream,
+ int flags);
+
+/* Dump the geometry as C code.
+ * The geometry cannot be empty and must be conflict-free */
+SG3_API res_T
+sg3_geometry_dump_as_C_code
+ (const struct sg3_geometry* geometry,
+ FILE* stream,
+ const char* name_prefix);
+
SG3_API res_T
sg3_geometry_ref_get
(struct sg3_geometry* geometry);
diff --git a/src/test_sg3_geometry.c b/src/test_sg3_geometry.c
@@ -16,37 +16,163 @@
#include "star-geometry.h"
#include "test_sg3_utils.h"
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+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;
+}
+
+static res_T
+merge_trg
+ (const unsigned global_id,
+ const unsigned itri,
+ const int reversed_triangle,
+ unsigned triangle_properties[3],
+ const unsigned merged_properties[3],
+ void* context,
+ int* merge_conflict)
+{
+ ASSERT(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;
+}
+
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
struct sg3_device* dev;
- struct sg3_report* report;
- struct sg3_geometry* geometry;
- struct sg3_geometry* geometry2;
+ struct sg3_geometry* geom;
+ unsigned count, i;
+ struct context ctx;
(void)argc, (void)argv;
OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
OK(sg3_device_create(NULL, &allocator, 1, &dev));
- BA(sg3_geometry_create(NULL, NULL, &geometry));
- BA(sg3_geometry_create(dev, NULL, NULL));
- OK(sg3_geometry_create(dev, NULL, &geometry));
+ BA(sg3_geometry_create(NULL, &geom));
+ BA(sg3_geometry_create(dev, NULL));
+ OK(sg3_geometry_create(dev, &geom));
BA(sg3_geometry_ref_get(NULL));
- OK(sg3_geometry_ref_get(geometry));
+ OK(sg3_geometry_ref_get(geom));
BA(sg3_geometry_ref_put(NULL));
- OK(sg3_geometry_ref_put(geometry));
- OK(sg3_geometry_ref_put(geometry));
+ OK(sg3_geometry_ref_put(geom));
+ OK(sg3_geometry_ref_put(geom));
+
+ OK(sg3_geometry_create(dev, &geom));
+
+ BA(sg3_geometry_validate_properties(NULL, NULL, NULL));
+ BA(sg3_geometry_validate_properties(geom, NULL, NULL));
+ BA(sg3_geometry_validate_properties(NULL, validate, NULL));
+ OK(sg3_geometry_validate_properties(geom, validate, NULL));
+
+ BA(sg3_geometry_get_unique_vertices_count(NULL, NULL));
+ BA(sg3_geometry_get_unique_vertices_count(geom, NULL));
+ BA(sg3_geometry_get_unique_vertices_count(NULL, &count));
+ OK(sg3_geometry_get_unique_vertices_count(geom, &count));
+
+ BA(sg3_geometry_get_unique_triangles_count(NULL, NULL));
+ BA(sg3_geometry_get_unique_triangles_count(geom, NULL));
+ BA(sg3_geometry_get_unique_triangles_count(NULL, &count));
+ OK(sg3_geometry_get_unique_triangles_count(geom, &count));
+
+ BA(sg3_geometry_get_triangle_with_undefined_side_count(NULL, NULL));
+ BA(sg3_geometry_get_triangle_with_undefined_side_count(geom, NULL));
+ BA(sg3_geometry_get_triangle_with_undefined_side_count(NULL, &count));
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+
+ BA(sg3_geometry_get_triangle_with_undefined_interface_count(NULL, NULL));
+ BA(sg3_geometry_get_triangle_with_undefined_interface_count(geom, NULL));
+ BA(sg3_geometry_get_triangle_with_undefined_interface_count(NULL, &count));
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+
+ BA(sg3_geometry_get_merge_conflict_count(NULL, NULL));
+ BA(sg3_geometry_get_merge_conflict_count(geom, NULL));
+ BA(sg3_geometry_get_merge_conflict_count(NULL, &count));
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+
+ BA(sg3_geometry_get_properties_conflict_count(NULL, NULL));
+ BA(sg3_geometry_get_properties_conflict_count(geom, NULL));
+ BA(sg3_geometry_get_properties_conflict_count(NULL, &count));
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+
+ BA(sg3_geometry_dump_as_obj(NULL, NULL, 0));
+ BA(sg3_geometry_dump_as_obj(geom, NULL, 0));
+ BA(sg3_geometry_dump_as_obj(NULL, stdout, 0));
+ BA(sg3_geometry_dump_as_obj(NULL, NULL, SG3_ALL_TRIANGLES));
+ BA(sg3_geometry_dump_as_obj(geom, stdout, 0));
+ BA(sg3_geometry_dump_as_obj(geom, NULL, SG3_ALL_TRIANGLES));
+ BA(sg3_geometry_dump_as_obj(NULL, stdout, SG3_ALL_TRIANGLES));
+ /* Empty geometry */
+ BA(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+
+ 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(geom, stdout, NULL));
+ BA(sg3_geometry_dump_as_C_code(NULL, stdout, "test"));
+ /* Empty geometry */
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+
+ /* 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));
+ OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+
+ /* Conflicts with merge_trg callback */
+ OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
+ nvertices, get_position, NULL, merge_trg, &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));
+ /* BA because of conflicts */
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
+ OK(sg3_geometry_ref_put(geom));
- OK(sg3_report_create(dev, &report));
- OK(sg3_geometry_create(dev, report, &geometry));
- /* Cannot associate 2 geometries to the same report */
- BA(sg3_geometry_create(dev, report, &geometry2));
- OK(sg3_report_ref_put(report));
+ /* 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));
+ ctx.front_media = medium1_front0;
+ OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
+ nvertices, get_position, NULL, NULL, &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));
+ /* BA because of conflicts */
+ BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
- OK(sg3_geometry_ref_put(geometry));
+ OK(sg3_geometry_ref_put(geom));
OK(sg3_device_ref_put(dev));
check_memory_allocator(&allocator);
diff --git a/src/test_sg3_geometry_2.c b/src/test_sg3_geometry_2.c
@@ -0,0 +1,399 @@
+/* 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,
+ 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;
+ int i;
+ ASSERT(ctx && triangle_properties && merged_properties && merge_conflict);
+ (void)global_id; (void)itri; (void)reversed_triangle;
+ (void)triangle_properties; (void)merged_properties;
+ add_geom_ctx = ctx->custom;
+ if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt;
+ FOR_EACH(i, 0, 3)
+ if(!sg3_compatible_property(triangle_properties[i], merged_properties[i]))
+ *merge_conflict = 1;
+ 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;
+}
+
+static res_T
+validate2
+ (const unsigned itri,
+ const unsigned properties[3],
+ void* context,
+ int* properties_conflict)
+{
+ (void)itri; (void)properties; (void)context;
+ *properties_conflict = (itri % 2 == 0) ? 0 : itri;
+ return RES_OK;
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_geometry* geom;
+ 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_geometry_create(dev, &geom));
+
+ /* 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.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(geom, ntriangles, get_indices, get_properties,
+ nvertices, get_position, add_trg, merge_trg, &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));
+ CHK(add_geom_ctx.add_cpt == 0);
+ CHK(count == 0);
+ OK(sg3_geometry_get_unique_triangles_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* 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));
+ CHK(add_geom_ctx.add_cpt == ntriangles);
+ CHK(add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geom));
+ OK(sg3_geometry_create(dev, &geom));
+
+ /* 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));
+ CHK(add_geom_ctx.add_cpt == 0);
+ CHK(add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* 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));
+ 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));
+ CHK(add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0); /* merge failed but with a no-conflict status */
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ 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));
+ CHK(add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* 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));
+ CHK(add_geom_ctx.merge_cpt == ntriangles);
+ add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0); /* merge failed but with a no-conflict status */
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Geometry with media information on both sides */
+ ctx.front_media = medium0;
+ ctx.back_media = medium1;
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geom));
+ OK(sg3_geometry_create(dev, &geom));
+
+ /* 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));
+ CHK(add_geom_ctx.add_cpt == ntriangles);
+ CHK(add_geom_ctx.merge_cpt == 0);
+ 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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0); /* media where defined */
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles); /* interfaces where undefined */
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geom));
+ OK(sg3_geometry_create(dev, &geom));
+
+ /* 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));
+ CHK(add_geom_ctx.add_cpt == ntriangles);
+ CHK(add_geom_ctx.merge_cpt == 0);
+ 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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == ntriangles); /* media where undefined */
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == ntriangles); /* interfaces where undefined */
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Define interface */
+ ctx.intface = intface0;
+
+ /* 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));
+ CHK(add_geom_ctx.merge_cpt == ntriangles);
+ add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0); /* media where defined */
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0); /* interfaces where defined */
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Geometry with incompatible media information on both sides */
+ ctx.front_media = medium1;
+ 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));
+ CHK(add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0); /* media where defined */
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0); /* interfaces where defined */
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Incompatible interface */
+ ctx.intface = intface1;
+
+ /* 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));
+ CHK(add_geom_ctx.merge_cpt == ntriangles);
+ add_geom_ctx.merge_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 == ntriangles);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0); /* media where defined */
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0); /* interfaces where defined */
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == ntriangles);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ /* Clear geometry */
+ SG3(geometry_ref_put(geom));
+ 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_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ OK(sg3_geometry_validate_properties(geom, validate, NULL));
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+
+ OK(sg3_geometry_validate_properties(geom, validate, NULL));
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ OK(sg3_geometry_validate_properties(geom, validate2, NULL));
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == ntriangles / 2);
+
+ OK(sg3_geometry_ref_put(geom));
+ 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_report.c b/src/test_sg3_report.c
@@ -56,80 +56,14 @@ main(int argc, char** argv)
struct sg3_device* dev;
struct sg3_report* report;
struct sg3_geometry* geometry;
- unsigned count, i;
+ unsigned count;
struct context ctx;
(void)argc, (void)argv;
+
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(sg3_device_create(NULL, &allocator, 1, &dev));
- BA(sg3_report_create(NULL, &report));
- BA(sg3_report_create(dev, NULL));
- OK(sg3_report_create(dev, &report));
-
- BA(sg3_report_ref_get(NULL));
- OK(sg3_report_ref_get(report));
- BA(sg3_report_ref_put(NULL));
- OK(sg3_report_ref_put(report));
-
- BA(sg3_report_validate_properties(NULL, NULL, NULL));
- BA(sg3_report_validate_properties(report, NULL, NULL));
- BA(sg3_report_validate_properties(NULL, validate, NULL));
- /* 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));
- /* Not associated to a geometry */
- BA(sg3_report_get_merge_conflict_count(report, &count));
-
- BA(sg3_report_get_properties_conflict_count(NULL, NULL));
- BA(sg3_report_get_properties_conflict_count(report, NULL));
- BA(sg3_report_get_properties_conflict_count(NULL, &count));
- /* Not associated to a geometry */
- BA(sg3_report_get_properties_conflict_count(report, &count));
-
- BA(sg3_report_dump_as_obj(NULL, NULL, 0));
- BA(sg3_report_dump_as_obj(report, NULL, 0));
- BA(sg3_report_dump_as_obj(NULL, stdout, 0));
- BA(sg3_report_dump_as_obj(NULL, NULL, SG3_ALL_TRIANGLES));
- BA(sg3_report_dump_as_obj(report, stdout, 0));
- BA(sg3_report_dump_as_obj(report, NULL, SG3_ALL_TRIANGLES));
- BA(sg3_report_dump_as_obj(NULL, stdout, SG3_ALL_TRIANGLES));
- /* Not associated to a geometry */
- BA(sg3_report_dump_as_obj(report, stdout, SG3_ALL_TRIANGLES));
- BA(sg3_report_dump_as_C_code(report, stdout, "test"));
- 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));
@@ -161,8 +95,8 @@ main(int argc, char** argv)
OK(sg3_report_dump_as_C_code(report, stdout, "test"));
/* Conflicts with merge_trg callback */
- /* BA because merge_trg detects conflicts */
- BA(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
+ /* BA because merge_trg detects conflic */
+ OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
nvertices, get_position, NULL, merge_trg, &ctx));
OK(sg3_report_get_merge_conflict_count(report, &count));
/* Due to merge_trg internals, all but the first triangle report conflict */
@@ -181,9 +115,8 @@ main(int argc, char** argv)
BA(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
nvertices, get_position, NULL, NULL, &ctx));
OK(sg3_report_get_merge_conflict_count(report, &count));
- FOR_EACH(i, 0, ntriangles)
- if(medium1_front0[i] != medium0[i]) count--; /* Count conflicts */
- CHK(count == 0);
+ /* Without merge_trg add stops at the first conflict */
+ CHK(count == 1);
BA(sg3_report_dump_as_C_code(report, stdout, "test"));
OK(sg3_geometry_ref_put(geometry));
OK(sg3_report_ref_put(report));
diff --git a/src/test_sg3_report_2.c b/src/test_sg3_report_2.c
@@ -1,412 +0,0 @@
-/* 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,
- 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;
- int i;
- ASSERT(ctx && triangle_properties && merged_properties && merge_conflict);
- (void)global_id; (void)itri; (void)reversed_triangle;
- (void)triangle_properties; (void)merged_properties;
- add_geom_ctx = ctx->custom;
- if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt;
- FOR_EACH(i, 0, 3)
- if(!sg3_compatible_property(triangle_properties[i], merged_properties[i]))
- *merge_conflict = 1;
- 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;
-}
-
-static res_T
-validate2
- (const unsigned itri,
- const unsigned properties[3],
- void* context,
- int* properties_conflict)
-{
- (void)itri; (void)properties; (void)context;
- *properties_conflict = (itri % 2 == 0) ? 0 : itri;
- 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;
- 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_properties,
- 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_properties,
- 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);
- 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));
- 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_properties,
- 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);
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* 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_properties,
- 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);
- 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);
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* 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_properties,
- 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_properties,
- 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);
- 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);
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0); /* merge failed but with a no-conflict status */
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* Successful add geometry without merge callback */
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
- 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);
- 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);
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* Successful add geometry with merge callback */
- add_geom_ctx.merge_res = RES_OK;
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
- 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);
- 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);
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0); /* merge failed but with a no-conflict status */
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* 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, get_properties,
- 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;
- 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 == 0); /* media where defined */
- OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
- CHK(count == ntriangles); /* interfaces where undefined */
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 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 and no defined properties */
- add_geom_ctx.add_res = RES_OK;
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, 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;
- 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); /* media where undefined */
- OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
- CHK(count == ntriangles); /* interfaces where undefined */
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* Define interface */
- ctx.intface = intface0;
-
- /* Successful add geometry with merge callback and properties */
- add_geom_ctx.merge_res = RES_OK;
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
- 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);
- OK(sg3_report_get_triangle_with_undefined_side_count(report, &count));
- CHK(count == 0); /* media where defined */
- OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
- CHK(count == 0); /* interfaces where defined */
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* Geometry with incompatible media information on both sides */
- ctx.front_media = medium1;
- ctx.back_media = medium0;
-
- /* Unsuccessful add geometry without merge callback */
- BA(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
- 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);
- OK(sg3_report_get_triangle_with_undefined_side_count(report, &count));
- CHK(count == 0); /* media where defined */
- OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
- CHK(count == 0); /* interfaces where defined */
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == ntriangles);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- /* Incompatible interface */
- ctx.intface = intface1;
-
- /* Successful add geometry with merge callback */
- add_geom_ctx.merge_res = RES_OK;
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
- 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);
- OK(sg3_report_get_triangle_with_undefined_side_count(report, &count));
- CHK(count == 0); /* media where defined */
- OK(sg3_report_get_triangle_with_undefined_interface_count(report, &count));
- CHK(count == 0); /* interfaces where defined */
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == ntriangles);
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 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 merge callback */
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
- nvertices, get_position, add_trg, merge_trg, &ctx));
- OK(sg3_report_get_merge_conflict_count(report, &count));
- CHK(count == 0);
-
- OK(sg3_report_validate_properties(report, validate, NULL));
- 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_report_validate_properties(report, validate, NULL));
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == 0);
-
- OK(sg3_report_validate_properties(report, validate2, NULL));
- OK(sg3_report_get_properties_conflict_count(report, &count));
- CHK(count == ntriangles / 2);
-
- 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;
-}