commit 0966c671e2044a5b6aa3857300ab3bb912a11606
parent 5e7f33dfc6a5ab1120f194dcd469ff659c98bc15
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 10 Dec 2019 12:36:14 +0100
Adding geometry now proceed to the end even when detecting conflicts
Diffstat:
4 files changed, 49 insertions(+), 65 deletions(-)
diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c
@@ -185,6 +185,7 @@ 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;
@@ -271,13 +272,11 @@ sg3_geometry_add
reversed = trg_make_key(&trg_key, tmp.vertex_ids);
p_trg = htable_trg_find(&geom->unique_triangles_ids, &trg_key);
if(p_trg) {
- struct triangle* upd_ptr;
/* Duplicate triangle. Need to check duplicate validity */
struct unsigned3 utrg_key;
int ureversed = trg_make_key(&utrg_key, trg[*p_trg].vertex_ids);
int same = (reversed == ureversed);
int already_conflict;
- unsigned* uprop;
ASSERT(trg_key_eq(&trg_key, &utrg_key));
unique_id = *p_trg;
/* Use report or tmp storage for merge_conflict status */
@@ -291,34 +290,30 @@ sg3_geometry_add
else p_trgd = &trgd;
if(!same)
SWAP(unsigned, tmp.properties[SG3_FRONT], tmp.properties[SG3_BACK]);
- uprop = trg[*p_trg].properties;
already_conflict = p_trgd->merge_conflict;
if(merge_trg) {
/* Let the client app rule. */
- ERR(merge_trg(trg[*p_trg].global_id, i, same, uprop, tmp.properties,
- ctx, &p_trgd->merge_conflict));
- /* If merge_triangle returns OK add_geometry will continue regardless
- * of conflicts */
+ ERR(merge_trg(trg[*p_trg].global_id, i, same, trg[*p_trg].properties,
+ tmp.properties, ctx, &p_trgd->merge_conflict));
} else {
FOR_EACH(j, 0, SG3_PROP_TYPES_COUNT__) {
- if(!sg3_compatible_property(uprop[j], tmp.properties[j])) {
- res = RES_BAD_ARG;
+ if(!sg3_compatible_property(trg[*p_trg].properties[j],
+ tmp.properties[j]))
+ {
p_trgd->merge_conflict = 1;
break;
}
}
}
- if(geom->report && p_trgd->merge_conflict)
- if(!already_conflict) geom->report->merge_conflict_count++;
- if(res != RES_OK) goto error;
- /* Legit duplicate (or accepted by merge_triangle): replace undef media */
- upd_ptr = darray_triangle_data_get(&geom->v_n_t->unique_triangles)
- + *p_trg;
- /* Replace possible undefined media */
+ if(p_trgd->merge_conflict && !already_conflict) {
+ if(geom->report) geom->report->merge_conflict_count++;
+ found_inconsistency = 1;
+ }
+ /* Replace SG3_UNDEFINED_PROPERTY properties */
FOR_EACH(j, 0, SG3_PROP_TYPES_COUNT__) {
- if(upd_ptr->properties[j] == SG3_UNDEFINED_PROPERTY
+ if(trg[*p_trg].properties[j] == SG3_UNDEFINED_PROPERTY
&& tmp.properties[j] != SG3_UNDEFINED_PROPERTY) {
- upd_ptr->properties[j] = tmp.properties[j];
+ trg[*p_trg].properties[j] = tmp.properties[j];
if(j == SG3_FRONT || j == SG3_BACK)
geom->sides_with_defined_medium_count++;
}
@@ -367,7 +362,7 @@ exit:
darray_uint_release(&unique_vertice_ids);
/* Update sizes */
geom->triangle_count_including_duplicates += actual_ntris;
- return res;
+ return found_inconsistency ? RES_BAD_ARG : res;
error:
goto exit;
}
diff --git a/src/star-geometry.h b/src/star-geometry.h
@@ -183,8 +183,8 @@ sg3_report_get_properties_conflict_count
unsigned* count);
/* Dump a report in the provided stream in the OBJ format. The report must have
- * been associatd to a geometry or dump will end in error.
- * The OBJ dump is made of vertices and triangles, without and property, that
+ * 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.
@@ -228,43 +228,31 @@ sg3_geometry_create
* be decorated with 3 properties (front and back media and interface) that can
* 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. 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, the property consistency question is to be
- * understood as the consistency of the different values for the same property
- * across calls of sg3_geometry_add, and 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).
- * Valid triangle duplicates are silently deduplicated, the first invalid
- * duplicate triggers an error (sg3_geometry_add stops and returns non-RES_OK).
- * The value SG3_UNDEFINED_PROPERTY that can be used to denote undefined
- * properties cannot create a conflict.
- * The way properties consistency is decided depends of the merge_triangle
- * callback being provided or not:
+ * Triangles can be duplicates, but this can be ruled invalid due to property
+ * inconsistency. 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.
+ * 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
* merge_conflict int* paramater (0 for consistent; any other value for
- * inconsistent, this value being recorded in the report); sg3_geometry_add
- * never stops/returns an error due to merge_conflict value, but do if
- * merge_triangle return is not RES_OK (see below);
+ * inconsistent, this value being recorded in the report); 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; the first occuring inconsistency makes
- * sg3_geometry_add stop and return RES_BAD_ARG and the report records the
- * merge_conflict value of 1.
+ * with SG3_UNDEFINED_PROPERTY; 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, regardless of deduplication); the only
- * way deduplication can change a triangle is to change a property from
- * SG3_UNDEFINED_PROPERTY to any defined value.
- * The add_triangle and merge_triangle callbacks can be used for external
- * attribute and app-data management. By returning RES_OK even though an
- * inconsistency exists, these callbacks can let sg3_geometry_add process
- * through the end and build a full report; in this scenario, the client code
- * has to proceed according to the inconsistency despite sg3_geometry_add
- * returning RES_OK.
- * If any user callback returns any non-RES_OK value, sg3_geometry_add
- * stops and returns the same error value. In this case the geometry is
- * partially added without any possible undo, but is in a state that allows
- * further calls to sg3_geometry_add. */
+ * original index in user world). After consistency being computed, a final
+ * step consists in rewriting SG3_UNDEFINED_PROPERTY properties if the merged
+ * property is defined. */
SG3_API res_T
sg3_geometry_add
(struct sg3_geometry* geometry,
@@ -288,15 +276,15 @@ sg3_geometry_add
(const unsigned global_id, const unsigned itri, void* context),
/* Called if the itri_th triangle of the current sg3_geometry_add is equal
* to the global_id_th global triangle so that the client app can merge
- * its own triangle data and rule merge validity.
+ * its own triangle data, rule merge validity, and possibly change the
+ * recorded properties.
* The reversed_triangle arg indicates if the triangle vertices' order is
* the same it was when the triangle was first added.
* The merge_conflict 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 properties.
- * If return is not RES_OK, sg3_geometry_add stops immediately and returns
- * whatever value merge_triangle returned. */
+ * triangle_properties and merged_properties contain the involved
+ * properties. */
res_T(*merge_triangle) /* Can be NULL */
(const unsigned global_id, const unsigned itri, const int reversed_triangle,
unsigned triangle_properties[3], const unsigned merged_properties[3],
diff --git a/src/test_sg3_report.c b/src/test_sg3_report.c
@@ -56,10 +56,10 @@ main(int argc, char** argv)
struct sg3_device* dev;
struct sg3_report* report;
struct sg3_geometry* geometry;
- unsigned count;
+ 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));
@@ -161,8 +161,8 @@ main(int argc, char** argv)
OK(sg3_report_dump_as_C_code(report, stdout, "test"));
/* Conflicts with merge_trg callback */
- /* OK because merge_trg returns RES_OK */
- OK(sg3_geometry_add(geometry, ntriangles, get_indices, get_properties,
+ /* BA because merge_trg detects conflicts */
+ BA(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,8 +181,9 @@ 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));
- /* Without merge_trg add stops at the first conflict */
- CHK(count == 1);
+ FOR_EACH(i, 0, ntriangles)
+ if(medium1_front0[i] != medium0[i]) count--; /* Count conflicts */
+ CHK(count == 0);
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
@@ -350,7 +350,7 @@ main(int argc, char** argv)
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 == 1); /* Without merge_trg add stops at the first conflict */
+ CHK(count == ntriangles);
OK(sg3_report_get_properties_conflict_count(report, &count));
CHK(count == 0);