commit eca71d51fce720def244960c2b98aa3d07035cb9
parent 4f7999439ac8842d8a3332d4494d3b738feefebc
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 30 Jan 2020 16:42:26 +0100
Add an include file to help writing code for 2D and 3D
Diffstat:
| M | src/sg2.h | | | 19 | ++++++++++--------- |
| A | src/sgX2.h | | | 418 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 428 insertions(+), 9 deletions(-)
diff --git a/src/sg2.h b/src/sg2.h
@@ -39,11 +39,11 @@
#define SG2(Func) sg2_ ## Func
#endif
- /* Forward declaration of external opaque data types */
+/* Forward declaration of external opaque data types */
struct logger;
struct mem_allocator;
-/* Forward declaration of the star-geometry opaque data types. These data
+/* Forward declaration of the star-geometry-2D 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
@@ -90,7 +90,7 @@ enum sg2_cdump_qualifiers {
/*******************************************************************************
* The value that should be used for properties attached to segments (i.e.
- * media or interface) when not defined.
+ * media or interface) when let unspecified.
* SG2_UNSPECIFIED_PROPERTY can be used for a property that has already been
* defined; in this case the previous value will remain.
******************************************************************************/
@@ -201,7 +201,7 @@ sg2_geometry_reserve
const unsigned segments_count,
const unsigned properties_count);
-/* Add a new set of 3D vertices and segments to the geometry; segments can
+/* Add a new set of 2D vertices and segments to the geometry; segments can
* be decorated with 3 properties (front and back media and interface) that can
* be let unspecified using the SG2_UNSPECIFIED_PROPERTY special value.
* Vertices can be duplicates and are silently deduplicated, always valid.
@@ -333,7 +333,7 @@ sg2_geometry_get_unique_primitives_with_properties_conflict_count
/* Dump a geometry in the provided stream in the OBJ format.
* The geometry can include conflicts, but cannot be empty. Note that vertices
- * in this output are 3D with Z==0, as OBJ files cannot define 2 vertices.
+ * in this output are 3D with Z==0, as OBJ files cannot define 2D vertices.
* The dump is made of the vertices and some segments, without their
* properties. The dumped segments are defined by the flags argument, that
* must be ORed enum sg2_obj_dump_content values.
@@ -349,7 +349,7 @@ sg2_geometry_dump_as_obj
/* Dump a geometry in the provided stream in the VTK ascii format.
* The geometry can include conflicts, but cannot be empty. Note that POINTS
- * in this output are 3D with Z==0, as VTK text files cannot define 2 POINTS.
+ * in this output are 3D with Z==0, as VTK text files cannot define 2D POINTS.
* The dump is made of the vertices and segments, with most of their
* properties:
* - Front_medium (medium ID of the front side, INT_MAX for both unspecified
@@ -368,13 +368,14 @@ sg2_geometry_dump_as_vtk
/* Dump the geometry as C code.
* The geometry cannot be empty and must be conflict-free.
- * The C code defines the 3 variables:
+ * The C code defines the 5 variables:
* - [static] [const] unsigned <name_prefix>_vertices_count = N1;
* - [static] [const] double <name_prefix>_vertices[<N1>] = { .... };
* - [static] [const] unsigned <name_prefix>_segments_count = N2;
* - [static] [const] unsigned <name_prefix>_segments[<N2>] = { .... };
- * - [static] [const] unsigned <name_prefix>_properties[<N2>] = { .... };
- * Where <N1> is 3 * vertices_count and <N2> is 3 * segments_count.
+ * - [static] [const] unsigned <name_prefix>_properties[<N3>] = { .... };
+ * Where <N1> is 2 * vertices_count, <N2> is 2 * segments_count and <N3> is
+ * 3 * segments_count.
* The two qualifiers static and const are output or not according to flags;
* flags must be ORed enum sg2_cdump_qualifiers values. */
SG2_API res_T
diff --git a/src/sgX2.h b/src/sgX2.h
@@ -0,0 +1,418 @@
+/* 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_2D_H__
+#define STAR_GEOMETRY_X_2D_H__
+
+#include <star/sg2.h>
+#include <rsys/rsys.h>
+
+#include <stdio.h>
+
+/* This file can be used in conjunction with sgX3.h from the the star-geometry
+ * 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-2D 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 sg2_device sgX_device;
+typedef struct sg2_geometry sgX_geometry;
+
+/*******************************************************************************
+ * Some defines to introduce dimensions in use in the library.
+ ******************************************************************************/
+#define SGX_GEOMETRY_DIMENSION SG2_GEOMETRY_DIMENSION
+
+/*******************************************************************************
+ * A type to list the different user properties attached to segments.
+ ******************************************************************************/
+enum sgX_property_type {
+ SGX_FRONT = SG2_FRONT,
+ SGX_BACK = SG2_BACK,
+ SGX_INTFACE = SG2_INTFACE,
+ SGX_PROP_TYPES_COUNT__ = SG2_PROP_TYPES_COUNT__
+};
+
+/*******************************************************************************
+ * A type to list the different possible partitions of segments.
+ ******************************************************************************/
+enum sgX_obj_dump_content {
+ SGX_OBJ_DUMP_MERGE_CONFLICTS = SG2_OBJ_DUMP_MERGE_CONFLICTS,
+ SGX_OBJ_DUMP_PROPERTY_CONFLICTS = SG2_OBJ_DUMP_PROPERTY_CONFLICTS,
+ SGX_OBJ_DUMP_VALID_PRIMITIVE = SG2_OBJ_DUMP_VALID_PRIMITIVE,
+ SGX_OBJ_DUMP_ALL = SG2_OBJ_DUMP_ALL
+};
+
+/*******************************************************************************
+ * A type to list the different qualifiers of C code variable output.
+ ******************************************************************************/
+enum sgX_c_dump_qualifiers {
+ SGX_C_DUMP_CONST = SG2_C_DUMP_CONST,
+ SGX_C_DUMP_STATIC = SG2_C_DUMP_STATIC
+};
+
+/*******************************************************************************
+ * The value that should be used for properties attached to segments (i.e.
+ * media or interface) when let unspecified.
+ * SG2_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 SG2_UNSPECIFIED_PROPERTY
+
+ /*******************************************************************************
+ * A type to hold callbacks for sg2_geometry_add.
+ ******************************************************************************/
+typedef struct sg2_geometry_add_callbacks sgX_geometry_add_callbacks;
+#define SGX_ADD_CALLBACKS_NULL__ SG2_ADD_CALLBACKS_NULL__
+
+BEGIN_DECLS
+
+/*******************************************************************************
+ * A helper function on properties compatibility.
+ ******************************************************************************/
+static FINLINE int
+sgX_compatible_property
+ (const unsigned p1,
+ const unsigned p2)
+{
+ return sg2_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 sg2_device_create(logger, allocator, verbose, dev);
+}
+
+static FINLINE res_T
+sgX_device_ref_get
+ (sgX_device* dev)
+{
+ return sg2_device_ref_get(dev);
+}
+
+static FINLINE res_T
+sgX_device_ref_put
+ (sgX_device* dev)
+{
+ return sg2_device_ref_put(dev);
+}
+
+/*******************************************************************************
+ * star-geometry geometry.
+ * It stores decorated geometry accumulated through calls to sg2_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 segments
+ * decorated with properties. */
+static FINLINE res_T
+sgX_geometry_create
+ (sgX_device* dev,
+ sgX_geometry** geometry)
+{
+ return sg2_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 segments_count,
+ const unsigned properties_count)
+{
+ return sg2_geometry_reserve(
+ geometry, vertices_count, segments_count, properties_count);
+}
+
+/* Add a new set of 2D vertices and segments to the geometry; segments can
+ * be decorated with 3 properties (front and back media and interface) that can
+ * be let unspecified using the SG2_UNSPECIFIED_PROPERTY special value.
+ * Vertices can be duplicates and are silently deduplicated, always valid.
+ * Segments can be duplicates, but this can be ruled invalid due to property
+ * inconsistency. Segment 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 sg2_geometry_add,
+ * not as the consistency of the values of the 3 properties of a segment at
+ * some given time (this question has its own callback (validate) in the
+ * sg2_geometry_validate_properties API call).
+ * Duplicate segments validity is either ruled by the user-provided
+ * merge_segment callback, or is just a matter of properties consistency if no
+ * callback is provided. In either case, sg2_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
+ * segment before the SG2_UNSPECIFIED_PROPERTY overwriting step;
+ * - if not, a non-SG2_UNSPECIFIED_PROPERTY is only consistent with itself and
+ * with SG2_UNSPECIFIED_PROPERTY (if inconsistent, merge_conflict_status is set
+ * to 1 and recorded) ; regardless of merge_conflict_status, a
+ * non-SG2_UNSPECIFIED_PROPERTY property is never overridden.
+ * When deduplicating segments, the first occurence remains (with its
+ * original index in user world). After consistency being computed, a final
+ * step consists in rewriting SG2_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 segments_count,
+ const sgX_geometry_add_callbacks* callbacks,
+ void* context) /* Can be NULL */
+{
+ return sg2_geometry_add(
+ geometry, vertices_count, segments_count, callbacks, context);
+}
+
+/* Apply a validation callback on each segment 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 segments. */
+static FINLINE res_T
+sgX_geometry_validate_properties
+ (sgX_geometry* geometry,
+ res_T(*validate)
+ (const unsigned iseg,
+ const unsigned properties[SGX_PROP_TYPES_COUNT__],
+ void* context,
+ int* properties_conflict_status),
+ void* context) /* Can be NULL */
+{
+ return sg2_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 sg2_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 sg2_geometry_get_unique_vertex(geometry, ivtx, coord);
+}
+
+/* Get the number of segments added to the geometry, regardless of unicity. */
+static FINLINE res_T
+sgX_geometry_get_added_primitives_count
+ (const sgX_geometry* geometry,
+ unsigned* count)
+{
+ return sg2_geometry_get_added_primitives_count(geometry, count);
+}
+
+/* Get the number of unique segments. */
+static FINLINE res_T
+sgX_geometry_get_unique_primitives_count
+ (const sgX_geometry* geometry,
+ unsigned* count)
+{
+ return sg2_geometry_get_unique_primitives_count(geometry, count);
+}
+
+/* Get the vertex indices of the iseg_th unique segment. */
+static FINLINE res_T
+sgX_geometry_get_unique_primitive_vertices
+ (const sgX_geometry* geometry,
+ const unsigned iseg,
+ unsigned indices[SGX_GEOMETRY_DIMENSION])
+{
+ return sg2_geometry_get_unique_primitive_vertices(geometry, iseg, indices);
+}
+
+/* Get the properties of the iseg_th unique segment. */
+static FINLINE res_T
+sgX_geometry_get_unique_primitive_properties
+ (const sgX_geometry* geometry,
+ const unsigned iseg,
+ unsigned properties[SG2_PROP_TYPES_COUNT__])
+{
+ return sg2_geometry_get_unique_primitive_properties(
+ geometry, iseg, properties);
+}
+
+/* Get the user ID of the iseg_th unique segment, that is the user world's
+ * index of the segment that first created this unique segment.
+ * User world index starts at 0 and increases for every segment that is
+ * submitted to sg2_geometry_add calls, regardless of duplication or
+ * sg2_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 iseg,
+ unsigned* user_id)
+{
+ return sg2_geometry_get_unique_primitive_user_id(geometry, iseg, user_id);
+}
+
+/* Get the number of segments 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 sg2_geometry_get_unique_primitives_with_unspecified_side_count(
+ geometry, count);
+}
+
+/* Get the number of segments with unspecified interface. */
+static FINLINE res_T
+sgX_geometry_get_unique_primitives_with_unspecified_interface_count
+ (const sgX_geometry* geometry,
+ unsigned* count)
+{
+ return sg2_geometry_get_unique_primitives_with_unspecified_interface_count(
+ geometry, count);
+}
+
+/* Get the number of segments 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 sg2_geometry_get_unique_primitives_with_merge_conflict_count(
+ geometry, count);
+}
+
+/* Get the number of segments flagged with a property conflict. Only meaningful
+ * after sg2_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 sg2_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. Note that vertices
+ * in this output are 3D with Z==0, as OBJ files cannot define 2D vertices.
+ * The dump is made of the vertices and some segments, without their
+ * properties. The dumped segments are defined by the flags argument, that
+ * must be ORed enum sg2_obj_dump_content values.
+ * The dumped segments are partitioned in the following groups:
+ * - Valid_segments
+ * - Merge_conflicts
+ * - Property_conflict */
+static FINLINE res_T
+sgX_geometry_dump_as_obj
+ (const sgX_geometry* geometry,
+ FILE* stream,
+ const int flags)
+{
+ return sg2_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. Note that POINTS
+ * in this output are 3D with Z==0, as VTK text files cannot define 2D POINTS.
+ * The dump is made of the vertices and segments, 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_sg2_geometry_add (rank of the sg2_geometry_add that created the
+ * segment) */
+static FINLINE res_T
+sgX_geometry_dump_as_vtk
+ (const sgX_geometry* geometry,
+ FILE* stream)
+{
+ return sg2_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 5 variables:
+ * - [static] [const] unsigned <name_prefix>_vertices_count = N1;
+ * - [static] [const] double <name_prefix>_vertices[<N1>] = { .... };
+ * - [static] [const] unsigned <name_prefix>_segments_count = N2;
+ * - [static] [const] unsigned <name_prefix>_segments[<N2>] = { .... };
+ * - [static] [const] unsigned <name_prefix>_properties[<N3>] = { .... };
+ * Where <N1> is 2 * vertices_count, <N2> is 2 * segments_count and <N3> is
+ * 3 * segments_count.
+ * The two qualifiers static and const are output or not according to flags;
+ * flags must be ORed enum sg2_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 sg2_geometry_dump_as_c_code(geometry, stream, flags);
+}
+
+static FINLINE res_T
+sgX_geometry_ref_get
+ (sgX_geometry* geometry)
+{
+ return sg2_geometry_ref_get(geometry);
+}
+
+static FINLINE res_T
+sgX_geometry_ref_put
+ (sgX_geometry* geometry)
+{
+ return sg2_geometry_ref_put(geometry);
+}
+
+END_DECLS
+
+#endif /* STAR_GEOMETRY_X_2D_H__ */