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 5ff0e0a25018c088a5239b14f3562aea9ae03e30
parent 150780eba2a08c240e005a8f27dfd0d9ad00d3db
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 30 Jan 2020 16:51:24 +0100

Add an include file to help writing code for 2D and 3D

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/sg3.h | 23++++++++++++++---------
Msrc/sg3_geometry.c | 2+-
Asrc/sgX3.h | 416+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 432 insertions(+), 10 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -73,6 +73,7 @@ set(SG3_FILES_INC_API sg3.h sg3_s3d_helper.h sg3_senc_helper.h + sgX3.h ) set(SG3_FILES_INC diff --git a/src/sg3.h b/src/sg3.h @@ -39,7 +39,7 @@ #define SG3(Func) sg3_ ## Func #endif - /* Forward declaration of external opaque data types */ +/* Forward declaration of external opaque data types */ struct logger; struct mem_allocator; struct senc_scene; @@ -54,6 +54,11 @@ struct sg3_device; struct sg3_geometry; /******************************************************************************* + * Some defines to introduce dimensions in use in the library. + ******************************************************************************/ +#define SG3_GEOMETRY_DIMENSION + +/******************************************************************************* * A type to list the different user properties attached to triangles. ******************************************************************************/ enum sg3_property_type { @@ -66,7 +71,7 @@ enum sg3_property_type { /******************************************************************************* * A type to list the different possible partitions of triangles. ******************************************************************************/ -enum sg3_dump_content { +enum sg3_obj_dump_content { SG3_OBJ_DUMP_MERGE_CONFLICTS = BIT(0), SG3_OBJ_DUMP_PROPERTY_CONFLICTS = BIT(1), SG3_OBJ_DUMP_VALID_PRIMITIVE = BIT(2), @@ -79,7 +84,7 @@ enum sg3_dump_content { /******************************************************************************* * A type to list the different qualifiers of C code variable output. ******************************************************************************/ -enum sg3_cdump_qualifiers { +enum sg3_c_dump_qualifiers { SG3_C_DUMP_CONST = BIT(0), SG3_C_DUMP_STATIC = BIT(1) }; @@ -98,7 +103,7 @@ enum sg3_cdump_qualifiers { struct sg3_geometry_add_callbacks { /* User function that provides vertices ids for added triangles */ void(*get_indices) - (const unsigned itri, unsigned ids[3], void* context); + (const unsigned itri, unsigned ids[SG3_GEOMETRY_DIMENSION], void* context); /* User function that provides properties for added triangles */ void(*get_properties) /* Can be NULL <=> SG3_UNSPECIFIED_PROPERTY used */ (const unsigned itri, @@ -108,7 +113,7 @@ struct sg3_geometry_add_callbacks { void* context); /* User function that provides coordinates for added vertices */ void(*get_position) - (const unsigned ivert, double pos[3], void* context); + (const unsigned ivert, double pos[SG3_GEOMETRY_DIMENSION], void* context); /* Called if the itri_th triangle of the current sg3_geometry_add is a new * triangle (i.e. not a duplicate) so that the client app can manage its own * triangle data/properties/attributes. @@ -263,7 +268,7 @@ SG3_API res_T sg3_geometry_get_unique_vertex (const struct sg3_geometry* geometry, const unsigned ivtx, - double coord[3]); + double coord[SG3_GEOMETRY_DIMENSION]); /* Get the number of triangles added to the geometry, regardless of unicity. */ SG3_API res_T @@ -282,7 +287,7 @@ SG3_API res_T sg3_geometry_get_unique_primitive_vertices (const struct sg3_geometry* geometry, const unsigned itri, - unsigned indices[3]); + unsigned indices[SG3_GEOMETRY_DIMENSION]); /* Get the properties of the itri_th unique triangle. */ SG3_API res_T @@ -331,7 +336,7 @@ sg3_geometry_get_unique_primitives_with_properties_conflict_count * The geometry can include conflicts, but cannot be empty. * The dump is made of the vertices and some triangles, without their * properties. The dumped triangles are defined by the flags argument, that - * must be ORed enum sg3_dump_content values. + * must be ORed enum sg3_obj_dump_content values. * The dumped triangles are partitioned in the following groups: * - Valid_triangles * - Merge_conflicts @@ -370,7 +375,7 @@ sg3_geometry_dump_as_vtk * - [static] [const] unsigned <name_prefix>_properties[<N2>] = { .... }; * Where <N1> is 3 * vertices_count and <N2> is 3 * triangles_count. * The two qualifiers static and const are output or not according to flags; - * flags must be ORed enum sg3_cdump_qualifiers values. */ + * flags must be ORed enum sg3_c_dump_qualifiers values. */ SG3_API res_T sg3_geometry_dump_as_c_code (const struct sg3_geometry* geometry, diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c @@ -244,7 +244,7 @@ dump_partition (const struct sg3_geometry* geom, FILE* stream, const char* group_name, - enum sg3_dump_content partition) + enum sg3_obj_dump_content partition) { const struct trg_descriptions* trg_descriptions; const struct triangle* triangles; diff --git a/src/sgX3.h b/src/sgX3.h @@ -0,0 +1,416 @@ +/* Copyright (C) 2019-2020 |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 STAR_GEOMETRY_X_3D_H__ +#define STAR_GEOMETRY_X_3D_H__ + +#include <star/sg3.h> +#include <rsys/rsys.h> + +#include <stdio.h> + +/* This file can be used in conjunction with sgX2.h from the the + * star-geometry-2D library to write code for both 2D and 3D geometries using + * the following pattern: + * + * #if (DIM==2) + * #include <star/sgX2.h> + * #elif (DIM==3) + * #include <star/sgX3.h> + * #else + * #error DIM should be defined; possible values are 2 and 3 + * #endif + * + * Then use the sgX_... types and functions in your code. + */ + + +/* 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 + * decrement the reference counter, respectively. When this counter reaches 0, + * the object is silently destroyed and cannot be used anymore. */ +typedef struct sg3_device sgX_device; +typedef struct sg3_geometry sgX_geometry; + +/******************************************************************************* + * Some defines to introduce dimensions in use in the library. + ******************************************************************************/ +#define SGX_GEOMETRY_DIMENSION SG3_GEOMETRY_DIMENSION + +/******************************************************************************* + * A type to list the different user properties attached to triangles. + ******************************************************************************/ +enum sgX_property_type { + SGX_FRONT = SG3_FRONT, + SGX_BACK = SG3_BACK, + SGX_INTFACE = SG3_INTFACE, + SGX_PROP_TYPES_COUNT__ = SG3_PROP_TYPES_COUNT__ +}; + +/******************************************************************************* + * A type to list the different possible partitions of triangles. + ******************************************************************************/ +enum sgX_obj_dump_content { + SGX_OBJ_DUMP_MERGE_CONFLICTS = SG3_OBJ_DUMP_MERGE_CONFLICTS, + SGX_OBJ_DUMP_PROPERTY_CONFLICTS = SG3_OBJ_DUMP_PROPERTY_CONFLICTS, + SGX_OBJ_DUMP_VALID_PRIMITIVE = SG3_OBJ_DUMP_VALID_PRIMITIVE, + SGX_OBJ_DUMP_ALL = SG3_OBJ_DUMP_ALL +}; + +/******************************************************************************* + * A type to list the different qualifiers of C code variable output. + ******************************************************************************/ +enum sgX_c_dump_qualifiers { + SGX_C_DUMP_CONST = SG3_C_DUMP_CONST, + SGX_C_DUMP_STATIC = SG3_C_DUMP_STATIC +}; + +/******************************************************************************* + * The value that should be used for properties attached to triangles (i.e. + * media or interface) when let unspecified. + * SG3_UNSPECIFIED_PROPERTY can be used for a property that has already been + * defined; in this case the previous value will remain. + ******************************************************************************/ +#define SGX_UNSPECIFIED_PROPERTY SG3_UNSPECIFIED_PROPERTY + + /******************************************************************************* + * A type to hold callbacks for sg3_geometry_add. + ******************************************************************************/ +typedef struct sg3_geometry_add_callbacks sgX_geometry_add_callbacks; +#define SGX_ADD_CALLBACKS_NULL__ SG3_ADD_CALLBACKS_NULL__ + +BEGIN_DECLS + +/******************************************************************************* + * A helper function on properties compatibility. + ******************************************************************************/ +static FINLINE int +sgX_compatible_property + (const unsigned p1, + const unsigned p2) +{ + return sg3_compatible_property(p1, p2); +} + +/******************************************************************************* + * star-geometry device. It is an handle toward the star-geometry library. + * It manages the star-geometry resources. + ******************************************************************************/ +static FINLINE res_T +sgX_device_create + (struct logger* logger, /* Can be NULL <=> use default logger */ + struct mem_allocator* allocator, /* Can be NULL <=> use default allocator */ + const int verbose, /* Verbosity level */ + sgX_device** dev) +{ + return sg3_device_create(logger, allocator, verbose, dev); +} + +static FINLINE res_T +sgX_device_ref_get + (sgX_device* dev) +{ + return sg3_device_ref_get(dev); +} + +static FINLINE res_T +sgX_device_ref_put + (sgX_device* dev) +{ + return sg3_device_ref_put(dev); +} + +/******************************************************************************* + * star-geometry geometry. + * 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. */ +static FINLINE res_T +sgX_geometry_create + (sgX_device* dev, + sgX_geometry** geometry) +{ + return sg3_geometry_create(dev, geometry); +} + +/* Reserve memory according to anticipated geometry size. */ +static FINLINE res_T +sgX_geometry_reserve + (sgX_geometry* geometry, + const unsigned vertices_count, + const unsigned triangles_count, + const unsigned properties_count) +{ + return sg3_geometry_reserve( + geometry, vertices_count, triangles_count, properties_count); +} + +/* Add a new set of 3D vertices and triangles to the geometry; triangles can + * be decorated with 3 properties (front and back media and interface) that can + * be let unspecified using the SG3_UNSPECIFIED_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. 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_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 nor returns an error code due to a merge conflict. + * - if provided, the callback must return the consistency status using 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_UNSPECIFIED_PROPERTY overwriting step; + * - if not, a non-SG3_UNSPECIFIED_PROPERTY is only consistent with itself and + * with SG3_UNSPECIFIED_PROPERTY (if inconsistent, merge_conflict_status is set + * to 1 and recorded) ; regardless of merge_conflict_status, a + * non-SG3_UNSPECIFIED_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_UNSPECIFIED_PROPERTY properties if the merged + * property is defined. */ +static FINLINE res_T +sgX_geometry_add + (sgX_geometry* geometry, + const unsigned vertices_count, + const unsigned triangles_count, + const sgX_geometry_add_callbacks* callbacks, + void* context) /* Can be NULL */ +{ + return sg3_geometry_add( + geometry, vertices_count, triangles_count, callbacks, context); +} + +/* 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_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. + * If validation is processed again, the properties conflict count is reset, + * as well as the properties_conflict_status status of the triangles. */ +static FINLINE res_T +sgX_geometry_validate_properties + (sgX_geometry* geometry, + res_T(*validate) + (const unsigned itri, + const unsigned properties[SGX_PROP_TYPES_COUNT__], + void* context, + int* properties_conflict_status), + void* context) /* Can be NULL */ +{ + return sg3_geometry_validate_properties(geometry, validate, context); +} + +/* Get the number of unique vertices. */ +static FINLINE res_T +sgX_geometry_get_unique_vertices_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_unique_vertices_count(geometry, count); +} + +/* Get the ivtx_th vertex. */ +static FINLINE res_T +sgX_geometry_get_unique_vertex + (const sgX_geometry* geometry, + const unsigned ivtx, + double coord[SGX_GEOMETRY_DIMENSION]) +{ + return sg3_geometry_get_unique_vertex(geometry, ivtx, coord); +} + +/* Get the number of triangles added to the geometry, regardless of unicity. */ +static FINLINE res_T +sgX_geometry_get_added_primitives_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_added_primitives_count(geometry, count); +} + +/* Get the number of unique triangles. */ +static FINLINE res_T +sgX_geometry_get_unique_primitives_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_unique_primitives_count(geometry, count); +} + +/* Get the vertex indices of the itri_th unique triangle. */ +static FINLINE res_T +sgX_geometry_get_unique_primitive_vertices + (const sgX_geometry* geometry, + const unsigned itri, + unsigned indices[SGX_GEOMETRY_DIMENSION]) +{ + return sg3_geometry_get_unique_primitive_vertices(geometry, itri, indices); +} + +/* Get the properties of the itri_th unique triangle. */ +static FINLINE res_T +sgX_geometry_get_unique_primitive_properties + (const sgX_geometry* geometry, + const unsigned itri, + unsigned properties[SG3_PROP_TYPES_COUNT__]) +{ + return sg3_geometry_get_unique_primitive_properties( + geometry, itri, properties); +} + +/* Get the user ID of the itri_th unique triangle, that is the user world's + * index of the triangle that first created this unique triangle. + * User world index starts at 0 and increases for every triangle that is + * submitted to sg3_geometry_add calls, regardless of duplication or + * sg3_geometry_add failures (non-RES_OK return value). */ +static FINLINE res_T +sgX_geometry_get_unique_primitive_user_id + (const sgX_geometry* geometry, + const unsigned itri, + unsigned* user_id) +{ + return sg3_geometry_get_unique_primitive_user_id(geometry, itri, user_id); +} + +/* Get the number of triangles with (at least) one unspecified side. */ +static FINLINE res_T +sgX_geometry_get_unique_primitives_with_unspecified_side_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_unique_primitives_with_unspecified_side_count( + geometry, count); +} + +/* Get the number of triangles with unspecified interface. */ +static FINLINE res_T +sgX_geometry_get_unique_primitives_with_unspecified_interface_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_unique_primitives_with_unspecified_interface_count( + geometry, count); +} + +/* Get the number of triangles flagged with a merge conflict. */ +static FINLINE res_T +sgX_geometry_get_unique_primitives_with_merge_conflict_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_unique_primitives_with_merge_conflict_count( + geometry, count); +} + +/* Get the number of triangles flagged with a property conflict. Only + * meaningful after sg3_geometry_validate_properties has been called. */ +static FINLINE res_T +sgX_geometry_get_unique_primitives_with_properties_conflict_count + (const sgX_geometry* geometry, + unsigned* count) +{ + return sg3_geometry_get_unique_primitives_with_properties_conflict_count( + geometry, count); +} + +/* Dump a geometry in the provided stream in the OBJ format. + * The geometry can include conflicts, but cannot be empty. + * The dump is made of the vertices and some triangles, without their + * properties. The dumped triangles are defined by the flags argument, that + * must be ORed enum sg3_obj_dump_content values. + * The dumped triangles are partitioned in the following groups: + * - Valid_triangles + * - Merge_conflicts + * - Property_conflict */ +static FINLINE res_T +sgX_geometry_dump_as_obj + (const sgX_geometry* geometry, + FILE* stream, + const int flags) +{ + return sg3_geometry_dump_as_obj(geometry, stream, 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 unspecified + * and conflicted) + * - Back_medium (medium ID of the back side, INT_MAX for both unspecified and + * conflicted) + * - Interface (interface ID, INT_MAX for both unspecified 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) */ +static FINLINE res_T +sgX_geometry_dump_as_vtk + (const sgX_geometry* geometry, + FILE* stream) +{ + return sg3_geometry_dump_as_vtk(geometry, stream); +} + +/* Dump the geometry as C code. + * The geometry cannot be empty and must be conflict-free. + * The C code defines the 3 variables: + * - [static] [const] unsigned <name_prefix>_vertices_count = N1; + * - [static] [const] double <name_prefix>_vertices[<N1>] = { .... }; + * - [static] [const] unsigned <name_prefix>_triangles_count = N2; + * - [static] [const] unsigned <name_prefix>_triangles[<N2>] = { .... }; + * - [static] [const] unsigned <name_prefix>_properties[<N2>] = { .... }; + * Where <N1> is 3 * vertices_count and <N2> is 3 * triangles_count. + * The two qualifiers static and const are output or not according to flags; + * flags must be ORed enum sg3_c_dump_qualifiers values. */ +static FINLINE res_T +sgX_geometry_dump_as_c_code + (const sgX_geometry* geometry, + FILE* stream, + const char* name_prefix, /* Can be NULL or "" */ + const int flags) +{ + return sg3_geometry_dump_as_c_code(geometry, stream, flags); +} + +static FINLINE res_T +sgX_geometry_ref_get + (sgX_geometry* geometry) +{ + return sg3_geometry_ref_get(geometry); +} + +static FINLINE res_T +sgX_geometry_ref_put + (sgX_geometry* geometry) +{ + return sg3_geometry_ref_put(geometry); +} + +END_DECLS + +#endif /* STAR_GEOMETRY_X_3D_H__ */