star-geometry-3d

Clean and decorate 3D geometries
git clone git://git.meso-star.fr/star-geometry-3d.git
Log | Files | Refs | README | LICENSE

commit 27da621f84f64ffece50e28384cd1b4d528b7b3e
parent a28151cd5adc1bef6a9a2a567c2064788c3f5c66
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon,  2 Dec 2019 17:19:58 +0100

Some additions

Diffstat:
Mcmake/CMakeLists.txt | 5-----
Msrc/sg3_device.c | 3++-
Msrc/sg3_geometry.c | 13+++++++++++--
Msrc/sg3_report.c | 101++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/sg3_report.h | 11++++++-----
Msrc/star-geometry.h | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/test_sg3_geometry.c | 13++++++++-----
Msrc/test_sg3_report.c | 41++++++++++++++++++++++++++++++++---------
8 files changed, 219 insertions(+), 57 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -30,7 +30,6 @@ CMAKE_DEPENDENT_OPTION(ALL_TESTS ################################################################################ find_package(RCMake 0.4 REQUIRED) find_package(RSys 0.8.1 REQUIRED) -find_package(OpenMP 2.0 REQUIRED) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) include(rcmake) @@ -97,10 +96,6 @@ set_target_properties(star-geometry PROPERTIES SOVERSION ${VERSION_MAJOR}) rcmake_copy_runtime_libraries(star-geometry) -if(CMAKE_COMPILER_IS_GNUCC) - set_target_properties(star-geometry PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}") -endif() - rcmake_setup_devel(star-geometry SdisGeom ${VERSION} star-geometry_version.h) ################################################################################ diff --git a/src/sg3_device.c b/src/sg3_device.c @@ -75,7 +75,8 @@ sg3_device_create if(verbose) { /* Do not use helper log functions since dev is not initialised */ CHK(logger_print(log, LOG_ERROR, - "%s: could not allocate the Stardis device.\n", FUNC_NAME) == RES_OK); + "%s: could not allocate the star-geometry device.\n", FUNC_NAME) + == RES_OK); } res = RES_MEM_ERR; goto error; diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c @@ -32,6 +32,10 @@ geometry_release(ref_T* ref) darray_vertex_release(&geometry->unique_vertices); htable_trg_release(&geometry->unique_triangles_ids); htable_vrtx_release(&geometry->unique_vertices_ids); + if(geometry->report) { + /* Don't reset geometry->report->associated!!! */ + sg3_report_ref_put(geometry->report); + } MEM_RM(geometry->dev->allocator, geometry); } @@ -93,7 +97,7 @@ trg_make_key(struct unsigned3* k, const unsigned t[3]) static INLINE int compatible_property - (const enum property_type t, + (const enum sg3_property_type t, const unsigned p1, const unsigned p2) { @@ -115,7 +119,7 @@ sg3_geometry_create struct sg3_geometry* geometry = NULL; res_T res = RES_OK; - if(!dev || !out_geometry) { + if(!dev || !out_geometry || (report && report->associated)) { res = RES_BAD_ARG; goto error; } @@ -138,6 +142,11 @@ sg3_geometry_create geometry->set_id = 0; geometry->report = report; + if(report) { + report->associated = 1; + sg3_report_ref_get(report); + } + ref_init(&geometry->ref); exit: diff --git a/src/sg3_report.c b/src/sg3_report.c @@ -18,6 +18,8 @@ #include "sg3_report.h" #include "sg3_device.h" +#include <limits.h> + /******************************************************************************* * Helper functions ******************************************************************************/ @@ -89,11 +91,11 @@ report_record_triangle darray_uint_init(report->dev->allocator, &new_def.set_ids); ERR(darray_uint_push_back(&new_def.set_ids, &set_id)); darray_definition_push_back(definitions, &new_def); - if(!trg_d->conflict + if(!trg_d->merge_conflict && (darray_definition_size_get(definitions) > 1)) { - trg_d->conflict = 1; - report->conflict_count++; + trg_d->merge_conflict = 1; + report->merge_conflict_count++; } } } @@ -110,7 +112,6 @@ error: res_T sg3_report_create (struct sg3_device* dev, - res_T(*validate)(const unsigned, unsigned*, void*), struct sg3_report** out_report) { struct sg3_report* report = NULL; @@ -124,13 +125,14 @@ sg3_report_create report = MEM_CALLOC(dev->allocator, 1, sizeof(struct sg3_report)); if(!report) { log_err(dev, - "%s: could not allocate the Stardis device.\n", FUNC_NAME); + "%s: could not allocate the star-geometry device.\n", FUNC_NAME); res = RES_MEM_ERR; goto error; } report->dev = dev; - report->conflict_count = 0; - report->validate = validate; + report->merge_conflict_count = 0; + report->properties_conflict_count = 0; + report->associated = 0; darray_accumulated_set_init(dev->allocator, &report->accumulated_sets); darray_trg_descriptions_init(dev->allocator, &report->trg_descriptions); ref_init(&report->ref); @@ -147,7 +149,70 @@ error: } res_T -sg3_report_get_conflict_count +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) { + 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) { + int properties_conflict; + 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, &properties_conflict)); + if(properties_conflict) + report->properties_conflict_count++; + trgd->properties_conflict = properties_conflict; + } + +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) { + 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) { @@ -156,7 +221,25 @@ sg3_report_get_conflict_count res = RES_BAD_ARG; goto error; } - *count = report->conflict_count; + *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; + if (!report || !stream || !flags) { + res = RES_BAD_ARG; + goto error; + } + exit: return res; error: diff --git a/src/sg3_report.h b/src/sg3_report.h @@ -93,7 +93,8 @@ release_definition * If there is more than 1 definition / field, it is a conflict */ struct trg_descriptions { struct darray_definition defs[SG3_PROP_TYPES_COUNT__]; - char conflict; + char merge_conflict; + int properties_conflict; }; static FINLINE void @@ -105,7 +106,7 @@ init_trg_descriptions ASSERT(alloc && data); FOR_EACH(i, 0, 3) darray_definition_init(alloc, data->defs + i); - data->conflict = 0; + data->merge_conflict = 0; } static INLINE res_T @@ -215,9 +216,9 @@ struct sg3_report { /* Record which set defined what */ struct darray_trg_descriptions trg_descriptions; /* Counts */ - unsigned conflict_count; - /* Callback used to validate the consistency of triangle properties */ - res_T(*validate)(const unsigned, unsigned*, void*); + unsigned merge_conflict_count; + unsigned properties_conflict_count; + int associated; ref_T ref; struct sg3_device* dev; diff --git a/src/star-geometry.h b/src/star-geometry.h @@ -30,8 +30,8 @@ #define SG3_API extern IMPORT_SYM #endif -/* Helper macro that asserts if the invocation of the stardis-geometry function - * `Func' returns an error. One should use this macro on stardis-geometry +/* Helper macro that asserts if the invocation of the star-geometry function + * `Func' returns an error. One should use this macro on star-geometry * function calls for which no explicit error checking is performed. */ #ifndef NDEBUG #define SG3(Func) ASSERT(sg3_ ## Func == RES_OK) @@ -44,7 +44,7 @@ struct logger; struct mem_allocator; struct senc_scene; -/* Forward declaration of the stardis-geometry opaque data types. These data +/* Forward declaration of the star-geometry opaque data types. These data * types are ref counted. Once created the caller implicitly owns the created * data, i.e. its reference counter is set to 1. The sdis_<TYPE>_ref_<get|put> * functions get or release a reference on the data, i.e. they increment or @@ -57,30 +57,40 @@ struct sg3_report; /******************************************************************************* * A type to list the different user properties attached to triangles. ******************************************************************************/ -enum property_type { +enum sg3_property_type { SG3_FRONT, SG3_BACK, SG3_INTFACE, SG3_PROP_TYPES_COUNT__ }; +/******************************************************************************* + * A type to list the different user properties attached to triangles. + ******************************************************************************/ +enum sg3_report_dump_content { + SG3_MERGE_CONFLICTS = BIT(0), + SG3_PROPERTY_CONFLICTS = BIT(1) +}; - +/******************************************************************************* + * The value that should be used for properties attached to triangles (i.e. + * media or interface) when not defined. + * SG3_UNDEFINED_PROPERTY can be used for a property that has already been + * defined; in this case the previous value will remain. + ******************************************************************************/ #define SG3_UNDEFINED_PROPERTY UINT_MAX - - BEGIN_DECLS /******************************************************************************* - * stardis-geometry device. It is an handle toward the stardis-geometry library. - * It manages the stardis-geometry resources. + * star-geometry device. It is an handle toward the star-geometry library. + * It manages the star-geometry resources. ******************************************************************************/ SG3_API res_T sg3_device_create - (struct logger* logger, /* May be NULL <=> use default logger */ - struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ + (struct logger* logger, /* Can be NULL <=> use default logger */ + struct mem_allocator* allocator, /* Can be NULL <=> use default allocator */ const int verbose, /* Verbosity level */ struct sg3_device** dev); @@ -93,22 +103,57 @@ sg3_device_ref_put (struct sg3_device* dev); /******************************************************************************* - * stardis-geometry report. It stores information related to calls to - * sg3_accumulate_stl_file, including conflicts. + * 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, - res_T(*validate) /* Can be NULL */ - (const unsigned itri, unsigned properties[3], void* context), 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_register_set +sg3_report_validate_properties (struct sg3_report* report, - const char* set_name, - int set_type, - unsigned* set_id); + res_T(*validate) + (const unsigned itri, const unsigned properties[3], void* context, + int* properties_conflict), + void* context); /* Can be NULL */ + +/* 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 dump is made of vertices and triangles 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. */ +SG3_API res_T +sg3_report_dump_as_obj + (const struct sg3_report* report, + FILE* stream, + int flags); SG3_API res_T sg3_report_ref_get @@ -119,8 +164,10 @@ sg3_report_ref_put (struct sg3_report* report); /******************************************************************************* - * stardis geometry. It stores information related to calls to - * sg3_accumulate_stl_file, including conflicts. + * 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. ******************************************************************************/ SG3_API res_T sg3_geometry_create diff --git a/src/test_sg3_geometry.c b/src/test_sg3_geometry.c @@ -23,7 +23,9 @@ 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; (void)argc, (void)argv; OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); @@ -38,13 +40,14 @@ main(int argc, char** argv) BA(sg3_geometry_ref_put(NULL)); OK(sg3_geometry_ref_put(geometry)); + OK(sg3_geometry_ref_put(geometry)); - - - - - + 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)); OK(sg3_geometry_ref_put(geometry)); OK(sg3_device_ref_put(dev)); diff --git a/src/test_sg3_report.c b/src/test_sg3_report.c @@ -18,20 +18,33 @@ #include <rsys/logger.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; +} + int main(int argc, char** argv) { struct mem_allocator allocator; struct sg3_device* dev; struct sg3_report* report; + unsigned count; (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, NULL, &report)); - BA(sg3_report_create(dev, NULL, NULL)); - OK(sg3_report_create(dev, NULL, &report)); + 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)); @@ -39,12 +52,22 @@ main(int argc, char** argv) 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)); + OK(sg3_report_validate_properties(report, validate, NULL)); + + 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)); + OK(sg3_report_get_merge_conflict_count(report, &count)); + CHK(count == 0); + + 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)); + OK(sg3_report_get_properties_conflict_count(report, &count)); + CHK(count == 0); OK(sg3_report_ref_put(report)); OK(sg3_device_ref_put(dev));