commit b54696785e585f5efa90954dd0df09f560f8bd4e
parent e8024de027ddbb370ca8b26aeef7a8b725f9681d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 12 Dec 2019 19:13:14 +0100
Add dump geometry to VTK
Diffstat:
4 files changed, 175 insertions(+), 20 deletions(-)
diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c
@@ -93,6 +93,39 @@ trg_make_key(struct unsigned3* k, const unsigned t[3])
}
}
+static void
+dump_trg_property
+ (const struct sg3_geometry* geom,
+ FILE* stream,
+ const enum sg3_property_type type)
+{
+ size_t i;
+ const struct trg_descriptions* descriptions;
+ ASSERT(geom && stream && type < SG3_PROP_TYPES_COUNT__);
+
+ descriptions
+ = darray_trg_descriptions_cdata_get(&geom->trg_descriptions);
+ FOR_EACH(i, 0, darray_triangle_size_get(&geom->unique_triangles)) {
+ unsigned property = SG3_UNDEFINED_PROPERTY;
+ size_t tdefs_count
+ = darray_definition_size_get(&descriptions[i].defs[type]);
+ if(tdefs_count && descriptions[i].property_defined[type]) {
+ const struct definition* tdefs
+ = darray_definition_cdata_get(&descriptions[i].defs[type]);
+ size_t j;
+ FOR_EACH(j, 0, tdefs_count) {
+ if(tdefs->property_value != SG3_UNDEFINED_PROPERTY) {
+ property = tdefs->property_value;
+ break; /* Found the defined value */
+ }
+ tdefs++; /* Next value */
+ }
+ }
+ /* Value is INT_MAX for both undefined and conflict */
+ fprintf(stream, "%u\n", MMIN(property, INT_MAX));
+ }
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -102,8 +135,6 @@ geometry_register_triangle
const struct triangle* triangle,
const unsigned triangle_unique_id,
const unsigned set_id,
- /* The conflict code as returned by user callback; if no callback provided
- * set_id is 0 or 1 according to media equality / SG3_UNDEFINED_PROPERTY */
const int merge_conflict)
{
res_T res = RES_OK;
@@ -223,6 +254,7 @@ dump_partition
1 + triangles[i].vertex_ids[2]);
}
}
+
/*******************************************************************************
* Exported functions
******************************************************************************/
@@ -366,8 +398,8 @@ sg3_geometry_add
|| tmp.vertex_ids[0] == tmp.vertex_ids[2]
|| tmp.vertex_ids[1] == tmp.vertex_ids[2])
{
- log_err(geom->dev, "%s: triangle %lu is degenerate.\n",
- FUNC_NAME, (unsigned long)tmp.global_id);
+ log_err(geom->dev, "%s: triangle %u is degenerate.\n",
+ FUNC_NAME, tmp.global_id);
res = RES_BAD_ARG;
goto error;
}
@@ -648,9 +680,9 @@ sg3_geometry_dump_as_obj
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);
+ 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:
return res;
@@ -659,6 +691,97 @@ error:
}
res_T
+sg3_geometry_dump_as_vtk
+ (const struct sg3_geometry* geom,
+ FILE* stream)
+{
+ res_T res = RES_OK;
+ const struct vertex* vertices;
+ const struct triangle* triangles;
+ const struct trg_descriptions* descriptions;
+ size_t vsz, tsz, i;
+ if(!geom || !stream || !geom->triangle_count_including_duplicates) {
+ if(geom && !geom->triangle_count_including_duplicates)
+ log_err(geom->dev,
+ "%s: cannot dump empty geometries as VTK\n",
+ FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* Headers */
+ fprintf(stream, "# vtk DataFile Version 3.0\n");
+ fprintf(stream, "Dump of star-geometry report\n");
+ fprintf(stream, "ASCII\n");
+ fprintf(stream, "DATASET POLYDATA\n");
+
+ /* Dump vertices */
+ vsz = darray_vertex_size_get(&geom->unique_vertices);
+ ASSERT(vsz <= UINT_MAX);
+ fprintf(stream, "POINTS %u double\n", (unsigned)vsz);
+ vertices = darray_vertex_cdata_get(&geom->unique_vertices);
+ FOR_EACH(i, 0, vsz)
+ fprintf(stream, "%f %f %f\n", SPLIT3(vertices[i].coord));
+
+ /* Dump triangles */
+ tsz = darray_triangle_size_get(&geom->unique_triangles);
+ ASSERT(4 * tsz <= UINT_MAX);
+ fprintf(stream, "POLYGONS %u %u\n", (unsigned)tsz, (unsigned)(4 * tsz));
+ triangles = darray_triangle_cdata_get(&geom->unique_triangles);
+ FOR_EACH(i, 0, tsz)
+ fprintf(stream, "3 %u %u %u\n", SPLIT3(triangles[i].vertex_ids));
+
+ /* Start triangles properties */
+ fprintf(stream, "CELL_DATA %u\n", (unsigned)tsz);
+ descriptions = darray_trg_descriptions_cdata_get(&geom->trg_descriptions);
+
+ /* Dump front medium */
+ fprintf(stream, "SCALARS Front_medium int\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ dump_trg_property(geom, stream, SG3_FRONT);
+
+ /* Dump back medium */
+ fprintf(stream, "SCALARS Back_medium int\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ dump_trg_property(geom, stream, SG3_BACK);
+
+ /* Dump interface */
+ fprintf(stream, "SCALARS Interface int\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ dump_trg_property(geom, stream, SG3_INTFACE);
+
+ /* Dump merge conflict status */
+ fprintf(stream, "SCALARS Merge_conflict int\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ FOR_EACH(i, 0, tsz)
+ fprintf(stream, "%d\n", descriptions[i].merge_conflict);
+
+ /* Dump property property status */
+ fprintf(stream, "SCALARS Property_conflict int\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ FOR_EACH(i, 0, tsz)
+ fprintf(stream, "%d\n", descriptions[i].properties_conflict);
+
+ /* Dump rank of the sg3_geometry_add that created the triangle */
+ fprintf(stream, "SCALARS Created_at_sg3_geometry_add int\n");
+ fprintf(stream, "LOOKUP_TABLE default\n");
+ FOR_EACH(i, 0, tsz) {
+ size_t tdefs_count
+ = darray_definition_size_get(&descriptions[i].defs[SG3_FRONT]);
+ const struct definition* tdefs;
+ const unsigned* ranks;
+ ASSERT(tdefs_count);
+ /* Rank is the first set_id of the first definition of any property */
+ tdefs = darray_definition_cdata_get(&descriptions[i].defs[SG3_FRONT]);
+ ranks = darray_uint_cdata_get(&tdefs[0].set_ids);
+ fprintf(stream, "%u\n", ranks[0]);
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+res_T
sg3_geometry_dump_as_C_code
(const struct sg3_geometry* geom,
FILE* stream,
diff --git a/src/star-geometry.h b/src/star-geometry.h
@@ -144,13 +144,13 @@ sg3_geometry_create
* callback is provided. In either case, sg3_geometry_add never stops
* 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); regardless of the
- * merge_conflict status, the callback can change the properties of the
+ * merge_conflict_status int* paramater (0 for consistent; any other value
+ * for inconsistent, this value being recorded); regardless of
+ * 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 (if inconsistent, the merge_conflict status is
- * set to 1 and recorded) ; regardless of the merge_conflict status, a
+ * with SG3_UNDEFINED_PROPERTY (if inconsistent, merge_conflict_status is set
+ * to 1 and recorded) ; regardless of 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
@@ -182,15 +182,15 @@ sg3_geometry_add
* 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 dumps, allowing
+ * The merge_conflict_status argument can be set to any value. Any non-0
+ * value is accounted for a conflict and is kept as-is in dumps, allowing
* different shades of conflict.
* The triangle_properties and merged_properties args contain the involved
* properties. */
res_T(*merge_triangle) /* Can be NULL */
(const unsigned global_id, const unsigned itri, const int reversed_triangle,
unsigned triangle_properties[3], const unsigned merged_properties[3],
- void* context, int* merge_conflict),
+ void* context, int* merge_conflict_status),
void* context); /* Can be NULL */
/* Apply a validation callback on each triangle included in this geometry that
@@ -253,15 +253,33 @@ sg3_geometry_get_properties_conflict_count
* properties. The dumped triangles are defined by the flags argument, that
* must be ORed enum sg3_dump_content values.
* The dumped triangles are partitioned in the following groups:
- * - Valid triangles
- * - Merge conflicts
- * - Property conflict */
+ * - Valid_triangles
+ * - Merge_conflicts
+ * - Property_conflict */
SG3_API res_T
sg3_geometry_dump_as_obj
(const struct sg3_geometry* geometry,
FILE* stream,
int flags);
+/* Dump a geometry in the provided stream in the VTK ascii format.
+ * The geometry can include conflicts, but cannot be empty.
+ * The dump is made of the vertices and triangles, with most of their
+ * properties:
+ * - Front_medium (medium ID of the front side, INT_MAX for both undefined and
+ * conflicted)
+ * - Back_medium (medium ID of the back side, INT_MAX for both undefined and
+ * conflicted)
+ * - Interface (interface ID, INT_MAX for both undefined and conflicted)
+ * - Merge_conflict (merge conflict status)
+ * - Property_conflict (property conflict status)
+ * - Created_at_sg3_geometry_add (rank of the sg3_geometry_add that created the
+ * triangle) */
+SG3_API res_T
+sg3_geometry_dump_as_vtk
+ (const struct sg3_geometry* geometry,
+ FILE* stream);
+
/* Dump the geometry as C code.
* The geometry cannot be empty and must be conflict-free.
* The C code defines the 3 variables:
diff --git a/src/test_sg3_geometry.c b/src/test_sg3_geometry.c
@@ -120,6 +120,12 @@ main(int argc, char** argv)
/* BA because geometry is empty */
BA(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+ BA(sg3_geometry_dump_as_vtk(NULL, NULL));
+ BA(sg3_geometry_dump_as_vtk(geom, NULL));
+ BA(sg3_geometry_dump_as_vtk(NULL, stdout));
+ /* BA because geometry is empty */
+ BA(sg3_geometry_dump_as_vtk(geom, stdout));
+
BA(sg3_geometry_dump_as_C_code(NULL, NULL, NULL));
BA(sg3_geometry_dump_as_C_code(geom, NULL, NULL));
BA(sg3_geometry_dump_as_C_code(NULL, stdout, NULL));
@@ -145,6 +151,7 @@ main(int argc, char** argv)
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_vtk(geom, stdout));
OK(sg3_geometry_dump_as_C_code(geom, stdout, NULL));
OK(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
@@ -155,6 +162,7 @@ main(int argc, char** argv)
/* Due to merge_trg internals, all but the first triangle have conflict */
CHK(count == ntriangles - 1);
OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+ OK(sg3_geometry_dump_as_vtk(geom, stdout));
/* BA because of conflicts */
BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
OK(sg3_geometry_ref_put(geom));
@@ -170,6 +178,7 @@ main(int argc, char** argv)
FOR_EACH(i, 0, ntriangles) if(medium0[i] != medium1_front0[i]) count--;
CHK(count == 0);
OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+ OK(sg3_geometry_dump_as_vtk(geom, stdout));
/* BA because of conflicts */
BA(sg3_geometry_dump_as_C_code(geom, stdout, "test"));
diff --git a/src/test_sg3_geometry_2.c b/src/test_sg3_geometry_2.c
@@ -257,12 +257,15 @@ main(int argc, char** argv)
SG3(geometry_ref_put(geom));
OK(sg3_geometry_create(dev, &geom));
- /* Successful add geometry with add callback */
+ /* Successful add geometry with add callback
+ * First half of the triangles, then all of them */
add_geom_ctx.add_res = RES_OK;
+ OK(sg3_geometry_add(geom, ntriangles / 2, get_indices, get_properties,
+ nvertices, get_position, add_trg, merge_trg, &ctx));
OK(sg3_geometry_add(geom, ntriangles, get_indices, get_properties,
nvertices, get_position, add_trg, merge_trg, &ctx));
CHK(add_geom_ctx.add_cpt == ntriangles);
- CHK(add_geom_ctx.merge_cpt == 0);
+ CHK(add_geom_ctx.merge_cpt == ntriangles / 2);
add_geom_ctx.add_cpt = 0;
OK(sg3_geometry_get_unique_vertices_count(geom, &count));
CHK(count == nvertices);
@@ -276,10 +279,12 @@ main(int argc, char** argv)
CHK(count == 0);
OK(sg3_geometry_get_properties_conflict_count(geom, &count));
CHK(count == 0);
+ OK(sg3_geometry_dump_as_vtk(geom, stdout));
/* Clear geometry */
SG3(geometry_ref_put(geom));
OK(sg3_geometry_create(dev, &geom));
+ add_geom_ctx.merge_cpt = 0;
/* Successful add geometry with add callback and no defined properties */
add_geom_ctx.add_res = RES_OK;