commit 8aba9d351ab42cc5db3da4c68346e627b45ac245
parent 032b30794963a1a802bf82c972bf5011fbdbc071
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 6 Feb 2020 14:26:19 +0100
Same API changes introduced in star-enclosures-3d
Diffstat:
38 files changed, 8550 insertions(+), 4422 deletions(-)
diff --git a/README.md b/README.md
@@ -1,7 +1,7 @@
-StarEnclosures 2D
-=================
+Star-enclosures-2d
+==================
-The purpose of Star-enclosures-2D is to extract enclosures from raw
+The purpose of Star-enclosures-2d is to extract enclosures from raw
geometry. An enclosure is a set of segments enclosing a given area. The
enclosure notion extends to open enclosures for which there is no inside
or outside. For every detected enclosure, the library provides the set
@@ -19,7 +19,7 @@ segments can be set.
How to build
------------
-StarEnclosures 2D relies on the [CMake](http://www.cmake.org) and the
+Star-enclosures-2d relies on the [CMake](http://www.cmake.org) and the
[RCMake](https://gitlab.com/vaplv/rcmake/) package to build. It also
depends on the [RSys](https://gitlab.com/vaplv/rsys/) and
[Star-2D](https://gitlab.com/meso-star/star-2d/) libraries. Additionaly,
@@ -87,7 +87,7 @@ Release notes
License
-------
-StarEnclosures 2D is Copyright (C) |Méso|Star> 2018-2020
+Star-enclosures-2d is Copyright (C) |Méso|Star> 2018-2020
(<a href="mailto:contact@meso-star.com" class="email">contact@meso-star.com</a>).
It is free software released under the GPLv3+ license. You are welcome
to redistribute it under certain conditions; refer to the COPYING files
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -14,7 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.1)
-project(Star-Enclosures2D C)
+project(star-enclosures-2d C)
enable_testing()
include(CMakeDependentOption)
@@ -76,7 +76,9 @@ set(SENC2D_FILES_SRC
set(SENC2D_FILES_INC_API
senc2d.h
- senc2d_s2d_helper.h)
+ senc2d_sXd_helper.h
+ sencX2d.h
+ sencX2d_undefs.h)
set(SENC2D_FILES_INC
senc2d_device_c.h
@@ -117,7 +119,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
target_link_libraries(senc2d m)
endif()
-rcmake_setup_devel(senc2d StarEnc ${VERSION} star/senc2d_version.h)
+rcmake_setup_devel(senc2d StarEnc2D ${VERSION} star/senc2d_version.h)
################################################################################
# Add tests
@@ -178,4 +180,4 @@ install(TARGETS senc2d
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
install(FILES ${SENC2D_FILES_INC_API} DESTINATION include/star)
-install(FILES ${SENC2D_FILES_DOC} DESTINATION share/doc/star-enc)
+install(FILES ${SENC2D_FILES_DOC} DESTINATION share/doc/star-enclosures-2d)
diff --git a/src/senc2d.h b/src/senc2d.h
@@ -29,7 +29,7 @@
#define SENC2D_API extern IMPORT_SYM
#endif
-/* Helper macro that asserts if the invocation of the StarEnc2D function `Func'
+/* Helper macro that asserts if the invocation of the StarEnc function `Func'
* returns an error. One should use this macro on StarEnc function calls for
* which no explicit error checking is performed. */
#ifndef NDEBUG
@@ -42,51 +42,56 @@
* as CPU cores */
#define SENC2D_NTHREADS_DEFAULT (~0u)
-/* A constant to specify an undefined medium */
-#define SENC2D_UNDEFINED_MEDIUM UINT_MAX
+/* A constant to denote an unspecified medium */
+#define SENC2D_UNSPECIFIED_MEDIUM UINT_MAX
/* Forward declaration of external opaque data types */
struct logger;
struct mem_allocator;
-/* Forward declaration of StarEnclosures2D opaque data types. These data types
- * are ref counted. Once created with the appropriated `senc2d_<TYPE>_create'
- * function, the caller implicitly owns the created data, i.e. its reference
- * counter is set to 1. The senc2d_<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. */
-struct senc2d_descriptor;
+/* Forward declaration of star-enclosures-2d opaque data types. These data
+ * types are ref counted. Once created with the appropriated
+ * `senc2d_<TYPE>_create' function, the caller implicitly owns the created
+ * data, i.e. its reference counter is set to 1.
+ * The senc2d_<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. */
struct senc2d_device;
struct senc2d_scene;
struct senc2d_enclosure;
+/******************************************************************************
+ * The dimension of the geometry used in the library.
+ *****************************************************************************/
+#define SENC2D_GEOMETRY_DIMENSION 2
+
/* A type to discriminate segment sides */
enum senc2d_side {
SENC2D_FRONT,
SENC2D_BACK
};
-/* Enclosure2D header type */
+/* Enclosure header type */
struct senc2d_enclosure_header {
/* The ID of the enclosure; 0, 1, ... */
unsigned enclosure_id;
/* Number of segments; a segment can be accounted for twice, once by side */
- unsigned segment_count;
+ unsigned primitives_count;
/* Number of segments; a segment cannot be accounted for twice */
- unsigned unique_segment_count;
+ unsigned unique_primitives_count;
/* Number of vertices */
unsigned vertices_count;
/* The number of media inside the enclosure,
- * SENC2D_UNDEFINED_MEDIUM included */
+ * SENC2D_UNSPECIFIED_MEDIUM included */
unsigned enclosed_media_count;
- /* Is the enclosure infinite?
+ /* Is the enclosure open/infinite?
* Only the outermost enclosure is infinite. */
char is_infinite;
};
-/* We consider the geometrical normal Ng to a segment V0 V1
- * that verifies "(V0, V0V1, Ng) is a direct system".
+/* We consider the geometrical normal Ng to a segment V0 V1 that verifies
+ * "(V0, V0V1, Ng) is a direct system" (right-handed system).
*
* The user can set the convention used to determine which side of
* a segment is to be considered front/back by using the flags :
@@ -98,7 +103,8 @@ struct senc2d_enclosure_header {
* (for a closed enclosure Ng points toward the inside or toward the outside)
* by using the flags :
* SENC2D_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure,
- * SENC2D_CONVENTION_NORMAL_OUTSIDE => Ng points to the opposite of the enclosure.
+ * SENC2D_CONVENTION_NORMAL_OUTSIDE => Ng points toward the opposite of the
+ * enclosure.
*
* Note that normals in output data can be opposite to normals in input data
* (vertices are then given in reverse order).
@@ -112,7 +118,7 @@ enum senc2d_convention {
* Convention regarding FRONT/BACK sides in input data
*/
- /* Geometrical normals point toward the front side */
+ /* Geometrical normals point toward the front side */
SENC2D_CONVENTION_NORMAL_FRONT = BIT(0),
/* Geometrical normals point toward the back side */
SENC2D_CONVENTION_NORMAL_BACK = BIT(1),
@@ -121,20 +127,20 @@ enum senc2d_convention {
* Convention regarding geometrical normals in output data
*/
- /* Geometrical normals point toward the enclosure */
- SENC2D_CONVENTION_NORMAL_INSIDE = BIT(2),
- /* Geometrical normals point to the opposite of the enclosure */
- SENC2D_CONVENTION_NORMAL_OUTSIDE = BIT(3)
+ /* Geometrical normals point toward the enclosure */
+ SENC2D_CONVENTION_NORMAL_INSIDE = BIT(2),
+ /* Geometrical normals point to the opposite of the enclosure */
+ SENC2D_CONVENTION_NORMAL_OUTSIDE = BIT(3)
};
BEGIN_DECLS
-/*******************************************************************************
- * StarEnclosures2D device. It is an handle toward the StarEnc2d library.
+/******************************************************************************
+ * star-enclosures-2d device. It is an handle toward the StarEnc library.
* It manages the lib resources.
* If provided, the allocator has to be suitable for parallel high frequency
* allocations. As a consequence, a rsys proxy allocator should be avoided.
- ******************************************************************************/
+ *****************************************************************************/
SENC2D_API res_T
senc2d_device_create
(struct logger* logger, /* May be NULL <=> use default logger */
@@ -151,87 +157,38 @@ SENC2D_API res_T
senc2d_device_ref_put
(struct senc2d_device* device);
-/*******************************************************************************
- * StarEnclosures2D scene. A scene is a collection of segments. Each segment is
- * defined with a medium on each side.
- ******************************************************************************/
-/* Creates an empty scene */
+/******************************************************************************
+ * star-enclosures-2d scene. A scene is a collection of segments. Each segment
+ * is defined with a medium on each side.
+ *****************************************************************************/
+/* Creates a scene from some vertices and segments.
+ * Neither vertices nor segments can include duplicates.
+ * Segments cannot be degenerated. */
SENC2D_API res_T
senc2d_scene_create
(struct senc2d_device* device,
const int convention,
- struct senc2d_scene** scene);
-
-/* Reserve memory according to anticipated scene size. */
-SENC2D_API res_T
-senc2d_scene_reserve
- (struct senc2d_scene* scene,
- const unsigned vertices_count,
- const unsigned segments_count,
- const unsigned media_count);
-
-/* Add a new set of vertices and segments to the scene.
- * Vertices can be duplicates and are silently deduplicated on the fly.
- * Segments can be duplicates as long as media are compatible on both sides.
- * Valid segment duplicates are silently deduplicated, invalid duplicates
- * trigger an error (add_geometry returns RES_BAD_ARG).
- * The special value SENC2D_UNDEFINED_MEDIUM denotes an undefined medium.
- * It can be used to define the 2 sides of a segment at different times.
- * Media on duplicate segments are consider compatible if:
- * - the merge_segment callback is provided and returns RES_OK,
- * - or media are identical or SENC2D_UNDEFINED_MEDIUM.
- * When deduplicating segments, the first occurence remains (with its
- * original index in user world, regardless of deduplication); the only
- * situation where deduplication changes a previously recorded media is from
- * SENC2D_UNDEFINED_MEDIUM to any defined medium.
- * The add_segment and merge_segment callbacks can be used for attribute
- * management (including segment IDs) and to record media incompatibilities for
- * a subsequent report; they allow the client app to store its own data.
- * By returning an error, they can also stop the add_geometry call. */
-SENC2D_API res_T
-senc2d_scene_add_geometry
- (struct senc2d_scene* scene,
- /* Number of added segments */
+ /* Number of segments */
const unsigned segments_count,
- /* User function that provides vertices ids for added segments */
- void(*indices)(const unsigned iseg, unsigned ids[2], void* context),
- /* User function that provides media ids for added segments */
- void(*media) /* Can be NULL <=> SENC2D_UNDEFINED_MEDIUM medium used */
+ /* User function that provides vertices ids for segments */
+ void(*get_indices)(
+ const unsigned iseg,
+ unsigned ids[SENC2D_GEOMETRY_DIMENSION],
+ void* context),
+ /* User function that provides media ids for segments */
+ void(*get_media) /* Can be NULL <=> SENC2D_UNSPECIFIED_MEDIUM medium used */
(const unsigned iseg, unsigned med[2], void* context),
- /* Number of added vertices */
+ /* Number of vertices */
const unsigned vertices_count,
- /* User function that provides coordinates for added vertices */
- void(*position)(const unsigned ivert, double pos[2], void* context),
- /* Called for each new segment so that the client app can manage its own
- * segment data/properties/attributes.
- * If return is not RES_OK, add_geometry stops immediately and returns
- * whatever value add_segment returned. */
- res_T(*add_segment) /* Can be NULL */
- (const unsigned global_id, const unsigned iseg, void* context),
- /* Called if the iseg_th segment of the current add_geometry is equal to
- * the global_id_th global segment so that the client app can try to merge
- * its own segment data or record a possible media conflict.
- * The reversed_segment arg indicates if the segment vertices' order is the
- * same it was when the segment was first added.
- * segment_media and merge_media contain the involved media.
- * If those media are incompatible and merge_segment returns RES_OK the
- * process will continue with the next segment and possibly end in success.
- * If return is not RES_OK, add_geometry stops immediately and returns
- * whatever value merge_segment returned.
- * If merge_segment is NULL, a strict media compatibility is required for
- * add_geometry to success: add_geometry would stop and return RES_BAD_ARG
- * on the first occurence of duplicate segment with incompatible media. */
- res_T(*merge_segment) /* Can be NULL */
- (const unsigned global_id, const unsigned iseg, const int reversed_segment,
- const unsigned segment_media[2], const unsigned merge_media[2],
- void* context),
- void* context);
-
-/* Returns a descriptor of the scene that holds the analysis' result. */
-SENC2D_API res_T
-senc2d_scene_analyze
- (struct senc2d_scene* scene,
- struct senc2d_descriptor** descriptor);
+ /* User function that provides coordinates for vertices */
+ void(*get_position)(
+ const unsigned ivert,
+ double pos[SENC2D_GEOMETRY_DIMENSION],
+ void* context),
+ /* Context provided to user callbacks; can be NULL */
+ void* context,
+ /* The created scene */
+ struct senc2d_scene** scene);
/* Returns the convention flags in use with the scene. */
SENC2D_API res_T
@@ -245,33 +202,16 @@ senc2d_scene_get_segments_count
(const struct senc2d_scene* scene,
unsigned* count);
-/* Returns the number of unique segments in the scene (remaining
- * segments after deduplication). */
-SENC2D_API res_T
-senc2d_scene_get_unique_segments_count
- (const struct senc2d_scene* scene,
- unsigned* count);
-
-/* Returns the number of unique sides with SENC2D_UNDEFINED_MEDIUM medium. */
+/* Returns the iseg_th segment vertices' indices. */
SENC2D_API res_T
-senc2d_scene_get_unique_sides_without_medium_count
- (const struct senc2d_scene* scene,
- unsigned* count);
-
-/* Returns the iseg_th unique segment; the returned indices are
- * unique vertex indices.
- * Can be called anytime, before or after a call to analyze. */
-SENC2D_API res_T
-senc2d_scene_get_unique_segment
+senc2d_scene_get_segment
(const struct senc2d_scene* scene,
const unsigned iseg,
- unsigned indices[2]);
+ unsigned indices[SENC2D_GEOMETRY_DIMENSION]);
-/* Returns the iseg_th unique segment; the returned indices are
- * unique vertex indices.
- * Can be called anytime, before or after a call to analyze. */
+/* Returns the media for the iseg_th segment. */
SENC2D_API res_T
-senc2d_scene_get_unique_segment_media
+senc2d_scene_get_segment_media
(const struct senc2d_scene* scene,
const unsigned iseg,
unsigned media[2]);
@@ -282,159 +222,98 @@ senc2d_scene_get_vertices_count
(const struct senc2d_scene* scene,
unsigned* count);
-/* Returns the number of unique vertices in the scene (remaining
- * vertices after deduplication). */
-SENC2D_API res_T
-senc2d_scene_get_unique_vertices_count
- (const struct senc2d_scene* scene,
- unsigned* count);
-
-/* Returns the coordinates of the ivert_th unique vertex.
- * Can be called anytime, before or after a call to analyze. */
+/* Returns the coordinates of the ivert_th vertex. */
SENC2D_API res_T
-senc2d_scene_get_unique_vertex
+senc2d_scene_get_vertex
(const struct senc2d_scene* scene,
const unsigned ivert,
- double coord[2]);
-
-SENC2D_API res_T
-senc2d_scene_ref_get
- (struct senc2d_scene* scene);
-
-SENC2D_API res_T
-senc2d_scene_ref_put
- (struct senc2d_scene* scene);
+ double coord[SENC2D_GEOMETRY_DIMENSION]);
-/*******************************************************************************
- * StarEnclosures2D descriptor. It is an handle toward an analyze result.
- ******************************************************************************/
/* Returns the greater medium id found in added geometry. In API calls using a
* medium, any value in the [0 max_medium_id[ range is valid. However there can
* be unused ids (no geometry refered to this medium id). */
SENC2D_API res_T
-senc2d_descriptor_get_max_medium
- (const struct senc2d_descriptor* descriptor,
+senc2d_scene_get_max_medium
+ (const struct senc2d_scene* scene,
unsigned* max_medium_id);
/* Returns the number of enclosures. */
SENC2D_API res_T
-senc2d_descriptor_get_enclosure_count
- (const struct senc2d_descriptor* descriptor,
+senc2d_scene_get_enclosure_count
+ (const struct senc2d_scene* scene,
unsigned* count);
/* Returns the number of enclosures that have some geometry refering to the
- * imed_th medium. */
+ * imed_th medium or SENC2D_UNSPECIFIED_MEDIUM. */
SENC2D_API res_T
-senc2d_descriptor_get_enclosure_count_by_medium
- (const struct senc2d_descriptor* descriptor,
+senc2d_scene_get_enclosure_count_by_medium
+ (const struct senc2d_scene* scene,
const unsigned imed,
unsigned* count);
/* Returns the idx_th enclosure. */
SENC2D_API res_T
-senc2d_descriptor_get_enclosure
- (struct senc2d_descriptor* descriptor,
+senc2d_scene_get_enclosure
+ (struct senc2d_scene* scene,
const unsigned idx,
struct senc2d_enclosure** enclosure);
-/* Returns the idx_th enclosure using the imed_th medium. */
+/* Returns the idx_th enclosure using the imed_th medium or
+ * SENC2D_UNSPECIFIED_MEDIUM. */
SENC2D_API res_T
-senc2d_descriptor_get_enclosure_by_medium
- (struct senc2d_descriptor* descriptor,
+senc2d_scene_get_enclosure_by_medium
+ (struct senc2d_scene* scene,
const unsigned imed,
const unsigned idx,
struct senc2d_enclosure** enclosure);
-/* Returns the number of unique segments (no duplicates here) in the whole
- * geometry. */
-SENC2D_API res_T
-senc2d_descriptor_get_global_segments_count
- (const struct senc2d_descriptor* descriptor,
- unsigned* count);
-
-/* Returns the number of unique vertices (no duplicates here) in the whole
- * geometry. */
+/* Returns the enclosures the iseg_th segment front and back sides are member
+ * of. */
SENC2D_API res_T
-senc2d_descriptor_get_global_vertices_count
- (const struct senc2d_descriptor* descriptor,
- unsigned* count);
-
-/* Returns the iseg_th global unique segment; the returned indices are global
- * unique vertex indices. */
-SENC2D_API res_T
-senc2d_descriptor_get_global_segment
- (const struct senc2d_descriptor* descriptor,
- const unsigned iseg,
- unsigned indices[2]);
-
-/* Returns the coordinates of the ivert_th global unique vertex. */
-SENC2D_API res_T
-senc2d_descriptor_get_global_vertex
- (const struct senc2d_descriptor* descriptor,
- const unsigned ivert,
- double coord[2]);
-
-/* Returns the front and back media ids of the iseg_th global unique segment. */
-SENC2D_API res_T
-senc2d_descriptor_get_global_segment_media
- (const struct senc2d_descriptor* descriptor,
- const unsigned iseg,
- unsigned media[2]);
-
-/* Returns the enclosures the iseg_th global unique segment front and back
- * sides are member of. */
-SENC2D_API res_T
-senc2d_descriptor_get_global_segment_enclosures
- (const struct senc2d_descriptor* descriptor,
+senc2d_scene_get_segment_enclosures
+ (const struct senc2d_scene* scene,
const unsigned iseg,
unsigned enclosures[2]);
-/* Returns the global id of the iseg_th global unique segment, that is the
- * segment index in user world regardless of deduplication. */
-SENC2D_API res_T
-senc2d_descriptor_get_global_segment_global_id
- (const struct senc2d_descriptor* descriptor,
- const unsigned iseg,
- unsigned* gid);
-
/* Returns the number of vertices that are frontier vertices:
* - that have arity 1 (single segment using the vertex)
* - that connect 2 different media */
SENC2D_API res_T
-senc2d_descriptor_get_frontier_vertices_count
- (const struct senc2d_descriptor* descriptor,
+senc2d_scene_get_frontier_vertice_count
+ (const struct senc2d_scene* scene,
unsigned* count);
-/* Returns the iver_th frontier vertex; the returned index is an global unique
- * vertex index. */
+/* Returns the iver_th frontier vertex; the returned index is a global vertex
+ * index whose coordinates can be retrieved using senc2d_scene_get_vertex. */
SENC2D_API res_T
-senc2d_descriptor_get_frontier_vertex
- (const struct senc2d_descriptor* descriptor,
+senc2d_scene_get_frontier_vertex
+ (const struct senc2d_scene* scene,
const unsigned iver,
- unsigned* vrtx_id);
+ unsigned vrtx_id[SENC2D_GEOMETRY_DIMENSION-1]);
SENC2D_API res_T
-senc2d_descriptor_ref_get
- (struct senc2d_descriptor* descriptor);
+senc2d_scene_ref_get
+ (struct senc2d_scene* scene);
SENC2D_API res_T
-senc2d_descriptor_ref_put
- (struct senc2d_descriptor* descriptor);
+senc2d_scene_ref_put
+ (struct senc2d_scene* scene);
-/*******************************************************************************
- * StarEnclosures2D enclosure. It is an handle toward an enclosure.
+/******************************************************************************
+ * star-enclosures-2d enclosure. It is an handle toward an enclosure.
* Counts and other information on enclosures are not individually accessible,
* but as a whole through header access.
* An enclosure can list the "same" segment twice if both sides are in. In this
* case the 2 occurences of the segment have reversed vertices order and
- * unique_segment_count and segment_count differ.
+ * unique_primitives_count and primitives_count differ.
* Vertices and segments numbering schemes are specific to each enclosure:
* the "same" item appearing in 2 different enclosures has no reason to get the
* same index twice or to have the same index in the global numbering scheme.
* By-index API accesses of segments (or properties) visit unique segments
- * for indices in the [0 unique_segment_count[ range and back-faces of the
- * doubly-included segments in the [unique_segment_count segment_count[ range.
- ******************************************************************************/
+ * for indices in the [0 unique_primitives_count[ range and back-faces of the
+ * doubly-included segments in the [unique_primitives_count primitives_count[
+ * range.
+ *****************************************************************************/
/* Returns the header of an enclosure. */
SENC2D_API res_T
senc2d_enclosure_get_header
@@ -447,19 +326,19 @@ SENC2D_API res_T
senc2d_enclosure_get_segment
(const struct senc2d_enclosure* enclosure,
const unsigned iseg,
- unsigned indices[2]);
+ unsigned indices[SENC2D_GEOMETRY_DIMENSION]);
/* Returns the coordinates of the ivert_th vertex of an enclosure. */
SENC2D_API res_T
senc2d_enclosure_get_vertex
(const struct senc2d_enclosure* enclosure,
const unsigned ivert,
- double coord[2]);
+ double coord[SENC2D_GEOMETRY_DIMENSION]);
/* Returns the global id of the iseg_th segment of an enclosure
* and the involved side. */
SENC2D_API res_T
-senc2d_enclosure_get_segment_global_id
+senc2d_enclosure_get_segment_id
(const struct senc2d_enclosure* enclosure,
const unsigned iseg,
unsigned* gid,
diff --git a/src/senc2d_descriptor.c b/src/senc2d_descriptor.c
@@ -13,8 +13,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#include "senc2d_descriptor_c.h"
-#include "senc2d_device_c.h"
#include "senc2d_enclosure_c.h"
#include "senc2d_scene_c.h"
#include "senc2d.h"
@@ -23,108 +21,47 @@
#include <rsys/double2.h>
#include <rsys/mem_allocator.h>
- /*******************************************************************************
- * Helper function
- ******************************************************************************/
-static void
-descriptor_release(ref_T * ref)
-{
- struct senc2d_scene* scn = NULL;
- struct senc2d_descriptor* desc = NULL;
- ASSERT(ref);
- desc = CONTAINER_OF(ref, struct senc2d_descriptor, ref);
- scn = desc->scene;
- darray_segment_enc_release(&desc->segments_enc);
- darray_enclosure_release(&desc->enclosures);
- darray_enc_ids_array_release(&desc->enc_ids_array_by_medium);
- darray_vrtx_id_release(&desc->frontiers);
-
- MEM_RM(scn->dev->allocator, desc);
- SENC2D(scene_ref_put(scn));
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-struct senc2d_descriptor*
-descriptor_create(struct senc2d_scene* scn)
-{
- struct senc2d_descriptor* desc;
- res_T res = RES_OK;
- ASSERT(scn);
- desc = MEM_CALLOC(scn->dev->allocator, 1, sizeof(struct senc2d_descriptor));
- if(desc) {
- desc->scene = scn;
- SENC2D(scene_ref_get(desc->scene));
- ref_init(&desc->ref);
- darray_segment_enc_init(scn->dev->allocator, &desc->segments_enc);
- darray_enclosure_init(scn->dev->allocator, &desc->enclosures);
- darray_enc_ids_array_init(scn->dev->allocator,
- &desc->enc_ids_array_by_medium);
- OK(darray_enc_ids_array_resize(&desc->enc_ids_array_by_medium,
- 1 + scn->next_medium_idx)); /* +1 is for undef */
- darray_vrtx_id_init(scn->dev->allocator, &desc->frontiers);
- /* Enclosure 0 is always defined for infinite */
- OK(darray_enclosure_resize(&desc->enclosures, 1));
- desc->enclosures_count = 1;
- desc->segment_count = scn->nusegs;
- desc->vertices_count = scn->nuverts;
- }
-exit:
- return desc;
-error:
- if(desc) SENC2D(descriptor_ref_put(desc));
- goto exit;
-}
-
-struct mem_allocator*
- descriptor_get_allocator(struct senc2d_descriptor* desc)
-{
- ASSERT(desc);
- return desc->scene->dev->allocator;
-}
-
-/*******************************************************************************
+/******************************************************************************
* Exported functions
- ******************************************************************************/
+ *****************************************************************************/
res_T
-senc2d_descriptor_get_max_medium
- (const struct senc2d_descriptor* desc, unsigned* max_medium_id)
+senc2d_scene_get_max_medium
+ (const struct senc2d_scene* scn, unsigned* max_medium_id)
{
- if(!desc || !max_medium_id) return RES_BAD_ARG;
- ASSERT(desc->scene->next_medium_idx < UINT_MAX); /* API type */
- *max_medium_id = (unsigned)desc->scene->next_medium_idx - 1;
+ if(!scn || !max_medium_id) return RES_BAD_ARG;
+ ASSERT(scn->next_medium_idx < UINT_MAX); /* API type */
+ *max_medium_id = (unsigned)scn->next_medium_idx - 1;
return RES_OK;
}
res_T
-senc2d_descriptor_get_enclosure_count
- (const struct senc2d_descriptor* desc, unsigned* count)
+senc2d_scene_get_enclosure_count
+ (const struct senc2d_scene* scn, unsigned* count)
{
size_t tmp;
- if(!desc || !count) return RES_BAD_ARG;
- tmp = darray_enclosure_size_get(&desc->enclosures);
+ if(!scn || !count) return RES_BAD_ARG;
+ tmp = darray_enclosure_size_get(&scn->analyze.enclosures);
ASSERT(tmp < UINT_MAX); /* API type */
- ASSERT(desc->enclosures_count == tmp);
+ ASSERT(scn->analyze.enclosures_count == tmp);
*count = (unsigned)tmp;
return RES_OK;
}
res_T
-senc2d_descriptor_get_enclosure_count_by_medium
- (const struct senc2d_descriptor* desc,
+senc2d_scene_get_enclosure_count_by_medium
+ (const struct senc2d_scene* scn,
const unsigned imed,
unsigned* count)
{
size_t tmp, m_idx;
const struct darray_enc_id* enc_ids;
- if(!desc || !count
- || (imed != SENC2D_UNDEFINED_MEDIUM && imed >= desc->scene->next_medium_idx))
+ if(!scn || !count
+ || (imed != SENC2D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
return RES_BAD_ARG;
- ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
- == 1 + desc->scene->next_medium_idx);
- m_idx = (imed == SENC2D_UNDEFINED_MEDIUM) ? desc->scene->next_medium_idx : imed;
- enc_ids = darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium)
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ m_idx = (imed == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : imed + 1;
+ enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
+ m_idx;
tmp = darray_enc_id_size_get(enc_ids);
ASSERT(tmp < UINT_MAX); /* API type */
@@ -133,23 +70,24 @@ senc2d_descriptor_get_enclosure_count_by_medium
}
FINLINE res_T
-senc2d_descriptor_get_enclosure
- (struct senc2d_descriptor* desc,
+senc2d_scene_get_enclosure
+ (struct senc2d_scene* scn,
const unsigned idx,
struct senc2d_enclosure** out_enc)
{
struct senc2d_enclosure* enc;
- if(!desc || idx >= darray_enclosure_size_get(&desc->enclosures) || !out_enc)
+ if(!scn || idx >= darray_enclosure_size_get(&scn->analyze.enclosures)
+ || !out_enc)
return RES_BAD_ARG;
- enc = enclosure_create(desc, idx);
+ enc = enclosure_create(scn, idx);
if(!enc) return RES_MEM_ERR;
*out_enc = enc;
return RES_OK;
}
res_T
-senc2d_descriptor_get_enclosure_by_medium
- (struct senc2d_descriptor* desc,
+senc2d_scene_get_enclosure_by_medium
+ (struct senc2d_scene* scn,
const unsigned imed,
const unsigned idx,
struct senc2d_enclosure** out_enc)
@@ -157,111 +95,31 @@ senc2d_descriptor_get_enclosure_by_medium
size_t m_idx;
const struct darray_enc_id* enc_ids;
unsigned index;
- if(!desc || !out_enc
- || (imed != SENC2D_UNDEFINED_MEDIUM && imed >= desc->scene->next_medium_idx))
+ if(!scn || !out_enc
+ || (imed != SENC2D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
return RES_BAD_ARG;
- ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
- == 1 + desc->scene->next_medium_idx);
- m_idx = (imed == SENC2D_UNDEFINED_MEDIUM) ? desc->scene->next_medium_idx : imed;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ m_idx = (imed == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : imed + 1;
enc_ids =
- darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium) + m_idx;
+ darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG;
index = darray_enc_id_cdata_get(enc_ids)[idx];
- return senc2d_descriptor_get_enclosure(desc, index, out_enc);
+ return senc2d_scene_get_enclosure(scn, index, out_enc);
}
res_T
-senc2d_descriptor_get_global_segments_count
- (const struct senc2d_descriptor* desc,
- unsigned* count)
-{
- if(!desc || !count) return RES_BAD_ARG;
- ASSERT(desc->segment_count < UINT_MAX);
- *count = (unsigned)desc->segment_count; /* Back to API type */
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_get_global_vertices_count
- (const struct senc2d_descriptor* desc,
- unsigned* count)
-{
- if(!desc || !count) return RES_BAD_ARG;
- if(desc->vertices_count >= UINT_MAX)
- return RES_BAD_ARG;
- *count = (unsigned)desc->vertices_count; /* Back to API type */
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_get_global_segment
- (const struct senc2d_descriptor* desc,
- const unsigned iseg,
- unsigned indices[2])
-{
- const struct segment_in* seg;
- int i;
- if(!indices || ! desc
- || iseg >= darray_segment_in_size_get(&desc->scene->segments_in))
- return RES_BAD_ARG;
- seg = darray_segment_in_cdata_get(&desc->scene->segments_in) + iseg;
-
- FOR_EACH(i, 0, 2) {
- ASSERT(seg->vertice_id[i] < UINT_MAX);
- indices[i] = (unsigned)seg->vertice_id[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_get_global_vertex
- (const struct senc2d_descriptor* desc,
- const unsigned ivert,
- double vrtx[2])
-{
- const union double2* v;
- if(!vrtx || !desc
- || ivert >= darray_position_size_get(&desc->scene->vertices))
- return RES_BAD_ARG;
-
- v = darray_position_cdata_get(&desc->scene->vertices) + ivert;
- d2_set(vrtx, v->vec);
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_get_global_segment_media
- (const struct senc2d_descriptor* desc,
- const unsigned isef,
- unsigned media[2])
-{
- const struct segment_in* seg;
- int i;
- if(!media || !desc
- || isef >= darray_segment_in_size_get(&desc->scene->segments_in))
- return RES_BAD_ARG;
- seg = darray_segment_in_cdata_get(&desc->scene->segments_in) + isef;
- FOR_EACH(i, 0, 2) {
-#if (UINT_MAX < MEDIUM_MAX__)
- ASSERT(seg->medium[i] < UINT_MAX);
-#endif
- media[i] = (unsigned)seg->medium[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_get_global_segment_enclosures
- (const struct senc2d_descriptor* desc,
+senc2d_scene_get_segment_enclosures
+ (const struct senc2d_scene* scn,
const unsigned iseg,
unsigned enclosures[2])
{
const struct segment_enc* seg;
int i;
- if(!enclosures || !desc
- || iseg >= darray_segment_enc_size_get(&desc->segments_enc))
+ if(!enclosures || !scn
+ || iseg >= darray_segment_enc_size_get(&scn->analyze.segments_enc))
return RES_BAD_ARG;
- seg = darray_segment_enc_cdata_get(&desc->segments_enc) + iseg;
+ seg = darray_segment_enc_cdata_get(&scn->analyze.segments_enc) + iseg;
FOR_EACH(i, 0, 2) {
#if (UINT_MAX < ENCLOSURE_MAX__)
ASSERT(seg->enclosure[i] < UINT_MAX);
@@ -272,61 +130,30 @@ senc2d_descriptor_get_global_segment_enclosures
}
res_T
-senc2d_descriptor_get_global_segment_global_id
- (const struct senc2d_descriptor* desc,
- const unsigned iseg,
- unsigned* gid)
-{
- const struct segment_in* seg;
- if(!gid || !desc
- || iseg >= darray_segment_in_size_get(&desc->scene->segments_in))
- return RES_BAD_ARG;
- seg = darray_segment_in_cdata_get(&desc->scene->segments_in) + iseg;
- *gid = seg->global_id;
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_get_frontier_vertices_count
- (const struct senc2d_descriptor* desc,
+senc2d_scene_get_frontier_vertice_count
+ (const struct senc2d_scene* scn,
unsigned* count)
{
size_t tmp;
- if(!desc || !count)
+ if(!scn || !count)
return RES_BAD_ARG;
- tmp = darray_vrtx_id_size_get(&desc->frontiers);
+ tmp = darray_vrtx_id_size_get(&scn->analyze.frontiers);
ASSERT(tmp < UINT_MAX);
*count = (unsigned)tmp;
return RES_OK;
}
res_T
-senc2d_descriptor_get_frontier_vertex
- (const struct senc2d_descriptor* desc,
+senc2d_scene_get_frontier_vertex
+ (const struct senc2d_scene* scn,
const unsigned iver,
unsigned* vrtx_id)
{
vrtx_id_t vrtx;
- if(!vrtx_id || !desc
- || iver >= darray_vrtx_id_size_get(&desc->frontiers))
+ if(!vrtx_id || !scn
+ || iver >= darray_vrtx_id_size_get(&scn->analyze.frontiers))
return RES_BAD_ARG;
- vrtx = darray_vrtx_id_cdata_get(&desc->frontiers)[iver];
+ vrtx = darray_vrtx_id_cdata_get(&scn->analyze.frontiers)[iver];
*vrtx_id = (unsigned)vrtx; /* Back to API type */
return RES_OK;
}
-
-res_T
-senc2d_descriptor_ref_get(struct senc2d_descriptor* desc)
-{
- if(!desc) return RES_BAD_ARG;
- ref_get(&desc->ref);
- return RES_OK;
-}
-
-res_T
-senc2d_descriptor_ref_put(struct senc2d_descriptor* desc)
-{
- if(!desc) return RES_BAD_ARG;
- ref_put(&desc->ref, descriptor_release);
- return RES_OK;
-}
diff --git a/src/senc2d_descriptor_c.h b/src/senc2d_descriptor_c.h
@@ -1,109 +0,0 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (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 SENC2D_DESCRIPTOR_C_H
-#define SENC2D_DESCRIPTOR_C_H
-
-#include <rsys/ref_count.h>
-#include <rsys/dynamic_array.h>
-
-#include "senc2d.h"
-#include "senc2d_enclosure_data.h"
-#include "senc2d_internal_types.h"
-
-struct senc2d_scene;
-struct mem_allocator;
-
-struct segment_comp {
- /* The connex component in which each side is. */
- component_id_t component[2];
-};
-
-static void
-segment_comp_init(struct mem_allocator* alloc, struct segment_comp* seg) {
- int i;
- (void)alloc;
- ASSERT(seg);
- FOR_EACH(i, 0, 2) seg->component[i] = COMPONENT_NULL__;
-}
-
-#define DARRAY_NAME segment_comp
-#define DARRAY_DATA struct segment_comp
-#define DARRAY_FUNCTOR_INIT segment_comp_init
-#include <rsys/dynamic_array.h>
-
-struct segment_enc {
- /* The enclosure in which each side is. */
- enclosure_id_t enclosure[2];
-};
-
-#ifndef NDEBUG
-static void
-segment_enc_init(struct mem_allocator* alloc, struct segment_enc* seg) {
- int i;
- (void)alloc;
- ASSERT(seg);
- FOR_EACH(i, 0, 2) seg->enclosure[i] = ENCLOSURE_NULL__;
-}
-#define DARRAY_FUNCTOR_INIT segment_enc_init
-#endif
-
-#define DARRAY_NAME segment_enc
-#define DARRAY_DATA struct segment_enc
-#include <rsys/dynamic_array.h>
-
-#define DARRAY_NAME enclosure
-#define DARRAY_DATA struct enclosure_data
-#define DARRAY_FUNCTOR_INIT enclosure_data_init
-#define DARRAY_FUNCTOR_COPY enclosure_data_copy
-#define DARRAY_FUNCTOR_RELEASE enclosure_data_release
-#define DARRAY_FUNCTOR_COPY_AND_RELEASE enclosure_data_copy_and_release
-#include <rsys/dynamic_array.h>
-
-#define DARRAY_NAME enc_id
-#define DARRAY_DATA enclosure_id_t
-#include <rsys/dynamic_array.h>
-
-#define DARRAY_NAME enc_ids_array
-#define DARRAY_DATA struct darray_enc_id
-#define DARRAY_FUNCTOR_INIT darray_enc_id_init
-#define DARRAY_FUNCTOR_COPY darray_enc_id_copy
-#define DARRAY_FUNCTOR_RELEASE darray_enc_id_release
-#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_enc_id_copy_and_release
-#include <rsys/dynamic_array.h>
-
-struct senc2d_descriptor {
- struct senc2d_scene* scene;
- enclosure_id_t enclosures_count;
- /* Store by-segment enclosures */
- struct darray_segment_enc segments_enc;
- /* Store enclosures */
- struct darray_enclosure enclosures;
- struct darray_enc_ids_array enc_ids_array_by_medium;
- seg_id_t segment_count;
- vrtx_id_t vertices_count;
- /* Store frontiers */
- struct darray_vrtx_id frontiers;
-
- ref_T ref;
-};
-
-struct senc2d_descriptor*
-descriptor_create(struct senc2d_scene* scn);
-
-struct mem_allocator*
-descriptor_get_allocator(struct senc2d_descriptor* desc);
-
-#endif /* SENC2D_DESCRIPTOR_C_H */
diff --git a/src/senc2d_device.c b/src/senc2d_device.c
@@ -21,9 +21,9 @@
#include <omp.h>
-/*******************************************************************************
+/******************************************************************************
* Helper functions
- ******************************************************************************/
+ *****************************************************************************/
static void
log_msg
(struct senc2d_device* dev,
@@ -48,9 +48,9 @@ device_release(ref_T* ref)
MEM_RM(dev->allocator, dev);
}
-/*******************************************************************************
+/******************************************************************************
* Local functions
- ******************************************************************************/
+ *****************************************************************************/
void
log_err(struct senc2d_device* dev, const char* msg, ...)
{
@@ -84,9 +84,9 @@ log_info(struct senc2d_device* dev, const char* msg, ...)
va_end(vargs_list);
}
-/*******************************************************************************
+/******************************************************************************
* Exported functions
- ******************************************************************************/
+ *****************************************************************************/
res_T
senc2d_device_create
(struct logger* logger,
@@ -108,7 +108,7 @@ senc2d_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 StarEnclosures2D device.\n", FUNC_NAME) == RES_OK);
+ "%s: could not allocate the star-enclosures-2d device.\n", FUNC_NAME) == RES_OK);
}
res = RES_MEM_ERR;
goto error;
diff --git a/src/senc2d_enclosure.c b/src/senc2d_enclosure.c
@@ -14,8 +14,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "senc2d_enclosure_c.h"
-#include "senc2d_descriptor_c.h"
+#include "senc2d_enclosure_data.h"
#include "senc2d_scene_c.h"
+#include "senc2d_device_c.h"
#include "senc2d.h"
#include <rsys/rsys.h>
@@ -23,48 +24,46 @@
#include <rsys/mem_allocator.h>
-/*******************************************************************************
+/******************************************************************************
* Helper function
- ******************************************************************************/
+ *****************************************************************************/
static void
enclosure_release(ref_T * ref)
{
struct senc2d_enclosure* enclosure = NULL;
- struct senc2d_descriptor* desc = NULL;
+ struct senc2d_scene* scn = NULL;
ASSERT(ref);
enclosure = CONTAINER_OF(ref, struct senc2d_enclosure, ref);
- desc = enclosure->desc;
-
- MEM_RM(descriptor_get_allocator(desc), enclosure);
- SENC2D(descriptor_ref_put(desc));
+ scn = enclosure->scene;
+ MEM_RM(scn->dev->allocator, enclosure);
+ SENC2D(scene_ref_put(scn));
}
-/*******************************************************************************
+/******************************************************************************
* Local functions
- ******************************************************************************/
+ *****************************************************************************/
struct senc2d_enclosure*
enclosure_create
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scn,
const unsigned idx)
{
struct senc2d_enclosure* enc;
- ASSERT(desc && idx < darray_enclosure_size_get(&desc->enclosures));
- enc = MEM_CALLOC(descriptor_get_allocator(desc),
- 1, sizeof(struct senc2d_enclosure));
+ ASSERT(scn && idx < darray_enclosure_size_get(&scn->analyze.enclosures));
+ enc = MEM_CALLOC(scn->dev->allocator, 1, sizeof(struct senc2d_enclosure));
if(enc) {
const struct enclosure_data* data
- = darray_enclosure_data_get(&desc->enclosures) + idx;
- SENC2D(descriptor_ref_get(desc));
- enc->desc = desc;
+ = darray_enclosure_data_get(&scn->analyze.enclosures) + idx;
+ enc->scene = scn;
enc->data = data;
ref_init(&enc->ref);
+ SENC2D(scene_ref_get(scn));
}
return enc;
}
-/*******************************************************************************
+/******************************************************************************
* Exported functions
- ******************************************************************************/
+ *****************************************************************************/
res_T
senc2d_enclosure_get_header
(const struct senc2d_enclosure* enclosure,
@@ -84,10 +83,10 @@ senc2d_enclosure_get_segment
const struct side_enc* side;
int i;
if(!enclosure || !indices
- || iseg >= enclosure->data->header.segment_count)
+ || iseg >= enclosure->data->header.primitives_count)
return RES_BAD_ARG;
ASSERT(darray_sides_enc_size_get(&enclosure->data->sides)
- == enclosure->data->header.segment_count);
+ == enclosure->data->header.primitives_count);
side = darray_sides_enc_cdata_get(&enclosure->data->sides) + iseg;
FOR_EACH(i, 0, 2) {
ASSERT(side->vertice_id[i] < UINT_MAX);
@@ -109,7 +108,7 @@ senc2d_enclosure_get_vertex
const vrtx_id_t idx
= darray_vrtx_id_cdata_get(&enclosure->data->vertices)[ivert];
const union double2* positions
- = darray_position_cdata_get(&enclosure->desc->scene->vertices);
+ = darray_position_cdata_get(&enclosure->scene->vertices);
ASSERT(darray_vrtx_id_size_get(&enclosure->data->vertices)
== enclosure->data->header.vertices_count);
d2_set(coord, positions[idx].vec);
@@ -118,7 +117,7 @@ senc2d_enclosure_get_vertex
}
res_T
-senc2d_enclosure_get_segment_global_id
+senc2d_enclosure_get_segment_id
(const struct senc2d_enclosure* enclosure,
const unsigned iseg,
unsigned* gid,
@@ -126,10 +125,10 @@ senc2d_enclosure_get_segment_global_id
{
const struct side_enc* side;
if(!enclosure || !gid || !sde
- || iseg >= enclosure->data->header.segment_count)
+ || iseg >= enclosure->data->header.primitives_count)
return RES_BAD_ARG;
ASSERT(darray_sides_enc_size_get(&enclosure->data->sides)
- == enclosure->data->header.segment_count);
+ == enclosure->data->header.primitives_count);
side = darray_sides_enc_cdata_get(&enclosure->data->sides) + iseg;
*gid = (unsigned)SEGSIDE_2_SEG(side->side_id);
*sde = SEGSIDE_2_SIDE(side->side_id);
diff --git a/src/senc2d_enclosure_c.h b/src/senc2d_enclosure_c.h
@@ -21,17 +21,17 @@
#include "senc2d.h"
struct enclosure_data;
-struct senc2d_descriptor;
+struct senc2d_scene;
struct senc2d_enclosure {
const struct enclosure_data* data;
- struct senc2d_descriptor* desc;
+ struct senc2d_scene* scene;
ref_T ref;
};
struct senc2d_enclosure*
enclosure_create
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scene,
const unsigned idx);
#endif /* SENC2D_ENCLOSURE_C_H */
diff --git a/src/senc2d_enclosure_data.h b/src/senc2d_enclosure_data.h
@@ -16,17 +16,27 @@
#ifndef SENC2D_ENCLOSURE_DATA_H
#define SENC2D_ENCLOSURE_DATA_H
+#include "senc2d.h"
+#include "senc2d_internal_types.h"
+#include "senc2d_side_range.h"
+
#include <rsys/rsys.h>
#include <rsys/ref_count.h>
#include <rsys/hash_table.h>
#include <rsys/dynamic_array.h>
-
-#include "senc2d.h"
-#include "senc2d_scene_c.h"
-#include "senc2d_internal_types.h"
+#include <rsys/hash_table.h>
#include <limits.h>
+#define DARRAY_NAME vrtx_id
+#define DARRAY_DATA vrtx_id_t
+#include <rsys/dynamic_array.h>
+
+#define HTABLE_NAME vrtx_id
+#define HTABLE_KEY vrtx_id_t
+#define HTABLE_DATA vrtx_id_t
+#include <rsys/hash_table.h>
+
struct side_enc {
vrtx_id_t vertice_id[2];
side_id_t side_id;
@@ -41,7 +51,8 @@ static FINLINE void
zero_init_uchar
(struct mem_allocator* alloc, unsigned char* data)
{
- ASSERT(data); (void)alloc;
+ ASSERT(data); (void)
+ alloc;
*data = 0;
}
#define DARRAY_FUNCTOR_INIT zero_init_uchar
@@ -52,8 +63,8 @@ init_header(struct senc2d_enclosure_header* header)
{
ASSERT(header);
header->enclosure_id = ENCLOSURE_NULL__;
- header->segment_count = 0;
- header->unique_segment_count = 0;
+ header->primitives_count = 0;
+ header->unique_primitives_count = 0;
header->vertices_count = 0;
header->enclosed_media_count = 0;
header->is_infinite = CHAR_MAX;
@@ -92,24 +103,24 @@ error:
static FINLINE res_T
bool_array_of_media_to_darray_media
(struct darray_media* dst,
- struct darray_uchar* src,
- const medium_id_t undef_idx)
+ const struct darray_uchar* src,
+ const medium_id_t next_medium_idx)
{
res_T res = RES_OK;
- medium_id_t i;
+ unsigned m_idx;
const unsigned char* data;
ASSERT(src && dst);
data = darray_uchar_cdata_get(src);
- ASSERT(undef_idx + 1 == darray_uchar_size_get(src));
- ASSERT(undef_idx < MEDIUM_MAX__);
+ ASSERT(next_medium_idx + 1 == darray_uchar_size_get(src));
+ ASSERT(next_medium_idx < MEDIUM_MAX__);
darray_media_clear(dst);
if(res != RES_OK) goto error;
- FOR_EACH(i, 0, undef_idx + 1) {
- medium_id_t v = (i == undef_idx) ? SENC2D_UNDEFINED_MEDIUM : i;
- if(!data[i]) continue;
- res = darray_media_push_back(dst, &v);
+ FOR_EACH(m_idx, 0, next_medium_idx + 1) {
+ medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC2D_UNSPECIFIED_MEDIUM;
+ if(!data[m_idx]) continue;
+ res = darray_media_push_back(dst, &medium);
if(res != RES_OK) goto error;
}
end:
@@ -120,7 +131,7 @@ error:
struct enclosure_data {
struct senc2d_enclosure_header header;
- /* Same segment can appear twice if both sides */
+ /* Same segments can appear twice if both sides */
struct darray_sides_enc sides;
/* Index of vertices in scene's unique vertices */
struct darray_vrtx_id vertices;
@@ -202,4 +213,24 @@ error:
return res;
}
+#define DARRAY_NAME enclosure
+#define DARRAY_DATA struct enclosure_data
+#define DARRAY_FUNCTOR_INIT enclosure_data_init
+#define DARRAY_FUNCTOR_COPY enclosure_data_copy
+#define DARRAY_FUNCTOR_RELEASE enclosure_data_release
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE enclosure_data_copy_and_release
+#include <rsys/dynamic_array.h>
+
+#define DARRAY_NAME enc_id
+#define DARRAY_DATA enclosure_id_t
+#include <rsys/dynamic_array.h>
+
+#define DARRAY_NAME enc_ids_array
+#define DARRAY_DATA struct darray_enc_id
+#define DARRAY_FUNCTOR_INIT darray_enc_id_init
+#define DARRAY_FUNCTOR_COPY darray_enc_id_copy
+#define DARRAY_FUNCTOR_RELEASE darray_enc_id_release
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_enc_id_copy_and_release
+#include <rsys/dynamic_array.h>
+
#endif /* SENC2D_ENCLOSURE_DATA_H */
diff --git a/src/senc2d_internal_types.h b/src/senc2d_internal_types.h
@@ -16,8 +16,11 @@
#ifndef SENC2D_INTERNAL_TYPES_H
#define SENC2D_INTERNAL_TYPES_H
+#include "senc2d.h"
+
#include <rsys/math.h>
+#include <stdio.h>
#include <stdint.h>
/* Utility macros */
@@ -119,7 +122,7 @@ SEGSIDE_2_SIDEFLAG(side_id_t s) {
static FINLINE unsigned char
SIDE_CANCELED_FLAG(enum side_flag f) {
- ASSERT((((unsigned)f) << 4) <= UCHAR_MAX);
+ ASSERT((f << 4) <= UCHAR_MAX);
return (unsigned char)(f << 4);
}
diff --git a/src/senc2d_s2d_wrapper.h b/src/senc2d_s2d_wrapper.h
@@ -1,80 +0,0 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (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 SENC2D_S2D_WRAPPER_H
-#define SENC2D_S2D_WRAPPER_H
-
-#include "senc2d.h"
-
-#include <rsys/rsys.h>
-#include <rsys/float2.h>
-
-static FINLINE void
-senc2d_descriptor_get_global_indices__
- (const unsigned iseg,
- unsigned indices[2],
- void* ctx)
-{
- const struct senc2d_descriptor* descriptor = ctx;
- res_T r;
- ASSERT(indices && ctx);
- r = senc2d_descriptor_get_global_segment(descriptor, iseg, indices);
- ASSERT(r == RES_OK); (void)r;
-}
-
-static FINLINE void
-senc2d_descriptor_get_global_vertices__
- (const unsigned ivert,
- float coord[2],
- void* ctx)
-{
- const struct senc2d_descriptor* descriptor = ctx;
- double tmp[2];
- res_T r;
- ASSERT(coord && ctx);
- r = senc2d_descriptor_get_global_vertex(descriptor, ivert, tmp);
- ASSERT(r == RES_OK); (void)r;
- f2_set_d2(coord, tmp);
-}
-
-static FINLINE void
-senc2d_enclosure_get_segment__
- (const unsigned iseg,
- unsigned indices[2],
- void* ctx)
-{
- const struct senc2d_enclosure* enclosure = ctx;
- res_T r;
- ASSERT(indices && ctx);
- r = senc2d_enclosure_get_segment(enclosure, iseg, indices);
- ASSERT(r == RES_OK); (void)r;
-}
-
-static FINLINE void
-senc2d_enclosure_get_vertex__
- (const unsigned ivert,
- float coord[2],
- void* ctx)
-{
- const struct senc2d_enclosure* enclosure = ctx;
- double tmp[2];
- res_T r;
- ASSERT(coord && ctx);
- r = senc2d_enclosure_get_vertex(enclosure, ivert, tmp);
- ASSERT(r == RES_OK); (void)r;
- f2_set_d2(coord, tmp);
-}
-
-#endif /* SENC2D_S2D_WRAPPER_H */
diff --git a/src/senc2d_sXd_helper.h b/src/senc2d_sXd_helper.h
@@ -0,0 +1,92 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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 SENC2D_S2D_WRAPPER_H
+#define SENC2D_S2D_WRAPPER_H
+
+#include "senc2d.h"
+
+#include <rsys/rsys.h>
+#include <rsys/float2.h>
+
+/* Get vertex indices for the iseg_th segment.
+ * Suitable for use as get_indice callback in s2d_mesh_setup_indexed_vertices
+ * calls. */
+static FINLINE void
+senc2d_sXd_scene_get_indices
+ (const unsigned iseg,
+ unsigned indices[SENC2D_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ const struct senc2d_scene* scene = ctx;
+ res_T r;
+ ASSERT(indices && scene);
+ r = senc2d_scene_get_segment(scene, iseg, indices);
+ ASSERT(r == RES_OK); (void)r;
+}
+
+/* Get coordinates for the ivert_th vertex.
+ * Suitable for use as s2d_vertex_data getter for S2D_POSITION s2d_attrib_usage
+ * in s2d_mesh_setup_indexed_vertices calls. */
+static FINLINE void
+senc2d_sXd_scene_get_position
+ (const unsigned ivert,
+ float coord[SENC2D_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ const struct senc2d_scene* scene = ctx;
+ double tmp[2];
+ res_T r;
+ ASSERT(coord && scene);
+ r = senc2d_scene_get_vertex(scene, ivert, tmp);
+ ASSERT(r == RES_OK); (void)r;
+ f2_set_d2(coord, tmp);
+}
+
+/* Get vertex indices for the iseg_th segment of the enclosure.
+ * Suitable for use as get_indice callback in s2d_mesh_setup_indexed_vertices
+ * calls. */
+static FINLINE void
+senc2d_sXd_enclosure_get_indices
+ (const unsigned iseg,
+ unsigned indices[SENC2D_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ const struct senc2d_enclosure* enclosure = ctx;
+ res_T r;
+ ASSERT(indices && ctx);
+ r = senc2d_enclosure_get_segment(enclosure, iseg, indices);
+ ASSERT(r == RES_OK); (void)r;
+}
+
+/* Get coordinates for the ivert_th vertex of the enclosure.
+ * Suitable for use as s2d_vertex_data getter for S2D_POSITION s2d_attrib_usage
+ * in s2d_mesh_setup_indexed_vertices calls. */
+static FINLINE void
+senc2d_sXd_enclosure_get_position
+ (const unsigned ivert,
+ float coord[SENC2D_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ const struct senc2d_enclosure* enclosure = ctx;
+ double tmp[2];
+ res_T r;
+ ASSERT(coord && ctx);
+ r = senc2d_enclosure_get_vertex(enclosure, ivert, tmp);
+ ASSERT(r == RES_OK); (void)r;
+ f2_set_d2(coord, tmp);
+}
+
+#endif /* SENC2D_S2D_WRAPPER_H */
diff --git a/src/senc2d_scene.c b/src/senc2d_scene.c
@@ -16,6 +16,7 @@
#include "senc2d.h"
#include "senc2d_device_c.h"
#include "senc2d_scene_c.h"
+#include "senc2d_scene_analyze_c.h"
#include <rsys/rsys.h>
#include <rsys/double2.h>
@@ -23,9 +24,9 @@
#include <limits.h>
-/*******************************************************************************
+/******************************************************************************
* Helper function
- ******************************************************************************/
+ *****************************************************************************/
static void
scene_release(ref_T * ref)
{
@@ -36,9 +37,13 @@ scene_release(ref_T * ref)
dev = scn->dev;
darray_segment_in_release(&scn->segments_in);
darray_position_release(&scn->vertices);
- htable_vrtx_release(&scn->unique_vertices);
- htable_seg_release(&scn->unique_segments);
darray_side_range_release(&scn->media_use);
+
+ darray_segment_enc_release(&scn->analyze.segments_enc);
+ darray_enclosure_release(&scn->analyze.enclosures);
+ darray_enc_ids_array_release(&scn->analyze.enc_ids_array_by_medium);
+ darray_vrtx_id_release(&scn->analyze.frontiers);
+
MEM_RM(dev->allocator, scn);
SENC2D(device_ref_put(dev));
}
@@ -48,23 +53,33 @@ compatible_medium
(const medium_id_t m1,
const medium_id_t m2)
{
- if(m1 == SENC2D_UNDEFINED_MEDIUM || m2 == SENC2D_UNDEFINED_MEDIUM) return 1;
+ if(m1 == SENC2D_UNSPECIFIED_MEDIUM || m2 == SENC2D_UNSPECIFIED_MEDIUM) return 1;
return (m1 == m2);
}
-/*******************************************************************************
+/******************************************************************************
* Exported functions
- ******************************************************************************/
+ *****************************************************************************/
res_T
senc2d_scene_create
(struct senc2d_device* dev,
const int conv,
+ const unsigned nsegs,
+ void(*indices)(const unsigned, unsigned*, void*),
+ void(*media)(const unsigned, unsigned*, void*),
+ const unsigned nverts,
+ void(*position)(const unsigned, double*, void* ctx),
+ void* ctx,
struct senc2d_scene** out_scn)
{
struct senc2d_scene* scn = NULL;
+ /* Tables to detect duplicates */
+ struct htable_vrtx unique_vertices;
+ struct htable_seg unique_segments;
+ unsigned i;
res_T res = RES_OK;
- if(!dev || !out_scn
+ if(!dev || !out_scn || !indices || !position
/* Convention must be set both regarding FRONT/BACK and INSIDE/OUTSIDE */
|| !(conv & (SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_BACK))
|| !(conv & (SENC2D_CONVENTION_NORMAL_INSIDE | SENC2D_CONVENTION_NORMAL_OUTSIDE)))
@@ -72,7 +87,7 @@ senc2d_scene_create
scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct senc2d_scene));
if(!scn) {
- log_err(dev, "%s: could not allocate the StarEnclosures2D scene.\n", FUNC_NAME);
+ log_err(dev, "%s: could not allocate the star-enclosures-2d scene.\n", FUNC_NAME);
res = RES_MEM_ERR;
goto error;
}
@@ -80,240 +95,130 @@ senc2d_scene_create
SENC2D(device_ref_get(dev));
scn->dev = dev;
scn->convention = conv;
- scn->nsegs = 0;
- scn->nusegs = 0;
+ scn->nsegs = nsegs;
scn->next_medium_idx = 0;
- scn->nverts = 0;
- scn->nuverts = 0;
- scn->sides_with_defined_medium_count = 0;
+ scn->nverts = nverts;
darray_segment_in_init(dev->allocator, &scn->segments_in);
darray_position_init(dev->allocator, &scn->vertices);
- htable_vrtx_init(dev->allocator, &scn->unique_vertices);
- htable_seg_init(dev->allocator, &scn->unique_segments);
+ htable_vrtx_init(dev->allocator, &unique_vertices);
+ htable_seg_init(dev->allocator, &unique_segments);
darray_side_range_init(dev->allocator, &scn->media_use);
-exit:
- if(scn) *out_scn = scn;
- return res;
-error:
- if(scn) {
- SENC2D(scene_ref_put(scn));
- scn = NULL;
+ darray_segment_enc_init(scn->dev->allocator, &scn->analyze.segments_enc);
+ darray_enclosure_init(scn->dev->allocator, &scn->analyze.enclosures);
+ darray_enc_ids_array_init(scn->dev->allocator,
+ &scn->analyze.enc_ids_array_by_medium);
+ darray_vrtx_id_init(scn->dev->allocator, &scn->analyze.frontiers);
+ /* Enclosure 0 is always defined for infinite */
+ OK(darray_enclosure_resize(&scn->analyze.enclosures, 1));
+ scn->analyze.enclosures_count = 1;
+
+ if(!scn || !indices || !position || !nverts || !nsegs) {
+ res = RES_BAD_ARG;
+ goto error;
}
- goto exit;
-}
-
-res_T
-senc2d_scene_reserve
- (struct senc2d_scene* scn,
- const unsigned vertices_count,
- const unsigned segments_count,
- const unsigned media_count)
-{
- res_T res = RES_OK;
- if(!scn) return RES_BAD_ARG;
-
- OK(darray_position_reserve(&scn->vertices, vertices_count));
- OK(darray_segment_in_reserve(&scn->segments_in, segments_count));
- OK(htable_vrtx_reserve(&scn->unique_vertices, vertices_count));
- OK(htable_seg_reserve(&scn->unique_segments, segments_count));
- OK(darray_side_range_reserve(&scn->media_use, media_count));
-end:
- return res;
-error:
- goto end;
-}
-
-res_T
-senc2d_scene_add_geometry
- (struct senc2d_scene* scn,
- const unsigned nsegs,
- void(*indices)(const unsigned, unsigned* ids, void*),
- void(*media)(const unsigned, unsigned* med, void*),
- const unsigned nverts,
- void(*position)(const unsigned, double* pos, void*),
- res_T(*add_segment)(const unsigned, const unsigned, void*),
- res_T(*merge_segment)(const unsigned, const unsigned, const int,
- const unsigned*, const unsigned*, void*),
- void* ctx)
-{
- struct darray_vrtx_id unique_vertice_ids;
- unsigned i;
- vrtx_id_t actual_nverts = 0;
- vrtx_id_t actual_nuverts = 0;
- seg_id_t actual_nsegs = 0;
- seg_id_t actual_nusegs = 0;
- const struct segment_in* seg;
- res_T res = RES_OK;
+ OK(darray_position_reserve(&scn->vertices, scn->nverts));
+ OK(darray_segment_in_reserve(&scn->segments_in, scn->nsegs));
+ OK(htable_vrtx_reserve(&unique_vertices, scn->nverts));
+ OK(htable_seg_reserve(&unique_segments, scn->nsegs));
- if(!scn
- || !indices || !position
- || !nverts || ((size_t)scn->nverts + (size_t)nverts) > VRTX_MAX__
- || !nsegs || ((size_t)scn->nsegs + (size_t)nsegs) > SEG_MAX__)
- return RES_BAD_ARG;
-
- /* Make room for new geometry; suppose no more duplicates. */
- darray_vrtx_id_init(scn->dev->allocator, &unique_vertice_ids);
- OK(darray_vrtx_id_reserve(&unique_vertice_ids, nverts));
- OK(darray_position_reserve(&scn->vertices, scn->nuverts + nverts));
- OK(darray_segment_in_reserve(&scn->segments_in, scn->nusegs + nsegs));
- OK(htable_vrtx_reserve(&scn->unique_vertices, scn->nuverts + nverts));
- OK(htable_seg_reserve(&scn->unique_segments, scn->nusegs + nsegs));
-
- seg = darray_segment_in_cdata_get(&scn->segments_in);
-
- /* Get geometry */
+ /* Get vertices */
FOR_EACH(i, 0, nverts) {
vrtx_id_t* p_vrtx;
union double2 tmp;
- vrtx_id_t unique_v;
/* API: position needs an unsigned */
position(i, tmp.vec, ctx);
- p_vrtx = htable_vrtx_find(&scn->unique_vertices, &tmp);
+ p_vrtx = htable_vrtx_find(&unique_vertices, &tmp);
if(p_vrtx) {
/* Duplicate vertex */
- unique_v = *p_vrtx;
- } else {
- /* New vertex */
- unique_v = scn->nuverts + actual_nuverts;
- ASSERT(unique_v == htable_vrtx_size_get(&scn->unique_vertices));
- OK(darray_position_push_back(&scn->vertices, &tmp));
- OK(htable_vrtx_set(&scn->unique_vertices, &tmp, &unique_v));
- ++actual_nuverts;
+ log_err(scn->dev, "%s: vertex %u is a duplicate.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
}
- /* The unique ID for vertex i is unique_v */
- ASSERT(i == darray_vrtx_id_size_get(&unique_vertice_ids));
- OK(darray_vrtx_id_push_back(&unique_vertice_ids, &unique_v));
- ++actual_nverts;
+ /* New vertex */
+ ASSERT(i == htable_vrtx_size_get(&unique_vertices));
+ OK(darray_position_push_back(&scn->vertices, &tmp));
+ OK(htable_vrtx_set(&unique_vertices, &tmp, &i));
}
-
+ /* Get segments */
FOR_EACH(i, 0, nsegs) {
int j;
- unsigned med[2] = { SENC2D_UNDEFINED_MEDIUM, SENC2D_UNDEFINED_MEDIUM };
+ unsigned med[2] = { SENC2D_UNSPECIFIED_MEDIUM, SENC2D_UNSPECIFIED_MEDIUM };
unsigned ind[2];
union vrtx_id2 seg_key;
- struct segment_in tmp, *range_adjust_ptr = NULL;
+ struct segment_in tmp;
seg_id_t* p_seg;
- char reversed;
- /* Segment index in user world regardless of deduplication. */
- tmp.global_id = (unsigned)(scn->nsegs + i);
- indices(i, ind, ctx); /* API: indices needs an unsigned */
+ indices(i, ind, ctx); /* API: indices need unsigneds */
FOR_EACH(j, 0, 2) {
if(ind[j] >= nverts) {
+ log_err(scn->dev, "%s: segment %u uses invalid vertex id %u.\n",
+ FUNC_NAME, i, ind[j]);
res = RES_BAD_ARG;
goto error;
}
- ASSERT(ind[j] < darray_vrtx_id_size_get(&unique_vertice_ids));
- /* Find the unique ID for this vertex */
- tmp.vertice_id[j] = darray_vrtx_id_cdata_get(&unique_vertice_ids)[ind[j]];
+ ASSERT(ind[j] <= VRTX_MAX__);
+ tmp.vertice_id[j] = (vrtx_id_t)ind[j];
}
- if(tmp.vertice_id[0] == tmp.vertice_id[1]) {
- const union double2* positions
- = darray_position_cdata_get(&scn->vertices);
- log_err(scn->dev, "%s: segment %lu is degenerate.\n",
- FUNC_NAME, (unsigned long)tmp.global_id);
- log_err(scn->dev, " (%g %g) (%g %g)\n",
- SPLIT2(positions[seg[i].vertice_id[0]].vec),
- SPLIT2(positions[seg[i].vertice_id[1]].vec));
+ if(tmp.vertice_id[0] == tmp.vertice_id[1])
+ {
+ log_err(scn->dev, "%s: segment %u is degenerated.\n",
+ FUNC_NAME, i);
res = RES_BAD_ARG;
goto error;
}
/* Get media */
- if(media) media(i, med, ctx); /* API: media need unsigneds */
- FOR_EACH(j, 0, 2) {
- if(med[j] != SENC2D_UNDEFINED_MEDIUM && med[j] >= scn->next_medium_idx) {
- ASSERT(med[j] < MEDIUM_MAX__);
- scn->next_medium_idx = 1 + med[j];
- darray_side_range_resize(&scn->media_use, scn->next_medium_idx);
- }
- tmp.medium[j] = (medium_id_t)med[j];
- }
- /* Find duplicate segments */
- reversed = seg_make_key(&seg_key, tmp.vertice_id);
- p_seg = htable_seg_find(&scn->unique_segments, &seg_key);
+ if(media) media(i, med, ctx); /* API: media needs an unsigned */
+ seg_make_key(&seg_key, tmp.vertice_id);
+ p_seg = htable_seg_find(&unique_segments, &seg_key);
if(p_seg) {
- /* Duplicate segment. Need to check duplicate validity */
- union vrtx_id2 useg_key;
- char ureversed = seg_make_key(&useg_key, seg[*p_seg].vertice_id);
- int same = (reversed == ureversed);
- const medium_id_t* umed;
- ASSERT(seg_key_eq(&seg_key, &useg_key));
- if(!same) SWAP(unsigned, tmp.medium[0], tmp.medium[1]);
- umed = seg[*p_seg].medium;
- if(merge_segment) {
- /* Let the client app rule. */
- unsigned smed[2], mmed[2];
- FOR_EACH(j, 0, 2) {
- smed[j] = (unsigned)umed[j];
- mmed[j] = (unsigned)tmp.medium[j];
- }
- OK(merge_segment(seg[*p_seg].global_id, i, same, smed, mmed, ctx));
- /* If merge_segment returns OK its OK even if media are incompatible. */
- } else {
- if(!compatible_medium(umed[0], tmp.medium[0])
- || !compatible_medium(umed[1], tmp.medium[1]))
- {
- res = RES_BAD_ARG;
- goto error;
- }
- }
- /* Legit duplicate (or accepted by merge_segment): replace undef media. */
- range_adjust_ptr = darray_segment_in_data_get(&scn->segments_in) + *p_seg;
- /* Replace possible undefined media */
- FOR_EACH(j, 0, 2) {
- if(range_adjust_ptr->medium[j] == SENC2D_UNDEFINED_MEDIUM
- && tmp.medium[j] != SENC2D_UNDEFINED_MEDIUM) {
- range_adjust_ptr->medium[j] = tmp.medium[j];
- scn->sides_with_defined_medium_count++;
- }
- }
- } else {
- /* New segment */
- seg_id_t u = scn->nusegs + actual_nusegs;
- if(add_segment)
- OK(add_segment(tmp.global_id, i, ctx));
- OK(darray_segment_in_push_back(&scn->segments_in, &tmp));
- range_adjust_ptr = darray_segment_in_data_get(&scn->segments_in) + u;
- FOR_EACH(j, 0, 2) {
- if(tmp.medium[j] != SENC2D_UNDEFINED_MEDIUM)
- scn->sides_with_defined_medium_count++;
- }
- ASSERT(u == htable_seg_size_get(&scn->unique_segments));
- OK(htable_seg_set(&scn->unique_segments, &seg_key, &u));
- ++actual_nusegs;
+ /* Duplicate segment */
+ log_err(scn->dev, "%s: segment %u is a duplicate.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
}
- if(range_adjust_ptr) {
- ptrdiff_t u = range_adjust_ptr - seg;
- ASSERT(u < scn->nusegs + actual_nusegs && u < SEG_MAX__);
- FOR_EACH(j, 0, 2) {
- struct side_range* media_use;
- if(tmp.medium[j] == SENC2D_UNDEFINED_MEDIUM) continue;
- ASSERT(tmp.medium[j] < scn->next_medium_idx);
- media_use = darray_side_range_data_get(&scn->media_use) + tmp.medium[j];
- media_use->first =
- MMIN(media_use->first, SEGIDxSIDE_2_SEGSIDE((seg_id_t)u, j));
- ASSERT(media_use->first < 2 * (scn->nusegs + actual_nusegs + 1));
- media_use->last =
- MMAX(media_use->last, SEGIDxSIDE_2_SEGSIDE((seg_id_t)u, j));
- ASSERT(media_use->last < 2 * (scn->nusegs + actual_nusegs + 1));
- ASSERT(media_use->first <= media_use->last);
+ /* New segment */
+ ASSERT(i == htable_seg_size_get(&unique_segments));
+ OK(htable_seg_set(&unique_segments, &seg_key, &i));
+ FOR_EACH(j, 0, 2) {
+ struct side_range* media_use;
+ unsigned m_idx = (med[j] == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : med[j] + 1;
+ tmp.medium[j] = (medium_id_t)med[j];
+ if(m_idx >= scn->next_medium_idx) {
+ scn->next_medium_idx = m_idx;
+ darray_side_range_resize(&scn->media_use, 1 + m_idx);
}
+ /* media_use 0 is for SENC2D_UNSPECIFIED_MEDIUM */
+ media_use = darray_side_range_data_get(&scn->media_use) + m_idx;
+ media_use->first =
+ MMIN(media_use->first, SEGIDxSIDE_2_SEGSIDE((seg_id_t)i, j));
+ ASSERT(media_use->first < 2 * (scn->nsegs + 1));
+ media_use->last =
+ MMAX(media_use->last, SEGIDxSIDE_2_SEGSIDE((seg_id_t)i, j));
+ ASSERT(media_use->last < 2 * (scn->nsegs + 1));
+ ASSERT(media_use->first <= media_use->last);
}
- ++actual_nsegs;
+ OK(darray_segment_in_push_back(&scn->segments_in, &tmp));
}
+ OK(darray_enc_ids_array_resize(&scn->analyze.enc_ids_array_by_medium,
+ 1 + scn->next_medium_idx)); /* +1 is for undef */
+ /* Proceed to the analyze */
+ OK(scene_analyze(scn));
+
exit:
- darray_vrtx_id_release(&unique_vertice_ids);
- /* Update sizes */
- scn->nuverts += actual_nuverts;
- scn->nverts += actual_nverts;
- scn->nusegs += actual_nusegs;
- scn->nsegs += actual_nsegs;
- ASSERT(scn->nuverts == htable_vrtx_size_get(&scn->unique_vertices));
- ASSERT(scn->nusegs == htable_seg_size_get(&scn->unique_segments));
+ htable_vrtx_release(&unique_vertices);
+ htable_seg_release(&unique_segments);
+ if(scn) *out_scn = scn;
return res;
+
error:
+ if(scn) {
+ SENC2D(scene_ref_put(scn));
+ scn = NULL;
+ }
goto exit;
}
@@ -325,7 +230,6 @@ senc2d_scene_get_convention
if(!scn || !convention) return RES_BAD_ARG;
*convention = scn->convention;
return RES_OK;
-
}
res_T
@@ -339,28 +243,7 @@ senc2d_scene_get_segments_count
}
res_T
-senc2d_scene_get_unique_segments_count
- (const struct senc2d_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- *count = scn->nusegs;
- return RES_OK;
-}
-
-res_T
-senc2d_scene_get_unique_sides_without_medium_count
- (const struct senc2d_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- ASSERT(2 * scn->nusegs >= scn->sides_with_defined_medium_count);
- *count = 2 * scn->nusegs - scn->sides_with_defined_medium_count;
- return RES_OK;
-}
-
-res_T
-senc2d_scene_get_unique_segment
+senc2d_scene_get_segment
(const struct senc2d_scene* scn,
const unsigned iseg,
unsigned indices[2])
@@ -380,7 +263,7 @@ senc2d_scene_get_unique_segment
}
res_T
-senc2d_scene_get_unique_segment_media
+senc2d_scene_get_segment_media
(const struct senc2d_scene* scn,
const unsigned iseg,
unsigned media[2])
@@ -410,22 +293,11 @@ senc2d_scene_get_vertices_count
}
res_T
-senc2d_scene_get_unique_vertices_count
- (const struct senc2d_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- *count = scn->nuverts;
- return RES_OK;
-}
-
-res_T
-senc2d_scene_get_unique_vertex
+senc2d_scene_get_vertex
(const struct senc2d_scene* scn,
const unsigned ivert,
double coord[2])
{
-
const union double2* v;
if(!scn || !coord
|| ivert >= darray_position_size_get(&scn->vertices))
diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c
@@ -14,14 +14,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "senc2d.h"
-#include "senc2d_descriptor_c.h"
#include "senc2d_device_c.h"
#include "senc2d_scene_c.h"
+#include "senc2d_enclosure_data.h"
#include "senc2d_scene_analyze_c.h"
#include "senc2d_internal_types.h"
#include <rsys/rsys.h>
#include <rsys/float2.h>
+#include <rsys/double22.h>
#include <rsys/mem_allocator.h>
#include <rsys/hash_table.h>
#include <rsys/dynamic_array.h>
@@ -41,21 +42,21 @@
NULL\
}
#ifdef COMPILER_GCC
- #pragma GCC diagnostic push
+ #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
const struct cc_descriptor CC_DESCRIPTOR_NULL = CC_DESCRIPTOR_NULL__;
#ifdef COMPILER_GCC
- #pragma GCC diagnostic pop
+ #pragma GCC diagnostic pop
#endif
#define DARRAY_NAME component_id
#define DARRAY_DATA component_id_t
#include <rsys/dynamic_array.h>
-/*******************************************************************************
+/******************************************************************************
* Helper function
- ******************************************************************************/
+ *****************************************************************************/
static INLINE int
neighbour_cmp(const void* w1, const void* w2)
{
@@ -79,6 +80,7 @@ get_side_not_in_connex_component
&& (segsides[i].medium != medium
|| (processed[SEGSIDE_2_SEG(i)] & SEGSIDE_2_SIDEFLAG(i))))
++i;
+
*first_side_not_in_component = i + 1;
if(i > last_side) return SIDE_NULL__;
return i;
@@ -124,11 +126,12 @@ self_hit_filter
+ hit->prim.prim_id;
return (hit_seg_comp->component[SENC2D_FRONT] == *origin_component
|| hit_seg_comp->component[SENC2D_BACK] == *origin_component);
+
}
static void
extract_connex_components
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scn,
struct segside* segsides,
struct darray_ptr_component_descriptor* connex_components,
const struct darray_segment_tmp* segments_tmp_array,
@@ -141,9 +144,8 @@ extract_connex_components
{
/* This function is called from an omp parallel block and executed
* concurrently. */
- struct senc2d_scene* scn;
struct mem_allocator* alloc;
- int64_t mm, undefs;
+ int64_t m_idx;
struct darray_side_id stack;
struct darray_side_id ids_of_sides_around_max_y_vertex;
const union double2* positions;
@@ -155,53 +157,40 @@ extract_connex_components
struct darray_side_id current_component;
/* A bool array to store media of the component being processed */
unsigned char* current_media = NULL;
- size_t ii, sz;
+ size_t sz, ii;
- ASSERT(segsides && desc && connex_components && segments_tmp_array
+ ASSERT(scn && segsides && connex_components && segments_tmp_array
&& segments_comp_array && s2d_view && component_count && p_res);
- alloc = descriptor_get_allocator(desc);
- scn = desc->scene;
+ alloc = scn->dev->allocator;
positions = darray_position_cdata_get(&scn->vertices);
segments_tmp = darray_segment_tmp_cdata_get(segments_tmp_array);
segments_comp = darray_segment_comp_data_get(segments_comp_array);
darray_side_id_init(alloc, &stack);
darray_side_id_init(alloc, &ids_of_sides_around_max_y_vertex);
darray_side_id_init(alloc, ¤t_component);
- processed = MEM_CALLOC(alloc, scn->nusegs, sizeof(unsigned char));
+ processed = MEM_CALLOC(alloc, scn->nsegs, sizeof(unsigned char));
if(!processed) {
*p_res = RES_MEM_ERR;
return;
}
- /* If there are sides with undefined medium, its like another medium */
- undefs = (scn->sides_with_defined_medium_count < 2 * scn->nsegs) ? 1 : 0;
- #pragma omp single
- {
- if(undefs) {
- /* Range is unknown, process each side */
- struct side_range und;
- und.first = 0;
- und.last = 2 * scn->nsegs - 1;
- darray_side_range_push_back(&scn->media_use, &und);
- }
- } /* Implicit barrier here */
-
#ifndef NDEBUG
#pragma omp single
{
seg_id_t s_;
+ int s;
ASSERT(darray_ptr_component_descriptor_size_get(connex_components) == 0);
- FOR_EACH(s_, 0, scn->nusegs) {
+ FOR_EACH(s_, 0, scn->nsegs) {
const struct segment_in* seg_in =
darray_segment_in_cdata_get(&scn->segments_in) + s_;
const struct side_range* media_use
= darray_side_range_cdata_get(&scn->media_use);
- FOR_EACH(mm, 0, 2) {
- const side_id_t side = SEGIDxSIDE_2_SEGSIDE(s_, mm);
- medium_id_t medium = seg_in->medium[mm];
- if(medium == SENC2D_UNDEFINED_MEDIUM) medium = scn->next_medium_idx;
- ASSERT(media_use[medium].first <= side && side
- <= media_use[medium].last);
+ FOR_EACH(s, 0, 2) {
+ const side_id_t side = SEGIDxSIDE_2_SEGSIDE(s_, s);
+ medium_id_t medium = seg_in->medium[s];
+ m_idx = (medium == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1;
+ ASSERT(media_use[m_idx].first <= side && side
+ <= media_use[m_idx].last);
}
}
} /* Implicit barrier here */
@@ -210,13 +199,12 @@ extract_connex_components
/* We loop on sides to build connex components. */
#pragma omp for schedule(dynamic) nowait
/* Process all media, including undef */
- for(mm = 0; mm < undefs + (int64_t)scn->next_medium_idx; mm++) {
- const medium_id_t m_idx = (medium_id_t)mm;
- const medium_id_t m = (mm == scn->next_medium_idx)
- ? SENC2D_UNDEFINED_MEDIUM : (medium_id_t)mm;
- /* Any not-already-used side is used as a starting point */
+ for(m_idx = 0; m_idx < 1 + (int64_t)scn->next_medium_idx; m_idx++) {
+ const medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC2D_UNSPECIFIED_MEDIUM;
+ /* media_use 0 is for SENC2D_UNSPECIFIED_MEDIUM, n+1 is for n */
const struct side_range* media_use =
darray_side_range_cdata_get(&scn->media_use) + m_idx;
+ /* Any not-already-used side is used as a starting point */
side_id_t first_side_not_in_component = media_use->first;
double max_ny;
side_id_t max_ny_side_id = SIDE_NULL__;
@@ -228,20 +216,19 @@ extract_connex_components
if(*p_res != RES_OK) continue;
if(first_side_not_in_component == SIDE_NULL__)
continue; /* Unused medium */
- ASSERT(first_side_not_in_component < 2 * scn->nusegs);
+ ASSERT(first_side_not_in_component < 2 * scn->nsegs);
ASSERT(darray_side_id_size_get(&stack) == 0);
ASSERT(darray_side_id_size_get(¤t_component) == 0);
for(;;) { /* Process all components for this medium */
const side_id_t start_side_id = get_side_not_in_connex_component
- (last_side, segsides, processed, &first_side_not_in_component, m);
+ (last_side, segsides, processed, &first_side_not_in_component, medium);
side_id_t crt_side_id = start_side_id;
side_id_t last_side_id = start_side_id;
vrtx_id_t max_y_vrtx_id = VRTX_NULL__;
struct cc_descriptor *cc;
double max_y = -DBL_MAX;
component_canceled = 0;
-
- ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->nusegs);
+ ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->nsegs);
darray_side_id_clear(¤t_component);
if(*p_res != RES_OK) break;
@@ -253,16 +240,18 @@ extract_connex_components
seg_id_t sid = SEGSIDE_2_SEG(start_side_id);
enum senc2d_side s = SEGSIDE_2_SIDE(start_side_id);
medium_id_t side_med
- = darray_segment_in_data_get(&desc->scene->segments_in)[sid].medium[s];
- ASSERT(side_med == m);
+ = darray_segment_in_data_get(&scn->segments_in)[sid].medium[s];
+ ASSERT(side_med == medium);
}
#endif
/* Reuse array if possible, or create a new one */
if(current_media) {
- memset(current_media, 0, scn->next_medium_idx);
+ /* current_media 0 is for SENC2D_UNSPECIFIED_MEDIUM, n+1 is for n */
+ memset(current_media, 0, 1 + scn->next_medium_idx);
} else {
- current_media = MEM_CALLOC(alloc, 1 + scn->next_medium_idx, sizeof(unsigned char));
+ current_media = MEM_CALLOC(alloc, 1 + scn->next_medium_idx,
+ sizeof(*current_media));
if(!current_media) {
*p_res = RES_MEM_ERR;
continue;
@@ -278,9 +267,10 @@ extract_connex_components
darray_segment_in_cdata_get(&scn->segments_in) + crt_seg_id;
unsigned char* seg_used = processed + crt_seg_id;
const struct segment_tmp* const seg_tmp = segments_tmp + crt_seg_id;
- ASSERT(crt_seg_id < scn->nusegs);
+ ASSERT(crt_seg_id < scn->nsegs);
if(*p_res != RES_OK) break;
+
/* Record Ymax information
* Keep track of the appropriate vertex of the component in order
* to cast a ray at the component grouping step of the algorithm.
@@ -293,12 +283,13 @@ extract_connex_components
darray_side_id_clear(&ids_of_sides_around_max_y_vertex);
/* Select a vertex with y == max_y */
- if(max_y == positions[seg_in->vertice_id[0]].pos.y) {
- max_y_vrtx_id = seg_in->vertice_id[0];
- } else {
- ASSERT(max_y == positions[seg_in->vertice_id[1]].pos.y);
- max_y_vrtx_id = seg_in->vertice_id[1];
+ FOR_EACH(i, 0, 2) {
+ if(max_y == positions[seg_in->vertice_id[i]].pos.y) {
+ max_y_vrtx_id = seg_in->vertice_id[i];
+ break;
+ }
}
+ ASSERT(i < 2); /* Found one */
/* List of sides using the vertex */
OK2(darray_side_id_push_back(&ids_of_sides_around_max_y_vertex,
&crt_side_id));
@@ -317,19 +308,19 @@ extract_connex_components
/* Record crt_side both as component and segment level */
if((*seg_used & crt_side_flag) == 0) {
OK2(darray_side_id_push_back(¤t_component, &crt_side_id));
- *seg_used = *seg_used |(unsigned char)crt_side_flag;
+ *seg_used = *seg_used | (unsigned char)crt_side_flag;
}
- /* Store neighbours' sides in a stack */
+ /* Store neighbour's sides in a waiting stack */
FOR_EACH(i, 0, 2) {
side_id_t neighbour_id = crt_side->facing_side_id[i];
seg_id_t nbour_seg_id = SEGSIDE_2_SEG(neighbour_id);
enum side_flag nbour_side_id = SEGSIDE_2_SIDEFLAG(neighbour_id);
unsigned char* nbour_used = processed + nbour_seg_id;
const struct segside* neighbour = segsides + neighbour_id;
- medium_id_t nbour_med_idx = (neighbour->medium == SENC2D_UNDEFINED_MEDIUM)
- ? scn->next_medium_idx : neighbour->medium;
- if(neighbour->medium < m
+ medium_id_t nbour_med_idx = (neighbour->medium == SENC2D_UNSPECIFIED_MEDIUM)
+ ? 0 : neighbour->medium + 1;
+ if(neighbour->medium < medium
|| (*nbour_used & SIDE_CANCELED_FLAG(nbour_side_id)))
{
/* 1) Not the same medium.
@@ -338,20 +329,20 @@ extract_connex_components
* associated with neighbour's medium).
* 2) Neighbour was canceled: no need to replay the component
* again as it will eventually rediscover the side with low medium
- * id and recancel all the work in progress. */
+ * id and recancel all the work in progress */
component_canceled = 1;
darray_side_id_clear(&stack);
- /* Don't cancel used flags as all these sides will get us back to
+ /* Don't cancel used flags as all these sides will get us back to
* (at least) the neighbour side we have just discovered, that will
* cancel them again and again */
sz = darray_side_id_size_get(¤t_component);
FOR_EACH(ii, 0, sz) {
side_id_t used_side
= darray_side_id_cdata_get(¤t_component)[ii];
- seg_id_t used_trg_id = SEGSIDE_2_SEG(used_side);
+ seg_id_t used_seg_id = SEGSIDE_2_SEG(used_side);
enum side_flag used_side_flag
= SEGSIDE_2_SIDEFLAG(used_side);
- unsigned char* used = processed + used_trg_id;
+ unsigned char* used = processed + used_seg_id;
ASSERT(*used & (unsigned char)used_side_flag);
/* Set the used flag for sides in cancelled component as leading
* to further cancellations */
@@ -373,7 +364,7 @@ extract_connex_components
darray_side_id_pop_back(&stack);
last_side_id = MMAX(last_side_id, crt_side_id);
}
-canceled:
+ canceled:
if(component_canceled) continue;
/* Register the new component and get it initialized */
@@ -381,7 +372,7 @@ canceled:
if(!cc) *p_res = RES_MEM_ERR;
if(*p_res != RES_OK) break;
- ASSERT(m == segsides[start_side_id].medium);
+ ASSERT(medium == segsides[start_side_id].medium);
ASSERT(max_y_vrtx_id != VRTX_NULL__);
cc_descriptor_init(alloc, cc);
id = ATOMIC_INCR(component_count) - 1;
@@ -408,7 +399,7 @@ canceled:
enum senc2d_side sid = SEGSIDE_2_SIDE(s);
component_id_t* cmp = segments_comp[segid].component;
ASSERT(cmp[sid] == COMPONENT_NULL__);
- ASSERT(segsides[s].medium >= m);
+ ASSERT(segsides[s].medium >= medium);
cmp[sid] = cc->cc_id;
}
@@ -423,7 +414,7 @@ canceled:
enum senc2d_side s = SEGSIDE_2_SIDE(side_id);
const struct segment_in* seg_in =
darray_segment_in_cdata_get(&scn->segments_in) + seg_id;
- struct segment_comp* seg_comp = segments_comp + seg_id;
+ const struct segment_comp* seg_comp = segments_comp + seg_id;
const union double2* vertices =
darray_position_cdata_get(&scn->vertices);
double edge[2], normal[2], norm;
@@ -502,16 +493,16 @@ canceled:
attribs.get = get_scn_position;
/* Put geometry in a 2D view */
- OK(s2d_device_create(desc->scene->dev->logger, alloc, 0, &s2d));
+ OK(s2d_device_create(scn->dev->logger, alloc, 0, &s2d));
OK(s2d_scene_create(s2d, &s2d_scn));
OK(s2d_shape_create_line_segments(s2d, &s2d_shp));
/* Back to API type for nsegs and nverts */
- ASSERT(desc->scene->nusegs < UINT_MAX);
- ASSERT(desc->scene->nuverts < UINT_MAX);
+ ASSERT(scn->nsegs < UINT_MAX);
+ ASSERT(scn->nverts < UINT_MAX);
OK(s2d_line_segments_setup_indexed_vertices(s2d_shp,
- (unsigned)desc->scene->nusegs, get_scn_indices,
- (unsigned)desc->scene->nuverts, &attribs, 1, scn));
+ (unsigned)scn->nsegs, get_scn_indices,
+ (unsigned)scn->nverts, &attribs, 1, scn));
s2d_line_segments_set_hit_filter_function(s2d_shp, self_hit_filter,
segments_comp_array);
OK(s2d_scene_attach_shape(s2d_scn, s2d_shp));
@@ -533,8 +524,8 @@ canceled:
component_id_t c;
ASSERT(ATOMIC_GET(component_count) ==
(int)darray_ptr_component_descriptor_size_get(connex_components));
- FOR_EACH(s_, 0, scn->nusegs) {
- struct segment_comp* seg_comp =
+ FOR_EACH(s_, 0, scn->nsegs) {
+ struct segment_comp* seg_comp =
darray_segment_comp_data_get(segments_comp_array) + s_;
ASSERT(seg_comp->component[SENC2D_FRONT] != COMPONENT_NULL__);
ASSERT(seg_comp->component[SENC2D_BACK] != COMPONENT_NULL__);
@@ -544,14 +535,13 @@ canceled:
darray_ptr_component_descriptor_data_get(connex_components);
ASSERT(components[c] != NULL && components[c]->cc_id == c);
}
- ASSERT(desc->segment_count == scn->nusegs);
} /* Implicit barrier here */
#endif
}
static void
group_connex_components
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scn,
struct segside* segsides,
struct darray_segment_comp* segments_comp,
struct darray_ptr_component_descriptor* connex_components,
@@ -570,15 +560,15 @@ group_connex_components
int64_t ccc;
(void)segsides;
- ASSERT(desc && segsides && segments_comp && connex_components
- && s2d_view && next_enclosure_id && res);
- ASSERT(desc->enclosures_count == 1);
+ ASSERT(scn && segsides && segments_comp && connex_components
+ && s2d_view && next_enclosure_id && res);
+ ASSERT(scn->analyze.enclosures_count == 1);
descriptors = darray_ptr_component_descriptor_data_get(connex_components);
tmp = darray_ptr_component_descriptor_size_get(connex_components);
ASSERT(tmp <= COMPONENT_MAX__);
cc_count = (component_id_t)tmp;
- positions = darray_position_cdata_get(&desc->scene->vertices);
+ positions = darray_position_cdata_get(&scn->vertices);
/* Cast rays to find links between connex components */
#pragma omp for
@@ -596,7 +586,7 @@ group_connex_components
if(*res != RES_OK) continue;
ASSERT(cc->cc_id == c);
ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
- ASSERT(cc->max_y_vrtx_id < desc->scene->nverts);
+ ASSERT(cc->max_y_vrtx_id < scn->nverts);
max_vrtx = positions[cc->max_y_vrtx_id].vec;
if(cc->is_outer_border) {
@@ -628,13 +618,13 @@ group_connex_components
darray_segment_comp_cdata_get(segments_comp) + hit_seg_id;
enum senc2d_side hit_side =
((hit.normal[1] < 0) /* Facing geometrical normal of hit */
- == ((desc->scene->convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0))
+ == ((scn->convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0))
/* Warning: following Embree 2 convention for geometrical normals,
- * the Star2D hit normal is left-handed while star-enclosure2D uses
+ * the Star2D hit normal is left-handed while star-enclosure uses
* right-handed convention */
? SENC2D_BACK : SENC2D_FRONT;
ASSERT(hit.normal[1] != 0);
- ASSERT(hit_seg_id < desc->scene->nusegs);
+ ASSERT(hit_seg_id < scn->nsegs);
/* Not really the root until following links */
cc->cc_group_root = hit_seg_comp->component[hit_side];
@@ -649,22 +639,28 @@ group_connex_components
#pragma omp single
{
res_T tmp_res = RES_OK;
- desc->enclosures_count = (enclosure_id_t)ATOMIC_GET(next_enclosure_id);
- tmp_res = darray_enclosure_resize(&desc->enclosures, desc->enclosures_count);
+ scn->analyze.enclosures_count = (enclosure_id_t)ATOMIC_GET(next_enclosure_id);
+ tmp_res = darray_enclosure_resize(&scn->analyze.enclosures,
+ scn->analyze.enclosures_count);
if(tmp_res != RES_OK) {
*res = tmp_res;
} else {
struct enclosure_data* enclosures
- = darray_enclosure_data_get(&desc->enclosures);
+ = darray_enclosure_data_get(&scn->analyze.enclosures);
FOR_EACH(ccc, 0, cc_count) {
component_id_t c = (component_id_t)ccc;
struct cc_descriptor* const cc = descriptors[c];
const struct cc_descriptor* other_desc = cc;
struct enclosure_data* enc;
+#ifndef NDEBUG
+ component_id_t cc_cpt = 0;
+#endif
while(other_desc->enclosure_id == CC_GROUP_ID_NONE) {
- other_desc = *(darray_ptr_component_descriptor_cdata_get(connex_components)
- + other_desc->cc_group_root);
+ ASSERT(other_desc->cc_group_root < cc_count);
+ other_desc = descriptors[other_desc->cc_group_root];
+ /* Cannot have more components in cc than cc_count! */
+ ASSERT(++cc_cpt <= cc_count);
}
ASSERT(other_desc->cc_group_root != CC_GROUP_ROOT_NONE);
ASSERT(other_desc->enclosure_id != CC_GROUP_ID_NONE);
@@ -678,7 +674,7 @@ group_connex_components
enc->side_range.last = MMAX(enc->side_range.last, cc->side_range.last);
enc->side_count += cc->side_count;
tmp_res = bool_array_of_media_merge(&enc->tmp_enclosed_media, cc->media,
- desc->scene->next_medium_idx + 1);
+ scn->next_medium_idx + 1);
if(tmp_res != RES_OK) {
*res = tmp_res;
break;
@@ -694,52 +690,54 @@ collect_and_link_neighbours
(struct senc2d_scene* scn,
struct segside* segsides,
struct darray_segment_tmp* segments_tmp_array,
- struct darray_neighbourhood* neighbourhood_by_vertex,
struct darray_vrtx_id* frontiers,
/* Shared error status.
* We accept to overwrite an error with a different error */
res_T* res)
{
/* This function is called from an omp parallel block and executed
- * concurrently.
- * Resize / Push operations on neighbourhood_by_vertex are valid
- * because each neighbourhood is processes by an unique thread */
+ * concurrently. */
const struct segment_in* segments_in;
struct segment_tmp* segments_tmp;
const union double2* vertices;
const int thread_count = omp_get_num_threads();
const int rank = omp_get_thread_num();
+ /* Array to keep neighbourhood of vertices
+ * Resize/Push operations on neighbourhood_by_vertex are valid in the
+ * openmp block because a given neighbourhood is only processed
+ * by a single thread */
+ struct darray_neighbourhood neighbourhood_by_vertex;
vrtx_id_t v;
seg_id_t s;
+ res_T tmp_res;
- ASSERT(scn && segsides && segments_tmp_array
- && neighbourhood_by_vertex && frontiers && res);
- ASSERT((size_t)scn->nuverts + (size_t)scn->nusegs + 2 <= EDGE_MAX__);
+ ASSERT(scn && segsides && segments_tmp_array && frontiers && res);
+ ASSERT((size_t)scn->nverts + (size_t)scn->nsegs + 2 <= EDGE_MAX__);
+
+ darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_vertex);
+ OK2(darray_neighbourhood_resize(&neighbourhood_by_vertex, scn->nverts));
segments_in = darray_segment_in_cdata_get(&scn->segments_in);
segments_tmp = darray_segment_tmp_data_get(segments_tmp_array);
vertices = darray_position_cdata_get(&scn->vertices);
- ASSERT(scn->nusegs == darray_segment_tmp_size_get(segments_tmp_array));
+ ASSERT(scn->nsegs == darray_segment_tmp_size_get(segments_tmp_array));
/* Loop on segments to collect edges' neighbours.
* All threads considering all the vertices and processing some */
- FOR_EACH(s, 0, scn->nusegs) {
+ FOR_EACH(s, 0, scn->nsegs) {
unsigned char vv;
FOR_EACH(vv, 0, 2) {
struct darray_neighbour* neighbourhood;
struct neighbour_info* info;
const vrtx_id_t vertex = segments_in[s].vertice_id[vv];
size_t sz;
- res_T tmp_res = RES_OK;
- ASSERT(vertex < scn->nuverts);
- if(*res != RES_OK) continue;
/* Process only "my" vertices! */
if((int64_t)vertex % thread_count != rank) continue;
/* Find neighbourhood */
- ASSERT(vertex < darray_neighbourhood_size_get(neighbourhood_by_vertex));
+ ASSERT(vertex < darray_neighbourhood_size_get(&neighbourhood_by_vertex));
neighbourhood =
- darray_neighbourhood_data_get(neighbourhood_by_vertex) + vertex;
+ darray_neighbourhood_data_get(&neighbourhood_by_vertex) + vertex;
sz = darray_neighbour_size_get(neighbourhood);
/* Make room for this neighbour */
if(darray_neighbour_capacity(neighbourhood) == sz) {
@@ -771,7 +769,7 @@ collect_and_link_neighbours
/* For each of "my" vertices sort segments sides by rotation angle
* and connect neighbours.
* All threads considering all the vertices and processing some */
- FOR_EACH(v, 0, scn->nuverts) {
+ FOR_EACH(v, 0, scn->nverts) {
const vrtx_id_t common_vrtx = v;
vrtx_id_t other_vrtx;
struct darray_neighbour* neighbourhood;
@@ -781,7 +779,7 @@ collect_and_link_neighbours
/* Process only "my" neighbourhoods! */
if((int64_t)v % thread_count != rank) continue;
neighbourhood
- = darray_neighbourhood_data_get(neighbourhood_by_vertex) + v;
+ = darray_neighbourhood_data_get(&neighbourhood_by_vertex) + v;
sz = darray_neighbour_size_get(neighbourhood);
/* sz can be 0 as a vertex can be unused */
if(!sz) continue;
@@ -793,7 +791,6 @@ collect_and_link_neighbours
= darray_neighbour_data_get(neighbourhood) + i;
const struct segment_in* seg_in = segments_in + neighbour_info->seg_id;
struct segment_tmp* neighbour = segments_tmp + neighbour_info->seg_id;
-
union double2 n; /* Geometrical normal to neighbour segment */
const int is_reversed = neighbour_info->common_vertex_rank;
@@ -833,8 +830,8 @@ collect_and_link_neighbours
/* Sort segments by rotation angle */
qsort(darray_neighbour_data_get(neighbourhood), neighbour_count,
sizeof(struct neighbour_info), neighbour_cmp);
- /* Link sides.
- * Create cycles of sides by neighbourhood around common vertex. */
+ /* Link sides.
+ * Create cycles of sides by neighbourhood around common vertex. */
a = -DBL_MAX;
FOR_EACH(i, 0, neighbour_count) {
/* Neighbourhood info for current pair of segments */
@@ -857,7 +854,7 @@ collect_and_link_neighbours
= current->normal_toward_next_neighbour == front ? SENC2D_FRONT : SENC2D_BACK;
const enum senc2d_side ccw_side
= ccw_neighbour->normal_toward_next_neighbour == front ?
- SENC2D_BACK : SENC2D_FRONT;
+ SENC2D_BACK : SENC2D_FRONT;
/* Index of sides in segsides */
const side_id_t crt_side_idx = SEGIDxSIDE_2_SEGSIDE(crt_id, crt_side);
const side_id_t ccw_side_idx = SEGIDxSIDE_2_SEGSIDE(ccw_id, ccw_side);
@@ -874,11 +871,10 @@ collect_and_link_neighbours
previous = darray_neighbour_cdata_get(neighbourhood) + i - 1;
prev_id = previous->seg_id;
log_err(scn->dev,
- "%s: found 2 overlying segments (%lu & %lu).\n", FUNC_NAME,
- (unsigned long)segments_in[crt_id].global_id,
- (unsigned long)segments_in[prev_id].global_id);
- *res = RES_BAD_OP;
- return;
+ "%s: found 2 overlying segments (%u & %u).\n", FUNC_NAME,
+ (unsigned)crt_id, (unsigned)prev_id);
+ tmp_res = RES_BAD_OP;
+ goto tmp_error;
}
a = current->angle;
/* Link sides */
@@ -893,30 +889,33 @@ collect_and_link_neighbours
|| p_ccw_side->medium == segments_in[ccw_id].medium[ccw_side]);
p_crt_side->medium = segments_in[crt_id].medium[crt_side];
p_ccw_side->medium = segments_in[ccw_id].medium[ccw_side];
- ASSERT(p_crt_side->medium == SENC2D_UNDEFINED_MEDIUM
+ ASSERT(p_crt_side->medium == SENC2D_UNSPECIFIED_MEDIUM
|| p_crt_side->medium < scn->next_medium_idx);
- ASSERT(p_ccw_side->medium == SENC2D_UNDEFINED_MEDIUM
+ ASSERT(p_ccw_side->medium == SENC2D_UNSPECIFIED_MEDIUM
|| p_ccw_side->medium < scn->next_medium_idx);
/* Detect segments that could surround a hole:
- * - single segments on (one of) its end
+ * - single segment on (one of) its end
* - different media on its sides */
if(neighbour_count == 1
&& p_crt_side->medium != p_ccw_side->medium)
#pragma omp critical
{
log_warn(scn->dev,
- "%s: found possible frontier involving segment %lu.\n",
- FUNC_NAME, (unsigned long)segments_in[crt_id].global_id);
+ "%s: found frontier involving segment %lu.\n",
+ FUNC_NAME, (unsigned long)crt_id);
darray_vrtx_id_push_back(frontiers, &v);
}
}
}
+tmp_error:
+ if(tmp_res != RES_OK) *res = tmp_res;
/* Threads are allowed to return whitout sync. */
+ darray_neighbourhood_release(&neighbourhood_by_vertex);
}
static void
build_result
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scn,
const struct darray_ptr_component_descriptor* connex_components,
const struct darray_segment_comp* segments_comp_array,
struct darray_vrtx_id* frontiers,
@@ -933,39 +932,38 @@ build_result
struct segment_enc* segments_enc;
const struct segment_comp* segments_comp;
struct htable_vrtx_id vtable;
- struct senc2d_scene* scn;
int output_normal_in, normals_front, normals_back;
int64_t sg;
int64_t ee;
- ASSERT(desc && connex_components && segments_comp_array && frontiers && res);
+ ASSERT(scn && connex_components && segments_comp_array && frontiers && res);
- alloc = descriptor_get_allocator(desc);
- scn = desc->scene;
+ alloc = scn->dev->allocator;
output_normal_in = (scn->convention & SENC2D_CONVENTION_NORMAL_INSIDE) != 0;
normals_front = (scn->convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
normals_back = (scn->convention & SENC2D_CONVENTION_NORMAL_BACK) != 0;
ASSERT(normals_back != normals_front);
- ASSERT(output_normal_in !=
- ((scn->convention & SENC2D_CONVENTION_NORMAL_OUTSIDE) != 0));
+ ASSERT(output_normal_in
+ != ((scn->convention & SENC2D_CONVENTION_NORMAL_OUTSIDE) != 0));
ASSERT(darray_ptr_component_descriptor_size_get(connex_components)
<= COMPONENT_MAX__);
cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components);
- enclosures = darray_enclosure_data_get(&desc->enclosures);
+ enclosures = darray_enclosure_data_get(&scn->analyze.enclosures);
segments_in = darray_segment_in_cdata_get(&scn->segments_in);
segments_comp = darray_segment_comp_cdata_get(segments_comp_array);
+
#pragma omp single
{
res_T tmp_res =
- darray_segment_enc_resize(&desc->segments_enc, scn->nusegs);
+ darray_segment_enc_resize(&scn->analyze.segments_enc, scn->nsegs);
if(tmp_res != RES_OK) *res = tmp_res;
}/* Implicit barrier here. */
if(*res != RES_OK) return;
- segments_enc = darray_segment_enc_data_get(&desc->segments_enc);
+ segments_enc = darray_segment_enc_data_get(&scn->analyze.segments_enc);
/* Build global enclosure information */
#pragma omp for
- for(sg = 0; sg < (int64_t)scn->nusegs; sg++) {
+ for(sg = 0; sg < (int64_t)scn->nsegs; sg++) {
seg_id_t s = (seg_id_t)sg;
const component_id_t cf_id = segments_comp[s].component[SENC2D_FRONT];
const component_id_t cb_id = segments_comp[s].component[SENC2D_BACK];
@@ -984,9 +982,9 @@ build_result
* openmp block as a given enclosure is processed by a single thread */
htable_vrtx_id_init(alloc, &vtable);
- ASSERT(desc->enclosures_count <= ENCLOSURE_MAX__);
+ ASSERT(scn->analyze.enclosures_count <= ENCLOSURE_MAX__);
#pragma omp for schedule(dynamic) nowait
- for(ee = 0; ee < (int64_t)desc->enclosures_count; ee++) {
+ for(ee = 0; ee < (int64_t)scn->analyze.enclosures_count; ee++) {
const enclosure_id_t e = (enclosure_id_t)ee;
struct enclosure_data* enc = enclosures + e;
seg_id_t fst_idx = 0;
@@ -1002,7 +1000,7 @@ build_result
if(*res != RES_OK) continue;
ASSERT(e <= UINT_MAX);
enc->header.enclosure_id = (unsigned)e; /* Back to API type */
- ASSERT(cc_descriptors[enc->first_component]->enclosure_id
+ ASSERT(cc_descriptors[enc->first_component]->enclosure_id
== enc->header.enclosure_id);
enc->header.is_infinite = (e == 0);
@@ -1016,18 +1014,17 @@ build_result
/* Add this enclosure in relevant by-medium lists */
FOR_EACH(m, 0, enc->header.enclosed_media_count) {
- medium_id_t medium = darray_media_data_get(&enc->enclosed_media)[m];
- size_t m_idx = (medium == SENC2D_UNDEFINED_MEDIUM)
- ? scn->next_medium_idx : medium;
- struct darray_enc_id* enc_ids_by_medium;
- ASSERT(medium == SENC2D_UNDEFINED_MEDIUM || medium < scn->next_medium_idx);
- ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
+ medium_id_t medium = darray_media_cdata_get(&enc->enclosed_media)[m];
+ unsigned m_idx = (medium == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1;
+ struct darray_enc_id* enc_ids_array_by_medium;
+ ASSERT(medium == SENC2D_UNSPECIFIED_MEDIUM || medium < scn->next_medium_idx);
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
== 1 + scn->next_medium_idx);
- enc_ids_by_medium =
- darray_enc_ids_array_data_get(&desc->enc_ids_array_by_medium) + m_idx;
+ enc_ids_array_by_medium =
+ darray_enc_ids_array_data_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
#pragma omp critical
{
- tmp_res = darray_enc_id_push_back(enc_ids_by_medium, &e);
+ tmp_res = darray_enc_id_push_back(enc_ids_array_by_medium, &e);
}
if(tmp_res != RES_OK) {
*res = tmp_res;
@@ -1039,10 +1036,11 @@ build_result
/* Build side and vertex lists. */
OK2(darray_sides_enc_resize(&enc->sides, enc->side_count));
/* Size is just a int */
- OK2(darray_vrtx_id_reserve(&enc->vertices, enc->side_count + 1));
+ OK2(darray_vrtx_id_reserve(&enc->vertices,
+ (size_t)(enc->side_count * 0.6)));
/* New vertex numbering scheme local to the enclosure */
htable_vrtx_id_clear(&vtable);
- ASSERT(scn->nusegs == darray_segment_in_size_get(&scn->segments_in));
+ ASSERT(scn->nsegs == darray_segment_in_size_get(&scn->segments_in));
/* Put at the end the back-faces of segments that also have their
* front-face in the list. */
for(s = SEGSIDE_2_SEG(enc->side_range.first);
@@ -1056,7 +1054,7 @@ build_result
if(segments_enc[s].enclosure[SENC2D_FRONT] != e
&& segments_enc[s].enclosure[SENC2D_BACK] != e)
continue;
- ++enc->header.unique_segment_count;
+ ++enc->header.unique_primitives_count;
FOR_EACH(i, 0, 2) {
vrtx_id_t* p_id = htable_vrtx_id_find(&vtable, seg_in->vertice_id + i);
@@ -1080,19 +1078,19 @@ build_result
/* Front side of the original segment is member of the enclosure */
int input_normal_in = normals_front;
int revert_segment = (input_normal_in != output_normal_in);
- ++enc->header.segment_count;
+ ++enc->header.primitives_count;
side_enc = darray_sides_enc_data_get(&enc->sides) + fst_idx++;
FOR_EACH(i, 0, 2) {
int ii = revert_segment ? 1 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(seg_in->global_id, SENC2D_FRONT);
+ side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(s, SENC2D_FRONT);
}
if(segments_enc[s].enclosure[SENC2D_BACK] == e) {
/* Back side of the original segment is member of the enclosure */
int input_normal_in = normals_back;
int revert_segment = (input_normal_in != output_normal_in);
- ++enc->header.segment_count;
+ ++enc->header.primitives_count;
/* If both sides are in the enclosure, put the second side at the end */
side_enc = darray_sides_enc_data_get(&enc->sides) +
((segments_enc[s].enclosure[SENC2D_FRONT] == e) ? --sgd_idx : fst_idx++);
@@ -1100,7 +1098,7 @@ build_result
int ii = revert_segment ? 1 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(seg_in->global_id, SENC2D_BACK);
+ side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(s, SENC2D_BACK);
}
if(fst_idx == sgd_idx) break;
}
@@ -1112,19 +1110,17 @@ build_result
htable_vrtx_id_release(&vtable);
/* The first thread here copies frontiers into descriptor */
#pragma omp single nowait
- darray_vrtx_id_copy_and_clear(&desc->frontiers, frontiers);
+ darray_vrtx_id_copy_and_clear(&scn->analyze.frontiers, frontiers);
/* No barrier here */
}
-/*******************************************************************************
+/******************************************************************************
* Exported functions
- ******************************************************************************/
+ *****************************************************************************/
res_T
-senc2d_scene_analyze
- (struct senc2d_scene* scn,
- struct senc2d_descriptor** out_desc)
+scene_analyze
+ (struct senc2d_scene* scn)
{
- struct senc2d_descriptor* desc = NULL;
/* By segment tmp data */
struct darray_segment_tmp segments_tmp;
char segments_tmp_initialized = 0;
@@ -1132,71 +1128,53 @@ senc2d_scene_analyze
* They are refered to by arrays of ids. */
struct darray_ptr_component_descriptor connex_components;
char connex_components_initialized = 0;
- /* Array of frontiers vertices */
+ /* Array of frontier vertices */
struct darray_vrtx_id frontiers;
char frontiers_initialized = 0;
/* Store by-segment components */
struct darray_segment_comp segments_comp;
char segments_comp_initialized = 0;
- /* Array of vertices (segment ends). */
+ /* Array of segment ends. */
struct segside* segsides = NULL;
struct s2d_scene_view* s2d_view = NULL;
- /* Array to keep neighbourhood of vertices */
- struct darray_neighbourhood neighbourhood_by_vertex;
- char neighbourhood_by_vertex_initialized = 0;
/* Atomic counters to share beetwen threads */
ATOMIC component_count = 0;
ATOMIC next_enclosure_id = 1;
res_T res = RES_OK;
res_T res2 = RES_OK;
+
+ if(!scn) return RES_BAD_ARG;
- if(!scn || !out_desc) return RES_BAD_ARG;
-
- /* The first part of the analyze is single threaded */
- desc = descriptor_create(scn);
- if(!desc) {
- res = RES_MEM_ERR;
- goto error;
- }
-
- if(!scn->nusegs) goto exit;
+ if(!scn->nsegs) goto exit;
darray_segment_tmp_init(scn->dev->allocator, &segments_tmp);
segments_tmp_initialized = 1;
darray_vrtx_id_init(scn->dev->allocator, &frontiers);
frontiers_initialized = 1;
- OK(darray_segment_tmp_resize(&segments_tmp, scn->nusegs));
+ OK(darray_segment_tmp_resize(&segments_tmp, scn->nsegs));
segsides
- = MEM_CALLOC(scn->dev->allocator, 2 * scn->nusegs, sizeof(struct segside));
+ = MEM_CALLOC(scn->dev->allocator, 2 * scn->nsegs, sizeof(struct segside));
if(!segsides) {
res = RES_MEM_ERR;
goto error;
}
#ifndef NDEBUG
else {
- /* Initialise trgsides to allow assert code */
+ /* Initialise segsides to allow assert code */
size_t i;
- FOR_EACH(i, 0, 2 * scn->nusegs)
- init_segside(scn->dev->allocator, segsides + i);
+ FOR_EACH(i, 0, 2 * scn->nsegs)
+ init_segside(scn->dev->allocator, segsides + i);
}
#endif
-
- /* We create a neighbourhood for every single unique vertex,
- * regardless the fact it is used by a segment.
- * This allows threads to use these neighbourhoods whithout sync. */
- darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_vertex);
- neighbourhood_by_vertex_initialized = 1;
- OK(darray_neighbourhood_resize(&neighbourhood_by_vertex, scn->nuverts));
-
/* The end of the analyze is multithreaded */
ASSERT(scn->dev->nthreads > 0);
#pragma omp parallel num_threads(scn->dev->nthreads)
{
/* Step 1: build neighbourhoods */
- collect_and_link_neighbours(scn, segsides, &segments_tmp,
- &neighbourhood_by_vertex, &frontiers, &res);
+ collect_and_link_neighbours(scn, segsides, &segments_tmp, &frontiers,
+ &res);
/* No barrier at the end of step 1: data used in step 1 cannot be
* released / data produced by step 1 cannot be used
* until next sync point */
@@ -1206,7 +1184,6 @@ senc2d_scene_analyze
#pragma omp single
{
res_T tmp_res = RES_OK;
-
darray_ptr_component_descriptor_init(scn->dev->allocator,
&connex_components);
connex_components_initialized = 1;
@@ -1215,14 +1192,14 @@ senc2d_scene_analyze
2 + 2 * scn->next_medium_idx));
darray_segment_comp_init(scn->dev->allocator, &segments_comp);
segments_comp_initialized = 1;
- OK2(darray_segment_comp_resize(&segments_comp, scn->nusegs));
+ OK2(darray_segment_comp_resize(&segments_comp, scn->nsegs));
tmp_error:
if(tmp_res != RES_OK) res2 = tmp_res;
}
/* Implicit barrier here: constraints on step 1 data are now met */
if(res != RES_OK || res2 != RES_OK) {
- #pragma omp single nowait
+ #pragma omp single nowait
{
if(res != RES_OK) {
log_err(scn->dev,
@@ -1234,16 +1211,8 @@ senc2d_scene_analyze
goto error_;
}
- /* One thread releases some data before going to step 2,
- * the others go to step 2 without sync */
- #pragma omp single nowait
- {
- darray_neighbourhood_release(&neighbourhood_by_vertex);
- neighbourhood_by_vertex_initialized = 0;
- } /* No barrier here */
-
/* Step 2: extract segment connex components */
- extract_connex_components(desc, segsides, &connex_components,
+ extract_connex_components(scn, segsides, &connex_components,
&segments_tmp, &segments_comp, &s2d_view, &component_count, &res);
/* No barrier at the end of step 2: data used in step 2 cannot be
* released / data produced by step 2 cannot be used
@@ -1251,7 +1220,7 @@ senc2d_scene_analyze
#pragma omp barrier
/* Constraints on step 2 data are now met */
-
+
if(res != RES_OK) {
#pragma omp single nowait
{
@@ -1270,8 +1239,8 @@ senc2d_scene_analyze
} /* No barrier here */
/* Step 3: group components */
- group_connex_components(desc, segsides, &segments_comp, &connex_components,
- s2d_view, &next_enclosure_id, &res);
+ group_connex_components(scn, segsides, &segments_comp,
+ &connex_components, s2d_view, &next_enclosure_id, &res);
/* Barrier at the end of step 3: data used in step 3 can be released /
* data produced by step 3 can be used */
@@ -1293,14 +1262,13 @@ senc2d_scene_analyze
} /* No barrier here */
/* Step 4: Build result */
- build_result(desc, &connex_components, &segments_comp, &frontiers,
- &res);
+ build_result(scn, &connex_components, &segments_comp, &frontiers, &res);
/* No barrier at the end of step 4: data used in step 4 cannot be
* released / data produced by step 4 cannot be used
* until next sync point */
#pragma omp barrier
- /* Constraints on step 4 data are now met */
+ /* Constraints on step 4 data are now met */
if(res != RES_OK) {
#pragma omp single nowait
@@ -1329,22 +1297,18 @@ error_:
;
} /* Implicit barrier here */
-if(res != RES_OK) goto error;
+ if(res != RES_OK) goto error;
exit:
if(connex_components_initialized)
custom_darray_ptr_component_descriptor_release(&connex_components);
if(s2d_view) S2D(scene_view_ref_put(s2d_view));
- if(neighbourhood_by_vertex_initialized)
- darray_neighbourhood_release(&neighbourhood_by_vertex);
if(segments_tmp_initialized) darray_segment_tmp_release(&segments_tmp);
if(segments_comp_initialized) darray_segment_comp_release(&segments_comp);
- if(frontiers_initialized) darray_vrtx_id_release(&frontiers);
+ if(frontiers_initialized)
+ darray_vrtx_id_release(&frontiers);
if(segsides) MEM_RM(scn->dev->allocator, segsides);
- if(desc) *out_desc = desc;
return res;
error:
- if(desc) SENC2D(descriptor_ref_put(desc));
- desc = NULL;
goto exit;
}
diff --git a/src/senc2d_scene_analyze.c.save b/src/senc2d_scene_analyze.c.save
@@ -1,1254 +0,0 @@
-/* Copyright (C) |Meso|Star> 2016-2018 (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/>. */
-
-#include "senc2d.h"
-#include "senc2d_descriptor_c.h"
-#include "senc2d_device_c.h"
-#include "senc2d_scene_c.h"
-#include "senc2d_scene_analyze_c.h"
-#include "senc2d_internal_types.h"
-
-#include <rsys/rsys.h>
-#include <rsys/float2.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/hash_table.h>
-#include <rsys/dynamic_array.h>
-
-#if defined(COMPILER_GCC)
-#define ATOMIC_CAS_PTR(Atom, NewVal, Comparand) /* Return the initial value */ \
- ATOMIC_CAS((Atom), (NewVal), (Comparand))
-#elif defined(COMPILER_CL)
-#define ATOMIC_CAS_PTR(Atom, NewVal, Comparand) /* Return the initial value */ \
- (InterlockedCompareExchangePointer(Atom, NewVal, Comparand))
-#else
-#error "Undefined atomic operations"
-#endif
-
-#include <star/s2d.h>
-
-#include <omp.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#define CC_DESCRIPTOR_NULL__ {\
- {0,-DBL_MAX}, -1, SIDE_NULL__, VRTX_NULL__, 0, MEDIUM_NULL__,\
- CC_ID_NONE, CC_GROUP_ROOT_NONE, CC_GROUP_ID_NONE, CC_ID_NONE,\
- { SEG_NULL__, 0}\
-}
-const struct cc_descriptor CC_DESCRIPTOR_NULL = CC_DESCRIPTOR_NULL__;
-
-#define DARRAY_NAME component_id
-#define DARRAY_DATA component_id_t
-#include <rsys/dynamic_array.h>
-
-#define DARRAY_NAME side_id
-#define DARRAY_DATA side_id_t
-#include <rsys/dynamic_array.h>
-
-/*******************************************************************************
- * Helper function
- ******************************************************************************/
-static INLINE int
-find_side_in_list
- (const struct segside* segsides,
- const struct darray_side_id* side_ids,
- const side_id_t side_id,
- const enum list_id list_id)
-{
- side_id_t i;
- size_t tmp;
- (void)list_id;
- (void)segsides;
- ASSERT(segsides && side_ids);
- tmp = darray_side_id_size_get(side_ids);
- ASSERT(tmp <= SIDE_MAX__);
- FOR_EACH(i, 0, (side_id_t)tmp) {
- const side_id_t id = darray_side_id_cdata_get(side_ids)[i];
- ASSERT(segsides[id].list_id & list_id);
- if(id == side_id) return 1;
- }
- return 0;
-}
-
-static INLINE int
-neighbour_cmp(const void* w1, const void* w2)
-{
- const double a1 = ((struct neighbour_info*)w1)->angle;
- const double a2 = ((struct neighbour_info*)w2)->angle;
- return (a1 > a2) - (a1 < a2);
-}
-
-static FINLINE void
-add_side_to_stack
- (const struct senc2d_scene* scn,
- struct darray_side_id* stack,
- struct segside* segsides,
- const side_id_t side_id)
-{
- (void)scn;
- ASSERT(scn && segsides && stack
- && side_id < SIDE_MAX__ && side_id < 2 * scn->nusegs);
- ASSERT((darray_side_id_size_get(stack) > 128)
- || !find_side_in_list(segsides, stack, side_id, FLAG_WAITING_STACK));
- darray_side_id_push_back(stack, &side_id);
- segsides[side_id].list_id = FLAG_WAITING_STACK;
-}
-
-static side_id_t
-get_side_not_in_connex_component
- (const struct senc2d_scene* scn,
- const struct segside* segsides,
- side_id_t* first_side_not_in_component,
- const medium_id_t medium)
-{
- side_id_t i;
- const seg_id_t last_side
- = darray_side_range_cdata_get(&scn->media_use)[medium].last;
- ASSERT(scn && segsides && first_side_not_in_component);
- i = *first_side_not_in_component;
- while(i <= last_side
- && (segsides[i].medium != medium
- || segsides[i].list_id != FLAG_LIST_SIDE_LIST)) {
- ++i;
- }
-
- *first_side_not_in_component = i+1;
- if(i > last_side) return SIDE_NULL__;
- return i;
-}
-
-static FINLINE side_id_t
-get_side_from_stack
- (const struct segside* segsides,
- struct darray_side_id* stack)
-{
- side_id_t id;
- size_t sz;
- (void)segsides;
- ASSERT(segsides && stack);
- sz = darray_side_id_size_get(stack);
- ASSERT(sz);
- id = darray_side_id_cdata_get(stack)[sz - 1];
- ASSERT(segsides[id].list_id == FLAG_WAITING_STACK);
- darray_side_id_pop_back(stack);
- return id;
-}
-
-static void
-get_scn_indices(const unsigned iseg, unsigned ids[2], void* ctx) {
- int i;
- const struct senc2d_scene* scene = ctx;
- const struct segment_in* seg =
- darray_segment_in_cdata_get(&scene->segments_in) + iseg;
- FOR_EACH(i, 0, 2) {
- ASSERT(seg->vertice_id[i] < scene->nverts);
- ids[i] = (unsigned)seg->vertice_id[i]; /* Back to API type */
- }
-}
-
-static void
-get_scn_position(const unsigned ivert, float pos[2], void* ctx) {
- const struct senc2d_scene* scene = ctx;
- const union double2* pt =
- darray_position_cdata_get(&scene->vertices) + ivert;
- f2_set_d2(pos, pt->vec);
-}
-
-static int
-self_hit_filter
- (const struct s2d_hit* hit,
- const float ray_org[2],
- const float ray_dir[2],
- void* ray_data,
- void* filter_data)
-{
- const struct darray_segment_comp* segments_comp = filter_data;
- const component_id_t* origin_component = ray_data;
- const struct segment_comp* hit_seg_comp;
- enum side_id hit_side;
- component_id_t hit_component;
-
- (void) ray_org; (void) ray_dir;
- ASSERT(hit && segments_comp && origin_component);
- ASSERT(hit->prim.prim_id < darray_segment_comp_size_get(segments_comp));
- hit_seg_comp = darray_segment_comp_cdata_get(segments_comp)
- + hit->prim.prim_id;
- hit_side = (hit->normal[1] > 0) ? SIDE_FRONT : SIDE_BACK;
- hit_component = hit_seg_comp->component[hit_side];
-
- /* Not self hit or distance should be small */
- ASSERT(hit_component != *origin_component || hit->distance < 1e-6);
- return (hit_component == *origin_component);
-}
-
-static res_T
-extract_connex_components
- (struct senc2d_descriptor* desc,
- struct segside* segsides,
- struct darray_ptr_component_descriptor* connex_components,
- const struct darray_segment_tmp* segments_tmp_array,
- struct darray_segment_comp* segments_comp,
- struct s2d_scene_view** s2d_view)
-{
- res_T res = RES_OK;
- const struct senc2d_scene* scn;
- struct mem_allocator* alloc;
- static ATOMIC component_count = 0;
- static volatile int exit_for = 0;
- int64_t mm;
-#ifndef NDEBUG
- seg_id_t s_;
- component_id_t c;
-#endif
-
- ASSERT(segsides && desc && connex_components && segments_tmp_array);
- ASSERT(darray_ptr_component_descriptor_size_get(connex_components) == 0);
- alloc = descriptor_get_allocator(desc);
- scn = desc->scene;
-
-#ifndef NDEBUG
- #pragma omp single
- {
- FOR_EACH(s_, 0, scn->nusegs) {
- const struct segment_in* seg_in =
- darray_segment_in_cdata_get(&scn->segments_in) + s_;
- const struct side_range* media_use
- = darray_side_range_cdata_get(&scn->media_use);
- FOR_EACH(mm, 0, 2) {
- const side_id_t side = SEGIDxSIDE_2_SEGSIDE(s_, mm);
- const medium_id_t medium = seg_in->medium[mm];
- ASSERT(media_use[medium].first <= side && side <= media_use[medium].last);
- }
- }
- } /* Implicit barrier here */
-#endif
-
- /* #pragma omp parallel */
- {
- struct darray_side_id stack;
- darray_side_id_init(alloc, &stack);
-
- #pragma omp for schedule(dynamic) nowait
- for(mm = 0; mm < (int64_t)scn->nmeds; mm++) { /* Process all media */
- const medium_id_t m = (medium_id_t)mm;
- struct cc_descriptor* cc;
- /* Any not-already-used side is used as a starting point */
- side_id_t first_side_not_in_component;
-
- if(exit_for) continue;
- first_side_not_in_component
- = darray_side_range_cdata_get(&scn->media_use)[m].first;
- if(first_side_not_in_component == SIDE_NULL__)
- continue; /* Unused medium */
- ASSERT(first_side_not_in_component < 2 * scn->nusegs);
- ASSERT(darray_side_id_size_get(&stack) == 0);
- for(;;) { /* Process all components for this medium */
- const side_id_t start_side_id = get_side_not_in_connex_component(scn,
- segsides, &first_side_not_in_component, m);
- side_id_t crt_side_id = start_side_id;
- side_id_t last_side_id = start_side_id;
- ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->nusegs);
- if(start_side_id == SIDE_NULL__)
- break; /* start_side_id=SIDE_NULL__ => done! */
- ASSERT(segsides[start_side_id].list_id == FLAG_LIST_SIDE_LIST);
-
-#ifndef NDEBUG
- {
- seg_id_t tid = SEGSIDE_2_SEG(start_side_id);
- enum side_flag s = SEGSIDE_2_SIDE(start_side_id);
- medium_id_t side_med
- = darray_segment_in_data_get(&desc->scene->segments_in)[tid].medium[s];
- ASSERT(side_med == m);
- }
-#endif
-
- /* Create and init a new component */
- cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
- if(!cc) {
- res = RES_MEM_ERR;
- goto error1;
- }
- cc_descriptor_init(alloc, cc);
- ASSERT(m == segsides[start_side_id].medium);
- cc->cc_id = (component_id_t)(ATOMIC_INCR(&component_count) - 1);
- cc->medium = m;
- cc->side_range.first = start_side_id;
-
- for(;;) { /* Process all sides of this component */
- int i;
- enum side_flag crt_side_flag = SEGSIDE_2_SIDE(crt_side_id);
- struct segside* crt_side = segsides + crt_side_id;
- const seg_id_t crt_seg_id = SEGSIDE_2_SEG(crt_side_id);
- const struct segment_in* seg_in =
- darray_segment_in_cdata_get(&scn->segments_in) + crt_seg_id;
- struct segment_comp* seg_comp =
- darray_segment_comp_data_get(segments_comp) + crt_seg_id;
- const struct segment_tmp* const seg_tmp =
- darray_segment_tmp_cdata_get(segments_tmp_array) + crt_seg_id;
- const union double2* vertices =
- darray_position_cdata_get(&scn->vertices);
- ASSERT(crt_seg_id < scn->nusegs);
- ASSERT(segsides[crt_side_id].medium == m);
-
- /* Record Ymax information
- * Keep track of the appropriate vertex/side of the connex component
- * in order to cast a ray at the component grouping step of the
- * algorithm.
- * The most appropriate vertex is (the) one with the greater Y
- * coordinate.
- * If more than one vertex/side has the same Y, we want the side that
- * most faces Y (that is the one with the greater ny).
- * This is mandatory to select the correct side when both sides of a
- * segment are candidate. */
- if(cc->max_vrtx[1] <= seg_tmp->max_y) {
- /* Can either improve y or ny */
-
- if(cc->max_y_side_id == SEGSIDE_OPPOSITE(crt_side_id)) {
- /* Both sides are in cc and the opposite side is currently selected
- * Just keep the side with ny>0 */
- if(cc->max_y_ny < 0) {
- /* Change side! */
- cc->max_y_ny = -cc->max_y_ny;
- cc->max_y_side_id = crt_side_id;
- }
- } else {
- double edge[2], normal[2], norm, side_ny;
- int process = 0;
-
- d2_sub(edge, vertices[seg_in->vertice_id[1]].vec,
- vertices[seg_in->vertice_id[0]].vec);
- d2(normal, edge[1], -edge[0]);
- norm = d2_normalize(normal, normal);
- ASSERT(norm); (void) norm;
-
- /* Geometrical normal points toward the right */
- if(SEGSIDE_IS_FRONT(crt_side_id)) {
- side_ny = -normal[1];
- process = 1;
- } else {
- side_ny = normal[1];
- process = 1;
- }
-
- if(process) {
- int change = 0;
- if(cc->max_vrtx[1] < seg_tmp->max_y) {
- change = 1; /* Try first to improve y */
- } else if(cc->max_y_ny <= 0 && fabs(cc->max_y_ny) < fabs(side_ny)) {
- change = 1; /* If ny <= 0, the more negative the better */
- } else if(cc->max_y_ny > 0 && cc->max_y_ny < side_ny) {
- change = 1; /* If ny > 0, the more positive the better */
- }
-
- if(change) {
- cc->max_y_ny = side_ny;
- cc->max_y_side_id = crt_side_id;
- ASSERT(seg_tmp->max_y_vrtx_rank < 2);
- ASSERT(seg_in->vertice_id[seg_tmp->max_y_vrtx_rank] < scn->nverts);
- cc->max_y_vrtx_id = seg_in->vertice_id[seg_tmp->max_y_vrtx_rank];
- ASSERT(seg_tmp->max_y == vertices[cc->max_y_vrtx_id].pos.y);
- d2_set(cc->max_vrtx, vertices[cc->max_y_vrtx_id].vec);
- }
- }
- }
- }
-
- /* Record crt_side both as component and segment level */
- cc->side_count++;
- segsides[crt_side_id].list_id = FLAG_LIST_COMPONENT;
- ASSERT(seg_comp->component[crt_side_flag] == COMPONENT_NULL__);
- seg_comp->component[crt_side_flag] = cc->cc_id;
-#ifndef NDEBUG
- crt_side->member_of_cc = cc->cc_id;
-#endif
-
- /* Store neighbour sides in a waiting stack */
- FOR_EACH(i, 0, 2) {
- side_id_t neighbour_id = crt_side->facing_side_id[i];
- seg_id_t nbour_seg_id = SEGSIDE_2_SEG(neighbour_id);
- const struct segside* neighbour = segsides + neighbour_id;
- ASSERT(m == crt_side->medium);
- if(neighbour->medium != crt_side->medium) {
- /* Found medium discontinuity! Model topology is broken. */
- const struct segment_in* segments_in
- = darray_segment_in_cdata_get(&scn->segments_in);
- const union double2* positions
- = darray_position_cdata_get(&scn->vertices);
- log_err(scn->dev,
- "Medium mismatch found between neighbour segments %lu %s"
- " side and %u %s side.\n",
- (unsigned long) segments_in[crt_seg_id].global_id,
- SEGSIDE_IS_FRONT(crt_side_id) ? "front" : "back",
- segments_in[nbour_seg_id].global_id,
- SEGSIDE_IS_FRONT(neighbour_id) ? "front" : "back");
- log_err(scn->dev,
- "Segment %lu:\n (%g %g) (%g %g))\n",
- (unsigned long) segments_in[crt_seg_id].global_id,
- SPLIT2(positions[segments_in[crt_seg_id].vertice_id[0]].vec),
- SPLIT2(positions[segments_in[crt_seg_id].vertice_id[1]].vec));
- log_err(scn->dev,
- "Segment %lu:\n (%g %g) (%g %g)\n",
- (unsigned long) segments_in[nbour_seg_id].global_id,
- SPLIT2(positions[segments_in[nbour_seg_id].vertice_id[0]].vec),
- SPLIT2(positions[segments_in[nbour_seg_id].vertice_id[1]].vec));
- log_err(desc->scene->dev, "Media: %lu VS %lu\n",
- (unsigned long)neighbour->medium, (unsigned long)crt_side->medium);
- res = RES_BAD_ARG;
- goto error1;
- }
- if(neighbour->list_id == FLAG_LIST_COMPONENT) {
- /* Already processed */
-#ifndef NDEBUG
- ASSERT(neighbour->member_of_cc == cc->cc_id);
-#endif
- continue;
- }
- if(neighbour->list_id == FLAG_WAITING_STACK) {
- continue; /* Already processed */
- }
- add_side_to_stack(scn, &stack, segsides, neighbour_id);
- }
- if(darray_side_id_size_get(&stack) == 0)
- break; /* Empty stack => connex component is done! */
- crt_side_id = get_side_from_stack(segsides, &stack);
- last_side_id = MMAX(last_side_id, crt_side_id);
- }
- /* Keep track of this new connex component */
- cc->side_range.last = last_side_id;
- /* Need to synchronize connex_components growth as this global structure
- * is accessed by multipe threads */
- #pragma omp critical
- {
- struct cc_descriptor** components;
- size_t sz = darray_ptr_component_descriptor_size_get(connex_components);
- if(sz <= cc->cc_id) {
- res_T tmp_res = darray_ptr_component_descriptor_resize(connex_components,
- 1 + cc->cc_id);
- if(tmp_res != RES_OK) res = tmp_res;
- }
- if(res == RES_OK) {
- /* Don't set the pointer before resize as this can lead to move data */
- components =
- darray_ptr_component_descriptor_data_get(connex_components);
- ASSERT(components[cc->cc_id] == NULL);
- components[cc->cc_id] = cc;
- }
- }
- OK2(res, error1);
- }
- continue;
- error1:
- /* Cannot goto out of openmp block */
- exit_for = 1;
- continue;
- }
- /* No barrier here (nowait clause).
- * The first thread executes the single block */
- darray_side_id_release(&stack);
- #pragma omp single nowait
- if(res == RES_OK) {
- struct s2d_device* s2d = NULL;
- struct s2d_scene* s2d_scn = NULL;
- struct s2d_shape* s2d_shp = NULL;
- struct s2d_vertex_data attribs;
-
- attribs.type = S2D_FLOAT2;
- attribs.usage = S2D_POSITION;
- attribs.get = get_scn_position;
-
- /* Put geometry in a 2D view */
- OK(s2d_device_create(desc->scene->dev->logger, alloc, 0, &s2d));
- OK(s2d_scene_create(s2d, &s2d_scn));
- OK(s2d_shape_create_line_segments(s2d, &s2d_shp));
-
- /* Back to API type for ntris and nverts */
- ASSERT(desc->scene->nusegs < UINT_MAX);
- ASSERT(desc->scene->nuverts < UINT_MAX);
- OK(s2d_line_segments_setup_indexed_vertices(s2d_shp, (unsigned)desc->scene->nusegs,
- get_scn_indices, (unsigned)desc->scene->nuverts, &attribs, 1, desc->scene));
- s2d_line_segments_set_hit_filter_function(s2d_shp, self_hit_filter, segments_comp);
- OK(s2d_scene_attach_shape(s2d_scn, s2d_shp));
- OK(s2d_scene_view_create(s2d_scn, S2D_TRACE, s2d_view));
- error:
- if(s2d) S2D(device_ref_put(s2d));
- if(s2d_scn) S2D(scene_ref_put(s2d_scn));
- if(s2d_shp) S2D(shape_ref_put(s2d_shp));
- }
- }/* No barrier here */
- OK2(res, error_);
-
-#ifndef NDEBUG
- #pragma omp barrier
- ASSERT(component_count ==
- (int)darray_ptr_component_descriptor_size_get(connex_components));
- FOR_EACH(s_, 0, scn->nusegs) {
- struct segment_comp* seg_comp =
- darray_segment_comp_data_get(segments_comp) + s_;
- ASSERT(seg_comp->component[SIDE_FRONT] != COMPONENT_NULL__);
- ASSERT(seg_comp->component[SIDE_BACK] != COMPONENT_NULL__);
- }
- FOR_EACH(c, 0, component_count) {
- struct cc_descriptor** components =
- darray_ptr_component_descriptor_data_get(connex_components);
- ASSERT(components[c] != NULL &&
- components[c]->cc_id == c);
- }
- ASSERT(desc->segment_count
- == darray_segment_comp_size_get(segments_comp));
-#endif
-
-exit:
- /* segments_enc is still unused: no size to assert */
- return res;
-error_:
- goto exit;
-}
-
-static res_T
-group_connex_components
- (struct senc2d_descriptor* desc,
- struct segside* segsides,
- struct darray_segment_comp* segments_comp,
- struct darray_ptr_component_descriptor* connex_components,
- struct s2d_scene_view* s2d_view)
-{
- res_T res = RES_OK;
- struct cc_descriptor** descriptors;
- size_t tmp;
- component_id_t cc_count;
- int64_t ccc;
- static volatile int exit_for = 0;
- static ATOMIC next_enclosure_id = 1;
- struct cc_descriptor* infinity_first_cc = NULL;
- (void)segsides;
- ASSERT(desc && segsides && segments_comp && connex_components);
- ASSERT(desc->enclosures_count == 1);
-
- descriptors = darray_ptr_component_descriptor_data_get(connex_components);
- tmp = darray_ptr_component_descriptor_size_get(connex_components);
- ASSERT(tmp <= COMPONENT_MAX__);
- cc_count = (component_id_t)tmp;
-
- /* Cast rays to find links between connex components */
- #pragma omp /* parallel */ for
- for(ccc = 0; ccc < (int64_t)cc_count; ccc++) {
- component_id_t c = (component_id_t)ccc;
- struct s2d_hit hit = S2D_HIT_NULL;
- float origin[2];
- const float dir[2] = { 0, 1 };
- const float range[2] = { 0, FLT_MAX };
- struct cc_descriptor* const cc = descriptors[c];
- const struct segment_comp* origin_seg =
- darray_segment_comp_cdata_get(segments_comp) + cc->max_y_vrtx_id;
- component_id_t self_hit_component
- = origin_seg->component[1 - SEGSIDE_2_SIDE(cc->max_y_side_id)];
-
- if(exit_for) continue;
- ASSERT(cc->cc_id == c);
- ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
-
- if(cc->max_y_ny < 0) {
- int64_t id;
- /* Don't need to cast a ray */
- cc->cc_group_root = cc->cc_id; /* New group with self as root */
- id = ATOMIC_INCR(&next_enclosure_id) - 1;
- ASSERT(id < ENCLOSURE_MAX__);
- cc->enclosure_id = (enclosure_id_t)id;
- continue;
- }
-
- ASSERT(cc->max_y_ny != 0
- /* The only situation with ny==0 we can think of is this one: */
- || (segsides[cc->max_y_side_id].medium
- == segsides[SEGSIDE_OPPOSITE(cc->max_y_side_id)].medium
- && (segsides[cc->max_y_side_id].facing_side_id[0]
- == SEGSIDE_OPPOSITE(cc->max_y_side_id)
- || segsides[cc->max_y_side_id].facing_side_id[1]
- == SEGSIDE_OPPOSITE(cc->max_y_side_id))));
- f2_set_d2(origin, cc->max_vrtx);
- /* Self-hit data: self hit if hit this component "on the other side" */
- OK2(s2d_scene_view_trace_ray(s2d_view, origin, dir, range,
- &self_hit_component, &hit), error_);
- /* If no hit, the component is facing an infinite medium */
- if(S2D_HIT_NONE(&hit)) {
- cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
- cc->enclosure_id = 0;
- /* Keep track of the first component facing infinity */
- ATOMIC_CAS_PTR(&infinity_first_cc, cc, NULL);
- if(infinity_first_cc->medium != cc->medium) {
- const side_id_t infinity_first_side = infinity_first_cc->max_y_side_id;
- const medium_id_t infinity_medium = infinity_first_cc->medium;
- /* Medium mismatch! Model topology is broken. */
- const seg_id_t t1 = SEGSIDE_2_SEG(infinity_first_side);
- const seg_id_t t2 = SEGSIDE_2_SEG(cc->max_y_side_id);
- const struct segment_in* segments_in
- = darray_segment_in_cdata_get(&desc->scene->segments_in);
- const union double2* positions
- = darray_position_cdata_get(&desc->scene->vertices);
- log_err(desc->scene->dev,
- "Medium mismatch found between segment %lu %s side and segment"
- " %lu %s side, both facing infinity.\n",
- (unsigned long)segments_in[t1].global_id,
- SEGSIDE_IS_FRONT(infinity_first_side) ? "front" : "back",
- (unsigned long) segments_in[t2].global_id,
- SEGSIDE_IS_FRONT(cc->max_y_side_id) ? "front" : "back");
- log_err(desc->scene->dev,
- "Segment %lu:\n (%g %g) (%g %g)\n",
- (unsigned long)segments_in[t1].global_id,
- SPLIT2(positions[segments_in[t1].vertice_id[0]].vec),
- SPLIT2(positions[segments_in[t1].vertice_id[1]].vec));
- log_err(desc->scene->dev,
- "Segment %lu:\n (%g %g) (%g %g)\n",
- (unsigned long)segments_in[t2].global_id,
- SPLIT2(positions[segments_in[t2].vertice_id[0]].vec),
- SPLIT2(positions[segments_in[t2].vertice_id[1]].vec));
- log_err(desc->scene->dev, "Media: %lu VS %lu\n",
- (unsigned long)infinity_medium, (unsigned long)cc->medium);
- res = RES_BAD_ARG;
- goto error_;
- }
- /* Same medium as previous members of the group: OK */
- continue;
- } else {
- /* If hit, group this component */
- const seg_id_t hit_seg_id = (seg_id_t)hit.prim.prim_id;
- const struct segment_in* hit_seg_in =
- darray_segment_in_cdata_get(&desc->scene->segments_in) + hit_seg_id;
- const struct segment_comp* hit_seg_comp =
- darray_segment_comp_cdata_get(segments_comp) + hit_seg_id;
- enum side_id hit_side = (hit.normal[1] > 0) ? SIDE_FRONT : SIDE_BACK;
- const side_id_t hit_side_id = SEGIDxSIDE_2_SEGSIDE(hit_seg_id, hit_side);
-
- ASSERT(hit_seg_id < desc->scene->nusegs);
-
- /* Not really the root until following links */
- cc->cc_group_root = hit_seg_comp->component[hit_side];
-#ifndef NDEBUG
- {
- const struct cc_descriptor* hit_desc;
- ASSERT(cc->cc_group_root
- < darray_ptr_component_descriptor_size_get(connex_components));
- hit_desc = *(darray_ptr_component_descriptor_cdata_get(connex_components)
- + cc->cc_group_root);
- ASSERT(hit_desc->medium == hit_seg_in->medium[hit_side]);
- }
-#endif
- if(hit_seg_in->medium[hit_side] != cc->medium) {
- /* Medium mismatch! Model topology is broken. */
- const seg_id_t t1 = SEGSIDE_2_SEG(hit_side_id);
- const seg_id_t t2 = SEGSIDE_2_SEG(cc->max_y_side_id);
- const struct segment_in* segments_in
- = darray_segment_in_cdata_get(&desc->scene->segments_in);
- const union double2* positions
- = darray_position_cdata_get(&desc->scene->vertices);
- log_err(desc->scene->dev,
- "Medium mismatch found between segment %lu %s side and segment"
- " %lu %s side facing each other.\n",
- (unsigned long)segments_in[t1].global_id,
- SEGSIDE_IS_FRONT(hit_side) ? "front" : "back",
- (unsigned long)segments_in[t2].global_id,
- SEGSIDE_IS_FRONT(cc->max_y_side_id) ? "front" : "back");
- log_err(desc->scene->dev,
- "Segment %lu:\n (%g %g) (%g %g)\n",
- (unsigned long)segments_in[t1].global_id,
- SPLIT2(positions[segments_in[t1].vertice_id[0]].vec),
- SPLIT2(positions[segments_in[t1].vertice_id[1]].vec));
- log_err(desc->scene->dev,
- "Segment %lu:\n (%g %g) (%g %g)\n",
- (unsigned long)segments_in[t2].global_id,
- SPLIT2(positions[segments_in[t2].vertice_id[0]].vec),
- SPLIT2(positions[segments_in[t2].vertice_id[1]].vec));
- log_err(desc->scene->dev, "Media: %lu VS %lu\n",
- (unsigned long)hit_seg_in->medium[hit_side],
- (unsigned long)cc->medium);
-
- res = RES_BAD_ARG;
- goto error_;
- }
- }
- continue;
- error_:
- /* Cannot goto out of openmp block */
- exit_for = 1;
- continue;
- } /* Implicit barrier here */
- ASSERT(next_enclosure_id < ENCLOSURE_MAX__);
- OK(res);
-
- /* Post-process links to group connex components */
- #pragma omp single
- {
- desc->enclosures_count = (enclosure_id_t)next_enclosure_id;
- res = darray_enclosure_resize(&desc->enclosures, desc->enclosures_count);
- if(res == RES_OK) {
- FOR_EACH(ccc, 0, cc_count) {
- component_id_t c = (component_id_t) ccc;
- struct cc_descriptor* const cc = descriptors[c];
- const struct cc_descriptor* other_desc = cc;
- struct enclosure_data* enclosures
- = darray_enclosure_data_get(&desc->enclosures);
- component_id_t fst;
-
- while(other_desc->enclosure_id == CC_GROUP_ID_NONE) {
- other_desc = *(darray_ptr_component_descriptor_cdata_get(connex_components)
- + other_desc->cc_group_root);
- }
- ASSERT(other_desc->cc_group_root != CC_GROUP_ROOT_NONE);
- ASSERT(other_desc->enclosure_id != CC_GROUP_ID_NONE);
- ASSERT(cc->medium == other_desc->medium);
- cc->cc_group_root = other_desc->cc_group_root;
- cc->enclosure_id = other_desc->enclosure_id;
- ++enclosures[cc->enclosure_id].cc_count;
- /* Linked list of componnents */
- fst = enclosures[cc->enclosure_id].first_component;
- cc->enclosure_next_component = fst;
- enclosures[cc->enclosure_id].first_component = cc->cc_id;
- enclosures[cc->enclosure_id].side_range.first
- = MMIN(enclosures[cc->enclosure_id].side_range.first, cc->side_range.first);
- enclosures[cc->enclosure_id].side_range.last
- = MMAX(enclosures[cc->enclosure_id].side_range.last, cc->side_range.last);
- enclosures[cc->enclosure_id].side_count += cc->side_count;
- }
- }
- } /* Implicit barrier here */
- OK(res);
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
-collect_and_link_neighbours
- (struct senc2d_scene* scn,
- struct segside* segsides,
- struct darray_segment_tmp* segments_tmp_array,
- struct darray_neighbourhood* neighbourhood_by_vertex)
-{
- res_T res = RES_OK;
- const struct segment_in *segments_in;
- struct segment_tmp *segments_tmp;
- const union double2* vertices;
- static volatile int exit_for = 0;
-
- ASSERT(scn && segsides && segments_tmp_array);
- ASSERT((size_t)scn->nuverts + (size_t)scn->nusegs + 2 <= EDGE_MAX__);
-
- segments_in = darray_segment_in_cdata_get(&scn->segments_in);
- segments_tmp = darray_segment_tmp_data_get(segments_tmp_array);
- vertices = darray_position_cdata_get(&scn->vertices);
-
- ASSERT(scn->nusegs == darray_segment_tmp_size_get(segments_tmp_array));
-
- /* Resize / Push operations on neighbourhood_by_vertex are valid in the
- * openmp block because each neighbourhood is processes by an unique thread */
- /* #pragma omp parallel */
- {
- const int thread_count = omp_get_num_threads();
- const int rank = omp_get_thread_num();
- /* Array to keep neighbourhood of vertices
- * Resize/Push operations on neighbourhood_by_vertex are valid in the
- * openmp block because it is thread local data */
- vrtx_id_t v;
- seg_id_t s;
- /* Loop on segments to collect edges' neighbours.
- * All threads considering all the vertices and processing some */
- FOR_EACH(s, 0, scn->nusegs) {
- unsigned char vv;
- FOR_EACH(vv, 0, 2) {
- struct darray_neighbour* neighbourhood;
- struct neighbour_info* info;
- const vrtx_id_t vertex = segments_in[s].vertice_id[vv];
- size_t sz;
- ASSERT(vertex < scn->nuverts);
- if(exit_for) continue;
- /* Process only "my" vertices! */
- if((int64_t)vertex % thread_count != rank) continue;
- /* Find neighbourhood */
- ASSERT(vertex < darray_neighbourhood_size_get(neighbourhood_by_vertex));
- neighbourhood =
- darray_neighbourhood_data_get(neighbourhood_by_vertex) + vertex;
- sz = darray_neighbour_size_get(neighbourhood);
- /* Make room for this neighbour */
- if(darray_neighbour_capacity(neighbourhood) == sz) {
- /* 2 seems to be a good guess for initial capacity */
- size_t new_sz = sz ? sz + 1 : 2;
- OK(darray_neighbour_reserve(neighbourhood, new_sz));
- }
- OK(darray_neighbour_resize(neighbourhood, 1 + sz));
- /* Add neighbour info to vertex's neighbour list */
- info = darray_neighbour_data_get(neighbourhood) + sz;
- info->seg_id = s;
- info->common_vertex_rank = vv;
- }
- } /* No barrier here. */
-
- /* For each of "my" vertices sort segments sides by rotation angle
- * and connect neighbours.
- * All threads considering all the vertices and processing some */
- FOR_EACH(v, 0, scn->nuverts) {
- const vrtx_id_t common_vrtx = v;
- vrtx_id_t other_vrtx;
- struct darray_neighbour* neighbourhood;
- side_id_t i, neighbour_count;
- size_t sz;
- /* Process only "my" vertices! */
- if((int64_t)v % thread_count != rank) continue;
- neighbourhood
- = darray_neighbourhood_data_get(neighbourhood_by_vertex) + v;
- sz = darray_neighbour_size_get(neighbourhood);
- /* sz can be 0 as a vertex can be unused */
- if(!sz) continue;
- ASSERT(sz <= SIDE_MAX__);
- neighbour_count = (side_id_t)sz;
- FOR_EACH(i, 0, neighbour_count) {
- double max_y, disp[2];
- unsigned char max_y_vrank;
- struct neighbour_info* neighbour_info
- = darray_neighbour_data_get(neighbourhood) + i;
- const struct segment_in* seg_in = segments_in + neighbour_info->seg_id;
- struct segment_tmp* neighbour = segments_tmp + neighbour_info->seg_id;
- other_vrtx =
- seg_in->vertice_id[(neighbour_info->common_vertex_rank + 1) % 2];
- if(vertices[other_vrtx].pos.y > vertices[common_vrtx].pos.y) {
- max_y = vertices[other_vrtx].pos.y;
- max_y_vrank = 1 - neighbour_info->common_vertex_rank;
- } else {
- max_y = vertices[common_vrtx].pos.y;
- max_y_vrank = neighbour_info->common_vertex_rank;
- }
- ASSERT(neighbour->max_y <= max_y);
- neighbour->max_y = max_y;
- neighbour->max_y_vrtx_rank = max_y_vrank;
- /* Compute rotation angle around common vertex (in world system) */
- d2_sub(disp, vertices[other_vrtx].vec, vertices[common_vrtx].vec);
- ASSERT(disp[0] || disp[1]);
- neighbour_info->angle = atan2(disp[1], disp[0]);
- if(neighbour_info->angle < 0) neighbour_info->angle += 2 * PI;
- /* Due to catastrophic cancelation, -eps+2pi translates to 2pi */
- ASSERT(0 <= neighbour_info->angle && neighbour_info->angle <= 2 * PI);
- }
- /* Sort segments by rotation angle */
- qsort(darray_neighbour_data_get(neighbourhood), neighbour_count,
- sizeof(struct neighbour_info), neighbour_cmp);
- /* Link sides.
- * Create cycles of sides by neighbourhood around common vertex. */
- FOR_EACH(i, 0, neighbour_count) {
- /* Neighbourhood info for current pair of segments */
- const struct neighbour_info* current
- = darray_neighbour_cdata_get(neighbourhood) + i;
- const struct neighbour_info* ccw_neighbour
- = darray_neighbour_cdata_get(neighbourhood) + (i+1) % neighbour_count;
- /* Rank of the end of interest in segments */
- const unsigned char crt_end = current->common_vertex_rank;
- const unsigned char ccw_end = ccw_neighbour->common_vertex_rank;
- /* User id of current segments */
- const seg_id_t crt_id = current->seg_id;
- const seg_id_t ccw_id = ccw_neighbour->seg_id;
- /* Facing sides of segments */
- const enum side_id crt_side = crt_end ? SIDE_BACK : SIDE_FRONT;
- const enum side_id ccw_side = ccw_end ? SIDE_FRONT : SIDE_BACK;
- /* Index of sides in segsides */
- const side_id_t crt_side_idx = SEGIDxSIDE_2_SEGSIDE(crt_id, crt_side);
- const side_id_t ccw_side_idx = SEGIDxSIDE_2_SEGSIDE(ccw_id, ccw_side);
- /* Side ptrs */
- struct segside* const p_crt_side = segsides + crt_side_idx;
- struct segside* const p_ccw_side = segsides + ccw_side_idx;
- /* Link sides */
- p_crt_side->facing_side_id[crt_end] = ccw_side_idx;
- p_ccw_side->facing_side_id[ccw_end] = crt_side_idx;
- /* Record media */
- p_crt_side->medium = segments_in[crt_id].medium[crt_side];
- p_ccw_side->medium = segments_in[ccw_id].medium[ccw_side];
- ASSERT(p_crt_side->medium < scn->nmeds);
- ASSERT(p_ccw_side->medium < scn->nmeds);
- p_crt_side->list_id = FLAG_LIST_SIDE_LIST;
- p_ccw_side->list_id = FLAG_LIST_SIDE_LIST;
- }
- } /* No barrier here. */
- /* jump error block */
- goto after_error;
-error:
- /* Cannot goto out of openmp block */
- exit_for = 1;
-after_error:
- ;
- }
- return res;
-}
-
-static res_T
-build_result
- (struct senc2d_descriptor* desc,
- const struct darray_ptr_component_descriptor* connex_components,
- const struct darray_segment_comp* segments_comp_array)
-{
- res_T res = RES_OK;
- struct mem_allocator* alloc;
- struct cc_descriptor* const* cc_descriptors;
- struct enclosure_data* enclosures;
- const struct segment_in* segments_in;
- struct segment_enc* segments_enc;
- const struct segment_comp* segments_comp;
- static volatile int exit_for = 0;
-
- ASSERT(desc && connex_components && segments_comp_array);
-
- alloc = descriptor_get_allocator(desc);
- ASSERT(darray_ptr_component_descriptor_size_get(connex_components) < COMPONENT_MAX__);
- cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components);
- enclosures = darray_enclosure_data_get(&desc->enclosures);
- segments_in = darray_segment_in_cdata_get(&desc->scene->segments_in);
- segments_comp = darray_segment_comp_cdata_get(segments_comp_array);
- #pragma omp single
- {
- res = darray_segment_enc_resize(&desc->segments_enc, desc->scene->nusegs);
- }/* Implicit barrier here. */
- OK2(res, error_);
- segments_enc = darray_segment_enc_data_get(&desc->segments_enc);
-
- /* #pragma omp parallel */
- {
- struct htable_vrtx_id vtable;
- int64_t sg;
- int64_t ee;
-
- /* Build global enclosure information */
- #pragma omp for
- for(sg = 0; sg < (int64_t) desc->scene->nusegs; sg++) {
- seg_id_t s = (seg_id_t) sg;
- const component_id_t cf_id = segments_comp[s].component[SIDE_FRONT];
- const component_id_t cb_id = segments_comp[s].component[SIDE_BACK];
- const struct cc_descriptor* cf = cc_descriptors[cf_id];
- const struct cc_descriptor* cb = cc_descriptors[cb_id];
- const enclosure_id_t ef_id = cf->enclosure_id;
- const enclosure_id_t eb_id = cb->enclosure_id;
- ASSERT(segments_enc[s].enclosure[SIDE_FRONT] == ENCLOSURE_NULL__);
- segments_enc[s].enclosure[SIDE_FRONT] = ef_id;
- ASSERT(segments_enc[s].enclosure[SIDE_BACK] == ENCLOSURE_NULL__);
- segments_enc[s].enclosure[SIDE_BACK] = eb_id;
- }
- /* Implicit barrier here */
-
- /* Resize/push operations on enclosure's fields are valid in the
- * openmp block as a given enclosure is processed by a single thread */
- htable_vrtx_id_init(alloc, &vtable);
-
- ASSERT(desc->enclosures_count <= ENCLOSURE_MAX__);
- #pragma omp for schedule(dynamic) nowait
- for(ee = 0; ee < (int64_t)desc->enclosures_count; ee++) {
- const enclosure_id_t e = (enclosure_id_t)ee;
- struct enclosure_data* enc = enclosures + e;
- const struct cc_descriptor* current = cc_descriptors[enc->first_component];
- seg_id_t fst_idx = 0;
- seg_id_t sgd_idx = enc->side_count;
- seg_id_t s;
- ASSERT(enc->first_component
- < darray_ptr_component_descriptor_size_get(connex_components));
- ASSERT(current->cc_id == enc->first_component);
-
- if(exit_for) continue;
- ASSERT(e <= UINT_MAX);
- enc->header.enclosure_id = (unsigned)e; /* Back to API type */
- ASSERT(current->enclosure_id == enc->header.enclosure_id);
- enc->header.is_infinite = (e == 0);
- enc->header.enclosed_medium
- = (unsigned)current->medium; /* Back to API type */
- ASSERT(enc->header.enclosed_medium < desc->scene->nmeds);
-
- /* Build side and vertex lists. */
- OK(darray_segment_in_resize(&enc->sides, enc->side_count));
- /* Size is just a int */
- OK(darray_vrtx_id_reserve(&enc->vertices, enc->side_count + 1));
- /* New vertex numbering scheme local to the enclosure */
- htable_vrtx_id_clear(&vtable);
- ASSERT(desc->scene->nusegs
- == darray_segment_in_size_get(&desc->scene->segments_in));
- /* Put at the end the back-faces of segments that also have their
- * front-face in the list. */
- for(s = SEGSIDE_2_SEG(enc->side_range.first);
- s <= SEGSIDE_2_SEG(enc->side_range.last);
- s++)
- {
- const struct segment_in* seg_in = segments_in + s;
- struct segment_in* seg;
- unsigned vertice_id[2];
- int i;
- if(segments_enc[s].enclosure[SIDE_FRONT] != e
- && segments_enc[s].enclosure[SIDE_BACK] != e)
- continue;
- ++enc->header.unique_segment_count;
-
- FOR_EACH(i, 0, 2) {
- vrtx_id_t* id = htable_vrtx_id_find(&vtable, seg_in->vertice_id + i);
- if(id) {
- vertice_id[i] = *id; /* Known vertex */
- } else {
- /* Create new association */
- size_t tmp = htable_vrtx_id_size_get(&vtable);
- ASSERT(tmp == darray_vrtx_id_size_get(&enc->vertices));
- ASSERT(tmp < VRTX_MAX__);
- vertice_id[i] = (vrtx_id_t)tmp;
- OK(htable_vrtx_id_set(&vtable, seg_in->vertice_id + i,
- vertice_id + i));
- OK(darray_vrtx_id_push_back(&enc->vertices, seg_in->vertice_id + i));
- ++enc->header.vertices_count;
- }
- }
- ASSERT(segments_enc[s].enclosure[SIDE_FRONT] == e
- || segments_enc[s].enclosure[SIDE_BACK] == e);
- if(segments_enc[s].enclosure[SIDE_FRONT] == e) {
- ++enc->header.segment_count;
- seg = darray_segment_in_data_get(&enc->sides) + fst_idx++;
-
- FOR_EACH(i, 0, 2) seg->medium[i] = seg_in->medium[i];
- seg->global_id = seg_in->global_id;
- FOR_EACH(i, 0, 2) seg->vertice_id[i] = vertice_id[i];
- }
- if(segments_enc[s].enclosure[SIDE_BACK] == e) {
- ++enc->header.segment_count;
- seg = darray_segment_in_data_get(&enc->sides) +
- ((segments_enc[s].enclosure[SIDE_FRONT] == e) ? --sgd_idx : fst_idx++);
-
- FOR_EACH(i, 0, 2) seg->medium[i] = seg_in->medium[1 - i];
- seg->global_id = seg_in->global_id;
- FOR_EACH(i, 0, 2) seg->vertice_id[i] = vertice_id[1 - i];
- }
- if(fst_idx == sgd_idx) break;
- }
- continue;
- error:
- /* Cannot goto out of openmp block */
- exit_for = 1;
- } /* No barrier here */
- htable_vrtx_id_release(&vtable);
- }
- OK2(res, error_);
-
-exit:
- return res;
-error_:
- goto exit;
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_desc)
-{
- res_T res = RES_OK;
- struct senc2d_descriptor* desc = NULL;
- /* By segment tmp data */
- struct darray_segment_tmp segments_tmp;
- char segments_tmp_initialized = 0;
- /* Array of connex components.
- * They are refered to by arrays of ids. */
- struct darray_ptr_component_descriptor connex_components;
- char connex_components_initialized = 0;
- /* Store by-segment components */
- struct darray_segment_comp segments_comp;
- char segments_comp_initialized = 0;
- /* Array of vertices (segment ends). */
- struct segside* segsides = NULL;
- struct s2d_scene_view* s2d_view = NULL;
- /* Array to keep neighbourhood of vertices */
- struct darray_neighbourhood neighbourhood_by_vertex;
- char neighbourhood_by_vertex_initialized = 0;
-
- if(!scn || !out_desc) return RES_BAD_ARG;
-
- desc = descriptor_create(scn);
- if(!desc) {
- res = RES_MEM_ERR;
- goto error;
- }
-
- if(!scn->nusegs) goto exit;
-
- darray_segment_tmp_init(scn->dev->allocator, &segments_tmp);
- segments_tmp_initialized = 1;
-
- OK(darray_segment_tmp_resize(&segments_tmp, scn->nusegs));
- segsides
- = MEM_CALLOC(scn->dev->allocator, 2 * scn->nusegs, sizeof(struct segside));
- if(!segsides) {
- res = RES_MEM_ERR;
- goto error;
- }
-
- /* We create a neighbourhood for every single unique vertex,
- * regardless the fact it is used by a segment */
- darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_vertex);
- neighbourhood_by_vertex_initialized = 1;
- OK(darray_neighbourhood_resize(&neighbourhood_by_vertex, scn->nuverts));
-
- #pragma omp parallel
- {
- res_T tmpres = RES_OK;
-
- /* Step 1: build neighbourhoods */
- tmpres = collect_and_link_neighbours(scn, segsides, &segments_tmp,
- &neighbourhood_by_vertex);
- /* No barrier at the end of step 1 */
-
- if(tmpres != RES_OK) {
- res = tmpres;
- #pragma omp single nowait
- {
- log_err(scn->dev,
- "%s: could not build neighbourhoods from scene.\n", FUNC_NAME);
- } /* No barrier here */
- }
- OK2(res, error_);
-
- /* The first thread here allocates some data */
- #pragma omp single
- {
- darray_ptr_component_descriptor_init(scn->dev->allocator,
- &connex_components);
- connex_components_initialized = 1;
- /* Just a hint; to limit contention */
- tmpres = darray_ptr_component_descriptor_reserve(&connex_components,
- 2 * scn->nmeds);
- if(tmpres != RES_OK) res = tmpres;
- darray_segment_comp_init(scn->dev->allocator, &segments_comp);
- segments_comp_initialized = 1;
- tmpres = darray_segment_comp_resize(&segments_comp, scn->nusegs);
- if(tmpres != RES_OK) res = tmpres;
- } /* Implicit barrier here */
- OK2(res, error_);
-
- /* One thread releases some data, the others go to step 2 */
- #pragma omp single nowait
- {
- darray_neighbourhood_release(&neighbourhood_by_vertex);
- neighbourhood_by_vertex_initialized = 0;
- } /* No implicit barrier here */
-
-
- /* Step 2: extract segment connex components */
- tmpres = extract_connex_components(desc, segsides, &connex_components,
- &segments_tmp, &segments_comp, &s2d_view);
- /* No barrier at the end of step 2 */
-
- if(tmpres != RES_OK) {
- res = tmpres;
- #pragma omp single nowait
- {
- log_err(scn->dev,
- "%s: could not extract connex components from scene.\n", FUNC_NAME);
- } /* No implicit barrier here */
- }
- OK2(res, error_);
-
- #pragma omp barrier
- /* One thread releases some data, the others go to step 3 */
- #pragma omp single nowait
- {
- darray_segment_tmp_release(&segments_tmp);
- segments_tmp_initialized = 0;
- } /* No implicit barrier here */
-
- /* Step 3: group components */
- tmpres = group_connex_components(desc, segsides, &segments_comp,
- &connex_components, s2d_view);
- /* Barrier at the end of step 3 */
-
- /* The first thread here releases some data */
- #pragma omp single nowait
- {
- if(s2d_view) S2D(scene_view_ref_put(s2d_view));
- s2d_view = NULL;
- } /* No implicit barrier here */
-
- if(res != RES_OK) {
- res = tmpres;
- #pragma omp single nowait
- {
- log_err(scn->dev,
- "%s: could not group connex components from scene.\n", FUNC_NAME);
- } /* No implicit barrier here */
- }
- OK2(res, error_);
-
- /* Build result. */
- tmpres = build_result(desc, &connex_components, &segments_comp);
- /* No barrier at the end of build step */
-
- if(tmpres != RES_OK) {
- res = tmpres;
- #pragma omp single nowait
- {
- log_err(scn->dev, "%s: could not build result.\n", FUNC_NAME);
- } /* No implicit barrier here */
- }
- OK2(res, error_);
-
- #pragma omp barrier
- /* Some threads release data */
- #pragma omp sections nowait
- {
- #pragma omp section
- {
- darray_segment_comp_release(&segments_comp);
- segments_comp_initialized = 0;
- }
- #pragma omp section
- {
- if(connex_components_initialized) {
- size_t c, cc_count =
- darray_ptr_component_descriptor_size_get(&connex_components);
- struct cc_descriptor** components =
- darray_ptr_component_descriptor_data_get(&connex_components);
- FOR_EACH(c, 0, cc_count) {
- ptr_component_descriptor_release(scn->dev->allocator, components + c);
- }
- darray_ptr_component_descriptor_release(&connex_components);
- connex_components_initialized = 0;
- }
- }
- } /* No implicit barrier here */
-error_:
- ;
- } /* Implicit barrier here */
-
-if(res != RES_OK) goto error;
-exit:
- if(connex_components_initialized) {
- size_t c, cc_count =
- darray_ptr_component_descriptor_size_get(&connex_components);
- struct cc_descriptor** components =
- darray_ptr_component_descriptor_data_get(&connex_components);
- FOR_EACH(c, 0, cc_count) {
- ptr_component_descriptor_release(scn->dev->allocator, components + c);
- }
- darray_ptr_component_descriptor_release(&connex_components);
- }
- if(s2d_view) S2D(scene_view_ref_put(s2d_view));
- if(neighbourhood_by_vertex_initialized)
- darray_neighbourhood_release(&neighbourhood_by_vertex);
- if(segments_tmp_initialized) darray_segment_tmp_release(&segments_tmp);
- if(segments_comp_initialized) darray_segment_comp_release(&segments_comp);
- if(segsides) MEM_RM(scn->dev->allocator, segsides);
- if(desc) *out_desc = desc;
-
- return res;
-error:
- if(desc) SENC2D(descriptor_ref_put(desc));
- desc = NULL;
- goto exit;
-}
diff --git a/src/senc2d_scene_analyze_c.h b/src/senc2d_scene_analyze_c.h
@@ -16,33 +16,21 @@
#ifndef SENC2D_SCNENE_ANALYZE_C_H
#define SENC2D_SCNENE_ANALYZE_C_H
-#include "senc2d_scene_c.h"
#include "senc2d_internal_types.h"
+#include "senc2d.h"
#include <rsys/mem_allocator.h>
#include <rsys/hash_table.h>
#include <rsys/double2.h>
-/* Information kept during the building side groups. */
-struct segside {
- /* Rank of the segside facing this segside through its vertices */
- side_id_t facing_side_id[2];
- /* Id of this segside's medium */
- medium_id_t medium;
-
- /* Implicit information that we don't need to store:
- * - segment_id
- * - side
- * This is due to the memory layout of the elt darray:
- * front(seg_0), back(seg_0), front(seg_1), back(seg_1), ... */
-};
+struct senc2d_scene;
static FINLINE void
init_segside(struct mem_allocator* alloc, struct segside* data)
{
int i;
ASSERT(data); (void)alloc;
- FOR_EACH(i, 0, 2) data->facing_side_id[i] = SIDE_NULL__;
+ FOR_EACH(i, 0, 3) data->facing_side_id[i] = SIDE_NULL__;
data->medium = MEDIUM_NULL__;
}
@@ -50,15 +38,14 @@ init_segside(struct mem_allocator* alloc, struct segside* data)
#define DARRAY_DATA side_id_t
#include <rsys/dynamic_array.h>
-/* Descriptors for connex components.
+/* Descriptors for connex component.
* Define lists of seg sides starting from a given head.
- * Also keeps the maximum y info of the component
- * along with the associated segment and vertex ids
+ * Also keeps the maximum z info of the component
* and the list of media found */
struct cc_descriptor {
/* Does this component is an outer border of an enclosure or an inner one? */
char is_outer_border;
- vrtx_id_t max_y_vrtx_id; /* id of the vrtx with max y value */
+ vrtx_id_t max_y_vrtx_id; /* id of the vrtx with max z value */
side_id_t side_count;
/* Used when grouping components to form enclosures */
component_id_t cc_id;
@@ -122,7 +109,7 @@ custom_darray_ptr_component_descriptor_release
* - segment_comp for information describing components (kept until
* segment_enc is ready)
* - segment_enc for information describing enclosures (kept in
- * senc2d_descriptor). */
+ * struct descriptor). */
struct segment_tmp {
double max_y;
};
@@ -162,4 +149,7 @@ struct neighbour_info {
#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_neighbour_copy_and_release
#include <rsys/dynamic_array.h>
+extern LOCAL_SYM res_T
+scene_analyze(struct senc2d_scene* scene);
+
#endif /* SENC2D_SCNENE_ANALYZE_C_H */
diff --git a/src/senc2d_scene_c.h b/src/senc2d_scene_c.h
@@ -13,21 +13,117 @@
* 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 SENC2D_SCNENE_C_H
-#define SENC2D_SCNENE_C_H
+#ifndef SENC2D_SCENE_C_H
+#define SENC2D_SCENE_C_H
#include "senc2d_internal_types.h"
+#include "senc2d_enclosure_data.h"
+#include "senc2d_side_range.h"
+#include "senc2d.h"
#include <rsys/ref_count.h>
#include <rsys/dynamic_array.h>
#include <rsys/hash_table.h>
struct mem_allocator;
+struct senc2d_scene;
-#define HTABLE_NAME vrtx_id
-#define HTABLE_KEY vrtx_id_t
-#define HTABLE_DATA vrtx_id_t
-#include <rsys/hash_table.h>
+struct segment_comp {
+ /* The connex component in which each side is. */
+ component_id_t component[2];
+};
+
+static void
+segment_comp_init(struct mem_allocator* alloc, struct segment_comp* seg) {
+ int i;
+ (void)alloc;
+ ASSERT(seg);
+ FOR_EACH(i, 0, 2) seg->component[i] = COMPONENT_NULL__;
+}
+
+#define DARRAY_NAME segment_comp
+#define DARRAY_DATA struct segment_comp
+#define DARRAY_FUNCTOR_INIT segment_comp_init
+#include <rsys/dynamic_array.h>
+
+struct segment_enc {
+ /* The enclosure in which each side is. */
+ enclosure_id_t enclosure[2];
+};
+
+#ifndef NDEBUG
+static void
+segment_enc_init(struct mem_allocator* alloc, struct segment_enc* seg) {
+ int i;
+ (void)alloc;
+ ASSERT(seg);
+ FOR_EACH(i, 0, 2) seg->enclosure[i] = ENCLOSURE_NULL__;
+}
+#define DARRAY_FUNCTOR_INIT segment_enc_init
+#endif
+
+#define DARRAY_NAME segment_enc
+#define DARRAY_DATA struct segment_enc
+#include <rsys/dynamic_array.h>
+
+/* Segment edge struct and basic functions */
+struct seg_edge {
+ vrtx_id_t vrtx0, vrtx1;
+};
+
+static FINLINE int
+edge_ok(const struct seg_edge* edge) {
+ return(edge
+ && edge->vrtx0 <= VRTX_MAX__
+ && edge->vrtx1 <= VRTX_MAX__
+ && edge->vrtx0 < edge->vrtx1);
+}
+
+static FINLINE void
+set_edge
+ (const vrtx_id_t vrtx0,
+ const vrtx_id_t vrtx1,
+ struct seg_edge* edge,
+ unsigned char* reversed)
+{
+ ASSERT(edge && reversed && vrtx0 != vrtx1);
+ ASSERT(*reversed == UCHAR_MAX); /* Should not be already set. */
+ if(vrtx0 < vrtx1) {
+ edge->vrtx0 = vrtx0;
+ edge->vrtx1 = vrtx1;
+ *reversed = 0; /* Non reversed edge */
+ } else {
+ edge->vrtx0 = vrtx1;
+ edge->vrtx1 = vrtx0;
+ *reversed = 1; /* Reversed edge */
+ }
+ ASSERT(edge_ok(edge));
+}
+
+static FINLINE int
+edge_eq(const struct seg_edge* e1, const struct seg_edge* e2)
+{
+ ASSERT(edge_ok(e1) && edge_ok(e2));
+ return e1->vrtx0 == e2->vrtx0 && e1->vrtx1 == e2->vrtx1;
+}
+
+/* Information kept during the building of side groups. */
+struct segside {
+ /* Rank of the segside facing this segside through its edges */
+ side_id_t facing_side_id[2];
+ /* Id of this segside's medium */
+ medium_id_t medium;
+
+ /* Implicit information that we don't need to store:
+ * - segment_id
+ * - side
+ * This is due to the memory layout of the elt darray:
+ * front(seg_0), back(seg_0), front(seg_1), back(seg_1), ... */
+};
+
+#define DARRAY_NAME frontier_edge
+#define DARRAY_DATA struct seg_edge
+#include <rsys/dynamic_array.h>
union double2 {
struct {
@@ -41,15 +137,13 @@ union double2 {
/* Segment information.
* Depending on lifespan, information is kept in different places:
* - segment_in for user provided information (kept in scene)
- * - segment_comp for information describing components (kept in senc2d_descriptor)
- * - segment_cmp for tmp information (kept until segment_comp is ready) */
+ * - segment_comp for information describing components (kept in struct descriptor)
+ * - segment_tmp for tmp information (kept until segment_comp is ready) */
struct segment_in {
/* Ids of the segment's vertices */
vrtx_id_t vertice_id[2];
/* Ids of this segment's media */
medium_id_t medium[2];
- /* Segment index in user world regardless of deduplication. */
- unsigned global_id;
};
static FINLINE void
@@ -58,8 +152,7 @@ segment_in_init(struct mem_allocator* alloc, struct segment_in* seg) {
(void)alloc;
ASSERT(seg);
FOR_EACH(i, 0, 2) seg->vertice_id[i] = VRTX_NULL__;
- FOR_EACH(i, 0, 2) seg->medium[i] = SENC2D_UNDEFINED_MEDIUM;
- seg->global_id = 0;
+ FOR_EACH(i, 0, 2) seg->medium[i] = SENC2D_UNSPECIFIED_MEDIUM;
}
#define DARRAY_NAME segment_in
@@ -67,19 +160,6 @@ segment_in_init(struct mem_allocator* alloc, struct segment_in* seg) {
#define DARRAY_FUNCTOR_INIT segment_in_init
#include <rsys/dynamic_array.h>
-static FINLINE void
-segment_in_flip(struct segment_in* seg) {
- vrtx_id_t v;
- medium_id_t m;
- ASSERT(seg);
- v = seg->vertice_id[1];
- seg->vertice_id[1] = seg->vertice_id[2];
- seg->vertice_id[2] = v;
- m = seg->medium[0];
- seg->medium[0] = seg->medium[1];
- seg->medium[1] = m;
-}
-
static FINLINE int
vrtx_eq(const union double2* v1, const union double2* v2)
{
@@ -93,10 +173,6 @@ vrtx_eq(const union double2* v1, const union double2* v2)
#define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
#include <rsys/hash_table.h>
-#define DARRAY_NAME vrtx_id
-#define DARRAY_DATA vrtx_id_t
-#include <rsys/dynamic_array.h>
-
union vrtx_id2 {
struct {
vrtx_id_t v0, v1;
@@ -135,51 +211,37 @@ seg_key_eq(const union vrtx_id2* k1, const union vrtx_id2* k2)
#define HTABLE_KEY_FUNCTOR_EQ seg_key_eq
#include <rsys/hash_table.h>
-struct side_range {
- side_id_t first, last;
+struct descriptor {
+ enclosure_id_t enclosures_count;
+ /* Store by-segment enclosures */
+ struct darray_segment_enc segments_enc;
+ /* Store enclosures */
+ struct darray_enclosure enclosures;
+ struct darray_enc_ids_array enc_ids_array_by_medium;
+ /* Store frontiers */
+ struct darray_vrtx_id frontiers;
};
-static FINLINE void
-side_range_init(struct mem_allocator* alloc, struct side_range* data)
-{
- ASSERT(data);
- (void)alloc;
- data->first = SIDE_NULL__;
- data->last = 0;
-}
-#define DARRAY_NAME side_range
-#define DARRAY_DATA struct side_range
-#define DARRAY_FUNCTOR_INIT side_range_init
-#include <rsys/dynamic_array.h>
struct senc2d_scene {
/* Front / Back sides convention */
int convention;
-
- /* Segment information as given by user; no duplicates here */
+ /* Segment information as given by user */
struct darray_segment_in segments_in;
-
- /* Vertex information as given by user; no duplicates here */
+ /* Vertex information as given by user */
struct darray_position vertices;
-
- /* Htables used to detect duplicate vertices.
- * As we rely on edges (i.e. vertice IDs) to build
- * neighbourhoods, we need vertice unicity. */
- /* Keep each unique vertex; no duplicates here. */
- struct htable_vrtx unique_vertices;
-
- /* Htables used to detect duplicate segments. */
- /* Keep each unique segment; no duplicates here. */
- struct htable_seg unique_segments;
/* Keep sizes */
- seg_id_t nsegs, nusegs; /* Segment count, unique segment count */
- vrtx_id_t nverts, nuverts; /* Vrtx count, unique vrtx count */
+ seg_id_t nsegs; /* Seg count */
+ vrtx_id_t nverts; /* Vrtx count */
medium_id_t next_medium_idx;
+ /* media_use 0 is for SENC2D_UNSPECIFIED_MEDIUM, n+1 is for n */
struct darray_side_range media_use;
- side_id_t sides_with_defined_medium_count;
+
+ /* The descriptor of the analyze */
+ struct descriptor analyze;
ref_T ref;
struct senc2d_device* dev;
};
-#endif /* SENC2D_SCNENE_C_H */
+#endif /* SENC2D_SCENE_C_H */
diff --git a/src/senc2d_side_range.h b/src/senc2d_side_range.h
@@ -0,0 +1,44 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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 SENC2D_SIDE_RANGE_H
+#define SENC2D_SIDE_RANGE_H
+
+#include "senc2d_internal_types.h"
+
+#include <rsys/dynamic_array.h>
+
+struct mem_allocator;
+
+struct side_range {
+ side_id_t first, last;
+};
+
+static FINLINE void
+side_range_init(struct mem_allocator* alloc, struct side_range* data)
+{
+ ASSERT(data);
+ (void)alloc;
+ data->first = SIDE_NULL__;
+ data->last = 0;
+}
+
+#define DARRAY_NAME side_range
+#define DARRAY_DATA struct side_range
+#define DARRAY_FUNCTOR_INIT side_range_init
+#include <rsys/dynamic_array.h>
+
+
+#endif /* SENC2D_SCENE_C_H */
diff --git a/src/sencX2d.h b/src/sencX2d.h
@@ -0,0 +1,44 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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 SENC_X_2D_H
+#define SENC_X_2D_H
+
+#if !defined(SENCXD_DIM) || (SENCXD_DIM != 2 && SENCXD_DIM != 3)
+#error "SENCXD_DIM must be defined; admissible values are 2 and 3"
+#endif
+
+#include <star/senc2d.h>
+
+/* Star-enclosures-XD macros generic to the SENCXD_DIM */
+#ifndef SENCXD
+#define SENCXD CONCAT(CONCAT(SENC, SENCXD_DIM), D)
+#endif
+#ifndef sencXd
+#define sencXd(Name) CONCAT(CONCAT(CONCAT(senc, SENCXD_DIM), d_), Name)
+#endif
+#ifndef SENCXD_
+#define SENCXD_(Name) CONCAT(CONCAT(CONCAT(SENC, SENCXD_DIM), D_), Name)
+#endif
+
+/* Function names that require additional dedicated macros */
+#define senc2d_scene_get_primitives_count senc2d_scene_get_segments_count
+#define senc2d_scene_get_primitive senc2d_scene_get_segment
+#define senc2d_scene_get_primitive_media senc2d_scene_get_segment_media
+#define senc2d_scene_get_primitive_enclosures senc2d_scene_get_segment_enclosures
+#define senc2d_enclosure_get_primitive senc2d_enclosure_get_segment
+#define senc2d_enclosure_get_primitive_id senc2d_enclosure_get_segment_id
+
+#endif /* SENC_X_2D_H */
diff --git a/src/sencX2d_undefs.h b/src/sencX2d_undefs.h
@@ -0,0 +1,33 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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 SENC_X_2D_H
+#error "The sencX2d.h file must be included priorly to this file."
+#endif
+
+/* Star-enclosures-XD macros generic to the SENCXD_DIM */
+#undef SENCXD
+#undef sencXd
+#undef SENCXD_
+
+/* Function names that require additional dedicated macros */
+#undef senc2d_scene_get_primitives_count
+#undef senc2d_scene_get_primitive
+#undef senc2d_scene_get_primitive_media
+#undef senc2d_scene_get_primitive_enclosures
+#undef senc2d_enclosure_get_primitive
+#undef senc2d_enclosure_get_primitive_id
+
+#undef SENC_X_2D_H
diff --git a/src/test_senc2d_add_n_merge.c b/src/test_senc2d_add_n_merge.c
@@ -1,203 +0,0 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (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/>. */
-
-#include "senc2d.h"
-#include "test_senc2d_utils.h"
-
-/* Manage add_geometry behaviour */
-struct add_geom_ctx {
- unsigned add_cpt, merge_cpt;
- res_T add_res, merge_res;
-};
-
-static res_T
-add_seg
- (const unsigned global_id,
- const unsigned iseg,
- void* context)
-{
- struct context* ctx = context;
- struct add_geom_ctx* add_geom_ctx;
- ASSERT(ctx); (void)global_id; (void)iseg;
- add_geom_ctx = ctx->custom;
- if(add_geom_ctx->add_res == RES_OK) ++add_geom_ctx->add_cpt;
- return add_geom_ctx->add_res;
-}
-
-static res_T
-merge_seg
- (const unsigned global_id,
- const unsigned iseg,
- const int reversed_segment,
- const unsigned segment_media[2],
- const unsigned merge_media[2],
- void* context)
-{
- struct context* ctx = context;
- struct add_geom_ctx* add_geom_ctx;
- ASSERT(ctx && segment_media && merge_media);
- (void)global_id; (void)iseg; (void)reversed_segment; (void)segment_media; (void)merge_media;
- add_geom_ctx = ctx->custom;
- if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt;
- return add_geom_ctx->merge_res;
-}
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc2d_device* dev = NULL;
- struct senc2d_scene* scn = NULL;
- struct context ctx;
- unsigned i;
- struct add_geom_ctx add_geom_ctx;
- unsigned media[4];
- const int conv = SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE;
- const unsigned media_count = sizeof(media) / sizeof(*media);
- (void)argc; (void)argv;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
- OK(senc2d_scene_create(dev, conv, &scn));
-
- /* A 2D square.
- * 2 enclosures (inside, outside) sharing the same segments,
- * but opposite sides */
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
- ctx.front_media = media;
-
- add_geom_ctx.add_cpt = add_geom_ctx.merge_cpt = 0;
- add_geom_ctx.add_res = add_geom_ctx.merge_res = RES_OK;
-
- /* Geometry with no media information on both sides */
- for (i = 0; i < media_count; i++) media[i] = SENC2D_UNDEFINED_MEDIUM;
- ctx.front_media = media;
- ctx.back_media = media;
-
- /* If add fails, add geometry fails the same way */
- add_geom_ctx.add_res = RES_BAD_ARG;
- BA(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.add_cpt == 0);
- add_geom_ctx.add_res = RES_MEM_ERR;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx) == RES_MEM_ERR);
- CHK(add_geom_ctx.add_cpt == 0);
-
- /* Successful add geometry with add callback */
- add_geom_ctx.add_res = RES_OK;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.add_cpt == media_count);
- CHK(add_geom_ctx.merge_cpt == 0);
-
- /* Clear scene */
- SENC2D(scene_ref_put(scn));
- OK(senc2d_scene_create(dev, conv, &scn));
-
- /* Successful add geometry without add callback */
- add_geom_ctx.add_cpt = 0;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, NULL, merge_seg, &ctx));
- CHK(add_geom_ctx.add_cpt == 0);
- CHK(add_geom_ctx.merge_cpt == 0);
-
- /* If merge fails, add geometry fails the same way */
- add_geom_ctx.merge_res = RES_BAD_ARG;
- BA(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.merge_cpt == 0);
- add_geom_ctx.merge_res = RES_MEM_ERR;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx) == RES_MEM_ERR);
- CHK(add_geom_ctx.merge_cpt == 0);
-
- /* Successful add geometry without merge callback */
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, NULL, &ctx));
- CHK(add_geom_ctx.merge_cpt == 0);
-
- /* Successful add geometry with merge callback */
- add_geom_ctx.merge_res = RES_OK;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.merge_cpt == media_count);
- add_geom_ctx.merge_cpt = 0;
-
- /* Geometry with media information on both sides */
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- /* Clear scene */
- SENC2D(scene_ref_put(scn));
- OK(senc2d_scene_create(dev, conv, &scn));
-
- /* Successful add geometry with add callback */
- add_geom_ctx.add_res = RES_OK;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.add_cpt == media_count);
- CHK(add_geom_ctx.merge_cpt == 0);
- add_geom_ctx.add_cpt = 0;
-
- /* Clear scene */
- SENC2D(scene_ref_put(scn));
- OK(senc2d_scene_create(dev, conv, &scn));
-
- /* Successful add geometry with add callback */
- add_geom_ctx.add_res = RES_OK;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.add_cpt == media_count);
- CHK(add_geom_ctx.merge_cpt == 0);
- add_geom_ctx.add_cpt = 0;
-
- /* Successful add geometry with merge callback */
- add_geom_ctx.merge_res = RES_OK;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.merge_cpt == media_count);
- add_geom_ctx.merge_cpt = 0;
-
- /* Geometry with incompatible media information on both sides */
- ctx.front_media = medium1;
- ctx.back_media = medium0;
-
- /* Unsuccessful add geometry without merge callback */
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, NULL, &ctx));
- CHK(add_geom_ctx.merge_cpt == 0);
-
- /* Successful add geometry with merge callback */
- add_geom_ctx.merge_res = RES_OK;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- CHK(add_geom_ctx.merge_cpt == media_count);
- add_geom_ctx.merge_cpt = 0;
-
- SENC2D(scene_ref_put(scn));
- SENC2D(device_ref_put(dev));
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
-
- return 0;
-}
diff --git a/src/test_senc2d_descriptor.c b/src/test_senc2d_descriptor.c
@@ -1,254 +0,0 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (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/>. */
-
-#include "senc2d.h"
-#include "test_senc2d_utils.h"
-
-#include <rsys/float2.h>
-#include <rsys/double2.h>
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc2d_device* dev = NULL;
- struct senc2d_scene* scn = NULL;
- struct senc2d_descriptor* desc = NULL;
- struct senc2d_enclosure* enc = NULL;
- struct context ctx;
- unsigned count, maxm;
- unsigned indices[2];
- double coord[2];
- unsigned media[2];
- unsigned enclosures[2];
- (void)argc, (void)argv;
-
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
-
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- /* A 2D square */
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_ref_get(desc) == RES_OK);
- CHK(senc2d_descriptor_ref_get(NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_ref_put(NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_max_medium(NULL, &maxm) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_max_medium(desc, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_max_medium(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
-
- CHK(maxm == 1);
-
- CHK(senc2d_descriptor_get_enclosure_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count(desc, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &count) == RES_OK);
-
- CHK(count == 2);
-
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(NULL, 0, &count)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 9, &count)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(NULL, 9, &count)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(NULL, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 9, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(NULL, 9, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 0, &count)
- == RES_OK);
-
- CHK(count == 1);
-
- CHK(senc2d_descriptor_get_enclosure(desc, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(desc, 9, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(desc, 9, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(NULL, 0, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(NULL, 9, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(NULL, 9, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure(desc, 0, &enc) == RES_OK);
-
- CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
-
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 9, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 9, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 9, 0, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 9, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 9, 9, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 9, 9, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 0, 0, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 0, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 0, 9, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 0, 9, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 9, 0, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 9, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 9, 9, &enc) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(NULL, 9, 9, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 0, &enc) == RES_OK);
-
- CHK(senc2d_descriptor_get_global_vertices_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_vertices_count(desc, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
- CHK(count == nvertices);
-
- CHK(senc2d_descriptor_get_global_segments_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segments_count(desc, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segments_count(desc, &count) == RES_OK);
- CHK(count == nsegments);
-
- CHK(senc2d_descriptor_get_global_segment(NULL, 0, indices) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment(NULL, nsegments, indices)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment(desc, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment(desc, 0, indices) == RES_OK);
- CHK(indices[0] == box_indices[0] && indices[1] == box_indices[1]);
-
- CHK(senc2d_descriptor_get_global_vertex(NULL, 0, coord) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_vertex(NULL, nvertices, coord)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_vertex(desc, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_vertex(desc, 0, coord) == RES_OK);
- CHK(coord[0] == box_vertices[0] && coord[1] == box_vertices[1]);
-
- CHK(senc2d_descriptor_get_global_segment_media(NULL, 0, media)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_media(NULL, nvertices, media)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_media(desc, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_media(desc, 0, media) == RES_OK);
- CHK(media[0] == ctx.front_media[0] && media[1] == ctx.back_media[1]);
-
- CHK(senc2d_descriptor_get_global_segment_enclosures(NULL, 0, enclosures)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_enclosures(NULL, nvertices, enclosures)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_enclosures(desc, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_enclosures(desc, 0, enclosures)
- == RES_OK);
- CHK(enclosures[0] == 0 && enclosures[1] == 1);
-
- CHK(senc2d_descriptor_get_global_segment_global_id(NULL, 0, indices)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_global_id(NULL, nvertices, indices)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_global_id(desc, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_global_id(desc, 0, indices)
- == RES_OK);
- /* No duplicates and no custom id: user id is unique vertex id */
- CHK(indices[0] == 0);
-
- /* Add valid duplicate geometry */
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- desc = NULL;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
- /* Duplicate vertices have been replaced */
- CHK(count == nvertices);
-
- CHK(senc2d_descriptor_get_global_segments_count(desc, &count) == RES_OK);
- /* Duplicate segments have been replaced */
- CHK(count == nsegments);
-
- /* Add invalid duplicate geometry */
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- desc = NULL;
- ctx.front_media = medium1;
- ctx.back_media = medium0;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
-
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- desc = NULL;
- CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
-
- /* Same square with a hole (last segment is missing) */
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- CHK(senc2d_scene_add_geometry(scn, nsegments - 1, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_frontier_vertices_count(NULL, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertices_count(desc, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertices_count(NULL, &count)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertices_count(desc, &count)
- == RES_OK);
-
- CHK(senc2d_descriptor_get_frontier_vertex(NULL, count, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(desc, count, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(NULL, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(NULL, count, indices)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(desc, 0, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(desc, count, indices)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(NULL, 0, indices)
- == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_frontier_vertex(desc, 0, indices)
- == RES_OK);
-
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
-
- return 0;
-}
diff --git a/src/test_senc2d_device.c b/src/test_senc2d_device.c
@@ -18,6 +18,8 @@
#include <rsys/logger.h>
+#include <stdio.h>
+
static INLINE void
log_stream(const char* msg, void* ctx)
{
@@ -34,40 +36,38 @@ main(int argc, char** argv)
struct senc2d_device* dev;
(void)argc, (void)argv;
- CHK(senc2d_device_create(NULL, NULL, 0, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_device_create(NULL, NULL, 0, 0, &dev) == RES_BAD_ARG);
- CHK(senc2d_device_create(NULL, NULL, 1, 0, &dev) == RES_OK);
- CHK(senc2d_device_ref_get(NULL) == RES_BAD_ARG);
- CHK(senc2d_device_ref_get(dev) == RES_OK);
- CHK(senc2d_device_ref_put(NULL) == RES_BAD_ARG);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
+ BA(senc2d_device_create(NULL, NULL, 0, 0, NULL));
+ BA(senc2d_device_create(NULL, NULL, 0, 0, &dev));
+ OK(senc2d_device_create(NULL, NULL, 1, 0, &dev));
+ BA(senc2d_device_ref_get(NULL));
+ OK(senc2d_device_ref_get(dev));
+ BA(senc2d_device_ref_put(NULL));
+ OK(senc2d_device_ref_put(dev));
+ OK(senc2d_device_ref_put(dev));
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)
- == RES_OK);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- CHK(senc2d_device_create(NULL, &allocator, 1, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_device_create(NULL, &allocator, 1, 0, &dev) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
+ BA(senc2d_device_create(NULL, &allocator, 1, 0, NULL));
+ OK(senc2d_device_create(NULL, &allocator, 1, 0, &dev));
+ OK(senc2d_device_ref_put(dev));
CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- CHK(logger_init(&allocator, &logger) == RES_OK);
+ OK(logger_init(&allocator, &logger));
logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
- CHK(senc2d_device_create(&logger, NULL, 1, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_device_create(&logger, NULL, 1, 0, &dev) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
+ BA(senc2d_device_create(&logger, NULL, 1, 0, NULL));
+ OK(senc2d_device_create(&logger, NULL, 1, 0, &dev));
+ OK(senc2d_device_ref_put(dev));
- CHK(senc2d_device_create(&logger, &allocator, 1, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_device_create(&logger, &allocator, 1, 0, &dev) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
+ BA(senc2d_device_create(&logger, &allocator, 1, 0, NULL));
+ OK(senc2d_device_create(&logger, &allocator, 1, 0, &dev));
+ OK(senc2d_device_ref_put(dev));
- CHK(senc2d_device_create
- (&logger, &allocator, SENC2D_NTHREADS_DEFAULT, 0, &dev) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
+ OK(senc2d_device_create(&logger, &allocator, SENC2D_NTHREADS_DEFAULT, 0, &dev));
+ OK(senc2d_device_ref_put(dev));
logger_release(&logger);
check_memory_allocator(&allocator);
diff --git a/src/test_senc2d_enclosure.c b/src/test_senc2d_enclosure.c
@@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "senc2d.h"
-#include "senc2d_s2d_wrapper.h"
+#include "senc2d_sXd_helper.h"
#include "test_senc2d_utils.h"
#include <rsys/double2.h>
@@ -25,7 +25,6 @@ static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
struct senc2d_enclosure* enclosures[2] = { NULL, NULL };
@@ -40,157 +39,120 @@ test(const int convention)
unsigned gid;
enum senc2d_side side;
double vrtx[2];
- struct context ctx;
- unsigned i, n, s, ecount;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned i, n, s, count;
int conv;
const int conv_front = (convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
const int conv_in = (convention & SENC2D_CONVENTION_NORMAL_INSIDE) != 0;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
-
- CHK(senc2d_scene_create(dev, convention, &scn) == RES_OK);
-
- CHK(senc2d_scene_get_convention(scn, &conv) == RES_OK);
- CHK(conv == convention);
-
- s2d_attribs.type = S2D_FLOAT2;
- s2d_attribs.usage = S2D_POSITION;
- s2d_attribs.get = senc2d_enclosure_get_vertex__;
-
- CHK(s2d_device_create(NULL, &allocator, 0, &s2d) == RES_OK);
-
- CHK(s2d_scene_create(s2d, &s2d_scn) == RES_OK);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
/* A 2D square.
* 2 enclosures (inside, outside) sharing the same segments,
* but opposite sides */
ctx.positions = box_vertices;
ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
ctx.front_media = medium0;
ctx.back_media = medium1;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
+ OK(senc2d_scene_create(dev, convention, nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_get_convention(scn, &conv));
+ CHK(conv == convention);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
- CHK(ecount == 2);
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 2);
- CHK(senc2d_descriptor_get_enclosure(desc, 0, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_ref_get(NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_ref_get(enclosure) == RES_OK);
- CHK(senc2d_enclosure_ref_put(NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
-
- CHK(senc2d_enclosure_get_segment(NULL, 0, indices[0]) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(enclosure, nsegments, indices[0])
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(enclosure, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(NULL, nsegments, indices[0])
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(enclosure, nsegments, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(NULL, nsegments, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment(enclosure, 0, indices[0]) == RES_OK);
-
- CHK(senc2d_enclosure_get_vertex(NULL, 0, vrtx) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(enclosure, nvertices, vrtx)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(enclosure, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(NULL, nvertices, vrtx) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(enclosure, nvertices, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(NULL, nvertices, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_vertex(enclosure, 0, vrtx) == RES_OK);
-
- CHK(senc2d_enclosure_get_segment_global_id(NULL, 0, &gid, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, nsegments, &gid, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, 0, NULL, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, nsegments, &gid, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, 0, NULL, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, nsegments, NULL, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, nsegments, NULL, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, 0, &gid, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, 0, &gid, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, nsegments, &gid, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, 0, NULL, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, nsegments, &gid, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, 0, NULL, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, nsegments, NULL, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(NULL, nsegments, NULL, &side)
- == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, 0, &gid, &side)
- == RES_OK);
-
- CHK(senc2d_enclosure_get_medium(NULL, 0, &medium) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(enclosure, 2, &medium) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(enclosure, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(NULL, 2, &medium) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(enclosure, 2, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(NULL, 2, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_medium(enclosure, 0, &medium) == RES_OK);
-
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
-
- FOR_EACH(i, 0, ecount) {
- CHK(senc2d_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
-
- CHK(senc2d_enclosure_get_header(NULL, &header) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_header(enclosure, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_header(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, 0, &enclosure));
+ BA(senc2d_enclosure_ref_get(NULL));
+ OK(senc2d_enclosure_ref_get(enclosure));
+ BA(senc2d_enclosure_ref_put(NULL));
+ OK(senc2d_enclosure_ref_put(enclosure));
+
+ BA(senc2d_enclosure_get_segment(NULL, 0, indices[0]));
+ BA(senc2d_enclosure_get_segment(enclosure, nsegments, indices[0]));
+ BA(senc2d_enclosure_get_segment(enclosure, 0, NULL));
+ BA(senc2d_enclosure_get_segment(NULL, nsegments, indices[0]));
+ BA(senc2d_enclosure_get_segment(NULL, 0, NULL));
+ BA(senc2d_enclosure_get_segment(enclosure, nsegments, NULL));
+ BA(senc2d_enclosure_get_segment(NULL, nsegments, NULL));
+ OK(senc2d_enclosure_get_segment(enclosure, 0, indices[0]));
+
+ BA(senc2d_enclosure_get_vertex(NULL, 0, vrtx));
+ BA(senc2d_enclosure_get_vertex(enclosure, nvertices, vrtx));
+ BA(senc2d_enclosure_get_vertex(enclosure, 0, NULL));
+ BA(senc2d_enclosure_get_vertex(NULL, nvertices, vrtx));
+ BA(senc2d_enclosure_get_vertex(NULL, 0, NULL));
+ BA(senc2d_enclosure_get_vertex(enclosure, nvertices, NULL));
+ BA(senc2d_enclosure_get_vertex(NULL, nvertices, NULL));
+ OK(senc2d_enclosure_get_vertex(enclosure, 0, vrtx));
+
+ BA(senc2d_enclosure_get_segment_id(NULL, 0, &gid, NULL));
+ BA(senc2d_enclosure_get_segment_id(enclosure, nsegments, &gid, NULL));
+ BA(senc2d_enclosure_get_segment_id(enclosure, 0, NULL, NULL));
+ BA(senc2d_enclosure_get_segment_id(NULL, nsegments, &gid, NULL));
+ BA(senc2d_enclosure_get_segment_id(NULL, 0, NULL, NULL));
+ BA(senc2d_enclosure_get_segment_id(enclosure, nsegments, NULL, NULL));
+ BA(senc2d_enclosure_get_segment_id(NULL, nsegments, NULL, NULL));
+ BA(senc2d_enclosure_get_segment_id(enclosure, 0, &gid, NULL));
+ BA(senc2d_enclosure_get_segment_id(NULL, 0, &gid, &side));
+ BA(senc2d_enclosure_get_segment_id(enclosure, nsegments, &gid, &side));
+ BA(senc2d_enclosure_get_segment_id(enclosure, 0, NULL, &side));
+ BA(senc2d_enclosure_get_segment_id(NULL, nsegments, &gid, &side));
+ BA(senc2d_enclosure_get_segment_id(NULL, 0, NULL, &side));
+ BA(senc2d_enclosure_get_segment_id(enclosure, nsegments, NULL, &side));
+ BA(senc2d_enclosure_get_segment_id(NULL, nsegments, NULL, &side));
+ OK(senc2d_enclosure_get_segment_id(enclosure, 0, &gid, &side));
+
+ BA(senc2d_enclosure_get_medium(NULL, 0, &medium));
+ BA(senc2d_enclosure_get_medium(enclosure, 2, &medium));
+ BA(senc2d_enclosure_get_medium(enclosure, 0, NULL));
+ BA(senc2d_enclosure_get_medium(NULL, 2, &medium));
+ BA(senc2d_enclosure_get_medium(NULL, 0, NULL));
+ BA(senc2d_enclosure_get_medium(enclosure, 2, NULL));
+ BA(senc2d_enclosure_get_medium(NULL, 2, NULL));
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
+
+ OK(senc2d_enclosure_ref_put(enclosure));
+
+ FOR_EACH(i, 0, count) {
+ OK(senc2d_scene_get_enclosure(scn, i, &enclosure));
+
+ BA(senc2d_enclosure_get_header(NULL, &header));
+ BA(senc2d_enclosure_get_header(enclosure, NULL));
+ BA(senc2d_enclosure_get_header(NULL, NULL));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
CHK(header.enclosure_id == i);
CHK(header.enclosed_media_count == 1);
- CHK(senc2d_enclosure_get_medium(enclosure, 0, &medium) == RES_OK);
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
/* Geometrical normals point outside the square in input segments:
* if convention is front, front medium (0) is outside,
* that is medium 0's enclosure is infinite */
CHK(conv_front == ((medium == 0) == header.is_infinite));
- CHK(header.segment_count == nsegments);
- CHK(header.unique_segment_count == nsegments);
+ CHK(header.primitives_count == nsegments);
+ CHK(header.unique_primitives_count == nsegments);
CHK(header.vertices_count == nvertices);
+ CHK(header.is_infinite == (i == 0));
- FOR_EACH(s, 0, header.segment_count) {
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side) == RES_OK);
+ FOR_EACH(s, 0, header.primitives_count) {
+ OK(senc2d_enclosure_get_segment_id(enclosure, s, &gid, &side));
CHK(gid == s);
CHK(side == (medium == 0) ? SENC2D_FRONT : SENC2D_BACK);
}
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enclosure));
}
FOR_EACH(i, 0, 2)
- CHK(senc2d_descriptor_get_enclosure(desc, i, enclosures + i) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, i, enclosures + i));
FOR_EACH(n, 0, nsegments) {
int same, reversed;
/* Read same segments in both enclosures */
FOR_EACH(i, 0, 2)
- CHK(senc2d_enclosure_get_segment(enclosures[i], n, indices[i]) == RES_OK);
+ OK(senc2d_enclosure_get_segment(enclosures[i], n, indices[i]));
/* Same segments and opposite sides for the 2 enclosures */
FOR_EACH(i, 0, 2) CHK(indices[0][i] == indices[1][1 - i]);
/* Enclosure 0 is outside (and contains medium 0 if convention is front).
@@ -203,74 +165,70 @@ test(const int convention)
CHK(same && reversed == conv_in);
}
FOR_EACH(i, 0, 2)
- CHK(senc2d_enclosure_ref_put(enclosures[i]) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enclosures[i]));
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
/* Same 2D square, but with a hole (incomplete).
* 1 single enclosure including both sides of segments */
- CHK(senc2d_scene_create(dev, convention, &scn) == RES_OK);
-
ctx.positions = box_vertices;
ctx.indices = box_indices;
- ctx.scale = 1;
- d2(ctx.offset, 0, 0);
ctx.front_media = medium0;
ctx.back_media = medium1;
- CHK(senc2d_scene_add_geometry(scn, nsegments - 1, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
+ OK(senc2d_scene_create(dev, convention, nsegments - 1, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_get_frontier_vertice_count(scn, &count));
+ CHK(count == 2);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
- CHK(ecount == 1);
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1);
- dump_enclosure(desc, 0, "test2d_enclosure_hole.obj");
+#ifdef DUMP_ENCLOSURES
+ dump_enclosure(scn, 0, "test_enclosure_hole.obj");
+#endif
- CHK(senc2d_descriptor_get_enclosure(desc, 0, &enclosure) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, 0, &enclosure));
- CHK(senc2d_enclosure_get_header(NULL, &header) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_header(enclosure, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_header(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ BA(senc2d_enclosure_get_header(NULL, &header));
+ BA(senc2d_enclosure_get_header(enclosure, NULL));
+ BA(senc2d_enclosure_get_header(NULL, NULL));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
CHK(header.enclosure_id == 0);
CHK(header.enclosed_media_count == 2);
- CHK(header.segment_count == 2 * header.unique_segment_count);
- CHK(header.unique_segment_count == nsegments - 1);
+ CHK(header.primitives_count == 2 * header.unique_primitives_count);
+ CHK(header.unique_primitives_count == nsegments - 1);
CHK(header.vertices_count == nvertices);
CHK(header.is_infinite == 1);
- FOR_EACH(s, 0, header.segment_count) {
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side) == RES_OK);
- /* The first unique_segment_count segments of an enclosure
+ FOR_EACH(s, 0, header.primitives_count) {
+ OK(senc2d_enclosure_get_segment_id(enclosure, s, &gid, &side));
+ /* The first unique_primitives_count segments of an enclosure
* are unique segments */
- if(s < header.unique_segment_count) CHK(gid == s);
- CHK(side == (s < header.unique_segment_count) ? SENC2D_FRONT : SENC2D_BACK);
- }
-
- FOR_EACH(n, 0, header.unique_segment_count) {
- /* Put geometry in a 2D view */
- CHK(s2d_shape_create_line_segments(s2d, &s2d_shp) == RES_OK);
-
- CHK(s2d_line_segments_setup_indexed_vertices(s2d_shp, header.segment_count,
- senc2d_enclosure_get_segment__, header.vertices_count, &s2d_attribs,
- 1, enclosure)
- == RES_OK);
-
- CHK(s2d_scene_attach_shape(s2d_scn, s2d_shp) == RES_OK);
- S2D(shape_ref_put(s2d_shp));
+ if(s < header.unique_primitives_count) CHK(gid == s);
+ CHK(side == (s < header.unique_primitives_count) ? SENC2D_FRONT : SENC2D_BACK);
}
+ /* Put geometry in a 2D view using helper functions */
+ s2d_attribs.type = S2D_FLOAT2;
+ s2d_attribs.usage = S2D_POSITION;
+ s2d_attribs.get = senc2d_sXd_enclosure_get_position;
+ OK(s2d_device_create(NULL, &allocator, 0, &s2d));
+ OK(s2d_scene_create(s2d, &s2d_scn));
+ S2D(shape_create_line_segments(s2d, &s2d_shp));
+ S2D(line_segments_setup_indexed_vertices(s2d_shp, header.primitives_count,
+ senc2d_sXd_enclosure_get_indices, header.vertices_count, &s2d_attribs,
+ 1, enclosure));
+ OK(s2d_scene_attach_shape(s2d_scn, s2d_shp));
+ S2D(shape_ref_put(s2d_shp));
S2D(device_ref_put(s2d));
S2D(scene_ref_put(s2d_scn));
SENC2D(scene_ref_put(scn));
SENC2D(device_ref_put(dev));
- SENC2D(descriptor_ref_put(desc));
SENC2D(enclosure_ref_put(enclosure));
check_memory_allocator(&allocator);
@@ -281,7 +239,7 @@ test(const int convention)
int
main(int argc, char** argv)
{
- (void) argc, (void) argv;
+ (void)argc, (void)argv;
test(SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE);
test(SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE);
test(SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_OUTSIDE);
diff --git a/src/test_senc2d_inconsistant_square.c b/src/test_senc2d_inconsistant_square.c
@@ -14,13 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "senc2d.h"
-#include "senc2d_s2d_wrapper.h"
#include "test_senc2d_utils.h"
#include <rsys/double2.h>
/* The following array lists the indices toward the 2D vertices of each
-* segment.
+ * segment.
* Y
* 2----3 |
* | | 0----X
@@ -47,45 +46,35 @@ static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
struct senc2d_enclosure* enclosure;
struct senc2d_enclosure_header header;
int conv;
int conv_front, conv_in;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, e, ecount;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
-
- CHK(senc2d_scene_create(dev, convention, &scn) == RES_OK);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
/* A 2D square.
* 2 enclosures (inside, outside) sharing the same segments,
* but opposite sides.
* What differs in this test is that segment #0 vertices are given
- * in the opposite order. */
+ * in the opposite rotation order. */
ctx.positions = box_vertices;
ctx.indices = inconsistant_box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
ctx.front_media = inconsistant_medium_front;
ctx.back_media = inconsistant_medium_back;
- CHK(senc2d_scene_add_geometry(scn, inconsistant_box_nsegments, get_indices,
- get_media, nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_create(dev, convention, inconsistant_box_nsegments,
+ get_indices, get_media, nvertices, get_position, &ctx, &scn));
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 2);
- CHK(senc2d_scene_get_convention(scn, &conv) == RES_OK);
+ OK(senc2d_scene_get_convention(scn, &conv));
CHK(conv == convention);
conv_front = (conv & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
conv_in = (conv & SENC2D_CONVENTION_NORMAL_INSIDE) != 0;
@@ -95,10 +84,11 @@ test(const int convention)
char name[128];
enum senc2d_side side, expected_side;
unsigned gid;
- CHK(senc2d_descriptor_get_enclosure(desc, e, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ (void)name;
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
CHK(header.enclosed_media_count == 1);
- CHK(senc2d_enclosure_get_medium(enclosure, 0, &medium) == RES_OK);
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
/* If NORMAL_FRONT the external enclosure's medium should be 0,
* 1 if NORMAL_BACK */
expected_external_medium = conv_front ? 0 : 1;
@@ -106,11 +96,13 @@ test(const int convention)
expected_external_medium : !expected_external_medium);
CHK(medium == expected_medium);
+#ifdef DUMP_ENCLOSURES
sprintf(name, "test_inconsistant_square_%s_%s_%u.obj",
conv_front ? "front" : "back", conv_in ? "in" : "out", e);
- dump_enclosure(desc, e, name);
+ dump_enclosure(scn, e, name);
+#endif
- FOR_EACH(i, 0, header.segment_count) {
+ FOR_EACH(i, 0, header.primitives_count) {
int same, reversed, fst_reversed;
fst_reversed = ((e == 0) == conv_in);
expected_side = (inconsistant_medium_front[i] == expected_medium)
@@ -121,7 +113,7 @@ test(const int convention)
/* Should be made of the same segments */
CHK(same);
CHK(i ? reversed != fst_reversed : reversed == fst_reversed);
- CHK(senc2d_enclosure_get_segment_global_id(enclosure, i, &gid, &side) == RES_OK);
+ OK(senc2d_enclosure_get_segment_id(enclosure, i, &gid, &side));
CHK(side == expected_side);
}
SENC2D(enclosure_ref_put(enclosure));
@@ -129,7 +121,6 @@ test(const int convention)
SENC2D(scene_ref_put(scn));
SENC2D(device_ref_put(dev));
- SENC2D(descriptor_ref_put(desc));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
@@ -138,11 +129,12 @@ test(const int convention)
int main(int argc, char** argv)
{
- (void) argc, (void) argv;
+ (void)argc, (void)argv;
test(SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE);
test(SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE);
test(SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_OUTSIDE);
test(SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_OUTSIDE);
+
return 0;
}
diff --git a/src/test_senc2d_many_enclosures.c b/src/test_senc2d_many_enclosures.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2020 (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
@@ -13,79 +13,42 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This test is similar to test_senc2d_some_enclosures, but involves 64*64*64
+ * circles instead of 4*4*4, thus making it impossible to define the geometry
+ * through static arrays. */
+
+#define NB_CIRC_X 32
+#define NB_CIRC_Y 32
+#define NB_CIRC_Z 64
+/* 64^3 = 262144 circles */
+#define NB_CIRC (NB_CIRC_X * NB_CIRC_Y * NB_CIRC_Z)
+
#include "senc2d.h"
#include "test_senc2d_utils.h"
+#include "test_senc2d_utils2.h"
-#include <rsys/double2.h>
-#include <rsys/stretchy_array.h>
#include <rsys/clock_time.h>
+#include <rsys/double2.h>
+#include <stdio.h>
#include <limits.h>
-static void
-get_ctx_indices(const unsigned iseg, unsigned ids[2], void* context)
-{
- struct context* ctx = context;
- (void)ctx;
- ASSERT(ids && ctx);
- ASSERT(2 * iseg + 1 < sa_size(ctx->indices));
- get_indices(iseg, ids, context);
-}
-
-static void
-get_ctx_position(const unsigned ivert, double pos[2], void* context)
-{
- struct context* ctx = context;
- (void)ctx;
- ASSERT(pos && ctx);
- ASSERT(2 * ivert + 1 < sa_size(ctx->positions));
- get_position(ivert, pos, context);
-}
-
-static void
-get_ctx_media(const unsigned iseg, unsigned medium[2], void* context)
-{
- struct context* ctx = context;
- (void)iseg;
- ASSERT(medium && ctx);
- medium[ctx->reverse_med ? 1 : 0] = *ctx->front_media;
- medium[ctx->reverse_med ? 0 : 1] = *ctx->back_media;
-}
-
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
- struct context ctx;
- unsigned m_in, m_out;
+ struct context ctx = CONTEXT_NULL__;
unsigned count;
unsigned circ_seg_count, circ_vrtx_count, e;
- int i, j, k;
char dump[64];
struct time t0, t1;
(void)argc, (void)argv;
- CHK(mem_init_regular_allocator(&allocator) == RES_OK);
- CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
+ OK(mem_init_regular_allocator(&allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
-#define NB_CIRC_1 64
- /* 64^3 = 262144 circles */
-#define NB_CIRC (NB_CIRC_1 * NB_CIRC_1 * NB_CIRC_1)
- /* Create the scene */
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- ctx.positions = NULL;
- ctx.indices = NULL;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- ctx.front_media = &m_in;
- ctx.back_media = &m_out;
/* A 16 segments circle template */
create_circle(1, 16, &ctx);
ASSERT(sa_size(ctx.positions) % 2 == 0
@@ -94,61 +57,48 @@ main(int argc, char** argv)
&& sa_size(ctx.indices) / 2 < UINT_MAX);
circ_seg_count = (unsigned)sa_size(ctx.indices) / 2;
circ_vrtx_count = (unsigned)sa_size(ctx.positions) / 2;
- CHK(senc2d_scene_reserve(scn, NB_CIRC * circ_vrtx_count, NB_CIRC * circ_seg_count, 0)
- == RES_OK);
- FOR_EACH(i, 0, NB_CIRC_1) {
- double center_x = 2 * (1 + NB_CIRC_1) * (i - NB_CIRC_1 / 2);
- FOR_EACH(j, 0, NB_CIRC_1) {
- FOR_EACH(k, 0, NB_CIRC_1) {
- double center_y = 2 * (1 + NB_CIRC_1) * (j - NB_CIRC_1 / 2);
- m_in = (unsigned)k;
- m_out = (unsigned)(k + 1);
- ctx.scale = k + 1;
- d2(ctx.offset, center_x, center_y);
- CHK(senc2d_scene_add_geometry(scn, circ_seg_count, get_ctx_indices,
- get_ctx_media, circ_vrtx_count, get_ctx_position, NULL, NULL, &ctx)
- == RES_OK);
- }
- }
- }
- circle_release(&ctx);
+ /* Create the scene with NB_CIRC circles.
+ * There are NB_CIRC_X * NB_CIRC_Y imbrications of NB_CIRC_Z circles each.
+ * Each imbrication is located on a grid.
+ * The get_ctx_xxx getters have to retrieve the circle from the
+ * primitive and vertice indexes. */
time_current(&t0);
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ NB_CIRC * circ_seg_count, get_ctx_indices, get_ctx_media,
+ NB_CIRC * circ_vrtx_count, get_ctx_position, &ctx, &scn));
time_sub(&t0, time_current(&t1), &t0);
time_dump(&t0, TIME_MSEC | TIME_SEC | TIME_MIN, NULL, dump, sizeof(dump));
- printf("Scene analyzed in: %s\n", dump);
-
- /* dump_global(desc, "test2d_many_enclosures.obj"); */
+ printf("Scene created in: %s\n", dump);
+ circle_release(&ctx);
- CHK(senc2d_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ OK(senc2d_scene_get_vertices_count(scn, &count));
CHK(count == NB_CIRC * circ_vrtx_count);
- CHK(senc2d_descriptor_get_global_segments_count(desc, &count) == RES_OK);
+ OK(senc2d_scene_get_segments_count(scn, &count));
CHK(count == NB_CIRC * circ_seg_count);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &count) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
CHK(count == 1 + NB_CIRC);
-
FOR_EACH(e, 0, count) {
struct senc2d_enclosure* enclosure;
struct senc2d_enclosure_header header;
unsigned m;
- CHK(senc2d_descriptor_get_enclosure(desc, e, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
CHK(header.enclosed_media_count == 1);
- CHK(senc2d_enclosure_get_medium(enclosure, 0, &m) == RES_OK);
- CHK(header.segment_count ==
- (header.is_infinite /* Outermost enclosure: NB_CIRC_1*NB_CIRC_1 circles */
- ? NB_CIRC_1 * NB_CIRC_1 * circ_seg_count
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &m));
+ CHK(header.primitives_count ==
+ (header.is_infinite /* Outermost enclosure: NB_CIRC_X*NB_CIRC_Y circles */
+ ? NB_CIRC_X * NB_CIRC_Y * circ_seg_count
: (m == 0
- ? circ_seg_count /* Innermost enclosures: 1 circle */
+ ? circ_seg_count /* Innermost enclosures: 1 circles */
: 2 * circ_seg_count))); /* Other enclosures: 2 circles */
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enclosure));
}
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
check_memory_allocator(&allocator);
mem_shutdown_regular_allocator(&allocator);
diff --git a/src/test_senc2d_many_segments.c b/src/test_senc2d_many_segments.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2020 (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
@@ -13,77 +13,43 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This test is similar to test_senc2d_some_segments, but involves 4*2562560
+ * segments instead of 4*1054, thus making it impossible to define the geometry
+ * through static arrays. */
+
+#define NB_CIRC_X 2
+#define NB_CIRC_Y 1
+#define NB_CIRC_Z 1
+ /* 4 circles */
+#define NB_CIRC (NB_CIRC_X * NB_CIRC_Y * NB_CIRC_Z)
+
#include "senc2d.h"
#include "test_senc2d_utils.h"
+#include "test_senc2d_utils2.h"
-#include <rsys/double2.h>
-#include <rsys/stretchy_array.h>
#include <rsys/clock_time.h>
+#include <rsys/double2.h>
+#include <stdio.h>
#include <limits.h>
-static void
-get_ctx_indices(const unsigned iseg, unsigned ids[2], void* context)
-{
- struct context* ctx = context;
- (void)ctx;
- ASSERT(ids && ctx);
- ASSERT(2*iseg+1 < sa_size(ctx->indices));
- get_indices(iseg, ids, context);
-}
-
-static void
-get_ctx_position(const unsigned ivert, double pos[2], void* context)
-{
- struct context* ctx = context;
- (void)ctx;
- ASSERT(pos && ctx);
- ASSERT(2*ivert+1 < sa_size(ctx->positions));
- get_position(ivert, pos, context);
-}
-
-static void
-get_ctx_media(const unsigned iseg, unsigned medium[2], void* context)
-{
- struct context* ctx = context;
- (void)iseg;
- ASSERT(medium && ctx);
- medium[ctx->reverse_med ? 1 : 0] = *ctx->front_media;
- medium[ctx->reverse_med ? 0 : 1] = *ctx->back_media;
-}
-
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
- struct context ctx;
- unsigned m0 = 0, m1;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned m0 = 0;
unsigned count;
- unsigned circ_seg_count, circ_vrtx_count, i;
+ unsigned circ_seg_count, circ_vrtx_count, e;
char dump[64];
struct time t0, t1;
(void)argc, (void)argv;
- CHK(mem_init_regular_allocator(&allocator) == RES_OK);
- CHK(senc2d_device_create (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
+ OK(mem_init_regular_allocator(&allocator));
+ OK(senc2d_device_create (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
-#define NB_CIRC 4
- /* Create the scene */
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- ctx.positions = NULL;
- ctx.indices = NULL;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- ctx.back_media = &m0;
- ctx.front_media = &m1;
/* A 1,048,576 segments circle template */
create_circle(1, 1048576, &ctx);
ASSERT(sa_size(ctx.positions) % 2 == 0
@@ -92,45 +58,40 @@ main(int argc, char** argv)
&& sa_size(ctx.indices) / 2 < UINT_MAX);
circ_seg_count = (unsigned)sa_size(ctx.indices) / 2;
circ_vrtx_count = (unsigned)sa_size(ctx.positions) / 2;
- CHK(senc2d_scene_reserve(scn, NB_CIRC * circ_vrtx_count, NB_CIRC * circ_seg_count, 0)
- == RES_OK);
- FOR_EACH(i, 0, NB_CIRC) {
- m1 = i;
- d2(ctx.offset, 0, i * 10);
- CHK(senc2d_scene_add_geometry(scn, circ_seg_count, get_ctx_indices,
- get_ctx_media, circ_vrtx_count, get_ctx_position, NULL, NULL, &ctx)
- == RES_OK);
- }
- circle_release(&ctx);
+ /* Create the scene with 4 circles.
+ * The get_ctx_xxx getters have to retrieve the circle from the
+ * primitive and vertice indexes. */
+ ctx.back_media = &m0;
time_current(&t0);
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ NB_CIRC* circ_seg_count, get_ctx_indices, get_ctx_media,
+ NB_CIRC* circ_vrtx_count, get_ctx_position, &ctx, &scn));
time_sub(&t0, time_current(&t1), &t0);
time_dump(&t0, TIME_MSEC | TIME_SEC | TIME_MIN, NULL, dump, sizeof(dump));
- printf("Scene analyzed in: %s\n", dump);
-
- /* dump_global(desc, "test2d_many_segments.obj"); */
+ printf("Scene created in: %s\n", dump);
+ circle_release(&ctx);
- CHK(senc2d_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ OK(senc2d_scene_get_vertices_count(scn, &count));
CHK(count == NB_CIRC * circ_vrtx_count);
- CHK(senc2d_descriptor_get_global_segments_count(desc, &count) == RES_OK);
+ OK(senc2d_scene_get_segments_count(scn, &count));
CHK(count == NB_CIRC * circ_seg_count);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &count) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
CHK(count == 1 + NB_CIRC);
- FOR_EACH(i, 0, count) {
+ FOR_EACH(e, 0, count) {
struct senc2d_enclosure* enclosure;
struct senc2d_enclosure_header header;
- CHK(senc2d_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
- CHK(header.segment_count ==
- i ? circ_seg_count : NB_CIRC * circ_seg_count);
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
+ CHK(header.primitives_count ==
+ e ? circ_seg_count : NB_CIRC * circ_seg_count);
+ OK(senc2d_enclosure_ref_put(enclosure));
}
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
check_memory_allocator(&allocator);
mem_shutdown_regular_allocator(&allocator);
diff --git a/src/test_senc2d_sample_enclosure.c b/src/test_senc2d_sample_enclosure.c
@@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "senc2d.h"
-#include "senc2d_s2d_wrapper.h"
+#include "senc2d_sXd_helper.h"
#include "test_senc2d_utils.h"
#include <rsys/float2.h>
@@ -27,7 +27,6 @@ int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
struct senc2d_enclosure* enclosure = NULL;
@@ -39,74 +38,57 @@ main(int argc, char** argv)
struct s2d_primitive prim;
struct s2d_vertex_data vrtx_get;
struct ssp_rng* rng;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
int i;
- float s;
+ float st;
(void)argc, (void)argv;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
-
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- vrtx_get.type = S2D_FLOAT2;
- vrtx_get.usage = S2D_POSITION;
- vrtx_get.get = senc2d_enclosure_get_vertex__;
-
- S2D(device_create(NULL, &allocator, 0, &s2d));
-
- S2D(scene_create(s2d, &s2d_scn));
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
/* A 2D square, but with a hole (incomplete).
* 1 single enclosure including both sides of segments */
-
- ctx.positions = square_vertices; /* Need a true square */
+ ctx.positions = square_vertices;
ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
ctx.front_media = medium0;
ctx.back_media = medium0;
- CHK(senc2d_scene_add_geometry(scn, nsegments - 1, get_indices,
- get_media, nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments - 1, get_indices, get_media, nvertices, get_position, &ctx,
+ &scn));
- CHK(senc2d_descriptor_get_enclosure(desc, 0, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, 0, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
/* Put enclosure in a 2D view... */
+ vrtx_get.type = S2D_FLOAT2;
+ vrtx_get.usage = S2D_POSITION;
+ vrtx_get.get = senc2d_sXd_enclosure_get_position;
+ S2D(device_create(NULL, &allocator, 0, &s2d));
+ S2D(scene_create(s2d, &s2d_scn));
S2D(shape_create_line_segments(s2d, &s2d_shp));
- S2D(line_segments_setup_indexed_vertices(s2d_shp, header.segment_count,
- senc2d_enclosure_get_segment__, header.vertices_count, &vrtx_get, 1,
+ S2D(line_segments_setup_indexed_vertices(s2d_shp, header.primitives_count,
+ senc2d_sXd_enclosure_get_indices, header.vertices_count, &vrtx_get, 1,
enclosure));
-
S2D(scene_attach_shape(s2d_scn, s2d_shp));
-
S2D(scene_view_create(s2d_scn, S2D_SAMPLE, &s2d_view));
/* ... and sample it. */
- CHK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng) == RES_OK);
+ OK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng));
FOR_EACH(i, 0, 10000) {
struct s2d_attrib attrib;
int n, c;
- S2D(scene_view_sample(s2d_view,
- ssp_rng_canonical_float(rng),
- ssp_rng_canonical_float(rng),
- &prim, &s));
- S2D(primitive_get_attrib(&prim, S2D_POSITION, s, &attrib));
+ S2D(scene_view_sample(s2d_view, ssp_rng_canonical_float(rng),
+ ssp_rng_canonical_float(rng), &prim, &st));
+ S2D(primitive_get_attrib(&prim, S2D_POSITION, st, &attrib));
c = 0;
FOR_EACH(n, 0, 2)
if(eq_eps(attrib.value[n], 0, FLT_EPSILON)
|| eq_eps(attrib.value[n], 1, FLT_EPSILON))
c++;
CHK(c == 1);
- S2D(primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, s, &attrib));
+ S2D(primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, st, &attrib));
c = 0;
FOR_EACH(n, 0, 2)
if(eq_eps(attrib.value[n], -1, FLT_EPSILON)
@@ -123,7 +105,6 @@ main(int argc, char** argv)
SENC2D(enclosure_ref_put(enclosure));
SENC2D(scene_ref_put(scn));
SENC2D(device_ref_put(dev));
- SENC2D(descriptor_ref_put(desc));
SSP(rng_ref_put(rng));
diff --git a/src/test_senc2d_scene.c b/src/test_senc2d_scene.c
@@ -25,267 +25,268 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_enclosure* enc = NULL;
struct senc2d_enclosure_header header;
- struct context ctx;
- unsigned medfront[2], medback[2], ind[2];
+ struct context ctx = CONTEXT_NULL__;
+ unsigned medfront[2], medback[2], ind[2], ids[2];
double vrtx[2];
unsigned count, i, maxm;
int convention;
(void)argc, (void)argv;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev)
- == RES_OK);
-
- CHK(senc2d_scene_create(NULL,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_BAD_ARG);
- CHK(senc2d_scene_create(dev, 0, &scn) == RES_BAD_ARG);
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_scene_create(NULL, 0, &scn) == RES_BAD_ARG);
- CHK(senc2d_scene_create(NULL,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_scene_create(dev, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_create(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- CHK(senc2d_scene_reserve(NULL, 0, 0, 0) == RES_BAD_ARG);
- CHK(senc2d_scene_reserve(scn, 0, 0, 0) == RES_OK);
-
- CHK(senc2d_scene_get_convention(NULL, &convention) == RES_BAD_ARG);
- CHK(senc2d_scene_get_convention(scn, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_convention(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_convention(scn, &convention) == RES_OK);
- CHK(convention ==
- (SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE));
-
- CHK(senc2d_scene_get_segments_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_scene_get_segments_count(scn, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_segments_count(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_segments_count(scn, &count) == RES_OK);
- CHK(count == 0);
-
- CHK(senc2d_scene_get_unique_segments_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segments_count(scn, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segments_count(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segments_count(scn, &count) == RES_OK);
- CHK(count == 0);
-
- CHK(senc2d_scene_get_vertices_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_scene_get_vertices_count(scn, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_vertices_count(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_vertices_count(scn, &count) == RES_OK);
- CHK(count == 0);
-
- CHK(senc2d_scene_get_unique_vertices_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertices_count(scn, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertices_count(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertices_count(scn, &count) == RES_OK);
- CHK(count == 0);
-
- CHK(senc2d_scene_get_unique_sides_without_medium_count(NULL, &count)
- == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_sides_without_medium_count(scn, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_sides_without_medium_count(NULL, NULL)
- == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_sides_without_medium_count(scn, &count)
- == RES_OK);
- CHK(count == 0);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
- /* A 2D square
+ /* A 2D square.
* With this geometry front is inside with NORMAL_BACK convention,
* outside with NORMAL_FRONT convention */
ctx.positions = box_vertices;
ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
ctx.front_media = medium0;
ctx.back_media = medium1;
- CHK(senc2d_scene_add_geometry(NULL, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
- CHK(senc2d_scene_add_geometry(scn, 0, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
- CHK(senc2d_scene_add_geometry(scn, nsegments, NULL, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- 0, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, NULL, NULL, NULL, &ctx) == RES_BAD_ARG);
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_get_segments_count(scn, &count) == RES_OK);
+ BA(senc2d_scene_create(NULL,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc2d_scene_create(dev,
+ 0,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ 0, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, NULL, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ 0, get_position, &ctx, &scn));
+ BA(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, NULL, &ctx, &scn));
+ BA(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, NULL));
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ BA(senc2d_scene_get_convention(NULL, &convention));
+ BA(senc2d_scene_get_convention(scn, NULL));
+ BA(senc2d_scene_get_convention(NULL, NULL));
+ OK(senc2d_scene_get_convention(scn, &convention));
+ CHK(convention
+ == (SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE));
+
+ BA(senc2d_scene_get_segments_count(NULL, &count));
+ BA(senc2d_scene_get_segments_count(scn, NULL));
+ BA(senc2d_scene_get_segments_count(NULL, NULL));
+ OK(senc2d_scene_get_segments_count(scn, &count));
CHK(count == nsegments);
- CHK(senc2d_scene_get_unique_segments_count(scn, &count) == RES_OK);
- CHK(count == nsegments);
- CHK(senc2d_scene_get_vertices_count(scn, &count) == RES_OK);
- CHK(count == nvertices);
- CHK(senc2d_scene_get_unique_vertices_count(scn, &count) == RES_OK);
+
+ BA(senc2d_scene_get_vertices_count(NULL, &count));
+ BA(senc2d_scene_get_vertices_count(scn, NULL));
+ BA(senc2d_scene_get_vertices_count(NULL, NULL));
+ OK(senc2d_scene_get_vertices_count(scn, &count));
CHK(count == nvertices);
- CHK(senc2d_scene_get_unique_segment(NULL, 0, ind) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(scn, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(scn, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(NULL, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(scn, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment(scn, 0, ind) == RES_OK);
-
- CHK(senc2d_scene_get_unique_segment_media(NULL, 0, ind) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(scn, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(scn, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(NULL, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(scn, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_segment_media(scn, 0, ind) == RES_OK);
-
- CHK(senc2d_scene_get_unique_vertex(NULL, 0, vrtx) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(scn, UINT_MAX, vrtx) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(scn, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(NULL, UINT_MAX, vrtx) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(scn, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_get_unique_vertex(scn, 0, vrtx) == RES_OK);
-
- CHK(senc2d_scene_analyze(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_analyze(scn, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_analyze(NULL, &desc) == RES_BAD_ARG);
- CHK(senc2d_scene_analyze(NULL, NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_scene_ref_get(NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_ref_get(scn) == RES_OK);
- CHK(senc2d_scene_ref_put(NULL) == RES_BAD_ARG);
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
-
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
- CHK(senc2d_scene_get_convention(scn, &convention) == RES_OK);
- CHK(convention ==
- (SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE));
- /* Add the first segment twice to create a shift in numbering */
- CHK(senc2d_scene_add_geometry(scn, 1, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ BA(senc2d_scene_get_segment(NULL, 0, ind));
+ BA(senc2d_scene_get_segment(scn, UINT_MAX, ind));
+ BA(senc2d_scene_get_segment(scn, 0, NULL));
+ BA(senc2d_scene_get_segment(NULL, UINT_MAX, ind));
+ BA(senc2d_scene_get_segment(NULL, 0, NULL));
+ BA(senc2d_scene_get_segment(scn, UINT_MAX, NULL));
+ BA(senc2d_scene_get_segment(NULL, UINT_MAX, NULL));
+ OK(senc2d_scene_get_segment(scn, 0, ind));
+
+ BA(senc2d_scene_get_segment_media(NULL, 0, ind));
+ BA(senc2d_scene_get_segment_media(scn, UINT_MAX, ind));
+ BA(senc2d_scene_get_segment_media(scn, 0, NULL));
+ BA(senc2d_scene_get_segment_media(NULL, UINT_MAX, ind));
+ BA(senc2d_scene_get_segment_media(NULL, 0, NULL));
+ BA(senc2d_scene_get_segment_media(scn, UINT_MAX, NULL));
+ BA(senc2d_scene_get_segment_media(NULL, UINT_MAX, NULL));
+ OK(senc2d_scene_get_segment_media(scn, 0, ind));
+
+ BA(senc2d_scene_get_vertex(NULL, 0, vrtx));
+ BA(senc2d_scene_get_vertex(scn, UINT_MAX, vrtx));
+ BA(senc2d_scene_get_vertex(scn, 0, NULL));
+ BA(senc2d_scene_get_vertex(NULL, UINT_MAX, vrtx));
+ BA(senc2d_scene_get_vertex(NULL, 0, NULL));
+ BA(senc2d_scene_get_vertex(scn, UINT_MAX, NULL));
+ BA(senc2d_scene_get_vertex(NULL, UINT_MAX, NULL));
+ OK(senc2d_scene_get_vertex(scn, 0, vrtx));
+
+ BA(senc2d_scene_get_max_medium(NULL, &maxm));
+ BA(senc2d_scene_get_max_medium(scn, NULL));
+ BA(senc2d_scene_get_max_medium(NULL, NULL));
+ OK(senc2d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 1);
+
+ BA(senc2d_scene_get_enclosure_count(NULL, &count));
+ BA(senc2d_scene_get_enclosure_count(scn, NULL));
+ BA(senc2d_scene_get_enclosure_count(NULL, NULL));
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 2);
+
+ BA(senc2d_scene_get_enclosure_count_by_medium(NULL, 0, &count));
+ BA(senc2d_scene_get_enclosure_count_by_medium(scn, 100, &count));
+ BA(senc2d_scene_get_enclosure_count_by_medium(scn, 0, NULL));
+ BA(senc2d_scene_get_enclosure_count_by_medium(NULL, 100, &count));
+ BA(senc2d_scene_get_enclosure_count_by_medium(NULL, 0, NULL));
+ BA(senc2d_scene_get_enclosure_count_by_medium(scn, 100, NULL));
+ BA(senc2d_scene_get_enclosure_count_by_medium(NULL, 100, NULL));
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, 0, &count));
+ CHK(count == 1);
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, SENC2D_UNSPECIFIED_MEDIUM,
+ &count));
+ CHK(count == 0);
+
+ BA(senc2d_scene_get_enclosure(NULL, 0, &enc));
+ BA(senc2d_scene_get_enclosure(scn, UINT_MAX, &enc));
+ BA(senc2d_scene_get_enclosure(scn, 0, NULL));
+ BA(senc2d_scene_get_enclosure(NULL, UINT_MAX, &enc));
+ BA(senc2d_scene_get_enclosure(NULL, 0, NULL));
+ BA(senc2d_scene_get_enclosure(scn, UINT_MAX, NULL));
+ BA(senc2d_scene_get_enclosure(NULL, UINT_MAX, NULL));
+ OK(senc2d_scene_get_enclosure(scn, 0, &enc));
+ OK(senc2d_enclosure_ref_put(enc));
+
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 0, 0, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 100, 0, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 0, UINT_MAX, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 0, 0, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 100, 0, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 0, UINT_MAX, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 0, 0, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 100, UINT_MAX, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 100, 0, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 0, UINT_MAX, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, 100, UINT_MAX, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 0, UINT_MAX, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 100, 0, NULL));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 100, UINT_MAX, &enc));
+ BA(senc2d_scene_get_enclosure_by_medium(NULL, 100, UINT_MAX, NULL));
+ OK(senc2d_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
+ OK(senc2d_enclosure_ref_put(enc));
+ /* Index 0 is out of range for SENC2D_UNSPECIFIED_MEDIUM. */
+ BA(senc2d_scene_get_enclosure_by_medium(scn, SENC2D_UNSPECIFIED_MEDIUM, 0, &enc));
+
+ BA(senc2d_scene_get_segment_enclosures(NULL, 0, ids));
+ BA(senc2d_scene_get_segment_enclosures(scn, UINT_MAX, ids));
+ BA(senc2d_scene_get_segment_enclosures(scn, 0, NULL));
+ BA(senc2d_scene_get_segment_enclosures(NULL, UINT_MAX, ids));
+ BA(senc2d_scene_get_segment_enclosures(NULL, 0, NULL));
+ BA(senc2d_scene_get_segment_enclosures(scn, UINT_MAX, NULL));
+ BA(senc2d_scene_get_segment_enclosures(NULL, UINT_MAX, NULL));
+ OK(senc2d_scene_get_segment_enclosures(scn, 0, ids));
+
+ BA(senc2d_scene_get_frontier_vertice_count(NULL, &count));
+ BA(senc2d_scene_get_frontier_vertice_count(scn, NULL));
+ BA(senc2d_scene_get_frontier_vertice_count(NULL, NULL));
+ OK(senc2d_scene_get_frontier_vertice_count(scn, &count));
+ CHK(count == 0);
+
+ BA(senc2d_scene_get_frontier_vertex(NULL, 0, ids));
+ BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, ids));
+ BA(senc2d_scene_get_frontier_vertex(scn, 0, NULL));
+ BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, ids));
+ BA(senc2d_scene_get_frontier_vertex(NULL, 0, NULL));
+ BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, NULL));
+ BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, NULL));
+
+ BA(senc2d_scene_ref_get(NULL));
+ OK(senc2d_scene_ref_get(scn));
+ BA(senc2d_scene_ref_put(NULL));
+ OK(senc2d_scene_ref_put(scn));
+
+ OK(senc2d_scene_ref_put(scn));
+
+ /* Same geometry with SENC2D_UNSPECIFIED_MEDIUM */
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, NULL,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_by_medium(scn, SENC2D_UNSPECIFIED_MEDIUM, 0, &enc));
+ OK(senc2d_enclosure_ref_put(enc));
+ BA(senc2d_scene_get_enclosure_by_medium(scn, SENC2D_UNSPECIFIED_MEDIUM, 100, &enc));
+
+ OK(senc2d_scene_ref_put(scn));
+
+ /* Same geometry with a hole (1 missing segment) */
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments - 1, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_frontier_vertice_count(scn, &count));
+ CHK(count == 2);
+ OK(senc2d_scene_get_frontier_vertex(scn, 0, ids));
+ BA(senc2d_scene_get_frontier_vertex(scn, 3, ids));
+
+ OK(senc2d_scene_ref_put(scn));
+
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_convention(scn, &convention));
+ CHK(convention
+ == (SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE));
/* Check that medium 0 is inside */
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 0, &enc) == RES_OK);
- CHK(senc2d_enclosure_get_header(enc, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
+ OK(senc2d_enclosure_get_header(enc, &header));
CHK(!header.is_infinite);
- CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enc));
- FOR_EACH(i, 0, nsegments) {
- unsigned gid;
- CHK(senc2d_descriptor_get_global_segment_global_id(desc, i, &gid) == RES_OK);
- /* Check numbering shift */
- CHK(gid == (i ? i + 1 : 0));
- }
+ OK(senc2d_scene_get_segment_media(scn, 0, medback));
+ OK(senc2d_scene_ref_put(scn));
- CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medback) == RES_OK);
- ctx.front_media = medium1_3;
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
/* Medium mismatch between neighbour segments, but OK */
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ ctx.front_media = medium1_3;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ OK(senc2d_scene_get_max_medium(scn, &maxm));
CHK(maxm == 3);
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 0, &count) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, 0, &count));
CHK(count == 0); /* Medium 0 unused */
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 1, &count) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, 1, &count));
CHK(count == 2); /* Medium 1 used twice */
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 2, &count) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, 2, &count));
CHK(count == 0); /* Medium 2 unused */
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, 3, &count) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, 3, &count));
CHK(count == 1); /* Medium 3 used */
- check_desc(desc);
+
+ OK(senc2d_scene_ref_put(scn));
ctx.front_media = medium0;
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
- /* Add the first segment twice to create a shift in numbering */
- CHK(senc2d_scene_add_geometry(scn, 1, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ nsegments, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
/* Check that medium 0 is outside */
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 0, &enc) == RES_OK);
- CHK(senc2d_enclosure_get_header(enc, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
+ OK(senc2d_enclosure_get_header(enc, &header));
CHK(header.is_infinite);
- CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enc));
- FOR_EACH(i, 0, nsegments) {
- unsigned gid;
- CHK(senc2d_descriptor_get_global_segment_global_id(desc, i, &gid) == RES_OK);
- /* Check numbering shift */
- CHK(gid == (i ? i + 1 : 0));
- }
-
- CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medfront) == RES_OK);
+ OK(senc2d_scene_get_segment_media(scn, 0, medfront));
FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);
- /* Invalid vertex ID */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices - 1, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
-
- /* Incoherent medium on a duplicate segment */
- ctx.back_media = medium1_3;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_BAD_ARG);
-
- /* It is OK add geometry after a failed add */
- ctx.back_media = medium1;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- /* Coherent medium on duplicate segment */
- ctx.back_media = medium1;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- /* Coherent medium on duplicate segment V2 */
- ctx.reverse_med = 1;
- ctx.front_media = medium1;
- ctx.back_media = medium0;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- /* Coherent medium on duplicate segment V3 */
- ctx.reverse_med = 0;
- ctx.reverse_vrtx = 1;
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_senc2d_some_enclosures.c b/src/test_senc2d_some_enclosures.c
@@ -0,0 +1,3173 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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/>. */
+
+/* This test has been created using the sg2_geometry_dump_as_C_code feature
+ * of star-geometry-2D-2D. It uses output from test_sg2_some_enclosures.
+ * This test is similar to test_senc2d_many_enclosures that creates a huge
+ * geometry by program. */
+
+#include "senc2d.h"
+#include "test_senc2d_utils.h"
+
+#include <rsys/double2.h>
+
+/* Dump of star-geometry-2D 'some_enclosures'. */
+static const unsigned some_enclosures_vertices_count = 1024;
+static const double some_enclosures_vertices[2048] =
+{
+ -19, -20,
+ -19.0761, -19.6173,
+ -19.2929, -19.2929,
+ -19.6173, -19.0761,
+ -20, -19,
+ -20.3827, -19.0761,
+ -20.7071, -19.2929,
+ -20.9239, -19.6173,
+ -21, -20,
+ -20.9239, -20.3827,
+ -20.7071, -20.7071,
+ -20.3827, -20.9239,
+ -20, -21,
+ -19.6173, -20.9239,
+ -19.2929, -20.7071,
+ -19.0761, -20.3827,
+ -18, -20,
+ -18.1522, -19.2346,
+ -18.5858, -18.5858,
+ -19.2346, -18.1522,
+ -20, -18,
+ -20.7654, -18.1522,
+ -21.4142, -18.5858,
+ -21.8478, -19.2346,
+ -22, -20,
+ -21.8478, -20.7654,
+ -21.4142, -21.4142,
+ -20.7654, -21.8478,
+ -20, -22,
+ -19.2346, -21.8478,
+ -18.5858, -21.4142,
+ -18.1522, -20.7654,
+ -17, -20,
+ -17.2284, -18.8519,
+ -17.8787, -17.8787,
+ -18.8519, -17.2284,
+ -20, -17,
+ -21.1481, -17.2284,
+ -22.1213, -17.8787,
+ -22.7716, -18.8519,
+ -23, -20,
+ -22.7716, -21.1481,
+ -22.1213, -22.1213,
+ -21.1481, -22.7716,
+ -20, -23,
+ -18.8519, -22.7716,
+ -17.8787, -22.1213,
+ -17.2284, -21.1481,
+ -16, -20,
+ -16.3045, -18.4693,
+ -17.1716, -17.1716,
+ -18.4693, -16.3045,
+ -20, -16,
+ -21.5307, -16.3045,
+ -22.8284, -17.1716,
+ -23.6955, -18.4693,
+ -24, -20,
+ -23.6955, -21.5307,
+ -22.8284, -22.8284,
+ -21.5307, -23.6955,
+ -20, -24,
+ -18.4693, -23.6955,
+ -17.1716, -22.8284,
+ -16.3045, -21.5307,
+ -19, -10,
+ -19.0761, -9.61732,
+ -19.2929, -9.29289,
+ -19.6173, -9.07612,
+ -20, -9,
+ -20.3827, -9.07612,
+ -20.7071, -9.29289,
+ -20.9239, -9.61732,
+ -21, -10,
+ -20.9239, -10.3827,
+ -20.7071, -10.7071,
+ -20.3827, -10.9239,
+ -20, -11,
+ -19.6173, -10.9239,
+ -19.2929, -10.7071,
+ -19.0761, -10.3827,
+ -18, -10,
+ -18.1522, -9.23463,
+ -18.5858, -8.58579,
+ -19.2346, -8.15224,
+ -20, -8,
+ -20.7654, -8.15224,
+ -21.4142, -8.58579,
+ -21.8478, -9.23463,
+ -22, -10,
+ -21.8478, -10.7654,
+ -21.4142, -11.4142,
+ -20.7654, -11.8478,
+ -20, -12,
+ -19.2346, -11.8478,
+ -18.5858, -11.4142,
+ -18.1522, -10.7654,
+ -17, -10,
+ -17.2284, -8.85195,
+ -17.8787, -7.87868,
+ -18.8519, -7.22836,
+ -20, -7,
+ -21.1481, -7.22836,
+ -22.1213, -7.87868,
+ -22.7716, -8.85195,
+ -23, -10,
+ -22.7716, -11.1481,
+ -22.1213, -12.1213,
+ -21.1481, -12.7716,
+ -20, -13,
+ -18.8519, -12.7716,
+ -17.8787, -12.1213,
+ -17.2284, -11.1481,
+ -16, -10,
+ -16.3045, -8.46927,
+ -17.1716, -7.17157,
+ -18.4693, -6.30448,
+ -20, -6,
+ -21.5307, -6.30448,
+ -22.8284, -7.17157,
+ -23.6955, -8.46927,
+ -24, -10,
+ -23.6955, -11.5307,
+ -22.8284, -12.8284,
+ -21.5307, -13.6955,
+ -20, -14,
+ -18.4693, -13.6955,
+ -17.1716, -12.8284,
+ -16.3045, -11.5307,
+ -19, 0,
+ -19.0761, 0.382683,
+ -19.2929, 0.707107,
+ -19.6173, 0.92388,
+ -20, 1,
+ -20.3827, 0.92388,
+ -20.7071, 0.707107,
+ -20.9239, 0.382683,
+ -21, 1.22465e-16,
+ -20.9239, -0.382683,
+ -20.7071, -0.707107,
+ -20.3827, -0.92388,
+ -20, -1,
+ -19.6173, -0.92388,
+ -19.2929, -0.707107,
+ -19.0761, -0.382683,
+ -18, 0,
+ -18.1522, 0.765367,
+ -18.5858, 1.41421,
+ -19.2346, 1.84776,
+ -20, 2,
+ -20.7654, 1.84776,
+ -21.4142, 1.41421,
+ -21.8478, 0.765367,
+ -22, 2.44929e-16,
+ -21.8478, -0.765367,
+ -21.4142, -1.41421,
+ -20.7654, -1.84776,
+ -20, -2,
+ -19.2346, -1.84776,
+ -18.5858, -1.41421,
+ -18.1522, -0.765367,
+ -17, 0,
+ -17.2284, 1.14805,
+ -17.8787, 2.12132,
+ -18.8519, 2.77164,
+ -20, 3,
+ -21.1481, 2.77164,
+ -22.1213, 2.12132,
+ -22.7716, 1.14805,
+ -23, 3.67394e-16,
+ -22.7716, -1.14805,
+ -22.1213, -2.12132,
+ -21.1481, -2.77164,
+ -20, -3,
+ -18.8519, -2.77164,
+ -17.8787, -2.12132,
+ -17.2284, -1.14805,
+ -16, 0,
+ -16.3045, 1.53073,
+ -17.1716, 2.82843,
+ -18.4693, 3.69552,
+ -20, 4,
+ -21.5307, 3.69552,
+ -22.8284, 2.82843,
+ -23.6955, 1.53073,
+ -24, 4.89859e-16,
+ -23.6955, -1.53073,
+ -22.8284, -2.82843,
+ -21.5307, -3.69552,
+ -20, -4,
+ -18.4693, -3.69552,
+ -17.1716, -2.82843,
+ -16.3045, -1.53073,
+ -19, 10,
+ -19.0761, 10.3827,
+ -19.2929, 10.7071,
+ -19.6173, 10.9239,
+ -20, 11,
+ -20.3827, 10.9239,
+ -20.7071, 10.7071,
+ -20.9239, 10.3827,
+ -21, 10,
+ -20.9239, 9.61732,
+ -20.7071, 9.29289,
+ -20.3827, 9.07612,
+ -20, 9,
+ -19.6173, 9.07612,
+ -19.2929, 9.29289,
+ -19.0761, 9.61732,
+ -18, 10,
+ -18.1522, 10.7654,
+ -18.5858, 11.4142,
+ -19.2346, 11.8478,
+ -20, 12,
+ -20.7654, 11.8478,
+ -21.4142, 11.4142,
+ -21.8478, 10.7654,
+ -22, 10,
+ -21.8478, 9.23463,
+ -21.4142, 8.58579,
+ -20.7654, 8.15224,
+ -20, 8,
+ -19.2346, 8.15224,
+ -18.5858, 8.58579,
+ -18.1522, 9.23463,
+ -17, 10,
+ -17.2284, 11.1481,
+ -17.8787, 12.1213,
+ -18.8519, 12.7716,
+ -20, 13,
+ -21.1481, 12.7716,
+ -22.1213, 12.1213,
+ -22.7716, 11.1481,
+ -23, 10,
+ -22.7716, 8.85195,
+ -22.1213, 7.87868,
+ -21.1481, 7.22836,
+ -20, 7,
+ -18.8519, 7.22836,
+ -17.8787, 7.87868,
+ -17.2284, 8.85195,
+ -16, 10,
+ -16.3045, 11.5307,
+ -17.1716, 12.8284,
+ -18.4693, 13.6955,
+ -20, 14,
+ -21.5307, 13.6955,
+ -22.8284, 12.8284,
+ -23.6955, 11.5307,
+ -24, 10,
+ -23.6955, 8.46927,
+ -22.8284, 7.17157,
+ -21.5307, 6.30448,
+ -20, 6,
+ -18.4693, 6.30448,
+ -17.1716, 7.17157,
+ -16.3045, 8.46927,
+ -9, -20,
+ -9.07612, -19.6173,
+ -9.29289, -19.2929,
+ -9.61732, -19.0761,
+ -10, -19,
+ -10.3827, -19.0761,
+ -10.7071, -19.2929,
+ -10.9239, -19.6173,
+ -11, -20,
+ -10.9239, -20.3827,
+ -10.7071, -20.7071,
+ -10.3827, -20.9239,
+ -10, -21,
+ -9.61732, -20.9239,
+ -9.29289, -20.7071,
+ -9.07612, -20.3827,
+ -8, -20,
+ -8.15224, -19.2346,
+ -8.58579, -18.5858,
+ -9.23463, -18.1522,
+ -10, -18,
+ -10.7654, -18.1522,
+ -11.4142, -18.5858,
+ -11.8478, -19.2346,
+ -12, -20,
+ -11.8478, -20.7654,
+ -11.4142, -21.4142,
+ -10.7654, -21.8478,
+ -10, -22,
+ -9.23463, -21.8478,
+ -8.58579, -21.4142,
+ -8.15224, -20.7654,
+ -7, -20,
+ -7.22836, -18.8519,
+ -7.87868, -17.8787,
+ -8.85195, -17.2284,
+ -10, -17,
+ -11.1481, -17.2284,
+ -12.1213, -17.8787,
+ -12.7716, -18.8519,
+ -13, -20,
+ -12.7716, -21.1481,
+ -12.1213, -22.1213,
+ -11.1481, -22.7716,
+ -10, -23,
+ -8.85195, -22.7716,
+ -7.87868, -22.1213,
+ -7.22836, -21.1481,
+ -6, -20,
+ -6.30448, -18.4693,
+ -7.17157, -17.1716,
+ -8.46927, -16.3045,
+ -10, -16,
+ -11.5307, -16.3045,
+ -12.8284, -17.1716,
+ -13.6955, -18.4693,
+ -14, -20,
+ -13.6955, -21.5307,
+ -12.8284, -22.8284,
+ -11.5307, -23.6955,
+ -10, -24,
+ -8.46927, -23.6955,
+ -7.17157, -22.8284,
+ -6.30448, -21.5307,
+ -9, -10,
+ -9.07612, -9.61732,
+ -9.29289, -9.29289,
+ -9.61732, -9.07612,
+ -10, -9,
+ -10.3827, -9.07612,
+ -10.7071, -9.29289,
+ -10.9239, -9.61732,
+ -11, -10,
+ -10.9239, -10.3827,
+ -10.7071, -10.7071,
+ -10.3827, -10.9239,
+ -10, -11,
+ -9.61732, -10.9239,
+ -9.29289, -10.7071,
+ -9.07612, -10.3827,
+ -8, -10,
+ -8.15224, -9.23463,
+ -8.58579, -8.58579,
+ -9.23463, -8.15224,
+ -10, -8,
+ -10.7654, -8.15224,
+ -11.4142, -8.58579,
+ -11.8478, -9.23463,
+ -12, -10,
+ -11.8478, -10.7654,
+ -11.4142, -11.4142,
+ -10.7654, -11.8478,
+ -10, -12,
+ -9.23463, -11.8478,
+ -8.58579, -11.4142,
+ -8.15224, -10.7654,
+ -7, -10,
+ -7.22836, -8.85195,
+ -7.87868, -7.87868,
+ -8.85195, -7.22836,
+ -10, -7,
+ -11.1481, -7.22836,
+ -12.1213, -7.87868,
+ -12.7716, -8.85195,
+ -13, -10,
+ -12.7716, -11.1481,
+ -12.1213, -12.1213,
+ -11.1481, -12.7716,
+ -10, -13,
+ -8.85195, -12.7716,
+ -7.87868, -12.1213,
+ -7.22836, -11.1481,
+ -6, -10,
+ -6.30448, -8.46927,
+ -7.17157, -7.17157,
+ -8.46927, -6.30448,
+ -10, -6,
+ -11.5307, -6.30448,
+ -12.8284, -7.17157,
+ -13.6955, -8.46927,
+ -14, -10,
+ -13.6955, -11.5307,
+ -12.8284, -12.8284,
+ -11.5307, -13.6955,
+ -10, -14,
+ -8.46927, -13.6955,
+ -7.17157, -12.8284,
+ -6.30448, -11.5307,
+ -9, 0,
+ -9.07612, 0.382683,
+ -9.29289, 0.707107,
+ -9.61732, 0.92388,
+ -10, 1,
+ -10.3827, 0.92388,
+ -10.7071, 0.707107,
+ -10.9239, 0.382683,
+ -11, 1.22465e-16,
+ -10.9239, -0.382683,
+ -10.7071, -0.707107,
+ -10.3827, -0.92388,
+ -10, -1,
+ -9.61732, -0.92388,
+ -9.29289, -0.707107,
+ -9.07612, -0.382683,
+ -8, 0,
+ -8.15224, 0.765367,
+ -8.58579, 1.41421,
+ -9.23463, 1.84776,
+ -10, 2,
+ -10.7654, 1.84776,
+ -11.4142, 1.41421,
+ -11.8478, 0.765367,
+ -12, 2.44929e-16,
+ -11.8478, -0.765367,
+ -11.4142, -1.41421,
+ -10.7654, -1.84776,
+ -10, -2,
+ -9.23463, -1.84776,
+ -8.58579, -1.41421,
+ -8.15224, -0.765367,
+ -7, 0,
+ -7.22836, 1.14805,
+ -7.87868, 2.12132,
+ -8.85195, 2.77164,
+ -10, 3,
+ -11.1481, 2.77164,
+ -12.1213, 2.12132,
+ -12.7716, 1.14805,
+ -13, 3.67394e-16,
+ -12.7716, -1.14805,
+ -12.1213, -2.12132,
+ -11.1481, -2.77164,
+ -10, -3,
+ -8.85195, -2.77164,
+ -7.87868, -2.12132,
+ -7.22836, -1.14805,
+ -6, 0,
+ -6.30448, 1.53073,
+ -7.17157, 2.82843,
+ -8.46927, 3.69552,
+ -10, 4,
+ -11.5307, 3.69552,
+ -12.8284, 2.82843,
+ -13.6955, 1.53073,
+ -14, 4.89859e-16,
+ -13.6955, -1.53073,
+ -12.8284, -2.82843,
+ -11.5307, -3.69552,
+ -10, -4,
+ -8.46927, -3.69552,
+ -7.17157, -2.82843,
+ -6.30448, -1.53073,
+ -9, 10,
+ -9.07612, 10.3827,
+ -9.29289, 10.7071,
+ -9.61732, 10.9239,
+ -10, 11,
+ -10.3827, 10.9239,
+ -10.7071, 10.7071,
+ -10.9239, 10.3827,
+ -11, 10,
+ -10.9239, 9.61732,
+ -10.7071, 9.29289,
+ -10.3827, 9.07612,
+ -10, 9,
+ -9.61732, 9.07612,
+ -9.29289, 9.29289,
+ -9.07612, 9.61732,
+ -8, 10,
+ -8.15224, 10.7654,
+ -8.58579, 11.4142,
+ -9.23463, 11.8478,
+ -10, 12,
+ -10.7654, 11.8478,
+ -11.4142, 11.4142,
+ -11.8478, 10.7654,
+ -12, 10,
+ -11.8478, 9.23463,
+ -11.4142, 8.58579,
+ -10.7654, 8.15224,
+ -10, 8,
+ -9.23463, 8.15224,
+ -8.58579, 8.58579,
+ -8.15224, 9.23463,
+ -7, 10,
+ -7.22836, 11.1481,
+ -7.87868, 12.1213,
+ -8.85195, 12.7716,
+ -10, 13,
+ -11.1481, 12.7716,
+ -12.1213, 12.1213,
+ -12.7716, 11.1481,
+ -13, 10,
+ -12.7716, 8.85195,
+ -12.1213, 7.87868,
+ -11.1481, 7.22836,
+ -10, 7,
+ -8.85195, 7.22836,
+ -7.87868, 7.87868,
+ -7.22836, 8.85195,
+ -6, 10,
+ -6.30448, 11.5307,
+ -7.17157, 12.8284,
+ -8.46927, 13.6955,
+ -10, 14,
+ -11.5307, 13.6955,
+ -12.8284, 12.8284,
+ -13.6955, 11.5307,
+ -14, 10,
+ -13.6955, 8.46927,
+ -12.8284, 7.17157,
+ -11.5307, 6.30448,
+ -10, 6,
+ -8.46927, 6.30448,
+ -7.17157, 7.17157,
+ -6.30448, 8.46927,
+ 1, -20,
+ 0.92388, -19.6173,
+ 0.707107, -19.2929,
+ 0.382683, -19.0761,
+ 6.12323e-17, -19,
+ -0.382683, -19.0761,
+ -0.707107, -19.2929,
+ -0.92388, -19.6173,
+ -1, -20,
+ -0.92388, -20.3827,
+ -0.707107, -20.7071,
+ -0.382683, -20.9239,
+ -1.83697e-16, -21,
+ 0.382683, -20.9239,
+ 0.707107, -20.7071,
+ 0.92388, -20.3827,
+ 2, -20,
+ 1.84776, -19.2346,
+ 1.41421, -18.5858,
+ 0.765367, -18.1522,
+ 1.22465e-16, -18,
+ -0.765367, -18.1522,
+ -1.41421, -18.5858,
+ -1.84776, -19.2346,
+ -2, -20,
+ -1.84776, -20.7654,
+ -1.41421, -21.4142,
+ -0.765367, -21.8478,
+ -3.67394e-16, -22,
+ 0.765367, -21.8478,
+ 1.41421, -21.4142,
+ 1.84776, -20.7654,
+ 3, -20,
+ 2.77164, -18.8519,
+ 2.12132, -17.8787,
+ 1.14805, -17.2284,
+ 1.83697e-16, -17,
+ -1.14805, -17.2284,
+ -2.12132, -17.8787,
+ -2.77164, -18.8519,
+ -3, -20,
+ -2.77164, -21.1481,
+ -2.12132, -22.1213,
+ -1.14805, -22.7716,
+ -5.51091e-16, -23,
+ 1.14805, -22.7716,
+ 2.12132, -22.1213,
+ 2.77164, -21.1481,
+ 4, -20,
+ 3.69552, -18.4693,
+ 2.82843, -17.1716,
+ 1.53073, -16.3045,
+ 2.44929e-16, -16,
+ -1.53073, -16.3045,
+ -2.82843, -17.1716,
+ -3.69552, -18.4693,
+ -4, -20,
+ -3.69552, -21.5307,
+ -2.82843, -22.8284,
+ -1.53073, -23.6955,
+ -7.34788e-16, -24,
+ 1.53073, -23.6955,
+ 2.82843, -22.8284,
+ 3.69552, -21.5307,
+ 1, -10,
+ 0.92388, -9.61732,
+ 0.707107, -9.29289,
+ 0.382683, -9.07612,
+ 6.12323e-17, -9,
+ -0.382683, -9.07612,
+ -0.707107, -9.29289,
+ -0.92388, -9.61732,
+ -1, -10,
+ -0.92388, -10.3827,
+ -0.707107, -10.7071,
+ -0.382683, -10.9239,
+ -1.83697e-16, -11,
+ 0.382683, -10.9239,
+ 0.707107, -10.7071,
+ 0.92388, -10.3827,
+ 2, -10,
+ 1.84776, -9.23463,
+ 1.41421, -8.58579,
+ 0.765367, -8.15224,
+ 1.22465e-16, -8,
+ -0.765367, -8.15224,
+ -1.41421, -8.58579,
+ -1.84776, -9.23463,
+ -2, -10,
+ -1.84776, -10.7654,
+ -1.41421, -11.4142,
+ -0.765367, -11.8478,
+ -3.67394e-16, -12,
+ 0.765367, -11.8478,
+ 1.41421, -11.4142,
+ 1.84776, -10.7654,
+ 3, -10,
+ 2.77164, -8.85195,
+ 2.12132, -7.87868,
+ 1.14805, -7.22836,
+ 1.83697e-16, -7,
+ -1.14805, -7.22836,
+ -2.12132, -7.87868,
+ -2.77164, -8.85195,
+ -3, -10,
+ -2.77164, -11.1481,
+ -2.12132, -12.1213,
+ -1.14805, -12.7716,
+ -5.51091e-16, -13,
+ 1.14805, -12.7716,
+ 2.12132, -12.1213,
+ 2.77164, -11.1481,
+ 4, -10,
+ 3.69552, -8.46927,
+ 2.82843, -7.17157,
+ 1.53073, -6.30448,
+ 2.44929e-16, -6,
+ -1.53073, -6.30448,
+ -2.82843, -7.17157,
+ -3.69552, -8.46927,
+ -4, -10,
+ -3.69552, -11.5307,
+ -2.82843, -12.8284,
+ -1.53073, -13.6955,
+ -7.34788e-16, -14,
+ 1.53073, -13.6955,
+ 2.82843, -12.8284,
+ 3.69552, -11.5307,
+ 1, 0,
+ 0.92388, 0.382683,
+ 0.707107, 0.707107,
+ 0.382683, 0.92388,
+ 6.12323e-17, 1,
+ -0.382683, 0.92388,
+ -0.707107, 0.707107,
+ -0.92388, 0.382683,
+ -1, 1.22465e-16,
+ -0.92388, -0.382683,
+ -0.707107, -0.707107,
+ -0.382683, -0.92388,
+ -1.83697e-16, -1,
+ 0.382683, -0.92388,
+ 0.707107, -0.707107,
+ 0.92388, -0.382683,
+ 2, 0,
+ 1.84776, 0.765367,
+ 1.41421, 1.41421,
+ 0.765367, 1.84776,
+ 1.22465e-16, 2,
+ -0.765367, 1.84776,
+ -1.41421, 1.41421,
+ -1.84776, 0.765367,
+ -2, 2.44929e-16,
+ -1.84776, -0.765367,
+ -1.41421, -1.41421,
+ -0.765367, -1.84776,
+ -3.67394e-16, -2,
+ 0.765367, -1.84776,
+ 1.41421, -1.41421,
+ 1.84776, -0.765367,
+ 3, 0,
+ 2.77164, 1.14805,
+ 2.12132, 2.12132,
+ 1.14805, 2.77164,
+ 1.83697e-16, 3,
+ -1.14805, 2.77164,
+ -2.12132, 2.12132,
+ -2.77164, 1.14805,
+ -3, 3.67394e-16,
+ -2.77164, -1.14805,
+ -2.12132, -2.12132,
+ -1.14805, -2.77164,
+ -5.51091e-16, -3,
+ 1.14805, -2.77164,
+ 2.12132, -2.12132,
+ 2.77164, -1.14805,
+ 4, 0,
+ 3.69552, 1.53073,
+ 2.82843, 2.82843,
+ 1.53073, 3.69552,
+ 2.44929e-16, 4,
+ -1.53073, 3.69552,
+ -2.82843, 2.82843,
+ -3.69552, 1.53073,
+ -4, 4.89859e-16,
+ -3.69552, -1.53073,
+ -2.82843, -2.82843,
+ -1.53073, -3.69552,
+ -7.34788e-16, -4,
+ 1.53073, -3.69552,
+ 2.82843, -2.82843,
+ 3.69552, -1.53073,
+ 1, 10,
+ 0.92388, 10.3827,
+ 0.707107, 10.7071,
+ 0.382683, 10.9239,
+ 6.12323e-17, 11,
+ -0.382683, 10.9239,
+ -0.707107, 10.7071,
+ -0.92388, 10.3827,
+ -1, 10,
+ -0.92388, 9.61732,
+ -0.707107, 9.29289,
+ -0.382683, 9.07612,
+ -1.83697e-16, 9,
+ 0.382683, 9.07612,
+ 0.707107, 9.29289,
+ 0.92388, 9.61732,
+ 2, 10,
+ 1.84776, 10.7654,
+ 1.41421, 11.4142,
+ 0.765367, 11.8478,
+ 1.22465e-16, 12,
+ -0.765367, 11.8478,
+ -1.41421, 11.4142,
+ -1.84776, 10.7654,
+ -2, 10,
+ -1.84776, 9.23463,
+ -1.41421, 8.58579,
+ -0.765367, 8.15224,
+ -3.67394e-16, 8,
+ 0.765367, 8.15224,
+ 1.41421, 8.58579,
+ 1.84776, 9.23463,
+ 3, 10,
+ 2.77164, 11.1481,
+ 2.12132, 12.1213,
+ 1.14805, 12.7716,
+ 1.83697e-16, 13,
+ -1.14805, 12.7716,
+ -2.12132, 12.1213,
+ -2.77164, 11.1481,
+ -3, 10,
+ -2.77164, 8.85195,
+ -2.12132, 7.87868,
+ -1.14805, 7.22836,
+ -5.51091e-16, 7,
+ 1.14805, 7.22836,
+ 2.12132, 7.87868,
+ 2.77164, 8.85195,
+ 4, 10,
+ 3.69552, 11.5307,
+ 2.82843, 12.8284,
+ 1.53073, 13.6955,
+ 2.44929e-16, 14,
+ -1.53073, 13.6955,
+ -2.82843, 12.8284,
+ -3.69552, 11.5307,
+ -4, 10,
+ -3.69552, 8.46927,
+ -2.82843, 7.17157,
+ -1.53073, 6.30448,
+ -7.34788e-16, 6,
+ 1.53073, 6.30448,
+ 2.82843, 7.17157,
+ 3.69552, 8.46927,
+ 11, -20,
+ 10.9239, -19.6173,
+ 10.7071, -19.2929,
+ 10.3827, -19.0761,
+ 10, -19,
+ 9.61732, -19.0761,
+ 9.29289, -19.2929,
+ 9.07612, -19.6173,
+ 9, -20,
+ 9.07612, -20.3827,
+ 9.29289, -20.7071,
+ 9.61732, -20.9239,
+ 10, -21,
+ 10.3827, -20.9239,
+ 10.7071, -20.7071,
+ 10.9239, -20.3827,
+ 12, -20,
+ 11.8478, -19.2346,
+ 11.4142, -18.5858,
+ 10.7654, -18.1522,
+ 10, -18,
+ 9.23463, -18.1522,
+ 8.58579, -18.5858,
+ 8.15224, -19.2346,
+ 8, -20,
+ 8.15224, -20.7654,
+ 8.58579, -21.4142,
+ 9.23463, -21.8478,
+ 10, -22,
+ 10.7654, -21.8478,
+ 11.4142, -21.4142,
+ 11.8478, -20.7654,
+ 13, -20,
+ 12.7716, -18.8519,
+ 12.1213, -17.8787,
+ 11.1481, -17.2284,
+ 10, -17,
+ 8.85195, -17.2284,
+ 7.87868, -17.8787,
+ 7.22836, -18.8519,
+ 7, -20,
+ 7.22836, -21.1481,
+ 7.87868, -22.1213,
+ 8.85195, -22.7716,
+ 10, -23,
+ 11.1481, -22.7716,
+ 12.1213, -22.1213,
+ 12.7716, -21.1481,
+ 14, -20,
+ 13.6955, -18.4693,
+ 12.8284, -17.1716,
+ 11.5307, -16.3045,
+ 10, -16,
+ 8.46927, -16.3045,
+ 7.17157, -17.1716,
+ 6.30448, -18.4693,
+ 6, -20,
+ 6.30448, -21.5307,
+ 7.17157, -22.8284,
+ 8.46927, -23.6955,
+ 10, -24,
+ 11.5307, -23.6955,
+ 12.8284, -22.8284,
+ 13.6955, -21.5307,
+ 11, -10,
+ 10.9239, -9.61732,
+ 10.7071, -9.29289,
+ 10.3827, -9.07612,
+ 10, -9,
+ 9.61732, -9.07612,
+ 9.29289, -9.29289,
+ 9.07612, -9.61732,
+ 9, -10,
+ 9.07612, -10.3827,
+ 9.29289, -10.7071,
+ 9.61732, -10.9239,
+ 10, -11,
+ 10.3827, -10.9239,
+ 10.7071, -10.7071,
+ 10.9239, -10.3827,
+ 12, -10,
+ 11.8478, -9.23463,
+ 11.4142, -8.58579,
+ 10.7654, -8.15224,
+ 10, -8,
+ 9.23463, -8.15224,
+ 8.58579, -8.58579,
+ 8.15224, -9.23463,
+ 8, -10,
+ 8.15224, -10.7654,
+ 8.58579, -11.4142,
+ 9.23463, -11.8478,
+ 10, -12,
+ 10.7654, -11.8478,
+ 11.4142, -11.4142,
+ 11.8478, -10.7654,
+ 13, -10,
+ 12.7716, -8.85195,
+ 12.1213, -7.87868,
+ 11.1481, -7.22836,
+ 10, -7,
+ 8.85195, -7.22836,
+ 7.87868, -7.87868,
+ 7.22836, -8.85195,
+ 7, -10,
+ 7.22836, -11.1481,
+ 7.87868, -12.1213,
+ 8.85195, -12.7716,
+ 10, -13,
+ 11.1481, -12.7716,
+ 12.1213, -12.1213,
+ 12.7716, -11.1481,
+ 14, -10,
+ 13.6955, -8.46927,
+ 12.8284, -7.17157,
+ 11.5307, -6.30448,
+ 10, -6,
+ 8.46927, -6.30448,
+ 7.17157, -7.17157,
+ 6.30448, -8.46927,
+ 6, -10,
+ 6.30448, -11.5307,
+ 7.17157, -12.8284,
+ 8.46927, -13.6955,
+ 10, -14,
+ 11.5307, -13.6955,
+ 12.8284, -12.8284,
+ 13.6955, -11.5307,
+ 11, 0,
+ 10.9239, 0.382683,
+ 10.7071, 0.707107,
+ 10.3827, 0.92388,
+ 10, 1,
+ 9.61732, 0.92388,
+ 9.29289, 0.707107,
+ 9.07612, 0.382683,
+ 9, 1.22465e-16,
+ 9.07612, -0.382683,
+ 9.29289, -0.707107,
+ 9.61732, -0.92388,
+ 10, -1,
+ 10.3827, -0.92388,
+ 10.7071, -0.707107,
+ 10.9239, -0.382683,
+ 12, 0,
+ 11.8478, 0.765367,
+ 11.4142, 1.41421,
+ 10.7654, 1.84776,
+ 10, 2,
+ 9.23463, 1.84776,
+ 8.58579, 1.41421,
+ 8.15224, 0.765367,
+ 8, 2.44929e-16,
+ 8.15224, -0.765367,
+ 8.58579, -1.41421,
+ 9.23463, -1.84776,
+ 10, -2,
+ 10.7654, -1.84776,
+ 11.4142, -1.41421,
+ 11.8478, -0.765367,
+ 13, 0,
+ 12.7716, 1.14805,
+ 12.1213, 2.12132,
+ 11.1481, 2.77164,
+ 10, 3,
+ 8.85195, 2.77164,
+ 7.87868, 2.12132,
+ 7.22836, 1.14805,
+ 7, 3.67394e-16,
+ 7.22836, -1.14805,
+ 7.87868, -2.12132,
+ 8.85195, -2.77164,
+ 10, -3,
+ 11.1481, -2.77164,
+ 12.1213, -2.12132,
+ 12.7716, -1.14805,
+ 14, 0,
+ 13.6955, 1.53073,
+ 12.8284, 2.82843,
+ 11.5307, 3.69552,
+ 10, 4,
+ 8.46927, 3.69552,
+ 7.17157, 2.82843,
+ 6.30448, 1.53073,
+ 6, 4.89859e-16,
+ 6.30448, -1.53073,
+ 7.17157, -2.82843,
+ 8.46927, -3.69552,
+ 10, -4,
+ 11.5307, -3.69552,
+ 12.8284, -2.82843,
+ 13.6955, -1.53073,
+ 11, 10,
+ 10.9239, 10.3827,
+ 10.7071, 10.7071,
+ 10.3827, 10.9239,
+ 10, 11,
+ 9.61732, 10.9239,
+ 9.29289, 10.7071,
+ 9.07612, 10.3827,
+ 9, 10,
+ 9.07612, 9.61732,
+ 9.29289, 9.29289,
+ 9.61732, 9.07612,
+ 10, 9,
+ 10.3827, 9.07612,
+ 10.7071, 9.29289,
+ 10.9239, 9.61732,
+ 12, 10,
+ 11.8478, 10.7654,
+ 11.4142, 11.4142,
+ 10.7654, 11.8478,
+ 10, 12,
+ 9.23463, 11.8478,
+ 8.58579, 11.4142,
+ 8.15224, 10.7654,
+ 8, 10,
+ 8.15224, 9.23463,
+ 8.58579, 8.58579,
+ 9.23463, 8.15224,
+ 10, 8,
+ 10.7654, 8.15224,
+ 11.4142, 8.58579,
+ 11.8478, 9.23463,
+ 13, 10,
+ 12.7716, 11.1481,
+ 12.1213, 12.1213,
+ 11.1481, 12.7716,
+ 10, 13,
+ 8.85195, 12.7716,
+ 7.87868, 12.1213,
+ 7.22836, 11.1481,
+ 7, 10,
+ 7.22836, 8.85195,
+ 7.87868, 7.87868,
+ 8.85195, 7.22836,
+ 10, 7,
+ 11.1481, 7.22836,
+ 12.1213, 7.87868,
+ 12.7716, 8.85195,
+ 14, 10,
+ 13.6955, 11.5307,
+ 12.8284, 12.8284,
+ 11.5307, 13.6955,
+ 10, 14,
+ 8.46927, 13.6955,
+ 7.17157, 12.8284,
+ 6.30448, 11.5307,
+ 6, 10,
+ 6.30448, 8.46927,
+ 7.17157, 7.17157,
+ 8.46927, 6.30448,
+ 10, 6,
+ 11.5307, 6.30448,
+ 12.8284, 7.17157,
+ 13.6955, 8.46927
+};
+static const unsigned some_enclosures_segments_count = 1024;
+static const unsigned some_enclosures_segments[2048] =
+{
+ 0, 1,
+ 1, 2,
+ 2, 3,
+ 3, 4,
+ 4, 5,
+ 5, 6,
+ 6, 7,
+ 7, 8,
+ 8, 9,
+ 9, 10,
+ 10, 11,
+ 11, 12,
+ 12, 13,
+ 13, 14,
+ 14, 15,
+ 15, 0,
+ 16, 17,
+ 17, 18,
+ 18, 19,
+ 19, 20,
+ 20, 21,
+ 21, 22,
+ 22, 23,
+ 23, 24,
+ 24, 25,
+ 25, 26,
+ 26, 27,
+ 27, 28,
+ 28, 29,
+ 29, 30,
+ 30, 31,
+ 31, 16,
+ 32, 33,
+ 33, 34,
+ 34, 35,
+ 35, 36,
+ 36, 37,
+ 37, 38,
+ 38, 39,
+ 39, 40,
+ 40, 41,
+ 41, 42,
+ 42, 43,
+ 43, 44,
+ 44, 45,
+ 45, 46,
+ 46, 47,
+ 47, 32,
+ 48, 49,
+ 49, 50,
+ 50, 51,
+ 51, 52,
+ 52, 53,
+ 53, 54,
+ 54, 55,
+ 55, 56,
+ 56, 57,
+ 57, 58,
+ 58, 59,
+ 59, 60,
+ 60, 61,
+ 61, 62,
+ 62, 63,
+ 63, 48,
+ 64, 65,
+ 65, 66,
+ 66, 67,
+ 67, 68,
+ 68, 69,
+ 69, 70,
+ 70, 71,
+ 71, 72,
+ 72, 73,
+ 73, 74,
+ 74, 75,
+ 75, 76,
+ 76, 77,
+ 77, 78,
+ 78, 79,
+ 79, 64,
+ 80, 81,
+ 81, 82,
+ 82, 83,
+ 83, 84,
+ 84, 85,
+ 85, 86,
+ 86, 87,
+ 87, 88,
+ 88, 89,
+ 89, 90,
+ 90, 91,
+ 91, 92,
+ 92, 93,
+ 93, 94,
+ 94, 95,
+ 95, 80,
+ 96, 97,
+ 97, 98,
+ 98, 99,
+ 99, 100,
+ 100, 101,
+ 101, 102,
+ 102, 103,
+ 103, 104,
+ 104, 105,
+ 105, 106,
+ 106, 107,
+ 107, 108,
+ 108, 109,
+ 109, 110,
+ 110, 111,
+ 111, 96,
+ 112, 113,
+ 113, 114,
+ 114, 115,
+ 115, 116,
+ 116, 117,
+ 117, 118,
+ 118, 119,
+ 119, 120,
+ 120, 121,
+ 121, 122,
+ 122, 123,
+ 123, 124,
+ 124, 125,
+ 125, 126,
+ 126, 127,
+ 127, 112,
+ 128, 129,
+ 129, 130,
+ 130, 131,
+ 131, 132,
+ 132, 133,
+ 133, 134,
+ 134, 135,
+ 135, 136,
+ 136, 137,
+ 137, 138,
+ 138, 139,
+ 139, 140,
+ 140, 141,
+ 141, 142,
+ 142, 143,
+ 143, 128,
+ 144, 145,
+ 145, 146,
+ 146, 147,
+ 147, 148,
+ 148, 149,
+ 149, 150,
+ 150, 151,
+ 151, 152,
+ 152, 153,
+ 153, 154,
+ 154, 155,
+ 155, 156,
+ 156, 157,
+ 157, 158,
+ 158, 159,
+ 159, 144,
+ 160, 161,
+ 161, 162,
+ 162, 163,
+ 163, 164,
+ 164, 165,
+ 165, 166,
+ 166, 167,
+ 167, 168,
+ 168, 169,
+ 169, 170,
+ 170, 171,
+ 171, 172,
+ 172, 173,
+ 173, 174,
+ 174, 175,
+ 175, 160,
+ 176, 177,
+ 177, 178,
+ 178, 179,
+ 179, 180,
+ 180, 181,
+ 181, 182,
+ 182, 183,
+ 183, 184,
+ 184, 185,
+ 185, 186,
+ 186, 187,
+ 187, 188,
+ 188, 189,
+ 189, 190,
+ 190, 191,
+ 191, 176,
+ 192, 193,
+ 193, 194,
+ 194, 195,
+ 195, 196,
+ 196, 197,
+ 197, 198,
+ 198, 199,
+ 199, 200,
+ 200, 201,
+ 201, 202,
+ 202, 203,
+ 203, 204,
+ 204, 205,
+ 205, 206,
+ 206, 207,
+ 207, 192,
+ 208, 209,
+ 209, 210,
+ 210, 211,
+ 211, 212,
+ 212, 213,
+ 213, 214,
+ 214, 215,
+ 215, 216,
+ 216, 217,
+ 217, 218,
+ 218, 219,
+ 219, 220,
+ 220, 221,
+ 221, 222,
+ 222, 223,
+ 223, 208,
+ 224, 225,
+ 225, 226,
+ 226, 227,
+ 227, 228,
+ 228, 229,
+ 229, 230,
+ 230, 231,
+ 231, 232,
+ 232, 233,
+ 233, 234,
+ 234, 235,
+ 235, 236,
+ 236, 237,
+ 237, 238,
+ 238, 239,
+ 239, 224,
+ 240, 241,
+ 241, 242,
+ 242, 243,
+ 243, 244,
+ 244, 245,
+ 245, 246,
+ 246, 247,
+ 247, 248,
+ 248, 249,
+ 249, 250,
+ 250, 251,
+ 251, 252,
+ 252, 253,
+ 253, 254,
+ 254, 255,
+ 255, 240,
+ 256, 257,
+ 257, 258,
+ 258, 259,
+ 259, 260,
+ 260, 261,
+ 261, 262,
+ 262, 263,
+ 263, 264,
+ 264, 265,
+ 265, 266,
+ 266, 267,
+ 267, 268,
+ 268, 269,
+ 269, 270,
+ 270, 271,
+ 271, 256,
+ 272, 273,
+ 273, 274,
+ 274, 275,
+ 275, 276,
+ 276, 277,
+ 277, 278,
+ 278, 279,
+ 279, 280,
+ 280, 281,
+ 281, 282,
+ 282, 283,
+ 283, 284,
+ 284, 285,
+ 285, 286,
+ 286, 287,
+ 287, 272,
+ 288, 289,
+ 289, 290,
+ 290, 291,
+ 291, 292,
+ 292, 293,
+ 293, 294,
+ 294, 295,
+ 295, 296,
+ 296, 297,
+ 297, 298,
+ 298, 299,
+ 299, 300,
+ 300, 301,
+ 301, 302,
+ 302, 303,
+ 303, 288,
+ 304, 305,
+ 305, 306,
+ 306, 307,
+ 307, 308,
+ 308, 309,
+ 309, 310,
+ 310, 311,
+ 311, 312,
+ 312, 313,
+ 313, 314,
+ 314, 315,
+ 315, 316,
+ 316, 317,
+ 317, 318,
+ 318, 319,
+ 319, 304,
+ 320, 321,
+ 321, 322,
+ 322, 323,
+ 323, 324,
+ 324, 325,
+ 325, 326,
+ 326, 327,
+ 327, 328,
+ 328, 329,
+ 329, 330,
+ 330, 331,
+ 331, 332,
+ 332, 333,
+ 333, 334,
+ 334, 335,
+ 335, 320,
+ 336, 337,
+ 337, 338,
+ 338, 339,
+ 339, 340,
+ 340, 341,
+ 341, 342,
+ 342, 343,
+ 343, 344,
+ 344, 345,
+ 345, 346,
+ 346, 347,
+ 347, 348,
+ 348, 349,
+ 349, 350,
+ 350, 351,
+ 351, 336,
+ 352, 353,
+ 353, 354,
+ 354, 355,
+ 355, 356,
+ 356, 357,
+ 357, 358,
+ 358, 359,
+ 359, 360,
+ 360, 361,
+ 361, 362,
+ 362, 363,
+ 363, 364,
+ 364, 365,
+ 365, 366,
+ 366, 367,
+ 367, 352,
+ 368, 369,
+ 369, 370,
+ 370, 371,
+ 371, 372,
+ 372, 373,
+ 373, 374,
+ 374, 375,
+ 375, 376,
+ 376, 377,
+ 377, 378,
+ 378, 379,
+ 379, 380,
+ 380, 381,
+ 381, 382,
+ 382, 383,
+ 383, 368,
+ 384, 385,
+ 385, 386,
+ 386, 387,
+ 387, 388,
+ 388, 389,
+ 389, 390,
+ 390, 391,
+ 391, 392,
+ 392, 393,
+ 393, 394,
+ 394, 395,
+ 395, 396,
+ 396, 397,
+ 397, 398,
+ 398, 399,
+ 399, 384,
+ 400, 401,
+ 401, 402,
+ 402, 403,
+ 403, 404,
+ 404, 405,
+ 405, 406,
+ 406, 407,
+ 407, 408,
+ 408, 409,
+ 409, 410,
+ 410, 411,
+ 411, 412,
+ 412, 413,
+ 413, 414,
+ 414, 415,
+ 415, 400,
+ 416, 417,
+ 417, 418,
+ 418, 419,
+ 419, 420,
+ 420, 421,
+ 421, 422,
+ 422, 423,
+ 423, 424,
+ 424, 425,
+ 425, 426,
+ 426, 427,
+ 427, 428,
+ 428, 429,
+ 429, 430,
+ 430, 431,
+ 431, 416,
+ 432, 433,
+ 433, 434,
+ 434, 435,
+ 435, 436,
+ 436, 437,
+ 437, 438,
+ 438, 439,
+ 439, 440,
+ 440, 441,
+ 441, 442,
+ 442, 443,
+ 443, 444,
+ 444, 445,
+ 445, 446,
+ 446, 447,
+ 447, 432,
+ 448, 449,
+ 449, 450,
+ 450, 451,
+ 451, 452,
+ 452, 453,
+ 453, 454,
+ 454, 455,
+ 455, 456,
+ 456, 457,
+ 457, 458,
+ 458, 459,
+ 459, 460,
+ 460, 461,
+ 461, 462,
+ 462, 463,
+ 463, 448,
+ 464, 465,
+ 465, 466,
+ 466, 467,
+ 467, 468,
+ 468, 469,
+ 469, 470,
+ 470, 471,
+ 471, 472,
+ 472, 473,
+ 473, 474,
+ 474, 475,
+ 475, 476,
+ 476, 477,
+ 477, 478,
+ 478, 479,
+ 479, 464,
+ 480, 481,
+ 481, 482,
+ 482, 483,
+ 483, 484,
+ 484, 485,
+ 485, 486,
+ 486, 487,
+ 487, 488,
+ 488, 489,
+ 489, 490,
+ 490, 491,
+ 491, 492,
+ 492, 493,
+ 493, 494,
+ 494, 495,
+ 495, 480,
+ 496, 497,
+ 497, 498,
+ 498, 499,
+ 499, 500,
+ 500, 501,
+ 501, 502,
+ 502, 503,
+ 503, 504,
+ 504, 505,
+ 505, 506,
+ 506, 507,
+ 507, 508,
+ 508, 509,
+ 509, 510,
+ 510, 511,
+ 511, 496,
+ 512, 513,
+ 513, 514,
+ 514, 515,
+ 515, 516,
+ 516, 517,
+ 517, 518,
+ 518, 519,
+ 519, 520,
+ 520, 521,
+ 521, 522,
+ 522, 523,
+ 523, 524,
+ 524, 525,
+ 525, 526,
+ 526, 527,
+ 527, 512,
+ 528, 529,
+ 529, 530,
+ 530, 531,
+ 531, 532,
+ 532, 533,
+ 533, 534,
+ 534, 535,
+ 535, 536,
+ 536, 537,
+ 537, 538,
+ 538, 539,
+ 539, 540,
+ 540, 541,
+ 541, 542,
+ 542, 543,
+ 543, 528,
+ 544, 545,
+ 545, 546,
+ 546, 547,
+ 547, 548,
+ 548, 549,
+ 549, 550,
+ 550, 551,
+ 551, 552,
+ 552, 553,
+ 553, 554,
+ 554, 555,
+ 555, 556,
+ 556, 557,
+ 557, 558,
+ 558, 559,
+ 559, 544,
+ 560, 561,
+ 561, 562,
+ 562, 563,
+ 563, 564,
+ 564, 565,
+ 565, 566,
+ 566, 567,
+ 567, 568,
+ 568, 569,
+ 569, 570,
+ 570, 571,
+ 571, 572,
+ 572, 573,
+ 573, 574,
+ 574, 575,
+ 575, 560,
+ 576, 577,
+ 577, 578,
+ 578, 579,
+ 579, 580,
+ 580, 581,
+ 581, 582,
+ 582, 583,
+ 583, 584,
+ 584, 585,
+ 585, 586,
+ 586, 587,
+ 587, 588,
+ 588, 589,
+ 589, 590,
+ 590, 591,
+ 591, 576,
+ 592, 593,
+ 593, 594,
+ 594, 595,
+ 595, 596,
+ 596, 597,
+ 597, 598,
+ 598, 599,
+ 599, 600,
+ 600, 601,
+ 601, 602,
+ 602, 603,
+ 603, 604,
+ 604, 605,
+ 605, 606,
+ 606, 607,
+ 607, 592,
+ 608, 609,
+ 609, 610,
+ 610, 611,
+ 611, 612,
+ 612, 613,
+ 613, 614,
+ 614, 615,
+ 615, 616,
+ 616, 617,
+ 617, 618,
+ 618, 619,
+ 619, 620,
+ 620, 621,
+ 621, 622,
+ 622, 623,
+ 623, 608,
+ 624, 625,
+ 625, 626,
+ 626, 627,
+ 627, 628,
+ 628, 629,
+ 629, 630,
+ 630, 631,
+ 631, 632,
+ 632, 633,
+ 633, 634,
+ 634, 635,
+ 635, 636,
+ 636, 637,
+ 637, 638,
+ 638, 639,
+ 639, 624,
+ 640, 641,
+ 641, 642,
+ 642, 643,
+ 643, 644,
+ 644, 645,
+ 645, 646,
+ 646, 647,
+ 647, 648,
+ 648, 649,
+ 649, 650,
+ 650, 651,
+ 651, 652,
+ 652, 653,
+ 653, 654,
+ 654, 655,
+ 655, 640,
+ 656, 657,
+ 657, 658,
+ 658, 659,
+ 659, 660,
+ 660, 661,
+ 661, 662,
+ 662, 663,
+ 663, 664,
+ 664, 665,
+ 665, 666,
+ 666, 667,
+ 667, 668,
+ 668, 669,
+ 669, 670,
+ 670, 671,
+ 671, 656,
+ 672, 673,
+ 673, 674,
+ 674, 675,
+ 675, 676,
+ 676, 677,
+ 677, 678,
+ 678, 679,
+ 679, 680,
+ 680, 681,
+ 681, 682,
+ 682, 683,
+ 683, 684,
+ 684, 685,
+ 685, 686,
+ 686, 687,
+ 687, 672,
+ 688, 689,
+ 689, 690,
+ 690, 691,
+ 691, 692,
+ 692, 693,
+ 693, 694,
+ 694, 695,
+ 695, 696,
+ 696, 697,
+ 697, 698,
+ 698, 699,
+ 699, 700,
+ 700, 701,
+ 701, 702,
+ 702, 703,
+ 703, 688,
+ 704, 705,
+ 705, 706,
+ 706, 707,
+ 707, 708,
+ 708, 709,
+ 709, 710,
+ 710, 711,
+ 711, 712,
+ 712, 713,
+ 713, 714,
+ 714, 715,
+ 715, 716,
+ 716, 717,
+ 717, 718,
+ 718, 719,
+ 719, 704,
+ 720, 721,
+ 721, 722,
+ 722, 723,
+ 723, 724,
+ 724, 725,
+ 725, 726,
+ 726, 727,
+ 727, 728,
+ 728, 729,
+ 729, 730,
+ 730, 731,
+ 731, 732,
+ 732, 733,
+ 733, 734,
+ 734, 735,
+ 735, 720,
+ 736, 737,
+ 737, 738,
+ 738, 739,
+ 739, 740,
+ 740, 741,
+ 741, 742,
+ 742, 743,
+ 743, 744,
+ 744, 745,
+ 745, 746,
+ 746, 747,
+ 747, 748,
+ 748, 749,
+ 749, 750,
+ 750, 751,
+ 751, 736,
+ 752, 753,
+ 753, 754,
+ 754, 755,
+ 755, 756,
+ 756, 757,
+ 757, 758,
+ 758, 759,
+ 759, 760,
+ 760, 761,
+ 761, 762,
+ 762, 763,
+ 763, 764,
+ 764, 765,
+ 765, 766,
+ 766, 767,
+ 767, 752,
+ 768, 769,
+ 769, 770,
+ 770, 771,
+ 771, 772,
+ 772, 773,
+ 773, 774,
+ 774, 775,
+ 775, 776,
+ 776, 777,
+ 777, 778,
+ 778, 779,
+ 779, 780,
+ 780, 781,
+ 781, 782,
+ 782, 783,
+ 783, 768,
+ 784, 785,
+ 785, 786,
+ 786, 787,
+ 787, 788,
+ 788, 789,
+ 789, 790,
+ 790, 791,
+ 791, 792,
+ 792, 793,
+ 793, 794,
+ 794, 795,
+ 795, 796,
+ 796, 797,
+ 797, 798,
+ 798, 799,
+ 799, 784,
+ 800, 801,
+ 801, 802,
+ 802, 803,
+ 803, 804,
+ 804, 805,
+ 805, 806,
+ 806, 807,
+ 807, 808,
+ 808, 809,
+ 809, 810,
+ 810, 811,
+ 811, 812,
+ 812, 813,
+ 813, 814,
+ 814, 815,
+ 815, 800,
+ 816, 817,
+ 817, 818,
+ 818, 819,
+ 819, 820,
+ 820, 821,
+ 821, 822,
+ 822, 823,
+ 823, 824,
+ 824, 825,
+ 825, 826,
+ 826, 827,
+ 827, 828,
+ 828, 829,
+ 829, 830,
+ 830, 831,
+ 831, 816,
+ 832, 833,
+ 833, 834,
+ 834, 835,
+ 835, 836,
+ 836, 837,
+ 837, 838,
+ 838, 839,
+ 839, 840,
+ 840, 841,
+ 841, 842,
+ 842, 843,
+ 843, 844,
+ 844, 845,
+ 845, 846,
+ 846, 847,
+ 847, 832,
+ 848, 849,
+ 849, 850,
+ 850, 851,
+ 851, 852,
+ 852, 853,
+ 853, 854,
+ 854, 855,
+ 855, 856,
+ 856, 857,
+ 857, 858,
+ 858, 859,
+ 859, 860,
+ 860, 861,
+ 861, 862,
+ 862, 863,
+ 863, 848,
+ 864, 865,
+ 865, 866,
+ 866, 867,
+ 867, 868,
+ 868, 869,
+ 869, 870,
+ 870, 871,
+ 871, 872,
+ 872, 873,
+ 873, 874,
+ 874, 875,
+ 875, 876,
+ 876, 877,
+ 877, 878,
+ 878, 879,
+ 879, 864,
+ 880, 881,
+ 881, 882,
+ 882, 883,
+ 883, 884,
+ 884, 885,
+ 885, 886,
+ 886, 887,
+ 887, 888,
+ 888, 889,
+ 889, 890,
+ 890, 891,
+ 891, 892,
+ 892, 893,
+ 893, 894,
+ 894, 895,
+ 895, 880,
+ 896, 897,
+ 897, 898,
+ 898, 899,
+ 899, 900,
+ 900, 901,
+ 901, 902,
+ 902, 903,
+ 903, 904,
+ 904, 905,
+ 905, 906,
+ 906, 907,
+ 907, 908,
+ 908, 909,
+ 909, 910,
+ 910, 911,
+ 911, 896,
+ 912, 913,
+ 913, 914,
+ 914, 915,
+ 915, 916,
+ 916, 917,
+ 917, 918,
+ 918, 919,
+ 919, 920,
+ 920, 921,
+ 921, 922,
+ 922, 923,
+ 923, 924,
+ 924, 925,
+ 925, 926,
+ 926, 927,
+ 927, 912,
+ 928, 929,
+ 929, 930,
+ 930, 931,
+ 931, 932,
+ 932, 933,
+ 933, 934,
+ 934, 935,
+ 935, 936,
+ 936, 937,
+ 937, 938,
+ 938, 939,
+ 939, 940,
+ 940, 941,
+ 941, 942,
+ 942, 943,
+ 943, 928,
+ 944, 945,
+ 945, 946,
+ 946, 947,
+ 947, 948,
+ 948, 949,
+ 949, 950,
+ 950, 951,
+ 951, 952,
+ 952, 953,
+ 953, 954,
+ 954, 955,
+ 955, 956,
+ 956, 957,
+ 957, 958,
+ 958, 959,
+ 959, 944,
+ 960, 961,
+ 961, 962,
+ 962, 963,
+ 963, 964,
+ 964, 965,
+ 965, 966,
+ 966, 967,
+ 967, 968,
+ 968, 969,
+ 969, 970,
+ 970, 971,
+ 971, 972,
+ 972, 973,
+ 973, 974,
+ 974, 975,
+ 975, 960,
+ 976, 977,
+ 977, 978,
+ 978, 979,
+ 979, 980,
+ 980, 981,
+ 981, 982,
+ 982, 983,
+ 983, 984,
+ 984, 985,
+ 985, 986,
+ 986, 987,
+ 987, 988,
+ 988, 989,
+ 989, 990,
+ 990, 991,
+ 991, 976,
+ 992, 993,
+ 993, 994,
+ 994, 995,
+ 995, 996,
+ 996, 997,
+ 997, 998,
+ 998, 999,
+ 999, 1000,
+ 1000, 1001,
+ 1001, 1002,
+ 1002, 1003,
+ 1003, 1004,
+ 1004, 1005,
+ 1005, 1006,
+ 1006, 1007,
+ 1007, 992,
+ 1008, 1009,
+ 1009, 1010,
+ 1010, 1011,
+ 1011, 1012,
+ 1012, 1013,
+ 1013, 1014,
+ 1014, 1015,
+ 1015, 1016,
+ 1016, 1017,
+ 1017, 1018,
+ 1018, 1019,
+ 1019, 1020,
+ 1020, 1021,
+ 1021, 1022,
+ 1022, 1023,
+ 1023, 1008
+};
+static const unsigned some_enclosures_properties[3072] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 2, 3, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0
+};
+
+#define NB_CIRC_X 4
+#define NB_CIRC_Y 4
+#define NB_CIRC_Z 4
+#define NB_CIRC (NB_CIRC_X * NB_CIRC_Y * NB_CIRC_Z)
+#define CIRC_VRTX_COUNT 16u
+#define CIRC_SEG_COUNT 16u
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc2d_device* dev = NULL;
+ struct senc2d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned e, count;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene */
+ ctx.positions = some_enclosures_vertices;
+ ctx.indices = some_enclosures_segments;
+ ctx.properties = some_enclosures_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ some_enclosures_segments_count, get_indices, get_media_from_properties,
+ some_enclosures_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_vertices_count(scn, &count));
+ CHK(count == some_enclosures_vertices_count);
+ CHK(count == NB_CIRC * CIRC_VRTX_COUNT);
+ OK(senc2d_scene_get_segments_count(scn, &count));
+ CHK(count == some_enclosures_segments_count);
+ CHK(count == NB_CIRC * CIRC_SEG_COUNT);
+
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1 + NB_CIRC);
+ FOR_EACH(e, 0, count) {
+ struct senc2d_enclosure* enclosure;
+ struct senc2d_enclosure_header header;
+ unsigned m;
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
+ CHK(header.enclosed_media_count == 1);
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &m));
+ CHK(header.primitives_count ==
+ (header.is_infinite /* Outermost enclosure: NB_CIRC_X*NB_CIRC_Y circles */
+ ? NB_CIRC_X * NB_CIRC_Y * CIRC_SEG_COUNT
+ : (m == 0
+ ? CIRC_SEG_COUNT /* Innermost enclosures: 1 circle */
+ : 2 * CIRC_SEG_COUNT))); /* Other enclosures: 2 circles */
+ OK(senc2d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_senc2d_some_segments.c b/src/test_senc2d_some_segments.c
@@ -0,0 +1,3259 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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/>. */
+
+/* This test has been created using the sg2_geometry_dump_as_C_code feature
+ * of star-geometry-2D. It uses output from test_sg2_some_segments.
+ * This test is similar to test_senc2d_many_segments that creates a huge
+ * geometry by program. */
+
+#include "senc2d.h"
+#include "test_senc2d_utils.h"
+
+#include <rsys/double2.h>
+
+/* Dump of star-geometry-2D 'some_segments'. */
+static const unsigned some_segments_vertices_count = 1056;
+static const double some_segments_vertices[2112] =
+{
+ 1, 0,
+ 0.999717, 0.0237977,
+ 0.998867, 0.0475819,
+ 0.997452, 0.0713392,
+ 0.995472, 0.095056,
+ 0.992928, 0.118719,
+ 0.989821, 0.142315,
+ 0.986154, 0.16583,
+ 0.981929, 0.189251,
+ 0.977147, 0.212565,
+ 0.971812, 0.235759,
+ 0.965926, 0.258819,
+ 0.959493, 0.281733,
+ 0.952517, 0.304486,
+ 0.945001, 0.327068,
+ 0.93695, 0.349464,
+ 0.928368, 0.371662,
+ 0.91926, 0.39365,
+ 0.909632, 0.415415,
+ 0.899488, 0.436945,
+ 0.888835, 0.458227,
+ 0.877679, 0.479249,
+ 0.866025, 0.5,
+ 0.853881, 0.520468,
+ 0.841254, 0.540641,
+ 0.828149, 0.560508,
+ 0.814576, 0.580057,
+ 0.800541, 0.599278,
+ 0.786053, 0.618159,
+ 0.77112, 0.63669,
+ 0.75575, 0.654861,
+ 0.739951, 0.67266,
+ 0.723734, 0.690079,
+ 0.707107, 0.707107,
+ 0.690079, 0.723734,
+ 0.67266, 0.739951,
+ 0.654861, 0.75575,
+ 0.63669, 0.77112,
+ 0.618159, 0.786053,
+ 0.599278, 0.800541,
+ 0.580057, 0.814576,
+ 0.560508, 0.828149,
+ 0.540641, 0.841254,
+ 0.520468, 0.853881,
+ 0.5, 0.866025,
+ 0.479249, 0.877679,
+ 0.458227, 0.888835,
+ 0.436945, 0.899488,
+ 0.415415, 0.909632,
+ 0.39365, 0.91926,
+ 0.371662, 0.928368,
+ 0.349464, 0.93695,
+ 0.327068, 0.945001,
+ 0.304486, 0.952517,
+ 0.281733, 0.959493,
+ 0.258819, 0.965926,
+ 0.235759, 0.971812,
+ 0.212565, 0.977147,
+ 0.189251, 0.981929,
+ 0.16583, 0.986154,
+ 0.142315, 0.989821,
+ 0.118719, 0.992928,
+ 0.095056, 0.995472,
+ 0.0713392, 0.997452,
+ 0.0475819, 0.998867,
+ 0.0237977, 0.999717,
+ 6.12323e-17, 1,
+ -0.0237977, 0.999717,
+ -0.0475819, 0.998867,
+ -0.0713392, 0.997452,
+ -0.095056, 0.995472,
+ -0.118719, 0.992928,
+ -0.142315, 0.989821,
+ -0.16583, 0.986154,
+ -0.189251, 0.981929,
+ -0.212565, 0.977147,
+ -0.235759, 0.971812,
+ -0.258819, 0.965926,
+ -0.281733, 0.959493,
+ -0.304486, 0.952517,
+ -0.327068, 0.945001,
+ -0.349464, 0.93695,
+ -0.371662, 0.928368,
+ -0.39365, 0.91926,
+ -0.415415, 0.909632,
+ -0.436945, 0.899488,
+ -0.458227, 0.888835,
+ -0.479249, 0.877679,
+ -0.5, 0.866025,
+ -0.520468, 0.853881,
+ -0.540641, 0.841254,
+ -0.560508, 0.828149,
+ -0.580057, 0.814576,
+ -0.599278, 0.800541,
+ -0.618159, 0.786053,
+ -0.63669, 0.77112,
+ -0.654861, 0.75575,
+ -0.67266, 0.739951,
+ -0.690079, 0.723734,
+ -0.707107, 0.707107,
+ -0.723734, 0.690079,
+ -0.739951, 0.67266,
+ -0.75575, 0.654861,
+ -0.77112, 0.63669,
+ -0.786053, 0.618159,
+ -0.800541, 0.599278,
+ -0.814576, 0.580057,
+ -0.828149, 0.560508,
+ -0.841254, 0.540641,
+ -0.853881, 0.520468,
+ -0.866025, 0.5,
+ -0.877679, 0.479249,
+ -0.888835, 0.458227,
+ -0.899488, 0.436945,
+ -0.909632, 0.415415,
+ -0.91926, 0.39365,
+ -0.928368, 0.371662,
+ -0.93695, 0.349464,
+ -0.945001, 0.327068,
+ -0.952517, 0.304486,
+ -0.959493, 0.281733,
+ -0.965926, 0.258819,
+ -0.971812, 0.235759,
+ -0.977147, 0.212565,
+ -0.981929, 0.189251,
+ -0.986154, 0.16583,
+ -0.989821, 0.142315,
+ -0.992928, 0.118719,
+ -0.995472, 0.095056,
+ -0.997452, 0.0713392,
+ -0.998867, 0.0475819,
+ -0.999717, 0.0237977,
+ -1, 1.22465e-16,
+ -0.999717, -0.0237977,
+ -0.998867, -0.0475819,
+ -0.997452, -0.0713392,
+ -0.995472, -0.095056,
+ -0.992928, -0.118719,
+ -0.989821, -0.142315,
+ -0.986154, -0.16583,
+ -0.981929, -0.189251,
+ -0.977147, -0.212565,
+ -0.971812, -0.235759,
+ -0.965926, -0.258819,
+ -0.959493, -0.281733,
+ -0.952517, -0.304486,
+ -0.945001, -0.327068,
+ -0.93695, -0.349464,
+ -0.928368, -0.371662,
+ -0.91926, -0.39365,
+ -0.909632, -0.415415,
+ -0.899488, -0.436945,
+ -0.888835, -0.458227,
+ -0.877679, -0.479249,
+ -0.866025, -0.5,
+ -0.853881, -0.520468,
+ -0.841254, -0.540641,
+ -0.828149, -0.560508,
+ -0.814576, -0.580057,
+ -0.800541, -0.599278,
+ -0.786053, -0.618159,
+ -0.77112, -0.63669,
+ -0.75575, -0.654861,
+ -0.739951, -0.67266,
+ -0.723734, -0.690079,
+ -0.707107, -0.707107,
+ -0.690079, -0.723734,
+ -0.67266, -0.739951,
+ -0.654861, -0.75575,
+ -0.63669, -0.77112,
+ -0.618159, -0.786053,
+ -0.599278, -0.800541,
+ -0.580057, -0.814576,
+ -0.560508, -0.828149,
+ -0.540641, -0.841254,
+ -0.520468, -0.853881,
+ -0.5, -0.866025,
+ -0.479249, -0.877679,
+ -0.458227, -0.888835,
+ -0.436945, -0.899488,
+ -0.415415, -0.909632,
+ -0.39365, -0.91926,
+ -0.371662, -0.928368,
+ -0.349464, -0.93695,
+ -0.327068, -0.945001,
+ -0.304486, -0.952517,
+ -0.281733, -0.959493,
+ -0.258819, -0.965926,
+ -0.235759, -0.971812,
+ -0.212565, -0.977147,
+ -0.189251, -0.981929,
+ -0.16583, -0.986154,
+ -0.142315, -0.989821,
+ -0.118719, -0.992928,
+ -0.095056, -0.995472,
+ -0.0713392, -0.997452,
+ -0.0475819, -0.998867,
+ -0.0237977, -0.999717,
+ -1.83697e-16, -1,
+ 0.0237977, -0.999717,
+ 0.0475819, -0.998867,
+ 0.0713392, -0.997452,
+ 0.095056, -0.995472,
+ 0.118719, -0.992928,
+ 0.142315, -0.989821,
+ 0.16583, -0.986154,
+ 0.189251, -0.981929,
+ 0.212565, -0.977147,
+ 0.235759, -0.971812,
+ 0.258819, -0.965926,
+ 0.281733, -0.959493,
+ 0.304486, -0.952517,
+ 0.327068, -0.945001,
+ 0.349464, -0.93695,
+ 0.371662, -0.928368,
+ 0.39365, -0.91926,
+ 0.415415, -0.909632,
+ 0.436945, -0.899488,
+ 0.458227, -0.888835,
+ 0.479249, -0.877679,
+ 0.5, -0.866025,
+ 0.520468, -0.853881,
+ 0.540641, -0.841254,
+ 0.560508, -0.828149,
+ 0.580057, -0.814576,
+ 0.599278, -0.800541,
+ 0.618159, -0.786053,
+ 0.63669, -0.77112,
+ 0.654861, -0.75575,
+ 0.67266, -0.739951,
+ 0.690079, -0.723734,
+ 0.707107, -0.707107,
+ 0.723734, -0.690079,
+ 0.739951, -0.67266,
+ 0.75575, -0.654861,
+ 0.77112, -0.63669,
+ 0.786053, -0.618159,
+ 0.800541, -0.599278,
+ 0.814576, -0.580057,
+ 0.828149, -0.560508,
+ 0.841254, -0.540641,
+ 0.853881, -0.520468,
+ 0.866025, -0.5,
+ 0.877679, -0.479249,
+ 0.888835, -0.458227,
+ 0.899488, -0.436945,
+ 0.909632, -0.415415,
+ 0.91926, -0.39365,
+ 0.928368, -0.371662,
+ 0.93695, -0.349464,
+ 0.945001, -0.327068,
+ 0.952517, -0.304486,
+ 0.959493, -0.281733,
+ 0.965926, -0.258819,
+ 0.971812, -0.235759,
+ 0.977147, -0.212565,
+ 0.981929, -0.189251,
+ 0.986154, -0.16583,
+ 0.989821, -0.142315,
+ 0.992928, -0.118719,
+ 0.995472, -0.095056,
+ 0.997452, -0.0713392,
+ 0.998867, -0.0475819,
+ 0.999717, -0.0237977,
+ 1, 10,
+ 0.999717, 10.0238,
+ 0.998867, 10.0476,
+ 0.997452, 10.0713,
+ 0.995472, 10.0951,
+ 0.992928, 10.1187,
+ 0.989821, 10.1423,
+ 0.986154, 10.1658,
+ 0.981929, 10.1893,
+ 0.977147, 10.2126,
+ 0.971812, 10.2358,
+ 0.965926, 10.2588,
+ 0.959493, 10.2817,
+ 0.952517, 10.3045,
+ 0.945001, 10.3271,
+ 0.93695, 10.3495,
+ 0.928368, 10.3717,
+ 0.91926, 10.3937,
+ 0.909632, 10.4154,
+ 0.899488, 10.4369,
+ 0.888835, 10.4582,
+ 0.877679, 10.4792,
+ 0.866025, 10.5,
+ 0.853881, 10.5205,
+ 0.841254, 10.5406,
+ 0.828149, 10.5605,
+ 0.814576, 10.5801,
+ 0.800541, 10.5993,
+ 0.786053, 10.6182,
+ 0.77112, 10.6367,
+ 0.75575, 10.6549,
+ 0.739951, 10.6727,
+ 0.723734, 10.6901,
+ 0.707107, 10.7071,
+ 0.690079, 10.7237,
+ 0.67266, 10.74,
+ 0.654861, 10.7557,
+ 0.63669, 10.7711,
+ 0.618159, 10.7861,
+ 0.599278, 10.8005,
+ 0.580057, 10.8146,
+ 0.560508, 10.8281,
+ 0.540641, 10.8413,
+ 0.520468, 10.8539,
+ 0.5, 10.866,
+ 0.479249, 10.8777,
+ 0.458227, 10.8888,
+ 0.436945, 10.8995,
+ 0.415415, 10.9096,
+ 0.39365, 10.9193,
+ 0.371662, 10.9284,
+ 0.349464, 10.9369,
+ 0.327068, 10.945,
+ 0.304486, 10.9525,
+ 0.281733, 10.9595,
+ 0.258819, 10.9659,
+ 0.235759, 10.9718,
+ 0.212565, 10.9771,
+ 0.189251, 10.9819,
+ 0.16583, 10.9862,
+ 0.142315, 10.9898,
+ 0.118719, 10.9929,
+ 0.095056, 10.9955,
+ 0.0713392, 10.9975,
+ 0.0475819, 10.9989,
+ 0.0237977, 10.9997,
+ 6.12323e-17, 11,
+ -0.0237977, 10.9997,
+ -0.0475819, 10.9989,
+ -0.0713392, 10.9975,
+ -0.095056, 10.9955,
+ -0.118719, 10.9929,
+ -0.142315, 10.9898,
+ -0.16583, 10.9862,
+ -0.189251, 10.9819,
+ -0.212565, 10.9771,
+ -0.235759, 10.9718,
+ -0.258819, 10.9659,
+ -0.281733, 10.9595,
+ -0.304486, 10.9525,
+ -0.327068, 10.945,
+ -0.349464, 10.9369,
+ -0.371662, 10.9284,
+ -0.39365, 10.9193,
+ -0.415415, 10.9096,
+ -0.436945, 10.8995,
+ -0.458227, 10.8888,
+ -0.479249, 10.8777,
+ -0.5, 10.866,
+ -0.520468, 10.8539,
+ -0.540641, 10.8413,
+ -0.560508, 10.8281,
+ -0.580057, 10.8146,
+ -0.599278, 10.8005,
+ -0.618159, 10.7861,
+ -0.63669, 10.7711,
+ -0.654861, 10.7557,
+ -0.67266, 10.74,
+ -0.690079, 10.7237,
+ -0.707107, 10.7071,
+ -0.723734, 10.6901,
+ -0.739951, 10.6727,
+ -0.75575, 10.6549,
+ -0.77112, 10.6367,
+ -0.786053, 10.6182,
+ -0.800541, 10.5993,
+ -0.814576, 10.5801,
+ -0.828149, 10.5605,
+ -0.841254, 10.5406,
+ -0.853881, 10.5205,
+ -0.866025, 10.5,
+ -0.877679, 10.4792,
+ -0.888835, 10.4582,
+ -0.899488, 10.4369,
+ -0.909632, 10.4154,
+ -0.91926, 10.3937,
+ -0.928368, 10.3717,
+ -0.93695, 10.3495,
+ -0.945001, 10.3271,
+ -0.952517, 10.3045,
+ -0.959493, 10.2817,
+ -0.965926, 10.2588,
+ -0.971812, 10.2358,
+ -0.977147, 10.2126,
+ -0.981929, 10.1893,
+ -0.986154, 10.1658,
+ -0.989821, 10.1423,
+ -0.992928, 10.1187,
+ -0.995472, 10.0951,
+ -0.997452, 10.0713,
+ -0.998867, 10.0476,
+ -0.999717, 10.0238,
+ -1, 10,
+ -0.999717, 9.9762,
+ -0.998867, 9.95242,
+ -0.997452, 9.92866,
+ -0.995472, 9.90494,
+ -0.992928, 9.88128,
+ -0.989821, 9.85769,
+ -0.986154, 9.83417,
+ -0.981929, 9.81075,
+ -0.977147, 9.78743,
+ -0.971812, 9.76424,
+ -0.965926, 9.74118,
+ -0.959493, 9.71827,
+ -0.952517, 9.69551,
+ -0.945001, 9.67293,
+ -0.93695, 9.65054,
+ -0.928368, 9.62834,
+ -0.91926, 9.60635,
+ -0.909632, 9.58458,
+ -0.899488, 9.56306,
+ -0.888835, 9.54177,
+ -0.877679, 9.52075,
+ -0.866025, 9.5,
+ -0.853881, 9.47953,
+ -0.841254, 9.45936,
+ -0.828149, 9.43949,
+ -0.814576, 9.41994,
+ -0.800541, 9.40072,
+ -0.786053, 9.38184,
+ -0.77112, 9.36331,
+ -0.75575, 9.34514,
+ -0.739951, 9.32734,
+ -0.723734, 9.30992,
+ -0.707107, 9.29289,
+ -0.690079, 9.27627,
+ -0.67266, 9.26005,
+ -0.654861, 9.24425,
+ -0.63669, 9.22888,
+ -0.618159, 9.21395,
+ -0.599278, 9.19946,
+ -0.580057, 9.18542,
+ -0.560508, 9.17185,
+ -0.540641, 9.15875,
+ -0.520468, 9.14612,
+ -0.5, 9.13397,
+ -0.479249, 9.12232,
+ -0.458227, 9.11116,
+ -0.436945, 9.10051,
+ -0.415415, 9.09037,
+ -0.39365, 9.08074,
+ -0.371662, 9.07163,
+ -0.349464, 9.06305,
+ -0.327068, 9.055,
+ -0.304486, 9.04748,
+ -0.281733, 9.04051,
+ -0.258819, 9.03407,
+ -0.235759, 9.02819,
+ -0.212565, 9.02285,
+ -0.189251, 9.01807,
+ -0.16583, 9.01385,
+ -0.142315, 9.01018,
+ -0.118719, 9.00707,
+ -0.095056, 9.00453,
+ -0.0713392, 9.00255,
+ -0.0475819, 9.00113,
+ -0.0237977, 9.00028,
+ -1.83697e-16, 9,
+ 0.0237977, 9.00028,
+ 0.0475819, 9.00113,
+ 0.0713392, 9.00255,
+ 0.095056, 9.00453,
+ 0.118719, 9.00707,
+ 0.142315, 9.01018,
+ 0.16583, 9.01385,
+ 0.189251, 9.01807,
+ 0.212565, 9.02285,
+ 0.235759, 9.02819,
+ 0.258819, 9.03407,
+ 0.281733, 9.04051,
+ 0.304486, 9.04748,
+ 0.327068, 9.055,
+ 0.349464, 9.06305,
+ 0.371662, 9.07163,
+ 0.39365, 9.08074,
+ 0.415415, 9.09037,
+ 0.436945, 9.10051,
+ 0.458227, 9.11116,
+ 0.479249, 9.12232,
+ 0.5, 9.13397,
+ 0.520468, 9.14612,
+ 0.540641, 9.15875,
+ 0.560508, 9.17185,
+ 0.580057, 9.18542,
+ 0.599278, 9.19946,
+ 0.618159, 9.21395,
+ 0.63669, 9.22888,
+ 0.654861, 9.24425,
+ 0.67266, 9.26005,
+ 0.690079, 9.27627,
+ 0.707107, 9.29289,
+ 0.723734, 9.30992,
+ 0.739951, 9.32734,
+ 0.75575, 9.34514,
+ 0.77112, 9.36331,
+ 0.786053, 9.38184,
+ 0.800541, 9.40072,
+ 0.814576, 9.41994,
+ 0.828149, 9.43949,
+ 0.841254, 9.45936,
+ 0.853881, 9.47953,
+ 0.866025, 9.5,
+ 0.877679, 9.52075,
+ 0.888835, 9.54177,
+ 0.899488, 9.56306,
+ 0.909632, 9.58458,
+ 0.91926, 9.60635,
+ 0.928368, 9.62834,
+ 0.93695, 9.65054,
+ 0.945001, 9.67293,
+ 0.952517, 9.69551,
+ 0.959493, 9.71827,
+ 0.965926, 9.74118,
+ 0.971812, 9.76424,
+ 0.977147, 9.78743,
+ 0.981929, 9.81075,
+ 0.986154, 9.83417,
+ 0.989821, 9.85769,
+ 0.992928, 9.88128,
+ 0.995472, 9.90494,
+ 0.997452, 9.92866,
+ 0.998867, 9.95242,
+ 0.999717, 9.9762,
+ 1, 20,
+ 0.999717, 20.0238,
+ 0.998867, 20.0476,
+ 0.997452, 20.0713,
+ 0.995472, 20.0951,
+ 0.992928, 20.1187,
+ 0.989821, 20.1423,
+ 0.986154, 20.1658,
+ 0.981929, 20.1893,
+ 0.977147, 20.2126,
+ 0.971812, 20.2358,
+ 0.965926, 20.2588,
+ 0.959493, 20.2817,
+ 0.952517, 20.3045,
+ 0.945001, 20.3271,
+ 0.93695, 20.3495,
+ 0.928368, 20.3717,
+ 0.91926, 20.3937,
+ 0.909632, 20.4154,
+ 0.899488, 20.4369,
+ 0.888835, 20.4582,
+ 0.877679, 20.4792,
+ 0.866025, 20.5,
+ 0.853881, 20.5205,
+ 0.841254, 20.5406,
+ 0.828149, 20.5605,
+ 0.814576, 20.5801,
+ 0.800541, 20.5993,
+ 0.786053, 20.6182,
+ 0.77112, 20.6367,
+ 0.75575, 20.6549,
+ 0.739951, 20.6727,
+ 0.723734, 20.6901,
+ 0.707107, 20.7071,
+ 0.690079, 20.7237,
+ 0.67266, 20.74,
+ 0.654861, 20.7557,
+ 0.63669, 20.7711,
+ 0.618159, 20.7861,
+ 0.599278, 20.8005,
+ 0.580057, 20.8146,
+ 0.560508, 20.8281,
+ 0.540641, 20.8413,
+ 0.520468, 20.8539,
+ 0.5, 20.866,
+ 0.479249, 20.8777,
+ 0.458227, 20.8888,
+ 0.436945, 20.8995,
+ 0.415415, 20.9096,
+ 0.39365, 20.9193,
+ 0.371662, 20.9284,
+ 0.349464, 20.9369,
+ 0.327068, 20.945,
+ 0.304486, 20.9525,
+ 0.281733, 20.9595,
+ 0.258819, 20.9659,
+ 0.235759, 20.9718,
+ 0.212565, 20.9771,
+ 0.189251, 20.9819,
+ 0.16583, 20.9862,
+ 0.142315, 20.9898,
+ 0.118719, 20.9929,
+ 0.095056, 20.9955,
+ 0.0713392, 20.9975,
+ 0.0475819, 20.9989,
+ 0.0237977, 20.9997,
+ 6.12323e-17, 21,
+ -0.0237977, 20.9997,
+ -0.0475819, 20.9989,
+ -0.0713392, 20.9975,
+ -0.095056, 20.9955,
+ -0.118719, 20.9929,
+ -0.142315, 20.9898,
+ -0.16583, 20.9862,
+ -0.189251, 20.9819,
+ -0.212565, 20.9771,
+ -0.235759, 20.9718,
+ -0.258819, 20.9659,
+ -0.281733, 20.9595,
+ -0.304486, 20.9525,
+ -0.327068, 20.945,
+ -0.349464, 20.9369,
+ -0.371662, 20.9284,
+ -0.39365, 20.9193,
+ -0.415415, 20.9096,
+ -0.436945, 20.8995,
+ -0.458227, 20.8888,
+ -0.479249, 20.8777,
+ -0.5, 20.866,
+ -0.520468, 20.8539,
+ -0.540641, 20.8413,
+ -0.560508, 20.8281,
+ -0.580057, 20.8146,
+ -0.599278, 20.8005,
+ -0.618159, 20.7861,
+ -0.63669, 20.7711,
+ -0.654861, 20.7557,
+ -0.67266, 20.74,
+ -0.690079, 20.7237,
+ -0.707107, 20.7071,
+ -0.723734, 20.6901,
+ -0.739951, 20.6727,
+ -0.75575, 20.6549,
+ -0.77112, 20.6367,
+ -0.786053, 20.6182,
+ -0.800541, 20.5993,
+ -0.814576, 20.5801,
+ -0.828149, 20.5605,
+ -0.841254, 20.5406,
+ -0.853881, 20.5205,
+ -0.866025, 20.5,
+ -0.877679, 20.4792,
+ -0.888835, 20.4582,
+ -0.899488, 20.4369,
+ -0.909632, 20.4154,
+ -0.91926, 20.3937,
+ -0.928368, 20.3717,
+ -0.93695, 20.3495,
+ -0.945001, 20.3271,
+ -0.952517, 20.3045,
+ -0.959493, 20.2817,
+ -0.965926, 20.2588,
+ -0.971812, 20.2358,
+ -0.977147, 20.2126,
+ -0.981929, 20.1893,
+ -0.986154, 20.1658,
+ -0.989821, 20.1423,
+ -0.992928, 20.1187,
+ -0.995472, 20.0951,
+ -0.997452, 20.0713,
+ -0.998867, 20.0476,
+ -0.999717, 20.0238,
+ -1, 20,
+ -0.999717, 19.9762,
+ -0.998867, 19.9524,
+ -0.997452, 19.9287,
+ -0.995472, 19.9049,
+ -0.992928, 19.8813,
+ -0.989821, 19.8577,
+ -0.986154, 19.8342,
+ -0.981929, 19.8107,
+ -0.977147, 19.7874,
+ -0.971812, 19.7642,
+ -0.965926, 19.7412,
+ -0.959493, 19.7183,
+ -0.952517, 19.6955,
+ -0.945001, 19.6729,
+ -0.93695, 19.6505,
+ -0.928368, 19.6283,
+ -0.91926, 19.6063,
+ -0.909632, 19.5846,
+ -0.899488, 19.5631,
+ -0.888835, 19.5418,
+ -0.877679, 19.5208,
+ -0.866025, 19.5,
+ -0.853881, 19.4795,
+ -0.841254, 19.4594,
+ -0.828149, 19.4395,
+ -0.814576, 19.4199,
+ -0.800541, 19.4007,
+ -0.786053, 19.3818,
+ -0.77112, 19.3633,
+ -0.75575, 19.3451,
+ -0.739951, 19.3273,
+ -0.723734, 19.3099,
+ -0.707107, 19.2929,
+ -0.690079, 19.2763,
+ -0.67266, 19.26,
+ -0.654861, 19.2443,
+ -0.63669, 19.2289,
+ -0.618159, 19.2139,
+ -0.599278, 19.1995,
+ -0.580057, 19.1854,
+ -0.560508, 19.1719,
+ -0.540641, 19.1587,
+ -0.520468, 19.1461,
+ -0.5, 19.134,
+ -0.479249, 19.1223,
+ -0.458227, 19.1112,
+ -0.436945, 19.1005,
+ -0.415415, 19.0904,
+ -0.39365, 19.0807,
+ -0.371662, 19.0716,
+ -0.349464, 19.0631,
+ -0.327068, 19.055,
+ -0.304486, 19.0475,
+ -0.281733, 19.0405,
+ -0.258819, 19.0341,
+ -0.235759, 19.0282,
+ -0.212565, 19.0229,
+ -0.189251, 19.0181,
+ -0.16583, 19.0138,
+ -0.142315, 19.0102,
+ -0.118719, 19.0071,
+ -0.095056, 19.0045,
+ -0.0713392, 19.0025,
+ -0.0475819, 19.0011,
+ -0.0237977, 19.0003,
+ -1.83697e-16, 19,
+ 0.0237977, 19.0003,
+ 0.0475819, 19.0011,
+ 0.0713392, 19.0025,
+ 0.095056, 19.0045,
+ 0.118719, 19.0071,
+ 0.142315, 19.0102,
+ 0.16583, 19.0138,
+ 0.189251, 19.0181,
+ 0.212565, 19.0229,
+ 0.235759, 19.0282,
+ 0.258819, 19.0341,
+ 0.281733, 19.0405,
+ 0.304486, 19.0475,
+ 0.327068, 19.055,
+ 0.349464, 19.0631,
+ 0.371662, 19.0716,
+ 0.39365, 19.0807,
+ 0.415415, 19.0904,
+ 0.436945, 19.1005,
+ 0.458227, 19.1112,
+ 0.479249, 19.1223,
+ 0.5, 19.134,
+ 0.520468, 19.1461,
+ 0.540641, 19.1587,
+ 0.560508, 19.1719,
+ 0.580057, 19.1854,
+ 0.599278, 19.1995,
+ 0.618159, 19.2139,
+ 0.63669, 19.2289,
+ 0.654861, 19.2443,
+ 0.67266, 19.26,
+ 0.690079, 19.2763,
+ 0.707107, 19.2929,
+ 0.723734, 19.3099,
+ 0.739951, 19.3273,
+ 0.75575, 19.3451,
+ 0.77112, 19.3633,
+ 0.786053, 19.3818,
+ 0.800541, 19.4007,
+ 0.814576, 19.4199,
+ 0.828149, 19.4395,
+ 0.841254, 19.4594,
+ 0.853881, 19.4795,
+ 0.866025, 19.5,
+ 0.877679, 19.5208,
+ 0.888835, 19.5418,
+ 0.899488, 19.5631,
+ 0.909632, 19.5846,
+ 0.91926, 19.6063,
+ 0.928368, 19.6283,
+ 0.93695, 19.6505,
+ 0.945001, 19.6729,
+ 0.952517, 19.6955,
+ 0.959493, 19.7183,
+ 0.965926, 19.7412,
+ 0.971812, 19.7642,
+ 0.977147, 19.7874,
+ 0.981929, 19.8107,
+ 0.986154, 19.8342,
+ 0.989821, 19.8577,
+ 0.992928, 19.8813,
+ 0.995472, 19.9049,
+ 0.997452, 19.9287,
+ 0.998867, 19.9524,
+ 0.999717, 19.9762,
+ 1, 30,
+ 0.999717, 30.0238,
+ 0.998867, 30.0476,
+ 0.997452, 30.0713,
+ 0.995472, 30.0951,
+ 0.992928, 30.1187,
+ 0.989821, 30.1423,
+ 0.986154, 30.1658,
+ 0.981929, 30.1893,
+ 0.977147, 30.2126,
+ 0.971812, 30.2358,
+ 0.965926, 30.2588,
+ 0.959493, 30.2817,
+ 0.952517, 30.3045,
+ 0.945001, 30.3271,
+ 0.93695, 30.3495,
+ 0.928368, 30.3717,
+ 0.91926, 30.3937,
+ 0.909632, 30.4154,
+ 0.899488, 30.4369,
+ 0.888835, 30.4582,
+ 0.877679, 30.4792,
+ 0.866025, 30.5,
+ 0.853881, 30.5205,
+ 0.841254, 30.5406,
+ 0.828149, 30.5605,
+ 0.814576, 30.5801,
+ 0.800541, 30.5993,
+ 0.786053, 30.6182,
+ 0.77112, 30.6367,
+ 0.75575, 30.6549,
+ 0.739951, 30.6727,
+ 0.723734, 30.6901,
+ 0.707107, 30.7071,
+ 0.690079, 30.7237,
+ 0.67266, 30.74,
+ 0.654861, 30.7557,
+ 0.63669, 30.7711,
+ 0.618159, 30.7861,
+ 0.599278, 30.8005,
+ 0.580057, 30.8146,
+ 0.560508, 30.8281,
+ 0.540641, 30.8413,
+ 0.520468, 30.8539,
+ 0.5, 30.866,
+ 0.479249, 30.8777,
+ 0.458227, 30.8888,
+ 0.436945, 30.8995,
+ 0.415415, 30.9096,
+ 0.39365, 30.9193,
+ 0.371662, 30.9284,
+ 0.349464, 30.9369,
+ 0.327068, 30.945,
+ 0.304486, 30.9525,
+ 0.281733, 30.9595,
+ 0.258819, 30.9659,
+ 0.235759, 30.9718,
+ 0.212565, 30.9771,
+ 0.189251, 30.9819,
+ 0.16583, 30.9862,
+ 0.142315, 30.9898,
+ 0.118719, 30.9929,
+ 0.095056, 30.9955,
+ 0.0713392, 30.9975,
+ 0.0475819, 30.9989,
+ 0.0237977, 30.9997,
+ 6.12323e-17, 31,
+ -0.0237977, 30.9997,
+ -0.0475819, 30.9989,
+ -0.0713392, 30.9975,
+ -0.095056, 30.9955,
+ -0.118719, 30.9929,
+ -0.142315, 30.9898,
+ -0.16583, 30.9862,
+ -0.189251, 30.9819,
+ -0.212565, 30.9771,
+ -0.235759, 30.9718,
+ -0.258819, 30.9659,
+ -0.281733, 30.9595,
+ -0.304486, 30.9525,
+ -0.327068, 30.945,
+ -0.349464, 30.9369,
+ -0.371662, 30.9284,
+ -0.39365, 30.9193,
+ -0.415415, 30.9096,
+ -0.436945, 30.8995,
+ -0.458227, 30.8888,
+ -0.479249, 30.8777,
+ -0.5, 30.866,
+ -0.520468, 30.8539,
+ -0.540641, 30.8413,
+ -0.560508, 30.8281,
+ -0.580057, 30.8146,
+ -0.599278, 30.8005,
+ -0.618159, 30.7861,
+ -0.63669, 30.7711,
+ -0.654861, 30.7557,
+ -0.67266, 30.74,
+ -0.690079, 30.7237,
+ -0.707107, 30.7071,
+ -0.723734, 30.6901,
+ -0.739951, 30.6727,
+ -0.75575, 30.6549,
+ -0.77112, 30.6367,
+ -0.786053, 30.6182,
+ -0.800541, 30.5993,
+ -0.814576, 30.5801,
+ -0.828149, 30.5605,
+ -0.841254, 30.5406,
+ -0.853881, 30.5205,
+ -0.866025, 30.5,
+ -0.877679, 30.4792,
+ -0.888835, 30.4582,
+ -0.899488, 30.4369,
+ -0.909632, 30.4154,
+ -0.91926, 30.3937,
+ -0.928368, 30.3717,
+ -0.93695, 30.3495,
+ -0.945001, 30.3271,
+ -0.952517, 30.3045,
+ -0.959493, 30.2817,
+ -0.965926, 30.2588,
+ -0.971812, 30.2358,
+ -0.977147, 30.2126,
+ -0.981929, 30.1893,
+ -0.986154, 30.1658,
+ -0.989821, 30.1423,
+ -0.992928, 30.1187,
+ -0.995472, 30.0951,
+ -0.997452, 30.0713,
+ -0.998867, 30.0476,
+ -0.999717, 30.0238,
+ -1, 30,
+ -0.999717, 29.9762,
+ -0.998867, 29.9524,
+ -0.997452, 29.9287,
+ -0.995472, 29.9049,
+ -0.992928, 29.8813,
+ -0.989821, 29.8577,
+ -0.986154, 29.8342,
+ -0.981929, 29.8107,
+ -0.977147, 29.7874,
+ -0.971812, 29.7642,
+ -0.965926, 29.7412,
+ -0.959493, 29.7183,
+ -0.952517, 29.6955,
+ -0.945001, 29.6729,
+ -0.93695, 29.6505,
+ -0.928368, 29.6283,
+ -0.91926, 29.6063,
+ -0.909632, 29.5846,
+ -0.899488, 29.5631,
+ -0.888835, 29.5418,
+ -0.877679, 29.5208,
+ -0.866025, 29.5,
+ -0.853881, 29.4795,
+ -0.841254, 29.4594,
+ -0.828149, 29.4395,
+ -0.814576, 29.4199,
+ -0.800541, 29.4007,
+ -0.786053, 29.3818,
+ -0.77112, 29.3633,
+ -0.75575, 29.3451,
+ -0.739951, 29.3273,
+ -0.723734, 29.3099,
+ -0.707107, 29.2929,
+ -0.690079, 29.2763,
+ -0.67266, 29.26,
+ -0.654861, 29.2443,
+ -0.63669, 29.2289,
+ -0.618159, 29.2139,
+ -0.599278, 29.1995,
+ -0.580057, 29.1854,
+ -0.560508, 29.1719,
+ -0.540641, 29.1587,
+ -0.520468, 29.1461,
+ -0.5, 29.134,
+ -0.479249, 29.1223,
+ -0.458227, 29.1112,
+ -0.436945, 29.1005,
+ -0.415415, 29.0904,
+ -0.39365, 29.0807,
+ -0.371662, 29.0716,
+ -0.349464, 29.0631,
+ -0.327068, 29.055,
+ -0.304486, 29.0475,
+ -0.281733, 29.0405,
+ -0.258819, 29.0341,
+ -0.235759, 29.0282,
+ -0.212565, 29.0229,
+ -0.189251, 29.0181,
+ -0.16583, 29.0138,
+ -0.142315, 29.0102,
+ -0.118719, 29.0071,
+ -0.095056, 29.0045,
+ -0.0713392, 29.0025,
+ -0.0475819, 29.0011,
+ -0.0237977, 29.0003,
+ -1.83697e-16, 29,
+ 0.0237977, 29.0003,
+ 0.0475819, 29.0011,
+ 0.0713392, 29.0025,
+ 0.095056, 29.0045,
+ 0.118719, 29.0071,
+ 0.142315, 29.0102,
+ 0.16583, 29.0138,
+ 0.189251, 29.0181,
+ 0.212565, 29.0229,
+ 0.235759, 29.0282,
+ 0.258819, 29.0341,
+ 0.281733, 29.0405,
+ 0.304486, 29.0475,
+ 0.327068, 29.055,
+ 0.349464, 29.0631,
+ 0.371662, 29.0716,
+ 0.39365, 29.0807,
+ 0.415415, 29.0904,
+ 0.436945, 29.1005,
+ 0.458227, 29.1112,
+ 0.479249, 29.1223,
+ 0.5, 29.134,
+ 0.520468, 29.1461,
+ 0.540641, 29.1587,
+ 0.560508, 29.1719,
+ 0.580057, 29.1854,
+ 0.599278, 29.1995,
+ 0.618159, 29.2139,
+ 0.63669, 29.2289,
+ 0.654861, 29.2443,
+ 0.67266, 29.26,
+ 0.690079, 29.2763,
+ 0.707107, 29.2929,
+ 0.723734, 29.3099,
+ 0.739951, 29.3273,
+ 0.75575, 29.3451,
+ 0.77112, 29.3633,
+ 0.786053, 29.3818,
+ 0.800541, 29.4007,
+ 0.814576, 29.4199,
+ 0.828149, 29.4395,
+ 0.841254, 29.4594,
+ 0.853881, 29.4795,
+ 0.866025, 29.5,
+ 0.877679, 29.5208,
+ 0.888835, 29.5418,
+ 0.899488, 29.5631,
+ 0.909632, 29.5846,
+ 0.91926, 29.6063,
+ 0.928368, 29.6283,
+ 0.93695, 29.6505,
+ 0.945001, 29.6729,
+ 0.952517, 29.6955,
+ 0.959493, 29.7183,
+ 0.965926, 29.7412,
+ 0.971812, 29.7642,
+ 0.977147, 29.7874,
+ 0.981929, 29.8107,
+ 0.986154, 29.8342,
+ 0.989821, 29.8577,
+ 0.992928, 29.8813,
+ 0.995472, 29.9049,
+ 0.997452, 29.9287,
+ 0.998867, 29.9524,
+ 0.999717, 29.9762
+};
+static const unsigned some_segments_segments_count = 1056;
+static const unsigned some_segments_segments[2112] =
+{
+ 0, 1,
+ 1, 2,
+ 2, 3,
+ 3, 4,
+ 4, 5,
+ 5, 6,
+ 6, 7,
+ 7, 8,
+ 8, 9,
+ 9, 10,
+ 10, 11,
+ 11, 12,
+ 12, 13,
+ 13, 14,
+ 14, 15,
+ 15, 16,
+ 16, 17,
+ 17, 18,
+ 18, 19,
+ 19, 20,
+ 20, 21,
+ 21, 22,
+ 22, 23,
+ 23, 24,
+ 24, 25,
+ 25, 26,
+ 26, 27,
+ 27, 28,
+ 28, 29,
+ 29, 30,
+ 30, 31,
+ 31, 32,
+ 32, 33,
+ 33, 34,
+ 34, 35,
+ 35, 36,
+ 36, 37,
+ 37, 38,
+ 38, 39,
+ 39, 40,
+ 40, 41,
+ 41, 42,
+ 42, 43,
+ 43, 44,
+ 44, 45,
+ 45, 46,
+ 46, 47,
+ 47, 48,
+ 48, 49,
+ 49, 50,
+ 50, 51,
+ 51, 52,
+ 52, 53,
+ 53, 54,
+ 54, 55,
+ 55, 56,
+ 56, 57,
+ 57, 58,
+ 58, 59,
+ 59, 60,
+ 60, 61,
+ 61, 62,
+ 62, 63,
+ 63, 64,
+ 64, 65,
+ 65, 66,
+ 66, 67,
+ 67, 68,
+ 68, 69,
+ 69, 70,
+ 70, 71,
+ 71, 72,
+ 72, 73,
+ 73, 74,
+ 74, 75,
+ 75, 76,
+ 76, 77,
+ 77, 78,
+ 78, 79,
+ 79, 80,
+ 80, 81,
+ 81, 82,
+ 82, 83,
+ 83, 84,
+ 84, 85,
+ 85, 86,
+ 86, 87,
+ 87, 88,
+ 88, 89,
+ 89, 90,
+ 90, 91,
+ 91, 92,
+ 92, 93,
+ 93, 94,
+ 94, 95,
+ 95, 96,
+ 96, 97,
+ 97, 98,
+ 98, 99,
+ 99, 100,
+ 100, 101,
+ 101, 102,
+ 102, 103,
+ 103, 104,
+ 104, 105,
+ 105, 106,
+ 106, 107,
+ 107, 108,
+ 108, 109,
+ 109, 110,
+ 110, 111,
+ 111, 112,
+ 112, 113,
+ 113, 114,
+ 114, 115,
+ 115, 116,
+ 116, 117,
+ 117, 118,
+ 118, 119,
+ 119, 120,
+ 120, 121,
+ 121, 122,
+ 122, 123,
+ 123, 124,
+ 124, 125,
+ 125, 126,
+ 126, 127,
+ 127, 128,
+ 128, 129,
+ 129, 130,
+ 130, 131,
+ 131, 132,
+ 132, 133,
+ 133, 134,
+ 134, 135,
+ 135, 136,
+ 136, 137,
+ 137, 138,
+ 138, 139,
+ 139, 140,
+ 140, 141,
+ 141, 142,
+ 142, 143,
+ 143, 144,
+ 144, 145,
+ 145, 146,
+ 146, 147,
+ 147, 148,
+ 148, 149,
+ 149, 150,
+ 150, 151,
+ 151, 152,
+ 152, 153,
+ 153, 154,
+ 154, 155,
+ 155, 156,
+ 156, 157,
+ 157, 158,
+ 158, 159,
+ 159, 160,
+ 160, 161,
+ 161, 162,
+ 162, 163,
+ 163, 164,
+ 164, 165,
+ 165, 166,
+ 166, 167,
+ 167, 168,
+ 168, 169,
+ 169, 170,
+ 170, 171,
+ 171, 172,
+ 172, 173,
+ 173, 174,
+ 174, 175,
+ 175, 176,
+ 176, 177,
+ 177, 178,
+ 178, 179,
+ 179, 180,
+ 180, 181,
+ 181, 182,
+ 182, 183,
+ 183, 184,
+ 184, 185,
+ 185, 186,
+ 186, 187,
+ 187, 188,
+ 188, 189,
+ 189, 190,
+ 190, 191,
+ 191, 192,
+ 192, 193,
+ 193, 194,
+ 194, 195,
+ 195, 196,
+ 196, 197,
+ 197, 198,
+ 198, 199,
+ 199, 200,
+ 200, 201,
+ 201, 202,
+ 202, 203,
+ 203, 204,
+ 204, 205,
+ 205, 206,
+ 206, 207,
+ 207, 208,
+ 208, 209,
+ 209, 210,
+ 210, 211,
+ 211, 212,
+ 212, 213,
+ 213, 214,
+ 214, 215,
+ 215, 216,
+ 216, 217,
+ 217, 218,
+ 218, 219,
+ 219, 220,
+ 220, 221,
+ 221, 222,
+ 222, 223,
+ 223, 224,
+ 224, 225,
+ 225, 226,
+ 226, 227,
+ 227, 228,
+ 228, 229,
+ 229, 230,
+ 230, 231,
+ 231, 232,
+ 232, 233,
+ 233, 234,
+ 234, 235,
+ 235, 236,
+ 236, 237,
+ 237, 238,
+ 238, 239,
+ 239, 240,
+ 240, 241,
+ 241, 242,
+ 242, 243,
+ 243, 244,
+ 244, 245,
+ 245, 246,
+ 246, 247,
+ 247, 248,
+ 248, 249,
+ 249, 250,
+ 250, 251,
+ 251, 252,
+ 252, 253,
+ 253, 254,
+ 254, 255,
+ 255, 256,
+ 256, 257,
+ 257, 258,
+ 258, 259,
+ 259, 260,
+ 260, 261,
+ 261, 262,
+ 262, 263,
+ 263, 0,
+ 264, 265,
+ 265, 266,
+ 266, 267,
+ 267, 268,
+ 268, 269,
+ 269, 270,
+ 270, 271,
+ 271, 272,
+ 272, 273,
+ 273, 274,
+ 274, 275,
+ 275, 276,
+ 276, 277,
+ 277, 278,
+ 278, 279,
+ 279, 280,
+ 280, 281,
+ 281, 282,
+ 282, 283,
+ 283, 284,
+ 284, 285,
+ 285, 286,
+ 286, 287,
+ 287, 288,
+ 288, 289,
+ 289, 290,
+ 290, 291,
+ 291, 292,
+ 292, 293,
+ 293, 294,
+ 294, 295,
+ 295, 296,
+ 296, 297,
+ 297, 298,
+ 298, 299,
+ 299, 300,
+ 300, 301,
+ 301, 302,
+ 302, 303,
+ 303, 304,
+ 304, 305,
+ 305, 306,
+ 306, 307,
+ 307, 308,
+ 308, 309,
+ 309, 310,
+ 310, 311,
+ 311, 312,
+ 312, 313,
+ 313, 314,
+ 314, 315,
+ 315, 316,
+ 316, 317,
+ 317, 318,
+ 318, 319,
+ 319, 320,
+ 320, 321,
+ 321, 322,
+ 322, 323,
+ 323, 324,
+ 324, 325,
+ 325, 326,
+ 326, 327,
+ 327, 328,
+ 328, 329,
+ 329, 330,
+ 330, 331,
+ 331, 332,
+ 332, 333,
+ 333, 334,
+ 334, 335,
+ 335, 336,
+ 336, 337,
+ 337, 338,
+ 338, 339,
+ 339, 340,
+ 340, 341,
+ 341, 342,
+ 342, 343,
+ 343, 344,
+ 344, 345,
+ 345, 346,
+ 346, 347,
+ 347, 348,
+ 348, 349,
+ 349, 350,
+ 350, 351,
+ 351, 352,
+ 352, 353,
+ 353, 354,
+ 354, 355,
+ 355, 356,
+ 356, 357,
+ 357, 358,
+ 358, 359,
+ 359, 360,
+ 360, 361,
+ 361, 362,
+ 362, 363,
+ 363, 364,
+ 364, 365,
+ 365, 366,
+ 366, 367,
+ 367, 368,
+ 368, 369,
+ 369, 370,
+ 370, 371,
+ 371, 372,
+ 372, 373,
+ 373, 374,
+ 374, 375,
+ 375, 376,
+ 376, 377,
+ 377, 378,
+ 378, 379,
+ 379, 380,
+ 380, 381,
+ 381, 382,
+ 382, 383,
+ 383, 384,
+ 384, 385,
+ 385, 386,
+ 386, 387,
+ 387, 388,
+ 388, 389,
+ 389, 390,
+ 390, 391,
+ 391, 392,
+ 392, 393,
+ 393, 394,
+ 394, 395,
+ 395, 396,
+ 396, 397,
+ 397, 398,
+ 398, 399,
+ 399, 400,
+ 400, 401,
+ 401, 402,
+ 402, 403,
+ 403, 404,
+ 404, 405,
+ 405, 406,
+ 406, 407,
+ 407, 408,
+ 408, 409,
+ 409, 410,
+ 410, 411,
+ 411, 412,
+ 412, 413,
+ 413, 414,
+ 414, 415,
+ 415, 416,
+ 416, 417,
+ 417, 418,
+ 418, 419,
+ 419, 420,
+ 420, 421,
+ 421, 422,
+ 422, 423,
+ 423, 424,
+ 424, 425,
+ 425, 426,
+ 426, 427,
+ 427, 428,
+ 428, 429,
+ 429, 430,
+ 430, 431,
+ 431, 432,
+ 432, 433,
+ 433, 434,
+ 434, 435,
+ 435, 436,
+ 436, 437,
+ 437, 438,
+ 438, 439,
+ 439, 440,
+ 440, 441,
+ 441, 442,
+ 442, 443,
+ 443, 444,
+ 444, 445,
+ 445, 446,
+ 446, 447,
+ 447, 448,
+ 448, 449,
+ 449, 450,
+ 450, 451,
+ 451, 452,
+ 452, 453,
+ 453, 454,
+ 454, 455,
+ 455, 456,
+ 456, 457,
+ 457, 458,
+ 458, 459,
+ 459, 460,
+ 460, 461,
+ 461, 462,
+ 462, 463,
+ 463, 464,
+ 464, 465,
+ 465, 466,
+ 466, 467,
+ 467, 468,
+ 468, 469,
+ 469, 470,
+ 470, 471,
+ 471, 472,
+ 472, 473,
+ 473, 474,
+ 474, 475,
+ 475, 476,
+ 476, 477,
+ 477, 478,
+ 478, 479,
+ 479, 480,
+ 480, 481,
+ 481, 482,
+ 482, 483,
+ 483, 484,
+ 484, 485,
+ 485, 486,
+ 486, 487,
+ 487, 488,
+ 488, 489,
+ 489, 490,
+ 490, 491,
+ 491, 492,
+ 492, 493,
+ 493, 494,
+ 494, 495,
+ 495, 496,
+ 496, 497,
+ 497, 498,
+ 498, 499,
+ 499, 500,
+ 500, 501,
+ 501, 502,
+ 502, 503,
+ 503, 504,
+ 504, 505,
+ 505, 506,
+ 506, 507,
+ 507, 508,
+ 508, 509,
+ 509, 510,
+ 510, 511,
+ 511, 512,
+ 512, 513,
+ 513, 514,
+ 514, 515,
+ 515, 516,
+ 516, 517,
+ 517, 518,
+ 518, 519,
+ 519, 520,
+ 520, 521,
+ 521, 522,
+ 522, 523,
+ 523, 524,
+ 524, 525,
+ 525, 526,
+ 526, 527,
+ 527, 264,
+ 528, 529,
+ 529, 530,
+ 530, 531,
+ 531, 532,
+ 532, 533,
+ 533, 534,
+ 534, 535,
+ 535, 536,
+ 536, 537,
+ 537, 538,
+ 538, 539,
+ 539, 540,
+ 540, 541,
+ 541, 542,
+ 542, 543,
+ 543, 544,
+ 544, 545,
+ 545, 546,
+ 546, 547,
+ 547, 548,
+ 548, 549,
+ 549, 550,
+ 550, 551,
+ 551, 552,
+ 552, 553,
+ 553, 554,
+ 554, 555,
+ 555, 556,
+ 556, 557,
+ 557, 558,
+ 558, 559,
+ 559, 560,
+ 560, 561,
+ 561, 562,
+ 562, 563,
+ 563, 564,
+ 564, 565,
+ 565, 566,
+ 566, 567,
+ 567, 568,
+ 568, 569,
+ 569, 570,
+ 570, 571,
+ 571, 572,
+ 572, 573,
+ 573, 574,
+ 574, 575,
+ 575, 576,
+ 576, 577,
+ 577, 578,
+ 578, 579,
+ 579, 580,
+ 580, 581,
+ 581, 582,
+ 582, 583,
+ 583, 584,
+ 584, 585,
+ 585, 586,
+ 586, 587,
+ 587, 588,
+ 588, 589,
+ 589, 590,
+ 590, 591,
+ 591, 592,
+ 592, 593,
+ 593, 594,
+ 594, 595,
+ 595, 596,
+ 596, 597,
+ 597, 598,
+ 598, 599,
+ 599, 600,
+ 600, 601,
+ 601, 602,
+ 602, 603,
+ 603, 604,
+ 604, 605,
+ 605, 606,
+ 606, 607,
+ 607, 608,
+ 608, 609,
+ 609, 610,
+ 610, 611,
+ 611, 612,
+ 612, 613,
+ 613, 614,
+ 614, 615,
+ 615, 616,
+ 616, 617,
+ 617, 618,
+ 618, 619,
+ 619, 620,
+ 620, 621,
+ 621, 622,
+ 622, 623,
+ 623, 624,
+ 624, 625,
+ 625, 626,
+ 626, 627,
+ 627, 628,
+ 628, 629,
+ 629, 630,
+ 630, 631,
+ 631, 632,
+ 632, 633,
+ 633, 634,
+ 634, 635,
+ 635, 636,
+ 636, 637,
+ 637, 638,
+ 638, 639,
+ 639, 640,
+ 640, 641,
+ 641, 642,
+ 642, 643,
+ 643, 644,
+ 644, 645,
+ 645, 646,
+ 646, 647,
+ 647, 648,
+ 648, 649,
+ 649, 650,
+ 650, 651,
+ 651, 652,
+ 652, 653,
+ 653, 654,
+ 654, 655,
+ 655, 656,
+ 656, 657,
+ 657, 658,
+ 658, 659,
+ 659, 660,
+ 660, 661,
+ 661, 662,
+ 662, 663,
+ 663, 664,
+ 664, 665,
+ 665, 666,
+ 666, 667,
+ 667, 668,
+ 668, 669,
+ 669, 670,
+ 670, 671,
+ 671, 672,
+ 672, 673,
+ 673, 674,
+ 674, 675,
+ 675, 676,
+ 676, 677,
+ 677, 678,
+ 678, 679,
+ 679, 680,
+ 680, 681,
+ 681, 682,
+ 682, 683,
+ 683, 684,
+ 684, 685,
+ 685, 686,
+ 686, 687,
+ 687, 688,
+ 688, 689,
+ 689, 690,
+ 690, 691,
+ 691, 692,
+ 692, 693,
+ 693, 694,
+ 694, 695,
+ 695, 696,
+ 696, 697,
+ 697, 698,
+ 698, 699,
+ 699, 700,
+ 700, 701,
+ 701, 702,
+ 702, 703,
+ 703, 704,
+ 704, 705,
+ 705, 706,
+ 706, 707,
+ 707, 708,
+ 708, 709,
+ 709, 710,
+ 710, 711,
+ 711, 712,
+ 712, 713,
+ 713, 714,
+ 714, 715,
+ 715, 716,
+ 716, 717,
+ 717, 718,
+ 718, 719,
+ 719, 720,
+ 720, 721,
+ 721, 722,
+ 722, 723,
+ 723, 724,
+ 724, 725,
+ 725, 726,
+ 726, 727,
+ 727, 728,
+ 728, 729,
+ 729, 730,
+ 730, 731,
+ 731, 732,
+ 732, 733,
+ 733, 734,
+ 734, 735,
+ 735, 736,
+ 736, 737,
+ 737, 738,
+ 738, 739,
+ 739, 740,
+ 740, 741,
+ 741, 742,
+ 742, 743,
+ 743, 744,
+ 744, 745,
+ 745, 746,
+ 746, 747,
+ 747, 748,
+ 748, 749,
+ 749, 750,
+ 750, 751,
+ 751, 752,
+ 752, 753,
+ 753, 754,
+ 754, 755,
+ 755, 756,
+ 756, 757,
+ 757, 758,
+ 758, 759,
+ 759, 760,
+ 760, 761,
+ 761, 762,
+ 762, 763,
+ 763, 764,
+ 764, 765,
+ 765, 766,
+ 766, 767,
+ 767, 768,
+ 768, 769,
+ 769, 770,
+ 770, 771,
+ 771, 772,
+ 772, 773,
+ 773, 774,
+ 774, 775,
+ 775, 776,
+ 776, 777,
+ 777, 778,
+ 778, 779,
+ 779, 780,
+ 780, 781,
+ 781, 782,
+ 782, 783,
+ 783, 784,
+ 784, 785,
+ 785, 786,
+ 786, 787,
+ 787, 788,
+ 788, 789,
+ 789, 790,
+ 790, 791,
+ 791, 528,
+ 792, 793,
+ 793, 794,
+ 794, 795,
+ 795, 796,
+ 796, 797,
+ 797, 798,
+ 798, 799,
+ 799, 800,
+ 800, 801,
+ 801, 802,
+ 802, 803,
+ 803, 804,
+ 804, 805,
+ 805, 806,
+ 806, 807,
+ 807, 808,
+ 808, 809,
+ 809, 810,
+ 810, 811,
+ 811, 812,
+ 812, 813,
+ 813, 814,
+ 814, 815,
+ 815, 816,
+ 816, 817,
+ 817, 818,
+ 818, 819,
+ 819, 820,
+ 820, 821,
+ 821, 822,
+ 822, 823,
+ 823, 824,
+ 824, 825,
+ 825, 826,
+ 826, 827,
+ 827, 828,
+ 828, 829,
+ 829, 830,
+ 830, 831,
+ 831, 832,
+ 832, 833,
+ 833, 834,
+ 834, 835,
+ 835, 836,
+ 836, 837,
+ 837, 838,
+ 838, 839,
+ 839, 840,
+ 840, 841,
+ 841, 842,
+ 842, 843,
+ 843, 844,
+ 844, 845,
+ 845, 846,
+ 846, 847,
+ 847, 848,
+ 848, 849,
+ 849, 850,
+ 850, 851,
+ 851, 852,
+ 852, 853,
+ 853, 854,
+ 854, 855,
+ 855, 856,
+ 856, 857,
+ 857, 858,
+ 858, 859,
+ 859, 860,
+ 860, 861,
+ 861, 862,
+ 862, 863,
+ 863, 864,
+ 864, 865,
+ 865, 866,
+ 866, 867,
+ 867, 868,
+ 868, 869,
+ 869, 870,
+ 870, 871,
+ 871, 872,
+ 872, 873,
+ 873, 874,
+ 874, 875,
+ 875, 876,
+ 876, 877,
+ 877, 878,
+ 878, 879,
+ 879, 880,
+ 880, 881,
+ 881, 882,
+ 882, 883,
+ 883, 884,
+ 884, 885,
+ 885, 886,
+ 886, 887,
+ 887, 888,
+ 888, 889,
+ 889, 890,
+ 890, 891,
+ 891, 892,
+ 892, 893,
+ 893, 894,
+ 894, 895,
+ 895, 896,
+ 896, 897,
+ 897, 898,
+ 898, 899,
+ 899, 900,
+ 900, 901,
+ 901, 902,
+ 902, 903,
+ 903, 904,
+ 904, 905,
+ 905, 906,
+ 906, 907,
+ 907, 908,
+ 908, 909,
+ 909, 910,
+ 910, 911,
+ 911, 912,
+ 912, 913,
+ 913, 914,
+ 914, 915,
+ 915, 916,
+ 916, 917,
+ 917, 918,
+ 918, 919,
+ 919, 920,
+ 920, 921,
+ 921, 922,
+ 922, 923,
+ 923, 924,
+ 924, 925,
+ 925, 926,
+ 926, 927,
+ 927, 928,
+ 928, 929,
+ 929, 930,
+ 930, 931,
+ 931, 932,
+ 932, 933,
+ 933, 934,
+ 934, 935,
+ 935, 936,
+ 936, 937,
+ 937, 938,
+ 938, 939,
+ 939, 940,
+ 940, 941,
+ 941, 942,
+ 942, 943,
+ 943, 944,
+ 944, 945,
+ 945, 946,
+ 946, 947,
+ 947, 948,
+ 948, 949,
+ 949, 950,
+ 950, 951,
+ 951, 952,
+ 952, 953,
+ 953, 954,
+ 954, 955,
+ 955, 956,
+ 956, 957,
+ 957, 958,
+ 958, 959,
+ 959, 960,
+ 960, 961,
+ 961, 962,
+ 962, 963,
+ 963, 964,
+ 964, 965,
+ 965, 966,
+ 966, 967,
+ 967, 968,
+ 968, 969,
+ 969, 970,
+ 970, 971,
+ 971, 972,
+ 972, 973,
+ 973, 974,
+ 974, 975,
+ 975, 976,
+ 976, 977,
+ 977, 978,
+ 978, 979,
+ 979, 980,
+ 980, 981,
+ 981, 982,
+ 982, 983,
+ 983, 984,
+ 984, 985,
+ 985, 986,
+ 986, 987,
+ 987, 988,
+ 988, 989,
+ 989, 990,
+ 990, 991,
+ 991, 992,
+ 992, 993,
+ 993, 994,
+ 994, 995,
+ 995, 996,
+ 996, 997,
+ 997, 998,
+ 998, 999,
+ 999, 1000,
+ 1000, 1001,
+ 1001, 1002,
+ 1002, 1003,
+ 1003, 1004,
+ 1004, 1005,
+ 1005, 1006,
+ 1006, 1007,
+ 1007, 1008,
+ 1008, 1009,
+ 1009, 1010,
+ 1010, 1011,
+ 1011, 1012,
+ 1012, 1013,
+ 1013, 1014,
+ 1014, 1015,
+ 1015, 1016,
+ 1016, 1017,
+ 1017, 1018,
+ 1018, 1019,
+ 1019, 1020,
+ 1020, 1021,
+ 1021, 1022,
+ 1022, 1023,
+ 1023, 1024,
+ 1024, 1025,
+ 1025, 1026,
+ 1026, 1027,
+ 1027, 1028,
+ 1028, 1029,
+ 1029, 1030,
+ 1030, 1031,
+ 1031, 1032,
+ 1032, 1033,
+ 1033, 1034,
+ 1034, 1035,
+ 1035, 1036,
+ 1036, 1037,
+ 1037, 1038,
+ 1038, 1039,
+ 1039, 1040,
+ 1040, 1041,
+ 1041, 1042,
+ 1042, 1043,
+ 1043, 1044,
+ 1044, 1045,
+ 1045, 1046,
+ 1046, 1047,
+ 1047, 1048,
+ 1048, 1049,
+ 1049, 1050,
+ 1050, 1051,
+ 1051, 1052,
+ 1052, 1053,
+ 1053, 1054,
+ 1054, 1055,
+ 1055, 792
+};
+static const unsigned some_segments_properties[3168] =
+{
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 2, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0,
+ 3, 0, 0
+};
+
+#define NB_CIRC 4
+#define CIRC_VRTX_COUNT 264u
+#define CIRC_SEG_COUNT 264u
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc2d_device* dev = NULL;
+ struct senc2d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned e, count;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene */
+ ctx.positions = some_segments_vertices;
+ ctx.indices = some_segments_segments;
+ ctx.properties = some_segments_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ some_segments_segments_count, get_indices, get_media_from_properties,
+ some_segments_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_vertices_count(scn, &count));
+ CHK(count == some_segments_vertices_count);
+ CHK(count == NB_CIRC * CIRC_VRTX_COUNT);
+ OK(senc2d_scene_get_segments_count(scn, &count));
+ CHK(count == some_segments_segments_count);
+ CHK(count == NB_CIRC * CIRC_VRTX_COUNT);
+
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1 + NB_CIRC);
+ FOR_EACH(e, 0, count) {
+ struct senc2d_enclosure* enclosure;
+ struct senc2d_enclosure_header header;
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
+ CHK(header.primitives_count ==
+ (e ? CIRC_SEG_COUNT : NB_CIRC * CIRC_SEG_COUNT));
+ OK(senc2d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_senc2d_square_behind_square.c b/src/test_senc2d_square_behind_square.c
@@ -13,105 +13,198 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This test has been created using the sg2_geometry_dump_as_C_code feature
+ * of star-geometry-2D. It uses output from test_sg2_square_behind_square. */
+
#include "senc2d.h"
#include "test_senc2d_utils.h"
#include <rsys/double2.h>
+/*
+ cube_2 cube_3
+
+ +-----------------------+
+ | 3
+ | |
+ m1 | m0 |
+ | |
+ | |
+ | |
+ | |--> N
+ | |
+ | |
+ +-----------------------+
+ +------------+ +------------+
+ | 2 | 2
+ m0 | m1 | m0 | m1 |
+ | | | |
+ | |--> N | |--> N
+ | | | |
+ +------------+ +------------+
+ +-----+ +-----+
+ m0 | m1 1 m0 | m1 1
+ | |--> N | |--> N
+ +-----+ +-----+
+ */
+
+/* Dump of star-geometry-2D 'square_behind_square_2'. */
+static const unsigned square_behind_square_2_vertices_count = 8;
+static const double square_behind_square_2_vertices[16] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1,
+ -0.2, 2,
+ 2.5, 2,
+ -0.5, 5.3,
+ 2.5, 5
+};
+static const unsigned square_behind_square_2_segments_count = 8;
+static const unsigned square_behind_square_2_segments[16] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0,
+ 4, 6,
+ 6, 7,
+ 7, 5,
+ 5, 4
+};
+static const unsigned square_behind_square_2_properties[24] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0
+};
+/* Dump of star-geometry-2D 'square_behind_square_3'. */
+static const unsigned square_behind_square_3_vertices_count = 12;
+static const double square_behind_square_3_vertices[24] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1,
+ -0.2, 2,
+ 2.5, 2,
+ -0.5, 5.3,
+ 2.5, 5,
+ -0.5, 6,
+ 4, 6,
+ -1, 11.5,
+ 4, 11
+};
+static const unsigned square_behind_square_3_segments_count = 12;
+static const unsigned square_behind_square_3_segments[24] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0,
+ 4, 6,
+ 6, 7,
+ 7, 5,
+ 5, 4,
+ 8, 10,
+ 10, 11,
+ 11, 9,
+ 9, 8
+};
+static const unsigned square_behind_square_3_properties[36] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0
+};
+
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, ecount, maxm;
(void)argc, (void)argv;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create
- (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK);
-
- /* Create the scene */
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- /* First square */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- /* +Y from the first square,
- * big enough to prevent rays from the first square to miss this one */
- d2(ctx.offset, -2, 20);
- ctx.scale = 5;
-
- /* Second square */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene with the first and second squares.
+ * Both squares have medium 1 inside and medium 0 outside,
+ * the second square is +Y from the first square and is big enough
+ * to prevent rays from the first square to miss it. */
+ ctx.positions = square_behind_square_2_vertices;
+ ctx.indices = square_behind_square_2_segments;
+ ctx.properties = square_behind_square_2_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ square_behind_square_2_segments_count, get_indices,
+ get_media_from_properties, square_behind_square_2_vertices_count,
+ get_position, &ctx, &scn));
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 3);
FOR_EACH(i, 0, ecount) {
struct senc2d_enclosure* enclosure;
struct senc2d_enclosure_header header;
- CHK(senc2d_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
ASSERT(header.enclosed_media_count == 1);
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enclosure));
}
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ OK(senc2d_scene_get_max_medium(scn, &maxm));
CHK(maxm == 1);
- check_desc(desc);
-
- /* Even further in +Y, even bigger */
- d2(ctx.offset, -3, 30);
- ctx.scale = 7;
- /* Front/back media have been exchanged: external enclosure shows 2 media */
- ctx.front_media = medium1;
- ctx.back_media = medium0;
-
- /* Third square */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- desc = NULL;
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+
+ /* Create a scene with the 3 squares, same 2 first squares as above
+ * The third square has medium 0 inside and medium 1 outside and is further
+ * in +Y and bigger */
+ ctx.positions = square_behind_square_3_vertices;
+ ctx.indices = square_behind_square_3_segments;
+ ctx.properties = square_behind_square_3_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ square_behind_square_3_segments_count, get_indices,
+ get_media_from_properties, square_behind_square_3_vertices_count,
+ get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 4);
FOR_EACH(i, 0, ecount) {
struct senc2d_enclosure* enclosure;
struct senc2d_enclosure_header header;
- CHK(senc2d_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
+ /* Inside enclosures contain 1 single media */
ASSERT(header.enclosed_media_count == (header.is_infinite ? 2u : 1u));
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enclosure));
}
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ OK(senc2d_scene_get_max_medium(scn, &maxm));
CHK(maxm == 1);
- check_desc(desc);
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_senc2d_square_in_square.c b/src/test_senc2d_square_in_square.c
@@ -13,102 +13,198 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This test has been created using the sg2_geometry_dump_as_C_code feature
+ * of star-geometry-2D. It uses output from test_sg2_square_in_square. */
+
#include "senc2d.h"
#include "test_senc2d_utils.h"
#include <rsys/double2.h>
+/*
+ square_2 square_3
+
+ +-------------------------+
+ | B
+ +-------------+ | +-------------+ |
+ m1 | m0 M m1 | m1 | m0 M |
+ | +------+ | | m0 | +------+ | |
+ | | m1 S | | | | m1 S | |
+ | | N <--| | | | | N <--| | |
+ | +------+ | | | +------+ | |
+ | N <--| | | N <--| |
+ +-------------+ | +-------------+ |
+ | N <--|
+ +-------------------------+
+ */
+
+/* Dump of star-geometry-2D 'square_in_square_2'. */
+static const unsigned square_in_square_2_vertices_count = 8;
+static const double square_in_square_2_vertices[16] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1,
+ -0.7, -1,
+ 2, -1,
+ -1, 2.3,
+ 2, 2
+};
+static const unsigned square_in_square_2_segments_count = 8;
+static const unsigned square_in_square_2_segments[16] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0,
+ 6, 4,
+ 7, 6,
+ 5, 7,
+ 4, 5
+};
+static const unsigned square_in_square_2_properties[24] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0
+};
+/* Dump of star-geometry-2D 'square_in_square_3'. */
+static const unsigned square_in_square_3_vertices_count = 12;
+static const double square_in_square_3_vertices[24] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1,
+ -0.7, -1,
+ 2, -1,
+ -1, 2.3,
+ 2, 2,
+ -3, -4,
+ 6, -4,
+ -4, 7,
+ 6, 6
+};
+static const unsigned square_in_square_3_segments_count = 12;
+static const unsigned square_in_square_3_segments[24] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0,
+ 6, 4,
+ 7, 6,
+ 5, 7,
+ 4, 5,
+ 10, 8,
+ 11, 10,
+ 9, 11,
+ 8, 9
+};
+static const unsigned square_in_square_3_properties[36] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0
+};
+
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
- struct context ctx;
- unsigned i, ecount, maxm;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned e, ecount, maxm, e2;
(void)argc, (void)argv;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create
- (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK);
-
- /* Create the scene */
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
- /* Smallest square exterior is medium 0 */
- ctx.front_media = medium0;
- /* Smallest square interior is medium 1 */
- ctx.back_media = medium1;
-
- /* First square */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- d2(ctx.offset, -1, -1);
- ctx.scale = 3;
- /* Bigger square exterior is medium 1 */
- /* Bigger square interior is medium 0 */
- ctx.reverse_vrtx = 1;
-
- /* Second square */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene with the first and second squares.
+ * The enclosure in the small contains medium 1, the external enclosure
+ * contains medium 1, the enclosure between the small and medium squares
+ * contains medium 0. */
+ ctx.positions = square_in_square_2_vertices;
+ ctx.indices = square_in_square_2_segments;
+ ctx.properties = square_in_square_2_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ square_in_square_2_segments_count, get_indices, get_media_from_properties,
+ square_in_square_2_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 3);
- FOR_EACH(i, 0, ecount) {
+ FOR_EACH(e, 0, ecount) {
struct senc2d_enclosure* enclosure;
struct senc2d_enclosure_header header;
- CHK(senc2d_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ unsigned m;
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
ASSERT(header.enclosed_media_count == 1);
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &m));
+ ASSERT(m <= 1);
+ ASSERT((m == 0) == (header.primitives_count == square_in_square_2_segments_count));
+ OK(senc2d_enclosure_ref_put(enclosure));
}
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ OK(senc2d_scene_get_max_medium(scn, &maxm));
CHK(maxm == 1);
- check_desc(desc);
-
- d2(ctx.offset, -4, -4);
- ctx.scale = 10;
- ctx.reverse_vrtx = 1;
- ctx.reverse_med = 1;
- /* Biggest square exterior is medium 1 */
- ctx.front_media = medium1;
- /* Biggest square interior is medium 0
- * interior/exterior media have been exchanged: external enclosure shows 2 media */
- ctx.back_media = medium0;
-
- /* Third square */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
- desc = NULL;
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+
+ /* Create a scene with the 3 squares, same 2 first squares as above.
+ * The enclosure in the small square contains medium 1, the external enclosure
+ * contains medium 1, the enclosure between the small and medium squares
+ * contains medium 0 and the enclosure between the medium and big squares
+ * contains both media 0 and 1. */
+ ctx.positions = square_in_square_3_vertices;
+ ctx.indices = square_in_square_3_segments;
+ ctx.properties = square_in_square_3_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ square_in_square_3_segments_count, get_indices, get_media_from_properties,
+ square_in_square_3_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 4);
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ e2 = ecount;
+ FOR_EACH(e, 0, ecount) {
+ struct senc2d_enclosure* enclosure;
+ struct senc2d_enclosure_header header;
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
+ ASSERT(header.enclosed_media_count <= 2);
+ if(header.enclosed_media_count == 2) {
+ /* A single internal enclosure has 2 media */
+ ASSERT(!header.is_infinite);
+ ASSERT(e2 == ecount); (void)e2;
+ e2 = e;
+ }
+ OK(senc2d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc2d_scene_get_max_medium(scn, &maxm));
CHK(maxm == 1);
- check_desc(desc);
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_senc2d_square_on_square.c b/src/test_senc2d_square_on_square.c
@@ -13,6 +13,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This test has been created using the sg2_geometry_dump_as_C_code feature
+ * of star-geometry-2D. It uses output from test_sg2_square_on_square. */
+
#define _POSIX_C_SOURCE 200112L /* snprintf */
#include "senc2d.h"
@@ -22,108 +25,122 @@
#include <stdio.h>
-/*
- Y
- ^
-4 | +-----------------------+
- | | 3
-3 | | +-----+ |
- | m2 | m1 | m0 2 |
- | | | | |
-2 | | +-----+ |
- | | | m0 1 |
- | | | | |
-1 | | +-----+ |
- | | |
-0 - +-----------------------+
-
- |--------------------------> X
- 0 1 2 3 4
-*/
+/*
+ +-----------------------+
+ | 3
+ | +------+ |
+ m2 | m1 | m0 2 |
+ | | |--> N |
+ | +------+ |
+ | | m0 1 |
+ | | |--> N |
+ | +------+ |
+ |--> N |
+ +-----------------------+
+ */
+
+/* Dump of star-geometry-2D 'square_on_square'. */
+static const unsigned square_on_square_vertices_count = 10;
+static const double square_on_square_vertices[20] =
+{
+ 1, 1,
+ 2, 1,
+ 1, 2,
+ 2, 2,
+ 1, 3,
+ 2, 3,
+ 0.4, 0,
+ 4, 0,
+ 0, 4.4,
+ 4, 4
+};
+static const unsigned square_on_square_segments_count = 11;
+static const unsigned square_on_square_segments[22] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0,
+ 2, 4,
+ 4, 5,
+ 5, 3,
+ 8, 6,
+ 9, 8,
+ 7, 9,
+ 6, 7
+};
+static const unsigned square_on_square_properties[33] =
+{
+ 1, 0, 0,
+ 0, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0,
+ 1, 2, 0
+};
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
- struct context ctx;
- unsigned count, i;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned count, e;
(void)argc, (void)argv;
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- CHK(senc2d_device_create
- (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK);
-
- /* Create the scene */
- CHK(senc2d_scene_create(dev,
- SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
- == RES_OK);
-
- ctx.positions = square_vertices; /* Need true squares for squares #1 and #2 */
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 1, 1);
- /* Small square #1 exterior is medium 1,
- * except for the top face where it is 0 */
- ctx.front_media = medium1_front0;
- /* Smallest square interior is medium 0 */
- ctx.back_media = medium0;
-
- /* Add square #1 */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- d2(ctx.offset, 1, 2);
- ctx.scale = 1;
- /* Small square #2 exterior is medium 1,
- * except for the bottom face where it is 0 */
- ctx.front_media = medium1_back0;
- /* Smallest square interior is medium 0 */
- ctx.back_media = medium0;
-
- /* Add square #2 (has a duplicate face with square #1) */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- ctx.positions = box_vertices; /* Can use distorded square for square #3 */
- d2(ctx.offset, 0, 0);
- ctx.scale = 4;
- ctx.reverse_vrtx = 1;
- ctx.reverse_med = 1;
- /* Big square #3 exterior is medium 2 */
- ctx.front_media = medium2;
- /* Big square #3 interior is medium 1 */
- ctx.back_media = medium1;
-
- /* Add square #3 */
- CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc2d_descriptor_get_enclosure_count(desc, &count) == RES_OK);
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene with the squares.
+ * The enclosures in the small squares contain medium 0, the external enclosure
+ * contains medium 2, the enclosure between the small and big squares
+ * contains medium 1. */
+ ctx.positions = square_on_square_vertices;
+ ctx.indices = square_on_square_segments;
+ ctx.properties = square_on_square_properties;
+ OK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE,
+ square_on_square_segments_count, get_indices, get_media_from_properties,
+ square_on_square_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
CHK(count == 4);
- CHK(senc2d_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
- CHK(count == 10);
+ OK(senc2d_scene_get_vertices_count(scn, &count));
+ CHK(count == square_on_square_vertices_count);
- CHK(senc2d_descriptor_get_global_segments_count(desc, &count) == RES_OK);
- CHK(count == 11);
+ OK(senc2d_scene_get_segments_count(scn, &count));
+ CHK(count == square_on_square_segments_count);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &count) == RES_OK);
- FOR_EACH(i, 0, count) {
- char name[128];
- snprintf(name, sizeof(name), "test2d_square_on_square_%u.obj", i);
- dump_enclosure(desc, i, name);
+ OK(senc2d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 4);
+ FOR_EACH(e, 0, count) {
+ struct senc2d_enclosure* enclosure;
+ struct senc2d_enclosure_header header;
+ unsigned m;
+ char name[128]; (void)name;
+ OK(senc2d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
+ CHK(header.enclosed_media_count == 1);
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &m));
+ if(header.is_infinite) ASSERT(m == 2); /* External */
+ else if(header.primitives_count == 4) ASSERT(m == 0); /* Internal */
+ else ASSERT(m == 1); /* In between */
+ OK(senc2d_enclosure_ref_put(enclosure));
+#ifdef DUMP_ENCLOSURES
+ snprintf(name, sizeof(name), "test_square_on_square_%u.obj", e);
+ dump_enclosure(scn, e, name);
+#endif
}
- CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
- if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ OK(senc2d_scene_ref_put(scn));
+ OK(senc2d_device_ref_put(dev));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_senc2d_undefined_medium.c b/src/test_senc2d_undefined_medium.c
@@ -13,17 +13,96 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This test has been created using the sg2_geometry_dump_as_C_code feature
+ * of star-geometry-2D. It uses output from test_sg2_undefined_properties.
+ * This test is similar to test_senc2d_many_enclosures that creates a huge
+ * geometry by program. */
+
#include "senc2d.h"
-#include "senc2d_s2d_wrapper.h"
+#include "senc2d_sXd_helper.h"
#include "test_senc2d_utils.h"
#include <rsys/double2.h>
+#define SG2_UNDEFINED_PROPERTY UINT_MAX
+
+/* Dump of star-geometry-2D 'front_undefined'. */
+static const unsigned front_undefined_vertices_count = 4;
+static const double front_undefined_vertices[8] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1
+};
+static const unsigned front_undefined_segments_count = 4;
+static const unsigned front_undefined_segments[8] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0
+};
+static const unsigned front_undefined_properties[12] =
+{
+ SG2_UNDEFINED_PROPERTY, 1, SG2_UNDEFINED_PROPERTY,
+ SG2_UNDEFINED_PROPERTY, 1, SG2_UNDEFINED_PROPERTY,
+ SG2_UNDEFINED_PROPERTY, 1, SG2_UNDEFINED_PROPERTY,
+ SG2_UNDEFINED_PROPERTY, 1, SG2_UNDEFINED_PROPERTY
+};
+/* Dump of star-geometry-2D 'front_half_undefined'. */
+static const unsigned front_half_undefined_vertices_count = 4;
+static const double front_half_undefined_vertices[8] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1
+};
+static const unsigned front_half_undefined_segments_count = 4;
+static const unsigned front_half_undefined_segments[8] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0
+};
+static const unsigned front_half_undefined_properties[12] =
+{
+ SG2_UNDEFINED_PROPERTY, 1, SG2_UNDEFINED_PROPERTY,
+ 0, 1, 0,
+ SG2_UNDEFINED_PROPERTY, 1, SG2_UNDEFINED_PROPERTY,
+ 0, 1, 0
+};
+/* Dump of star-geometry-2D 'all_defined'. */
+static const unsigned all_defined_vertices_count = 4;
+static const double all_defined_vertices[8] =
+{
+ 0.1, 0,
+ 1, 0,
+ 0, 1.1,
+ 1, 1
+};
+static const unsigned all_defined_segments_count = 4;
+static const unsigned all_defined_segments[8] =
+{
+ 0, 2,
+ 2, 3,
+ 3, 1,
+ 1, 0
+};
+static const unsigned all_defined_properties[12] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0
+};
+
static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
struct senc2d_device* dev = NULL;
struct senc2d_scene* scn = NULL;
struct senc2d_enclosure* enclosure;
@@ -31,236 +110,145 @@ test(const int convention)
unsigned medium, expected_external_medium, expected_internal_medium;
unsigned gid;
enum senc2d_side side;
- struct context ctx;
- unsigned i, s, ecount, vcount, scount;
- unsigned media[4];
- unsigned rev_box_indices[sizeof(box_indices) / sizeof(*box_indices)];
- int conv_front;
-
- conv_front = (convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned i, s, ecount;
+ const int conv_front = (convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
- /* Create a box with reversed segments */
- FOR_EACH(i, 0, sizeof(rev_box_indices) / sizeof(*rev_box_indices)) {
- switch (i % 2) {
- case 0: rev_box_indices[i] = box_indices[i + 1]; break;
- case 1: rev_box_indices[i] = box_indices[i - 1]; break;
- }
- }
OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
-
- OK(senc2d_scene_create(dev, convention, &scn));
-
- /* A 2D square.
- * 2 enclosures (inside, outside) sharing the same segments,
- * but opposite sides */
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
- ctx.front_media = media;
- ctx.back_media = medium1;
-
- /* Can add the same segments again defined/undefined media in any order */
-
- /* Add geometry with no media information on both sides */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = SENC2D_UNDEFINED_MEDIUM;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 2 * nsegments);
-
- /* Add geometry with no media information on the front sides */
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == nsegments);
-
- /* Analyze with undefined media on the front sides */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_get_enclosure_count(desc, &ecount));
+
+ /* Geometry with no media information on both sides */
+ ctx.positions = front_undefined_vertices;
+ ctx.indices = front_undefined_segments;
+ ctx.properties = front_undefined_properties;
+ OK(senc2d_scene_create(dev, convention, front_undefined_segments_count,
+ get_indices, get_media_from_properties, front_undefined_vertices_count,
+ get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 2);
FOR_EACH(i, 0, ecount) {
struct senc2d_enclosure* ee;
struct senc2d_enclosure_header hh;
unsigned cc;
- OK(senc2d_descriptor_get_enclosure(desc, i, &enclosure));
+ OK(senc2d_scene_get_enclosure(scn, i, &enclosure));
OK(senc2d_enclosure_get_header(enclosure, &header));
CHK(header.enclosure_id == i);
CHK(header.enclosed_media_count == 1);
OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input segments:
+ /* Geometrical normals point outside the square in input segments:
* if convention is front, front medium (undef) is outside,
* that is medium 0's enclosure is infinite */
- expected_external_medium = conv_front ? SENC2D_UNDEFINED_MEDIUM : 1;
- expected_internal_medium = conv_front ? 1 : SENC2D_UNDEFINED_MEDIUM;
+ expected_external_medium = conv_front ? SENC2D_UNSPECIFIED_MEDIUM : 1;
+ expected_internal_medium = conv_front ? 1 :SENC2D_UNSPECIFIED_MEDIUM;
CHK(medium == (header.is_infinite
? expected_external_medium : expected_internal_medium));
- CHK(header.segment_count == nsegments);
- CHK(header.unique_segment_count == nsegments);
+ CHK(header.primitives_count == nsegments);
+ CHK(header.unique_primitives_count == nsegments);
CHK(header.vertices_count == nvertices);
CHK(header.is_infinite == (i == 0));
- OK(senc2d_descriptor_get_enclosure_count_by_medium(desc, medium, &cc));
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, medium, &cc));
CHK(cc == 1);
- OK(senc2d_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee));
+ OK(senc2d_scene_get_enclosure_by_medium(scn, medium, 0, &ee));
OK(senc2d_enclosure_get_header(ee, &hh));
CHK(header.enclosure_id == hh.enclosure_id);
OK(senc2d_enclosure_ref_put(ee));
- FOR_EACH(s, 0, header.segment_count) {
+ FOR_EACH(s, 0, header.primitives_count) {
unsigned ind[2];
- OK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side));
- CHK(side == (medium == 1) ? SENC2D_BACK : SENC2D_FRONT);
+ OK(senc2d_enclosure_get_segment_id(enclosure, s, &gid, &side));
CHK(gid == s);
+ CHK(side == (medium == 1) ? SENC2D_BACK : SENC2D_FRONT);
OK(senc2d_enclosure_get_segment(enclosure, s, ind));
}
OK(senc2d_enclosure_ref_put(enclosure));
}
- OK(senc2d_descriptor_ref_put(desc));
-
+ OK(senc2d_scene_ref_put(scn));
/* Same geometry, front media are defined for odd segments */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = (i % 2) ? 0 : SENC2D_UNDEFINED_MEDIUM;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == nsegments / 2);
-
- /* Analyze with undefined media */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_ref_put(desc));
-
- /* Get the deduplicated geometry without (successful) analyze */
- OK(senc2d_scene_get_unique_vertices_count(scn, &vcount));
- CHK(vcount == nvertices);
- OK(senc2d_scene_get_unique_segments_count(scn, &scount));
- CHK(vcount == nsegments);
- FOR_EACH(i, 0, vcount) {
- int j;
- unsigned med[2], ids[2];
- OK(senc2d_scene_get_unique_segment(scn, i, ids));
- OK(senc2d_scene_get_unique_segment_media(scn, i, med));
- CHK(med[0] == ((i % 2) ? 0 : SENC2D_UNDEFINED_MEDIUM) && med[1] == 1);
- FOR_EACH(j, 0, 2) {
- double pos[2];
- CHK(ids[j] < vcount);
- OK(senc2d_scene_get_unique_vertex(scn, ids[j], pos));
- }
- }
-
- /* Same information again, using a reversed box */
- ctx.indices = rev_box_indices;
- SWAP(const unsigned*, ctx.front_media, ctx.back_media);
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == nsegments / 2);
+ ctx.positions = front_half_undefined_vertices;
+ ctx.indices = front_half_undefined_segments;
+ ctx.properties = front_half_undefined_properties;
+ OK(senc2d_scene_create(dev, convention, front_half_undefined_segments_count,
+ get_indices, get_media_from_properties, front_half_undefined_vertices_count,
+ get_position, &ctx, &scn));
+
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 2);
- /* Analyze with undefined media */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_ref_put(desc));
+ FOR_EACH(i, 0, ecount) {
+ unsigned expected_external_media_count, expected_internal_media_count,
+ expected_media_count;
+ OK(senc2d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
- /* Define media for remaining segments, using reversed box */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = (i % 2) ? SENC2D_UNDEFINED_MEDIUM : 0;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 0);
+ CHK(header.enclosure_id == i);
- /* Get the deduplicated geometry without (successful) analyze */
- OK(senc2d_scene_get_unique_vertices_count(scn, &vcount));
- CHK(vcount == nvertices);
- OK(senc2d_scene_get_unique_segments_count(scn, &scount));
- CHK(scount == nsegments);
- FOR_EACH(i, 0, scount) {
- int j;
- unsigned med[2], ids[2];
- OK(senc2d_scene_get_unique_segment(scn, i, ids));
- OK(senc2d_scene_get_unique_segment_media(scn, i, med));
- CHK(med[0] == 0 && med[1] == 1);
- FOR_EACH(j, 0, 2) {
- double pos[2];
- CHK(ids[j] < vcount);
- OK(senc2d_scene_get_unique_vertex(scn, ids[j], pos));
- }
+ OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
+ /* Geometrical normals point outside the square in input segments:
+ * if convention is front, front medium is outside and the enclosure
+ * contains 2 media */
+ expected_external_media_count = conv_front ? 2 : 1;
+ expected_internal_media_count = conv_front ? 1 : 2;
+ expected_media_count = header.is_infinite
+ ? expected_external_media_count : expected_internal_media_count;
+ CHK(header.enclosed_media_count == expected_media_count);
+ OK(senc2d_enclosure_ref_put(enclosure));
}
+ OK(senc2d_scene_ref_put(scn));
- /* Analyze with all media defined */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_ref_put(desc));
-
- /* Define media for all segments, nothing new here */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = 0;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 0);
+ /* Same geometry, all media are defined */
+ ctx.positions = all_defined_vertices;
+ ctx.indices = all_defined_segments;
+ ctx.properties = all_defined_properties;
+ OK(senc2d_scene_create(dev, convention, all_defined_segments_count,
+ get_indices, get_media_from_properties, all_defined_vertices_count,
+ get_position, &ctx, &scn));
- /* Define incoherent media for some segments */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = (i % 2);
- BA(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 0);
-
- /* Scene is still OK and can be analyzed */
- OK(senc2d_scene_analyze(scn, &desc));
-
- OK(senc2d_descriptor_get_global_segments_count(desc, &scount));
- CHK(scount == sizeof(media) / sizeof(*media));
-
- OK(senc2d_descriptor_get_enclosure_count(desc, &ecount));
+ OK(senc2d_scene_get_enclosure_count(scn, &ecount));
CHK(ecount == 2);
FOR_EACH(i, 0, ecount) {
struct senc2d_enclosure* ee;
struct senc2d_enclosure_header hh;
unsigned cc;
- OK(senc2d_descriptor_get_enclosure(desc, i, &enclosure));
+ OK(senc2d_scene_get_enclosure(scn, i, &enclosure));
OK(senc2d_enclosure_get_header(enclosure, &header));
CHK(header.enclosure_id == i);
CHK(header.enclosed_media_count == 1);
OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input segments:
+ /* Geometrical normals point outside the square in input segments:
* if convention is front, front medium (0) is outside,
* that is medium 0's enclosure is infinite */
CHK(conv_front == ((medium == 0) == header.is_infinite));
- CHK(header.segment_count == nsegments);
- CHK(header.unique_segment_count == nsegments);
+ CHK(header.primitives_count == nsegments);
+ CHK(header.unique_primitives_count == nsegments);
CHK(header.vertices_count == nvertices);
CHK(header.is_infinite == (i == 0));
- OK(senc2d_descriptor_get_enclosure_count_by_medium(desc, medium, &cc));
+ OK(senc2d_scene_get_enclosure_count_by_medium(scn, medium, &cc));
CHK(cc == 1);
- OK(senc2d_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee));
+ OK(senc2d_scene_get_enclosure_by_medium(scn, medium, 0, &ee));
OK(senc2d_enclosure_get_header(ee, &hh));
CHK(header.enclosure_id == hh.enclosure_id);
OK(senc2d_enclosure_ref_put(ee));
- FOR_EACH(s, 0, header.segment_count) {
- OK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side));
- CHK(side == (medium == 1) ? SENC2D_BACK : SENC2D_FRONT);
+ FOR_EACH(s, 0, header.primitives_count) {
+ OK(senc2d_enclosure_get_segment_id(enclosure, s, &gid, &side));
CHK(gid == s);
+ CHK(side == (medium == 1) ? SENC2D_BACK : SENC2D_FRONT);
}
OK(senc2d_enclosure_ref_put(enclosure));
}
SENC2D(scene_ref_put(scn));
SENC2D(device_ref_put(dev));
- SENC2D(descriptor_ref_put(desc));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_senc2d_undefined_medium_attr.c b/src/test_senc2d_undefined_medium_attr.c
@@ -1,376 +0,0 @@
-/* Copyright (C) |Meso|Star> 2018-2020 (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/>. */
-
-#include "senc2d.h"
-#include "senc2d_s2d_wrapper.h"
-#include "test_senc2d_utils.h"
-
-#include <rsys/double2.h>
-
-#include <limits.h>
-
-#define INVALID_INTFACE_ID UINT_MAX
-
-static FINLINE void
-set_null_id(struct mem_allocator* alloc, unsigned* data)
-{
- ASSERT(data); (void)alloc;
- *data = INVALID_INTFACE_ID;
-}
-
-#include <rsys/dynamic_array.h>
-#define DARRAY_NAME intface_id
-#define DARRAY_FUNCTOR_INIT set_null_id
-#define DARRAY_DATA unsigned
-#include <rsys/dynamic_array.h>
-
-/* Manage interface properties */
-struct merge_ctx {
- struct darray_intface_id global_interf_data;
- const unsigned* current_add_interf_data;
-};
-
-static res_T
-add_seg
- (const unsigned global_id,
- const unsigned iseg,
- void* context)
-{
- res_T res = RES_OK;
- struct context* ctx = context;
- struct merge_ctx* merge_ctx;
- unsigned interf;
- ASSERT(ctx);
- merge_ctx = ctx->custom;
- /* Get interface information from ctx */
- interf = merge_ctx->current_add_interf_data[iseg];
- /* Keep data */
- res = darray_intface_id_resize(&merge_ctx->global_interf_data, global_id + 1);
- if(res != RES_OK) return res;
- darray_intface_id_data_get(&merge_ctx->global_interf_data)[global_id] = interf;
- return res;
-}
-
-static res_T
-merge_seg
- (const unsigned global_id,
- const unsigned iseg,
- const int reversed_segment,
- const unsigned segment_media[2],
- const unsigned merge_media[2],
- void* context)
-{
- res_T res = RES_OK;
- struct context* ctx = context;
- struct merge_ctx* merge_ctx;
- int need_merge;
- unsigned interf;
- unsigned* interf_data;
- int i, compat;
- ASSERT(ctx); (void)reversed_segment;
- /* Check media compatibility */
- compat = 1;
- FOR_EACH(i, 0, 2)
- compat &= (segment_media[i] == SENC2D_UNDEFINED_MEDIUM
- || merge_media[i] == SENC2D_UNDEFINED_MEDIUM
- || segment_media[i] == merge_media[i]);
- if(!compat) return RES_BAD_ARG;
- merge_ctx = ctx->custom;
- res = darray_intface_id_resize(&merge_ctx->global_interf_data, global_id + 1);
- if(res != RES_OK) return res;
- /* Get interface information from ctx */
- interf = merge_ctx->current_add_interf_data[iseg];
- interf_data = darray_intface_id_data_get(&merge_ctx->global_interf_data);
-
- need_merge = (interf_data[global_id] != INVALID_INTFACE_ID);
- if(need_merge) {
- if(interf_data[global_id] != interf)
- /* Previous interface id is different: no possible merge */
- return RES_BAD_ARG;
- } else {
- /* Segment is known, but without interface information: create */
- interf_data[global_id] = interf;
- }
- /* Same data: no merge needed */
- return RES_OK;
-}
-
-static void
-test(const int convention)
-{
- struct mem_allocator allocator;
- struct senc2d_descriptor* desc = NULL;
- struct senc2d_device* dev = NULL;
- struct senc2d_scene* scn = NULL;
- struct senc2d_enclosure* enclosure;
- struct senc2d_enclosure_header header;
- unsigned medium, expected_external_medium, expected_internal_medium;
- unsigned gid;
- enum senc2d_side side;
- struct context ctx;
- unsigned i, s, ecount, vcount, scount;
- unsigned media[4], interface_ids[4] = { 0, 0, 1, 1, };
- unsigned rev_box_indices[sizeof(box_indices) / sizeof(*box_indices)];
- struct merge_ctx merge_ctx;
- int conv_front = (convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
-
- darray_intface_id_init(&allocator, &merge_ctx.global_interf_data);
- merge_ctx.current_add_interf_data = interface_ids;
-
- /* Create a box with reversed segments */
- FOR_EACH(i, 0, sizeof(rev_box_indices) / sizeof(*rev_box_indices)) {
- switch (i % 2) {
- case 0: rev_box_indices[i] = box_indices[i + 1]; break;
- case 1: rev_box_indices[i] = box_indices[i - 1]; break;
- }
- }
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev));
-
- OK(senc2d_scene_create(dev, convention, &scn));
-
- /* A 2D square.
- * 2 enclosures (inside, outside) sharing the same segments,
- * but opposite sides */
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d2(ctx.offset, 0, 0);
- ctx.front_media = media;
- ctx.back_media = medium1;
- ctx.custom = &merge_ctx;
-
- /* Can add the same segments again defined/undefined media in any order */
-
- /* Add geometry with no media information on both sides */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = SENC2D_UNDEFINED_MEDIUM;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 2 * nsegments);
-
- /* If merge fails, add geometry fails */
- interface_ids[0] = 6;
- BA(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- interface_ids[0] = 0;
-
- /* Add geometry with no media information on the front sides */
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == nsegments);
-
- /* Analyze with undefined media on the front sides */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_get_enclosure_count(desc, &ecount));
- CHK(ecount == 2);
-
- FOR_EACH(i, 0, ecount) {
- struct senc2d_enclosure* ee;
- struct senc2d_enclosure_header hh;
- unsigned cc;
- OK(senc2d_descriptor_get_enclosure(desc, i, &enclosure));
- OK(senc2d_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == i);
- CHK(header.enclosed_media_count == 1);
-
- OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input segments:
- * if convention is front, front medium (undef) is outside,
- * that is medium 0's enclosure is infinite */
- expected_external_medium = conv_front ? SENC2D_UNDEFINED_MEDIUM : 1;
- expected_internal_medium = conv_front ? 1 : SENC2D_UNDEFINED_MEDIUM;
-
- CHK(medium == (header.is_infinite
- ? expected_external_medium : expected_internal_medium));
- CHK(header.segment_count == nsegments);
- CHK(header.unique_segment_count == nsegments);
- CHK(header.vertices_count == nvertices);
- CHK(header.is_infinite == (i == 0));
-
- OK(senc2d_descriptor_get_enclosure_count_by_medium(desc, medium, &cc));
- CHK(cc == 1);
- OK(senc2d_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee));
- OK(senc2d_enclosure_get_header(ee, &hh));
- CHK(header.enclosure_id == hh.enclosure_id);
- OK(senc2d_enclosure_ref_put(ee));
-
- FOR_EACH(s, 0, header.segment_count) {
- unsigned ind[2];
- OK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side));
- CHK(gid == s);
- CHK(side == (medium == 1) ? SENC2D_BACK : SENC2D_FRONT);
- OK(senc2d_enclosure_get_segment(enclosure, s, ind));
- }
- OK(senc2d_enclosure_ref_put(enclosure));
- }
- OK(senc2d_descriptor_ref_put(desc));
-
- /* Same geometry, front media are defined for odd segments */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = (i % 2) ? 0 : SENC2D_UNDEFINED_MEDIUM;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == nsegments / 2);
-
- /* Analyze with undefined media */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_ref_put(desc));
-
- /* Get the deduplicated geometry without (successful) analyze */
- OK(senc2d_scene_get_unique_vertices_count(scn, &vcount));
- CHK(vcount == nvertices);
- OK(senc2d_scene_get_unique_segments_count(scn, &scount));
- CHK(scount == nsegments);
- FOR_EACH(i, 0, scount) {
- int j;
- unsigned med[2], ids[2];
- OK(senc2d_scene_get_unique_segment(scn, i, ids));
- OK(senc2d_scene_get_unique_segment_media(scn, i, med));
- CHK(med[0] == ((i % 2) ? 0 : SENC2D_UNDEFINED_MEDIUM) && med[1] == 1);
- FOR_EACH(j, 0, 2) {
- double pos[2];
- CHK(ids[j] < vcount);
- OK(senc2d_scene_get_unique_vertex(scn, ids[j], pos));
- }
- }
-
- /* Same information again, using a reversed box */
- ctx.indices = rev_box_indices;
- SWAP(const unsigned*, ctx.front_media, ctx.back_media);
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == nsegments / 2);
-
- /* Analyze with undefined media */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_ref_put(desc));
-
- /* Define media for remaining segments, using reversed box */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = (i % 2) ? SENC2D_UNDEFINED_MEDIUM : 0;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 0);
-
- /* Get the deduplicated geometry without (successful) analyze */
- OK(senc2d_scene_get_unique_vertices_count(scn, &vcount));
- CHK(vcount == nvertices);
- OK(senc2d_scene_get_unique_segments_count(scn, &scount));
- CHK(scount == nsegments);
- FOR_EACH(i, 0, scount) {
- int j;
- unsigned med[2], ids[2];
- OK(senc2d_scene_get_unique_segment(scn, i, ids));
- OK(senc2d_scene_get_unique_segment_media(scn, i, med));
- CHK(med[0] == 0 && med[1] == 1);
- FOR_EACH(j, 0, 2) {
- double pos[2];
- CHK(ids[j] < vcount);
- OK(senc2d_scene_get_unique_vertex(scn, ids[j], pos));
- }
- }
-
- /* Analyze with all media defined */
- OK(senc2d_scene_analyze(scn, &desc));
- OK(senc2d_descriptor_ref_put(desc));
-
- /* Define media for all segments, nothing new here */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = 0;
- OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 0);
-
- /* Define incoherent media for some segments */
- for(i = 0; i < sizeof(media) / sizeof(*media); i++)
- media[i] = (i % 2);
- BA(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
- nvertices, get_position, add_seg, merge_seg, &ctx));
- OK(senc2d_scene_get_unique_sides_without_medium_count(scn, &scount));
- CHK(scount == 0);
-
- /* Scene is still OK and can be analyzed */
- OK(senc2d_scene_analyze(scn, &desc));
-
- OK(senc2d_descriptor_get_global_segments_count(desc, &scount));
- CHK(scount == sizeof(media) / sizeof(*media));
-
- OK(senc2d_descriptor_get_enclosure_count(desc, &ecount));
- CHK(ecount == 2);
-
- FOR_EACH(i, 0, ecount) {
- struct senc2d_enclosure* ee;
- struct senc2d_enclosure_header hh;
- unsigned cc;
- OK(senc2d_descriptor_get_enclosure(desc, i, &enclosure));
- OK(senc2d_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == i);
- CHK(header.enclosed_media_count == 1);
- OK(senc2d_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input segments:
- * if convention is front, front medium (0) is outside,
- * that is medium 0's enclosure is infinite */
- CHK(conv_front == ((medium == 0) == header.is_infinite));
- CHK(header.segment_count == nsegments);
- CHK(header.unique_segment_count == nsegments);
- CHK(header.vertices_count == nvertices);
- CHK(header.is_infinite == (i == 0));
-
- OK(senc2d_descriptor_get_enclosure_count_by_medium(desc, medium, &cc));
- CHK(cc == 1);
- OK(senc2d_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee));
- OK(senc2d_enclosure_get_header(ee, &hh));
- CHK(header.enclosure_id == hh.enclosure_id);
- OK(senc2d_enclosure_ref_put(ee));
-
- FOR_EACH(s, 0, header.segment_count) {
- OK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side));
- CHK(gid == s);
- CHK(side == (medium == 1) ? SENC2D_BACK : SENC2D_FRONT);
- }
- OK(senc2d_enclosure_ref_put(enclosure));
- }
-
- SENC2D(scene_ref_put(scn));
- SENC2D(device_ref_put(dev));
- SENC2D(descriptor_ref_put(desc));
- darray_intface_id_release(&merge_ctx.global_interf_data);
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
-}
-
-int
-main(int argc, char** argv)
-{
- (void)argc, (void)argv;
- test(SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE);
- test(SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE);
- test(SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_OUTSIDE);
- test(SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_OUTSIDE);
- return 0;
-}
diff --git a/src/test_senc2d_utils.h b/src/test_senc2d_utils.h
@@ -13,8 +13,8 @@
* 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 TEST_UTILS2_H
-#define TEST_UTILS2_H
+#ifndef TEST_SENC2_UTILS_H
+#define TEST_SENC2_UTILS_H
#include <rsys/rsys.h>
#include <rsys/mem_allocator.h>
@@ -26,18 +26,20 @@
#define OK(Expr) CHK((Expr) == RES_OK)
#define BA(Expr) CHK((Expr) == RES_BAD_ARG)
-/*******************************************************************************
+/******************************************************************************
* Geometry
- ******************************************************************************/
- /* Distorded square */
-static double box_vertices[4/*#vertices*/*2/*#coords per vertex*/] = {
+ *****************************************************************************/
+/* Distorded square */
+static const double
+box_vertices[4/*#vertices*/ * 2/*#coords per vertex*/] = {
0.1, 0.0,
1.0, 0.0,
0.0, 1.1,
1.0, 1.0
};
/* Need a true square for some tests */
-static double square_vertices[4/*#vertices*/ * 2/*#coords per vertex*/] = {
+static const double
+square_vertices[4/*#vertices*/ * 2/*#coords per vertex*/] = {
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
@@ -56,8 +58,8 @@ STATIC_ASSERT(sizeof(box_vertices) == sizeof(square_vertices),
* | |
* 0----1
*/
-static unsigned
-box_indices[4/*#segments*/*2/*#indices per segment*/] = {
+static const unsigned
+box_indices[4/*#segments*/ * 2/*#indices per segment*/] = {
0, 2,
2, 3,
3, 1,
@@ -67,15 +69,19 @@ static const unsigned
nsegments = sizeof(box_indices) / (2 * sizeof(*box_indices));
struct context {
- double* positions;
- unsigned* indices;
+ const double* positions;
+ const unsigned* indices;
const unsigned* front_media;
const unsigned* back_media;
+ const unsigned* properties;
void* custom;
double offset[2];
double scale;
char reverse_vrtx, reverse_med;
};
+#define CONTEXT_NULL__ {\
+ NULL, NULL, NULL, NULL, NULL, NULL, {0,0}, 1, 0, 0\
+}
static const unsigned medium0[4] = { 0, 0, 0, 0 };
static const unsigned medium1[4] = { 1, 1, 1, 1 };
@@ -111,32 +117,41 @@ get_media(const unsigned iseg, unsigned medium[2], void* context)
medium[ctx->reverse_med ? 0 : 1] = ctx->back_media[iseg];
}
-/*******************************************************************************
+static INLINE void
+get_media_from_properties(const unsigned iseg, unsigned medium[2], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(medium && ctx);
+ medium[ctx->reverse_med ? 1 : 0] = ctx->properties[3 * iseg + 0];
+ medium[ctx->reverse_med ? 0 : 1] = ctx->properties[3 * iseg + 1];
+}
+
+/******************************************************************************
* Miscellaneous
- ******************************************************************************/
+ *****************************************************************************/
static INLINE void
dump_global
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scn,
const char* name)
{
FILE* stream;
- unsigned segment_count, vertices_count, i;
+ unsigned segments_count, vertices_count, i;
- ASSERT(desc && name);
+ ASSERT(scn && name);
- CHK(senc2d_descriptor_get_global_vertices_count(desc, &vertices_count) == RES_OK);
- CHK(senc2d_descriptor_get_global_segments_count(desc, &segment_count) == RES_OK);
+ OK(senc2d_scene_get_vertices_count(scn, &vertices_count));
+ OK(senc2d_scene_get_segments_count(scn, &segments_count));
stream = fopen(name, "w");
CHK(stream);
FOR_EACH(i, 0, vertices_count) {
double tmp[2];
- CHK(senc2d_descriptor_get_global_vertex(desc, i, tmp) == RES_OK);
- fprintf(stream, "v %g %g 0\n", SPLIT2(tmp));
+ OK(senc2d_scene_get_vertex(scn, i, tmp));
+ fprintf(stream, "v %g %g\n", SPLIT2(tmp));
}
- FOR_EACH(i, 0, segment_count) {
+ FOR_EACH(i, 0, segments_count) {
unsigned indices[2];
- CHK(senc2d_descriptor_get_global_segment(desc, i, indices) == RES_OK);
+ OK(senc2d_scene_get_segment(scn, i, indices));
fprintf(stream, "l %lu %lu\n",
(unsigned long)(1 + indices[0]), (unsigned long)(1 + indices[1]));
}
@@ -145,7 +160,7 @@ dump_global
static INLINE void
dump_enclosure
- (struct senc2d_descriptor* desc,
+ (struct senc2d_scene* scn,
const unsigned enc,
const char* name)
{
@@ -154,27 +169,27 @@ dump_enclosure
FILE* stream;
unsigned count, i;
- ASSERT(desc && name);
+ ASSERT(scn && name);
- SENC2D(descriptor_get_enclosure_count(desc, &count));
+ SENC2D(scene_get_enclosure_count(scn, &count));
ASSERT(enc < count);
- CHK(senc2d_descriptor_get_enclosure(desc, enc, &enclosure) == RES_OK);
- CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK);
+ OK(senc2d_scene_get_enclosure(scn, enc, &enclosure));
+ OK(senc2d_enclosure_get_header(enclosure, &header));
stream = fopen(name, "w");
CHK(stream);
FOR_EACH(i, 0, header.vertices_count) {
double tmp[2];
- CHK(senc2d_enclosure_get_vertex(enclosure, i, tmp) == RES_OK);
- fprintf(stream, "v %g %g 0\n", SPLIT2(tmp));
+ OK(senc2d_enclosure_get_vertex(enclosure, i, tmp));
+ fprintf(stream, "v %g %g\n", SPLIT2(tmp));
}
- FOR_EACH(i, 0, header.segment_count) {
+ FOR_EACH(i, 0, header.primitives_count) {
unsigned indices[2];
- CHK(senc2d_enclosure_get_segment(enclosure, i, indices) == RES_OK);
+ OK(senc2d_enclosure_get_segment(enclosure, i, indices));
fprintf(stream, "l %lu %lu\n",
(unsigned long)(1+indices[0]), (unsigned long)(1+indices[1]));
}
- CHK(senc2d_enclosure_ref_put(enclosure) == RES_OK);
+ OK(senc2d_enclosure_ref_put(enclosure));
fclose(stream);
}
@@ -189,10 +204,10 @@ check_memory_allocator(struct mem_allocator* allocator)
}
}
-/*******************************************************************************
+/******************************************************************************
* Circle functions
- ******************************************************************************/
-static INLINE void
+ *****************************************************************************/
+static INLINE void
create_circle
(const double radius,
const unsigned nslices,
@@ -201,6 +216,8 @@ create_circle
double step_theta;
unsigned itheta;
unsigned islice;
+ double* d = NULL;
+ unsigned* u = NULL;
ASSERT(radius > 0 && nslices >= 3 && ctx);
step_theta = 2 * PI / (double)nslices;
@@ -208,16 +225,18 @@ create_circle
const double theta = (double)itheta * step_theta;
const double x = cos(theta);
const double y = sin(theta);
- sa_push(ctx->positions, x*radius);
- sa_push(ctx->positions, y*radius);
+ sa_push(d, x * radius);
+ sa_push(d, y * radius);
}
+ ctx->positions = d;
FOR_EACH(islice, 0, nslices) {
const unsigned v0 = islice;
const unsigned v1 = ((islice + 1) % nslices);
- sa_push(ctx->indices, v0);
- sa_push(ctx->indices, v1);
+ sa_push(u, v0);
+ sa_push(u, v1);
}
+ ctx->indices = u;
}
static INLINE void
@@ -230,44 +249,9 @@ circle_release(struct context* ctx)
ctx->indices = NULL;
}
-
-/*******************************************************************************
+/******************************************************************************
* Check functions
- ******************************************************************************/
-static INLINE void check_desc(struct senc2d_descriptor* desc)
-{
- unsigned maxm, ecount, i;
- size_t e_cpt = 0;
- CHK(senc2d_descriptor_get_max_medium(desc, &maxm) == RES_OK);
- CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
- for(i = 0; i <= maxm; i++) {
- unsigned j, ecount_bym;
- unsigned found = 0;
- CHK(senc2d_descriptor_get_enclosure_count_by_medium(desc, i, &ecount_bym) == RES_OK);
- /* Can be 0 if media numbering is not compact */
- FOR_EACH(j, 0, ecount_bym) {
- struct senc2d_enclosure* enc;
- struct senc2d_enclosure_header h;
- unsigned k;
- int f = 0;
- CHK(senc2d_descriptor_get_enclosure_by_medium(desc, i, j, &enc) == RES_OK);
- CHK(senc2d_enclosure_get_header(enc, &h) == RES_OK);
- ASSERT(h.enclosed_media_count);
- FOR_EACH(k, 0, h.enclosed_media_count) {
- unsigned m;
- CHK(senc2d_enclosure_get_medium(enc, k, &m) == RES_OK);
- found += (m == i);
- f += (m == i);
- }
- ASSERT(f == 1); /* Single reference expected */
- CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
- }
- ASSERT(found == ecount_bym); /* All the enclosures enclose medim i */
- e_cpt += ecount_bym;
- }
- ASSERT(e_cpt >= ecount); /* Every enc has been visited at least once */
-}
-
+ *****************************************************************************/
/* Compare the iseg-th segment of enclosure with a segment described by seg2 & vertices2 */
static INLINE void
cmp_seg
@@ -286,9 +270,9 @@ cmp_seg
ASSERT(enclosure && seg2 && vertices2 && seg_eq && seg_reversed);
- CHK(senc2d_enclosure_get_segment(enclosure, iseg, seg1) == RES_OK);
+ OK(senc2d_enclosure_get_segment(enclosure, iseg, seg1));
FOR_EACH(i, 0, 2) {
- CHK(senc2d_enclosure_get_vertex(enclosure, seg1[i], s1[i]) == RES_OK);
+ OK(senc2d_enclosure_get_vertex(enclosure, seg1[i], s1[i]));
d2_set(s2[i], vertices2 + (2 * seg2[i]));
}
FOR_EACH(i, 0, 2) {
@@ -316,4 +300,4 @@ cmp_seg
ASSERT(*seg_reversed == (1 != seg1_eq[1]));
}
-#endif /* TEST_UTILS2_H */
+#endif /* TEST_SENC2_UTILS_H */
diff --git a/src/test_senc2d_utils2.h b/src/test_senc2d_utils2.h
@@ -0,0 +1,109 @@
+/* Copyright (C) |Meso|Star> 2018-2020 (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 TEST_SENC2_UTILS2_H
+#define TEST_SENC2_UTILS2_H
+
+#if !defined(NB_CIRC_X) || !defined(NB_CIRC_Y) || !defined(NB_CIRC_Z) | !defined(NB_CIRC)
+#error "Macro definitions are missing"
+#endif
+
+#include "test_senc2d_utils.h"
+
+#include <rsys/double2.h>
+#include <rsys/stretchy_array.h>
+
+static void
+get_ctx_indices(const unsigned iseg, unsigned ids[2], void* context)
+{
+ struct context* ctx = context;
+ unsigned s3dut_iseg, circ_idx, v_offset;
+ unsigned circ_seg_count, circ_vrtx_count;
+ ASSERT(ids && ctx);
+ /* Get circ_idx along with the s3dut vertice index */
+ circ_seg_count = (unsigned)sa_size(ctx->indices) / 2;
+ circ_vrtx_count = (unsigned)sa_size(ctx->positions) / 2;
+ ASSERT(iseg < NB_CIRC * circ_seg_count);
+ s3dut_iseg = iseg % circ_seg_count;
+ circ_idx = iseg / circ_seg_count;
+ ASSERT(ctx->indices[s3dut_iseg * 2 + 0] <= UINT_MAX
+ && ctx->indices[s3dut_iseg * 2 + 1] <= UINT_MAX);
+ /* Compute the vertex index in the user numbering
+ * from circ_idx and s3dut data; vertex related getters
+ * will have to get the s3dut index back */
+ v_offset = circ_idx * circ_vrtx_count;
+ ids[ctx->reverse_vrtx ? 1 : 0]
+ = v_offset + (unsigned)ctx->indices[s3dut_iseg * 2 + 0];
+ ids[ctx->reverse_vrtx ? 0 : 1]
+ = v_offset + (unsigned)ctx->indices[s3dut_iseg * 2 + 1];
+}
+
+static void
+get_ctx_position(const unsigned ivert, double pos[2], void* context)
+{
+ struct context* ctx = context;
+ unsigned ctx_ivert, circ_idx;
+ unsigned circ_seg_count, circ_vrtx_count;
+ int i, j, k;
+ double offset[2], tmp[2];
+ double center_x, center_y, scale, misalignment = 0;
+ ASSERT(pos && ctx); (void)circ_vrtx_count;
+ /* Get circ_idx and circle imbrication along with the vertice index */
+ circ_seg_count = (unsigned)sa_size(ctx->indices) / 2;
+ circ_vrtx_count = (unsigned)sa_size(ctx->positions) / 2;
+ ASSERT(ivert < NB_CIRC * circ_vrtx_count);
+ ctx_ivert = ivert % circ_seg_count;
+ circ_idx = ivert / circ_seg_count;
+ /* k th circle of the imbrication at grid position i,j */
+ i = (int)circ_idx / (NB_CIRC_Y * NB_CIRC_Z);
+ j = (circ_idx / NB_CIRC_Z) % NB_CIRC_Y;
+ k = circ_idx % NB_CIRC_Z;
+ ASSERT(i < NB_CIRC_X && j < NB_CIRC_Y && k < NB_CIRC_Z);
+ ASSERT((unsigned)(i * NB_CIRC_Y * NB_CIRC_Z + j * NB_CIRC_Z + k)
+ * circ_vrtx_count + ctx_ivert == ivert);
+ center_x = 2 * (1 + NB_CIRC_Z) * (i - NB_CIRC_X / 2);
+ center_y = 2 * (1 + NB_CIRC_Z) * (j - NB_CIRC_Y / 2);
+ /* Compute scale and offset from imbrication */
+ scale = k + 1;
+#ifdef MITIGATE_EMBREE_181
+ /* Mitigate Embree issue #181
+ * We cannot keep perfect alignment of circles
+ * or some hits are missed */
+ misalignment = (k % 2) ? -0.01 : +0.01;
+#endif
+ d2(offset, center_x + misalignment, center_y + misalignment);
+ d2_add(pos, d2_muld(tmp, ctx->positions + ctx_ivert * 2, scale),
+ offset);
+}
+
+static void
+get_ctx_media(const unsigned iseg, unsigned medium[2], void* context)
+{
+ struct context* ctx = context;
+ unsigned circ_idx;
+ unsigned circ_seg_count;
+ int k;
+ ASSERT(medium && ctx);
+ /* Get circ_idx */
+ circ_seg_count = (unsigned)sa_size(ctx->indices) / 2;
+ ASSERT(iseg < NB_CIRC * circ_seg_count);
+ circ_idx = iseg / circ_seg_count;
+ /* k th circle of the imbrication at some grid position */
+ k = circ_idx % NB_CIRC_Z;
+ medium[ctx->reverse_med ? SENC2D_BACK : SENC2D_FRONT] = (unsigned)k;
+ medium[ctx->reverse_med ? SENC2D_FRONT : SENC2D_BACK] = (unsigned)(k + 1);
+}
+
+#endif /* TEST_SENC2_UTILS2_H */