commit acae3736a9595dab4b4606ffef961a7365781743
parent e70b1309a821c6ef260ecdbd724755006a4ef216
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 5 Feb 2020 15:10:08 +0100
Rename everything senc3d (from senc) for coherency reasons
Diffstat:
62 files changed, 13000 insertions(+), 12931 deletions(-)
diff --git a/README.md b/README.md
@@ -1,10 +1,10 @@
-StarEnclosures
-==============
+Star-enclosures-3d
+==================
Overview
--------
-The purpose of Star-enclosures is to extract enclosures from raw
+The purpose of Star-enclosures-3d is to extract enclosures from raw
geometry. An enclosure is a set of triangles enclosing a given volume.
The enclosure notion extends to open enclosures for which there is no
inside or outside. For every detected enclosure, the library provides
@@ -22,7 +22,7 @@ triangles can be set.
How to build
------------
-StarEnclosures relies on the [CMake](http://www.cmake.org) and the
+Star-enclosures-3d 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-3D](https://gitlab.com/meso-star/star-3d/) libraries. Additionaly,
@@ -91,7 +91,7 @@ Release notes
License
-------
-StarEnclosures is Copyright (C) |Méso|Star> 2019-2020
+Star-enclosures-3d is Copyright (C) |Méso|Star> 2019-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,12 +14,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.1)
-project(Star-Enclosures C)
+project(star-enclosures-3d C)
enable_testing()
include(CMakeDependentOption)
-set(SENC_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+set(SENC3D_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
option(NO_TEST "Do not build tests" OFF)
cmake_dependent_option(HUGE_ADDITIONAL_TESTS
@@ -72,58 +72,58 @@ set(VERSION_MINOR 4)
set(VERSION_PATCH 2)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-set(SENC_FILES_SRC
- senc_descriptor.c
- senc_device.c
- senc_enclosure.c
- senc_scene.c
- senc_scene_analyze.c)
-
-set(SENC_FILES_INC_API
- senc.h
- senc_s3d_helper.h
- sencX3.h)
-
-set(SENC_FILES_INC
- senc_device_c.h
- senc_enclosure_c.h
- senc_enclosure_data.h
- senc_internal_types.h
- senc_scene_c.h
- senc_scene_analyze_c.h
- senc_side_range.h)
-
-set(SENC_FILES_DOC COPYING README.md)
-
-# Prepend each file by `SENC_SOURCE_DIR'
-rcmake_prepend_path(SENC_FILES_SRC ${SENC_SOURCE_DIR})
-rcmake_prepend_path(SENC_FILES_INC ${SENC_SOURCE_DIR})
-rcmake_prepend_path(SENC_FILES_INC_API ${SENC_SOURCE_DIR})
-rcmake_prepend_path(SENC_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+set(SENC3D_FILES_SRC
+ senc3d_descriptor.c
+ senc3d_device.c
+ senc3d_enclosure.c
+ senc3d_scene.c
+ senc3d_scene_analyze.c)
+
+set(SENC3D_FILES_INC_API
+ senc3d.h
+ senc3d_s3d_helper.h
+ sencX3d.h)
+
+set(SENC3D_FILES_INC
+ senc3d_device_c.h
+ senc3d_enclosure_c.h
+ senc3d_enclosure_data.h
+ senc3d_internal_types.h
+ senc3d_scene_c.h
+ senc3d_scene_analyze_c.h
+ senc3d_side_range.h)
+
+set(SENC3D_FILES_DOC COPYING README.md)
+
+# Prepend each file by `SENC3D_SOURCE_DIR'
+rcmake_prepend_path(SENC3D_FILES_SRC ${SENC3D_SOURCE_DIR})
+rcmake_prepend_path(SENC3D_FILES_INC ${SENC3D_SOURCE_DIR})
+rcmake_prepend_path(SENC3D_FILES_INC_API ${SENC3D_SOURCE_DIR})
+rcmake_prepend_path(SENC3D_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
if(CMAKE_COMPILER_IS_GNUCC)
set(MATH_LIB m)
endif()
-add_library(senc SHARED
- ${SENC_FILES_SRC}
- ${SENC_FILES_INC}
- ${SENC_FILES_INC_API})
-target_link_libraries(senc RSys Star3D ${MATH_LIB})
+add_library(senc3d SHARED
+ ${SENC3D_FILES_SRC}
+ ${SENC3D_FILES_INC}
+ ${SENC3D_FILES_INC_API})
+target_link_libraries(senc3d RSys Star3D ${MATH_LIB})
-set_target_properties(senc PROPERTIES
- DEFINE_SYMBOL SENC_SHARED_BUILD
+set_target_properties(senc3d PROPERTIES
+ DEFINE_SYMBOL SENC3D_SHARED_BUILD
VERSION ${VERSION}
COMPILE_FLAGS ${OpenMP_C_FLAGS}
SOVERSION ${VERSION_MAJOR})
-rcmake_copy_runtime_libraries(senc)
+rcmake_copy_runtime_libraries(senc3d)
if(CMAKE_COMPILER_IS_GNUCC)
- set_target_properties(senc PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}")
- target_link_libraries(senc m)
+ set_target_properties(senc3d PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}")
+ target_link_libraries(senc3d m)
endif()
-rcmake_setup_devel(senc StarEnc ${VERSION} star/senc_version.h)
+rcmake_setup_devel(senc3d StarEnc3D ${VERSION} star/senc3d_version.h)
###############################################################################
# Add tests
@@ -131,9 +131,13 @@ rcmake_setup_devel(senc StarEnc ${VERSION} star/senc_version.h)
if(NOT NO_TEST)
function(build_test _name)
add_executable(${_name}
- ${SENC_SOURCE_DIR}/test_senc_utils.h
- ${SENC_SOURCE_DIR}/${_name}.c)
- target_link_libraries(${_name} RSys senc)
+ ${SENC3D_SOURCE_DIR}/test_senc3d_utils.h
+ ${SENC3D_SOURCE_DIR}/${_name}.c)
+ foreach(other ${ARGN})
+ target_sources(${_name}
+ PUBLIC ${SENC3D_SOURCE_DIR}/${other})
+ endforeach()
+ target_link_libraries(${_name} RSys senc3d)
endfunction()
function(register_test _name)
@@ -142,45 +146,45 @@ if(NOT NO_TEST)
endfunction()
function(new_test _name)
- build_test(${_name})
+ build_test(${_name} ${ARGN})
register_test(${_name} ${_name})
endfunction()
- new_test(test_senc_cube_behind_cube)
- new_test(test_senc_cube_in_cube)
- new_test(test_senc_cube_on_cube)
- new_test(test_senc_device)
- new_test(test_senc_enclosure)
- new_test(test_senc_inconsistant_cube)
- new_test(test_senc_sample_enclosure)
- new_test(test_senc_scene)
- new_test(test_senc_some_enclosures)
- new_test(test_senc_some_triangles)
- new_test(test_senc_unspecified_medium)
+ new_test(test_senc3d_cube_behind_cube)
+ new_test(test_senc3d_cube_in_cube)
+ new_test(test_senc3d_cube_on_cube)
+ new_test(test_senc3d_device)
+ new_test(test_senc3d_enclosure)
+ new_test(test_senc3d_inconsistant_cube)
+ new_test(test_senc3d_sample_enclosure)
+ new_test(test_senc3d_scene)
+ new_test(test_senc3d_some_enclosures)
+ new_test(test_senc3d_some_triangles)
+ new_test(test_senc3d_unspecified_medium)
- target_link_libraries(test_senc_enclosure Star3D)
- target_link_libraries(test_senc_sample_enclosure StarSP Star3D)
+ target_link_libraries(test_senc3d_enclosure Star3D)
+ target_link_libraries(test_senc3d_sample_enclosure StarSP Star3D)
- rcmake_copy_runtime_libraries(test_senc_sample_enclosure)
+ rcmake_copy_runtime_libraries(test_senc3d_sample_enclosure)
if(HUGE_ADDITIONAL_TESTS)
- new_test(test_senc_many_enclosures)
- new_test(test_senc_many_triangles)
+ new_test(test_senc3d_many_enclosures test_senc3d_utils2.h)
+ new_test(test_senc3d_many_triangles test_senc3d_utils2.h)
- target_link_libraries(test_senc_many_enclosures Star3DUT)
- target_link_libraries(test_senc_many_triangles Star3DUT)
+ target_link_libraries(test_senc3d_many_enclosures Star3DUT)
+ target_link_libraries(test_senc3d_many_triangles Star3DUT)
- rcmake_copy_runtime_libraries(test_senc_many_enclosures)
- rcmake_copy_runtime_libraries(test_senc_many_triangles)
+ rcmake_copy_runtime_libraries(test_senc3d_many_enclosures)
+ rcmake_copy_runtime_libraries(test_senc3d_many_triangles)
endif()
endif()
###############################################################################
# Define output & install directories
###############################################################################
-install(TARGETS senc
+install(TARGETS senc3d
ARCHIVE DESTINATION bin
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
-install(FILES ${SENC_FILES_INC_API} DESTINATION include/star)
-install(FILES ${SENC_FILES_DOC} DESTINATION share/doc/star-enc)
+install(FILES ${SENC3D_FILES_INC_API} DESTINATION include/star)
+install(FILES ${SENC3D_FILES_DOC} DESTINATION share/doc/star-enclosures-3d)
diff --git a/src/senc.h b/src/senc.h
@@ -1,364 +0,0 @@
-/* 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
- * 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_H
-#define SENC_H
-
-#include <rsys/rsys.h>
-
-#include <limits.h>
-
-/* Library symbol management */
-#if defined(SENC_SHARED_BUILD)
- #define SENC_API extern EXPORT_SYM
-#elif defined(SENC_STATIC_BUILD)
- #define SENC_API extern LOCAL_SYM
-#else /* Use shared library */
- #define SENC_API extern IMPORT_SYM
-#endif
-
-/* 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
- #define SENC(Func) ASSERT(senc_ ## Func == RES_OK)
-#else
- #define SENC(Func) senc_ ## Func
-#endif
-
-/* Syntactic sugar used to inform the library that it can use as many threads
- * as CPU cores */
-#define SENC_NTHREADS_DEFAULT (~0u)
-
-/* A constant to specify an unspecified medium */
-#define SENC_UNSPECIFIED_MEDIUM UINT_MAX
-
-/* Forward declaration of external opaque data types */
-struct logger;
-struct mem_allocator;
-
-/* Forward declaration of StarEnclosures opaque data types. These data types
- * are ref counted. Once created with the appropriated `senc_<TYPE>_create'
- * function, the caller implicitly owns the created data, i.e. its reference
- * counter is set to 1. The senc_<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 senc_device;
-struct senc_scene;
-struct senc_enclosure;
-
-/*******************************************************************************
- * The dimension of the geometry used in the library.
- ******************************************************************************/
-#define SENC_GEOMETRY_DIMENSION 3
-
-/* A type to discriminate triangle sides */
-enum senc_side {
- SENC_FRONT,
- SENC_BACK
-};
-
-/* Enclosure header type */
-struct senc_enclosure_header {
- /* The ID of the enclosure; 0, 1, ... */
- unsigned enclosure_id;
- /* Number of triangles; a triangle can be accounted for twice, once by side*/
- unsigned primitives_count;
- /* Number of unique triangles; a triangle cannot be accounted for twice */
- unsigned unique_primitives_count;
- /* Number of vertices */
- unsigned vertices_count;
- /* The number of media inside the enclosure,
- * SENC_UNSPECIFIED_MEDIUM included */
- unsigned enclosed_media_count;
- /* Is the enclosure open/infinite?
- * Only the outermost enclosure is infinite. */
- char is_infinite;
-};
-
-/* We consider the geometrical normal Ng to a triangle V0 V1 V2
- * that verifies "(V0, V0V1, V0V2, Ng) is a direct system"
- * (right-handed system).
- *
- * The user can set the convention used to determine which side of
- * a triangle is to be considered front/back by using the flags :
- * SENC_CONVENTION_NORMAL_FRONT => Ng points toward the front side,
- * SENC_CONVENTION_NORMAL_BACK => Ng points toward the back side.
- *
- * Additionaly the user can set the convention used to output enclosures
- * so that Ng points toward the enclosure or on the opposite direction
- * (for a closed enclosure Ng points toward the inside or toward the outside)
- * by using the flags :
- * SENC_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure,
- * SENC_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).
- *
- * Also note that both sides of a triangle can be part of the same enclosure;
- * in this case the 2 sides will be given with opposite Ng (meaning they
- * will be given with opposite vertices order).
- */
-enum senc_convention {
- /*
- * Convention regarding FRONT/BACK sides in input data
- */
-
- /* Geometrical normals point toward the front side */
- SENC_CONVENTION_NORMAL_FRONT = BIT(0),
- /* Geometrical normals point toward the back side */
- SENC_CONVENTION_NORMAL_BACK = BIT(1),
-
- /*
- * Convention regarding geometrical normals in output data
- */
-
- /* Geometrical normals point toward the enclosure */
- SENC_CONVENTION_NORMAL_INSIDE = BIT(2),
- /* Geometrical normals point to the opposite of the enclosure */
- SENC_CONVENTION_NORMAL_OUTSIDE = BIT(3)
-};
-
-BEGIN_DECLS
-
-/******************************************************************************
- * StarEnclosures 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.
- *****************************************************************************/
-SENC_API res_T
-senc_device_create
- (struct logger* logger, /* May be NULL <=> use default logger */
- struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
- const unsigned nthreads_hint,
- const int verbose,
- struct senc_device** device);
-
-SENC_API res_T
-senc_device_ref_get
- (struct senc_device* device);
-
-SENC_API res_T
-senc_device_ref_put
- (struct senc_device* device);
-
-/******************************************************************************
- * StarEnclosures scene. A scene is a collection of triangles. Each triangle is
- * defined with a medium on each side.
- *****************************************************************************/
-/* Creates a scene from some vertices and triangles.
- * Neither vertices nor triangles can include duplicates.
- * Triangles cannot be degenerated. */
-SENC_API res_T
-senc_scene_create
- (struct senc_device* device,
- const int convention,
- /* Number of triangles */
- const unsigned triangles_count,
- /* User function that provides vertices ids for triangles */
- void(*get_indices)(
- const unsigned itri,
- unsigned ids[SENC_GEOMETRY_DIMENSION],
- void* context),
- /* User function that provides media ids for triangles */
- void(*get_media) /* Can be NULL <=> SENC_UNSPECIFIED_MEDIUM medium used */
- (const unsigned itri, unsigned med[2], void* context),
- /* Number of vertices */
- const unsigned vertices_count,
- /* User function that provides coordinates for vertices */
- void(*get_position)(
- const unsigned ivert,
- double pos[SENC_GEOMETRY_DIMENSION],
- void* context),
- /* Context provided to user callbacks; can be NULL */
- void* context,
- /* The created scene */
- struct senc_scene** scene);
-
-/* Returns the convention flags in use with the scene. */
-SENC_API res_T
-senc_scene_get_convention
- (const struct senc_scene* scene,
- int* convention);
-
-/* Returns the number of triangles in the scene. */
-SENC_API res_T
-senc_scene_get_triangles_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the itri_th triangle vertices' indices. */
-SENC_API res_T
-senc_scene_get_triangle
- (const struct senc_scene* scene,
- const unsigned itri,
- unsigned indices[SENC_GEOMETRY_DIMENSION]);
-
-/* Returns the media for the itri_th triangle. */
-SENC_API res_T
-senc_scene_get_triangle_media
- (const struct senc_scene* scene,
- const unsigned itri,
- unsigned media[2]);
-
-/* Returns the number of vertices in the scene. */
-SENC_API res_T
-senc_scene_get_vertices_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the coordinates of the ivert_th vertex. */
-SENC_API res_T
-senc_scene_get_vertex
- (const struct senc_scene* scene,
- const unsigned ivert,
- double coord[SENC_GEOMETRY_DIMENSION]);
-
-/* 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). */
-SENC_API res_T
-senc_scene_get_max_medium
- (const struct senc_scene* scene,
- unsigned* max_medium_id);
-
-/* Returns the number of enclosures. */
-SENC_API res_T
-senc_scene_get_enclosure_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the number of enclosures that have some geometry refering to the
- * imed_th medium or SENC_UNSPECIFIED_MEDIUM. */
-SENC_API res_T
-senc_scene_get_enclosure_count_by_medium
- (const struct senc_scene* scene,
- const unsigned imed,
- unsigned* count);
-
-/* Returns the idx_th enclosure. */
-SENC_API res_T
-senc_scene_get_enclosure
- (struct senc_scene* scene,
- const unsigned idx,
- struct senc_enclosure** enclosure);
-
-/* Returns the idx_th enclosure using the imed_th medium or
- * SENC_UNSPECIFIED_MEDIUM. */
-SENC_API res_T
-senc_scene_get_enclosure_by_medium
- (struct senc_scene* scene,
- const unsigned imed,
- const unsigned idx,
- struct senc_enclosure** enclosure);
-
-/* Returns the enclosures the itri_th triangle front and back sides are member
- * of. */
-SENC_API res_T
-senc_scene_get_triangle_enclosures
- (const struct senc_scene* scene,
- const unsigned itri,
- unsigned enclosures[2]);
-
-/* Returns the number of segments that are frontier segments:
- * - that have arity 1 (single triangle using the segment)
- * - that connect 2 different media */
-SENC_API res_T
-senc_scene_get_frontier_segments_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the iseg_th frontier segment; the returned indices are global vertex
- * indices whose coordinates can be retrieved using senc_scene_get_vertex. */
-SENC_API res_T
-senc_scene_get_frontier_segment
- (const struct senc_scene* scene,
- const unsigned iseg,
- unsigned vrtx_id[SENC_GEOMETRY_DIMENSION-1]);
-
-SENC_API res_T
-senc_scene_ref_get
- (struct senc_scene* scene);
-
-SENC_API res_T
-senc_scene_ref_put
- (struct senc_scene* scene);
-
-/******************************************************************************
- * StarEnclosures 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" triangle twice if both sides are in. In
- * this case the 2 occurences of the triangle have reversed vertices order and
- * unique_triangle_count and triangle_count differ.
- * Vertices and triangles 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 triangles (or properties) visit unique triangles
- * for indices in the [0 unique_triangle_count[ range and back-faces of the
- * doubly-included triangles in the [unique_triangle_count triangle_count[
- * range.
- *****************************************************************************/
-/* Returns the header of an enclosure. */
-SENC_API res_T
-senc_enclosure_get_header
- (const struct senc_enclosure* enclosure,
- struct senc_enclosure_header* header);
-
-/* Returns the itri_th triangle of an enclosure.
- * Indices are local to the enclosure. */
-SENC_API res_T
-senc_enclosure_get_triangle
- (const struct senc_enclosure* enclosure,
- const unsigned itri,
- unsigned indices[SENC_GEOMETRY_DIMENSION]);
-
-/* Returns the coordinates of the ivert_th vertex of an enclosure. */
-SENC_API res_T
-senc_enclosure_get_vertex
- (const struct senc_enclosure* enclosure,
- const unsigned ivert,
- double coord[SENC_GEOMETRY_DIMENSION]);
-
-/* Returns the global id of the itri_th triangle of an enclosure
- * and the involved side. */
-SENC_API res_T
-senc_enclosure_get_triangle_id
- (const struct senc_enclosure* enclosure,
- const unsigned itri,
- unsigned* gid,
- enum senc_side* side);
-
-/* Returns the id of the imed_th medium of an enclosure. */
-SENC_API res_T
-senc_enclosure_get_medium
- (const struct senc_enclosure* enclosure,
- const unsigned imed,
- unsigned* medium);
-
-SENC_API res_T
-senc_enclosure_ref_get
- (struct senc_enclosure* enclosure);
-
-SENC_API res_T
-senc_enclosure_ref_put
- (struct senc_enclosure* enclosure);
-
-END_DECLS
-
-#endif /* SENC_H */
diff --git a/src/senc3d.h b/src/senc3d.h
@@ -0,0 +1,364 @@
+/* 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
+ * 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 SENC3D_H
+#define SENC3D_H
+
+#include <rsys/rsys.h>
+
+#include <limits.h>
+
+/* Library symbol management */
+#if defined(SENC3D_SHARED_BUILD)
+ #define SENC3D_API extern EXPORT_SYM
+#elif defined(SENC3D_STATIC_BUILD)
+ #define SENC3D_API extern LOCAL_SYM
+#else /* Use shared library */
+ #define SENC3D_API extern IMPORT_SYM
+#endif
+
+/* 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
+ #define SENC3D(Func) ASSERT(senc3d_ ## Func == RES_OK)
+#else
+ #define SENC3D(Func) senc3d_ ## Func
+#endif
+
+/* Syntactic sugar used to inform the library that it can use as many threads
+ * as CPU cores */
+#define SENC3D_NTHREADS_DEFAULT (~0u)
+
+/* A constant to denote an unspecified medium */
+#define SENC3D_UNSPECIFIED_MEDIUM UINT_MAX
+
+/* Forward declaration of external opaque data types */
+struct logger;
+struct mem_allocator;
+
+/* Forward declaration of StarEnclosures opaque data types. These data types
+ * are ref counted. Once created with the appropriated `SENC3D_<TYPE>_create'
+ * function, the caller implicitly owns the created data, i.e. its reference
+ * counter is set to 1. The SENC3D_<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 senc3d_device;
+struct senc3d_scene;
+struct senc3d_enclosure;
+
+/*******************************************************************************
+ * The dimension of the geometry used in the library.
+ ******************************************************************************/
+#define SENC3D_GEOMETRY_DIMENSION 3
+
+/* A type to discriminate triangle sides */
+enum senc3d_side {
+ SENC3D_FRONT,
+ SENC3D_BACK
+};
+
+/* Enclosure header type */
+struct senc3d_enclosure_header {
+ /* The ID of the enclosure; 0, 1, ... */
+ unsigned enclosure_id;
+ /* Number of triangles; a triangle can be accounted for twice, once by side*/
+ unsigned primitives_count;
+ /* Number of unique triangles; a triangle cannot be accounted for twice */
+ unsigned unique_primitives_count;
+ /* Number of vertices */
+ unsigned vertices_count;
+ /* The number of media inside the enclosure,
+ * SENC3D_UNSPECIFIED_MEDIUM included */
+ unsigned enclosed_media_count;
+ /* Is the enclosure open/infinite?
+ * Only the outermost enclosure is infinite. */
+ char is_infinite;
+};
+
+/* We consider the geometrical normal Ng to a triangle V0 V1 V2
+ * that verifies "(V0, V0V1, V0V2, Ng) is a direct system"
+ * (right-handed system).
+ *
+ * The user can set the convention used to determine which side of
+ * a triangle is to be considered front/back by using the flags :
+ * SENC3D_CONVENTION_NORMAL_FRONT => Ng points toward the front side,
+ * SENC3D_CONVENTION_NORMAL_BACK => Ng points toward the back side.
+ *
+ * Additionaly the user can set the convention used to output enclosures
+ * so that Ng points toward the enclosure or on the opposite direction
+ * (for a closed enclosure Ng points toward the inside or toward the outside)
+ * by using the flags :
+ * SENC3D_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure,
+ * SENC3D_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).
+ *
+ * Also note that both sides of a triangle can be part of the same enclosure;
+ * in this case the 2 sides will be given with opposite Ng (meaning they
+ * will be given with opposite vertices order).
+ */
+enum senc3d_convention {
+ /*
+ * Convention regarding FRONT/BACK sides in input data
+ */
+
+ /* Geometrical normals point toward the front side */
+ SENC3D_CONVENTION_NORMAL_FRONT = BIT(0),
+ /* Geometrical normals point toward the back side */
+ SENC3D_CONVENTION_NORMAL_BACK = BIT(1),
+
+ /*
+ * Convention regarding geometrical normals in output data
+ */
+
+ /* Geometrical normals point toward the enclosure */
+ SENC3D_CONVENTION_NORMAL_INSIDE = BIT(2),
+ /* Geometrical normals point to the opposite of the enclosure */
+ SENC3D_CONVENTION_NORMAL_OUTSIDE = BIT(3)
+};
+
+BEGIN_DECLS
+
+/******************************************************************************
+ * StarEnclosures 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.
+ *****************************************************************************/
+SENC3D_API res_T
+senc3d_device_create
+ (struct logger* logger, /* May be NULL <=> use default logger */
+ struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
+ const unsigned nthreads_hint,
+ const int verbose,
+ struct senc3d_device** device);
+
+SENC3D_API res_T
+senc3d_device_ref_get
+ (struct senc3d_device* device);
+
+SENC3D_API res_T
+senc3d_device_ref_put
+ (struct senc3d_device* device);
+
+/******************************************************************************
+ * StarEnclosures scene. A scene is a collection of triangles. Each triangle is
+ * defined with a medium on each side.
+ *****************************************************************************/
+/* Creates a scene from some vertices and triangles.
+ * Neither vertices nor triangles can include duplicates.
+ * Triangles cannot be degenerated. */
+SENC3D_API res_T
+senc3d_scene_create
+ (struct senc3d_device* device,
+ const int convention,
+ /* Number of triangles */
+ const unsigned triangles_count,
+ /* User function that provides vertices ids for triangles */
+ void(*get_indices)(
+ const unsigned itri,
+ unsigned ids[SENC3D_GEOMETRY_DIMENSION],
+ void* context),
+ /* User function that provides media ids for triangles */
+ void(*get_media) /* Can be NULL <=> SENC3D_UNSPECIFIED_MEDIUM medium used */
+ (const unsigned itri, unsigned med[2], void* context),
+ /* Number of vertices */
+ const unsigned vertices_count,
+ /* User function that provides coordinates for vertices */
+ void(*get_position)(
+ const unsigned ivert,
+ double pos[SENC3D_GEOMETRY_DIMENSION],
+ void* context),
+ /* Context provided to user callbacks; can be NULL */
+ void* context,
+ /* The created scene */
+ struct senc3d_scene** scene);
+
+/* Returns the convention flags in use with the scene. */
+SENC3D_API res_T
+senc3d_scene_get_convention
+ (const struct senc3d_scene* scene,
+ int* convention);
+
+/* Returns the number of triangles in the scene. */
+SENC3D_API res_T
+senc3d_scene_get_triangles_count
+ (const struct senc3d_scene* scene,
+ unsigned* count);
+
+/* Returns the itri_th triangle vertices' indices. */
+SENC3D_API res_T
+senc3d_scene_get_triangle
+ (const struct senc3d_scene* scene,
+ const unsigned itri,
+ unsigned indices[SENC3D_GEOMETRY_DIMENSION]);
+
+/* Returns the media for the itri_th triangle. */
+SENC3D_API res_T
+senc3d_scene_get_triangle_media
+ (const struct senc3d_scene* scene,
+ const unsigned itri,
+ unsigned media[2]);
+
+/* Returns the number of vertices in the scene. */
+SENC3D_API res_T
+senc3d_scene_get_vertices_count
+ (const struct senc3d_scene* scene,
+ unsigned* count);
+
+/* Returns the coordinates of the ivert_th vertex. */
+SENC3D_API res_T
+senc3d_scene_get_vertex
+ (const struct senc3d_scene* scene,
+ const unsigned ivert,
+ double coord[SENC3D_GEOMETRY_DIMENSION]);
+
+/* 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). */
+SENC3D_API res_T
+senc3d_scene_get_max_medium
+ (const struct senc3d_scene* scene,
+ unsigned* max_medium_id);
+
+/* Returns the number of enclosures. */
+SENC3D_API res_T
+senc3d_scene_get_enclosure_count
+ (const struct senc3d_scene* scene,
+ unsigned* count);
+
+/* Returns the number of enclosures that have some geometry refering to the
+ * imed_th medium or SENC3D_UNSPECIFIED_MEDIUM. */
+SENC3D_API res_T
+senc3d_scene_get_enclosure_count_by_medium
+ (const struct senc3d_scene* scene,
+ const unsigned imed,
+ unsigned* count);
+
+/* Returns the idx_th enclosure. */
+SENC3D_API res_T
+senc3d_scene_get_enclosure
+ (struct senc3d_scene* scene,
+ const unsigned idx,
+ struct senc3d_enclosure** enclosure);
+
+/* Returns the idx_th enclosure using the imed_th medium or
+ * SENC3D_UNSPECIFIED_MEDIUM. */
+SENC3D_API res_T
+senc3d_scene_get_enclosure_by_medium
+ (struct senc3d_scene* scene,
+ const unsigned imed,
+ const unsigned idx,
+ struct senc3d_enclosure** enclosure);
+
+/* Returns the enclosures the itri_th triangle front and back sides are member
+ * of. */
+SENC3D_API res_T
+senc3d_scene_get_triangle_enclosures
+ (const struct senc3d_scene* scene,
+ const unsigned itri,
+ unsigned enclosures[2]);
+
+/* Returns the number of segments that are frontier segments:
+ * - that have arity 1 (single triangle using the segment)
+ * - that connect 2 different media */
+SENC3D_API res_T
+senc3d_scene_get_frontier_segments_count
+ (const struct senc3d_scene* scene,
+ unsigned* count);
+
+/* Returns the iseg_th frontier segment; the returned indices are global vertex
+ * indices whose coordinates can be retrieved using senc3d_scene_get_vertex. */
+SENC3D_API res_T
+senc3d_scene_get_frontier_segment
+ (const struct senc3d_scene* scene,
+ const unsigned iseg,
+ unsigned vrtx_id[SENC3D_GEOMETRY_DIMENSION-1]);
+
+SENC3D_API res_T
+senc3d_scene_ref_get
+ (struct senc3d_scene* scene);
+
+SENC3D_API res_T
+senc3d_scene_ref_put
+ (struct senc3d_scene* scene);
+
+/******************************************************************************
+ * StarEnclosures 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" triangle twice if both sides are in. In
+ * this case the 2 occurences of the triangle have reversed vertices order and
+ * unique_triangle_count and triangle_count differ.
+ * Vertices and triangles 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 triangles (or properties) visit unique triangles
+ * for indices in the [0 unique_triangle_count[ range and back-faces of the
+ * doubly-included triangles in the [unique_triangle_count triangle_count[
+ * range.
+ *****************************************************************************/
+/* Returns the header of an enclosure. */
+SENC3D_API res_T
+senc3d_enclosure_get_header
+ (const struct senc3d_enclosure* enclosure,
+ struct senc3d_enclosure_header* header);
+
+/* Returns the itri_th triangle of an enclosure.
+ * Indices are local to the enclosure. */
+SENC3D_API res_T
+senc3d_enclosure_get_triangle
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned itri,
+ unsigned indices[SENC3D_GEOMETRY_DIMENSION]);
+
+/* Returns the coordinates of the ivert_th vertex of an enclosure. */
+SENC3D_API res_T
+senc3d_enclosure_get_vertex
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned ivert,
+ double coord[SENC3D_GEOMETRY_DIMENSION]);
+
+/* Returns the global id of the itri_th triangle of an enclosure
+ * and the involved side. */
+SENC3D_API res_T
+senc3d_enclosure_get_triangle_id
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned itri,
+ unsigned* gid,
+ enum senc3d_side* side);
+
+/* Returns the id of the imed_th medium of an enclosure. */
+SENC3D_API res_T
+senc3d_enclosure_get_medium
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned imed,
+ unsigned* medium);
+
+SENC3D_API res_T
+senc3d_enclosure_ref_get
+ (struct senc3d_enclosure* enclosure);
+
+SENC3D_API res_T
+senc3d_enclosure_ref_put
+ (struct senc3d_enclosure* enclosure);
+
+END_DECLS
+
+#endif /* SENC3D_H */
diff --git a/src/senc3d_descriptor.c b/src/senc3d_descriptor.c
@@ -0,0 +1,160 @@
+/* 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
+ * 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 "senc3d_enclosure_c.h"
+#include "senc3d_scene_c.h"
+#include "senc3d.h"
+
+#include <rsys/rsys.h>
+#include <rsys/double3.h>
+#include <rsys/mem_allocator.h>
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+senc3d_scene_get_max_medium
+ (const struct senc3d_scene* scn, unsigned* max_medium_id)
+{
+ 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
+senc3d_scene_get_enclosure_count
+ (const struct senc3d_scene* scn, unsigned* count)
+{
+ size_t tmp;
+ if(!scn || !count) return RES_BAD_ARG;
+ tmp = darray_enclosure_size_get(&scn->analyze.enclosures);
+ ASSERT(tmp < UINT_MAX); /* API type */
+ ASSERT(scn->analyze.enclosures_count == tmp);
+ *count = (unsigned)tmp;
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_enclosure_count_by_medium
+ (const struct senc3d_scene* scn,
+ const unsigned imed,
+ unsigned* count)
+{
+ size_t tmp, m_idx;
+ const struct darray_enc_id* enc_ids;
+ if(!scn || !count
+ || (imed != SENC3D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
+ return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ m_idx = (imed == SENC3D_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 */
+ *count = (unsigned)tmp;
+ return RES_OK;
+}
+
+FINLINE res_T
+senc3d_scene_get_enclosure
+ (struct senc3d_scene* scn,
+ const unsigned idx,
+ struct senc3d_enclosure** out_enc)
+{
+ struct senc3d_enclosure* enc;
+ if(!scn || idx >= darray_enclosure_size_get(&scn->analyze.enclosures)
+ || !out_enc)
+ return RES_BAD_ARG;
+ enc = enclosure_create(scn, idx);
+ if(!enc) return RES_MEM_ERR;
+ *out_enc = enc;
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_enclosure_by_medium
+ (struct senc3d_scene* scn,
+ const unsigned imed,
+ const unsigned idx,
+ struct senc3d_enclosure** out_enc)
+{
+ size_t m_idx;
+ const struct darray_enc_id* enc_ids;
+ unsigned index;
+ if(!scn || !out_enc
+ || (imed != SENC3D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
+ return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ m_idx = (imed == SENC3D_UNSPECIFIED_MEDIUM) ? 0 : imed + 1;
+ enc_ids =
+ 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 senc3d_scene_get_enclosure(scn, index, out_enc);
+}
+
+res_T
+senc3d_scene_get_triangle_enclosures
+ (const struct senc3d_scene* scn,
+ const unsigned itri,
+ unsigned enclosures[2])
+{
+ const struct triangle_enc* trg;
+ int i;
+ if(!enclosures || !scn
+ || itri >= darray_triangle_enc_size_get(&scn->analyze.triangles_enc))
+ return RES_BAD_ARG;
+ trg = darray_triangle_enc_cdata_get(&scn->analyze.triangles_enc) + itri;
+ FOR_EACH(i, 0, 2) {
+#if (UINT_MAX < ENCLOSURE_MAX__)
+ ASSERT(trg->enclosure[i] < UINT_MAX);
+#endif
+ enclosures[i] = (unsigned)trg->enclosure[i]; /* Back to API type */
+ }
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_frontier_segments_count
+ (const struct senc3d_scene* scn,
+ unsigned* count)
+{
+ size_t tmp;
+ if(!scn || !count)
+ return RES_BAD_ARG;
+ tmp = darray_frontier_edge_size_get(&scn->analyze.frontiers);
+ ASSERT(tmp < UINT_MAX);
+ *count = (unsigned)tmp;
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_frontier_segment
+ (const struct senc3d_scene* scn,
+ const unsigned iseg,
+ unsigned vrtx_id[2])
+{
+ const struct trg_edge* edge;
+ if(!vrtx_id || !scn
+ || iseg >= darray_frontier_edge_size_get(&scn->analyze.frontiers))
+ return RES_BAD_ARG;
+ edge = darray_frontier_edge_cdata_get(&scn->analyze.frontiers) + iseg;
+ vrtx_id[0] = (unsigned)edge->vrtx0; /* Back to API type */
+ vrtx_id[1] = (unsigned)edge->vrtx1; /* Back to API type */
+ return RES_OK;
+}
diff --git a/src/senc3d_device.c b/src/senc3d_device.c
@@ -0,0 +1,148 @@
+/* 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
+ * 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 "senc3d.h"
+#include "senc3d_device_c.h"
+
+#include <rsys/logger.h>
+#include <rsys/mem_allocator.h>
+
+#include <omp.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+log_msg
+ (struct senc3d_device* dev,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(dev && msg);
+ if(dev->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(dev->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
+ }
+}
+
+static void
+device_release(ref_T* ref)
+{
+ struct senc3d_device* dev;
+ ASSERT(ref);
+ dev = CONTAINER_OF(ref, struct senc3d_device, ref);
+ MEM_RM(dev->allocator, dev);
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+void
+log_err(struct senc3d_device* dev, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(dev && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(dev, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_warn(struct senc3d_device* dev, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(dev && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(dev, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_info(struct senc3d_device* dev, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(dev && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(dev, LOG_OUTPUT, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+senc3d_device_create
+ (struct logger* logger,
+ struct mem_allocator* mem_allocator,
+ const unsigned nthreads_hint,
+ const int verbose,
+ struct senc3d_device** out_dev)
+{
+ struct logger* log = NULL;
+ struct senc3d_device* dev = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+ if(nthreads_hint == 0 || !out_dev) return RES_BAD_ARG;
+
+ log = logger ? logger : LOGGER_DEFAULT;
+ allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
+ dev = MEM_CALLOC(allocator, 1, sizeof(struct senc3d_device));
+ if(!dev) {
+ if(verbose) {
+ /* Do not use helper log functions since dev is not initialised */
+ CHK(logger_print(log, LOG_ERROR,
+ "%s: could not allocate the StarEnclosures device.\n", FUNC_NAME) == RES_OK);
+ }
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ dev->logger = log;
+ dev->allocator = allocator;
+ dev->verbose = verbose;
+ /* Cannot use int args for MMIN here as default is -1 */
+ dev->nthreads = (int)MMIN(nthreads_hint, (unsigned)omp_get_num_procs());
+ ref_init(&dev->ref);
+
+exit:
+ if(dev) *out_dev = dev;
+ return res;
+error:
+ if(dev) {
+ SENC3D(device_ref_put(dev));
+ dev = NULL;
+ }
+ goto exit;
+}
+
+res_T
+senc3d_device_ref_get(struct senc3d_device* dev)
+{
+ if(!dev) return RES_BAD_ARG;
+ ref_get(&dev->ref);
+ return RES_OK;
+}
+
+res_T
+senc3d_device_ref_put(struct senc3d_device* dev)
+{
+ if(!dev) return RES_BAD_ARG;
+ ref_put(&dev->ref, device_release);
+ return RES_OK;
+}
diff --git a/src/senc3d_device_c.h b/src/senc3d_device_c.h
@@ -0,0 +1,71 @@
+/* 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
+ * 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 SENC3D_DEVICE_C_H
+#define SENC3D_DEVICE_C_H
+
+#include <rsys/free_list.h>
+#include <rsys/ref_count.h>
+
+struct name { FITEM; };
+#define FITEM_TYPE name
+#include <rsys/free_list.h>
+
+struct senc3d_device {
+ struct logger* logger;
+ struct mem_allocator* allocator;
+ int verbose;
+ int nthreads;
+
+ ref_T ref;
+};
+
+/* Conditionally log a message on the LOG_ERROR stream of the device logger,
+ * with respect to the device verbose flag */
+extern LOCAL_SYM void
+log_err
+ (struct senc3d_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_WARNING stream of the device logger,
+ * with respect to the device verbose flag */
+extern LOCAL_SYM void
+log_warn
+ (struct senc3d_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_OUTPUT stream of the device logger,
+ * with respect to the device verbose flag */
+extern LOCAL_SYM void
+log_info
+ (struct senc3d_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+
+#endif /* SENC3D_DEVICE_C_H */
diff --git a/src/senc3d_enclosure.c b/src/senc3d_enclosure.c
@@ -0,0 +1,167 @@
+/* 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
+* 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 "senc3d_enclosure_c.h"
+#include "senc3d_enclosure_data.h"
+#include "senc3d_scene_c.h"
+#include "senc3d_device_c.h"
+#include "senc3d.h"
+
+#include <rsys/rsys.h>
+#include <rsys/double3.h>
+#include <rsys/mem_allocator.h>
+
+
+/*******************************************************************************
+ * Helper function
+ ******************************************************************************/
+static void
+enclosure_release(ref_T * ref)
+{
+ struct senc3d_enclosure* enclosure = NULL;
+ struct senc3d_scene* scn = NULL;
+ ASSERT(ref);
+ enclosure = CONTAINER_OF(ref, struct senc3d_enclosure, ref);
+ scn = enclosure->scene;
+ MEM_RM(scn->dev->allocator, enclosure);
+ SENC3D(scene_ref_put(scn));
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+struct senc3d_enclosure*
+enclosure_create
+ (struct senc3d_scene* scn,
+ const unsigned idx)
+{
+ struct senc3d_enclosure* enc;
+ ASSERT(scn && idx < darray_enclosure_size_get(&scn->analyze.enclosures));
+ enc = MEM_CALLOC(scn->dev->allocator, 1, sizeof(struct senc3d_enclosure));
+ if(enc) {
+ const struct enclosure_data* data
+ = darray_enclosure_data_get(&scn->analyze.enclosures) + idx;
+ enc->scene = scn;
+ enc->data = data;
+ ref_init(&enc->ref);
+ SENC3D(scene_ref_get(scn));
+ }
+ return enc;
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+senc3d_enclosure_get_header
+ (const struct senc3d_enclosure* enclosure,
+ struct senc3d_enclosure_header* header)
+{
+ if(!enclosure || !header) return RES_BAD_ARG;
+ *header = enclosure->data->header;
+ return RES_OK;
+}
+
+res_T
+senc3d_enclosure_get_triangle
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned itri,
+ unsigned indices[3])
+{
+ const struct side_enc* side;
+ int i;
+ if(!enclosure || !indices
+ || itri >= enclosure->data->header.primitives_count)
+ return RES_BAD_ARG;
+ ASSERT(darray_sides_enc_size_get(&enclosure->data->sides)
+ == enclosure->data->header.primitives_count);
+ side = darray_sides_enc_cdata_get(&enclosure->data->sides) + itri;
+ FOR_EACH(i, 0, 3) {
+ ASSERT(side->vertice_id[i] < UINT_MAX);
+ indices[i] = (unsigned)side->vertice_id[i]; /* Back to API type */
+ }
+ return RES_OK;
+}
+
+res_T
+senc3d_enclosure_get_vertex
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned ivert,
+ double coord[3])
+{
+ if(!enclosure || !coord
+ || ivert >= enclosure->data->header.vertices_count) {
+ return RES_BAD_ARG;
+ } else {
+ const vrtx_id_t idx
+ = darray_vrtx_id_cdata_get(&enclosure->data->vertices)[ivert];
+ const union double3* positions
+ = darray_position_cdata_get(&enclosure->scene->vertices);
+ ASSERT(darray_vrtx_id_size_get(&enclosure->data->vertices)
+ == enclosure->data->header.vertices_count);
+ d3_set(coord, positions[idx].vec);
+ return RES_OK;
+ }
+}
+
+res_T
+senc3d_enclosure_get_triangle_id
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned itri,
+ unsigned* gid,
+ enum senc3d_side* sde)
+{
+ const struct side_enc* side;
+ if(!enclosure || !gid || !sde
+ || itri >= enclosure->data->header.primitives_count)
+ return RES_BAD_ARG;
+ ASSERT(darray_sides_enc_size_get(&enclosure->data->sides)
+ == enclosure->data->header.primitives_count);
+ side = darray_sides_enc_cdata_get(&enclosure->data->sides) + itri;
+ *gid = (unsigned)TRGSIDE_2_TRG(side->side_id);
+ *sde = TRGSIDE_2_SIDE(side->side_id);
+ return RES_OK;
+}
+
+res_T
+senc3d_enclosure_get_medium
+ (const struct senc3d_enclosure* enclosure,
+ const unsigned imed,
+ unsigned* medium)
+{
+ if(!enclosure || !medium
+ || imed >= enclosure->data->header.enclosed_media_count)
+ return RES_BAD_ARG;
+ ASSERT(enclosure->data->header.enclosed_media_count
+ == darray_media_size_get(&enclosure->data->enclosed_media));
+ *medium = darray_media_cdata_get(&enclosure->data->enclosed_media)[imed];
+ return RES_OK;
+}
+
+res_T
+senc3d_enclosure_ref_get(struct senc3d_enclosure* enc)
+{
+ if(!enc) return RES_BAD_ARG;
+ ref_get(&enc->ref);
+ return RES_OK;
+}
+
+res_T
+senc3d_enclosure_ref_put(struct senc3d_enclosure* enc)
+{
+ if(!enc) return RES_BAD_ARG;
+ ref_put(&enc->ref, enclosure_release);
+ return RES_OK;
+}
diff --git a/src/senc3d_enclosure_c.h b/src/senc3d_enclosure_c.h
@@ -0,0 +1,37 @@
+/* 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
+* 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 SENC3D_ENCLOSURE_C_H
+#define SENC3D_ENCLOSURE_C_H
+
+#include <rsys/ref_count.h>
+
+#include "senc3d.h"
+
+struct enclosure_data;
+struct senc3d_scene;
+
+struct senc3d_enclosure {
+ const struct enclosure_data* data;
+ struct senc3d_scene* scene;
+ ref_T ref;
+};
+
+struct senc3d_enclosure*
+enclosure_create
+ (struct senc3d_scene* scene,
+ const unsigned idx);
+
+#endif /* SENC3D_ENCLOSURE_C_H */
diff --git a/src/senc3d_enclosure_data.h b/src/senc3d_enclosure_data.h
@@ -0,0 +1,235 @@
+/* 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
+* 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 SENC3D_ENCLOSURE_DATA_H
+#define SENC3D_ENCLOSURE_DATA_H
+
+#include "senc3d.h"
+#include "SENC3D_internal_types.h"
+#include "SENC3D_side_range.h"
+
+#include <rsys/rsys.h>
+#include <rsys/ref_count.h>
+#include <rsys/hash_table.h>
+#include <rsys/dynamic_array.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[3];
+ side_id_t side_id;
+};
+
+#define DARRAY_NAME sides_enc
+#define DARRAY_DATA struct side_enc
+#include <rsys/dynamic_array.h>
+
+/* unsigned char array with init to zero */
+static FINLINE void
+zero_init_uchar
+ (struct mem_allocator* alloc, unsigned char* data)
+{
+ ASSERT(data); (void) alloc;
+ *data = 0;
+}
+#define DARRAY_FUNCTOR_INIT zero_init_uchar
+#include <rsys/dynamic_array_uchar.h>
+
+static void
+init_header(struct senc3d_enclosure_header* header)
+{
+ ASSERT(header);
+ header->enclosure_id = ENCLOSURE_NULL__;
+ header->primitives_count = 0;
+ header->unique_primitives_count = 0;
+ header->vertices_count = 0;
+ header->enclosed_media_count = 0;
+ header->is_infinite = CHAR_MAX;
+}
+
+#define DARRAY_NAME media
+#define DARRAY_DATA medium_id_t
+#include <rsys/dynamic_array.h>
+
+static FINLINE res_T
+bool_array_of_media_merge
+ (struct darray_uchar* dst,
+ const unsigned char* src,
+ const medium_id_t sz)
+{
+ res_T res = RES_OK;
+ medium_id_t i;
+ unsigned char* data_dst;
+
+ ASSERT(src && dst);
+
+ OK(darray_uchar_resize(dst, sz));
+ data_dst = darray_uchar_data_get(dst);
+ ASSERT(sz <= MEDIUM_MAX__);
+ if(res != RES_OK) goto error;
+ FOR_EACH(i, 0, sz) {
+ if(!src[i]) continue;
+ data_dst[i] = 1;
+ }
+end:
+ return res;
+error:
+ goto end;
+}
+
+static FINLINE res_T
+bool_array_of_media_to_darray_media
+ (struct darray_media* dst,
+ const struct darray_uchar* src,
+ const medium_id_t next_medium_idx)
+{
+ res_T res = RES_OK;
+ unsigned m_idx;
+ const unsigned char* data;
+
+ ASSERT(src && dst);
+
+ data = darray_uchar_cdata_get(src);
+ 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(m_idx, 0, next_medium_idx + 1) {
+ medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC3D_UNSPECIFIED_MEDIUM;
+ if(!data[m_idx]) continue;
+ res = darray_media_push_back(dst, &medium);
+ if(res != RES_OK) goto error;
+ }
+end:
+ return res;
+error:
+ goto end;
+}
+
+struct enclosure_data {
+ struct senc3d_enclosure_header header;
+ /* Same triangle can appear twice if both sides */
+ struct darray_sides_enc sides;
+ /* Index of vertices in scene's unique vertices */
+ struct darray_vrtx_id vertices;
+ /* List of the enclosed media */
+ struct darray_uchar tmp_enclosed_media;
+ struct darray_media enclosed_media;
+ /* Number of components involved in this enclosure */
+ component_id_t cc_count;
+ /* Linked list of the components */
+ component_id_t first_component;
+ /* Range of triangles member of the enclosure */
+ struct side_range side_range;
+ /* Counts */
+ side_id_t side_count;
+};
+
+static FINLINE void
+enclosure_data_init(struct mem_allocator* alloc, struct enclosure_data* enc) {
+ ASSERT(enc);
+ init_header(&enc->header);
+ enc->cc_count = 0;
+ enc->first_component = COMPONENT_NULL__;
+ enc->side_range.first = SIDE_NULL__;
+ enc->side_range.last = 0;
+ enc->side_count = 0;
+ darray_sides_enc_init(alloc, &enc->sides);
+ darray_vrtx_id_init(alloc, &enc->vertices);
+ darray_uchar_init(alloc, &enc->tmp_enclosed_media);
+ darray_media_init(alloc, &enc->enclosed_media);
+}
+
+static FINLINE res_T
+enclosure_data_copy
+ (struct enclosure_data* dst,
+ const struct enclosure_data* src)
+{
+ res_T res = RES_OK;
+ ASSERT(src && dst);
+ dst->header = src->header;
+ dst->cc_count = src->cc_count;
+ dst->first_component = src->first_component;
+ dst->side_range = src->side_range;
+ dst->side_count = src->side_count;
+ OK(darray_sides_enc_copy(&dst->sides, &src->sides));
+ OK(darray_vrtx_id_copy(&dst->vertices, &src->vertices));
+ OK(darray_uchar_copy(&dst->tmp_enclosed_media, &src->tmp_enclosed_media));
+ OK(darray_media_copy(&dst->enclosed_media, &src->enclosed_media));
+error:
+ return res;
+}
+
+static FINLINE void
+enclosure_data_release(struct enclosure_data* n) {
+ ASSERT(n);
+ darray_sides_enc_release(&n->sides);
+ darray_vrtx_id_release(&n->vertices);
+ darray_uchar_release(&n->tmp_enclosed_media);
+ darray_media_release(&n->enclosed_media);
+}
+
+static FINLINE res_T
+enclosure_data_copy_and_release
+ (struct enclosure_data* dst,
+ struct enclosure_data* src)
+{
+ res_T res = RES_OK;
+ ASSERT(src && dst);
+ dst->header = src->header;
+ dst->cc_count = src->cc_count;
+ dst->first_component = src->first_component;
+ dst->side_range = src->side_range;
+ dst->side_count = src->side_count;
+ OK(darray_sides_enc_copy_and_release(&dst->sides, &src->sides));
+ OK(darray_vrtx_id_copy_and_release(&dst->vertices, &src->vertices));
+ OK(darray_uchar_copy_and_release(&dst->tmp_enclosed_media,
+ &src->tmp_enclosed_media));
+ OK(darray_media_copy_and_release(&dst->enclosed_media, &src->enclosed_media));
+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 /* SENC3D_ENCLOSURE_DATA_H */
diff --git a/src/senc3d_internal_types.h b/src/senc3d_internal_types.h
@@ -0,0 +1,142 @@
+/* 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
+* 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 SENC3D_INTERNAL_TYPES_H
+#define SENC3D_INTERNAL_TYPES_H
+
+#include "senc3d.h"
+
+#include <rsys/math.h>
+
+#include <stdio.h>
+#include <stdint.h>
+
+/* Utility macros */
+#ifdef NDEBUG
+#define OK2(Expr)\
+ if((tmp_res = (Expr)) != RES_OK) goto tmp_error;
+
+#define OK(Expr)\
+ if((res = (Expr)) != RES_OK) goto error;
+#else
+#define OK2(Expr)\
+ if((tmp_res = (Expr)) != RES_OK) {\
+ fprintf(stderr, "%s: error code set to %d at line %d\n", FUNC_NAME,\
+ tmp_res, __LINE__);\
+ goto tmp_error;\
+ }
+
+#define OK(Expr)\
+ if((res = (Expr)) != RES_OK) {\
+ fprintf(stderr, "%s: error code set to %d at line %d\n", FUNC_NAME,\
+ res, __LINE__);\
+ goto error;\
+ }
+#endif
+
+/* Side IDs are uint32_t */
+typedef uint32_t side_id_t;
+#define SIDE_MAX__ (UINT32_MAX-1)
+#define SIDE_NULL__ UINT32_MAX
+
+/* Trg IDs use internally side_id_t */
+/* Cannot be larger than unsigned, as the API uses it. */
+typedef side_id_t trg_id_t;
+/* TRG_MAX__ is limited to allow to count sides */
+#define TRG_MAX__ (SIDE_MAX__ / 2)
+#define TRG_NULL__ UINT32_MAX
+
+/* Vertex IDs are internally uint32_t */
+/* Cannot be larger than unsigned, as the API uses it. */
+typedef uint32_t vrtx_id_t;
+#define VRTX_MAX__ (UINT32_MAX-1)
+#define VRTX_NULL__ UINT32_MAX
+
+/* Edge IDs use the same type than vertex IDs */
+/* Cannot be larger than unsigned, as the API uses it. */
+typedef vrtx_id_t edge_id_t;
+#define EDGE_MAX__ VRTX_MAX__
+#define EDGE_NULL__ VRTX_NULL__
+
+/* Medium IDs are internally uint32_t */
+/* Should nnot be larger than unsigned, as the API uses it. */
+typedef uint32_t medium_id_t;
+#define MEDIUM_MAX__ INT32_MAX
+#define MEDIUM_NULL__ UINT32_MAX
+
+/* Enclosure IDs are internally uint32_t */
+/* Cannot be larger than unsigned, as the API uses it. */
+typedef uint32_t enclosure_id_t;
+#define ENCLOSURE_MAX__ UINT32_MAX
+#define ENCLOSURE_NULL__ UINT32_MAX
+
+/* Component IDs use the same type than enclosure IDs */
+typedef enclosure_id_t component_id_t;
+#define COMPONENT_MAX__ (UINT32_MAX - 2) /* To allow special values */
+#define COMPONENT_NULL__ UINT32_MAX
+/* Special values */
+#define CC_GROUP_ROOT_NONE UINT32_MAX
+#define CC_GROUP_ROOT_INFINITE (UINT32_MAX - 1)
+#define CC_GROUP_ID_NONE UINT32_MAX
+#define CC_ID_NONE UINT32_MAX
+
+/* This one is used as flag */
+enum side_flag {
+ FLAG_FRONT = BIT(0),
+ FLAG_BACK = BIT(1)
+};
+
+/* Utility macros */
+static FINLINE trg_id_t
+TRGSIDE_2_TRG(side_id_t s) {
+ ASSERT(((size_t)s >> 1) <= TRG_MAX__);
+ return s >> 1;
+}
+
+static FINLINE int
+TRGSIDE_IS_FRONT(side_id_t s) {
+ return (s & 1) == 0;
+}
+
+static FINLINE enum senc3d_side
+TRGSIDE_2_SIDE(side_id_t s) {
+ return (s & 1) ? SENC3D_BACK : SENC3D_FRONT;
+}
+
+static FINLINE enum side_flag
+TRGSIDE_2_SIDEFLAG(side_id_t s) {
+ return (s & 1) ? FLAG_BACK : FLAG_FRONT;
+}
+
+static FINLINE unsigned char
+SIDE_CANCELED_FLAG(enum side_flag f) {
+ ASSERT((f << 4) <= UCHAR_MAX);
+ return (unsigned char)(f << 4);
+}
+
+static FINLINE side_id_t
+TRGIDxSIDE_2_TRGSIDE(trg_id_t t, enum senc3d_side i) {
+ ASSERT((((size_t)t << 1) | (i == SENC3D_BACK)) < SIDE_MAX__);
+ ASSERT(i == SENC3D_FRONT || i == SENC3D_BACK);
+ return (side_id_t)((t << 1) | (i == SENC3D_BACK));
+}
+
+static FINLINE side_id_t
+TRGSIDE_OPPOSITE(side_id_t s) {
+ return TRGIDxSIDE_2_TRGSIDE(TRGSIDE_2_TRG(s),
+ TRGSIDE_IS_FRONT(s) ? SENC3D_BACK : SENC3D_FRONT);
+}
+
+#endif /* SENC3D_INTERNAL_TYPES_H */
diff --git a/src/senc3d_s3d_helper.h b/src/senc3d_s3d_helper.h
@@ -0,0 +1,92 @@
+/* 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
+* 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 SENC3D_S3D_WRAPPER_H
+#define SENC3D_S3D_WRAPPER_H
+
+#include "senc3d.h"
+
+#include <rsys/rsys.h>
+#include <rsys/float3.h>
+
+/* Get vertex indices for the itri_th triangle.
+ * Suitable for use as get_indice callback in s3d_mesh_setup_indexed_vertices
+ * calls. */
+static FINLINE void
+SENC3D_s3d_scene_get_indices
+ (const unsigned itri,
+ unsigned indices[3],
+ void* ctx)
+{
+ const struct senc3d_scene* scene = ctx;
+ res_T r;
+ ASSERT(indices && scene);
+ r = senc3d_scene_get_triangle(scene, itri, indices);
+ ASSERT(r == RES_OK); (void)r;
+}
+
+/* Get coordinates for the ivert_th vertex.
+ * Suitable for use as s3d_vertex_data getter for S3D_POSITION s3d_attrib_usage
+ * in s3d_mesh_setup_indexed_vertices calls. */
+static FINLINE void
+SENC3D_s3d_scene_get_position
+ (const unsigned ivert,
+ float coord[3],
+ void* ctx)
+{
+ const struct senc3d_scene* scene = ctx;
+ double tmp[3];
+ res_T r;
+ ASSERT(coord && scene);
+ r = senc3d_scene_get_vertex(scene, ivert, tmp);
+ ASSERT(r == RES_OK); (void)r;
+ f3_set_d3(coord, tmp);
+}
+
+/* Get vertex indices for the itri_th triangle of the enclosure.
+ * Suitable for use as get_indice callback in s3d_mesh_setup_indexed_vertices
+ * calls. */
+static FINLINE void
+SENC3D_s3d_enclosure_get_indices
+ (const unsigned itri,
+ unsigned indices[3],
+ void* ctx)
+{
+ const struct senc3d_enclosure* enclosure = ctx;
+ res_T r;
+ ASSERT(indices && ctx);
+ r = senc3d_enclosure_get_triangle(enclosure, itri, indices);
+ ASSERT(r == RES_OK); (void)r;
+}
+
+/* Get coordinates for the ivert_th vertex of the enclosure.
+ * Suitable for use as s3d_vertex_data getter for S3D_POSITION s3d_attrib_usage
+ * in s3d_mesh_setup_indexed_vertices calls. */
+static FINLINE void
+SENC3D_s3d_enclosure_get_position
+ (const unsigned ivert,
+ float coord[3],
+ void* ctx)
+{
+ const struct senc3d_enclosure* enclosure = ctx;
+ double tmp[3];
+ res_T r;
+ ASSERT(coord && ctx);
+ r = senc3d_enclosure_get_vertex(enclosure, ivert, tmp);
+ ASSERT(r == RES_OK); (void)r;
+ f3_set_d3(coord, tmp);
+}
+
+#endif /* SENC3D_S3D_WRAPPER_H */
diff --git a/src/senc3d_scene.c b/src/senc3d_scene.c
@@ -0,0 +1,327 @@
+/* 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
+ * 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 "senc3d.h"
+#include "senc3d_device_c.h"
+#include "senc3d_scene_c.h"
+#include "senc3d_scene_analyze_c.h"
+
+#include <rsys/rsys.h>
+#include <rsys/double3.h>
+#include <rsys/mem_allocator.h>
+
+#include <limits.h>
+
+/*******************************************************************************
+ * Helper function
+ ******************************************************************************/
+static void
+scene_release(ref_T * ref)
+{
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ ASSERT(ref);
+ scn = CONTAINER_OF(ref, struct senc3d_scene, ref);
+ dev = scn->dev;
+ darray_triangle_in_release(&scn->triangles_in);
+ darray_position_release(&scn->vertices);
+ darray_side_range_release(&scn->media_use);
+
+ darray_triangle_enc_release(&scn->analyze.triangles_enc);
+ darray_enclosure_release(&scn->analyze.enclosures);
+ darray_enc_ids_array_release(&scn->analyze.enc_ids_array_by_medium);
+ darray_frontier_edge_release(&scn->analyze.frontiers);
+
+ MEM_RM(dev->allocator, scn);
+ SENC3D(device_ref_put(dev));
+}
+
+static INLINE int
+compatible_medium
+ (const medium_id_t m1,
+ const medium_id_t m2)
+{
+ if(m1 == SENC3D_UNSPECIFIED_MEDIUM || m2 == SENC3D_UNSPECIFIED_MEDIUM) return 1;
+ return (m1 == m2);
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+senc3d_scene_create
+ (struct senc3d_device* dev,
+ const int conv,
+ const unsigned ntris,
+ 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 senc3d_scene** out_scn)
+{
+ struct senc3d_scene* scn = NULL;
+ /* Tables to detect duplicates */
+ struct htable_vrtx unique_vertices;
+ struct htable_trg unique_triangles;
+ unsigned i;
+ res_T res = RES_OK;
+
+ if(!dev || !out_scn || !indices || !position
+ /* Convention must be set both regarding FRONT/BACK and INSIDE/OUTSIDE */
+ || !(conv & (SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_BACK))
+ || !(conv & (SENC3D_CONVENTION_NORMAL_INSIDE | SENC3D_CONVENTION_NORMAL_OUTSIDE)))
+ return RES_BAD_ARG;
+
+ scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct senc3d_scene));
+ if(!scn) {
+ log_err(dev, "%s: could not allocate the StarEnclosures scene.\n", FUNC_NAME);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&scn->ref);
+ SENC3D(device_ref_get(dev));
+ scn->dev = dev;
+ scn->convention = conv;
+ scn->ntris = ntris;
+ scn->next_medium_idx = 0;
+ scn->nverts = nverts;
+ darray_triangle_in_init(dev->allocator, &scn->triangles_in);
+ darray_position_init(dev->allocator, &scn->vertices);
+ htable_vrtx_init(dev->allocator, &unique_vertices);
+ htable_trg_init(dev->allocator, &unique_triangles);
+ darray_side_range_init(dev->allocator, &scn->media_use);
+
+ darray_triangle_enc_init(scn->dev->allocator, &scn->analyze.triangles_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_frontier_edge_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 || !ntris) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ OK(darray_position_reserve(&scn->vertices, scn->nverts));
+ OK(darray_triangle_in_reserve(&scn->triangles_in, scn->ntris));
+ OK(htable_vrtx_reserve(&unique_vertices, scn->nverts));
+ OK(htable_trg_reserve(&unique_triangles, scn->ntris));
+
+ /* Get vertices */
+ FOR_EACH(i, 0, nverts) {
+ vrtx_id_t* p_vrtx;
+ union double3 tmp;
+ /* API: position needs an unsigned */
+ position(i, tmp.vec, ctx);
+ p_vrtx = htable_vrtx_find(&unique_vertices, &tmp);
+ if(p_vrtx) {
+ /* Duplicate vertex */
+ log_err(scn->dev, "%s: vertex %u is a duplicate.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* 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 triangles */
+ FOR_EACH(i, 0, ntris) {
+ int j;
+ unsigned med[2] = { SENC3D_UNSPECIFIED_MEDIUM, SENC3D_UNSPECIFIED_MEDIUM };
+ unsigned ind[3];
+ union vrtx_id3 trg_key;
+ struct triangle_in tmp;
+ trg_id_t* p_trg;
+ indices(i, ind, ctx); /* API: indices need unsigneds */
+ FOR_EACH(j, 0, 3) {
+ if(ind[j] >= nverts) {
+ log_err(scn->dev, "%s: triangle %u uses invalid vertex id %u.\n",
+ FUNC_NAME, i, ind[j]);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(ind[j] <= VRTX_MAX__);
+ tmp.vertice_id[j] = (vrtx_id_t)ind[j];
+ }
+ if(tmp.vertice_id[0] == tmp.vertice_id[1]
+ || tmp.vertice_id[0] == tmp.vertice_id[2]
+ || tmp.vertice_id[1] == tmp.vertice_id[2])
+ {
+ log_err(scn->dev, "%s: triangle %u is degenerated.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* Get media */
+ if(media) media(i, med, ctx); /* API: media needs an unsigned */
+ trg_make_key(&trg_key, tmp.vertice_id);
+ p_trg = htable_trg_find(&unique_triangles, &trg_key);
+ if(p_trg) {
+ /* Duplicate triangle */
+ log_err(scn->dev, "%s: triangle %u is a duplicate.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* New triangle */
+ ASSERT(i == htable_trg_size_get(&unique_triangles));
+ OK(htable_trg_set(&unique_triangles, &trg_key, &i));
+ FOR_EACH(j, 0, 2) {
+ struct side_range* media_use;
+ unsigned m_idx = (med[j] == SENC3D_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 SENC3D_UNSPECIFIED_MEDIUM */
+ media_use = darray_side_range_data_get(&scn->media_use) + m_idx;
+ media_use->first =
+ MMIN(media_use->first, TRGIDxSIDE_2_TRGSIDE((trg_id_t)i, j));
+ ASSERT(media_use->first < 2 * (scn->ntris + 1));
+ media_use->last =
+ MMAX(media_use->last, TRGIDxSIDE_2_TRGSIDE((trg_id_t)i, j));
+ ASSERT(media_use->last < 2 * (scn->ntris + 1));
+ ASSERT(media_use->first <= media_use->last);
+ }
+ OK(darray_triangle_in_push_back(&scn->triangles_in, &tmp));
+ }
+
+ OK(darray_enc_ids_array_resize(&scn->analyze.enc_ids_array_by_medium,
+ 1 + scn->next_medium_idx)); /* +1 is for unspecified */
+ /* Proceed to the analyze */
+ OK(scene_analyze(scn));
+
+exit:
+ htable_vrtx_release(&unique_vertices);
+ htable_trg_release(&unique_triangles);
+ if(scn) *out_scn = scn;
+ return res;
+
+error:
+ if(scn) {
+ SENC3D(scene_ref_put(scn));
+ scn = NULL;
+ }
+ goto exit;
+}
+
+res_T
+senc3d_scene_get_convention
+ (const struct senc3d_scene* scn,
+ int* convention)
+{
+ if(!scn || !convention) return RES_BAD_ARG;
+ *convention = scn->convention;
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_triangles_count
+ (const struct senc3d_scene* scn,
+ unsigned* count)
+{
+ if(!scn || !count) return RES_BAD_ARG;
+ *count = scn->ntris;
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_triangle
+ (const struct senc3d_scene* scn,
+ const unsigned itri,
+ unsigned indices[3])
+{
+ const struct triangle_in* trg;
+ int i;
+ if(!scn || !indices
+ || itri >= darray_triangle_in_size_get(&scn->triangles_in))
+ return RES_BAD_ARG;
+ trg = darray_triangle_in_cdata_get(&scn->triangles_in) + itri;
+
+ FOR_EACH(i, 0, 3) {
+ ASSERT(trg->vertice_id[i] < UINT_MAX);
+ indices[i] = (unsigned)trg->vertice_id[i]; /* Back to API type */
+ }
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_triangle_media
+ (const struct senc3d_scene* scn,
+ const unsigned itri,
+ unsigned media[2])
+{
+ const struct triangle_in* trg;
+ int i;
+ if(!scn || !media
+ || itri >= darray_triangle_in_size_get(&scn->triangles_in))
+ return RES_BAD_ARG;
+ trg = darray_triangle_in_cdata_get(&scn->triangles_in) + itri;
+
+ FOR_EACH(i, 0, 2) {
+ ASSERT(trg->vertice_id[i] < UINT_MAX);
+ media[i] = (unsigned)trg->medium[i]; /* Back to API type */
+ }
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_vertices_count
+ (const struct senc3d_scene* scn,
+ unsigned* count)
+{
+ if(!scn || !count) return RES_BAD_ARG;
+ *count = scn->nverts;
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_get_vertex
+ (const struct senc3d_scene* scn,
+ const unsigned ivert,
+ double coord[3])
+{
+ const union double3* v;
+ if(!scn || !coord
+ || ivert >= darray_position_size_get(&scn->vertices))
+ return RES_BAD_ARG;
+
+ v = darray_position_cdata_get(&scn->vertices) + ivert;
+ d3_set(coord, v->vec);
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_ref_get(struct senc3d_scene* scn)
+{
+ if(!scn) return RES_BAD_ARG;
+ ref_get(&scn->ref);
+ return RES_OK;
+}
+
+res_T
+senc3d_scene_ref_put(struct senc3d_scene* scn)
+{
+ if(!scn) return RES_BAD_ARG;
+ ref_put(&scn->ref, scene_release);
+ return RES_OK;
+}
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -0,0 +1,1347 @@
+/* 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
+ * 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 "senc3d.h"
+#include "senc3d_device_c.h"
+#include "senc3d_scene_c.h"
+#include "senc3d_scene_analyze_c.h"
+#include "SENC3D_internal_types.h"
+
+#include <rsys/rsys.h>
+#include <rsys/float3.h>
+#include <rsys/double33.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/hash_table.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/dynamic_array_uchar.h>
+#include <rsys/clock_time.h>
+
+#include <star/s3d.h>
+
+#include <omp.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#define CC_DESCRIPTOR_NULL__ {\
+ CHAR_MAX, VRTX_NULL__, 0,\
+ CC_ID_NONE, CC_GROUP_ROOT_NONE, ENCLOSURE_NULL__,\
+ { TRG_NULL__, 0},\
+ NULL\
+}
+#ifdef COMPILER_GCC
+ #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
+#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)
+{
+ const double a1 = ((struct neighbour_info*)w1)->angle;
+ const double a2 = ((struct neighbour_info*)w2)->angle;
+ return (a1 > a2) - (a1 < a2);
+}
+
+static side_id_t
+get_side_not_in_connex_component
+ (const side_id_t last_side,
+ const struct trgside* trgsides,
+ const unsigned char* processed,
+ side_id_t* first_side_not_in_component,
+ const medium_id_t medium)
+{
+ ASSERT(trgsides && processed && first_side_not_in_component);
+ {
+ side_id_t i = *first_side_not_in_component;
+ while (i <= last_side
+ && (trgsides[i].medium != medium
+ || (processed[TRGSIDE_2_TRG(i)] & TRGSIDE_2_SIDEFLAG(i))))
+ ++i;
+
+ *first_side_not_in_component = i + 1;
+ if(i > last_side) return SIDE_NULL__;
+ return i;
+ }
+}
+
+static void
+get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) {
+ int i;
+ const struct senc3d_scene* scene = ctx;
+ const struct triangle_in* trg =
+ darray_triangle_in_cdata_get(&scene->triangles_in) + itri;
+ FOR_EACH(i, 0, 3) {
+ ASSERT(trg->vertice_id[i] < scene->nverts);
+ ids[i] = (unsigned)trg->vertice_id[i]; /* Back to API type */
+ }
+}
+
+static void
+get_scn_position(const unsigned ivert, float pos[3], void* ctx) {
+ const struct senc3d_scene* scene = ctx;
+ const union double3* pt =
+ darray_position_cdata_get(&scene->vertices) + ivert;
+ f3_set_d3(pos, pt->vec);
+}
+
+static int
+self_hit_filter
+ (const struct s3d_hit* hit,
+ const float ray_org[3],
+ const float ray_dir[3],
+ void* ray_data,
+ void* filter_data)
+{
+ const struct darray_triangle_comp* triangles_comp = filter_data;
+ const component_id_t* origin_component = ray_data;
+ const struct triangle_comp* hit_trg_comp;
+
+ (void)ray_org; (void)ray_dir;
+ ASSERT(hit && triangles_comp && origin_component);
+ ASSERT(hit->prim.prim_id < darray_triangle_comp_size_get(triangles_comp));
+ hit_trg_comp = darray_triangle_comp_cdata_get(triangles_comp)
+ + hit->prim.prim_id;
+ return (hit_trg_comp->component[SENC3D_FRONT] == *origin_component
+ || hit_trg_comp->component[SENC3D_BACK] == *origin_component);
+
+}
+
+static void
+extract_connex_components
+ (struct senc3d_scene* scn,
+ struct trgside* trgsides,
+ struct darray_ptr_component_descriptor* connex_components,
+ const struct darray_triangle_tmp* triangles_tmp_array,
+ struct darray_triangle_comp* triangles_comp_array,
+ struct s3d_scene_view** s3d_view,
+ ATOMIC* component_count,
+ /* Shared error status.
+ * We accept to overwrite an error with a different error */
+ res_T* p_res)
+{
+ /* This function is called from an omp parallel block and executed
+ * concurrently. */
+ struct mem_allocator* alloc;
+ int64_t m_idx;
+ struct darray_side_id stack;
+ struct darray_side_id ids_of_sides_around_max_z_vertex;
+ const union double3* positions;
+ const struct triangle_tmp* triangles_tmp;
+ struct triangle_comp* triangles_comp;
+ /* An array to flag sides when processed */
+ unsigned char* processed;
+ /* An array to store the component being processed */
+ struct darray_side_id current_component;
+ /* A bool array to store media of the component being processed */
+ unsigned char* current_media = NULL;
+ size_t sz, ii;
+
+ ASSERT(scn && trgsides && connex_components && triangles_tmp_array
+ && triangles_comp_array && s3d_view && component_count && p_res);
+ alloc = scn->dev->allocator;
+ positions = darray_position_cdata_get(&scn->vertices);
+ triangles_tmp = darray_triangle_tmp_cdata_get(triangles_tmp_array);
+ triangles_comp = darray_triangle_comp_data_get(triangles_comp_array);
+ darray_side_id_init(alloc, &stack);
+ darray_side_id_init(alloc, &ids_of_sides_around_max_z_vertex);
+ darray_side_id_init(alloc, ¤t_component);
+ processed = MEM_CALLOC(alloc, scn->ntris, sizeof(unsigned char));
+ if(!processed) {
+ *p_res = RES_MEM_ERR;
+ return;
+ }
+
+#ifndef NDEBUG
+ #pragma omp single
+ {
+ trg_id_t t_;
+ int s;
+ ASSERT(darray_ptr_component_descriptor_size_get(connex_components) == 0);
+ FOR_EACH(t_, 0, scn->ntris) {
+ const struct triangle_in* trg_in =
+ darray_triangle_in_cdata_get(&scn->triangles_in) + t_;
+ const struct side_range* media_use
+ = darray_side_range_cdata_get(&scn->media_use);
+ FOR_EACH(s, 0, 2) {
+ const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, s);
+ medium_id_t medium = trg_in->medium[s];
+ m_idx = (medium == SENC3D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1;
+ ASSERT(media_use[m_idx].first <= side && side
+ <= media_use[m_idx].last);
+ }
+ }
+ } /* Implicit barrier here */
+#endif
+
+ /* We loop on sides to build connex components. */
+ #pragma omp for schedule(dynamic) nowait
+ /* Process all media, including unspecified */
+ 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) : SENC3D_UNSPECIFIED_MEDIUM;
+ /* media_use 0 is for SENC3D_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_nz;
+ side_id_t max_nz_side_id = SIDE_NULL__;
+ const side_id_t last_side = media_use->last;
+ int component_canceled = 0;
+ res_T tmp_res = RES_OK;
+ ATOMIC id;
+
+ 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->ntris);
+ 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, trgsides, 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_z_vrtx_id = VRTX_NULL__;
+ struct cc_descriptor *cc;
+ double max_z = -DBL_MAX;
+ component_canceled = 0;
+ ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->ntris);
+ darray_side_id_clear(¤t_component);
+
+ if(*p_res != RES_OK) break;
+ if(start_side_id == SIDE_NULL__)
+ break; /* start_side_id=SIDE_NULL__ => component done! */
+
+#ifndef NDEBUG
+ {
+ trg_id_t tid = TRGSIDE_2_TRG(start_side_id);
+ enum senc3d_side s = TRGSIDE_2_SIDE(start_side_id);
+ medium_id_t side_med
+ = darray_triangle_in_data_get(&scn->triangles_in)[tid].medium[s];
+ ASSERT(side_med == medium);
+ }
+#endif
+
+ /* Reuse array if possible, or create a new one */
+ if(current_media) {
+ /* current_media 0 is for SENC3D_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(*current_media));
+ if(!current_media) {
+ *p_res = RES_MEM_ERR;
+ continue;
+ }
+ }
+ current_media[m_idx] = 1;
+ for(;;) { /* Process all sides of this component */
+ int i;
+ enum side_flag crt_side_flag = TRGSIDE_2_SIDEFLAG(crt_side_id);
+ struct trgside* crt_side = trgsides + crt_side_id;
+ const trg_id_t crt_trg_id = TRGSIDE_2_TRG(crt_side_id);
+ const struct triangle_in* trg_in =
+ darray_triangle_in_cdata_get(&scn->triangles_in) + crt_trg_id;
+ unsigned char* trg_used = processed + crt_trg_id;
+ const struct triangle_tmp* const trg_tmp = triangles_tmp + crt_trg_id;
+ ASSERT(crt_trg_id < scn->ntris);
+
+ if(*p_res != RES_OK) break;
+
+ /* Record Zmax information
+ * Keep track of the appropriate vertex of the 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 Z
+ * coordinate. */
+ if(max_z < trg_tmp->max_z) {
+ /* New best vertex */
+ max_z = trg_tmp->max_z;
+ /* New vertex: reset list of sides */
+ darray_side_id_clear(&ids_of_sides_around_max_z_vertex);
+
+ /* Select a vertex with z == max_z */
+ FOR_EACH(i, 0, 3) {
+ if(max_z == positions[trg_in->vertice_id[i]].pos.z) {
+ max_z_vrtx_id = trg_in->vertice_id[i];
+ break;
+ }
+ }
+ ASSERT(i < 3); /* Found one */
+ /* List of sides using the vertex */
+ OK2(darray_side_id_push_back(&ids_of_sides_around_max_z_vertex,
+ &crt_side_id));
+ } else if(max_z == trg_tmp->max_z) {
+ /* Does this triangle use the currently selected max_z vertex? */
+ FOR_EACH(i, 0, 3) {
+ if(max_z_vrtx_id == trg_in->vertice_id[i]) {
+ /* List of sides using the vertex */
+ OK2(darray_side_id_push_back(&ids_of_sides_around_max_z_vertex,
+ &crt_side_id));
+ break;
+ }
+ }
+ }
+
+ /* Record crt_side both as component and triangle level */
+ if((*trg_used & crt_side_flag) == 0) {
+ OK2(darray_side_id_push_back(¤t_component, &crt_side_id));
+ *trg_used = *trg_used | (unsigned char)crt_side_flag;
+ }
+
+ /* Store neighbour's sides in a waiting stack */
+ FOR_EACH(i, 0, 3) {
+ side_id_t neighbour_id = crt_side->facing_side_id[i];
+ trg_id_t nbour_trg_id = TRGSIDE_2_TRG(neighbour_id);
+ enum side_flag nbour_side_id = TRGSIDE_2_SIDEFLAG(neighbour_id);
+ unsigned char* nbour_used = processed + nbour_trg_id;
+ const struct trgside* neighbour = trgsides + neighbour_id;
+ medium_id_t nbour_med_idx = (neighbour->medium == SENC3D_UNSPECIFIED_MEDIUM)
+ ? 0 : neighbour->medium + 1;
+ if(neighbour->medium < medium
+ || (*nbour_used & SIDE_CANCELED_FLAG(nbour_side_id)))
+ {
+ /* 1) Not the same medium.
+ * Neighbour's medium id is less than current medium: the whole
+ * component is to be processed by another thread (possibly the one
+ * 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 */
+ component_canceled = 1;
+ darray_side_id_clear(&stack);
+ /* 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];
+ trg_id_t used_trg_id = TRGSIDE_2_TRG(used_side);
+ enum side_flag used_side_flag
+ = TRGSIDE_2_SIDEFLAG(used_side);
+ unsigned char* used = processed + used_trg_id;
+ ASSERT(*used & (unsigned char)used_side_flag);
+ /* Set the used flag for sides in cancelled component as leading
+ * to further cancellations */
+ *used |= SIDE_CANCELED_FLAG(used_side_flag);
+ }
+
+ goto canceled;
+ }
+ if(*nbour_used & nbour_side_id) continue; /* Already processed */
+ /* Mark neighbour as processed and stack it */
+ *nbour_used |= (unsigned char)nbour_side_id;
+ OK2(darray_side_id_push_back(&stack, &neighbour_id));
+ OK2(darray_side_id_push_back(¤t_component, &neighbour_id));
+ current_media[nbour_med_idx] = 1;
+ }
+ sz = darray_side_id_size_get(&stack);
+ if(sz == 0) break; /* Empty stack => component is done! */
+ crt_side_id = darray_side_id_cdata_get(&stack)[sz - 1];
+ darray_side_id_pop_back(&stack);
+ last_side_id = MMAX(last_side_id, crt_side_id);
+ }
+ canceled:
+ if(component_canceled) continue;
+
+ /* Register the new component and get it initialized */
+ cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
+ if(!cc) *p_res = RES_MEM_ERR;
+ if(*p_res != RES_OK) break;
+
+ ASSERT(medium == trgsides[start_side_id].medium);
+ ASSERT(max_z_vrtx_id != VRTX_NULL__);
+ cc_descriptor_init(alloc, cc);
+ id = ATOMIC_INCR(component_count) - 1;
+ ASSERT(id <= COMPONENT_MAX__);
+ cc->cc_id = (component_id_t)id;
+ sz = darray_side_id_size_get(¤t_component);
+ ASSERT(sz <= SIDE_MAX__);
+ cc->side_count = (side_id_t)sz;
+ cc->side_range.first = start_side_id;
+ cc->side_range.last = last_side_id;
+ cc->max_z_vrtx_id = max_z_vrtx_id;
+ /* Tranfer ownership of the array to component */
+ ASSERT(!cc->media && current_media);
+ cc->media = current_media;
+ current_media = NULL;
+
+ /* Write component membership in the global structure
+ * No need for sync here as an unique thread writes a given side */
+ {STATIC_ASSERT(sizeof(cc->cc_id) >= 4, Cannot_write_IDs_sync_free);}
+ ASSERT(IS_ALIGNED(triangles_comp->component, sizeof(cc->cc_id)));
+ FOR_EACH(ii, 0, sz) {
+ const side_id_t s = darray_side_id_cdata_get(¤t_component)[ii];
+ trg_id_t tid = TRGSIDE_2_TRG(s);
+ enum senc3d_side sid = TRGSIDE_2_SIDE(s);
+ component_id_t* cmp = triangles_comp[tid].component;
+ ASSERT(cmp[sid] == COMPONENT_NULL__);
+ ASSERT(trgsides[s].medium >= medium);
+ cmp[sid] = cc->cc_id;
+ }
+
+ /* Compute the normal at the max_z vertex. */
+ max_nz = 0;
+ sz = darray_side_id_size_get(&ids_of_sides_around_max_z_vertex);
+ ASSERT(sz > 0);
+ FOR_EACH(ii, 0, sz) {
+ const side_id_t side_id =
+ darray_side_id_cdata_get(&ids_of_sides_around_max_z_vertex)[ii];
+ const trg_id_t trg_id = TRGSIDE_2_TRG(side_id);
+ enum senc3d_side s = TRGSIDE_2_SIDE(side_id);
+ const struct triangle_in* trg_in =
+ darray_triangle_in_cdata_get(&scn->triangles_in) + trg_id;
+ const struct triangle_comp* trg_comp = triangles_comp + trg_id;
+ const union double3* vertices =
+ darray_position_cdata_get(&scn->vertices);
+ double edge0[3], edge1[3], normal[3], norm;
+
+ /* To ensure that triangles with 2 sides in the component total to 0
+ * regardless of numeric accuracy, we need to prevent them to
+ * contribute (remember than x + y - y == x can be false). */
+ ASSERT(trg_comp->component[s] == cc->cc_id); (void)s;
+ if(trg_comp->component[SENC3D_FRONT] == trg_comp->component[SENC3D_BACK])
+ continue;
+
+ d3_sub(edge0, vertices[trg_in->vertice_id[1]].vec,
+ vertices[trg_in->vertice_id[0]].vec);
+ d3_sub(edge1, vertices[trg_in->vertice_id[2]].vec,
+ vertices[trg_in->vertice_id[0]].vec);
+ d3_cross(normal, edge0, edge1);
+ norm = d3_normalize(normal, normal);
+ ASSERT(norm); (void)norm;
+
+ if(fabs(max_nz) < fabs(normal[2])) {
+ max_nz_side_id = side_id;
+ max_nz = normal[2];
+ }
+ }
+ if(max_nz == 0) cc->is_outer_border = 0;
+ else {
+ if(TRGSIDE_IS_FRONT(max_nz_side_id)
+ == ((scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0)) {
+ /* Geom normal points towards the component */
+ cc->is_outer_border = (max_nz < 0);
+ } else {
+ /* Geom normal points away from the component */
+ cc->is_outer_border = (max_nz > 0);
+ }
+ }
+
+ /* Need to synchronize connex_components growth as this global structure
+ * is accessed by multipe threads */
+ #pragma omp critical
+ {
+ struct cc_descriptor** components;
+ sz = darray_ptr_component_descriptor_size_get(connex_components);
+ if(sz <= cc->cc_id) {
+ tmp_res = darray_ptr_component_descriptor_resize(connex_components,
+ 1 + cc->cc_id);
+ if(tmp_res != RES_OK) *p_res = tmp_res;
+ }
+ if(*p_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;
+ }
+ }
+ }
+ tmp_error:
+ if(tmp_res != RES_OK) *p_res = tmp_res;
+ } /* No barrier here */
+
+ MEM_RM(alloc, processed);
+ MEM_RM(alloc, current_media);
+ darray_side_id_release(¤t_component);
+ darray_side_id_release(&stack);
+ darray_side_id_release(&ids_of_sides_around_max_z_vertex);
+
+ /* The first thread here creates the s3d view */
+ #pragma omp single nowait
+ if(*p_res == RES_OK) {
+ res_T res = RES_OK;
+ struct s3d_device* s3d = NULL;
+ struct s3d_scene* s3d_scn = NULL;
+ struct s3d_shape* s3d_shp = NULL;
+ struct s3d_vertex_data attribs;
+
+ attribs.type = S3D_FLOAT3;
+ attribs.usage = S3D_POSITION;
+ attribs.get = get_scn_position;
+
+ /* Put geometry in a 3D view */
+ OK(s3d_device_create(scn->dev->logger, alloc, 0, &s3d));
+ OK(s3d_scene_create(s3d, &s3d_scn));
+ OK(s3d_shape_create_mesh(s3d, &s3d_shp));
+
+ /* Back to API type for ntris and nverts */
+ ASSERT(scn->ntris < UINT_MAX);
+ ASSERT(scn->nverts < UINT_MAX);
+ OK(s3d_mesh_setup_indexed_vertices(s3d_shp,
+ (unsigned)scn->ntris, get_scn_indices,
+ (unsigned)scn->nverts, &attribs, 1, scn));
+ s3d_mesh_set_hit_filter_function(s3d_shp, self_hit_filter,
+ triangles_comp_array);
+ OK(s3d_scene_attach_shape(s3d_scn, s3d_shp));
+ OK(s3d_scene_view_create(s3d_scn, S3D_TRACE, s3d_view));
+ error:
+ if(res != RES_OK) *p_res = res;
+ if(s3d) S3D(device_ref_put(s3d));
+ if(s3d_scn) S3D(scene_ref_put(s3d_scn));
+ if(s3d_shp) S3D(shape_ref_put(s3d_shp));
+ }
+
+#ifndef NDEBUG
+ /* Need to wait for all threads done to be able to check stuff */
+ #pragma omp barrier
+ if(*p_res != RES_OK) return;
+ #pragma omp single
+ {
+ trg_id_t t_;
+ component_id_t c;
+ ASSERT(ATOMIC_GET(component_count) ==
+ (int)darray_ptr_component_descriptor_size_get(connex_components));
+ FOR_EACH(t_, 0, scn->ntris) {
+ struct triangle_comp* trg_comp =
+ darray_triangle_comp_data_get(triangles_comp_array) + t_;
+ ASSERT(trg_comp->component[SENC3D_FRONT] != COMPONENT_NULL__);
+ ASSERT(trg_comp->component[SENC3D_BACK] != COMPONENT_NULL__);
+ }
+ FOR_EACH(c, 0, ATOMIC_GET(component_count)) {
+ struct cc_descriptor** components =
+ darray_ptr_component_descriptor_data_get(connex_components);
+ ASSERT(components[c] != NULL && components[c]->cc_id == c);
+ }
+ } /* Implicit barrier here */
+#endif
+}
+
+static void
+group_connex_components
+ (struct senc3d_scene* scn,
+ struct trgside* trgsides,
+ struct darray_triangle_comp* triangles_comp,
+ struct darray_ptr_component_descriptor* connex_components,
+ struct s3d_scene_view* s3d_view,
+ ATOMIC* next_enclosure_id,
+ /* 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. */
+ struct cc_descriptor** descriptors;
+ const union double3* positions;
+ size_t tmp;
+ component_id_t cc_count;
+ int64_t ccc;
+
+ (void)trgsides;
+ ASSERT(scn && trgsides && triangles_comp && connex_components
+ && s3d_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(&scn->vertices);
+
+ /* Cast rays to find links between connex components */
+ #pragma omp for
+ for(ccc = 0; ccc < (int64_t)cc_count; ccc++) {
+ res_T tmp_res = RES_OK;
+ component_id_t c = (component_id_t)ccc;
+ struct s3d_hit hit = S3D_HIT_NULL;
+ float origin[3];
+ const float dir[3] = { 0, 0, 1 };
+ const float range[2] = { 0, FLT_MAX };
+ struct cc_descriptor* const cc = descriptors[c];
+ component_id_t self_hit_component = cc->cc_id;
+ const double* max_vrtx;
+
+ if(*res != RES_OK) continue;
+ ASSERT(cc->cc_id == c);
+ ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
+ ASSERT(cc->max_z_vrtx_id < scn->nverts);
+
+ max_vrtx = positions[cc->max_z_vrtx_id].vec;
+ if(cc->is_outer_border) {
+ ATOMIC 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;
+ }
+
+ f3_set_d3(origin, max_vrtx);
+ /* Self-hit data: self hit if hit this component "on the other side" */
+ tmp_res = s3d_scene_view_trace_ray(s3d_view, origin, dir, range,
+ &self_hit_component, &hit);
+ if(tmp_res != RES_OK) {
+ *res = tmp_res;
+ continue;
+ }
+ /* If no hit, the component is facing an infinite medium */
+ if(S3D_HIT_NONE(&hit)) {
+ cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
+ cc->enclosure_id = 0;
+ } else {
+ /* If hit, group this component */
+ const trg_id_t hit_trg_id = (trg_id_t)hit.prim.prim_id;
+ const struct triangle_comp* hit_trg_comp =
+ darray_triangle_comp_cdata_get(triangles_comp) + hit_trg_id;
+ enum senc3d_side hit_side =
+ ((hit.normal[2] < 0) /* Facing geometrical normal of hit */
+ == ((scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0))
+ /* Warning: following Embree 2 convention for geometrical normals,
+ * the Star3D hit normal is left-handed while star-enclosure uses
+ * right-handed convention */
+ ? SENC3D_BACK : SENC3D_FRONT;
+ ASSERT(hit.normal[2] != 0);
+ ASSERT(hit_trg_id < scn->ntris);
+
+ /* Not really the root until following links */
+ cc->cc_group_root = hit_trg_comp->component[hit_side];
+ ASSERT(cc->cc_group_root < cc_count);
+ }
+ }
+ /* Implicit barrier here */
+ ASSERT(ATOMIC_GET(next_enclosure_id) < ENCLOSURE_MAX__);
+ if(*res != RES_OK) return;
+
+ /* One thread post-processes links to group connex components */
+ #pragma omp single
+ {
+ res_T tmp_res = RES_OK;
+ 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(&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) {
+ 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);
+ cc->cc_group_root = other_desc->cc_group_root;
+ cc->enclosure_id = other_desc->enclosure_id;
+ enc = enclosures + cc->enclosure_id;
+ ++enc->cc_count;
+ /* Linked list of componnents */
+ enc->first_component = cc->cc_id;
+ enc->side_range.first = MMIN(enc->side_range.first, cc->side_range.first);
+ 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,
+ scn->next_medium_idx + 1);
+ if(tmp_res != RES_OK) {
+ *res = tmp_res;
+ break;
+ }
+ }
+ }
+ }
+ /* Implicit barrier here */
+}
+
+static void
+collect_and_link_neighbours
+ (struct senc3d_scene* scn,
+ struct trgside* trgsides,
+ struct darray_triangle_tmp* triangles_tmp_array,
+ struct darray_frontier_edge* 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. */
+ const struct triangle_in* triangles_in;
+ struct triangle_tmp* triangles_tmp;
+ const union double3* vertices;
+ const int thread_count = omp_get_num_threads();
+ const int rank = omp_get_thread_num();
+ /* Htable used to give an id to edges */
+ struct htable_edge_id edge_ids;
+ /* Array to keep neighbourhood of edges
+ * Resize/Push operations on neighbourhood_by_edge are valid in the
+ * openmp block because a given neighbourhood is only processed
+ * by a single thread */
+ struct darray_neighbourhood neighbourhood_by_edge;
+ edge_id_t edge_count;
+ edge_id_t nbedges_guess;
+ edge_id_t e;
+ trg_id_t t;
+ size_t sz;
+ res_T tmp_res;
+
+ ASSERT(scn && trgsides && triangles_tmp_array && frontiers && res);
+ ASSERT((size_t)scn->nverts + (size_t)scn->ntris + 2 <= EDGE_MAX__);
+
+ htable_edge_id_init(scn->dev->allocator, &edge_ids);
+ darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_edge);
+
+ triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in);
+ triangles_tmp = darray_triangle_tmp_data_get(triangles_tmp_array);
+ vertices = darray_position_cdata_get(&scn->vertices);
+
+ ASSERT(scn->ntris == darray_triangle_tmp_size_get(triangles_tmp_array));
+
+ /* Make some room for edges. */
+ nbedges_guess = 4 + (thread_count == 1
+ ? (edge_id_t)(scn->nverts + scn->ntris)
+ : (edge_id_t)((scn->nverts + scn->ntris) / (0.75 * thread_count)));
+ OK2(darray_neighbourhood_reserve(&neighbourhood_by_edge, nbedges_guess));
+ OK2(htable_edge_id_reserve(&edge_ids, nbedges_guess));
+
+ /* Loop on triangles to register edges.
+ * All threads considering all the edges and processing some */
+ FOR_EACH(t, 0, scn->ntris) {
+ struct trg_edge edge;
+ unsigned char ee;
+ FOR_EACH(ee, 0, 3) {
+ edge_id_t* p_id;
+ size_t n_sz;
+ struct edge_neighbourhood* neighbourhood;
+ struct neighbour_info* info;
+ const vrtx_id_t v0 = triangles_in[t].vertice_id[ee];
+ const vrtx_id_t v1 = triangles_in[t].vertice_id[(ee + 1) % 3];
+ /* Process only "my" edges! */
+ const int64_t h =
+ /* v0,v1 and v1,v0 must give the same hash!!! */
+ v0 + v1 + (int64_t)MMIN(v0, v1);
+ if(h % thread_count != rank) continue;
+ /* Create edge. */
+ set_edge(v0, v1, &edge, &triangles_tmp[t].reversed_edge[ee]);
+ /* Find edge id; create it if not already done. */
+ p_id = htable_edge_id_find(&edge_ids, &edge);
+ if(p_id) {
+ neighbourhood =
+ darray_neighbourhood_data_get(&neighbourhood_by_edge) + *p_id;
+ ASSERT(neighbourhood->edge.vrtx0 == edge.vrtx0
+ && neighbourhood->edge.vrtx1 == edge.vrtx1);
+ } else {
+ /* Create id */
+ edge_id_t id;
+ sz = htable_edge_id_size_get(&edge_ids);
+ ASSERT(sz <= EDGE_MAX__);
+ id = (edge_id_t)sz;
+ ASSERT(htable_edge_id_size_get(&edge_ids)
+ == darray_neighbourhood_size_get(&neighbourhood_by_edge));
+ OK2(htable_edge_id_set(&edge_ids, &edge, &id));
+ OK2(darray_neighbourhood_resize(&neighbourhood_by_edge, 1 + sz));
+ neighbourhood = darray_neighbourhood_data_get(&neighbourhood_by_edge) + sz;
+ /* Add neighbour info to a newly created edge's neighbour list */
+ neighbourhood->edge = edge;
+ ASSERT(darray_neighbour_size_get(&neighbourhood->neighbours) == 0);
+ /* Just a guess: few edges will have less than 2 neighbours */
+ OK2(darray_neighbour_reserve(&neighbourhood->neighbours, 2));
+ }
+ /* Add neighbour info to neighbourhood */
+ n_sz = darray_neighbour_size_get(&neighbourhood->neighbours);
+ OK2(darray_neighbour_resize(&neighbourhood->neighbours, 1 + n_sz));
+ info = darray_neighbour_data_get(&neighbourhood->neighbours) + n_sz;
+ info->trg_id = t;
+ info->common_edge_rank = ee;
+ }
+ } /* No barrier here. */
+
+ /* Loop on collected edges.
+ * For each edge sort triangle sides by rotation angle
+ * and connect neighbours. */
+ sz = darray_neighbourhood_size_get(&neighbourhood_by_edge);
+ ASSERT(sz <= EDGE_MAX__);
+ edge_count = (edge_id_t)sz;
+ FOR_EACH(e, 0, edge_count) {
+ double edge[3], common_edge[3], basis[9], norm, max_z, maxz_edge, a;
+ vrtx_id_t v0, v1, v2;
+ struct edge_neighbourhood* neighbourhood
+ = darray_neighbourhood_data_get(&neighbourhood_by_edge) + e;
+ struct darray_neighbour* neighbour_list = &neighbourhood->neighbours;
+ side_id_t i, neighbour_count;
+ sz = darray_neighbour_size_get(neighbour_list);
+ ASSERT(sz > 0 && sz <= SIDE_MAX__);
+ neighbour_count = (side_id_t)sz;
+ ASSERT(neighbour_count);
+ v0 = neighbourhood->edge.vrtx0;
+ v1 = neighbourhood->edge.vrtx1;
+ d3_sub(common_edge, vertices[v1].vec, vertices[v0].vec);
+ maxz_edge = MMAX(vertices[v0].pos.z, vertices[v1].pos.z);
+ norm = d3_normalize(common_edge, common_edge);
+ ASSERT(norm); (void)norm;
+ d33_basis(basis, common_edge);
+ d33_inverse(basis, basis);
+ FOR_EACH(i, 0, neighbour_count) {
+ struct neighbour_info* neighbour_info
+ = darray_neighbour_data_get(neighbour_list) + i;
+ const trg_id_t crt_id = neighbour_info->trg_id;
+ const unsigned char crt_edge = neighbour_info->common_edge_rank;
+ const struct triangle_in* trg_in = triangles_in + crt_id;
+ struct triangle_tmp* neighbour = triangles_tmp + crt_id;
+ union double3 n; /* Geometrical normal to neighbour triangle */
+ const int is_reversed = neighbour->reversed_edge[crt_edge];
+ v2 = trg_in->vertice_id[(crt_edge + 2) % 3];
+ max_z = MMAX(vertices[v2].pos.z, maxz_edge);
+ ASSERT(neighbour->max_z <= max_z);
+ neighbour->max_z = max_z;
+ /* Compute rotation angle around common edge */
+ d3_sub(edge, vertices[v2].vec, vertices[v0].vec);
+ d33_muld3(edge, basis, edge);
+ ASSERT(d3_len(edge) && (edge[0] || edge[1]));
+ neighbour_info->angle = atan2(edge[1], edge[0]);
+ if(is_reversed)
+ d3(n.vec, +edge[1], -edge[0], 0);
+ else
+ d3(n.vec, -edge[1], +edge[0], 0);
+ if(neighbour_info->angle < 0) neighbour_info->angle += 2 * PI;
+
+ /* Normal orientation calculation. */
+ if(neighbour_info->angle <= PI / 4) {
+ ASSERT(n.pos.y);
+ neighbour_info->normal_toward_next_neighbour = (n.pos.y > 0);
+ } else if(neighbour_info->angle <= 3 * PI / 4) {
+ ASSERT(n.pos.x);
+ neighbour_info->normal_toward_next_neighbour = (n.pos.x < 0);
+ } else if(neighbour_info->angle <= 5 * PI / 4) {
+ ASSERT(n.pos.y);
+ neighbour_info->normal_toward_next_neighbour = (n.pos.y < 0);
+ } else if(neighbour_info->angle <= 7 * PI / 4) {
+ ASSERT(n.pos.x);
+ neighbour_info->normal_toward_next_neighbour = (n.pos.x > 0);
+ } else {
+ ASSERT(n.pos.y);
+ neighbour_info->normal_toward_next_neighbour = (n.pos.y > 0);
+ }
+ }
+ /* Sort triangles by rotation angle */
+ qsort(darray_neighbour_data_get(neighbour_list), neighbour_count,
+ sizeof(struct neighbour_info), neighbour_cmp);
+ /* Link sides.
+ * Create cycles of sides by neighbourhood around common edge. */
+ a = -DBL_MAX;
+ FOR_EACH(i, 0, neighbour_count) {
+ /* Neighbourhood info for current pair of triangles */
+ const struct neighbour_info* current
+ = darray_neighbour_cdata_get(neighbour_list) + i;
+ const struct neighbour_info* ccw_neighbour
+ = darray_neighbour_cdata_get(neighbour_list) + (i + 1) % neighbour_count;
+ /* Rank of the edge of interest in triangles */
+ const unsigned char crt_edge = current->common_edge_rank;
+ /* Here ccw refers to the rotation around the common edge
+ * and has nothing to do with vertices order in triangle definition
+ * nor Front/Back side convention */
+ const unsigned char ccw_edge = ccw_neighbour->common_edge_rank;
+ /* User id of current triangles */
+ const trg_id_t crt_id = current->trg_id;
+ const trg_id_t ccw_id = ccw_neighbour->trg_id;
+ /* Facing sides of triangles */
+ const int front = ((scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0);
+ const enum senc3d_side crt_side
+ = current->normal_toward_next_neighbour == front ? SENC3D_FRONT : SENC3D_BACK;
+ const enum senc3d_side ccw_side
+ = ccw_neighbour->normal_toward_next_neighbour == front ?
+ SENC3D_BACK : SENC3D_FRONT;
+ /* Index of sides in trgsides */
+ const side_id_t crt_side_idx = TRGIDxSIDE_2_TRGSIDE(crt_id, crt_side);
+ const side_id_t ccw_side_idx = TRGIDxSIDE_2_TRGSIDE(ccw_id, ccw_side);
+ /* Side ptrs */
+ struct trgside* const p_crt_side = trgsides + crt_side_idx;
+ struct trgside* const p_ccw_side = trgsides + ccw_side_idx;
+ /* Check that angle is a discriminant property */
+ ASSERT(a <= current->angle); /* Is sorted */
+ if(a == current->angle) {
+ /* Two consecutive triangles with same angle! */
+ const struct neighbour_info* previous;
+ trg_id_t prev_id;
+ ASSERT(i > 0);
+ previous = darray_neighbour_cdata_get(neighbour_list) + i - 1;
+ prev_id = previous->trg_id;
+ log_err(scn->dev,
+ "%s: found 2 overlying triangles (%u & %u).\n", FUNC_NAME,
+ (unsigned)crt_id, (unsigned)prev_id);
+ tmp_res = RES_BAD_OP;
+ goto tmp_error;
+ }
+ a = current->angle;
+ /* Link sides */
+ ASSERT(p_crt_side->facing_side_id[crt_edge] == SIDE_NULL__);
+ ASSERT(p_ccw_side->facing_side_id[ccw_edge] == SIDE_NULL__);
+ p_crt_side->facing_side_id[crt_edge] = ccw_side_idx;
+ p_ccw_side->facing_side_id[ccw_edge] = crt_side_idx;
+ /* Record media */
+ ASSERT(p_crt_side->medium == MEDIUM_NULL__
+ || p_crt_side->medium == triangles_in[crt_id].medium[crt_side]);
+ ASSERT(p_ccw_side->medium == MEDIUM_NULL__
+ || p_ccw_side->medium == triangles_in[ccw_id].medium[ccw_side]);
+ p_crt_side->medium = triangles_in[crt_id].medium[crt_side];
+ p_ccw_side->medium = triangles_in[ccw_id].medium[ccw_side];
+ ASSERT(p_crt_side->medium == SENC3D_UNSPECIFIED_MEDIUM
+ || p_crt_side->medium < scn->next_medium_idx);
+ ASSERT(p_ccw_side->medium == SENC3D_UNSPECIFIED_MEDIUM
+ || p_ccw_side->medium < scn->next_medium_idx);
+ /* Detect triangles that could surround a hole:
+ * - single triangle on (one of) its edge
+ * - different media on its sides */
+ if(neighbour_count == 1
+ && p_crt_side->medium != p_ccw_side->medium)
+#pragma omp critical
+ {
+ struct trg_edge disc;
+ log_warn(scn->dev,
+ "%s: found frontier involving triangle %lu.\n",
+ FUNC_NAME, (unsigned long)crt_id);
+ disc.vrtx0 = v0;
+ disc.vrtx1 = v1;
+ darray_frontier_edge_push_back(frontiers, &disc);
+ }
+ }
+ }
+tmp_error:
+ if(tmp_res != RES_OK) *res = tmp_res;
+ /* Threads are allowed to return whitout sync. */
+ htable_edge_id_release(&edge_ids);
+ darray_neighbourhood_release(&neighbourhood_by_edge);
+}
+
+static void
+build_result
+ (struct senc3d_scene* scn,
+ const struct darray_ptr_component_descriptor* connex_components,
+ const struct darray_triangle_comp* triangles_comp_array,
+ struct darray_frontier_edge* 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. */
+ struct mem_allocator* alloc;
+ struct cc_descriptor* const* cc_descriptors;
+ struct enclosure_data* enclosures;
+ const struct triangle_in* triangles_in;
+ struct triangle_enc* triangles_enc;
+ const struct triangle_comp* triangles_comp;
+ struct htable_vrtx_id vtable;
+ int output_normal_in, normals_front, normals_back;
+ int64_t tt;
+ int64_t ee;
+
+ ASSERT(scn && connex_components && triangles_comp_array && frontiers && res);
+
+ alloc = scn->dev->allocator;
+ output_normal_in = (scn->convention & SENC3D_CONVENTION_NORMAL_INSIDE) != 0;
+ normals_front = (scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0;
+ normals_back = (scn->convention & SENC3D_CONVENTION_NORMAL_BACK) != 0;
+ ASSERT(normals_back != normals_front);
+ ASSERT(output_normal_in
+ != ((scn->convention & SENC3D_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(&scn->analyze.enclosures);
+ triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in);
+ triangles_comp = darray_triangle_comp_cdata_get(triangles_comp_array);
+
+ #pragma omp single
+ {
+ res_T tmp_res =
+ darray_triangle_enc_resize(&scn->analyze.triangles_enc, scn->ntris);
+ if(tmp_res != RES_OK) *res = tmp_res;
+ }/* Implicit barrier here. */
+ if(*res != RES_OK) return;
+ triangles_enc = darray_triangle_enc_data_get(&scn->analyze.triangles_enc);
+
+ /* Build global enclosure information */
+ #pragma omp for
+ for(tt = 0; tt < (int64_t)scn->ntris; tt++) {
+ trg_id_t t = (trg_id_t)tt;
+ const component_id_t cf_id = triangles_comp[t].component[SENC3D_FRONT];
+ const component_id_t cb_id = triangles_comp[t].component[SENC3D_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(triangles_enc[t].enclosure[SENC3D_FRONT] == ENCLOSURE_NULL__);
+ triangles_enc[t].enclosure[SENC3D_FRONT] = ef_id;
+ ASSERT(triangles_enc[t].enclosure[SENC3D_BACK] == ENCLOSURE_NULL__);
+ triangles_enc[t].enclosure[SENC3D_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(scn->analyze.enclosures_count <= ENCLOSURE_MAX__);
+ #pragma omp for schedule(dynamic) nowait
+ 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;
+ trg_id_t fst_idx = 0;
+ trg_id_t sgd_idx = enc->side_count;
+ trg_id_t t;
+ medium_id_t m;
+ res_T tmp_res = RES_OK;
+ ASSERT(enc->first_component
+ < darray_ptr_component_descriptor_size_get(connex_components));
+ ASSERT(cc_descriptors[enc->first_component]->cc_id
+ == enc->first_component);
+
+ 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
+ == enc->header.enclosure_id);
+ enc->header.is_infinite = (e == 0);
+
+ ASSERT(darray_uchar_size_get(&enc->tmp_enclosed_media) <= UINT_MAX);
+ ASSERT(enc->header.enclosed_media_count < 1 + scn->next_medium_idx);
+ OK2(bool_array_of_media_to_darray_media
+ (&enc->enclosed_media, &enc->tmp_enclosed_media, scn->next_medium_idx));
+ enc->header.enclosed_media_count
+ = (unsigned)darray_media_size_get(&enc->enclosed_media);
+ darray_uchar_purge(&enc->tmp_enclosed_media);
+
+ /* Add this enclosure in relevant by-medium lists */
+ FOR_EACH(m, 0, enc->header.enclosed_media_count) {
+ medium_id_t medium = darray_media_cdata_get(&enc->enclosed_media)[m];
+ unsigned m_idx = (medium == SENC3D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1;
+ struct darray_enc_id* enc_ids_array_by_medium;
+ ASSERT(medium == SENC3D_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_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_array_by_medium, &e);
+ }
+ if(tmp_res != RES_OK) {
+ *res = tmp_res;
+ break;
+ }
+ }
+ if(*res != RES_OK) continue;
+
+ /* 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,
+ (size_t)(enc->side_count * 0.6)));
+ /* New vertex numbering scheme local to the enclosure */
+ htable_vrtx_id_clear(&vtable);
+ ASSERT(scn->ntris == darray_triangle_in_size_get(&scn->triangles_in));
+ /* Put at the end the back-faces of triangles that also have their
+ * front-face in the list. */
+ for(t = TRGSIDE_2_TRG(enc->side_range.first);
+ t <= TRGSIDE_2_TRG(enc->side_range.last);
+ t++)
+ {
+ const struct triangle_in* trg_in = triangles_in + t;
+ struct side_enc* side_enc;
+ unsigned vertice_id[3];
+ int i;
+ if(triangles_enc[t].enclosure[SENC3D_FRONT] != e
+ && triangles_enc[t].enclosure[SENC3D_BACK] != e)
+ continue;
+ ++enc->header.unique_primitives_count;
+
+ FOR_EACH(i, 0, 3) {
+ vrtx_id_t* p_id = htable_vrtx_id_find(&vtable, trg_in->vertice_id + i);
+ if(p_id) {
+ vertice_id[i] = *p_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;
+ OK2(htable_vrtx_id_set(&vtable, trg_in->vertice_id + i,
+ vertice_id + i));
+ OK2(darray_vrtx_id_push_back(&enc->vertices, trg_in->vertice_id + i));
+ ++enc->header.vertices_count;
+ }
+ }
+ ASSERT(triangles_enc[t].enclosure[SENC3D_FRONT] == e
+ || triangles_enc[t].enclosure[SENC3D_BACK] == e);
+ if(triangles_enc[t].enclosure[SENC3D_FRONT] == e) {
+ /* Front side of the original triangle is member of the enclosure */
+ int input_normal_in = normals_front;
+ int revert_triangle = (input_normal_in != output_normal_in);
+ ++enc->header.primitives_count;
+ side_enc = darray_sides_enc_data_get(&enc->sides) + fst_idx++;
+ FOR_EACH(i, 0, 3) {
+ int ii = revert_triangle ? 2 - i : i;
+ side_enc->vertice_id[i] = vertice_id[ii];
+ }
+ side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC3D_FRONT);
+ }
+ if(triangles_enc[t].enclosure[SENC3D_BACK] == e) {
+ /* Back side of the original triangle is member of the enclosure */
+ int input_normal_in = normals_back;
+ int revert_triangle = (input_normal_in != output_normal_in);
+ ++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) +
+ ((triangles_enc[t].enclosure[SENC3D_FRONT] == e) ? --sgd_idx : fst_idx++);
+ FOR_EACH(i, 0, 3) {
+ int ii = revert_triangle ? 2 - i : i;
+ side_enc->vertice_id[i] = vertice_id[ii];
+ }
+ side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC3D_BACK);
+ }
+ if(fst_idx == sgd_idx) break;
+ }
+ continue;
+ tmp_error:
+ ASSERT(tmp_res != RES_OK);
+ *res = tmp_res;
+ } /* No barrier here */
+ htable_vrtx_id_release(&vtable);
+ /* The first thread here copies frontiers into descriptor */
+#pragma omp single nowait
+ darray_frontier_edge_copy_and_clear(&scn->analyze.frontiers, frontiers);
+ /* No barrier here */
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+scene_analyze
+ (struct senc3d_scene* scn)
+{
+ /* By triangle tmp data */
+ struct darray_triangle_tmp triangles_tmp;
+ char triangles_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;
+ /* Array of frontiers edges */
+ struct darray_frontier_edge frontiers;
+ char frontiers_initialized = 0;
+ /* Store by-triangle components */
+ struct darray_triangle_comp triangles_comp;
+ char triangles_comp_initialized = 0;
+ /* Array of triangle sides. */
+ struct trgside* trgsides = NULL;
+ struct s3d_scene_view* s3d_view = NULL;
+ /* 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->ntris) goto exit;
+
+ darray_triangle_tmp_init(scn->dev->allocator, &triangles_tmp);
+ triangles_tmp_initialized = 1;
+ darray_frontier_edge_init(scn->dev->allocator, &frontiers);
+ frontiers_initialized = 1;
+
+ OK(darray_triangle_tmp_resize(&triangles_tmp, scn->ntris));
+ trgsides
+ = MEM_CALLOC(scn->dev->allocator, 2 * scn->ntris, sizeof(struct trgside));
+ if(!trgsides) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+#ifndef NDEBUG
+ else {
+ /* Initialise trgsides to allow assert code */
+ size_t i;
+ FOR_EACH(i, 0, 2 * scn->ntris)
+ init_trgside(scn->dev->allocator, trgsides + i);
+ }
+#endif
+
+ /* 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, trgsides, &triangles_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 */
+
+ /* The first thread here allocates some data.
+ * Barrier needed at the end to ensure data created before any use. */
+ #pragma omp single
+ {
+ res_T tmp_res = RES_OK;
+ darray_ptr_component_descriptor_init(scn->dev->allocator,
+ &connex_components);
+ connex_components_initialized = 1;
+ /* Just a hint; to limit contention */
+ OK2(darray_ptr_component_descriptor_reserve(&connex_components,
+ 2 + 2 * scn->next_medium_idx));
+ darray_triangle_comp_init(scn->dev->allocator, &triangles_comp);
+ triangles_comp_initialized = 1;
+ OK2(darray_triangle_comp_resize(&triangles_comp, scn->ntris));
+ 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
+ {
+ if(res != RES_OK) {
+ log_err(scn->dev,
+ "%s: could not build neighbourhoods from scene.\n", FUNC_NAME);
+ } else {
+ res = res2;
+ }
+ }
+ goto error_;
+ }
+
+ /* Step 2: extract triangle connex components */
+ extract_connex_components(scn, trgsides, &connex_components,
+ &triangles_tmp, &triangles_comp, &s3d_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
+ * until next sync point */
+
+ #pragma omp barrier
+ /* Constraints on step 2 data are now met */
+
+ if(res != RES_OK) {
+ #pragma omp single nowait
+ {
+ log_err(scn->dev,
+ "%s: could not extract connex components from scene.\n", FUNC_NAME);
+ } /* No barrier here */
+ goto error_;
+ }
+
+ /* One thread releases some data before going to step 3,
+ * the others go to step 3 without sync */
+ #pragma omp single nowait
+ {
+ darray_triangle_tmp_release(&triangles_tmp);
+ triangles_tmp_initialized = 0;
+ } /* No barrier here */
+
+ /* Step 3: group components */
+ group_connex_components(scn, trgsides, &triangles_comp,
+ &connex_components, s3d_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 */
+
+ if(res != RES_OK) {
+ #pragma omp single nowait
+ {
+ log_err(scn->dev,
+ "%s: could not group connex components from scene.\n", FUNC_NAME);
+ }
+ goto error_;
+ }
+
+ /* One thread releases some data before going to step 4,
+ * the others go to step 4 without sync */
+ #pragma omp single nowait
+ {
+ if(s3d_view) S3D(scene_view_ref_put(s3d_view));
+ s3d_view = NULL;
+ } /* No barrier here */
+
+ /* Step 4: Build result */
+ build_result(scn, &connex_components, &triangles_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 */
+
+ if(res != RES_OK) {
+ #pragma omp single nowait
+ {
+ log_err(scn->dev, "%s: could not build result.\n", FUNC_NAME);
+ }
+ goto error_;
+ }
+
+ /* Some threads release data */
+ #pragma omp sections nowait
+ {
+ #pragma omp section
+ {
+ custom_darray_ptr_component_descriptor_release(&connex_components);
+ connex_components_initialized = 0;
+ }
+ #pragma omp section
+ {
+ darray_triangle_comp_release(&triangles_comp);
+ triangles_comp_initialized = 0;
+ }
+ } /* No barrier here */
+
+error_:
+ ;
+ } /* Implicit barrier here */
+
+ if(res != RES_OK) goto error;
+exit:
+ if(connex_components_initialized)
+ custom_darray_ptr_component_descriptor_release(&connex_components);
+ if(s3d_view) S3D(scene_view_ref_put(s3d_view));
+ if(triangles_tmp_initialized) darray_triangle_tmp_release(&triangles_tmp);
+ if(triangles_comp_initialized) darray_triangle_comp_release(&triangles_comp);
+ if(frontiers_initialized)
+ darray_frontier_edge_release(&frontiers);
+ if(trgsides) MEM_RM(scn->dev->allocator, trgsides);
+
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/senc3d_scene_analyze_c.h b/src/senc3d_scene_analyze_c.h
@@ -0,0 +1,201 @@
+/* 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
+ * 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 SENC3D_SCNENE_ANALYZE_C_H
+#define SENC3D_SCNENE_ANALYZE_C_H
+
+#include "SENC3D_internal_types.h"
+#include "senc3d.h"
+
+#include <rsys/mem_allocator.h>
+#include <rsys/hash_table.h>
+#include <rsys/double3.h>
+
+struct senc3d_scene;
+
+static FINLINE void
+init_trgside(struct mem_allocator* alloc, struct trgside* data)
+{
+ int i;
+ ASSERT(data); (void)alloc;
+ FOR_EACH(i, 0, 3) data->facing_side_id[i] = SIDE_NULL__;
+ data->medium = MEDIUM_NULL__;
+}
+
+#define DARRAY_NAME side_id
+#define DARRAY_DATA side_id_t
+#include <rsys/dynamic_array.h>
+
+/* Descriptors for connex component.
+ * Define lists of trg sides starting from a given head.
+ * 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_z_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;
+ component_id_t cc_group_root;
+ enclosure_id_t enclosure_id;
+ /* Range of sides member of this component */
+ struct side_range side_range;
+ /* Media used by this component */
+ unsigned char* media;
+};
+extern const struct cc_descriptor CC_DESCRIPTOR_NULL;
+
+static FINLINE void
+cc_descriptor_init
+ (struct mem_allocator* alloc,
+ struct cc_descriptor* data)
+{
+ ASSERT(data);
+ (void)alloc;
+ *data = CC_DESCRIPTOR_NULL;
+}
+
+static FINLINE void
+ptr_component_descriptor_init
+ (struct mem_allocator* alloc,
+ struct cc_descriptor** data)
+{
+ (void)alloc;
+ ASSERT(data);
+ *data = NULL;
+}
+
+#define DARRAY_NAME ptr_component_descriptor
+#define DARRAY_DATA struct cc_descriptor*
+#define DARRAY_FUNCTOR_INIT ptr_component_descriptor_init
+#include <rsys/dynamic_array.h>
+
+/* Need allocator to free array elts: cannot rely on standard
+ * darray release stuff */
+static FINLINE void
+custom_darray_ptr_component_descriptor_release
+ (struct darray_ptr_component_descriptor* array)
+{
+ size_t c, cc_count;
+ struct cc_descriptor** components;
+ if(!array) return;
+ cc_count = darray_ptr_component_descriptor_size_get(array);
+ components = darray_ptr_component_descriptor_data_get(array);
+ FOR_EACH(c, 0, cc_count) {
+ if(!components[c]) continue;
+ MEM_RM(array->allocator, components[c]->media);
+ MEM_RM(array->allocator, components[c]);
+ }
+ darray_ptr_component_descriptor_release(array);
+}
+
+/* Triangle information.
+ * Depending on lifespan, information is kept in different places:
+ * - triangle_in for user provided information (kept in scene)
+ * - triangle_tmp for tmp information (kept until triangle_comp is ready)
+ * - triangle_comp for information describing components (kept until
+ * triangle_enc is ready)
+ * - triangle_enc for information describing enclosures (kept in
+ * struct descriptor). */
+struct triangle_tmp {
+ /* Are the edges of the triangle defined in the same order than
+ * the edges they are linked to? */
+ unsigned char reversed_edge[3];
+ double max_z;
+};
+
+#ifndef NDEBUG
+static FINLINE void
+triangle_tmp_init(struct mem_allocator* alloc, struct triangle_tmp* trg) {
+ int i;
+ (void)alloc;
+ ASSERT(trg);
+ FOR_EACH(i, 0, 3) trg->reversed_edge[i] = UCHAR_MAX;
+ trg->max_z = -DBL_MAX;
+}
+#define DARRAY_FUNCTOR_INIT triangle_tmp_init
+#endif
+
+#define DARRAY_NAME triangle_tmp
+#define DARRAY_DATA struct triangle_tmp
+#include <rsys/dynamic_array.h>
+
+#define HTABLE_NAME edge_id
+#define HTABLE_KEY struct trg_edge
+#define HTABLE_DATA edge_id_t
+#define HTABLE_KEY_FUNCTOR_EQ edge_eq
+#include <rsys/hash_table.h>
+
+struct neighbour_info {
+ double angle;
+ trg_id_t trg_id;
+ /* Rank of the edge in the triangle (in [0 2]) */
+ unsigned char common_edge_rank;
+ /* Does the geometrical normal point towards the next neighbour
+ * (if not, it points towards the previous one)? */
+ unsigned char normal_toward_next_neighbour;
+};
+#define DARRAY_NAME neighbour
+#define DARRAY_DATA struct neighbour_info
+#include <rsys/dynamic_array.h>
+
+struct edge_neighbourhood {
+ struct trg_edge edge;
+ struct darray_neighbour neighbours;
+};
+static void
+neighbourhood_init
+ (struct mem_allocator* alloc,
+ struct edge_neighbourhood* n)
+{
+ ASSERT(n);
+ darray_neighbour_init(alloc, &n->neighbours);
+}
+static res_T
+neighbourhood_copy
+ (struct edge_neighbourhood* dst,
+ const struct edge_neighbourhood* src)
+{
+ ASSERT(src && dst);
+ dst->edge = src->edge;
+ return darray_neighbour_copy(&dst->neighbours, &src->neighbours);
+}
+static void
+neighbourhood_release(struct edge_neighbourhood* n) {
+ ASSERT(n);
+ darray_neighbour_release(&n->neighbours);
+}
+static res_T
+neighbourhood_copy_and_release
+ (struct edge_neighbourhood* dst,
+ struct edge_neighbourhood* src)
+{
+ ASSERT(src && dst);
+ dst->edge = src->edge;
+ return darray_neighbour_copy_and_release(&dst->neighbours, &src->neighbours);
+}
+#define DARRAY_NAME neighbourhood
+#define DARRAY_DATA struct edge_neighbourhood
+#define DARRAY_FUNCTOR_INIT neighbourhood_init
+#define DARRAY_FUNCTOR_COPY neighbourhood_copy
+#define DARRAY_FUNCTOR_RELEASE neighbourhood_release
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE neighbourhood_copy_and_release
+#include <rsys/dynamic_array.h>
+
+extern LOCAL_SYM res_T
+scene_analyze(struct senc3d_scene* scene);
+
+#endif /* SENC3D_SCNENE_ANALYZE_C_H */
diff --git a/src/senc3d_scene_c.h b/src/senc3d_scene_c.h
@@ -0,0 +1,302 @@
+/* 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
+ * 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 SENC3D_SCENE_C_H
+#define SENC3D_SCENE_C_H
+
+#include "SENC3D_internal_types.h"
+#include "senc3d_enclosure_data.h"
+#include "SENC3D_side_range.h"
+#include "senc3d.h"
+
+#include <rsys/ref_count.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/hash_table.h>
+
+struct mem_allocator;
+struct senc3d_scene;
+
+struct triangle_comp {
+ /* The connex component in which each side is. */
+ component_id_t component[2];
+};
+
+static void
+triangle_comp_init(struct mem_allocator* alloc, struct triangle_comp* trg) {
+ int i;
+ (void)alloc;
+ ASSERT(trg);
+ FOR_EACH(i, 0, 2) trg->component[i] = COMPONENT_NULL__;
+}
+
+#define DARRAY_NAME triangle_comp
+#define DARRAY_DATA struct triangle_comp
+#define DARRAY_FUNCTOR_INIT triangle_comp_init
+#include <rsys/dynamic_array.h>
+
+struct triangle_enc {
+ /* The enclosure in which each side is. */
+ enclosure_id_t enclosure[2];
+};
+
+#ifndef NDEBUG
+static void
+triangle_enc_init(struct mem_allocator* alloc, struct triangle_enc* trg) {
+ int i;
+ (void)alloc;
+ ASSERT(trg);
+ FOR_EACH(i, 0, 2) trg->enclosure[i] = ENCLOSURE_NULL__;
+}
+#define DARRAY_FUNCTOR_INIT triangle_enc_init
+#endif
+
+#define DARRAY_NAME triangle_enc
+#define DARRAY_DATA struct triangle_enc
+#include <rsys/dynamic_array.h>
+
+/* Triangle edge struct and basic functions */
+struct trg_edge {
+ vrtx_id_t vrtx0, vrtx1;
+};
+
+static FINLINE int
+edge_ok(const struct trg_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 trg_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 trg_edge* e1, const struct trg_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 trgside {
+ /* Rank of the trgside facing this trgside through its edges */
+ side_id_t facing_side_id[3];
+ /* Id of this trgside's medium */
+ medium_id_t medium;
+
+ /* Implicit information that we don't need to store:
+ * - triangle_id
+ * - side
+ * This is due to the memory layout of the elt darray:
+ * front(trg_0), back(trg_0), front(trg_1), back(trg_1), ... */
+};
+
+#define DARRAY_NAME frontier_edge
+#define DARRAY_DATA struct trg_edge
+#include <rsys/dynamic_array.h>
+
+union double3 {
+ struct {
+ double x, y, z;
+ } pos;
+ double vec[3];
+};
+#define DARRAY_NAME position
+#define DARRAY_DATA union double3
+#include <rsys/dynamic_array.h>
+/* Triangle information.
+ * Depending on lifespan, information is kept in different places:
+ * - triangle_in for user provided information (kept in scene)
+ * - triangle_comp for information describing components (kept in struct descriptor)
+ * - triangle_tmp for tmp information (kept until triangle_comp is ready) */
+struct triangle_in {
+ /* Ids of the triangle's vertices */
+ vrtx_id_t vertice_id[3];
+ /* Ids of this triangle's media */
+ medium_id_t medium[2];
+};
+
+static FINLINE void
+triangle_in_init(struct mem_allocator* alloc, struct triangle_in* trg) {
+ int i;
+ (void)alloc;
+ ASSERT(trg);
+ FOR_EACH(i, 0, 3) trg->vertice_id[i] = VRTX_NULL__;
+ FOR_EACH(i, 0, 2) trg->medium[i] = SENC3D_UNSPECIFIED_MEDIUM;
+}
+
+#define DARRAY_NAME triangle_in
+#define DARRAY_DATA struct triangle_in
+#define DARRAY_FUNCTOR_INIT triangle_in_init
+#include <rsys/dynamic_array.h>
+
+static FINLINE void
+triangle_in_flip(struct triangle_in* trg) {
+ vrtx_id_t v;
+ medium_id_t m;
+ ASSERT(trg);
+ v = trg->vertice_id[1];
+ trg->vertice_id[1] = trg->vertice_id[2];
+ trg->vertice_id[2] = v;
+ m = trg->medium[0];
+ trg->medium[0] = trg->medium[1];
+ trg->medium[1] = m;
+}
+
+static FINLINE int
+vrtx_eq(const union double3* v1, const union double3* v2)
+{
+ ASSERT(v1 && v2);
+ return (v1->pos.x == v2->pos.x
+ && v1->pos.y == v2->pos.y
+ && v1->pos.z == v2->pos.z);
+}
+
+#define HTABLE_NAME vrtx
+#define HTABLE_KEY union double3
+#define HTABLE_DATA vrtx_id_t
+#define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
+#include <rsys/hash_table.h>
+
+union vrtx_id3 {
+ struct {
+ vrtx_id_t v0, v1, v2;
+ } pos;
+ vrtx_id_t vec[3];
+};
+
+static FINLINE char /* Return 1 if reversed */
+trg_make_key(union vrtx_id3* k, const vrtx_id_t t[3])
+{
+ ASSERT(t);
+ ASSERT(t[0] != t[1] && t[0] != t[2] && t[1] != t[2]);
+ if(t[0] < t[2]) {
+ if(t[0] < t[1]) {
+ k->vec[0] = t[0];
+ if(t[1] < t[2]) {
+ k->vec[1] = t[1];
+ k->vec[2] = t[2];
+ return 0;
+ } else {
+ k->vec[1] = t[2];
+ k->vec[2] = t[1];
+ return 1;
+ }
+ } else {
+ k->vec[0] = t[1];
+ if(t[0] < t[2]) {
+ k->vec[1] = t[0];
+ k->vec[2] = t[2];
+ return 1;
+ } else {
+ k->vec[1] = t[2];
+ k->vec[2] = t[0];
+ return 0;
+ }
+ }
+ } else if(t[2] < t[1]) {
+ k->vec[0] = t[2];
+ if(t[0] < t[1]) {
+ k->vec[1] = t[0];
+ k->vec[2] = t[1];
+ return 0;
+ } else {
+ k->vec[1] = t[1];
+ k->vec[2] = t[0];
+ return 1;
+ }
+ } else {
+ k->vec[0] = t[1];
+ if(t[0] < t[2]) {
+ k->vec[1] = t[0];
+ k->vec[2] = t[2];
+ return 1;
+ } else {
+ k->vec[1] = t[2];
+ k->vec[2] = t[0];
+ return 0;
+ }
+ }
+}
+
+static FINLINE int
+trg_key_eq(const union vrtx_id3* k1, const union vrtx_id3* k2)
+{
+ ASSERT(k1 && k2);
+ ASSERT(k1->vec[0] < k1->vec[1] && k1->vec[1] < k1->vec[2]);
+ ASSERT(k2->vec[0] < k2->vec[1] && k2->vec[1] < k2->vec[2]);
+ return (k1->vec[0] == k2->vec[0])
+ && (k1->vec[1] == k2->vec[1])
+ && (k1->vec[2] == k2->vec[2]);
+}
+
+#define HTABLE_NAME trg
+#define HTABLE_KEY union vrtx_id3
+#define HTABLE_DATA trg_id_t
+#define HTABLE_KEY_FUNCTOR_EQ trg_key_eq
+#include <rsys/hash_table.h>
+
+struct descriptor {
+ enclosure_id_t enclosures_count;
+ /* Store by-triangle enclosures */
+ struct darray_triangle_enc triangles_enc;
+ /* Store enclosures */
+ struct darray_enclosure enclosures;
+ struct darray_enc_ids_array enc_ids_array_by_medium;
+ /* Store frontiers */
+ struct darray_frontier_edge frontiers;
+};
+
+struct senc3d_scene {
+ /* Front / Back sides convention */
+ int convention;
+ /* Triangle information as given by user */
+ struct darray_triangle_in triangles_in;
+ /* Vertex information as given by user */
+ struct darray_position vertices;
+
+ /* Keep sizes */
+ trg_id_t ntris; /* Trg count */
+ vrtx_id_t nverts; /* Vrtx count */
+ medium_id_t next_medium_idx;
+ /* media_use 0 is for SENC3D_UNSPECIFIED_MEDIUM, n+1 is for n */
+ struct darray_side_range media_use;
+
+ /* The descriptor of the analyze */
+ struct descriptor analyze;
+
+ ref_T ref;
+ struct senc3d_device* dev;
+};
+
+#endif /* SENC3D_SCENE_C_H */
diff --git a/src/senc3d_side_range.h b/src/senc3d_side_range.h
@@ -0,0 +1,44 @@
+/* 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
+ * 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 SENC3D_SIDE_RANGE_H
+#define SENC3D_SIDE_RANGE_H
+
+#include "SENC3D_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 /* SENC3D_SCENE_C_H */
diff --git a/src/sencX3.h b/src/sencX3.h
@@ -1,423 +0,0 @@
-/* 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
- * 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_3D_H
-#define SENC_X_3D_H
-
-#include <star/senc.h>
-#include <rsys/rsys.h>
-
-/* This file can be used in conjunction with sencX2.h from the the
- * star-enclosures-2D library to write code for both 2D and 3D geometries using
- * the following pattern:
- *
- * #if (DIM==2)
- * #include <star/sencX2.h>
- * #elif (DIM==3)
- * #include <star/sencX3.h>
- * #else
- * #error DIM should be defined; possible values are 2 and 3
- * #endif
- *
- * Then use the sencX_... types and functions in your code.
- */
-
-/* Forward declaration of external opaque data types */
-struct logger;
-struct mem_allocator;
-
-/* Forward declaration of StarEnclosures opaque data types. These data types
- * are ref counted. Once created with the appropriated `senc_<TYPE>_create'
- * function, the caller implicitly owns the created data, i.e. its reference
- * counter is set to 1. The senc_<TYPE>_ref_<get|put> functions get or release
- * a reference on the data, i.e. they increment or decrement the reference
- * counter, respectively. When this counter reaches 0, the object is silently
- * destroyed and cannot be used anymore. */
-typedef struct senc_device sencX_device;
-typedef struct senc_scene sencX_scene;
-typedef struct senc_enclosure sencX_enclosure;
-
-/*******************************************************************************
- * The dimension of the geometry used in the library.
- ******************************************************************************/
-#define SENCX_GEOMETRY_DIMENSION SENC_GEOMETRY_DIMENSION
-
-/* A type to discriminate triangle sides */
-enum sencXd_side {
- SENCXD_FRONT = SENC_FRONT,
- SENCXD_BACK = SENC_BACK
-};
-
-/* Enclosure header type */
-typedef struct senc_enclosure_header sencXd_enclosure_header;
-
-/* We consider the geometrical normal Ng to a triangle V0 V1 V2
- * that verifies "(V0, V0V1, V0V2, Ng) is a direct system"
- * (right-handed system).
- *
- * The user can set the convention used to determine which side of
- * a triangle is to be considered front/back by using the flags :
- * SENC_CONVENTION_NORMAL_FRONT => Ng points toward the front side,
- * SENC_CONVENTION_NORMAL_BACK => Ng points toward the back side.
- *
- * Additionaly the user can set the convention used to output enclosures
- * so that Ng points toward the enclosure or on the opposite direction
- * (for a closed enclosure Ng points toward the inside or toward the outside)
- * by using the flags :
- * SENC_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure,
- * SENC_CONVENTION_NORMAL_OUTSIDE => Ng points to 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).
- *
- * Also note that both sides of a triangle can be part of the same enclosure;
- * in this case the 2 sides will be given with opposite Ng (meaning they
- * will be given with opposite vertices order).
- */
-enum sencXd_convention {
- /*
- * Convention regarding FRONT/BACK sides in input data
- */
-
- /* Geometrical normals point toward the front side */
- SENCXD_CONVENTION_NORMAL_FRONT = SENC_CONVENTION_NORMAL_FRONT,
- /* Geometrical normals point toward the back side */
- SENCXD_CONVENTION_NORMAL_BACK = SENC_CONVENTION_NORMAL_BACK,
-
- /*
- * Convention regarding geometrical normals in output data
- */
-
- /* Geometrical normals point toward the enclosure */
- SENCXD_CONVENTION_NORMAL_INSIDE = SENC_CONVENTION_NORMAL_INSIDE,
- /* Geometrical normals point to the opposite of the enclosure */
- SENCXD_CONVENTION_NORMAL_OUTSIDE = SENC_CONVENTION_NORMAL_OUTSIDE
-};
-
-/******************************************************************************
- * The value that should be used to let media unspecified.
- *****************************************************************************/
-#define SENCXD_UNSPECIFIED_MEDIUM SENC_UNSPECIFIED_MEDIUM
-
-BEGIN_DECLS
-
-/******************************************************************************
- * StarEnclosures 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.
- *****************************************************************************/
-static FINLINE res_T
-sencXd_device_create
- (struct logger* logger, /* May be NULL <=> use default logger */
- struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
- const unsigned nthreads_hint,
- const int verbose,
- struct senc_device** device)
-{
- return senc_device_create(logger, allocator, nthreads_hint, verbose, device);
-}
-
-static FINLINE res_T
-sencXd_device_ref_get
- (struct senc_device* device)
-{
- return senc_device_ref_get(device);
-}
-
-static FINLINE res_T
-sencXd_device_ref_put
- (struct senc_device* device)
-{
- return senc_device_ref_put(device);
-}
-
-/******************************************************************************
- * StarEnclosures scene. A scene is a collection of triangles. Each triangle is
- * defined with a medium on each side.
- *****************************************************************************/
-/* Creates a scene from some vertices and triangles.
- * Neither vertices nor triangles can include duplicates.
- * Triangles cannot be degenerated. */
-static FINLINE res_T
-sencXd_scene_create
- (struct senc_device* device,
- const int convention,
- /* Number of triangles */
- const unsigned triangles_count,
- /* User function that provides vertices ids for triangles */
- void(*get_indices)(
- const unsigned itri,
- unsigned ids[SENCX_GEOMETRY_DIMENSION],
- void* context),
- /* User function that provides media ids for triangles */
- void(*get_media) /* Can be NULL <=> SENC_UNSPECIFIED_MEDIUM medium used */
- (const unsigned itri, unsigned med[2], void* context),
- /* Number of vertices */
- const unsigned vertices_count,
- /* User function that provides coordinates for vertices */
- void(*get_position)(
- const unsigned ivert,
- double pos[SENCX_GEOMETRY_DIMENSION],
- void* context),
- /* Context provided to user callbacks; can be NULL */
- void* context,
- /* The created scene */
- struct senc_scene** scene)
-{
- return senc_scene_create(device, convention, triangles_count, get_indices,
- get_media, vertices_count, get_position, context, scene);
-}
-
-/* Returns the convention flags in use with the scene. */
-static FINLINE res_T
-sencXd_scene_get_convention
- (const struct senc_scene* scene,
- int* convention)
-{
- return senc_scene_get_convention(scene, convention);
-}
-
-/* Returns the number of triangles in the scene. */
-static FINLINE res_T
-sencXd_scene_get_primitives_count
- (const struct senc_scene* scene,
- unsigned* count)
-{
- return senc_enclosure_get_triangles_count(scene, count);
-}
-
-/* Returns the itri_th triangle vertices' indices. */
-static FINLINE res_T
-sencXd_scene_get_primitive
- (const struct senc_scene* scene,
- const unsigned itri,
- unsigned indices[SENCX_GEOMETRY_DIMENSION])
-{
- return senc_enclosure_get_triangle(scene, itri, indices);
-}
-
-/* Returns the media for the itri_th triangle. */
-static FINLINE res_T
-sencXd_scene_get_primitive_media
- (const struct senc_scene* scene,
- const unsigned itri,
- unsigned media[2])
-{
- return senc_enclosure_get_triangle_media(scene, itri, media);
-}
-
-/* Returns the number of vertices in the scene. */
-static FINLINE res_T
-sencXd_scene_get_vertices_count
- (const struct senc_scene* scene,
- unsigned* count)
-{
- return senc_scene_get_vertices_count(scene, count);
-}
-
-/* Returns the coordinates of the ivert_th vertex. */
-static FINLINE res_T
-sencXd_scene_get_vertex
- (const struct senc_scene* scene,
- const unsigned ivert,
- double coord[SENCX_GEOMETRY_DIMENSION])
-{
- return senc_scene_get_vertex(scene, ivert, coord);
-}
-
-/* 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). */
-static FINLINE res_T
-sencXd_scene_get_max_medium
- (const struct senc_scene* scene,
- unsigned* max_medium_id)
-{
- return senc_scene_get_max_medium(scene, max_medium_id);
-}
-
-/* Returns the number of enclosures. */
-static FINLINE res_T
-sencXd_scene_get_enclosure_count
- (const struct senc_scene* scene,
- unsigned* count)
-{
- return senc_scene_get_enclosure_count(scene, count);
-}
-
-/* Returns the number of enclosures that have some geometry refering to the
- * imed_th medium or SENC_UNSPECIFIED_MEDIUM. */
-static FINLINE res_T
-sencXd_scene_get_enclosure_count_by_medium
- (const struct senc_scene* scene,
- const unsigned imed,
- unsigned* count)
-{
- return senc_scene_get_enclosure_count_by_medium(scene, imed, count);
-}
-
-/* Returns the idx_th enclosure. */
-static FINLINE res_T
-sencXd_scene_get_enclosure
- (struct senc_scene* scene,
- const unsigned idx,
- struct senc_enclosure** enclosure)
-{
- return senc_scene_get_enclosure(scene, idx, enclosure);
-}
-
-/* Returns the idx_th enclosure using the imed_th medium or
- * SENC_UNSPECIFIED_MEDIUM. */
-static FINLINE res_T
-sencXd_scene_get_enclosure_by_medium
- (struct senc_scene* scene,
- const unsigned imed,
- const unsigned idx,
- struct senc_enclosure** enclosure)
-{
- return senc_scene_get_enclosure_by_medium(scene, imed, idx, enclosure);
-}
-
-/* Returns the enclosures the itri_th triangle front and back sides are member
- * of. */
-static FINLINE res_T
-sencXd_scene_get_primitive_enclosures
- (const struct senc_scene* scene,
- const unsigned itri,
- unsigned enclosures[2])
-{
- return senc_scene_get_triangle_enclosures(scene, itri, enclosures);
-}
-
-/* Returns the number of segments that are frontier segments:
- * - that have arity 1 (single triangle using the segment)
- * - that connect 2 different media */
-static FINLINE res_T
-sencXd_scene_get_frontier_elements_count
- (const struct senc_scene* scene,
- unsigned* count)
-{
- return senc_scene_get_frontier_segments_count(scene, count);
-}
-
-/* Returns the iseg_th frontier segment; the returned indices are global vertex
- * indices whose coordinates can be retrieved using sencXd_scene_get_vertex. */
-static FINLINE res_T
-sencXd_scene_get_frontier_element
- (const struct senc_scene* scene,
- const unsigned iseg,
- unsigned vrtx_id[SENCX_GEOMETRY_DIMENSION-1])
-{
- return senc_scene_get_frontier_segment(scene, iseg, vrtx_id);
-}
-
-static FINLINE res_T
-sencXd_scene_ref_get
- (struct senc_scene* scene)
-{
- return senc_scene_ref_get(scene);
-}
-
-static FINLINE res_T
-sencXd_scene_ref_put
- (struct senc_scene* scene)
-{
- return senc_scene_ref_put(scene);
-}
-
-/*******************************************************************************
- * StarEnclosures 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" triangle twice if both sides are in. In this
- * case the 2 occurences of the triangle have reversed vertices order and
- * unique_triangle_count and triangle_count differ.
- * Vertices and triangles 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 triangles (or properties) visit unique triangles
- * for indices in the [0 unique_triangle_count[ range and back-faces of the
- * doubly-included triangles in the [unique_triangle_count triangle_count[ range.
- ******************************************************************************/
-/* Returns the header of an enclosure. */
-static FINLINE res_T
-sencXd_enclosure_get_header
- (const struct senc_enclosure* enclosure,
- struct senc_enclosure_header* header)
-{
- return senc_enclosure_get_header(enclosure, header);
-}
-
-/* Returns the itri_th triangle of an enclosure.
- * Indices are local to the enclosure. */
-static FINLINE res_T
-sencXd_enclosure_get_primitive
- (const struct senc_enclosure* enclosure,
- const unsigned itri,
- unsigned indices[SENCX_GEOMETRY_DIMENSION])
-{
- return senc_enclosure_get_triangle(enclosure, itri, indices);
-}
-
-/* Returns the coordinates of the ivert_th vertex of an enclosure. */
-static FINLINE res_T
-sencXd_enclosure_get_vertex
- (const struct senc_enclosure* enclosure,
- const unsigned ivert,
- double coord[SENCX_GEOMETRY_DIMENSION])
-{
- return senc_enclosure_get_vertex(enclosure, ivert, coord);
-}
-
-/* Returns the global id of the itri_th triangle of an enclosure
- * and the involved side. */
-static FINLINE res_T
-sencXd_enclosure_get_primitive_id
- (const struct senc_enclosure* enclosure,
- const unsigned itri,
- unsigned* gid,
- enum senc_side* side)
-{
- return senc_enclosure_get_triangle_id(enclosure, itri, gid, side);
-}
-
-/* Returns the id of the imed_th medium of an enclosure. */
-static FINLINE res_T
-sencXd_enclosure_get_medium
- (const struct senc_enclosure* enclosure,
- const unsigned imed,
- unsigned* medium)
-{
- return senc_enclosure_get_medium(enclosure, imed, medium);
-}
-
-static FINLINE res_T
-sencXd_enclosure_ref_get
- (struct senc_enclosure* enclosure)
-{
- return senc_enclosure_ref_get(enclosure);
-}
-
-static FINLINE res_T
-sencXd_enclosure_ref_put
- (struct senc_enclosure* enclosure)
-{
- return senc_enclosure_ref_put(enclosure);
-}
-
-END_DECLS
-
-#endif /* SENC_X_3D_H */
diff --git a/src/sencX3d.h b/src/sencX3d.h
@@ -0,0 +1,488 @@
+/* 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
+ * 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 SENC3D_X_3D_H
+#define SENC3D_X_3D_H
+
+#include <star/senc3d.h>
+#include <star/SENC3D_s3d_helper.h>
+#include <rsys/rsys.h>
+
+/* This file can be used in conjunction with sencX2.h from the the
+ * star-enclosures-2D library to write code for both 2D and 3D geometries using
+ * the following pattern:
+ *
+ * #if (DIM==2)
+ * #include <star/sencX2.h>
+ * #elif (DIM==3)
+ * #include <star/sencX3d.h>
+ * #else
+ * #error DIM should be defined; possible values are 2 and 3
+ * #endif
+ *
+ * Then use the sencX_... types and functions in your code.
+ *
+ * Definitions from sencX2.h and sencX3d.h cannot be visible at the same time
+ * as some of them conflict.
+ */
+
+/* Helper macro that asserts if the invocation of the StarEnclosures function
+ * `Func' returns an error. One should use this macro on StarEnc function calls
+ * for which no explicit error checking is performed. */
+#ifndef NDEBUG
+#define SENCX(Func) ASSERT(sencX_ ## Func == RES_OK)
+#else
+#define SENCX(Func) sencX_ ## Func
+#endif
+
+/* Forward declaration of external opaque data types */
+struct logger;
+struct mem_allocator;
+
+/* Forward declaration of StarEnclosures opaque data types. These data types
+ * are ref counted. Once created with the appropriated `SENC3D_<TYPE>_create'
+ * function, the caller implicitly owns the created data, i.e. its reference
+ * counter is set to 1. The SENC3D_<TYPE>_ref_<get|put> functions get or release
+ * a reference on the data, i.e. they increment or decrement the reference
+ * counter, respectively. When this counter reaches 0, the object is silently
+ * destroyed and cannot be used anymore. */
+typedef struct senc3d_device sencX_device;
+typedef struct senc3d_scene sencX_scene;
+typedef struct senc3d_enclosure sencX_enclosure;
+
+/*******************************************************************************
+ * The dimension of the geometry used in the library.
+ ******************************************************************************/
+#define SENCX_GEOMETRY_DIMENSION SENC3D_GEOMETRY_DIMENSION
+
+/* A type to discriminate triangle sides */
+enum sencX_side {
+ SENCX_FRONT = SENC3D_FRONT,
+ SENCX_BACK = SENC3D_BACK
+};
+
+/* Enclosure header type */
+typedef struct senc3d_enclosure_header sencX_enclosure_header;
+
+/* We consider the geometrical normal Ng to a triangle V0 V1 V2
+ * that verifies "(V0, V0V1, V0V2, Ng) is a direct system"
+ * (right-handed system).
+ *
+ * The user can set the convention used to determine which side of
+ * a triangle is to be considered front/back by using the flags :
+ * SENC3D_CONVENTION_NORMAL_FRONT => Ng points toward the front side,
+ * SENC3D_CONVENTION_NORMAL_BACK => Ng points toward the back side.
+ *
+ * Additionaly the user can set the convention used to output enclosures
+ * so that Ng points toward the enclosure or on the opposite direction
+ * (for a closed enclosure Ng points toward the inside or toward the outside)
+ * by using the flags :
+ * SENC3D_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure,
+ * SENC3D_CONVENTION_NORMAL_OUTSIDE => Ng points to 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).
+ *
+ * Also note that both sides of a triangle can be part of the same enclosure;
+ * in this case the 2 sides will be given with opposite Ng (meaning they
+ * will be given with opposite vertices order).
+ */
+enum sencX_convention {
+ /*
+ * Convention regarding FRONT/BACK sides in input data
+ */
+
+ /* Geometrical normals point toward the front side */
+ SENCX_CONVENTION_NORMAL_FRONT = SENC3D_CONVENTION_NORMAL_FRONT,
+ /* Geometrical normals point toward the back side */
+ SENCX_CONVENTION_NORMAL_BACK = SENC3D_CONVENTION_NORMAL_BACK,
+
+ /*
+ * Convention regarding geometrical normals in output data
+ */
+
+ /* Geometrical normals point toward the enclosure */
+ SENCX_CONVENTION_NORMAL_INSIDE = SENC3D_CONVENTION_NORMAL_INSIDE,
+ /* Geometrical normals point to the opposite of the enclosure */
+ SENCX_CONVENTION_NORMAL_OUTSIDE = SENC3D_CONVENTION_NORMAL_OUTSIDE
+};
+
+/******************************************************************************
+ * The value that should be used to let media unspecified.
+ *****************************************************************************/
+#define SENCX_UNSPECIFIED_MEDIUM SENC3D_UNSPECIFIED_MEDIUM
+
+BEGIN_DECLS
+
+/******************************************************************************
+ * StarEnclosures 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.
+ *****************************************************************************/
+static FINLINE res_T
+sencX_device_create
+ (struct logger* logger, /* May be NULL <=> use default logger */
+ struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
+ const unsigned nthreads_hint,
+ const int verbose,
+ sencX_device** device)
+{
+ return senc3d_device_create(logger, allocator, nthreads_hint, verbose, device);
+}
+
+static FINLINE res_T
+sencX_device_ref_get
+ (sencX_device* device)
+{
+ return senc3d_device_ref_get(device);
+}
+
+static FINLINE res_T
+sencX_device_ref_put
+ (sencX_device* device)
+{
+ return senc3d_device_ref_put(device);
+}
+
+/******************************************************************************
+ * StarEnclosures scene. A scene is a collection of triangles. Each triangle is
+ * defined with a medium on each side.
+ *****************************************************************************/
+/* Creates a scene from some vertices and triangles.
+ * Neither vertices nor triangles can include duplicates.
+ * Triangles cannot be degenerated. */
+static FINLINE res_T
+sencX_scene_create
+ (sencX_device* device,
+ const int convention,
+ /* Number of triangles */
+ const unsigned triangles_count,
+ /* User function that provides vertices ids for triangles */
+ void(*get_indices)(
+ const unsigned itri,
+ unsigned ids[SENCX_GEOMETRY_DIMENSION],
+ void* context),
+ /* User function that provides media ids for triangles */
+ void(*get_media) /* Can be NULL <=> SENC3D_UNSPECIFIED_MEDIUM medium used */
+ (const unsigned itri, unsigned med[2], void* context),
+ /* Number of vertices */
+ const unsigned vertices_count,
+ /* User function that provides coordinates for vertices */
+ void(*get_position)(
+ const unsigned ivert,
+ double pos[SENCX_GEOMETRY_DIMENSION],
+ void* context),
+ /* Context provided to user callbacks; can be NULL */
+ void* context,
+ /* The created scene */
+ sencX_scene** scene)
+{
+ return senc3d_scene_create(device, convention, triangles_count, get_indices,
+ get_media, vertices_count, get_position, context, scene);
+}
+
+/* Returns the convention flags in use with the scene. */
+static FINLINE res_T
+sencX_scene_get_convention
+ (const sencX_scene* scene,
+ int* convention)
+{
+ return senc3d_scene_get_convention(scene, convention);
+}
+
+/* Returns the number of triangles in the scene. */
+static FINLINE res_T
+sencX_scene_get_primitives_count
+ (const sencX_scene* scene,
+ unsigned* count)
+{
+ return senc3d_scene_get_triangles_count(scene, count);
+}
+
+/* Returns the itri_th triangle vertices' indices. */
+static FINLINE res_T
+sencX_scene_get_primitive
+ (const sencX_scene* scene,
+ const unsigned itri,
+ unsigned indices[SENCX_GEOMETRY_DIMENSION])
+{
+ return senc3d_scene_get_triangle(scene, itri, indices);
+}
+
+/* Returns the media for the itri_th triangle. */
+static FINLINE res_T
+sencX_scene_get_primitive_media
+ (const sencX_scene* scene,
+ const unsigned itri,
+ unsigned media[2])
+{
+ return senc3d_scene_get_triangle_media(scene, itri, media);
+}
+
+/* Returns the number of vertices in the scene. */
+static FINLINE res_T
+sencX_scene_get_vertices_count
+ (const sencX_scene* scene,
+ unsigned* count)
+{
+ return senc3d_scene_get_vertices_count(scene, count);
+}
+
+/* Returns the coordinates of the ivert_th vertex. */
+static FINLINE res_T
+sencX_scene_get_vertex
+ (const sencX_scene* scene,
+ const unsigned ivert,
+ double coord[SENCX_GEOMETRY_DIMENSION])
+{
+ return senc3d_scene_get_vertex(scene, ivert, coord);
+}
+
+/* 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). */
+static FINLINE res_T
+sencX_scene_get_max_medium
+ (const sencX_scene* scene,
+ unsigned* max_medium_id)
+{
+ return senc3d_scene_get_max_medium(scene, max_medium_id);
+}
+
+/* Returns the number of enclosures. */
+static FINLINE res_T
+sencX_scene_get_enclosure_count
+ (const sencX_scene* scene,
+ unsigned* count)
+{
+ return senc3d_scene_get_enclosure_count(scene, count);
+}
+
+/* Returns the number of enclosures that have some geometry refering to the
+ * imed_th medium or SENC3D_UNSPECIFIED_MEDIUM. */
+static FINLINE res_T
+sencX_scene_get_enclosure_count_by_medium
+ (const sencX_scene* scene,
+ const unsigned imed,
+ unsigned* count)
+{
+ return senc3d_scene_get_enclosure_count_by_medium(scene, imed, count);
+}
+
+/* Returns the idx_th enclosure. */
+static FINLINE res_T
+sencX_scene_get_enclosure
+ (sencX_scene* scene,
+ const unsigned idx,
+ sencX_enclosure** enclosure)
+{
+ return senc3d_scene_get_enclosure(scene, idx, enclosure);
+}
+
+/* Returns the idx_th enclosure using the imed_th medium or
+ * SENC3D_UNSPECIFIED_MEDIUM. */
+static FINLINE res_T
+sencX_scene_get_enclosure_by_medium
+ (sencX_scene* scene,
+ const unsigned imed,
+ const unsigned idx,
+ sencX_enclosure** enclosure)
+{
+ return senc3d_scene_get_enclosure_by_medium(scene, imed, idx, enclosure);
+}
+
+/* Returns the enclosures the itri_th triangle front and back sides are member
+ * of. */
+static FINLINE res_T
+sencX_scene_get_primitive_enclosures
+ (const sencX_scene* scene,
+ const unsigned itri,
+ unsigned enclosures[2])
+{
+ return senc3d_scene_get_triangle_enclosures(scene, itri, enclosures);
+}
+
+/* Returns the number of segments that are frontier segments:
+ * - that have arity 1 (single triangle using the segment)
+ * - that connect 2 different media */
+static FINLINE res_T
+sencX_scene_get_frontier_elements_count
+ (const sencX_scene* scene,
+ unsigned* count)
+{
+ return senc3d_scene_get_frontier_segments_count(scene, count);
+}
+
+/* Returns the iseg_th frontier segment; the returned indices are global vertex
+ * indices whose coordinates can be retrieved using sencX_scene_get_vertex. */
+static FINLINE res_T
+sencX_scene_get_frontier_element
+ (const sencX_scene* scene,
+ const unsigned iseg,
+ unsigned vrtx_id[SENCX_GEOMETRY_DIMENSION-1])
+{
+ return senc3d_scene_get_frontier_segment(scene, iseg, vrtx_id);
+}
+
+static FINLINE res_T
+sencX_scene_ref_get
+ (sencX_scene* scene)
+{
+ return senc3d_scene_ref_get(scene);
+}
+
+static FINLINE res_T
+sencX_scene_ref_put
+ (sencX_scene* scene)
+{
+ return senc3d_scene_ref_put(scene);
+}
+
+/*******************************************************************************
+ * StarEnclosures 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" triangle twice if both sides are in. In this
+ * case the 2 occurences of the triangle have reversed vertices order and
+ * unique_triangle_count and triangle_count differ.
+ * Vertices and triangles 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 triangles (or properties) visit unique triangles
+ * for indices in the [0 unique_triangle_count[ range and back-faces of the
+ * doubly-included triangles in the [unique_triangle_count triangle_count[ range.
+ ******************************************************************************/
+/* Returns the header of an enclosure. */
+static FINLINE res_T
+sencX_enclosure_get_header
+ (const sencX_enclosure* enclosure,
+ sencX_enclosure_header* header)
+{
+ return senc3d_enclosure_get_header(enclosure, header);
+}
+
+/* Returns the itri_th triangle of an enclosure.
+ * Indices are local to the enclosure. */
+static FINLINE res_T
+sencX_enclosure_get_primitive
+ (const sencX_enclosure* enclosure,
+ const unsigned itri,
+ unsigned indices[SENCX_GEOMETRY_DIMENSION])
+{
+ return senc3d_enclosure_get_triangle(enclosure, itri, indices);
+}
+
+/* Returns the coordinates of the ivert_th vertex of an enclosure. */
+static FINLINE res_T
+sencX_enclosure_get_vertex
+ (const sencX_enclosure* enclosure,
+ const unsigned ivert,
+ double coord[SENCX_GEOMETRY_DIMENSION])
+{
+ return senc3d_enclosure_get_vertex(enclosure, ivert, coord);
+}
+
+/* Returns the global id of the itri_th triangle of an enclosure
+ * and the involved side. */
+static FINLINE res_T
+sencX_enclosure_get_primitive_id
+ (const sencX_enclosure* enclosure,
+ const unsigned itri,
+ unsigned* gid,
+ enum senc3d_side* side)
+{
+ return senc3d_enclosure_get_triangle_id(enclosure, itri, gid, side);
+}
+
+/* Returns the id of the imed_th medium of an enclosure. */
+static FINLINE res_T
+sencX_enclosure_get_medium
+ (const sencX_enclosure* enclosure,
+ const unsigned imed,
+ unsigned* medium)
+{
+ return senc3d_enclosure_get_medium(enclosure, imed, medium);
+}
+
+static FINLINE res_T
+sencX_enclosure_ref_get
+ (sencX_enclosure* enclosure)
+{
+ return senc3d_enclosure_ref_get(enclosure);
+}
+
+static FINLINE res_T
+sencX_enclosure_ref_put
+ (sencX_enclosure* enclosure)
+{
+ return senc3d_enclosure_ref_put(enclosure);
+}
+
+/******************************************************************************
+ * StarEnclosuresXD to StarXD helper.
+ *****************************************************************************/
+
+ /* Get vertex indices for the iseg_th segment.
+ * Suitable for use as get_indice callback in s3d_mesh_setup_indexed_vertices
+ * calls. */
+static FINLINE void
+sencX_sXd_scene_get_indices
+ (const unsigned iseg,
+ unsigned indices[SENCX_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ SENC3D_s3d_scene_get_indices(iseg, indices, ctx);
+}
+
+/* Get coordinates for the ivert_th vertex.
+ * Suitable for use as s3d_vertex_data getter for S3D_POSITION s3d_attrib_usage
+ * in s3d_mesh_setup_indexed_vertices calls. */
+static FINLINE void
+sencX_sXd_scene_get_position
+ (const unsigned ivert,
+ float coord[SENCX_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ SENC3D_s3d_scene_get_position(ivert, coord, ctx);
+}
+
+/* Get vertex indices for the iseg_th segment of the enclosure.
+ * Suitable for use as get_indice callback in s3d_mesh_setup_indexed_vertices
+ * calls. */
+static FINLINE void
+sencX_sXd_enclosure_get_indices
+ (const unsigned iseg,
+ unsigned indices[SENCX_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ SENC3D_s3d_enclosure_get_indices(iseg, indices, ctx);
+}
+
+/* Get coordinates for the ivert_th vertex of the enclosure.
+ * Suitable for use as s3d_vertex_data getter for S3D_POSITION s3d_attrib_usage
+ * in s3d_mesh_setup_indexed_vertices calls. */
+static FINLINE void
+sencX_sXd_enclosure_get_position
+ (const unsigned ivert,
+ float coord[SENCX_GEOMETRY_DIMENSION],
+ void* ctx)
+{
+ SENC3D_s3d_enclosure_get_position(ivert, coord, ctx);
+}
+
+END_DECLS
+
+#endif /* SENC3D_X_3D_H */
diff --git a/src/senc_descriptor.c b/src/senc_descriptor.c
@@ -1,160 +0,0 @@
-/* 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
- * 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 "senc_enclosure_c.h"
-#include "senc_scene_c.h"
-#include "senc.h"
-
-#include <rsys/rsys.h>
-#include <rsys/double3.h>
-#include <rsys/mem_allocator.h>
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-senc_scene_get_max_medium
- (const struct senc_scene* scn, unsigned* max_medium_id)
-{
- 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
-senc_scene_get_enclosure_count
- (const struct senc_scene* scn, unsigned* count)
-{
- size_t tmp;
- if(!scn || !count) return RES_BAD_ARG;
- tmp = darray_enclosure_size_get(&scn->analyze.enclosures);
- ASSERT(tmp < UINT_MAX); /* API type */
- ASSERT(scn->analyze.enclosures_count == tmp);
- *count = (unsigned)tmp;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_enclosure_count_by_medium
- (const struct senc_scene* scn,
- const unsigned imed,
- unsigned* count)
-{
- size_t tmp, m_idx;
- const struct darray_enc_id* enc_ids;
- if(!scn || !count
- || (imed != SENC_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
- return RES_BAD_ARG;
- ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
- == 1 + scn->next_medium_idx);
- m_idx = (imed == SENC_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 */
- *count = (unsigned)tmp;
- return RES_OK;
-}
-
-FINLINE res_T
-senc_scene_get_enclosure
- (struct senc_scene* scn,
- const unsigned idx,
- struct senc_enclosure** out_enc)
-{
- struct senc_enclosure* enc;
- if(!scn || idx >= darray_enclosure_size_get(&scn->analyze.enclosures)
- || !out_enc)
- return RES_BAD_ARG;
- enc = enclosure_create(scn, idx);
- if(!enc) return RES_MEM_ERR;
- *out_enc = enc;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_enclosure_by_medium
- (struct senc_scene* scn,
- const unsigned imed,
- const unsigned idx,
- struct senc_enclosure** out_enc)
-{
- size_t m_idx;
- const struct darray_enc_id* enc_ids;
- unsigned index;
- if(!scn || !out_enc
- || (imed != SENC_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
- return RES_BAD_ARG;
- ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
- == 1 + scn->next_medium_idx);
- m_idx = (imed == SENC_UNSPECIFIED_MEDIUM) ? 0 : imed + 1;
- enc_ids =
- 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 senc_scene_get_enclosure(scn, index, out_enc);
-}
-
-res_T
-senc_scene_get_triangle_enclosures
- (const struct senc_scene* scn,
- const unsigned itri,
- unsigned enclosures[2])
-{
- const struct triangle_enc* trg;
- int i;
- if(!enclosures || !scn
- || itri >= darray_triangle_enc_size_get(&scn->analyze.triangles_enc))
- return RES_BAD_ARG;
- trg = darray_triangle_enc_cdata_get(&scn->analyze.triangles_enc) + itri;
- FOR_EACH(i, 0, 2) {
-#if (UINT_MAX < ENCLOSURE_MAX__)
- ASSERT(trg->enclosure[i] < UINT_MAX);
-#endif
- enclosures[i] = (unsigned)trg->enclosure[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc_scene_get_frontier_segments_count
- (const struct senc_scene* scn,
- unsigned* count)
-{
- size_t tmp;
- if(!scn || !count)
- return RES_BAD_ARG;
- tmp = darray_frontier_edge_size_get(&scn->analyze.frontiers);
- ASSERT(tmp < UINT_MAX);
- *count = (unsigned)tmp;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_frontier_segment
- (const struct senc_scene* scn,
- const unsigned iseg,
- unsigned vrtx_id[2])
-{
- const struct trg_edge* edge;
- if(!vrtx_id || !scn
- || iseg >= darray_frontier_edge_size_get(&scn->analyze.frontiers))
- return RES_BAD_ARG;
- edge = darray_frontier_edge_cdata_get(&scn->analyze.frontiers) + iseg;
- vrtx_id[0] = (unsigned)edge->vrtx0; /* Back to API type */
- vrtx_id[1] = (unsigned)edge->vrtx1; /* Back to API type */
- return RES_OK;
-}
diff --git a/src/senc_device.c b/src/senc_device.c
@@ -1,148 +0,0 @@
-/* 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
- * 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 "senc.h"
-#include "senc_device_c.h"
-
-#include <rsys/logger.h>
-#include <rsys/mem_allocator.h>
-
-#include <omp.h>
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static void
-log_msg
- (struct senc_device* dev,
- const enum log_type stream,
- const char* msg,
- va_list vargs)
-{
- ASSERT(dev && msg);
- if(dev->verbose) {
- res_T res; (void)res;
- res = logger_vprint(dev->logger, stream, msg, vargs);
- ASSERT(res == RES_OK);
- }
-}
-
-static void
-device_release(ref_T* ref)
-{
- struct senc_device* dev;
- ASSERT(ref);
- dev = CONTAINER_OF(ref, struct senc_device, ref);
- MEM_RM(dev->allocator, dev);
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-void
-log_err(struct senc_device* dev, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(dev && msg);
-
- va_start(vargs_list, msg);
- log_msg(dev, LOG_ERROR, msg, vargs_list);
- va_end(vargs_list);
-}
-
-void
-log_warn(struct senc_device* dev, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(dev && msg);
-
- va_start(vargs_list, msg);
- log_msg(dev, LOG_WARNING, msg, vargs_list);
- va_end(vargs_list);
-}
-
-void
-log_info(struct senc_device* dev, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(dev && msg);
-
- va_start(vargs_list, msg);
- log_msg(dev, LOG_OUTPUT, msg, vargs_list);
- va_end(vargs_list);
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-senc_device_create
- (struct logger* logger,
- struct mem_allocator* mem_allocator,
- const unsigned nthreads_hint,
- const int verbose,
- struct senc_device** out_dev)
-{
- struct logger* log = NULL;
- struct senc_device* dev = NULL;
- struct mem_allocator* allocator = NULL;
- res_T res = RES_OK;
- if(nthreads_hint == 0 || !out_dev) return RES_BAD_ARG;
-
- log = logger ? logger : LOGGER_DEFAULT;
- allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
- dev = MEM_CALLOC(allocator, 1, sizeof(struct senc_device));
- if(!dev) {
- if(verbose) {
- /* Do not use helper log functions since dev is not initialised */
- CHK(logger_print(log, LOG_ERROR,
- "%s: could not allocate the StarEnclosures device.\n", FUNC_NAME) == RES_OK);
- }
- res = RES_MEM_ERR;
- goto error;
- }
- dev->logger = log;
- dev->allocator = allocator;
- dev->verbose = verbose;
- /* Cannot use int args for MMIN here as default is -1 */
- dev->nthreads = (int)MMIN(nthreads_hint, (unsigned)omp_get_num_procs());
- ref_init(&dev->ref);
-
-exit:
- if(dev) *out_dev = dev;
- return res;
-error:
- if(dev) {
- SENC(device_ref_put(dev));
- dev = NULL;
- }
- goto exit;
-}
-
-res_T
-senc_device_ref_get(struct senc_device* dev)
-{
- if(!dev) return RES_BAD_ARG;
- ref_get(&dev->ref);
- return RES_OK;
-}
-
-res_T
-senc_device_ref_put(struct senc_device* dev)
-{
- if(!dev) return RES_BAD_ARG;
- ref_put(&dev->ref, device_release);
- return RES_OK;
-}
diff --git a/src/senc_device_c.h b/src/senc_device_c.h
@@ -1,71 +0,0 @@
-/* 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
- * 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_DEVICE_C_H
-#define SENC_DEVICE_C_H
-
-#include <rsys/free_list.h>
-#include <rsys/ref_count.h>
-
-struct name { FITEM; };
-#define FITEM_TYPE name
-#include <rsys/free_list.h>
-
-struct senc_device {
- struct logger* logger;
- struct mem_allocator* allocator;
- int verbose;
- int nthreads;
-
- ref_T ref;
-};
-
-/* Conditionally log a message on the LOG_ERROR stream of the device logger,
- * with respect to the device verbose flag */
-extern LOCAL_SYM void
-log_err
- (struct senc_device* dev,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
-;
-
-/* Conditionally log a message on the LOG_WARNING stream of the device logger,
- * with respect to the device verbose flag */
-extern LOCAL_SYM void
-log_warn
- (struct senc_device* dev,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
-;
-
-/* Conditionally log a message on the LOG_OUTPUT stream of the device logger,
- * with respect to the device verbose flag */
-extern LOCAL_SYM void
-log_info
- (struct senc_device* dev,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
- ;
-
-#endif /* SENC_DEVICE_C_H */
diff --git a/src/senc_enclosure.c b/src/senc_enclosure.c
@@ -1,167 +0,0 @@
-/* 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
-* 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 "senc_enclosure_c.h"
-#include "senc_enclosure_data.h"
-#include "senc_scene_c.h"
-#include "senc_device_c.h"
-#include "senc.h"
-
-#include <rsys/rsys.h>
-#include <rsys/double3.h>
-#include <rsys/mem_allocator.h>
-
-
-/*******************************************************************************
- * Helper function
- ******************************************************************************/
-static void
-enclosure_release(ref_T * ref)
-{
- struct senc_enclosure* enclosure = NULL;
- struct senc_scene* scn = NULL;
- ASSERT(ref);
- enclosure = CONTAINER_OF(ref, struct senc_enclosure, ref);
- scn = enclosure->scene;
- MEM_RM(scn->dev->allocator, enclosure);
- SENC(scene_ref_put(scn));
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-struct senc_enclosure*
-enclosure_create
- (struct senc_scene* scn,
- const unsigned idx)
-{
- struct senc_enclosure* enc;
- ASSERT(scn && idx < darray_enclosure_size_get(&scn->analyze.enclosures));
- enc = MEM_CALLOC(scn->dev->allocator, 1, sizeof(struct senc_enclosure));
- if(enc) {
- const struct enclosure_data* data
- = darray_enclosure_data_get(&scn->analyze.enclosures) + idx;
- enc->scene = scn;
- enc->data = data;
- ref_init(&enc->ref);
- SENC(scene_ref_get(scn));
- }
- return enc;
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-senc_enclosure_get_header
- (const struct senc_enclosure* enclosure,
- struct senc_enclosure_header* header)
-{
- if(!enclosure || !header) return RES_BAD_ARG;
- *header = enclosure->data->header;
- return RES_OK;
-}
-
-res_T
-senc_enclosure_get_triangle
- (const struct senc_enclosure* enclosure,
- const unsigned itri,
- unsigned indices[3])
-{
- const struct side_enc* side;
- int i;
- if(!enclosure || !indices
- || itri >= enclosure->data->header.primitives_count)
- return RES_BAD_ARG;
- ASSERT(darray_sides_enc_size_get(&enclosure->data->sides)
- == enclosure->data->header.primitives_count);
- side = darray_sides_enc_cdata_get(&enclosure->data->sides) + itri;
- FOR_EACH(i, 0, 3) {
- ASSERT(side->vertice_id[i] < UINT_MAX);
- indices[i] = (unsigned)side->vertice_id[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc_enclosure_get_vertex
- (const struct senc_enclosure* enclosure,
- const unsigned ivert,
- double coord[3])
-{
- if(!enclosure || !coord
- || ivert >= enclosure->data->header.vertices_count) {
- return RES_BAD_ARG;
- } else {
- const vrtx_id_t idx
- = darray_vrtx_id_cdata_get(&enclosure->data->vertices)[ivert];
- const union double3* positions
- = darray_position_cdata_get(&enclosure->scene->vertices);
- ASSERT(darray_vrtx_id_size_get(&enclosure->data->vertices)
- == enclosure->data->header.vertices_count);
- d3_set(coord, positions[idx].vec);
- return RES_OK;
- }
-}
-
-res_T
-senc_enclosure_get_triangle_id
- (const struct senc_enclosure* enclosure,
- const unsigned itri,
- unsigned* gid,
- enum senc_side* sde)
-{
- const struct side_enc* side;
- if(!enclosure || !gid || !sde
- || itri >= enclosure->data->header.primitives_count)
- return RES_BAD_ARG;
- ASSERT(darray_sides_enc_size_get(&enclosure->data->sides)
- == enclosure->data->header.primitives_count);
- side = darray_sides_enc_cdata_get(&enclosure->data->sides) + itri;
- *gid = (unsigned)TRGSIDE_2_TRG(side->side_id);
- *sde = TRGSIDE_2_SIDE(side->side_id);
- return RES_OK;
-}
-
-res_T
-senc_enclosure_get_medium
- (const struct senc_enclosure* enclosure,
- const unsigned imed,
- unsigned* medium)
-{
- if(!enclosure || !medium
- || imed >= enclosure->data->header.enclosed_media_count)
- return RES_BAD_ARG;
- ASSERT(enclosure->data->header.enclosed_media_count
- == darray_media_size_get(&enclosure->data->enclosed_media));
- *medium = darray_media_cdata_get(&enclosure->data->enclosed_media)[imed];
- return RES_OK;
-}
-
-res_T
-senc_enclosure_ref_get(struct senc_enclosure* enc)
-{
- if(!enc) return RES_BAD_ARG;
- ref_get(&enc->ref);
- return RES_OK;
-}
-
-res_T
-senc_enclosure_ref_put(struct senc_enclosure* enc)
-{
- if(!enc) return RES_BAD_ARG;
- ref_put(&enc->ref, enclosure_release);
- return RES_OK;
-}
diff --git a/src/senc_enclosure_c.h b/src/senc_enclosure_c.h
@@ -1,37 +0,0 @@
-/* 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
-* 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_ENCLOSURE_C_H
-#define SENC_ENCLOSURE_C_H
-
-#include <rsys/ref_count.h>
-
-#include "senc.h"
-
-struct enclosure_data;
-struct senc_scene;
-
-struct senc_enclosure {
- const struct enclosure_data* data;
- struct senc_scene* scene;
- ref_T ref;
-};
-
-struct senc_enclosure*
-enclosure_create
- (struct senc_scene* scene,
- const unsigned idx);
-
-#endif /* SENC_ENCLOSURE_C_H */
diff --git a/src/senc_enclosure_data.h b/src/senc_enclosure_data.h
@@ -1,235 +0,0 @@
-/* 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
-* 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_ENCLOSURE_DATA_H
-#define SENC_ENCLOSURE_DATA_H
-
-#include "senc.h"
-#include "senc_internal_types.h"
-#include "senc_side_range.h"
-
-#include <rsys/rsys.h>
-#include <rsys/ref_count.h>
-#include <rsys/hash_table.h>
-#include <rsys/dynamic_array.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[3];
- side_id_t side_id;
-};
-
-#define DARRAY_NAME sides_enc
-#define DARRAY_DATA struct side_enc
-#include <rsys/dynamic_array.h>
-
-/* unsigned char array with init to zero */
-static FINLINE void
-zero_init_uchar
- (struct mem_allocator* alloc, unsigned char* data)
-{
- ASSERT(data); (void) alloc;
- *data = 0;
-}
-#define DARRAY_FUNCTOR_INIT zero_init_uchar
-#include <rsys/dynamic_array_uchar.h>
-
-static void
-init_header(struct senc_enclosure_header* header)
-{
- ASSERT(header);
- header->enclosure_id = ENCLOSURE_NULL__;
- header->primitives_count = 0;
- header->unique_primitives_count = 0;
- header->vertices_count = 0;
- header->enclosed_media_count = 0;
- header->is_infinite = CHAR_MAX;
-}
-
-#define DARRAY_NAME media
-#define DARRAY_DATA medium_id_t
-#include <rsys/dynamic_array.h>
-
-static FINLINE res_T
-bool_array_of_media_merge
- (struct darray_uchar* dst,
- const unsigned char* src,
- const medium_id_t sz)
-{
- res_T res = RES_OK;
- medium_id_t i;
- unsigned char* data_dst;
-
- ASSERT(src && dst);
-
- OK(darray_uchar_resize(dst, sz));
- data_dst = darray_uchar_data_get(dst);
- ASSERT(sz <= MEDIUM_MAX__);
- if(res != RES_OK) goto error;
- FOR_EACH(i, 0, sz) {
- if(!src[i]) continue;
- data_dst[i] = 1;
- }
-end:
- return res;
-error:
- goto end;
-}
-
-static FINLINE res_T
-bool_array_of_media_to_darray_media
- (struct darray_media* dst,
- const struct darray_uchar* src,
- const medium_id_t next_medium_idx)
-{
- res_T res = RES_OK;
- unsigned m_idx;
- const unsigned char* data;
-
- ASSERT(src && dst);
-
- data = darray_uchar_cdata_get(src);
- 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(m_idx, 0, next_medium_idx + 1) {
- medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC_UNSPECIFIED_MEDIUM;
- if(!data[m_idx]) continue;
- res = darray_media_push_back(dst, &medium);
- if(res != RES_OK) goto error;
- }
-end:
- return res;
-error:
- goto end;
-}
-
-struct enclosure_data {
- struct senc_enclosure_header header;
- /* Same triangle can appear twice if both sides */
- struct darray_sides_enc sides;
- /* Index of vertices in scene's unique vertices */
- struct darray_vrtx_id vertices;
- /* List of the enclosed media */
- struct darray_uchar tmp_enclosed_media;
- struct darray_media enclosed_media;
- /* Number of components involved in this enclosure */
- component_id_t cc_count;
- /* Linked list of the components */
- component_id_t first_component;
- /* Range of triangles member of the enclosure */
- struct side_range side_range;
- /* Counts */
- side_id_t side_count;
-};
-
-static FINLINE void
-enclosure_data_init(struct mem_allocator* alloc, struct enclosure_data* enc) {
- ASSERT(enc);
- init_header(&enc->header);
- enc->cc_count = 0;
- enc->first_component = COMPONENT_NULL__;
- enc->side_range.first = SIDE_NULL__;
- enc->side_range.last = 0;
- enc->side_count = 0;
- darray_sides_enc_init(alloc, &enc->sides);
- darray_vrtx_id_init(alloc, &enc->vertices);
- darray_uchar_init(alloc, &enc->tmp_enclosed_media);
- darray_media_init(alloc, &enc->enclosed_media);
-}
-
-static FINLINE res_T
-enclosure_data_copy
- (struct enclosure_data* dst,
- const struct enclosure_data* src)
-{
- res_T res = RES_OK;
- ASSERT(src && dst);
- dst->header = src->header;
- dst->cc_count = src->cc_count;
- dst->first_component = src->first_component;
- dst->side_range = src->side_range;
- dst->side_count = src->side_count;
- OK(darray_sides_enc_copy(&dst->sides, &src->sides));
- OK(darray_vrtx_id_copy(&dst->vertices, &src->vertices));
- OK(darray_uchar_copy(&dst->tmp_enclosed_media, &src->tmp_enclosed_media));
- OK(darray_media_copy(&dst->enclosed_media, &src->enclosed_media));
-error:
- return res;
-}
-
-static FINLINE void
-enclosure_data_release(struct enclosure_data* n) {
- ASSERT(n);
- darray_sides_enc_release(&n->sides);
- darray_vrtx_id_release(&n->vertices);
- darray_uchar_release(&n->tmp_enclosed_media);
- darray_media_release(&n->enclosed_media);
-}
-
-static FINLINE res_T
-enclosure_data_copy_and_release
- (struct enclosure_data* dst,
- struct enclosure_data* src)
-{
- res_T res = RES_OK;
- ASSERT(src && dst);
- dst->header = src->header;
- dst->cc_count = src->cc_count;
- dst->first_component = src->first_component;
- dst->side_range = src->side_range;
- dst->side_count = src->side_count;
- OK(darray_sides_enc_copy_and_release(&dst->sides, &src->sides));
- OK(darray_vrtx_id_copy_and_release(&dst->vertices, &src->vertices));
- OK(darray_uchar_copy_and_release(&dst->tmp_enclosed_media,
- &src->tmp_enclosed_media));
- OK(darray_media_copy_and_release(&dst->enclosed_media, &src->enclosed_media));
-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 /* SENC_ENCLOSURE_DATA_H */
diff --git a/src/senc_internal_types.h b/src/senc_internal_types.h
@@ -1,142 +0,0 @@
-/* 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
-* 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_INTERNAL_TYPES_H
-#define SENC_INTERNAL_TYPES_H
-
-#include "senc.h"
-
-#include <rsys/math.h>
-
-#include <stdio.h>
-#include <stdint.h>
-
-/* Utility macros */
-#ifdef NDEBUG
-#define OK2(Expr)\
- if((tmp_res = (Expr)) != RES_OK) goto tmp_error;
-
-#define OK(Expr)\
- if((res = (Expr)) != RES_OK) goto error;
-#else
-#define OK2(Expr)\
- if((tmp_res = (Expr)) != RES_OK) {\
- fprintf(stderr, "%s: error code set to %d at line %d\n", FUNC_NAME,\
- tmp_res, __LINE__);\
- goto tmp_error;\
- }
-
-#define OK(Expr)\
- if((res = (Expr)) != RES_OK) {\
- fprintf(stderr, "%s: error code set to %d at line %d\n", FUNC_NAME,\
- res, __LINE__);\
- goto error;\
- }
-#endif
-
-/* Side IDs are uint32_t */
-typedef uint32_t side_id_t;
-#define SIDE_MAX__ (UINT32_MAX-1)
-#define SIDE_NULL__ UINT32_MAX
-
-/* Trg IDs use internally side_id_t */
-/* Cannot be larger than unsigned, as the API uses it. */
-typedef side_id_t trg_id_t;
-/* TRG_MAX__ is limited to allow to count sides */
-#define TRG_MAX__ (SIDE_MAX__ / 2)
-#define TRG_NULL__ UINT32_MAX
-
-/* Vertex IDs are internally uint32_t */
-/* Cannot be larger than unsigned, as the API uses it. */
-typedef uint32_t vrtx_id_t;
-#define VRTX_MAX__ (UINT32_MAX-1)
-#define VRTX_NULL__ UINT32_MAX
-
-/* Edge IDs use the same type than vertex IDs */
-/* Cannot be larger than unsigned, as the API uses it. */
-typedef vrtx_id_t edge_id_t;
-#define EDGE_MAX__ VRTX_MAX__
-#define EDGE_NULL__ VRTX_NULL__
-
-/* Medium IDs are internally uint32_t */
-/* Should nnot be larger than unsigned, as the API uses it. */
-typedef uint32_t medium_id_t;
-#define MEDIUM_MAX__ INT32_MAX
-#define MEDIUM_NULL__ UINT32_MAX
-
-/* Enclosure IDs are internally uint32_t */
-/* Cannot be larger than unsigned, as the API uses it. */
-typedef uint32_t enclosure_id_t;
-#define ENCLOSURE_MAX__ UINT32_MAX
-#define ENCLOSURE_NULL__ UINT32_MAX
-
-/* Component IDs use the same type than enclosure IDs */
-typedef enclosure_id_t component_id_t;
-#define COMPONENT_MAX__ (UINT32_MAX - 2) /* To allow special values */
-#define COMPONENT_NULL__ UINT32_MAX
-/* Special values */
-#define CC_GROUP_ROOT_NONE UINT32_MAX
-#define CC_GROUP_ROOT_INFINITE (UINT32_MAX - 1)
-#define CC_GROUP_ID_NONE UINT32_MAX
-#define CC_ID_NONE UINT32_MAX
-
-/* This one is used as flag */
-enum side_flag {
- FLAG_FRONT = BIT(0),
- FLAG_BACK = BIT(1)
-};
-
-/* Utility macros */
-static FINLINE trg_id_t
-TRGSIDE_2_TRG(side_id_t s) {
- ASSERT(((size_t)s >> 1) <= TRG_MAX__);
- return s >> 1;
-}
-
-static FINLINE int
-TRGSIDE_IS_FRONT(side_id_t s) {
- return (s & 1) == 0;
-}
-
-static FINLINE enum senc_side
-TRGSIDE_2_SIDE(side_id_t s) {
- return (s & 1) ? SENC_BACK : SENC_FRONT;
-}
-
-static FINLINE enum side_flag
-TRGSIDE_2_SIDEFLAG(side_id_t s) {
- return (s & 1) ? FLAG_BACK : FLAG_FRONT;
-}
-
-static FINLINE unsigned char
-SIDE_CANCELED_FLAG(enum side_flag f) {
- ASSERT((f << 4) <= UCHAR_MAX);
- return (unsigned char)(f << 4);
-}
-
-static FINLINE side_id_t
-TRGIDxSIDE_2_TRGSIDE(trg_id_t t, enum senc_side i) {
- ASSERT((((size_t)t << 1) | (i == SENC_BACK)) < SIDE_MAX__);
- ASSERT(i == SENC_FRONT || i == SENC_BACK);
- return (side_id_t)((t << 1) | (i == SENC_BACK));
-}
-
-static FINLINE side_id_t
-TRGSIDE_OPPOSITE(side_id_t s) {
- return TRGIDxSIDE_2_TRGSIDE(TRGSIDE_2_TRG(s),
- TRGSIDE_IS_FRONT(s) ? SENC_BACK : SENC_FRONT);
-}
-
-#endif /* SENC_INTERNAL_TYPES_H */
diff --git a/src/senc_s3d_helper.h b/src/senc_s3d_helper.h
@@ -1,92 +0,0 @@
-/* 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
-* 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_S3D_WRAPPER_H
-#define SENC_S3D_WRAPPER_H
-
-#include "senc.h"
-
-#include <rsys/rsys.h>
-#include <rsys/float3.h>
-
-/* Get vertex indices for the itri_th triangle.
- * Suitable for use as get_indice callback in s3d_mesh_setup_indexed_vertices
- * calls. */
-static FINLINE void
-senc_s3d_scene_get_indices__
- (const unsigned itri,
- unsigned indices[3],
- void* ctx)
-{
- const struct senc_scene* scene = ctx;
- res_T r;
- ASSERT(indices && scene);
- r = senc_scene_get_triangle(scene, itri, indices);
- ASSERT(r == RES_OK); (void)r;
-}
-
-/* Get coordinates for the ivert_th vertex.
- * Suitable for use as s3d_vertex_data getter for S3D_POSITION s3d_attrib_usage
- * in s3d_mesh_setup_indexed_vertices calls. */
-static FINLINE void
-senc_s3d_scene_get_position__
- (const unsigned ivert,
- float coord[3],
- void* ctx)
-{
- const struct senc_scene* scene = ctx;
- double tmp[3];
- res_T r;
- ASSERT(coord && scene);
- r = senc_scene_get_vertex(scene, ivert, tmp);
- ASSERT(r == RES_OK); (void)r;
- f3_set_d3(coord, tmp);
-}
-
-/* Get vertex indices for the itri_th triangle of the enclosure.
- * Suitable for use as get_indice callback in s3d_mesh_setup_indexed_vertices
- * calls. */
-static FINLINE void
-senc_s3d_enclosure_get_indices__
- (const unsigned itri,
- unsigned indices[3],
- void* ctx)
-{
- const struct senc_enclosure* enclosure = ctx;
- res_T r;
- ASSERT(indices && ctx);
- r = senc_enclosure_get_triangle(enclosure, itri, indices);
- ASSERT(r == RES_OK); (void)r;
-}
-
-/* Get coordinates for the ivert_th vertex of the enclosure.
- * Suitable for use as s3d_vertex_data getter for S3D_POSITION s3d_attrib_usage
- * in s3d_mesh_setup_indexed_vertices calls. */
-static FINLINE void
-senc_s3d_enclosure_get_position__
- (const unsigned ivert,
- float coord[3],
- void* ctx)
-{
- const struct senc_enclosure* enclosure = ctx;
- double tmp[3];
- res_T r;
- ASSERT(coord && ctx);
- r = senc_enclosure_get_vertex(enclosure, ivert, tmp);
- ASSERT(r == RES_OK); (void)r;
- f3_set_d3(coord, tmp);
-}
-
-#endif /* SENC_S3D_WRAPPER_H */
diff --git a/src/senc_scene.c b/src/senc_scene.c
@@ -1,327 +0,0 @@
-/* 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
- * 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 "senc.h"
-#include "senc_device_c.h"
-#include "senc_scene_c.h"
-#include "senc_scene_analyze_c.h"
-
-#include <rsys/rsys.h>
-#include <rsys/double3.h>
-#include <rsys/mem_allocator.h>
-
-#include <limits.h>
-
-/*******************************************************************************
- * Helper function
- ******************************************************************************/
-static void
-scene_release(ref_T * ref)
-{
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- ASSERT(ref);
- scn = CONTAINER_OF(ref, struct senc_scene, ref);
- dev = scn->dev;
- darray_triangle_in_release(&scn->triangles_in);
- darray_position_release(&scn->vertices);
- darray_side_range_release(&scn->media_use);
-
- darray_triangle_enc_release(&scn->analyze.triangles_enc);
- darray_enclosure_release(&scn->analyze.enclosures);
- darray_enc_ids_array_release(&scn->analyze.enc_ids_array_by_medium);
- darray_frontier_edge_release(&scn->analyze.frontiers);
-
- MEM_RM(dev->allocator, scn);
- SENC(device_ref_put(dev));
-}
-
-static INLINE int
-compatible_medium
- (const medium_id_t m1,
- const medium_id_t m2)
-{
- if(m1 == SENC_UNSPECIFIED_MEDIUM || m2 == SENC_UNSPECIFIED_MEDIUM) return 1;
- return (m1 == m2);
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-senc_scene_create
- (struct senc_device* dev,
- const int conv,
- const unsigned ntris,
- 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 senc_scene** out_scn)
-{
- struct senc_scene* scn = NULL;
- /* Tables to detect duplicates */
- struct htable_vrtx unique_vertices;
- struct htable_trg unique_triangles;
- unsigned i;
- res_T res = RES_OK;
-
- if(!dev || !out_scn || !indices || !position
- /* Convention must be set both regarding FRONT/BACK and INSIDE/OUTSIDE */
- || !(conv & (SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_BACK))
- || !(conv & (SENC_CONVENTION_NORMAL_INSIDE | SENC_CONVENTION_NORMAL_OUTSIDE)))
- return RES_BAD_ARG;
-
- scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct senc_scene));
- if(!scn) {
- log_err(dev, "%s: could not allocate the StarEnclosures scene.\n", FUNC_NAME);
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&scn->ref);
- SENC(device_ref_get(dev));
- scn->dev = dev;
- scn->convention = conv;
- scn->ntris = ntris;
- scn->next_medium_idx = 0;
- scn->nverts = nverts;
- darray_triangle_in_init(dev->allocator, &scn->triangles_in);
- darray_position_init(dev->allocator, &scn->vertices);
- htable_vrtx_init(dev->allocator, &unique_vertices);
- htable_trg_init(dev->allocator, &unique_triangles);
- darray_side_range_init(dev->allocator, &scn->media_use);
-
- darray_triangle_enc_init(scn->dev->allocator, &scn->analyze.triangles_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_frontier_edge_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 || !ntris) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- OK(darray_position_reserve(&scn->vertices, scn->nverts));
- OK(darray_triangle_in_reserve(&scn->triangles_in, scn->ntris));
- OK(htable_vrtx_reserve(&unique_vertices, scn->nverts));
- OK(htable_trg_reserve(&unique_triangles, scn->ntris));
-
- /* Get vertices */
- FOR_EACH(i, 0, nverts) {
- vrtx_id_t* p_vrtx;
- union double3 tmp;
- /* API: position needs an unsigned */
- position(i, tmp.vec, ctx);
- p_vrtx = htable_vrtx_find(&unique_vertices, &tmp);
- if(p_vrtx) {
- /* Duplicate vertex */
- log_err(scn->dev, "%s: vertex %u is a duplicate.\n",
- FUNC_NAME, i);
- res = RES_BAD_ARG;
- goto error;
- }
- /* 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 triangles */
- FOR_EACH(i, 0, ntris) {
- int j;
- unsigned med[2] = { SENC_UNSPECIFIED_MEDIUM, SENC_UNSPECIFIED_MEDIUM };
- unsigned ind[3];
- union vrtx_id3 trg_key;
- struct triangle_in tmp;
- trg_id_t* p_trg;
- indices(i, ind, ctx); /* API: indices need unsigneds */
- FOR_EACH(j, 0, 3) {
- if(ind[j] >= nverts) {
- log_err(scn->dev, "%s: triangle %u uses invalid vertex id %u.\n",
- FUNC_NAME, i, ind[j]);
- res = RES_BAD_ARG;
- goto error;
- }
- ASSERT(ind[j] <= VRTX_MAX__);
- tmp.vertice_id[j] = (vrtx_id_t)ind[j];
- }
- if(tmp.vertice_id[0] == tmp.vertice_id[1]
- || tmp.vertice_id[0] == tmp.vertice_id[2]
- || tmp.vertice_id[1] == tmp.vertice_id[2])
- {
- log_err(scn->dev, "%s: triangle %u is degenerated.\n",
- FUNC_NAME, i);
- res = RES_BAD_ARG;
- goto error;
- }
- /* Get media */
- if(media) media(i, med, ctx); /* API: media needs an unsigned */
- trg_make_key(&trg_key, tmp.vertice_id);
- p_trg = htable_trg_find(&unique_triangles, &trg_key);
- if(p_trg) {
- /* Duplicate triangle */
- log_err(scn->dev, "%s: triangle %u is a duplicate.\n",
- FUNC_NAME, i);
- res = RES_BAD_ARG;
- goto error;
- }
- /* New triangle */
- ASSERT(i == htable_trg_size_get(&unique_triangles));
- OK(htable_trg_set(&unique_triangles, &trg_key, &i));
- FOR_EACH(j, 0, 2) {
- struct side_range* media_use;
- unsigned m_idx = (med[j] == SENC_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 SENC_UNSPECIFIED_MEDIUM */
- media_use = darray_side_range_data_get(&scn->media_use) + m_idx;
- media_use->first =
- MMIN(media_use->first, TRGIDxSIDE_2_TRGSIDE((trg_id_t)i, j));
- ASSERT(media_use->first < 2 * (scn->ntris + 1));
- media_use->last =
- MMAX(media_use->last, TRGIDxSIDE_2_TRGSIDE((trg_id_t)i, j));
- ASSERT(media_use->last < 2 * (scn->ntris + 1));
- ASSERT(media_use->first <= media_use->last);
- }
- OK(darray_triangle_in_push_back(&scn->triangles_in, &tmp));
- }
-
- OK(darray_enc_ids_array_resize(&scn->analyze.enc_ids_array_by_medium,
- 1 + scn->next_medium_idx)); /* +1 is for unspecified */
- /* Proceed to the analyze */
- OK(scene_analyze(scn));
-
-exit:
- htable_vrtx_release(&unique_vertices);
- htable_trg_release(&unique_triangles);
- if(scn) *out_scn = scn;
- return res;
-
-error:
- if(scn) {
- SENC(scene_ref_put(scn));
- scn = NULL;
- }
- goto exit;
-}
-
-res_T
-senc_scene_get_convention
- (const struct senc_scene* scn,
- int* convention)
-{
- if(!scn || !convention) return RES_BAD_ARG;
- *convention = scn->convention;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_triangles_count
- (const struct senc_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- *count = scn->ntris;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_triangle
- (const struct senc_scene* scn,
- const unsigned itri,
- unsigned indices[3])
-{
- const struct triangle_in* trg;
- int i;
- if(!scn || !indices
- || itri >= darray_triangle_in_size_get(&scn->triangles_in))
- return RES_BAD_ARG;
- trg = darray_triangle_in_cdata_get(&scn->triangles_in) + itri;
-
- FOR_EACH(i, 0, 3) {
- ASSERT(trg->vertice_id[i] < UINT_MAX);
- indices[i] = (unsigned)trg->vertice_id[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc_scene_get_triangle_media
- (const struct senc_scene* scn,
- const unsigned itri,
- unsigned media[2])
-{
- const struct triangle_in* trg;
- int i;
- if(!scn || !media
- || itri >= darray_triangle_in_size_get(&scn->triangles_in))
- return RES_BAD_ARG;
- trg = darray_triangle_in_cdata_get(&scn->triangles_in) + itri;
-
- FOR_EACH(i, 0, 2) {
- ASSERT(trg->vertice_id[i] < UINT_MAX);
- media[i] = (unsigned)trg->medium[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc_scene_get_vertices_count
- (const struct senc_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- *count = scn->nverts;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_vertex
- (const struct senc_scene* scn,
- const unsigned ivert,
- double coord[3])
-{
- const union double3* v;
- if(!scn || !coord
- || ivert >= darray_position_size_get(&scn->vertices))
- return RES_BAD_ARG;
-
- v = darray_position_cdata_get(&scn->vertices) + ivert;
- d3_set(coord, v->vec);
- return RES_OK;
-}
-
-res_T
-senc_scene_ref_get(struct senc_scene* scn)
-{
- if(!scn) return RES_BAD_ARG;
- ref_get(&scn->ref);
- return RES_OK;
-}
-
-res_T
-senc_scene_ref_put(struct senc_scene* scn)
-{
- if(!scn) return RES_BAD_ARG;
- ref_put(&scn->ref, scene_release);
- return RES_OK;
-}
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -1,1347 +0,0 @@
-/* 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
- * 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 "senc.h"
-#include "senc_device_c.h"
-#include "senc_scene_c.h"
-#include "senc_scene_analyze_c.h"
-#include "senc_internal_types.h"
-
-#include <rsys/rsys.h>
-#include <rsys/float3.h>
-#include <rsys/double33.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/hash_table.h>
-#include <rsys/dynamic_array.h>
-#include <rsys/dynamic_array_uchar.h>
-#include <rsys/clock_time.h>
-
-#include <star/s3d.h>
-
-#include <omp.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#define CC_DESCRIPTOR_NULL__ {\
- CHAR_MAX, VRTX_NULL__, 0,\
- CC_ID_NONE, CC_GROUP_ROOT_NONE, ENCLOSURE_NULL__,\
- { TRG_NULL__, 0},\
- NULL\
-}
-#ifdef COMPILER_GCC
- #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
-#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)
-{
- const double a1 = ((struct neighbour_info*)w1)->angle;
- const double a2 = ((struct neighbour_info*)w2)->angle;
- return (a1 > a2) - (a1 < a2);
-}
-
-static side_id_t
-get_side_not_in_connex_component
- (const side_id_t last_side,
- const struct trgside* trgsides,
- const unsigned char* processed,
- side_id_t* first_side_not_in_component,
- const medium_id_t medium)
-{
- ASSERT(trgsides && processed && first_side_not_in_component);
- {
- side_id_t i = *first_side_not_in_component;
- while (i <= last_side
- && (trgsides[i].medium != medium
- || (processed[TRGSIDE_2_TRG(i)] & TRGSIDE_2_SIDEFLAG(i))))
- ++i;
-
- *first_side_not_in_component = i + 1;
- if(i > last_side) return SIDE_NULL__;
- return i;
- }
-}
-
-static void
-get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) {
- int i;
- const struct senc_scene* scene = ctx;
- const struct triangle_in* trg =
- darray_triangle_in_cdata_get(&scene->triangles_in) + itri;
- FOR_EACH(i, 0, 3) {
- ASSERT(trg->vertice_id[i] < scene->nverts);
- ids[i] = (unsigned)trg->vertice_id[i]; /* Back to API type */
- }
-}
-
-static void
-get_scn_position(const unsigned ivert, float pos[3], void* ctx) {
- const struct senc_scene* scene = ctx;
- const union double3* pt =
- darray_position_cdata_get(&scene->vertices) + ivert;
- f3_set_d3(pos, pt->vec);
-}
-
-static int
-self_hit_filter
- (const struct s3d_hit* hit,
- const float ray_org[3],
- const float ray_dir[3],
- void* ray_data,
- void* filter_data)
-{
- const struct darray_triangle_comp* triangles_comp = filter_data;
- const component_id_t* origin_component = ray_data;
- const struct triangle_comp* hit_trg_comp;
-
- (void)ray_org; (void)ray_dir;
- ASSERT(hit && triangles_comp && origin_component);
- ASSERT(hit->prim.prim_id < darray_triangle_comp_size_get(triangles_comp));
- hit_trg_comp = darray_triangle_comp_cdata_get(triangles_comp)
- + hit->prim.prim_id;
- return (hit_trg_comp->component[SENC_FRONT] == *origin_component
- || hit_trg_comp->component[SENC_BACK] == *origin_component);
-
-}
-
-static void
-extract_connex_components
- (struct senc_scene* scn,
- struct trgside* trgsides,
- struct darray_ptr_component_descriptor* connex_components,
- const struct darray_triangle_tmp* triangles_tmp_array,
- struct darray_triangle_comp* triangles_comp_array,
- struct s3d_scene_view** s3d_view,
- ATOMIC* component_count,
- /* Shared error status.
- * We accept to overwrite an error with a different error */
- res_T* p_res)
-{
- /* This function is called from an omp parallel block and executed
- * concurrently. */
- struct mem_allocator* alloc;
- int64_t m_idx;
- struct darray_side_id stack;
- struct darray_side_id ids_of_sides_around_max_z_vertex;
- const union double3* positions;
- const struct triangle_tmp* triangles_tmp;
- struct triangle_comp* triangles_comp;
- /* An array to flag sides when processed */
- unsigned char* processed;
- /* An array to store the component being processed */
- struct darray_side_id current_component;
- /* A bool array to store media of the component being processed */
- unsigned char* current_media = NULL;
- size_t sz, ii;
-
- ASSERT(scn && trgsides && connex_components && triangles_tmp_array
- && triangles_comp_array && s3d_view && component_count && p_res);
- alloc = scn->dev->allocator;
- positions = darray_position_cdata_get(&scn->vertices);
- triangles_tmp = darray_triangle_tmp_cdata_get(triangles_tmp_array);
- triangles_comp = darray_triangle_comp_data_get(triangles_comp_array);
- darray_side_id_init(alloc, &stack);
- darray_side_id_init(alloc, &ids_of_sides_around_max_z_vertex);
- darray_side_id_init(alloc, ¤t_component);
- processed = MEM_CALLOC(alloc, scn->ntris, sizeof(unsigned char));
- if(!processed) {
- *p_res = RES_MEM_ERR;
- return;
- }
-
-#ifndef NDEBUG
- #pragma omp single
- {
- trg_id_t t_;
- int s;
- ASSERT(darray_ptr_component_descriptor_size_get(connex_components) == 0);
- FOR_EACH(t_, 0, scn->ntris) {
- const struct triangle_in* trg_in =
- darray_triangle_in_cdata_get(&scn->triangles_in) + t_;
- const struct side_range* media_use
- = darray_side_range_cdata_get(&scn->media_use);
- FOR_EACH(s, 0, 2) {
- const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, s);
- medium_id_t medium = trg_in->medium[s];
- m_idx = (medium == SENC_UNSPECIFIED_MEDIUM) ? 0 : medium + 1;
- ASSERT(media_use[m_idx].first <= side && side
- <= media_use[m_idx].last);
- }
- }
- } /* Implicit barrier here */
-#endif
-
- /* We loop on sides to build connex components. */
- #pragma omp for schedule(dynamic) nowait
- /* Process all media, including unspecified */
- 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) : SENC_UNSPECIFIED_MEDIUM;
- /* media_use 0 is for SENC_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_nz;
- side_id_t max_nz_side_id = SIDE_NULL__;
- const side_id_t last_side = media_use->last;
- int component_canceled = 0;
- res_T tmp_res = RES_OK;
- ATOMIC id;
-
- 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->ntris);
- 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, trgsides, 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_z_vrtx_id = VRTX_NULL__;
- struct cc_descriptor *cc;
- double max_z = -DBL_MAX;
- component_canceled = 0;
- ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->ntris);
- darray_side_id_clear(¤t_component);
-
- if(*p_res != RES_OK) break;
- if(start_side_id == SIDE_NULL__)
- break; /* start_side_id=SIDE_NULL__ => component done! */
-
-#ifndef NDEBUG
- {
- trg_id_t tid = TRGSIDE_2_TRG(start_side_id);
- enum senc_side s = TRGSIDE_2_SIDE(start_side_id);
- medium_id_t side_med
- = darray_triangle_in_data_get(&scn->triangles_in)[tid].medium[s];
- ASSERT(side_med == medium);
- }
-#endif
-
- /* Reuse array if possible, or create a new one */
- if(current_media) {
- /* current_media 0 is for SENC_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(*current_media));
- if(!current_media) {
- *p_res = RES_MEM_ERR;
- continue;
- }
- }
- current_media[m_idx] = 1;
- for(;;) { /* Process all sides of this component */
- int i;
- enum side_flag crt_side_flag = TRGSIDE_2_SIDEFLAG(crt_side_id);
- struct trgside* crt_side = trgsides + crt_side_id;
- const trg_id_t crt_trg_id = TRGSIDE_2_TRG(crt_side_id);
- const struct triangle_in* trg_in =
- darray_triangle_in_cdata_get(&scn->triangles_in) + crt_trg_id;
- unsigned char* trg_used = processed + crt_trg_id;
- const struct triangle_tmp* const trg_tmp = triangles_tmp + crt_trg_id;
- ASSERT(crt_trg_id < scn->ntris);
-
- if(*p_res != RES_OK) break;
-
- /* Record Zmax information
- * Keep track of the appropriate vertex of the 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 Z
- * coordinate. */
- if(max_z < trg_tmp->max_z) {
- /* New best vertex */
- max_z = trg_tmp->max_z;
- /* New vertex: reset list of sides */
- darray_side_id_clear(&ids_of_sides_around_max_z_vertex);
-
- /* Select a vertex with z == max_z */
- FOR_EACH(i, 0, 3) {
- if(max_z == positions[trg_in->vertice_id[i]].pos.z) {
- max_z_vrtx_id = trg_in->vertice_id[i];
- break;
- }
- }
- ASSERT(i < 3); /* Found one */
- /* List of sides using the vertex */
- OK2(darray_side_id_push_back(&ids_of_sides_around_max_z_vertex,
- &crt_side_id));
- } else if(max_z == trg_tmp->max_z) {
- /* Does this triangle use the currently selected max_z vertex? */
- FOR_EACH(i, 0, 3) {
- if(max_z_vrtx_id == trg_in->vertice_id[i]) {
- /* List of sides using the vertex */
- OK2(darray_side_id_push_back(&ids_of_sides_around_max_z_vertex,
- &crt_side_id));
- break;
- }
- }
- }
-
- /* Record crt_side both as component and triangle level */
- if((*trg_used & crt_side_flag) == 0) {
- OK2(darray_side_id_push_back(¤t_component, &crt_side_id));
- *trg_used = *trg_used | (unsigned char)crt_side_flag;
- }
-
- /* Store neighbour's sides in a waiting stack */
- FOR_EACH(i, 0, 3) {
- side_id_t neighbour_id = crt_side->facing_side_id[i];
- trg_id_t nbour_trg_id = TRGSIDE_2_TRG(neighbour_id);
- enum side_flag nbour_side_id = TRGSIDE_2_SIDEFLAG(neighbour_id);
- unsigned char* nbour_used = processed + nbour_trg_id;
- const struct trgside* neighbour = trgsides + neighbour_id;
- medium_id_t nbour_med_idx = (neighbour->medium == SENC_UNSPECIFIED_MEDIUM)
- ? 0 : neighbour->medium + 1;
- if(neighbour->medium < medium
- || (*nbour_used & SIDE_CANCELED_FLAG(nbour_side_id)))
- {
- /* 1) Not the same medium.
- * Neighbour's medium id is less than current medium: the whole
- * component is to be processed by another thread (possibly the one
- * 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 */
- component_canceled = 1;
- darray_side_id_clear(&stack);
- /* 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];
- trg_id_t used_trg_id = TRGSIDE_2_TRG(used_side);
- enum side_flag used_side_flag
- = TRGSIDE_2_SIDEFLAG(used_side);
- unsigned char* used = processed + used_trg_id;
- ASSERT(*used & (unsigned char)used_side_flag);
- /* Set the used flag for sides in cancelled component as leading
- * to further cancellations */
- *used |= SIDE_CANCELED_FLAG(used_side_flag);
- }
-
- goto canceled;
- }
- if(*nbour_used & nbour_side_id) continue; /* Already processed */
- /* Mark neighbour as processed and stack it */
- *nbour_used |= (unsigned char)nbour_side_id;
- OK2(darray_side_id_push_back(&stack, &neighbour_id));
- OK2(darray_side_id_push_back(¤t_component, &neighbour_id));
- current_media[nbour_med_idx] = 1;
- }
- sz = darray_side_id_size_get(&stack);
- if(sz == 0) break; /* Empty stack => component is done! */
- crt_side_id = darray_side_id_cdata_get(&stack)[sz - 1];
- darray_side_id_pop_back(&stack);
- last_side_id = MMAX(last_side_id, crt_side_id);
- }
- canceled:
- if(component_canceled) continue;
-
- /* Register the new component and get it initialized */
- cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
- if(!cc) *p_res = RES_MEM_ERR;
- if(*p_res != RES_OK) break;
-
- ASSERT(medium == trgsides[start_side_id].medium);
- ASSERT(max_z_vrtx_id != VRTX_NULL__);
- cc_descriptor_init(alloc, cc);
- id = ATOMIC_INCR(component_count) - 1;
- ASSERT(id <= COMPONENT_MAX__);
- cc->cc_id = (component_id_t)id;
- sz = darray_side_id_size_get(¤t_component);
- ASSERT(sz <= SIDE_MAX__);
- cc->side_count = (side_id_t)sz;
- cc->side_range.first = start_side_id;
- cc->side_range.last = last_side_id;
- cc->max_z_vrtx_id = max_z_vrtx_id;
- /* Tranfer ownership of the array to component */
- ASSERT(!cc->media && current_media);
- cc->media = current_media;
- current_media = NULL;
-
- /* Write component membership in the global structure
- * No need for sync here as an unique thread writes a given side */
- {STATIC_ASSERT(sizeof(cc->cc_id) >= 4, Cannot_write_IDs_sync_free);}
- ASSERT(IS_ALIGNED(triangles_comp->component, sizeof(cc->cc_id)));
- FOR_EACH(ii, 0, sz) {
- const side_id_t s = darray_side_id_cdata_get(¤t_component)[ii];
- trg_id_t tid = TRGSIDE_2_TRG(s);
- enum senc_side sid = TRGSIDE_2_SIDE(s);
- component_id_t* cmp = triangles_comp[tid].component;
- ASSERT(cmp[sid] == COMPONENT_NULL__);
- ASSERT(trgsides[s].medium >= medium);
- cmp[sid] = cc->cc_id;
- }
-
- /* Compute the normal at the max_z vertex. */
- max_nz = 0;
- sz = darray_side_id_size_get(&ids_of_sides_around_max_z_vertex);
- ASSERT(sz > 0);
- FOR_EACH(ii, 0, sz) {
- const side_id_t side_id =
- darray_side_id_cdata_get(&ids_of_sides_around_max_z_vertex)[ii];
- const trg_id_t trg_id = TRGSIDE_2_TRG(side_id);
- enum senc_side s = TRGSIDE_2_SIDE(side_id);
- const struct triangle_in* trg_in =
- darray_triangle_in_cdata_get(&scn->triangles_in) + trg_id;
- const struct triangle_comp* trg_comp = triangles_comp + trg_id;
- const union double3* vertices =
- darray_position_cdata_get(&scn->vertices);
- double edge0[3], edge1[3], normal[3], norm;
-
- /* To ensure that triangles with 2 sides in the component total to 0
- * regardless of numeric accuracy, we need to prevent them to
- * contribute (remember than x + y - y == x can be false). */
- ASSERT(trg_comp->component[s] == cc->cc_id); (void)s;
- if(trg_comp->component[SENC_FRONT] == trg_comp->component[SENC_BACK])
- continue;
-
- d3_sub(edge0, vertices[trg_in->vertice_id[1]].vec,
- vertices[trg_in->vertice_id[0]].vec);
- d3_sub(edge1, vertices[trg_in->vertice_id[2]].vec,
- vertices[trg_in->vertice_id[0]].vec);
- d3_cross(normal, edge0, edge1);
- norm = d3_normalize(normal, normal);
- ASSERT(norm); (void)norm;
-
- if(fabs(max_nz) < fabs(normal[2])) {
- max_nz_side_id = side_id;
- max_nz = normal[2];
- }
- }
- if(max_nz == 0) cc->is_outer_border = 0;
- else {
- if(TRGSIDE_IS_FRONT(max_nz_side_id)
- == ((scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0)) {
- /* Geom normal points towards the component */
- cc->is_outer_border = (max_nz < 0);
- } else {
- /* Geom normal points away from the component */
- cc->is_outer_border = (max_nz > 0);
- }
- }
-
- /* Need to synchronize connex_components growth as this global structure
- * is accessed by multipe threads */
- #pragma omp critical
- {
- struct cc_descriptor** components;
- sz = darray_ptr_component_descriptor_size_get(connex_components);
- if(sz <= cc->cc_id) {
- tmp_res = darray_ptr_component_descriptor_resize(connex_components,
- 1 + cc->cc_id);
- if(tmp_res != RES_OK) *p_res = tmp_res;
- }
- if(*p_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;
- }
- }
- }
- tmp_error:
- if(tmp_res != RES_OK) *p_res = tmp_res;
- } /* No barrier here */
-
- MEM_RM(alloc, processed);
- MEM_RM(alloc, current_media);
- darray_side_id_release(¤t_component);
- darray_side_id_release(&stack);
- darray_side_id_release(&ids_of_sides_around_max_z_vertex);
-
- /* The first thread here creates the s3d view */
- #pragma omp single nowait
- if(*p_res == RES_OK) {
- res_T res = RES_OK;
- struct s3d_device* s3d = NULL;
- struct s3d_scene* s3d_scn = NULL;
- struct s3d_shape* s3d_shp = NULL;
- struct s3d_vertex_data attribs;
-
- attribs.type = S3D_FLOAT3;
- attribs.usage = S3D_POSITION;
- attribs.get = get_scn_position;
-
- /* Put geometry in a 3D view */
- OK(s3d_device_create(scn->dev->logger, alloc, 0, &s3d));
- OK(s3d_scene_create(s3d, &s3d_scn));
- OK(s3d_shape_create_mesh(s3d, &s3d_shp));
-
- /* Back to API type for ntris and nverts */
- ASSERT(scn->ntris < UINT_MAX);
- ASSERT(scn->nverts < UINT_MAX);
- OK(s3d_mesh_setup_indexed_vertices(s3d_shp,
- (unsigned)scn->ntris, get_scn_indices,
- (unsigned)scn->nverts, &attribs, 1, scn));
- s3d_mesh_set_hit_filter_function(s3d_shp, self_hit_filter,
- triangles_comp_array);
- OK(s3d_scene_attach_shape(s3d_scn, s3d_shp));
- OK(s3d_scene_view_create(s3d_scn, S3D_TRACE, s3d_view));
- error:
- if(res != RES_OK) *p_res = res;
- if(s3d) S3D(device_ref_put(s3d));
- if(s3d_scn) S3D(scene_ref_put(s3d_scn));
- if(s3d_shp) S3D(shape_ref_put(s3d_shp));
- }
-
-#ifndef NDEBUG
- /* Need to wait for all threads done to be able to check stuff */
- #pragma omp barrier
- if(*p_res != RES_OK) return;
- #pragma omp single
- {
- trg_id_t t_;
- component_id_t c;
- ASSERT(ATOMIC_GET(component_count) ==
- (int)darray_ptr_component_descriptor_size_get(connex_components));
- FOR_EACH(t_, 0, scn->ntris) {
- struct triangle_comp* trg_comp =
- darray_triangle_comp_data_get(triangles_comp_array) + t_;
- ASSERT(trg_comp->component[SENC_FRONT] != COMPONENT_NULL__);
- ASSERT(trg_comp->component[SENC_BACK] != COMPONENT_NULL__);
- }
- FOR_EACH(c, 0, ATOMIC_GET(component_count)) {
- struct cc_descriptor** components =
- darray_ptr_component_descriptor_data_get(connex_components);
- ASSERT(components[c] != NULL && components[c]->cc_id == c);
- }
- } /* Implicit barrier here */
-#endif
-}
-
-static void
-group_connex_components
- (struct senc_scene* scn,
- struct trgside* trgsides,
- struct darray_triangle_comp* triangles_comp,
- struct darray_ptr_component_descriptor* connex_components,
- struct s3d_scene_view* s3d_view,
- ATOMIC* next_enclosure_id,
- /* 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. */
- struct cc_descriptor** descriptors;
- const union double3* positions;
- size_t tmp;
- component_id_t cc_count;
- int64_t ccc;
-
- (void)trgsides;
- ASSERT(scn && trgsides && triangles_comp && connex_components
- && s3d_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(&scn->vertices);
-
- /* Cast rays to find links between connex components */
- #pragma omp for
- for(ccc = 0; ccc < (int64_t)cc_count; ccc++) {
- res_T tmp_res = RES_OK;
- component_id_t c = (component_id_t)ccc;
- struct s3d_hit hit = S3D_HIT_NULL;
- float origin[3];
- const float dir[3] = { 0, 0, 1 };
- const float range[2] = { 0, FLT_MAX };
- struct cc_descriptor* const cc = descriptors[c];
- component_id_t self_hit_component = cc->cc_id;
- const double* max_vrtx;
-
- if(*res != RES_OK) continue;
- ASSERT(cc->cc_id == c);
- ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
- ASSERT(cc->max_z_vrtx_id < scn->nverts);
-
- max_vrtx = positions[cc->max_z_vrtx_id].vec;
- if(cc->is_outer_border) {
- ATOMIC 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;
- }
-
- f3_set_d3(origin, max_vrtx);
- /* Self-hit data: self hit if hit this component "on the other side" */
- tmp_res = s3d_scene_view_trace_ray(s3d_view, origin, dir, range,
- &self_hit_component, &hit);
- if(tmp_res != RES_OK) {
- *res = tmp_res;
- continue;
- }
- /* If no hit, the component is facing an infinite medium */
- if(S3D_HIT_NONE(&hit)) {
- cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
- cc->enclosure_id = 0;
- } else {
- /* If hit, group this component */
- const trg_id_t hit_trg_id = (trg_id_t)hit.prim.prim_id;
- const struct triangle_comp* hit_trg_comp =
- darray_triangle_comp_cdata_get(triangles_comp) + hit_trg_id;
- enum senc_side hit_side =
- ((hit.normal[2] < 0) /* Facing geometrical normal of hit */
- == ((scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0))
- /* Warning: following Embree 2 convention for geometrical normals,
- * the Star3D hit normal is left-handed while star-enclosure uses
- * right-handed convention */
- ? SENC_BACK : SENC_FRONT;
- ASSERT(hit.normal[2] != 0);
- ASSERT(hit_trg_id < scn->ntris);
-
- /* Not really the root until following links */
- cc->cc_group_root = hit_trg_comp->component[hit_side];
- ASSERT(cc->cc_group_root < cc_count);
- }
- }
- /* Implicit barrier here */
- ASSERT(ATOMIC_GET(next_enclosure_id) < ENCLOSURE_MAX__);
- if(*res != RES_OK) return;
-
- /* One thread post-processes links to group connex components */
- #pragma omp single
- {
- res_T tmp_res = RES_OK;
- 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(&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) {
- 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);
- cc->cc_group_root = other_desc->cc_group_root;
- cc->enclosure_id = other_desc->enclosure_id;
- enc = enclosures + cc->enclosure_id;
- ++enc->cc_count;
- /* Linked list of componnents */
- enc->first_component = cc->cc_id;
- enc->side_range.first = MMIN(enc->side_range.first, cc->side_range.first);
- 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,
- scn->next_medium_idx + 1);
- if(tmp_res != RES_OK) {
- *res = tmp_res;
- break;
- }
- }
- }
- }
- /* Implicit barrier here */
-}
-
-static void
-collect_and_link_neighbours
- (struct senc_scene* scn,
- struct trgside* trgsides,
- struct darray_triangle_tmp* triangles_tmp_array,
- struct darray_frontier_edge* 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. */
- const struct triangle_in* triangles_in;
- struct triangle_tmp* triangles_tmp;
- const union double3* vertices;
- const int thread_count = omp_get_num_threads();
- const int rank = omp_get_thread_num();
- /* Htable used to give an id to edges */
- struct htable_edge_id edge_ids;
- /* Array to keep neighbourhood of edges
- * Resize/Push operations on neighbourhood_by_edge are valid in the
- * openmp block because a given neighbourhood is only processed
- * by a single thread */
- struct darray_neighbourhood neighbourhood_by_edge;
- edge_id_t edge_count;
- edge_id_t nbedges_guess;
- edge_id_t e;
- trg_id_t t;
- size_t sz;
- res_T tmp_res;
-
- ASSERT(scn && trgsides && triangles_tmp_array && frontiers && res);
- ASSERT((size_t)scn->nverts + (size_t)scn->ntris + 2 <= EDGE_MAX__);
-
- htable_edge_id_init(scn->dev->allocator, &edge_ids);
- darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_edge);
-
- triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in);
- triangles_tmp = darray_triangle_tmp_data_get(triangles_tmp_array);
- vertices = darray_position_cdata_get(&scn->vertices);
-
- ASSERT(scn->ntris == darray_triangle_tmp_size_get(triangles_tmp_array));
-
- /* Make some room for edges. */
- nbedges_guess = 4 + (thread_count == 1
- ? (edge_id_t)(scn->nverts + scn->ntris)
- : (edge_id_t)((scn->nverts + scn->ntris) / (0.75 * thread_count)));
- OK2(darray_neighbourhood_reserve(&neighbourhood_by_edge, nbedges_guess));
- OK2(htable_edge_id_reserve(&edge_ids, nbedges_guess));
-
- /* Loop on triangles to register edges.
- * All threads considering all the edges and processing some */
- FOR_EACH(t, 0, scn->ntris) {
- struct trg_edge edge;
- unsigned char ee;
- FOR_EACH(ee, 0, 3) {
- edge_id_t* p_id;
- size_t n_sz;
- struct edge_neighbourhood* neighbourhood;
- struct neighbour_info* info;
- const vrtx_id_t v0 = triangles_in[t].vertice_id[ee];
- const vrtx_id_t v1 = triangles_in[t].vertice_id[(ee + 1) % 3];
- /* Process only "my" edges! */
- const int64_t h =
- /* v0,v1 and v1,v0 must give the same hash!!! */
- v0 + v1 + (int64_t)MMIN(v0, v1);
- if(h % thread_count != rank) continue;
- /* Create edge. */
- set_edge(v0, v1, &edge, &triangles_tmp[t].reversed_edge[ee]);
- /* Find edge id; create it if not already done. */
- p_id = htable_edge_id_find(&edge_ids, &edge);
- if(p_id) {
- neighbourhood =
- darray_neighbourhood_data_get(&neighbourhood_by_edge) + *p_id;
- ASSERT(neighbourhood->edge.vrtx0 == edge.vrtx0
- && neighbourhood->edge.vrtx1 == edge.vrtx1);
- } else {
- /* Create id */
- edge_id_t id;
- sz = htable_edge_id_size_get(&edge_ids);
- ASSERT(sz <= EDGE_MAX__);
- id = (edge_id_t)sz;
- ASSERT(htable_edge_id_size_get(&edge_ids)
- == darray_neighbourhood_size_get(&neighbourhood_by_edge));
- OK2(htable_edge_id_set(&edge_ids, &edge, &id));
- OK2(darray_neighbourhood_resize(&neighbourhood_by_edge, 1 + sz));
- neighbourhood = darray_neighbourhood_data_get(&neighbourhood_by_edge) + sz;
- /* Add neighbour info to a newly created edge's neighbour list */
- neighbourhood->edge = edge;
- ASSERT(darray_neighbour_size_get(&neighbourhood->neighbours) == 0);
- /* Just a guess: few edges will have less than 2 neighbours */
- OK2(darray_neighbour_reserve(&neighbourhood->neighbours, 2));
- }
- /* Add neighbour info to neighbourhood */
- n_sz = darray_neighbour_size_get(&neighbourhood->neighbours);
- OK2(darray_neighbour_resize(&neighbourhood->neighbours, 1 + n_sz));
- info = darray_neighbour_data_get(&neighbourhood->neighbours) + n_sz;
- info->trg_id = t;
- info->common_edge_rank = ee;
- }
- } /* No barrier here. */
-
- /* Loop on collected edges.
- * For each edge sort triangle sides by rotation angle
- * and connect neighbours. */
- sz = darray_neighbourhood_size_get(&neighbourhood_by_edge);
- ASSERT(sz <= EDGE_MAX__);
- edge_count = (edge_id_t)sz;
- FOR_EACH(e, 0, edge_count) {
- double edge[3], common_edge[3], basis[9], norm, max_z, maxz_edge, a;
- vrtx_id_t v0, v1, v2;
- struct edge_neighbourhood* neighbourhood
- = darray_neighbourhood_data_get(&neighbourhood_by_edge) + e;
- struct darray_neighbour* neighbour_list = &neighbourhood->neighbours;
- side_id_t i, neighbour_count;
- sz = darray_neighbour_size_get(neighbour_list);
- ASSERT(sz > 0 && sz <= SIDE_MAX__);
- neighbour_count = (side_id_t)sz;
- ASSERT(neighbour_count);
- v0 = neighbourhood->edge.vrtx0;
- v1 = neighbourhood->edge.vrtx1;
- d3_sub(common_edge, vertices[v1].vec, vertices[v0].vec);
- maxz_edge = MMAX(vertices[v0].pos.z, vertices[v1].pos.z);
- norm = d3_normalize(common_edge, common_edge);
- ASSERT(norm); (void)norm;
- d33_basis(basis, common_edge);
- d33_inverse(basis, basis);
- FOR_EACH(i, 0, neighbour_count) {
- struct neighbour_info* neighbour_info
- = darray_neighbour_data_get(neighbour_list) + i;
- const trg_id_t crt_id = neighbour_info->trg_id;
- const unsigned char crt_edge = neighbour_info->common_edge_rank;
- const struct triangle_in* trg_in = triangles_in + crt_id;
- struct triangle_tmp* neighbour = triangles_tmp + crt_id;
- union double3 n; /* Geometrical normal to neighbour triangle */
- const int is_reversed = neighbour->reversed_edge[crt_edge];
- v2 = trg_in->vertice_id[(crt_edge + 2) % 3];
- max_z = MMAX(vertices[v2].pos.z, maxz_edge);
- ASSERT(neighbour->max_z <= max_z);
- neighbour->max_z = max_z;
- /* Compute rotation angle around common edge */
- d3_sub(edge, vertices[v2].vec, vertices[v0].vec);
- d33_muld3(edge, basis, edge);
- ASSERT(d3_len(edge) && (edge[0] || edge[1]));
- neighbour_info->angle = atan2(edge[1], edge[0]);
- if(is_reversed)
- d3(n.vec, +edge[1], -edge[0], 0);
- else
- d3(n.vec, -edge[1], +edge[0], 0);
- if(neighbour_info->angle < 0) neighbour_info->angle += 2 * PI;
-
- /* Normal orientation calculation. */
- if(neighbour_info->angle <= PI / 4) {
- ASSERT(n.pos.y);
- neighbour_info->normal_toward_next_neighbour = (n.pos.y > 0);
- } else if(neighbour_info->angle <= 3 * PI / 4) {
- ASSERT(n.pos.x);
- neighbour_info->normal_toward_next_neighbour = (n.pos.x < 0);
- } else if(neighbour_info->angle <= 5 * PI / 4) {
- ASSERT(n.pos.y);
- neighbour_info->normal_toward_next_neighbour = (n.pos.y < 0);
- } else if(neighbour_info->angle <= 7 * PI / 4) {
- ASSERT(n.pos.x);
- neighbour_info->normal_toward_next_neighbour = (n.pos.x > 0);
- } else {
- ASSERT(n.pos.y);
- neighbour_info->normal_toward_next_neighbour = (n.pos.y > 0);
- }
- }
- /* Sort triangles by rotation angle */
- qsort(darray_neighbour_data_get(neighbour_list), neighbour_count,
- sizeof(struct neighbour_info), neighbour_cmp);
- /* Link sides.
- * Create cycles of sides by neighbourhood around common edge. */
- a = -DBL_MAX;
- FOR_EACH(i, 0, neighbour_count) {
- /* Neighbourhood info for current pair of triangles */
- const struct neighbour_info* current
- = darray_neighbour_cdata_get(neighbour_list) + i;
- const struct neighbour_info* ccw_neighbour
- = darray_neighbour_cdata_get(neighbour_list) + (i + 1) % neighbour_count;
- /* Rank of the edge of interest in triangles */
- const unsigned char crt_edge = current->common_edge_rank;
- /* Here ccw refers to the rotation around the common edge
- * and has nothing to do with vertices order in triangle definition
- * nor Front/Back side convention */
- const unsigned char ccw_edge = ccw_neighbour->common_edge_rank;
- /* User id of current triangles */
- const trg_id_t crt_id = current->trg_id;
- const trg_id_t ccw_id = ccw_neighbour->trg_id;
- /* Facing sides of triangles */
- const int front = ((scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0);
- const enum senc_side crt_side
- = current->normal_toward_next_neighbour == front ? SENC_FRONT : SENC_BACK;
- const enum senc_side ccw_side
- = ccw_neighbour->normal_toward_next_neighbour == front ?
- SENC_BACK : SENC_FRONT;
- /* Index of sides in trgsides */
- const side_id_t crt_side_idx = TRGIDxSIDE_2_TRGSIDE(crt_id, crt_side);
- const side_id_t ccw_side_idx = TRGIDxSIDE_2_TRGSIDE(ccw_id, ccw_side);
- /* Side ptrs */
- struct trgside* const p_crt_side = trgsides + crt_side_idx;
- struct trgside* const p_ccw_side = trgsides + ccw_side_idx;
- /* Check that angle is a discriminant property */
- ASSERT(a <= current->angle); /* Is sorted */
- if(a == current->angle) {
- /* Two consecutive triangles with same angle! */
- const struct neighbour_info* previous;
- trg_id_t prev_id;
- ASSERT(i > 0);
- previous = darray_neighbour_cdata_get(neighbour_list) + i - 1;
- prev_id = previous->trg_id;
- log_err(scn->dev,
- "%s: found 2 overlying triangles (%u & %u).\n", FUNC_NAME,
- (unsigned)crt_id, (unsigned)prev_id);
- tmp_res = RES_BAD_OP;
- goto tmp_error;
- }
- a = current->angle;
- /* Link sides */
- ASSERT(p_crt_side->facing_side_id[crt_edge] == SIDE_NULL__);
- ASSERT(p_ccw_side->facing_side_id[ccw_edge] == SIDE_NULL__);
- p_crt_side->facing_side_id[crt_edge] = ccw_side_idx;
- p_ccw_side->facing_side_id[ccw_edge] = crt_side_idx;
- /* Record media */
- ASSERT(p_crt_side->medium == MEDIUM_NULL__
- || p_crt_side->medium == triangles_in[crt_id].medium[crt_side]);
- ASSERT(p_ccw_side->medium == MEDIUM_NULL__
- || p_ccw_side->medium == triangles_in[ccw_id].medium[ccw_side]);
- p_crt_side->medium = triangles_in[crt_id].medium[crt_side];
- p_ccw_side->medium = triangles_in[ccw_id].medium[ccw_side];
- ASSERT(p_crt_side->medium == SENC_UNSPECIFIED_MEDIUM
- || p_crt_side->medium < scn->next_medium_idx);
- ASSERT(p_ccw_side->medium == SENC_UNSPECIFIED_MEDIUM
- || p_ccw_side->medium < scn->next_medium_idx);
- /* Detect triangles that could surround a hole:
- * - single triangle on (one of) its edge
- * - different media on its sides */
- if(neighbour_count == 1
- && p_crt_side->medium != p_ccw_side->medium)
-#pragma omp critical
- {
- struct trg_edge disc;
- log_warn(scn->dev,
- "%s: found frontier involving triangle %lu.\n",
- FUNC_NAME, (unsigned long)crt_id);
- disc.vrtx0 = v0;
- disc.vrtx1 = v1;
- darray_frontier_edge_push_back(frontiers, &disc);
- }
- }
- }
-tmp_error:
- if(tmp_res != RES_OK) *res = tmp_res;
- /* Threads are allowed to return whitout sync. */
- htable_edge_id_release(&edge_ids);
- darray_neighbourhood_release(&neighbourhood_by_edge);
-}
-
-static void
-build_result
- (struct senc_scene* scn,
- const struct darray_ptr_component_descriptor* connex_components,
- const struct darray_triangle_comp* triangles_comp_array,
- struct darray_frontier_edge* 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. */
- struct mem_allocator* alloc;
- struct cc_descriptor* const* cc_descriptors;
- struct enclosure_data* enclosures;
- const struct triangle_in* triangles_in;
- struct triangle_enc* triangles_enc;
- const struct triangle_comp* triangles_comp;
- struct htable_vrtx_id vtable;
- int output_normal_in, normals_front, normals_back;
- int64_t tt;
- int64_t ee;
-
- ASSERT(scn && connex_components && triangles_comp_array && frontiers && res);
-
- alloc = scn->dev->allocator;
- output_normal_in = (scn->convention & SENC_CONVENTION_NORMAL_INSIDE) != 0;
- normals_front = (scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0;
- normals_back = (scn->convention & SENC_CONVENTION_NORMAL_BACK) != 0;
- ASSERT(normals_back != normals_front);
- ASSERT(output_normal_in
- != ((scn->convention & SENC_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(&scn->analyze.enclosures);
- triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in);
- triangles_comp = darray_triangle_comp_cdata_get(triangles_comp_array);
-
- #pragma omp single
- {
- res_T tmp_res =
- darray_triangle_enc_resize(&scn->analyze.triangles_enc, scn->ntris);
- if(tmp_res != RES_OK) *res = tmp_res;
- }/* Implicit barrier here. */
- if(*res != RES_OK) return;
- triangles_enc = darray_triangle_enc_data_get(&scn->analyze.triangles_enc);
-
- /* Build global enclosure information */
- #pragma omp for
- for(tt = 0; tt < (int64_t)scn->ntris; tt++) {
- trg_id_t t = (trg_id_t)tt;
- const component_id_t cf_id = triangles_comp[t].component[SENC_FRONT];
- const component_id_t cb_id = triangles_comp[t].component[SENC_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(triangles_enc[t].enclosure[SENC_FRONT] == ENCLOSURE_NULL__);
- triangles_enc[t].enclosure[SENC_FRONT] = ef_id;
- ASSERT(triangles_enc[t].enclosure[SENC_BACK] == ENCLOSURE_NULL__);
- triangles_enc[t].enclosure[SENC_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(scn->analyze.enclosures_count <= ENCLOSURE_MAX__);
- #pragma omp for schedule(dynamic) nowait
- 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;
- trg_id_t fst_idx = 0;
- trg_id_t sgd_idx = enc->side_count;
- trg_id_t t;
- medium_id_t m;
- res_T tmp_res = RES_OK;
- ASSERT(enc->first_component
- < darray_ptr_component_descriptor_size_get(connex_components));
- ASSERT(cc_descriptors[enc->first_component]->cc_id
- == enc->first_component);
-
- 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
- == enc->header.enclosure_id);
- enc->header.is_infinite = (e == 0);
-
- ASSERT(darray_uchar_size_get(&enc->tmp_enclosed_media) <= UINT_MAX);
- ASSERT(enc->header.enclosed_media_count < 1 + scn->next_medium_idx);
- OK2(bool_array_of_media_to_darray_media
- (&enc->enclosed_media, &enc->tmp_enclosed_media, scn->next_medium_idx));
- enc->header.enclosed_media_count
- = (unsigned)darray_media_size_get(&enc->enclosed_media);
- darray_uchar_purge(&enc->tmp_enclosed_media);
-
- /* Add this enclosure in relevant by-medium lists */
- FOR_EACH(m, 0, enc->header.enclosed_media_count) {
- medium_id_t medium = darray_media_cdata_get(&enc->enclosed_media)[m];
- unsigned m_idx = (medium == SENC_UNSPECIFIED_MEDIUM) ? 0 : medium + 1;
- struct darray_enc_id* enc_ids_array_by_medium;
- ASSERT(medium == SENC_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_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_array_by_medium, &e);
- }
- if(tmp_res != RES_OK) {
- *res = tmp_res;
- break;
- }
- }
- if(*res != RES_OK) continue;
-
- /* 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,
- (size_t)(enc->side_count * 0.6)));
- /* New vertex numbering scheme local to the enclosure */
- htable_vrtx_id_clear(&vtable);
- ASSERT(scn->ntris == darray_triangle_in_size_get(&scn->triangles_in));
- /* Put at the end the back-faces of triangles that also have their
- * front-face in the list. */
- for(t = TRGSIDE_2_TRG(enc->side_range.first);
- t <= TRGSIDE_2_TRG(enc->side_range.last);
- t++)
- {
- const struct triangle_in* trg_in = triangles_in + t;
- struct side_enc* side_enc;
- unsigned vertice_id[3];
- int i;
- if(triangles_enc[t].enclosure[SENC_FRONT] != e
- && triangles_enc[t].enclosure[SENC_BACK] != e)
- continue;
- ++enc->header.unique_primitives_count;
-
- FOR_EACH(i, 0, 3) {
- vrtx_id_t* p_id = htable_vrtx_id_find(&vtable, trg_in->vertice_id + i);
- if(p_id) {
- vertice_id[i] = *p_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;
- OK2(htable_vrtx_id_set(&vtable, trg_in->vertice_id + i,
- vertice_id + i));
- OK2(darray_vrtx_id_push_back(&enc->vertices, trg_in->vertice_id + i));
- ++enc->header.vertices_count;
- }
- }
- ASSERT(triangles_enc[t].enclosure[SENC_FRONT] == e
- || triangles_enc[t].enclosure[SENC_BACK] == e);
- if(triangles_enc[t].enclosure[SENC_FRONT] == e) {
- /* Front side of the original triangle is member of the enclosure */
- int input_normal_in = normals_front;
- int revert_triangle = (input_normal_in != output_normal_in);
- ++enc->header.primitives_count;
- side_enc = darray_sides_enc_data_get(&enc->sides) + fst_idx++;
- FOR_EACH(i, 0, 3) {
- int ii = revert_triangle ? 2 - i : i;
- side_enc->vertice_id[i] = vertice_id[ii];
- }
- side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_FRONT);
- }
- if(triangles_enc[t].enclosure[SENC_BACK] == e) {
- /* Back side of the original triangle is member of the enclosure */
- int input_normal_in = normals_back;
- int revert_triangle = (input_normal_in != output_normal_in);
- ++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) +
- ((triangles_enc[t].enclosure[SENC_FRONT] == e) ? --sgd_idx : fst_idx++);
- FOR_EACH(i, 0, 3) {
- int ii = revert_triangle ? 2 - i : i;
- side_enc->vertice_id[i] = vertice_id[ii];
- }
- side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_BACK);
- }
- if(fst_idx == sgd_idx) break;
- }
- continue;
- tmp_error:
- ASSERT(tmp_res != RES_OK);
- *res = tmp_res;
- } /* No barrier here */
- htable_vrtx_id_release(&vtable);
- /* The first thread here copies frontiers into descriptor */
-#pragma omp single nowait
- darray_frontier_edge_copy_and_clear(&scn->analyze.frontiers, frontiers);
- /* No barrier here */
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-scene_analyze
- (struct senc_scene* scn)
-{
- /* By triangle tmp data */
- struct darray_triangle_tmp triangles_tmp;
- char triangles_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;
- /* Array of frontiers edges */
- struct darray_frontier_edge frontiers;
- char frontiers_initialized = 0;
- /* Store by-triangle components */
- struct darray_triangle_comp triangles_comp;
- char triangles_comp_initialized = 0;
- /* Array of triangle sides. */
- struct trgside* trgsides = NULL;
- struct s3d_scene_view* s3d_view = NULL;
- /* 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->ntris) goto exit;
-
- darray_triangle_tmp_init(scn->dev->allocator, &triangles_tmp);
- triangles_tmp_initialized = 1;
- darray_frontier_edge_init(scn->dev->allocator, &frontiers);
- frontiers_initialized = 1;
-
- OK(darray_triangle_tmp_resize(&triangles_tmp, scn->ntris));
- trgsides
- = MEM_CALLOC(scn->dev->allocator, 2 * scn->ntris, sizeof(struct trgside));
- if(!trgsides) {
- res = RES_MEM_ERR;
- goto error;
- }
-#ifndef NDEBUG
- else {
- /* Initialise trgsides to allow assert code */
- size_t i;
- FOR_EACH(i, 0, 2 * scn->ntris)
- init_trgside(scn->dev->allocator, trgsides + i);
- }
-#endif
-
- /* 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, trgsides, &triangles_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 */
-
- /* The first thread here allocates some data.
- * Barrier needed at the end to ensure data created before any use. */
- #pragma omp single
- {
- res_T tmp_res = RES_OK;
- darray_ptr_component_descriptor_init(scn->dev->allocator,
- &connex_components);
- connex_components_initialized = 1;
- /* Just a hint; to limit contention */
- OK2(darray_ptr_component_descriptor_reserve(&connex_components,
- 2 + 2 * scn->next_medium_idx));
- darray_triangle_comp_init(scn->dev->allocator, &triangles_comp);
- triangles_comp_initialized = 1;
- OK2(darray_triangle_comp_resize(&triangles_comp, scn->ntris));
- 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
- {
- if(res != RES_OK) {
- log_err(scn->dev,
- "%s: could not build neighbourhoods from scene.\n", FUNC_NAME);
- } else {
- res = res2;
- }
- }
- goto error_;
- }
-
- /* Step 2: extract triangle connex components */
- extract_connex_components(scn, trgsides, &connex_components,
- &triangles_tmp, &triangles_comp, &s3d_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
- * until next sync point */
-
- #pragma omp barrier
- /* Constraints on step 2 data are now met */
-
- if(res != RES_OK) {
- #pragma omp single nowait
- {
- log_err(scn->dev,
- "%s: could not extract connex components from scene.\n", FUNC_NAME);
- } /* No barrier here */
- goto error_;
- }
-
- /* One thread releases some data before going to step 3,
- * the others go to step 3 without sync */
- #pragma omp single nowait
- {
- darray_triangle_tmp_release(&triangles_tmp);
- triangles_tmp_initialized = 0;
- } /* No barrier here */
-
- /* Step 3: group components */
- group_connex_components(scn, trgsides, &triangles_comp,
- &connex_components, s3d_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 */
-
- if(res != RES_OK) {
- #pragma omp single nowait
- {
- log_err(scn->dev,
- "%s: could not group connex components from scene.\n", FUNC_NAME);
- }
- goto error_;
- }
-
- /* One thread releases some data before going to step 4,
- * the others go to step 4 without sync */
- #pragma omp single nowait
- {
- if(s3d_view) S3D(scene_view_ref_put(s3d_view));
- s3d_view = NULL;
- } /* No barrier here */
-
- /* Step 4: Build result */
- build_result(scn, &connex_components, &triangles_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 */
-
- if(res != RES_OK) {
- #pragma omp single nowait
- {
- log_err(scn->dev, "%s: could not build result.\n", FUNC_NAME);
- }
- goto error_;
- }
-
- /* Some threads release data */
- #pragma omp sections nowait
- {
- #pragma omp section
- {
- custom_darray_ptr_component_descriptor_release(&connex_components);
- connex_components_initialized = 0;
- }
- #pragma omp section
- {
- darray_triangle_comp_release(&triangles_comp);
- triangles_comp_initialized = 0;
- }
- } /* No barrier here */
-
-error_:
- ;
- } /* Implicit barrier here */
-
- if(res != RES_OK) goto error;
-exit:
- if(connex_components_initialized)
- custom_darray_ptr_component_descriptor_release(&connex_components);
- if(s3d_view) S3D(scene_view_ref_put(s3d_view));
- if(triangles_tmp_initialized) darray_triangle_tmp_release(&triangles_tmp);
- if(triangles_comp_initialized) darray_triangle_comp_release(&triangles_comp);
- if(frontiers_initialized)
- darray_frontier_edge_release(&frontiers);
- if(trgsides) MEM_RM(scn->dev->allocator, trgsides);
-
- return res;
-error:
- goto exit;
-}
diff --git a/src/senc_scene_analyze_c.h b/src/senc_scene_analyze_c.h
@@ -1,201 +0,0 @@
-/* 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
- * 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_SCNENE_ANALYZE_C_H
-#define SENC_SCNENE_ANALYZE_C_H
-
-#include "senc_internal_types.h"
-#include "senc.h"
-
-#include <rsys/mem_allocator.h>
-#include <rsys/hash_table.h>
-#include <rsys/double3.h>
-
-struct senc_scene;
-
-static FINLINE void
-init_trgside(struct mem_allocator* alloc, struct trgside* data)
-{
- int i;
- ASSERT(data); (void)alloc;
- FOR_EACH(i, 0, 3) data->facing_side_id[i] = SIDE_NULL__;
- data->medium = MEDIUM_NULL__;
-}
-
-#define DARRAY_NAME side_id
-#define DARRAY_DATA side_id_t
-#include <rsys/dynamic_array.h>
-
-/* Descriptors for connex component.
- * Define lists of trg sides starting from a given head.
- * 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_z_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;
- component_id_t cc_group_root;
- enclosure_id_t enclosure_id;
- /* Range of sides member of this component */
- struct side_range side_range;
- /* Media used by this component */
- unsigned char* media;
-};
-extern const struct cc_descriptor CC_DESCRIPTOR_NULL;
-
-static FINLINE void
-cc_descriptor_init
- (struct mem_allocator* alloc,
- struct cc_descriptor* data)
-{
- ASSERT(data);
- (void)alloc;
- *data = CC_DESCRIPTOR_NULL;
-}
-
-static FINLINE void
-ptr_component_descriptor_init
- (struct mem_allocator* alloc,
- struct cc_descriptor** data)
-{
- (void)alloc;
- ASSERT(data);
- *data = NULL;
-}
-
-#define DARRAY_NAME ptr_component_descriptor
-#define DARRAY_DATA struct cc_descriptor*
-#define DARRAY_FUNCTOR_INIT ptr_component_descriptor_init
-#include <rsys/dynamic_array.h>
-
-/* Need allocator to free array elts: cannot rely on standard
- * darray release stuff */
-static FINLINE void
-custom_darray_ptr_component_descriptor_release
- (struct darray_ptr_component_descriptor* array)
-{
- size_t c, cc_count;
- struct cc_descriptor** components;
- if(!array) return;
- cc_count = darray_ptr_component_descriptor_size_get(array);
- components = darray_ptr_component_descriptor_data_get(array);
- FOR_EACH(c, 0, cc_count) {
- if(!components[c]) continue;
- MEM_RM(array->allocator, components[c]->media);
- MEM_RM(array->allocator, components[c]);
- }
- darray_ptr_component_descriptor_release(array);
-}
-
-/* Triangle information.
- * Depending on lifespan, information is kept in different places:
- * - triangle_in for user provided information (kept in scene)
- * - triangle_tmp for tmp information (kept until triangle_comp is ready)
- * - triangle_comp for information describing components (kept until
- * triangle_enc is ready)
- * - triangle_enc for information describing enclosures (kept in
- * struct descriptor). */
-struct triangle_tmp {
- /* Are the edges of the triangle defined in the same order than
- * the edges they are linked to? */
- unsigned char reversed_edge[3];
- double max_z;
-};
-
-#ifndef NDEBUG
-static FINLINE void
-triangle_tmp_init(struct mem_allocator* alloc, struct triangle_tmp* trg) {
- int i;
- (void)alloc;
- ASSERT(trg);
- FOR_EACH(i, 0, 3) trg->reversed_edge[i] = UCHAR_MAX;
- trg->max_z = -DBL_MAX;
-}
-#define DARRAY_FUNCTOR_INIT triangle_tmp_init
-#endif
-
-#define DARRAY_NAME triangle_tmp
-#define DARRAY_DATA struct triangle_tmp
-#include <rsys/dynamic_array.h>
-
-#define HTABLE_NAME edge_id
-#define HTABLE_KEY struct trg_edge
-#define HTABLE_DATA edge_id_t
-#define HTABLE_KEY_FUNCTOR_EQ edge_eq
-#include <rsys/hash_table.h>
-
-struct neighbour_info {
- double angle;
- trg_id_t trg_id;
- /* Rank of the edge in the triangle (in [0 2]) */
- unsigned char common_edge_rank;
- /* Does the geometrical normal point towards the next neighbour
- * (if not, it points towards the previous one)? */
- unsigned char normal_toward_next_neighbour;
-};
-#define DARRAY_NAME neighbour
-#define DARRAY_DATA struct neighbour_info
-#include <rsys/dynamic_array.h>
-
-struct edge_neighbourhood {
- struct trg_edge edge;
- struct darray_neighbour neighbours;
-};
-static void
-neighbourhood_init
- (struct mem_allocator* alloc,
- struct edge_neighbourhood* n)
-{
- ASSERT(n);
- darray_neighbour_init(alloc, &n->neighbours);
-}
-static res_T
-neighbourhood_copy
- (struct edge_neighbourhood* dst,
- const struct edge_neighbourhood* src)
-{
- ASSERT(src && dst);
- dst->edge = src->edge;
- return darray_neighbour_copy(&dst->neighbours, &src->neighbours);
-}
-static void
-neighbourhood_release(struct edge_neighbourhood* n) {
- ASSERT(n);
- darray_neighbour_release(&n->neighbours);
-}
-static res_T
-neighbourhood_copy_and_release
- (struct edge_neighbourhood* dst,
- struct edge_neighbourhood* src)
-{
- ASSERT(src && dst);
- dst->edge = src->edge;
- return darray_neighbour_copy_and_release(&dst->neighbours, &src->neighbours);
-}
-#define DARRAY_NAME neighbourhood
-#define DARRAY_DATA struct edge_neighbourhood
-#define DARRAY_FUNCTOR_INIT neighbourhood_init
-#define DARRAY_FUNCTOR_COPY neighbourhood_copy
-#define DARRAY_FUNCTOR_RELEASE neighbourhood_release
-#define DARRAY_FUNCTOR_COPY_AND_RELEASE neighbourhood_copy_and_release
-#include <rsys/dynamic_array.h>
-
-extern LOCAL_SYM res_T
-scene_analyze(struct senc_scene* scene);
-
-#endif /* SENC_SCNENE_ANALYZE_C_H */
diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h
@@ -1,302 +0,0 @@
-/* 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
- * 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_SCENE_C_H
-#define SENC_SCENE_C_H
-
-#include "senc_internal_types.h"
-#include "senc_enclosure_data.h"
-#include "senc_side_range.h"
-#include "senc.h"
-
-#include <rsys/ref_count.h>
-#include <rsys/dynamic_array.h>
-#include <rsys/hash_table.h>
-
-struct mem_allocator;
-struct senc_scene;
-
-struct triangle_comp {
- /* The connex component in which each side is. */
- component_id_t component[2];
-};
-
-static void
-triangle_comp_init(struct mem_allocator* alloc, struct triangle_comp* trg) {
- int i;
- (void)alloc;
- ASSERT(trg);
- FOR_EACH(i, 0, 2) trg->component[i] = COMPONENT_NULL__;
-}
-
-#define DARRAY_NAME triangle_comp
-#define DARRAY_DATA struct triangle_comp
-#define DARRAY_FUNCTOR_INIT triangle_comp_init
-#include <rsys/dynamic_array.h>
-
-struct triangle_enc {
- /* The enclosure in which each side is. */
- enclosure_id_t enclosure[2];
-};
-
-#ifndef NDEBUG
-static void
-triangle_enc_init(struct mem_allocator* alloc, struct triangle_enc* trg) {
- int i;
- (void)alloc;
- ASSERT(trg);
- FOR_EACH(i, 0, 2) trg->enclosure[i] = ENCLOSURE_NULL__;
-}
-#define DARRAY_FUNCTOR_INIT triangle_enc_init
-#endif
-
-#define DARRAY_NAME triangle_enc
-#define DARRAY_DATA struct triangle_enc
-#include <rsys/dynamic_array.h>
-
-/* Triangle edge struct and basic functions */
-struct trg_edge {
- vrtx_id_t vrtx0, vrtx1;
-};
-
-static FINLINE int
-edge_ok(const struct trg_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 trg_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 trg_edge* e1, const struct trg_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 trgside {
- /* Rank of the trgside facing this trgside through its edges */
- side_id_t facing_side_id[3];
- /* Id of this trgside's medium */
- medium_id_t medium;
-
- /* Implicit information that we don't need to store:
- * - triangle_id
- * - side
- * This is due to the memory layout of the elt darray:
- * front(trg_0), back(trg_0), front(trg_1), back(trg_1), ... */
-};
-
-#define DARRAY_NAME frontier_edge
-#define DARRAY_DATA struct trg_edge
-#include <rsys/dynamic_array.h>
-
-union double3 {
- struct {
- double x, y, z;
- } pos;
- double vec[3];
-};
-#define DARRAY_NAME position
-#define DARRAY_DATA union double3
-#include <rsys/dynamic_array.h>
-/* Triangle information.
- * Depending on lifespan, information is kept in different places:
- * - triangle_in for user provided information (kept in scene)
- * - triangle_comp for information describing components (kept in struct descriptor)
- * - triangle_tmp for tmp information (kept until triangle_comp is ready) */
-struct triangle_in {
- /* Ids of the triangle's vertices */
- vrtx_id_t vertice_id[3];
- /* Ids of this triangle's media */
- medium_id_t medium[2];
-};
-
-static FINLINE void
-triangle_in_init(struct mem_allocator* alloc, struct triangle_in* trg) {
- int i;
- (void)alloc;
- ASSERT(trg);
- FOR_EACH(i, 0, 3) trg->vertice_id[i] = VRTX_NULL__;
- FOR_EACH(i, 0, 2) trg->medium[i] = SENC_UNSPECIFIED_MEDIUM;
-}
-
-#define DARRAY_NAME triangle_in
-#define DARRAY_DATA struct triangle_in
-#define DARRAY_FUNCTOR_INIT triangle_in_init
-#include <rsys/dynamic_array.h>
-
-static FINLINE void
-triangle_in_flip(struct triangle_in* trg) {
- vrtx_id_t v;
- medium_id_t m;
- ASSERT(trg);
- v = trg->vertice_id[1];
- trg->vertice_id[1] = trg->vertice_id[2];
- trg->vertice_id[2] = v;
- m = trg->medium[0];
- trg->medium[0] = trg->medium[1];
- trg->medium[1] = m;
-}
-
-static FINLINE int
-vrtx_eq(const union double3* v1, const union double3* v2)
-{
- ASSERT(v1 && v2);
- return (v1->pos.x == v2->pos.x
- && v1->pos.y == v2->pos.y
- && v1->pos.z == v2->pos.z);
-}
-
-#define HTABLE_NAME vrtx
-#define HTABLE_KEY union double3
-#define HTABLE_DATA vrtx_id_t
-#define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
-#include <rsys/hash_table.h>
-
-union vrtx_id3 {
- struct {
- vrtx_id_t v0, v1, v2;
- } pos;
- vrtx_id_t vec[3];
-};
-
-static FINLINE char /* Return 1 if reversed */
-trg_make_key(union vrtx_id3* k, const vrtx_id_t t[3])
-{
- ASSERT(t);
- ASSERT(t[0] != t[1] && t[0] != t[2] && t[1] != t[2]);
- if(t[0] < t[2]) {
- if(t[0] < t[1]) {
- k->vec[0] = t[0];
- if(t[1] < t[2]) {
- k->vec[1] = t[1];
- k->vec[2] = t[2];
- return 0;
- } else {
- k->vec[1] = t[2];
- k->vec[2] = t[1];
- return 1;
- }
- } else {
- k->vec[0] = t[1];
- if(t[0] < t[2]) {
- k->vec[1] = t[0];
- k->vec[2] = t[2];
- return 1;
- } else {
- k->vec[1] = t[2];
- k->vec[2] = t[0];
- return 0;
- }
- }
- } else if(t[2] < t[1]) {
- k->vec[0] = t[2];
- if(t[0] < t[1]) {
- k->vec[1] = t[0];
- k->vec[2] = t[1];
- return 0;
- } else {
- k->vec[1] = t[1];
- k->vec[2] = t[0];
- return 1;
- }
- } else {
- k->vec[0] = t[1];
- if(t[0] < t[2]) {
- k->vec[1] = t[0];
- k->vec[2] = t[2];
- return 1;
- } else {
- k->vec[1] = t[2];
- k->vec[2] = t[0];
- return 0;
- }
- }
-}
-
-static FINLINE int
-trg_key_eq(const union vrtx_id3* k1, const union vrtx_id3* k2)
-{
- ASSERT(k1 && k2);
- ASSERT(k1->vec[0] < k1->vec[1] && k1->vec[1] < k1->vec[2]);
- ASSERT(k2->vec[0] < k2->vec[1] && k2->vec[1] < k2->vec[2]);
- return (k1->vec[0] == k2->vec[0])
- && (k1->vec[1] == k2->vec[1])
- && (k1->vec[2] == k2->vec[2]);
-}
-
-#define HTABLE_NAME trg
-#define HTABLE_KEY union vrtx_id3
-#define HTABLE_DATA trg_id_t
-#define HTABLE_KEY_FUNCTOR_EQ trg_key_eq
-#include <rsys/hash_table.h>
-
-struct descriptor {
- enclosure_id_t enclosures_count;
- /* Store by-triangle enclosures */
- struct darray_triangle_enc triangles_enc;
- /* Store enclosures */
- struct darray_enclosure enclosures;
- struct darray_enc_ids_array enc_ids_array_by_medium;
- /* Store frontiers */
- struct darray_frontier_edge frontiers;
-};
-
-struct senc_scene {
- /* Front / Back sides convention */
- int convention;
- /* Triangle information as given by user */
- struct darray_triangle_in triangles_in;
- /* Vertex information as given by user */
- struct darray_position vertices;
-
- /* Keep sizes */
- trg_id_t ntris; /* Trg count */
- vrtx_id_t nverts; /* Vrtx count */
- medium_id_t next_medium_idx;
- /* media_use 0 is for SENC_UNSPECIFIED_MEDIUM, n+1 is for n */
- struct darray_side_range media_use;
-
- /* The descriptor of the analyze */
- struct descriptor analyze;
-
- ref_T ref;
- struct senc_device* dev;
-};
-
-#endif /* SENC_SCENE_C_H */
diff --git a/src/senc_side_range.h b/src/senc_side_range.h
@@ -1,44 +0,0 @@
-/* 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
- * 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_SIDE_RANGE_H
-#define SENC_SIDE_RANGE_H
-
-#include "senc_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 /* SENC_SCENE_C_H */
diff --git a/src/test_senc3d_cube_behind_cube.c b/src/test_senc3d_cube_behind_cube.c
@@ -0,0 +1,311 @@
+/* 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
+ * 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 sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_cube_behind_cube. */
+
+#include "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+/* Dump of star-geometry 'cube_behind_cube_2'. */
+static const unsigned cube_behind_cube_2_vertices_count = 16;
+static const double cube_behind_cube_2_vertices[48] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1,
+ -1.5, -2, 20,
+ 3, -2, 20,
+ -2, 3, 20,
+ 3, 3, 20,
+ -2, -2, 25.5,
+ 3, -2, 25,
+ -2, 3, 25,
+ 3, 3.5, 25
+};
+static const unsigned cube_behind_cube_2_triangles_count = 24;
+static const unsigned cube_behind_cube_2_triangles[72] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5,
+ 8, 10, 9,
+ 9, 10, 11,
+ 8, 12, 10,
+ 10, 12, 14,
+ 12, 13, 14,
+ 14, 13, 15,
+ 11, 15, 9,
+ 9, 15, 13,
+ 10, 14, 11,
+ 11, 14, 15,
+ 8, 9, 12,
+ 12, 9, 13
+};
+static const unsigned cube_behind_cube_2_properties[72] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 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 'cube_behind_cube_3'. */
+static const unsigned cube_behind_cube_3_vertices_count = 24;
+static const double cube_behind_cube_3_vertices[72] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1,
+ -1.5, -2, 20,
+ 3, -2, 20,
+ -2, 3, 20,
+ 3, 3, 20,
+ -2, -2, 25.5,
+ 3, -2, 25,
+ -2, 3, 25,
+ 3, 3.5, 25,
+ -2.3, -3, 30,
+ 4, -3, 30,
+ -3, 4, 30,
+ 4, 4, 30,
+ -3, -3, 37.7,
+ 4, -3, 37,
+ -3, 4, 37,
+ 4, 4.7, 37
+};
+static const unsigned cube_behind_cube_3_triangles_count = 36;
+static const unsigned cube_behind_cube_3_triangles[108] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5,
+ 8, 10, 9,
+ 9, 10, 11,
+ 8, 12, 10,
+ 10, 12, 14,
+ 12, 13, 14,
+ 14, 13, 15,
+ 11, 15, 9,
+ 9, 15, 13,
+ 10, 14, 11,
+ 11, 14, 15,
+ 8, 9, 12,
+ 12, 9, 13,
+ 16, 18, 17,
+ 17, 18, 19,
+ 16, 20, 18,
+ 18, 20, 22,
+ 20, 21, 22,
+ 22, 21, 23,
+ 19, 23, 17,
+ 17, 23, 21,
+ 18, 22, 19,
+ 19, 22, 23,
+ 16, 17, 20,
+ 20, 17, 21
+};
+static const unsigned cube_behind_cube_3_properties[108] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 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,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0,
+ 1, 0, 0
+};
+
+/*
+ cube_2 cube_3
+
+ +-----------------------+
+ | 3
+ | |
+ m1 | m0 |
+ | |
+ | |
+ | |
+ | |--> N
+ | |
+ | |
+ +-----------------------+
+ +------------+ +------------+
+ | 2 | 2
+ m0 | m1 | m0 | m1 |
+ | | | |
+ | |--> N | |--> N
+ | | | |
+ +------------+ +------------+
+ +-----+ +-----+
+ m0 | m1 1 m0 | m1 1
+ | |--> N | |--> N
+ +-----+ +-----+
+ */
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned i, ecount, maxm;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene with the first and second cubes.
+ * Both cubes have medium 1 inside and medium 0 outside,
+ * the second cube is +Z from the first cube and is big enough
+ * to prevent rays from the first cube to miss it. */
+ ctx.positions = cube_behind_cube_2_vertices;
+ ctx.indices = cube_behind_cube_2_triangles;
+ ctx.properties = cube_behind_cube_2_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ cube_behind_cube_2_triangles_count, get_indices, get_media_from_properties,
+ cube_behind_cube_2_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 3);
+
+ FOR_EACH(i, 0, ecount) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ OK(senc3d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ ASSERT(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 1);
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Create a scene with the 3 cubes, same 2 first cubes as above
+ * The third cube has medium 0 inside and medium 1 outside and is further
+ * in +Z and bigger */
+ ctx.positions = cube_behind_cube_3_vertices;
+ ctx.indices = cube_behind_cube_3_triangles;
+ ctx.properties = cube_behind_cube_3_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ cube_behind_cube_3_triangles_count, get_indices, get_media_from_properties,
+ cube_behind_cube_3_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 4);
+
+ FOR_EACH(i, 0, ecount) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ OK(senc3d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ /* Inside enclosures contain 1 single media */
+ ASSERT(header.enclosed_media_count == (header.is_infinite ? 2u : 1u));
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 1);
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_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_senc3d_cube_in_cube.c b/src/test_senc3d_cube_in_cube.c
@@ -0,0 +1,314 @@
+/* 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
+ * 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 sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_cube_in_cube. */
+
+#include "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+/*
+ cube_2 cube_3
+
+ +-------------------------+
+ | B
+ +-------------+ | +-------------+ |
+ m1 | m0 M m1 | m1 | m0 M |
+ | +------+ | | m0 | +------+ | |
+ | | m1 S | | | | m1 S | |
+ | | N <--| | | | | N <--| | |
+ | +------+ | | | +------+ | |
+ | N <--| | | N <--| |
+ +-------------+ | +-------------+ |
+ | N <--|
+ +-------------------------+
+ */
+
+
+/* Dump of star-geometry 'cube_in_cube_2'. */
+static const unsigned cube_in_cube_2_vertices_count = 16;
+static const double cube_in_cube_2_vertices[48] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1,
+ -0.7, -1, -1,
+ 2, -1, -1,
+ -1, 2, -1,
+ 2, 2, -1,
+ -1, -1, 2.3,
+ 2, -1, 2,
+ -1, 2, 2,
+ 2, 2.3, 2
+};
+static const unsigned cube_in_cube_2_triangles_count = 24;
+static const unsigned cube_in_cube_2_triangles[72] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5,
+ 8, 9, 10,
+ 9, 11, 10,
+ 8, 10, 12,
+ 10, 14, 12,
+ 12, 14, 13,
+ 14, 15, 13,
+ 11, 9, 15,
+ 9, 13, 15,
+ 10, 11, 14,
+ 11, 15, 14,
+ 8, 12, 9,
+ 12, 13, 9
+};
+static const unsigned cube_in_cube_2_properties[72] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 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 'cube_in_cube_3'. */
+static const unsigned cube_in_cube_3_vertices_count = 24;
+static const double cube_in_cube_3_vertices[72] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1,
+ -0.7, -1, -1,
+ 2, -1, -1,
+ -1, 2, -1,
+ 2, 2, -1,
+ -1, -1, 2.3,
+ 2, -1, 2,
+ -1, 2, 2,
+ 2, 2.3, 2,
+ -3, -4, -4,
+ 6, -4, -4,
+ -4, 6, -4,
+ 6, 6, -4,
+ -4, -4, 7,
+ 6, -4, 6,
+ -4, 6, 6,
+ 6, 7, 6
+};
+static const unsigned cube_in_cube_3_triangles_count = 36;
+static const unsigned cube_in_cube_3_triangles[108] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5,
+ 8, 9, 10,
+ 9, 11, 10,
+ 8, 10, 12,
+ 10, 14, 12,
+ 12, 14, 13,
+ 14, 15, 13,
+ 11, 9, 15,
+ 9, 13, 15,
+ 10, 11, 14,
+ 11, 15, 14,
+ 8, 12, 9,
+ 12, 13, 9,
+ 16, 17, 18,
+ 17, 19, 18,
+ 16, 18, 20,
+ 18, 22, 20,
+ 20, 22, 21,
+ 22, 23, 21,
+ 19, 17, 23,
+ 17, 21, 23,
+ 18, 19, 22,
+ 19, 23, 22,
+ 16, 20, 17,
+ 20, 21, 17
+};
+static const unsigned cube_in_cube_3_properties[108] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 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 senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned e, ecount, maxm, e2;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene with the first and second cubes.
+ * The enclosure in the small contains medium 1, the external enclosure
+ * contains medium 1, the enclosure between the small and medium cubes
+ * contains medium 0. */
+ ctx.positions = cube_in_cube_2_vertices;
+ ctx.indices = cube_in_cube_2_triangles;
+ ctx.properties = cube_in_cube_2_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ cube_in_cube_2_triangles_count, get_indices, get_media_from_properties,
+ cube_in_cube_2_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 3);
+
+ FOR_EACH(e, 0, ecount) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ unsigned m;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ ASSERT(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &m));
+ ASSERT(m <= 1);
+ ASSERT((m == 0) == (header.primitives_count == cube_in_cube_2_triangles_count));
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 1);
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Create a scene with the 3 cubes, same 2 first cubes as above.
+ * The enclosure in the small cube contains medium 1, the external enclosure
+ * contains medium 1, the enclosure between the small and medium cubes
+ * contains medium 0 and the enclosure between the medium and big cubes
+ * contains both media 0 and 1. */
+ ctx.positions = cube_in_cube_3_vertices;
+ ctx.indices = cube_in_cube_3_triangles;
+ ctx.properties = cube_in_cube_3_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ cube_in_cube_3_triangles_count, get_indices, get_media_from_properties,
+ cube_in_cube_3_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 4);
+
+ e2 = ecount;
+ FOR_EACH(e, 0, ecount) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_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);
+ e2 = e;
+ }
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 1);
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_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_senc3d_cube_on_cube.c b/src/test_senc3d_cube_on_cube.c
@@ -0,0 +1,205 @@
+/* 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
+ * 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 sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_cube_on_cube. */
+
+#define _POSIX_C_SOURCE 200112L /* snprintf */
+
+#include "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+/*
+ +-----------------------+
+ | 3
+ | +------+ |
+ m2 | m1 | m0 2 |
+ | | |--> N |
+ | +------+ |
+ | | m0 1 |
+ | | |--> N |
+ | +------+ |
+ |--> N |
+ +-----------------------+
+ */
+
+/* Dump of star-geometry 'cube_on_cube'. */
+static const unsigned cube_on_cube_vertices_count = 20;
+static const double cube_on_cube_vertices[60] =
+{
+ 1, 1, 2,
+ 2, 1, 2,
+ 1, 2, 2,
+ 2, 2, 2,
+ 1, 1, 3,
+ 2, 1, 3,
+ 1, 2, 3,
+ 2, 2, 3,
+ 1, 1, 1,
+ 2, 1, 1,
+ 1, 2, 1,
+ 2, 2, 1,
+ 0.4, 0, 0,
+ 4, 0, 0,
+ 0, 4, 0,
+ 4, 4, 0,
+ 0, 0, 4.4,
+ 4, 0, 4,
+ 0, 4, 4,
+ 4, 4.4, 4
+};
+static const unsigned cube_on_cube_triangles_count = 34;
+static const unsigned cube_on_cube_triangles[102] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5,
+ 8, 10, 9,
+ 9, 10, 11,
+ 8, 0, 10,
+ 10, 0, 2,
+ 11, 3, 9,
+ 9, 3, 1,
+ 10, 2, 11,
+ 11, 2, 3,
+ 8, 9, 0,
+ 0, 9, 1,
+ 12, 13, 14,
+ 13, 15, 14,
+ 12, 14, 16,
+ 14, 18, 16,
+ 16, 18, 17,
+ 18, 19, 17,
+ 15, 13, 19,
+ 13, 17, 19,
+ 14, 15, 18,
+ 15, 19, 18,
+ 12, 16, 13,
+ 16, 17, 13
+};
+static const unsigned cube_on_cube_properties[102] =
+{
+ 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, 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
+};
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned count, e;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene with the cubes.
+ * The enclosures in the small cubes contain medium 0, the external enclosure
+ * contains medium 2, the enclosure between the small and big cubes
+ * contains medium 1. */
+ ctx.positions = cube_on_cube_vertices;
+ ctx.indices = cube_on_cube_triangles;
+ ctx.properties = cube_on_cube_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ cube_on_cube_triangles_count, get_indices, get_media_from_properties,
+ cube_on_cube_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 4);
+
+ OK(senc3d_scene_get_vertices_count(scn, &count));
+ CHK(count == cube_on_cube_vertices_count);
+
+ OK(senc3d_scene_get_triangles_count(scn, &count));
+ CHK(count == cube_on_cube_triangles_count);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 4);
+ FOR_EACH(e, 0, count) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ unsigned m;
+ char name[128]; (void)name;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ CHK(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &m));
+ if(header.is_infinite) ASSERT(m == 2); /* External */
+ else if(header.primitives_count == 12) ASSERT(m == 0); /* Internal */
+ else ASSERT(m == 1); /* In between */
+ OK(senc3d_enclosure_ref_put(enclosure));
+#ifdef DUMP_ENCLOSURES
+ snprintf(name, sizeof(name), "test_cube_on_cube_%u.obj", e);
+ dump_enclosure(scn, e, name);
+#endif
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_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_senc3d_device.c b/src/test_senc3d_device.c
@@ -0,0 +1,77 @@
+/* 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
+ * 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 "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/logger.h>
+
+#include <stdio.h>
+
+static INLINE void
+log_stream(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)msg, (void)ctx;
+ printf("%s\n", msg);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct logger logger;
+ struct mem_allocator allocator;
+ struct senc3d_device* dev;
+ (void)argc, (void)argv;
+
+ BA(senc3d_device_create(NULL, NULL, 0, 0, NULL));
+ BA(senc3d_device_create(NULL, NULL, 0, 0, &dev));
+ OK(senc3d_device_create(NULL, NULL, 1, 0, &dev));
+ BA(senc3d_device_ref_get(NULL));
+ OK(senc3d_device_ref_get(dev));
+ BA(senc3d_device_ref_put(NULL));
+ OK(senc3d_device_ref_put(dev));
+ OK(senc3d_device_ref_put(dev));
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
+ BA(senc3d_device_create(NULL, &allocator, 1, 0, NULL));
+ OK(senc3d_device_create(NULL, &allocator, 1, 0, &dev));
+ OK(senc3d_device_ref_put(dev));
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
+
+ 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);
+
+ BA(senc3d_device_create(&logger, NULL, 1, 0, NULL));
+ OK(senc3d_device_create(&logger, NULL, 1, 0, &dev));
+ OK(senc3d_device_ref_put(dev));
+
+ BA(senc3d_device_create(&logger, &allocator, 1, 0, NULL));
+ OK(senc3d_device_create(&logger, &allocator, 1, 0, &dev));
+ OK(senc3d_device_ref_put(dev));
+
+ OK(senc3d_device_create(&logger, &allocator, SENC3D_NTHREADS_DEFAULT, 0, &dev));
+ OK(senc3d_device_ref_put(dev));
+
+ logger_release(&logger);
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_senc3d_enclosure.c b/src/test_senc3d_enclosure.c
@@ -0,0 +1,248 @@
+/* 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
+* 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 "senc3d.h"
+#include "SENC3D_s3d_helper.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+#include <star/s3d.h>
+
+static void
+test(const int convention)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct senc3d_enclosure* enclosures[2] = { NULL, NULL };
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ struct s3d_device* s3d = NULL;
+ struct s3d_scene* s3d_scn = NULL;
+ struct s3d_shape* s3d_shp = NULL;
+ struct s3d_vertex_data s3d_attribs;
+ unsigned indices[2][3];
+ unsigned medium;
+ unsigned gid;
+ enum senc3d_side side;
+ double vrtx[3];
+ struct context ctx = CONTEXT_NULL__;
+ unsigned i, n, t, count;
+ int conv;
+ const int conv_front = (convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0;
+ const int conv_in = (convention & SENC3D_CONVENTION_NORMAL_INSIDE) != 0;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* A 3D cube.
+ * 2 enclosures (inside, outside) sharing the same triangles,
+ * but opposite sides */
+ ctx.positions = box_vertices;
+ ctx.indices = box_indices;
+ ctx.front_media = medium0;
+ ctx.back_media = medium1;
+
+ OK(senc3d_scene_create(dev, convention, ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_convention(scn, &conv));
+ CHK(conv == convention);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 2);
+
+ OK(senc3d_scene_get_enclosure(scn, 0, &enclosure));
+ BA(senc3d_enclosure_ref_get(NULL));
+ OK(senc3d_enclosure_ref_get(enclosure));
+ BA(senc3d_enclosure_ref_put(NULL));
+ OK(senc3d_enclosure_ref_put(enclosure));
+
+ BA(senc3d_enclosure_get_triangle(NULL, 0, indices[0]));
+ BA(senc3d_enclosure_get_triangle(enclosure, ntriangles, indices[0]));
+ BA(senc3d_enclosure_get_triangle(enclosure, 0, NULL));
+ BA(senc3d_enclosure_get_triangle(NULL, ntriangles, indices[0]));
+ BA(senc3d_enclosure_get_triangle(NULL, 0, NULL));
+ BA(senc3d_enclosure_get_triangle(enclosure, ntriangles, NULL));
+ BA(senc3d_enclosure_get_triangle(NULL, ntriangles, NULL));
+ OK(senc3d_enclosure_get_triangle(enclosure, 0, indices[0]));
+
+ BA(senc3d_enclosure_get_vertex(NULL, 0, vrtx));
+ BA(senc3d_enclosure_get_vertex(enclosure, nvertices, vrtx));
+ BA(senc3d_enclosure_get_vertex(enclosure, 0, NULL));
+ BA(senc3d_enclosure_get_vertex(NULL, nvertices, vrtx));
+ BA(senc3d_enclosure_get_vertex(NULL, 0, NULL));
+ BA(senc3d_enclosure_get_vertex(enclosure, nvertices, NULL));
+ BA(senc3d_enclosure_get_vertex(NULL, nvertices, NULL));
+ OK(senc3d_enclosure_get_vertex(enclosure, 0, vrtx));
+
+ BA(senc3d_enclosure_get_triangle_id(NULL, 0, &gid, NULL));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, ntriangles, &gid, NULL));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, 0, NULL, NULL));
+ BA(senc3d_enclosure_get_triangle_id(NULL, ntriangles, &gid, NULL));
+ BA(senc3d_enclosure_get_triangle_id(NULL, 0, NULL, NULL));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, ntriangles, NULL, NULL));
+ BA(senc3d_enclosure_get_triangle_id(NULL, ntriangles, NULL, NULL));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, 0, &gid, NULL));
+ BA(senc3d_enclosure_get_triangle_id(NULL, 0, &gid, &side));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, ntriangles, &gid, &side));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, 0, NULL, &side));
+ BA(senc3d_enclosure_get_triangle_id(NULL, ntriangles, &gid, &side));
+ BA(senc3d_enclosure_get_triangle_id(NULL, 0, NULL, &side));
+ BA(senc3d_enclosure_get_triangle_id(enclosure, ntriangles, NULL, &side));
+ BA(senc3d_enclosure_get_triangle_id(NULL, ntriangles, NULL, &side));
+ OK(senc3d_enclosure_get_triangle_id(enclosure, 0, &gid, &side));
+
+ BA(senc3d_enclosure_get_medium(NULL, 0, &medium));
+ BA(senc3d_enclosure_get_medium(enclosure, 2, &medium));
+ BA(senc3d_enclosure_get_medium(enclosure, 0, NULL));
+ BA(senc3d_enclosure_get_medium(NULL, 2, &medium));
+ BA(senc3d_enclosure_get_medium(NULL, 0, NULL));
+ BA(senc3d_enclosure_get_medium(enclosure, 2, NULL));
+ BA(senc3d_enclosure_get_medium(NULL, 2, NULL));
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &medium));
+
+ OK(senc3d_enclosure_ref_put(enclosure));
+
+ FOR_EACH(i, 0, count) {
+ OK(senc3d_scene_get_enclosure(scn, i, &enclosure));
+
+ BA(senc3d_enclosure_get_header(NULL, &header));
+ BA(senc3d_enclosure_get_header(enclosure, NULL));
+ BA(senc3d_enclosure_get_header(NULL, NULL));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ CHK(header.enclosure_id == i);
+ CHK(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &medium));
+ /* Geometrical normals point outside the cube in input triangles:
+ * 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.primitives_count == ntriangles);
+ CHK(header.unique_primitives_count == ntriangles);
+ CHK(header.vertices_count == nvertices);
+ CHK(header.is_infinite == (i == 0));
+
+ FOR_EACH(t, 0, header.primitives_count) {
+ OK(senc3d_enclosure_get_triangle_id(enclosure, t, &gid, &side));
+ CHK(gid == t);
+ CHK(side == (medium == 0) ? SENC3D_FRONT : SENC3D_BACK);
+ }
+
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ FOR_EACH(i, 0, 2)
+ OK(senc3d_scene_get_enclosure(scn, i, enclosures + i));
+ FOR_EACH(n, 0, ntriangles) {
+ int same, reversed;
+ /* Read same triangles in both enclosures */
+ FOR_EACH(i, 0, 2)
+ OK(senc3d_enclosure_get_triangle(enclosures[i], n, indices[i]));
+ /* Same triangles and opposite sides for the 2 enclosures */
+ FOR_EACH(i, 0, 3) CHK(indices[0][i] == indices[1][2 - i]);
+ /* Enclosure 0 is outside (and contains medium 0 if convention is front).
+ * Geometrical normals in output data point in the same direction that those
+ * of input triangles for enclosure 0 iff convention is inside.
+ * The opposite holds for enclosure 1. */
+ cmp_trg(n, enclosures[0], box_indices + 3 * n, box_vertices, &same, &reversed);
+ CHK((same && !reversed) == conv_in);
+ cmp_trg(n, enclosures[1], box_indices + 3 * n, box_vertices, &same, &reversed);
+ CHK(same && reversed == conv_in);
+ }
+ FOR_EACH(i, 0, 2)
+ OK(senc3d_enclosure_ref_put(enclosures[i]));
+
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Same 3D cube, but with a hole (incomplete).
+ * 1 single enclosure including both sides of triangles */
+
+ ctx.positions = box_vertices;
+ ctx.indices = box_indices;
+ ctx.front_media = medium0;
+ ctx.back_media = medium1;
+
+ OK(senc3d_scene_create(dev, convention, ntriangles - 1, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_frontier_segments_count(scn, &count));
+ CHK(count == 3);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1);
+
+#ifdef DUMP_ENCLOSURES
+ dump_enclosure(scn, 0, "test_enclosure_hole.obj");
+#endif
+
+ OK(senc3d_scene_get_enclosure(scn, 0, &enclosure));
+
+ BA(senc3d_enclosure_get_header(NULL, &header));
+ BA(senc3d_enclosure_get_header(enclosure, NULL));
+ BA(senc3d_enclosure_get_header(NULL, NULL));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ CHK(header.enclosure_id == 0);
+ CHK(header.enclosed_media_count == 2);
+ CHK(header.primitives_count == 2 * header.unique_primitives_count);
+ CHK(header.unique_primitives_count == ntriangles - 1);
+ CHK(header.vertices_count == nvertices);
+ CHK(header.is_infinite == 1);
+
+ FOR_EACH(t, 0, header.primitives_count) {
+ OK(senc3d_enclosure_get_triangle_id(enclosure, t, &gid, &side));
+ /* The first unique_triangle_count triangles of an enclosure
+ * are unique triangles */
+ if(t < header.unique_primitives_count) CHK(gid == t);
+ CHK(side == (t < header.unique_primitives_count) ? SENC3D_FRONT : SENC3D_BACK);
+ }
+
+ /* Put geometry in a 3D view using helper functions */
+ s3d_attribs.type = S3D_FLOAT3;
+ s3d_attribs.usage = S3D_POSITION;
+ s3d_attribs.get = SENC3D_s3d_enclosure_get_position;
+ OK(s3d_device_create(NULL, &allocator, 0, &s3d));
+ OK(s3d_scene_create(s3d, &s3d_scn));
+ OK(s3d_shape_create_mesh(s3d, &s3d_shp));
+ OK(s3d_mesh_setup_indexed_vertices(s3d_shp, header.primitives_count,
+ SENC3D_s3d_enclosure_get_indices, header.vertices_count, &s3d_attribs,
+ 1, enclosure));
+ OK(s3d_scene_attach_shape(s3d_scn, s3d_shp));
+ S3D(shape_ref_put(s3d_shp));
+ S3D(device_ref_put(s3d));
+ S3D(scene_ref_put(s3d_scn));
+
+ SENC3D(scene_ref_put(scn));
+ SENC3D(device_ref_put(dev));
+ SENC3D(enclosure_ref_put(enclosure));
+
+ 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(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE);
+ test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE);
+ test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_OUTSIDE);
+ test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE);
+ return 0;
+}
diff --git a/src/test_senc3d_inconsistant_cube.c b/src/test_senc3d_inconsistant_cube.c
@@ -0,0 +1,145 @@
+/* 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
+* 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 "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+/* The following array lists the indices toward the 3D vertices of each
+* triangle.
+* ,6---,7 ,6----7
+* ,' | ,'/| ,' | \ | Y Z
+* 2----3' / | 2', | \ | | ,'
+* |', | / ,5 | ',4---,5 0----X
+* | ',|/,' | ,' | ,'
+* 0----1' 0----1'
+* Front, right Back, left and
+* and Top faces bottom faces */
+/* Triangle #1 rotation order is not consistant with other triangles */
+static unsigned
+inconsistant_box_indices[12/*#triangles*/ * 3/*#indices per triangle*/] = {
+ 0, 1, 2, 1, 2, 3, /* Front face */
+ 0, 4, 2, 2, 4, 6, /* Left face*/
+ 4, 5, 6, 6, 5, 7, /* Back face */
+ 3, 7, 1, 1, 7, 5, /* Right face */
+ 2, 6, 3, 3, 6, 7, /* Top face */
+ 0, 1, 4, 4, 1, 5 /* Bottom face */
+};
+static const unsigned inconsistant_box_ntriangles
+= sizeof(inconsistant_box_indices) / (3 * sizeof(*inconsistant_box_indices));
+
+/* Media definitions reflect triangle #1 inconsistancy */
+static const unsigned
+inconsistant_medium_front[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static const unsigned
+inconsistant_medium_back[12] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+static void
+test(const int convention)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ int conv;
+ int conv_front, conv_in;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned i, e, ecount;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* A 3D cube.
+ * 2 enclosures (inside, outside) sharing the same triangles,
+ * but opposite sides.
+ * What differs in this test is that triangle #0 vertices are given
+ * in the opposite rotation order. */
+ ctx.positions = box_vertices;
+ ctx.indices = inconsistant_box_indices;
+ ctx.front_media = inconsistant_medium_front;
+ ctx.back_media = inconsistant_medium_back;
+
+ OK(senc3d_scene_create(dev, convention, inconsistant_box_ntriangles,
+ get_indices, get_media, nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 2);
+
+ OK(senc3d_scene_get_convention(scn, &conv));
+ CHK(conv == convention);
+ conv_front = (conv & SENC3D_CONVENTION_NORMAL_FRONT) != 0;
+ conv_in = (conv & SENC3D_CONVENTION_NORMAL_INSIDE) != 0;
+
+ FOR_EACH(e, 0, ecount) {
+ unsigned medium, expected_external_medium, expected_medium;
+ char name[128];
+ enum senc3d_side side, expected_side;
+ unsigned gid;
+ (void)name;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ CHK(header.enclosed_media_count == 1);
+ OK(senc3d_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;
+ expected_medium = (header.is_infinite ?
+ expected_external_medium : !expected_external_medium);
+ CHK(medium == expected_medium);
+
+#ifdef DUMP_ENCLOSURES
+ sprintf(name, "test_inconsistant_cube_%s_%s_%u.obj",
+ conv_front ? "front" : "back", conv_in ? "in" : "out", e);
+ dump_enclosure(scn, e, name);
+#endif
+
+ 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)
+ ? SENC3D_FRONT : SENC3D_BACK;
+ cmp_trg(i, enclosure,
+ inconsistant_box_indices + (3 * i), box_vertices,
+ &same, &reversed);
+ /* Should be made of the same triangles */
+ CHK(same);
+ CHK(i ? reversed != fst_reversed : reversed == fst_reversed);
+ OK(senc3d_enclosure_get_triangle_id(enclosure, i, &gid, &side));
+ CHK(side == expected_side);
+ }
+ SENC3D(enclosure_ref_put(enclosure));
+ }
+
+ SENC3D(scene_ref_put(scn));
+ SENC3D(device_ref_put(dev));
+
+ 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(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE);
+ test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE);
+ test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_OUTSIDE);
+ test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE);
+
+ return 0;
+}
diff --git a/src/test_senc3d_many_enclosures.c b/src/test_senc3d_many_enclosures.c
@@ -0,0 +1,108 @@
+/* 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
+* 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 is similar to test_senc3d_some_enclosures, but involves 64*64*64
+ * cylinders instead of 4*4*4, thus making it impossible to define the geometry
+ * through static arrays. */
+
+#define NB_CYL_X 32
+#define NB_CYL_Y 32
+#define NB_CYL_Z 64
+ /* 64^3 = 262144 cylinders */
+#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
+
+#include "senc3d.h"
+#include "test_senc3d_utils.h"
+#include "test_senc3d_utils2.h"
+
+#include <star/s3dut.h>
+#include <rsys/clock_time.h>
+#include <rsys/double3.h>
+
+#include <stdio.h>
+#include <limits.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct s3dut_mesh* cyl = NULL;
+ struct s3dut_context ctx = { {NULL,NULL,0,0}, CONTEXT_NULL__ };
+ unsigned count;
+ unsigned cyl_trg_count, cyl_vrtx_count, e;
+ char dump[64];
+ struct time t0, t1;
+ (void)argc, (void)argv;
+
+ OK(mem_init_regular_allocator(&allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* A 20 triangles 12 vertices cylinder template */
+ S3DUT(create_cylinder(&allocator, 1, 1, 3, 1, &cyl));
+ S3DUT(mesh_get_data(cyl, &ctx.data));
+ ASSERT(ctx.data.nprimitives < UINT_MAX);
+ ASSERT(ctx.data.nvertices < UINT_MAX);
+ cyl_trg_count = (unsigned)ctx.data.nprimitives;
+ cyl_vrtx_count = (unsigned)ctx.data.nvertices;
+
+ /* Create the scene with N_CYL cylinders.
+ * There are NB_CYL_X * NB_CYL_Y imbrications of NB_CYL_Z cylinders each.
+ * Each imbrication is located on a grid.
+ * The get_s3du_xxx getters have to retrieve the cylinder from the
+ * primitive and vertice indexes. */
+ time_current(&t0);
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ NB_CYL * cyl_trg_count, get_s3dut_indices, get_s3dut_media,
+ NB_CYL * cyl_vrtx_count, get_s3dut_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 created in: %s\n", dump);
+ S3DUT(mesh_ref_put(cyl));
+
+ OK(senc3d_scene_get_vertices_count(scn, &count));
+ CHK(count == NB_CYL * cyl_vrtx_count);
+ OK(senc3d_scene_get_triangles_count(scn, &count));
+ CHK(count == NB_CYL * cyl_trg_count);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1 + NB_CYL);
+ FOR_EACH(e, 0, count) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ unsigned m;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ CHK(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &m));
+ CHK(header.primitives_count ==
+ (header.is_infinite /* Outermost enclosure: NB_CYL_X*NB_CYL_Y cylinders */
+ ? NB_CYL_X * NB_CYL_Y * cyl_trg_count
+ : (m == 0
+ ? cyl_trg_count /* Innermost enclosures: 1 cylinder */
+ : 2 * cyl_trg_count))); /* Other enclosures: 2 cylinders */
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_regular_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_senc3d_many_triangles.c b/src/test_senc3d_many_triangles.c
@@ -0,0 +1,101 @@
+/* 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
+* 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 is similar to test_senc3d_some_triangles, but involves 4*2562560
+ * triangles instead of 4*1054, thus making it impossible to define the geometry
+ * through static arrays. */
+
+#define NB_CYL_X 2
+#define NB_CYL_Y 1
+#define NB_CYL_Z 1
+ /* 4 cylinders */
+#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
+
+#include "senc3d.h"
+#include "test_senc3d_utils.h"
+#include "test_senc3d_utils2.h"
+
+#include <star/s3dut.h>
+#include <rsys/clock_time.h>
+#include <rsys/double3.h>
+
+#include <stdio.h>
+#include <limits.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct s3dut_mesh* cyl = NULL;
+ struct s3dut_context ctx = { {NULL,NULL,0,0}, CONTEXT_NULL__ };
+ unsigned m0 = 0;
+ unsigned count;
+ unsigned cyl_trg_count, cyl_vrtx_count, e;
+ char dump[64];
+ struct time t0, t1;
+ (void)argc, (void)argv;
+
+ OK(mem_init_regular_allocator(&allocator));
+ OK(senc3d_device_create (NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* A 2,562,560 triangles 1,281,282 vertices cylinder template */
+ S3DUT(create_cylinder(&allocator, 1, 2, 1280, 1000, &cyl));
+ S3DUT(mesh_get_data(cyl, &ctx.data));
+ ASSERT(ctx.data.nprimitives < UINT_MAX);
+ ASSERT(ctx.data.nvertices < UINT_MAX);
+ cyl_trg_count = (unsigned)ctx.data.nprimitives;
+ cyl_vrtx_count = (unsigned)ctx.data.nvertices;
+
+ /* Create the scene with 4 cylinders.
+ * The get_s3du_xxx getters have to retrieve the cylinder from the
+ * primitive and vertice indexes. */
+ ctx.ctx.back_media = &m0;
+ time_current(&t0);
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ NB_CYL* cyl_trg_count, get_s3dut_indices, get_s3dut_media,
+ NB_CYL* cyl_vrtx_count, get_s3dut_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 created in: %s\n", dump);
+ S3DUT(mesh_ref_put(cyl));
+
+ OK(senc3d_scene_get_vertices_count(scn, &count));
+ CHK(count == NB_CYL * cyl_vrtx_count);
+ OK(senc3d_scene_get_triangles_count(scn, &count));
+ CHK(count == NB_CYL * cyl_trg_count);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1 + NB_CYL);
+ FOR_EACH(e, 0, count) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ CHK(header.primitives_count ==
+ e ? cyl_trg_count : NB_CYL * cyl_trg_count);
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_regular_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_senc3d_sample_enclosure.c b/src/test_senc3d_sample_enclosure.c
@@ -0,0 +1,124 @@
+/* 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
+* 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 "senc3d.h"
+#include "SENC3D_s3d_helper.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/float3.h>
+#include <rsys/double3.h>
+
+#include <star/s3d.h>
+#include <star/ssp.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct senc3d_enclosure* enclosure = NULL;
+ struct senc3d_enclosure_header header;
+ struct s3d_device* s3d = NULL;
+ struct s3d_scene* s3d_scn = NULL;
+ struct s3d_scene_view* s3d_view = NULL;
+ struct s3d_shape* s3d_shp = NULL;
+ struct s3d_primitive prim;
+ struct s3d_vertex_data vrtx_get;
+ struct ssp_rng* rng;
+ struct context ctx = CONTEXT_NULL__;
+ int i;
+ float st[2];
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* A 3D cube, but with a hole (incomplete).
+ * 1 single enclosure including both sides of triangles */
+ ctx.positions = cube_vertices;
+ ctx.indices = box_indices;
+ ctx.front_media = medium0;
+ ctx.back_media = medium0;
+
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles - 1, get_indices, get_media, nvertices, get_position, &ctx,
+ &scn));
+
+ OK(senc3d_scene_get_enclosure(scn, 0, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ /* Put enclosure in a 3D view... */
+ vrtx_get.type = S3D_FLOAT3;
+ vrtx_get.usage = S3D_POSITION;
+ vrtx_get.get = SENC3D_s3d_enclosure_get_position;
+ S3D(device_create(NULL, &allocator, 0, &s3d));
+ S3D(scene_create(s3d, &s3d_scn));
+ S3D(shape_create_mesh(s3d, &s3d_shp));
+ S3D(mesh_setup_indexed_vertices(s3d_shp, header.primitives_count,
+ SENC3D_s3d_enclosure_get_indices, header.vertices_count, &vrtx_get, 1,
+ enclosure));
+ S3D(scene_attach_shape(s3d_scn, s3d_shp));
+ S3D(scene_view_create(s3d_scn, S3D_SAMPLE, &s3d_view));
+
+ /* ... and sample it. */
+ OK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng));
+ FOR_EACH(i, 0, 10000) {
+ struct s3d_attrib attrib;
+ int n, c;
+ S3D(scene_view_sample(s3d_view,
+ ssp_rng_canonical_float(rng),
+ ssp_rng_canonical_float(rng),
+ ssp_rng_canonical_float(rng),
+ &prim, st));
+ S3D(primitive_get_attrib(&prim, S3D_POSITION, st, &attrib));
+ c = 0;
+ FOR_EACH(n, 0, 3)
+ if(eq_eps(attrib.value[n], 0, FLT_EPSILON)
+ || eq_eps(attrib.value[n], 1, FLT_EPSILON))
+ c++;
+ CHK(c == 1);
+ S3D(primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, st, &attrib));
+ c = 0;
+ FOR_EACH(n, 0, 3)
+ if(eq_eps(attrib.value[n], -1, FLT_EPSILON)
+ || eq_eps(attrib.value[n], 1, FLT_EPSILON))
+ c++;
+ CHK(c == 1);
+ c = 0;
+ FOR_EACH(n, 0, 3)
+ if(eq_eps(attrib.value[n], 0, FLT_EPSILON))
+ c++;
+ CHK(c == 2);
+ }
+
+ SENC3D(enclosure_ref_put(enclosure));
+ SENC3D(scene_ref_put(scn));
+ SENC3D(device_ref_put(dev));
+
+ SSP(rng_ref_put(rng));
+
+ S3D(shape_ref_put(s3d_shp));
+ S3D(scene_view_ref_put(s3d_view));
+ S3D(device_ref_put(s3d));
+ S3D(scene_ref_put(s3d_scn));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+
+ return 0;
+}
diff --git a/src/test_senc3d_scene.c b/src/test_senc3d_scene.c
@@ -0,0 +1,296 @@
+/* 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
+ * 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 "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/float3.h>
+#include <rsys/double3.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct senc3d_enclosure* enc = NULL;
+ struct senc3d_enclosure_header header;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned medfront[2], medback[2], ind[3], ids[2];
+ double vrtx[3];
+ unsigned count, i, maxm;
+ int convention;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* A 3D cube.
+ * With this geometry front is inside with NORMAL_BACK convention,
+ * outside with NORMAL_FRONT convention */
+ ctx.positions = box_vertices;
+ ctx.indices = box_indices;
+ ctx.front_media = medium0;
+ ctx.back_media = medium1;
+
+ BA(senc3d_scene_create(NULL,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc3d_scene_create(dev,
+ 0,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ 0, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, NULL, get_media,
+ nvertices, get_position, &ctx, &scn));
+ BA(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ 0, get_position, &ctx, &scn));
+ BA(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, NULL, &ctx, &scn));
+ BA(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, NULL));
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ BA(senc3d_scene_get_convention(NULL, &convention));
+ BA(senc3d_scene_get_convention(scn, NULL));
+ BA(senc3d_scene_get_convention(NULL, NULL));
+ OK(senc3d_scene_get_convention(scn, &convention));
+ CHK(convention
+ == (SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE));
+
+ BA(senc3d_scene_get_triangles_count(NULL, &count));
+ BA(senc3d_scene_get_triangles_count(scn, NULL));
+ BA(senc3d_scene_get_triangles_count(NULL, NULL));
+ OK(senc3d_scene_get_triangles_count(scn, &count));
+ CHK(count == ntriangles);
+
+ BA(senc3d_scene_get_vertices_count(NULL, &count));
+ BA(senc3d_scene_get_vertices_count(scn, NULL));
+ BA(senc3d_scene_get_vertices_count(NULL, NULL));
+ OK(senc3d_scene_get_vertices_count(scn, &count));
+ CHK(count == nvertices);
+
+ BA(senc3d_scene_get_triangle(NULL, 0, ind));
+ BA(senc3d_scene_get_triangle(scn, UINT_MAX, ind));
+ BA(senc3d_scene_get_triangle(scn, 0, NULL));
+ BA(senc3d_scene_get_triangle(NULL, UINT_MAX, ind));
+ BA(senc3d_scene_get_triangle(NULL, 0, NULL));
+ BA(senc3d_scene_get_triangle(scn, UINT_MAX, NULL));
+ BA(senc3d_scene_get_triangle(NULL, UINT_MAX, NULL));
+ OK(senc3d_scene_get_triangle(scn, 0, ind));
+
+ BA(senc3d_scene_get_triangle_media(NULL, 0, ind));
+ BA(senc3d_scene_get_triangle_media(scn, UINT_MAX, ind));
+ BA(senc3d_scene_get_triangle_media(scn, 0, NULL));
+ BA(senc3d_scene_get_triangle_media(NULL, UINT_MAX, ind));
+ BA(senc3d_scene_get_triangle_media(NULL, 0, NULL));
+ BA(senc3d_scene_get_triangle_media(scn, UINT_MAX, NULL));
+ BA(senc3d_scene_get_triangle_media(NULL, UINT_MAX, NULL));
+ OK(senc3d_scene_get_triangle_media(scn, 0, ind));
+
+ BA(senc3d_scene_get_vertex(NULL, 0, vrtx));
+ BA(senc3d_scene_get_vertex(scn, UINT_MAX, vrtx));
+ BA(senc3d_scene_get_vertex(scn, 0, NULL));
+ BA(senc3d_scene_get_vertex(NULL, UINT_MAX, vrtx));
+ BA(senc3d_scene_get_vertex(NULL, 0, NULL));
+ BA(senc3d_scene_get_vertex(scn, UINT_MAX, NULL));
+ BA(senc3d_scene_get_vertex(NULL, UINT_MAX, NULL));
+ OK(senc3d_scene_get_vertex(scn, 0, vrtx));
+
+ BA(senc3d_scene_get_max_medium(NULL, &maxm));
+ BA(senc3d_scene_get_max_medium(scn, NULL));
+ BA(senc3d_scene_get_max_medium(NULL, NULL));
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 1);
+
+ BA(senc3d_scene_get_enclosure_count(NULL, &count));
+ BA(senc3d_scene_get_enclosure_count(scn, NULL));
+ BA(senc3d_scene_get_enclosure_count(NULL, NULL));
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 2);
+
+ BA(senc3d_scene_get_enclosure_count_by_medium(NULL, 0, &count));
+ BA(senc3d_scene_get_enclosure_count_by_medium(scn, 100, &count));
+ BA(senc3d_scene_get_enclosure_count_by_medium(scn, 0, NULL));
+ BA(senc3d_scene_get_enclosure_count_by_medium(NULL, 100, &count));
+ BA(senc3d_scene_get_enclosure_count_by_medium(NULL, 0, NULL));
+ BA(senc3d_scene_get_enclosure_count_by_medium(scn, 100, NULL));
+ BA(senc3d_scene_get_enclosure_count_by_medium(NULL, 100, NULL));
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, 0, &count));
+ CHK(count == 1);
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, SENC3D_UNSPECIFIED_MEDIUM,
+ &count));
+ CHK(count == 0);
+
+ BA(senc3d_scene_get_enclosure(NULL, 0, &enc));
+ BA(senc3d_scene_get_enclosure(scn, UINT_MAX, &enc));
+ BA(senc3d_scene_get_enclosure(scn, 0, NULL));
+ BA(senc3d_scene_get_enclosure(NULL, UINT_MAX, &enc));
+ BA(senc3d_scene_get_enclosure(NULL, 0, NULL));
+ BA(senc3d_scene_get_enclosure(scn, UINT_MAX, NULL));
+ BA(senc3d_scene_get_enclosure(NULL, UINT_MAX, NULL));
+ OK(senc3d_scene_get_enclosure(scn, 0, &enc));
+ OK(senc3d_enclosure_ref_put(enc));
+
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 0, 0, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 100, 0, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 0, UINT_MAX, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 0, 0, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 100, 0, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 0, UINT_MAX, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 0, 0, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 100, UINT_MAX, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 100, 0, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 0, UINT_MAX, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, 100, UINT_MAX, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 0, UINT_MAX, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 100, 0, NULL));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 100, UINT_MAX, &enc));
+ BA(senc3d_scene_get_enclosure_by_medium(NULL, 100, UINT_MAX, NULL));
+ OK(senc3d_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
+ OK(senc3d_enclosure_ref_put(enc));
+ /* Index 0 is out of range for SENC3D_UNSPECIFIED_MEDIUM. */
+ BA(senc3d_scene_get_enclosure_by_medium(scn, SENC3D_UNSPECIFIED_MEDIUM, 0, &enc));
+
+ BA(senc3d_scene_get_triangle_enclosures(NULL, 0, ids));
+ BA(senc3d_scene_get_triangle_enclosures(scn, UINT_MAX, ids));
+ BA(senc3d_scene_get_triangle_enclosures(scn, 0, NULL));
+ BA(senc3d_scene_get_triangle_enclosures(NULL, UINT_MAX, ids));
+ BA(senc3d_scene_get_triangle_enclosures(NULL, 0, NULL));
+ BA(senc3d_scene_get_triangle_enclosures(scn, UINT_MAX, NULL));
+ BA(senc3d_scene_get_triangle_enclosures(NULL, UINT_MAX, NULL));
+ OK(senc3d_scene_get_triangle_enclosures(scn, 0, ids));
+
+ BA(senc3d_scene_get_frontier_segments_count(NULL, &count));
+ BA(senc3d_scene_get_frontier_segments_count(scn, NULL));
+ BA(senc3d_scene_get_frontier_segments_count(NULL, NULL));
+ OK(senc3d_scene_get_frontier_segments_count(scn, &count));
+ CHK(count == 0);
+
+ BA(senc3d_scene_get_frontier_segment(NULL, 0, ids));
+ BA(senc3d_scene_get_frontier_segment(scn, UINT_MAX, ids));
+ BA(senc3d_scene_get_frontier_segment(scn, 0, NULL));
+ BA(senc3d_scene_get_frontier_segment(NULL, UINT_MAX, ids));
+ BA(senc3d_scene_get_frontier_segment(NULL, 0, NULL));
+ BA(senc3d_scene_get_frontier_segment(scn, UINT_MAX, NULL));
+ BA(senc3d_scene_get_frontier_segment(NULL, UINT_MAX, NULL));
+
+ BA(senc3d_scene_ref_get(NULL));
+ OK(senc3d_scene_ref_get(scn));
+ BA(senc3d_scene_ref_put(NULL));
+ OK(senc3d_scene_ref_put(scn));
+
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Same geometry with SENC3D_UNSPECIFIED_MEDIUM */
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, NULL,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_by_medium(scn, SENC3D_UNSPECIFIED_MEDIUM, 0, &enc));
+ OK(senc3d_enclosure_ref_put(enc));
+ BA(senc3d_scene_get_enclosure_by_medium(scn, SENC3D_UNSPECIFIED_MEDIUM, 100, &enc));
+
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Same geometry with a hole (1 missing triangle) */
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles - 1, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_frontier_segments_count(scn, &count));
+ CHK(count == 3);
+ OK(senc3d_scene_get_frontier_segment(scn, 0, ids));
+ BA(senc3d_scene_get_frontier_segment(scn, 3, ids));
+
+ OK(senc3d_scene_ref_put(scn));
+
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_convention(scn, &convention));
+ CHK(convention
+ == (SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE));
+ /* Check that medium 0 is inside */
+ OK(senc3d_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
+ OK(senc3d_enclosure_get_header(enc, &header));
+ CHK(!header.is_infinite);
+ OK(senc3d_enclosure_ref_put(enc));
+
+ OK(senc3d_scene_get_triangle_media(scn, 0, medback));
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Medium mismatch between neighbour segments, but OK */
+ ctx.front_media = medium1_3;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == 3);
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, 0, &count));
+ CHK(count == 0); /* Medium 0 unused */
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, 1, &count));
+ CHK(count == 2); /* Medium 1 used twice */
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, 2, &count));
+ CHK(count == 0); /* Medium 2 unused */
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, 3, &count));
+ CHK(count == 1); /* Medium 3 used */
+
+ OK(senc3d_scene_ref_put(scn));
+
+ ctx.front_media = medium0;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, get_media,
+ nvertices, get_position, &ctx, &scn));
+ /* Check that medium 0 is outside */
+ OK(senc3d_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
+ OK(senc3d_enclosure_get_header(enc, &header));
+ CHK(header.is_infinite);
+ OK(senc3d_enclosure_ref_put(enc));
+
+ OK(senc3d_scene_get_triangle_media(scn, 0, medfront));
+ FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_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_senc3d_some_enclosures.c b/src/test_senc3d_some_enclosures.c
@@ -0,0 +1,3427 @@
+/* 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
+ * 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 sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_some_enclosures.
+ * This test is similar to test_SENC3D_many_enclosures that creates a huge
+ * geometry by program. */
+
+#include "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+/* Dump of star-geometry 'some_enclosures'. */
+static const unsigned some_enclosures_vertices_count = 768;
+static const double some_enclosures_vertices[2304] =
+{
+ -19, -20, -0.5,
+ -19, -20, 0.5,
+ -19.691, -19.0489, -0.5,
+ -19.691, -19.0489, 0.5,
+ -20.809, -19.4122, -0.5,
+ -20.809, -19.4122, 0.5,
+ -20.809, -20.5878, -0.5,
+ -20.809, -20.5878, 0.5,
+ -19.691, -20.9511, -0.5,
+ -19.691, -20.9511, 0.5,
+ -20, -20, -0.5,
+ -20, -20, 0.5,
+ -18, -20, -1,
+ -18, -20, 1,
+ -19.382, -18.0979, -1,
+ -19.382, -18.0979, 1,
+ -21.618, -18.8244, -1,
+ -21.618, -18.8244, 1,
+ -21.618, -21.1756, -1,
+ -21.618, -21.1756, 1,
+ -19.382, -21.9021, -1,
+ -19.382, -21.9021, 1,
+ -20, -20, -1,
+ -20, -20, 1,
+ -17, -20, -1.5,
+ -17, -20, 1.5,
+ -19.0729, -17.1468, -1.5,
+ -19.0729, -17.1468, 1.5,
+ -22.4271, -18.2366, -1.5,
+ -22.4271, -18.2366, 1.5,
+ -22.4271, -21.7634, -1.5,
+ -22.4271, -21.7634, 1.5,
+ -19.0729, -22.8532, -1.5,
+ -19.0729, -22.8532, 1.5,
+ -20, -20, -1.5,
+ -20, -20, 1.5,
+ -16, -20, -2,
+ -16, -20, 2,
+ -18.7639, -16.1958, -2,
+ -18.7639, -16.1958, 2,
+ -23.2361, -17.6489, -2,
+ -23.2361, -17.6489, 2,
+ -23.2361, -22.3511, -2,
+ -23.2361, -22.3511, 2,
+ -18.7639, -23.8042, -2,
+ -18.7639, -23.8042, 2,
+ -20, -20, -2,
+ -20, -20, 2,
+ -19, -10, -0.5,
+ -19, -10, 0.5,
+ -19.691, -9.04894, -0.5,
+ -19.691, -9.04894, 0.5,
+ -20.809, -9.41221, -0.5,
+ -20.809, -9.41221, 0.5,
+ -20.809, -10.5878, -0.5,
+ -20.809, -10.5878, 0.5,
+ -19.691, -10.9511, -0.5,
+ -19.691, -10.9511, 0.5,
+ -20, -10, -0.5,
+ -20, -10, 0.5,
+ -18, -10, -1,
+ -18, -10, 1,
+ -19.382, -8.09789, -1,
+ -19.382, -8.09789, 1,
+ -21.618, -8.82443, -1,
+ -21.618, -8.82443, 1,
+ -21.618, -11.1756, -1,
+ -21.618, -11.1756, 1,
+ -19.382, -11.9021, -1,
+ -19.382, -11.9021, 1,
+ -20, -10, -1,
+ -20, -10, 1,
+ -17, -10, -1.5,
+ -17, -10, 1.5,
+ -19.0729, -7.14683, -1.5,
+ -19.0729, -7.14683, 1.5,
+ -22.4271, -8.23664, -1.5,
+ -22.4271, -8.23664, 1.5,
+ -22.4271, -11.7634, -1.5,
+ -22.4271, -11.7634, 1.5,
+ -19.0729, -12.8532, -1.5,
+ -19.0729, -12.8532, 1.5,
+ -20, -10, -1.5,
+ -20, -10, 1.5,
+ -16, -10, -2,
+ -16, -10, 2,
+ -18.7639, -6.19577, -2,
+ -18.7639, -6.19577, 2,
+ -23.2361, -7.64886, -2,
+ -23.2361, -7.64886, 2,
+ -23.2361, -12.3511, -2,
+ -23.2361, -12.3511, 2,
+ -18.7639, -13.8042, -2,
+ -18.7639, -13.8042, 2,
+ -20, -10, -2,
+ -20, -10, 2,
+ -19, 0, -0.5,
+ -19, 0, 0.5,
+ -19.691, 0.951057, -0.5,
+ -19.691, 0.951057, 0.5,
+ -20.809, 0.587785, -0.5,
+ -20.809, 0.587785, 0.5,
+ -20.809, -0.587785, -0.5,
+ -20.809, -0.587785, 0.5,
+ -19.691, -0.951057, -0.5,
+ -19.691, -0.951057, 0.5,
+ -20, 0, -0.5,
+ -20, 0, 0.5,
+ -18, 0, -1,
+ -18, 0, 1,
+ -19.382, 1.90211, -1,
+ -19.382, 1.90211, 1,
+ -21.618, 1.17557, -1,
+ -21.618, 1.17557, 1,
+ -21.618, -1.17557, -1,
+ -21.618, -1.17557, 1,
+ -19.382, -1.90211, -1,
+ -19.382, -1.90211, 1,
+ -20, 0, -1,
+ -20, 0, 1,
+ -17, 0, -1.5,
+ -17, 0, 1.5,
+ -19.0729, 2.85317, -1.5,
+ -19.0729, 2.85317, 1.5,
+ -22.4271, 1.76336, -1.5,
+ -22.4271, 1.76336, 1.5,
+ -22.4271, -1.76336, -1.5,
+ -22.4271, -1.76336, 1.5,
+ -19.0729, -2.85317, -1.5,
+ -19.0729, -2.85317, 1.5,
+ -20, 0, -1.5,
+ -20, 0, 1.5,
+ -16, 0, -2,
+ -16, 0, 2,
+ -18.7639, 3.80423, -2,
+ -18.7639, 3.80423, 2,
+ -23.2361, 2.35114, -2,
+ -23.2361, 2.35114, 2,
+ -23.2361, -2.35114, -2,
+ -23.2361, -2.35114, 2,
+ -18.7639, -3.80423, -2,
+ -18.7639, -3.80423, 2,
+ -20, 0, -2,
+ -20, 0, 2,
+ -19, 10, -0.5,
+ -19, 10, 0.5,
+ -19.691, 10.9511, -0.5,
+ -19.691, 10.9511, 0.5,
+ -20.809, 10.5878, -0.5,
+ -20.809, 10.5878, 0.5,
+ -20.809, 9.41221, -0.5,
+ -20.809, 9.41221, 0.5,
+ -19.691, 9.04894, -0.5,
+ -19.691, 9.04894, 0.5,
+ -20, 10, -0.5,
+ -20, 10, 0.5,
+ -18, 10, -1,
+ -18, 10, 1,
+ -19.382, 11.9021, -1,
+ -19.382, 11.9021, 1,
+ -21.618, 11.1756, -1,
+ -21.618, 11.1756, 1,
+ -21.618, 8.82443, -1,
+ -21.618, 8.82443, 1,
+ -19.382, 8.09789, -1,
+ -19.382, 8.09789, 1,
+ -20, 10, -1,
+ -20, 10, 1,
+ -17, 10, -1.5,
+ -17, 10, 1.5,
+ -19.0729, 12.8532, -1.5,
+ -19.0729, 12.8532, 1.5,
+ -22.4271, 11.7634, -1.5,
+ -22.4271, 11.7634, 1.5,
+ -22.4271, 8.23664, -1.5,
+ -22.4271, 8.23664, 1.5,
+ -19.0729, 7.14683, -1.5,
+ -19.0729, 7.14683, 1.5,
+ -20, 10, -1.5,
+ -20, 10, 1.5,
+ -16, 10, -2,
+ -16, 10, 2,
+ -18.7639, 13.8042, -2,
+ -18.7639, 13.8042, 2,
+ -23.2361, 12.3511, -2,
+ -23.2361, 12.3511, 2,
+ -23.2361, 7.64886, -2,
+ -23.2361, 7.64886, 2,
+ -18.7639, 6.19577, -2,
+ -18.7639, 6.19577, 2,
+ -20, 10, -2,
+ -20, 10, 2,
+ -9, -20, -0.5,
+ -9, -20, 0.5,
+ -9.69098, -19.0489, -0.5,
+ -9.69098, -19.0489, 0.5,
+ -10.809, -19.4122, -0.5,
+ -10.809, -19.4122, 0.5,
+ -10.809, -20.5878, -0.5,
+ -10.809, -20.5878, 0.5,
+ -9.69098, -20.9511, -0.5,
+ -9.69098, -20.9511, 0.5,
+ -10, -20, -0.5,
+ -10, -20, 0.5,
+ -8, -20, -1,
+ -8, -20, 1,
+ -9.38197, -18.0979, -1,
+ -9.38197, -18.0979, 1,
+ -11.618, -18.8244, -1,
+ -11.618, -18.8244, 1,
+ -11.618, -21.1756, -1,
+ -11.618, -21.1756, 1,
+ -9.38197, -21.9021, -1,
+ -9.38197, -21.9021, 1,
+ -10, -20, -1,
+ -10, -20, 1,
+ -7, -20, -1.5,
+ -7, -20, 1.5,
+ -9.07295, -17.1468, -1.5,
+ -9.07295, -17.1468, 1.5,
+ -12.4271, -18.2366, -1.5,
+ -12.4271, -18.2366, 1.5,
+ -12.4271, -21.7634, -1.5,
+ -12.4271, -21.7634, 1.5,
+ -9.07295, -22.8532, -1.5,
+ -9.07295, -22.8532, 1.5,
+ -10, -20, -1.5,
+ -10, -20, 1.5,
+ -6, -20, -2,
+ -6, -20, 2,
+ -8.76393, -16.1958, -2,
+ -8.76393, -16.1958, 2,
+ -13.2361, -17.6489, -2,
+ -13.2361, -17.6489, 2,
+ -13.2361, -22.3511, -2,
+ -13.2361, -22.3511, 2,
+ -8.76393, -23.8042, -2,
+ -8.76393, -23.8042, 2,
+ -10, -20, -2,
+ -10, -20, 2,
+ -9, -10, -0.5,
+ -9, -10, 0.5,
+ -9.69098, -9.04894, -0.5,
+ -9.69098, -9.04894, 0.5,
+ -10.809, -9.41221, -0.5,
+ -10.809, -9.41221, 0.5,
+ -10.809, -10.5878, -0.5,
+ -10.809, -10.5878, 0.5,
+ -9.69098, -10.9511, -0.5,
+ -9.69098, -10.9511, 0.5,
+ -10, -10, -0.5,
+ -10, -10, 0.5,
+ -8, -10, -1,
+ -8, -10, 1,
+ -9.38197, -8.09789, -1,
+ -9.38197, -8.09789, 1,
+ -11.618, -8.82443, -1,
+ -11.618, -8.82443, 1,
+ -11.618, -11.1756, -1,
+ -11.618, -11.1756, 1,
+ -9.38197, -11.9021, -1,
+ -9.38197, -11.9021, 1,
+ -10, -10, -1,
+ -10, -10, 1,
+ -7, -10, -1.5,
+ -7, -10, 1.5,
+ -9.07295, -7.14683, -1.5,
+ -9.07295, -7.14683, 1.5,
+ -12.4271, -8.23664, -1.5,
+ -12.4271, -8.23664, 1.5,
+ -12.4271, -11.7634, -1.5,
+ -12.4271, -11.7634, 1.5,
+ -9.07295, -12.8532, -1.5,
+ -9.07295, -12.8532, 1.5,
+ -10, -10, -1.5,
+ -10, -10, 1.5,
+ -6, -10, -2,
+ -6, -10, 2,
+ -8.76393, -6.19577, -2,
+ -8.76393, -6.19577, 2,
+ -13.2361, -7.64886, -2,
+ -13.2361, -7.64886, 2,
+ -13.2361, -12.3511, -2,
+ -13.2361, -12.3511, 2,
+ -8.76393, -13.8042, -2,
+ -8.76393, -13.8042, 2,
+ -10, -10, -2,
+ -10, -10, 2,
+ -9, 0, -0.5,
+ -9, 0, 0.5,
+ -9.69098, 0.951057, -0.5,
+ -9.69098, 0.951057, 0.5,
+ -10.809, 0.587785, -0.5,
+ -10.809, 0.587785, 0.5,
+ -10.809, -0.587785, -0.5,
+ -10.809, -0.587785, 0.5,
+ -9.69098, -0.951057, -0.5,
+ -9.69098, -0.951057, 0.5,
+ -10, 0, -0.5,
+ -10, 0, 0.5,
+ -8, 0, -1,
+ -8, 0, 1,
+ -9.38197, 1.90211, -1,
+ -9.38197, 1.90211, 1,
+ -11.618, 1.17557, -1,
+ -11.618, 1.17557, 1,
+ -11.618, -1.17557, -1,
+ -11.618, -1.17557, 1,
+ -9.38197, -1.90211, -1,
+ -9.38197, -1.90211, 1,
+ -10, 0, -1,
+ -10, 0, 1,
+ -7, 0, -1.5,
+ -7, 0, 1.5,
+ -9.07295, 2.85317, -1.5,
+ -9.07295, 2.85317, 1.5,
+ -12.4271, 1.76336, -1.5,
+ -12.4271, 1.76336, 1.5,
+ -12.4271, -1.76336, -1.5,
+ -12.4271, -1.76336, 1.5,
+ -9.07295, -2.85317, -1.5,
+ -9.07295, -2.85317, 1.5,
+ -10, 0, -1.5,
+ -10, 0, 1.5,
+ -6, 0, -2,
+ -6, 0, 2,
+ -8.76393, 3.80423, -2,
+ -8.76393, 3.80423, 2,
+ -13.2361, 2.35114, -2,
+ -13.2361, 2.35114, 2,
+ -13.2361, -2.35114, -2,
+ -13.2361, -2.35114, 2,
+ -8.76393, -3.80423, -2,
+ -8.76393, -3.80423, 2,
+ -10, 0, -2,
+ -10, 0, 2,
+ -9, 10, -0.5,
+ -9, 10, 0.5,
+ -9.69098, 10.9511, -0.5,
+ -9.69098, 10.9511, 0.5,
+ -10.809, 10.5878, -0.5,
+ -10.809, 10.5878, 0.5,
+ -10.809, 9.41221, -0.5,
+ -10.809, 9.41221, 0.5,
+ -9.69098, 9.04894, -0.5,
+ -9.69098, 9.04894, 0.5,
+ -10, 10, -0.5,
+ -10, 10, 0.5,
+ -8, 10, -1,
+ -8, 10, 1,
+ -9.38197, 11.9021, -1,
+ -9.38197, 11.9021, 1,
+ -11.618, 11.1756, -1,
+ -11.618, 11.1756, 1,
+ -11.618, 8.82443, -1,
+ -11.618, 8.82443, 1,
+ -9.38197, 8.09789, -1,
+ -9.38197, 8.09789, 1,
+ -10, 10, -1,
+ -10, 10, 1,
+ -7, 10, -1.5,
+ -7, 10, 1.5,
+ -9.07295, 12.8532, -1.5,
+ -9.07295, 12.8532, 1.5,
+ -12.4271, 11.7634, -1.5,
+ -12.4271, 11.7634, 1.5,
+ -12.4271, 8.23664, -1.5,
+ -12.4271, 8.23664, 1.5,
+ -9.07295, 7.14683, -1.5,
+ -9.07295, 7.14683, 1.5,
+ -10, 10, -1.5,
+ -10, 10, 1.5,
+ -6, 10, -2,
+ -6, 10, 2,
+ -8.76393, 13.8042, -2,
+ -8.76393, 13.8042, 2,
+ -13.2361, 12.3511, -2,
+ -13.2361, 12.3511, 2,
+ -13.2361, 7.64886, -2,
+ -13.2361, 7.64886, 2,
+ -8.76393, 6.19577, -2,
+ -8.76393, 6.19577, 2,
+ -10, 10, -2,
+ -10, 10, 2,
+ 1, -20, -0.5,
+ 1, -20, 0.5,
+ 0.309017, -19.0489, -0.5,
+ 0.309017, -19.0489, 0.5,
+ -0.809017, -19.4122, -0.5,
+ -0.809017, -19.4122, 0.5,
+ -0.809017, -20.5878, -0.5,
+ -0.809017, -20.5878, 0.5,
+ 0.309017, -20.9511, -0.5,
+ 0.309017, -20.9511, 0.5,
+ 0, -20, -0.5,
+ 0, -20, 0.5,
+ 2, -20, -1,
+ 2, -20, 1,
+ 0.618034, -18.0979, -1,
+ 0.618034, -18.0979, 1,
+ -1.61803, -18.8244, -1,
+ -1.61803, -18.8244, 1,
+ -1.61803, -21.1756, -1,
+ -1.61803, -21.1756, 1,
+ 0.618034, -21.9021, -1,
+ 0.618034, -21.9021, 1,
+ 0, -20, -1,
+ 0, -20, 1,
+ 3, -20, -1.5,
+ 3, -20, 1.5,
+ 0.927051, -17.1468, -1.5,
+ 0.927051, -17.1468, 1.5,
+ -2.42705, -18.2366, -1.5,
+ -2.42705, -18.2366, 1.5,
+ -2.42705, -21.7634, -1.5,
+ -2.42705, -21.7634, 1.5,
+ 0.927051, -22.8532, -1.5,
+ 0.927051, -22.8532, 1.5,
+ 0, -20, -1.5,
+ 0, -20, 1.5,
+ 4, -20, -2,
+ 4, -20, 2,
+ 1.23607, -16.1958, -2,
+ 1.23607, -16.1958, 2,
+ -3.23607, -17.6489, -2,
+ -3.23607, -17.6489, 2,
+ -3.23607, -22.3511, -2,
+ -3.23607, -22.3511, 2,
+ 1.23607, -23.8042, -2,
+ 1.23607, -23.8042, 2,
+ 0, -20, -2,
+ 0, -20, 2,
+ 1, -10, -0.5,
+ 1, -10, 0.5,
+ 0.309017, -9.04894, -0.5,
+ 0.309017, -9.04894, 0.5,
+ -0.809017, -9.41221, -0.5,
+ -0.809017, -9.41221, 0.5,
+ -0.809017, -10.5878, -0.5,
+ -0.809017, -10.5878, 0.5,
+ 0.309017, -10.9511, -0.5,
+ 0.309017, -10.9511, 0.5,
+ 0, -10, -0.5,
+ 0, -10, 0.5,
+ 2, -10, -1,
+ 2, -10, 1,
+ 0.618034, -8.09789, -1,
+ 0.618034, -8.09789, 1,
+ -1.61803, -8.82443, -1,
+ -1.61803, -8.82443, 1,
+ -1.61803, -11.1756, -1,
+ -1.61803, -11.1756, 1,
+ 0.618034, -11.9021, -1,
+ 0.618034, -11.9021, 1,
+ 0, -10, -1,
+ 0, -10, 1,
+ 3, -10, -1.5,
+ 3, -10, 1.5,
+ 0.927051, -7.14683, -1.5,
+ 0.927051, -7.14683, 1.5,
+ -2.42705, -8.23664, -1.5,
+ -2.42705, -8.23664, 1.5,
+ -2.42705, -11.7634, -1.5,
+ -2.42705, -11.7634, 1.5,
+ 0.927051, -12.8532, -1.5,
+ 0.927051, -12.8532, 1.5,
+ 0, -10, -1.5,
+ 0, -10, 1.5,
+ 4, -10, -2,
+ 4, -10, 2,
+ 1.23607, -6.19577, -2,
+ 1.23607, -6.19577, 2,
+ -3.23607, -7.64886, -2,
+ -3.23607, -7.64886, 2,
+ -3.23607, -12.3511, -2,
+ -3.23607, -12.3511, 2,
+ 1.23607, -13.8042, -2,
+ 1.23607, -13.8042, 2,
+ 0, -10, -2,
+ 0, -10, 2,
+ 1, 0, -0.5,
+ 1, 0, 0.5,
+ 0.309017, 0.951057, -0.5,
+ 0.309017, 0.951057, 0.5,
+ -0.809017, 0.587785, -0.5,
+ -0.809017, 0.587785, 0.5,
+ -0.809017, -0.587785, -0.5,
+ -0.809017, -0.587785, 0.5,
+ 0.309017, -0.951057, -0.5,
+ 0.309017, -0.951057, 0.5,
+ 0, 0, -0.5,
+ 0, 0, 0.5,
+ 2, 0, -1,
+ 2, 0, 1,
+ 0.618034, 1.90211, -1,
+ 0.618034, 1.90211, 1,
+ -1.61803, 1.17557, -1,
+ -1.61803, 1.17557, 1,
+ -1.61803, -1.17557, -1,
+ -1.61803, -1.17557, 1,
+ 0.618034, -1.90211, -1,
+ 0.618034, -1.90211, 1,
+ 0, 0, -1,
+ 0, 0, 1,
+ 3, 0, -1.5,
+ 3, 0, 1.5,
+ 0.927051, 2.85317, -1.5,
+ 0.927051, 2.85317, 1.5,
+ -2.42705, 1.76336, -1.5,
+ -2.42705, 1.76336, 1.5,
+ -2.42705, -1.76336, -1.5,
+ -2.42705, -1.76336, 1.5,
+ 0.927051, -2.85317, -1.5,
+ 0.927051, -2.85317, 1.5,
+ 0, 0, -1.5,
+ 0, 0, 1.5,
+ 4, 0, -2,
+ 4, 0, 2,
+ 1.23607, 3.80423, -2,
+ 1.23607, 3.80423, 2,
+ -3.23607, 2.35114, -2,
+ -3.23607, 2.35114, 2,
+ -3.23607, -2.35114, -2,
+ -3.23607, -2.35114, 2,
+ 1.23607, -3.80423, -2,
+ 1.23607, -3.80423, 2,
+ 0, 0, -2,
+ 0, 0, 2,
+ 1, 10, -0.5,
+ 1, 10, 0.5,
+ 0.309017, 10.9511, -0.5,
+ 0.309017, 10.9511, 0.5,
+ -0.809017, 10.5878, -0.5,
+ -0.809017, 10.5878, 0.5,
+ -0.809017, 9.41221, -0.5,
+ -0.809017, 9.41221, 0.5,
+ 0.309017, 9.04894, -0.5,
+ 0.309017, 9.04894, 0.5,
+ 0, 10, -0.5,
+ 0, 10, 0.5,
+ 2, 10, -1,
+ 2, 10, 1,
+ 0.618034, 11.9021, -1,
+ 0.618034, 11.9021, 1,
+ -1.61803, 11.1756, -1,
+ -1.61803, 11.1756, 1,
+ -1.61803, 8.82443, -1,
+ -1.61803, 8.82443, 1,
+ 0.618034, 8.09789, -1,
+ 0.618034, 8.09789, 1,
+ 0, 10, -1,
+ 0, 10, 1,
+ 3, 10, -1.5,
+ 3, 10, 1.5,
+ 0.927051, 12.8532, -1.5,
+ 0.927051, 12.8532, 1.5,
+ -2.42705, 11.7634, -1.5,
+ -2.42705, 11.7634, 1.5,
+ -2.42705, 8.23664, -1.5,
+ -2.42705, 8.23664, 1.5,
+ 0.927051, 7.14683, -1.5,
+ 0.927051, 7.14683, 1.5,
+ 0, 10, -1.5,
+ 0, 10, 1.5,
+ 4, 10, -2,
+ 4, 10, 2,
+ 1.23607, 13.8042, -2,
+ 1.23607, 13.8042, 2,
+ -3.23607, 12.3511, -2,
+ -3.23607, 12.3511, 2,
+ -3.23607, 7.64886, -2,
+ -3.23607, 7.64886, 2,
+ 1.23607, 6.19577, -2,
+ 1.23607, 6.19577, 2,
+ 0, 10, -2,
+ 0, 10, 2,
+ 11, -20, -0.5,
+ 11, -20, 0.5,
+ 10.309, -19.0489, -0.5,
+ 10.309, -19.0489, 0.5,
+ 9.19098, -19.4122, -0.5,
+ 9.19098, -19.4122, 0.5,
+ 9.19098, -20.5878, -0.5,
+ 9.19098, -20.5878, 0.5,
+ 10.309, -20.9511, -0.5,
+ 10.309, -20.9511, 0.5,
+ 10, -20, -0.5,
+ 10, -20, 0.5,
+ 12, -20, -1,
+ 12, -20, 1,
+ 10.618, -18.0979, -1,
+ 10.618, -18.0979, 1,
+ 8.38197, -18.8244, -1,
+ 8.38197, -18.8244, 1,
+ 8.38197, -21.1756, -1,
+ 8.38197, -21.1756, 1,
+ 10.618, -21.9021, -1,
+ 10.618, -21.9021, 1,
+ 10, -20, -1,
+ 10, -20, 1,
+ 13, -20, -1.5,
+ 13, -20, 1.5,
+ 10.9271, -17.1468, -1.5,
+ 10.9271, -17.1468, 1.5,
+ 7.57295, -18.2366, -1.5,
+ 7.57295, -18.2366, 1.5,
+ 7.57295, -21.7634, -1.5,
+ 7.57295, -21.7634, 1.5,
+ 10.9271, -22.8532, -1.5,
+ 10.9271, -22.8532, 1.5,
+ 10, -20, -1.5,
+ 10, -20, 1.5,
+ 14, -20, -2,
+ 14, -20, 2,
+ 11.2361, -16.1958, -2,
+ 11.2361, -16.1958, 2,
+ 6.76393, -17.6489, -2,
+ 6.76393, -17.6489, 2,
+ 6.76393, -22.3511, -2,
+ 6.76393, -22.3511, 2,
+ 11.2361, -23.8042, -2,
+ 11.2361, -23.8042, 2,
+ 10, -20, -2,
+ 10, -20, 2,
+ 11, -10, -0.5,
+ 11, -10, 0.5,
+ 10.309, -9.04894, -0.5,
+ 10.309, -9.04894, 0.5,
+ 9.19098, -9.41221, -0.5,
+ 9.19098, -9.41221, 0.5,
+ 9.19098, -10.5878, -0.5,
+ 9.19098, -10.5878, 0.5,
+ 10.309, -10.9511, -0.5,
+ 10.309, -10.9511, 0.5,
+ 10, -10, -0.5,
+ 10, -10, 0.5,
+ 12, -10, -1,
+ 12, -10, 1,
+ 10.618, -8.09789, -1,
+ 10.618, -8.09789, 1,
+ 8.38197, -8.82443, -1,
+ 8.38197, -8.82443, 1,
+ 8.38197, -11.1756, -1,
+ 8.38197, -11.1756, 1,
+ 10.618, -11.9021, -1,
+ 10.618, -11.9021, 1,
+ 10, -10, -1,
+ 10, -10, 1,
+ 13, -10, -1.5,
+ 13, -10, 1.5,
+ 10.9271, -7.14683, -1.5,
+ 10.9271, -7.14683, 1.5,
+ 7.57295, -8.23664, -1.5,
+ 7.57295, -8.23664, 1.5,
+ 7.57295, -11.7634, -1.5,
+ 7.57295, -11.7634, 1.5,
+ 10.9271, -12.8532, -1.5,
+ 10.9271, -12.8532, 1.5,
+ 10, -10, -1.5,
+ 10, -10, 1.5,
+ 14, -10, -2,
+ 14, -10, 2,
+ 11.2361, -6.19577, -2,
+ 11.2361, -6.19577, 2,
+ 6.76393, -7.64886, -2,
+ 6.76393, -7.64886, 2,
+ 6.76393, -12.3511, -2,
+ 6.76393, -12.3511, 2,
+ 11.2361, -13.8042, -2,
+ 11.2361, -13.8042, 2,
+ 10, -10, -2,
+ 10, -10, 2,
+ 11, 0, -0.5,
+ 11, 0, 0.5,
+ 10.309, 0.951057, -0.5,
+ 10.309, 0.951057, 0.5,
+ 9.19098, 0.587785, -0.5,
+ 9.19098, 0.587785, 0.5,
+ 9.19098, -0.587785, -0.5,
+ 9.19098, -0.587785, 0.5,
+ 10.309, -0.951057, -0.5,
+ 10.309, -0.951057, 0.5,
+ 10, 0, -0.5,
+ 10, 0, 0.5,
+ 12, 0, -1,
+ 12, 0, 1,
+ 10.618, 1.90211, -1,
+ 10.618, 1.90211, 1,
+ 8.38197, 1.17557, -1,
+ 8.38197, 1.17557, 1,
+ 8.38197, -1.17557, -1,
+ 8.38197, -1.17557, 1,
+ 10.618, -1.90211, -1,
+ 10.618, -1.90211, 1,
+ 10, 0, -1,
+ 10, 0, 1,
+ 13, 0, -1.5,
+ 13, 0, 1.5,
+ 10.9271, 2.85317, -1.5,
+ 10.9271, 2.85317, 1.5,
+ 7.57295, 1.76336, -1.5,
+ 7.57295, 1.76336, 1.5,
+ 7.57295, -1.76336, -1.5,
+ 7.57295, -1.76336, 1.5,
+ 10.9271, -2.85317, -1.5,
+ 10.9271, -2.85317, 1.5,
+ 10, 0, -1.5,
+ 10, 0, 1.5,
+ 14, 0, -2,
+ 14, 0, 2,
+ 11.2361, 3.80423, -2,
+ 11.2361, 3.80423, 2,
+ 6.76393, 2.35114, -2,
+ 6.76393, 2.35114, 2,
+ 6.76393, -2.35114, -2,
+ 6.76393, -2.35114, 2,
+ 11.2361, -3.80423, -2,
+ 11.2361, -3.80423, 2,
+ 10, 0, -2,
+ 10, 0, 2,
+ 11, 10, -0.5,
+ 11, 10, 0.5,
+ 10.309, 10.9511, -0.5,
+ 10.309, 10.9511, 0.5,
+ 9.19098, 10.5878, -0.5,
+ 9.19098, 10.5878, 0.5,
+ 9.19098, 9.41221, -0.5,
+ 9.19098, 9.41221, 0.5,
+ 10.309, 9.04894, -0.5,
+ 10.309, 9.04894, 0.5,
+ 10, 10, -0.5,
+ 10, 10, 0.5,
+ 12, 10, -1,
+ 12, 10, 1,
+ 10.618, 11.9021, -1,
+ 10.618, 11.9021, 1,
+ 8.38197, 11.1756, -1,
+ 8.38197, 11.1756, 1,
+ 8.38197, 8.82443, -1,
+ 8.38197, 8.82443, 1,
+ 10.618, 8.09789, -1,
+ 10.618, 8.09789, 1,
+ 10, 10, -1,
+ 10, 10, 1,
+ 13, 10, -1.5,
+ 13, 10, 1.5,
+ 10.9271, 12.8532, -1.5,
+ 10.9271, 12.8532, 1.5,
+ 7.57295, 11.7634, -1.5,
+ 7.57295, 11.7634, 1.5,
+ 7.57295, 8.23664, -1.5,
+ 7.57295, 8.23664, 1.5,
+ 10.9271, 7.14683, -1.5,
+ 10.9271, 7.14683, 1.5,
+ 10, 10, -1.5,
+ 10, 10, 1.5,
+ 14, 10, -2,
+ 14, 10, 2,
+ 11.2361, 13.8042, -2,
+ 11.2361, 13.8042, 2,
+ 6.76393, 12.3511, -2,
+ 6.76393, 12.3511, 2,
+ 6.76393, 7.64886, -2,
+ 6.76393, 7.64886, 2,
+ 11.2361, 6.19577, -2,
+ 11.2361, 6.19577, 2,
+ 10, 10, -2,
+ 10, 10, 2
+};
+static const unsigned some_enclosures_triangles_count = 1280;
+static const unsigned some_enclosures_triangles[3840] =
+{
+ 0, 1, 2,
+ 2, 1, 3,
+ 2, 3, 4,
+ 4, 3, 5,
+ 4, 5, 6,
+ 6, 5, 7,
+ 6, 7, 8,
+ 8, 7, 9,
+ 8, 9, 0,
+ 0, 9, 1,
+ 10, 0, 2,
+ 10, 2, 4,
+ 10, 4, 6,
+ 10, 6, 8,
+ 10, 8, 0,
+ 11, 3, 1,
+ 11, 5, 3,
+ 11, 7, 5,
+ 11, 9, 7,
+ 11, 1, 9,
+ 12, 13, 14,
+ 14, 13, 15,
+ 14, 15, 16,
+ 16, 15, 17,
+ 16, 17, 18,
+ 18, 17, 19,
+ 18, 19, 20,
+ 20, 19, 21,
+ 20, 21, 12,
+ 12, 21, 13,
+ 22, 12, 14,
+ 22, 14, 16,
+ 22, 16, 18,
+ 22, 18, 20,
+ 22, 20, 12,
+ 23, 15, 13,
+ 23, 17, 15,
+ 23, 19, 17,
+ 23, 21, 19,
+ 23, 13, 21,
+ 24, 25, 26,
+ 26, 25, 27,
+ 26, 27, 28,
+ 28, 27, 29,
+ 28, 29, 30,
+ 30, 29, 31,
+ 30, 31, 32,
+ 32, 31, 33,
+ 32, 33, 24,
+ 24, 33, 25,
+ 34, 24, 26,
+ 34, 26, 28,
+ 34, 28, 30,
+ 34, 30, 32,
+ 34, 32, 24,
+ 35, 27, 25,
+ 35, 29, 27,
+ 35, 31, 29,
+ 35, 33, 31,
+ 35, 25, 33,
+ 36, 37, 38,
+ 38, 37, 39,
+ 38, 39, 40,
+ 40, 39, 41,
+ 40, 41, 42,
+ 42, 41, 43,
+ 42, 43, 44,
+ 44, 43, 45,
+ 44, 45, 36,
+ 36, 45, 37,
+ 46, 36, 38,
+ 46, 38, 40,
+ 46, 40, 42,
+ 46, 42, 44,
+ 46, 44, 36,
+ 47, 39, 37,
+ 47, 41, 39,
+ 47, 43, 41,
+ 47, 45, 43,
+ 47, 37, 45,
+ 48, 49, 50,
+ 50, 49, 51,
+ 50, 51, 52,
+ 52, 51, 53,
+ 52, 53, 54,
+ 54, 53, 55,
+ 54, 55, 56,
+ 56, 55, 57,
+ 56, 57, 48,
+ 48, 57, 49,
+ 58, 48, 50,
+ 58, 50, 52,
+ 58, 52, 54,
+ 58, 54, 56,
+ 58, 56, 48,
+ 59, 51, 49,
+ 59, 53, 51,
+ 59, 55, 53,
+ 59, 57, 55,
+ 59, 49, 57,
+ 60, 61, 62,
+ 62, 61, 63,
+ 62, 63, 64,
+ 64, 63, 65,
+ 64, 65, 66,
+ 66, 65, 67,
+ 66, 67, 68,
+ 68, 67, 69,
+ 68, 69, 60,
+ 60, 69, 61,
+ 70, 60, 62,
+ 70, 62, 64,
+ 70, 64, 66,
+ 70, 66, 68,
+ 70, 68, 60,
+ 71, 63, 61,
+ 71, 65, 63,
+ 71, 67, 65,
+ 71, 69, 67,
+ 71, 61, 69,
+ 72, 73, 74,
+ 74, 73, 75,
+ 74, 75, 76,
+ 76, 75, 77,
+ 76, 77, 78,
+ 78, 77, 79,
+ 78, 79, 80,
+ 80, 79, 81,
+ 80, 81, 72,
+ 72, 81, 73,
+ 82, 72, 74,
+ 82, 74, 76,
+ 82, 76, 78,
+ 82, 78, 80,
+ 82, 80, 72,
+ 83, 75, 73,
+ 83, 77, 75,
+ 83, 79, 77,
+ 83, 81, 79,
+ 83, 73, 81,
+ 84, 85, 86,
+ 86, 85, 87,
+ 86, 87, 88,
+ 88, 87, 89,
+ 88, 89, 90,
+ 90, 89, 91,
+ 90, 91, 92,
+ 92, 91, 93,
+ 92, 93, 84,
+ 84, 93, 85,
+ 94, 84, 86,
+ 94, 86, 88,
+ 94, 88, 90,
+ 94, 90, 92,
+ 94, 92, 84,
+ 95, 87, 85,
+ 95, 89, 87,
+ 95, 91, 89,
+ 95, 93, 91,
+ 95, 85, 93,
+ 96, 97, 98,
+ 98, 97, 99,
+ 98, 99, 100,
+ 100, 99, 101,
+ 100, 101, 102,
+ 102, 101, 103,
+ 102, 103, 104,
+ 104, 103, 105,
+ 104, 105, 96,
+ 96, 105, 97,
+ 106, 96, 98,
+ 106, 98, 100,
+ 106, 100, 102,
+ 106, 102, 104,
+ 106, 104, 96,
+ 107, 99, 97,
+ 107, 101, 99,
+ 107, 103, 101,
+ 107, 105, 103,
+ 107, 97, 105,
+ 108, 109, 110,
+ 110, 109, 111,
+ 110, 111, 112,
+ 112, 111, 113,
+ 112, 113, 114,
+ 114, 113, 115,
+ 114, 115, 116,
+ 116, 115, 117,
+ 116, 117, 108,
+ 108, 117, 109,
+ 118, 108, 110,
+ 118, 110, 112,
+ 118, 112, 114,
+ 118, 114, 116,
+ 118, 116, 108,
+ 119, 111, 109,
+ 119, 113, 111,
+ 119, 115, 113,
+ 119, 117, 115,
+ 119, 109, 117,
+ 120, 121, 122,
+ 122, 121, 123,
+ 122, 123, 124,
+ 124, 123, 125,
+ 124, 125, 126,
+ 126, 125, 127,
+ 126, 127, 128,
+ 128, 127, 129,
+ 128, 129, 120,
+ 120, 129, 121,
+ 130, 120, 122,
+ 130, 122, 124,
+ 130, 124, 126,
+ 130, 126, 128,
+ 130, 128, 120,
+ 131, 123, 121,
+ 131, 125, 123,
+ 131, 127, 125,
+ 131, 129, 127,
+ 131, 121, 129,
+ 132, 133, 134,
+ 134, 133, 135,
+ 134, 135, 136,
+ 136, 135, 137,
+ 136, 137, 138,
+ 138, 137, 139,
+ 138, 139, 140,
+ 140, 139, 141,
+ 140, 141, 132,
+ 132, 141, 133,
+ 142, 132, 134,
+ 142, 134, 136,
+ 142, 136, 138,
+ 142, 138, 140,
+ 142, 140, 132,
+ 143, 135, 133,
+ 143, 137, 135,
+ 143, 139, 137,
+ 143, 141, 139,
+ 143, 133, 141,
+ 144, 145, 146,
+ 146, 145, 147,
+ 146, 147, 148,
+ 148, 147, 149,
+ 148, 149, 150,
+ 150, 149, 151,
+ 150, 151, 152,
+ 152, 151, 153,
+ 152, 153, 144,
+ 144, 153, 145,
+ 154, 144, 146,
+ 154, 146, 148,
+ 154, 148, 150,
+ 154, 150, 152,
+ 154, 152, 144,
+ 155, 147, 145,
+ 155, 149, 147,
+ 155, 151, 149,
+ 155, 153, 151,
+ 155, 145, 153,
+ 156, 157, 158,
+ 158, 157, 159,
+ 158, 159, 160,
+ 160, 159, 161,
+ 160, 161, 162,
+ 162, 161, 163,
+ 162, 163, 164,
+ 164, 163, 165,
+ 164, 165, 156,
+ 156, 165, 157,
+ 166, 156, 158,
+ 166, 158, 160,
+ 166, 160, 162,
+ 166, 162, 164,
+ 166, 164, 156,
+ 167, 159, 157,
+ 167, 161, 159,
+ 167, 163, 161,
+ 167, 165, 163,
+ 167, 157, 165,
+ 168, 169, 170,
+ 170, 169, 171,
+ 170, 171, 172,
+ 172, 171, 173,
+ 172, 173, 174,
+ 174, 173, 175,
+ 174, 175, 176,
+ 176, 175, 177,
+ 176, 177, 168,
+ 168, 177, 169,
+ 178, 168, 170,
+ 178, 170, 172,
+ 178, 172, 174,
+ 178, 174, 176,
+ 178, 176, 168,
+ 179, 171, 169,
+ 179, 173, 171,
+ 179, 175, 173,
+ 179, 177, 175,
+ 179, 169, 177,
+ 180, 181, 182,
+ 182, 181, 183,
+ 182, 183, 184,
+ 184, 183, 185,
+ 184, 185, 186,
+ 186, 185, 187,
+ 186, 187, 188,
+ 188, 187, 189,
+ 188, 189, 180,
+ 180, 189, 181,
+ 190, 180, 182,
+ 190, 182, 184,
+ 190, 184, 186,
+ 190, 186, 188,
+ 190, 188, 180,
+ 191, 183, 181,
+ 191, 185, 183,
+ 191, 187, 185,
+ 191, 189, 187,
+ 191, 181, 189,
+ 192, 193, 194,
+ 194, 193, 195,
+ 194, 195, 196,
+ 196, 195, 197,
+ 196, 197, 198,
+ 198, 197, 199,
+ 198, 199, 200,
+ 200, 199, 201,
+ 200, 201, 192,
+ 192, 201, 193,
+ 202, 192, 194,
+ 202, 194, 196,
+ 202, 196, 198,
+ 202, 198, 200,
+ 202, 200, 192,
+ 203, 195, 193,
+ 203, 197, 195,
+ 203, 199, 197,
+ 203, 201, 199,
+ 203, 193, 201,
+ 204, 205, 206,
+ 206, 205, 207,
+ 206, 207, 208,
+ 208, 207, 209,
+ 208, 209, 210,
+ 210, 209, 211,
+ 210, 211, 212,
+ 212, 211, 213,
+ 212, 213, 204,
+ 204, 213, 205,
+ 214, 204, 206,
+ 214, 206, 208,
+ 214, 208, 210,
+ 214, 210, 212,
+ 214, 212, 204,
+ 215, 207, 205,
+ 215, 209, 207,
+ 215, 211, 209,
+ 215, 213, 211,
+ 215, 205, 213,
+ 216, 217, 218,
+ 218, 217, 219,
+ 218, 219, 220,
+ 220, 219, 221,
+ 220, 221, 222,
+ 222, 221, 223,
+ 222, 223, 224,
+ 224, 223, 225,
+ 224, 225, 216,
+ 216, 225, 217,
+ 226, 216, 218,
+ 226, 218, 220,
+ 226, 220, 222,
+ 226, 222, 224,
+ 226, 224, 216,
+ 227, 219, 217,
+ 227, 221, 219,
+ 227, 223, 221,
+ 227, 225, 223,
+ 227, 217, 225,
+ 228, 229, 230,
+ 230, 229, 231,
+ 230, 231, 232,
+ 232, 231, 233,
+ 232, 233, 234,
+ 234, 233, 235,
+ 234, 235, 236,
+ 236, 235, 237,
+ 236, 237, 228,
+ 228, 237, 229,
+ 238, 228, 230,
+ 238, 230, 232,
+ 238, 232, 234,
+ 238, 234, 236,
+ 238, 236, 228,
+ 239, 231, 229,
+ 239, 233, 231,
+ 239, 235, 233,
+ 239, 237, 235,
+ 239, 229, 237,
+ 240, 241, 242,
+ 242, 241, 243,
+ 242, 243, 244,
+ 244, 243, 245,
+ 244, 245, 246,
+ 246, 245, 247,
+ 246, 247, 248,
+ 248, 247, 249,
+ 248, 249, 240,
+ 240, 249, 241,
+ 250, 240, 242,
+ 250, 242, 244,
+ 250, 244, 246,
+ 250, 246, 248,
+ 250, 248, 240,
+ 251, 243, 241,
+ 251, 245, 243,
+ 251, 247, 245,
+ 251, 249, 247,
+ 251, 241, 249,
+ 252, 253, 254,
+ 254, 253, 255,
+ 254, 255, 256,
+ 256, 255, 257,
+ 256, 257, 258,
+ 258, 257, 259,
+ 258, 259, 260,
+ 260, 259, 261,
+ 260, 261, 252,
+ 252, 261, 253,
+ 262, 252, 254,
+ 262, 254, 256,
+ 262, 256, 258,
+ 262, 258, 260,
+ 262, 260, 252,
+ 263, 255, 253,
+ 263, 257, 255,
+ 263, 259, 257,
+ 263, 261, 259,
+ 263, 253, 261,
+ 264, 265, 266,
+ 266, 265, 267,
+ 266, 267, 268,
+ 268, 267, 269,
+ 268, 269, 270,
+ 270, 269, 271,
+ 270, 271, 272,
+ 272, 271, 273,
+ 272, 273, 264,
+ 264, 273, 265,
+ 274, 264, 266,
+ 274, 266, 268,
+ 274, 268, 270,
+ 274, 270, 272,
+ 274, 272, 264,
+ 275, 267, 265,
+ 275, 269, 267,
+ 275, 271, 269,
+ 275, 273, 271,
+ 275, 265, 273,
+ 276, 277, 278,
+ 278, 277, 279,
+ 278, 279, 280,
+ 280, 279, 281,
+ 280, 281, 282,
+ 282, 281, 283,
+ 282, 283, 284,
+ 284, 283, 285,
+ 284, 285, 276,
+ 276, 285, 277,
+ 286, 276, 278,
+ 286, 278, 280,
+ 286, 280, 282,
+ 286, 282, 284,
+ 286, 284, 276,
+ 287, 279, 277,
+ 287, 281, 279,
+ 287, 283, 281,
+ 287, 285, 283,
+ 287, 277, 285,
+ 288, 289, 290,
+ 290, 289, 291,
+ 290, 291, 292,
+ 292, 291, 293,
+ 292, 293, 294,
+ 294, 293, 295,
+ 294, 295, 296,
+ 296, 295, 297,
+ 296, 297, 288,
+ 288, 297, 289,
+ 298, 288, 290,
+ 298, 290, 292,
+ 298, 292, 294,
+ 298, 294, 296,
+ 298, 296, 288,
+ 299, 291, 289,
+ 299, 293, 291,
+ 299, 295, 293,
+ 299, 297, 295,
+ 299, 289, 297,
+ 300, 301, 302,
+ 302, 301, 303,
+ 302, 303, 304,
+ 304, 303, 305,
+ 304, 305, 306,
+ 306, 305, 307,
+ 306, 307, 308,
+ 308, 307, 309,
+ 308, 309, 300,
+ 300, 309, 301,
+ 310, 300, 302,
+ 310, 302, 304,
+ 310, 304, 306,
+ 310, 306, 308,
+ 310, 308, 300,
+ 311, 303, 301,
+ 311, 305, 303,
+ 311, 307, 305,
+ 311, 309, 307,
+ 311, 301, 309,
+ 312, 313, 314,
+ 314, 313, 315,
+ 314, 315, 316,
+ 316, 315, 317,
+ 316, 317, 318,
+ 318, 317, 319,
+ 318, 319, 320,
+ 320, 319, 321,
+ 320, 321, 312,
+ 312, 321, 313,
+ 322, 312, 314,
+ 322, 314, 316,
+ 322, 316, 318,
+ 322, 318, 320,
+ 322, 320, 312,
+ 323, 315, 313,
+ 323, 317, 315,
+ 323, 319, 317,
+ 323, 321, 319,
+ 323, 313, 321,
+ 324, 325, 326,
+ 326, 325, 327,
+ 326, 327, 328,
+ 328, 327, 329,
+ 328, 329, 330,
+ 330, 329, 331,
+ 330, 331, 332,
+ 332, 331, 333,
+ 332, 333, 324,
+ 324, 333, 325,
+ 334, 324, 326,
+ 334, 326, 328,
+ 334, 328, 330,
+ 334, 330, 332,
+ 334, 332, 324,
+ 335, 327, 325,
+ 335, 329, 327,
+ 335, 331, 329,
+ 335, 333, 331,
+ 335, 325, 333,
+ 336, 337, 338,
+ 338, 337, 339,
+ 338, 339, 340,
+ 340, 339, 341,
+ 340, 341, 342,
+ 342, 341, 343,
+ 342, 343, 344,
+ 344, 343, 345,
+ 344, 345, 336,
+ 336, 345, 337,
+ 346, 336, 338,
+ 346, 338, 340,
+ 346, 340, 342,
+ 346, 342, 344,
+ 346, 344, 336,
+ 347, 339, 337,
+ 347, 341, 339,
+ 347, 343, 341,
+ 347, 345, 343,
+ 347, 337, 345,
+ 348, 349, 350,
+ 350, 349, 351,
+ 350, 351, 352,
+ 352, 351, 353,
+ 352, 353, 354,
+ 354, 353, 355,
+ 354, 355, 356,
+ 356, 355, 357,
+ 356, 357, 348,
+ 348, 357, 349,
+ 358, 348, 350,
+ 358, 350, 352,
+ 358, 352, 354,
+ 358, 354, 356,
+ 358, 356, 348,
+ 359, 351, 349,
+ 359, 353, 351,
+ 359, 355, 353,
+ 359, 357, 355,
+ 359, 349, 357,
+ 360, 361, 362,
+ 362, 361, 363,
+ 362, 363, 364,
+ 364, 363, 365,
+ 364, 365, 366,
+ 366, 365, 367,
+ 366, 367, 368,
+ 368, 367, 369,
+ 368, 369, 360,
+ 360, 369, 361,
+ 370, 360, 362,
+ 370, 362, 364,
+ 370, 364, 366,
+ 370, 366, 368,
+ 370, 368, 360,
+ 371, 363, 361,
+ 371, 365, 363,
+ 371, 367, 365,
+ 371, 369, 367,
+ 371, 361, 369,
+ 372, 373, 374,
+ 374, 373, 375,
+ 374, 375, 376,
+ 376, 375, 377,
+ 376, 377, 378,
+ 378, 377, 379,
+ 378, 379, 380,
+ 380, 379, 381,
+ 380, 381, 372,
+ 372, 381, 373,
+ 382, 372, 374,
+ 382, 374, 376,
+ 382, 376, 378,
+ 382, 378, 380,
+ 382, 380, 372,
+ 383, 375, 373,
+ 383, 377, 375,
+ 383, 379, 377,
+ 383, 381, 379,
+ 383, 373, 381,
+ 384, 385, 386,
+ 386, 385, 387,
+ 386, 387, 388,
+ 388, 387, 389,
+ 388, 389, 390,
+ 390, 389, 391,
+ 390, 391, 392,
+ 392, 391, 393,
+ 392, 393, 384,
+ 384, 393, 385,
+ 394, 384, 386,
+ 394, 386, 388,
+ 394, 388, 390,
+ 394, 390, 392,
+ 394, 392, 384,
+ 395, 387, 385,
+ 395, 389, 387,
+ 395, 391, 389,
+ 395, 393, 391,
+ 395, 385, 393,
+ 396, 397, 398,
+ 398, 397, 399,
+ 398, 399, 400,
+ 400, 399, 401,
+ 400, 401, 402,
+ 402, 401, 403,
+ 402, 403, 404,
+ 404, 403, 405,
+ 404, 405, 396,
+ 396, 405, 397,
+ 406, 396, 398,
+ 406, 398, 400,
+ 406, 400, 402,
+ 406, 402, 404,
+ 406, 404, 396,
+ 407, 399, 397,
+ 407, 401, 399,
+ 407, 403, 401,
+ 407, 405, 403,
+ 407, 397, 405,
+ 408, 409, 410,
+ 410, 409, 411,
+ 410, 411, 412,
+ 412, 411, 413,
+ 412, 413, 414,
+ 414, 413, 415,
+ 414, 415, 416,
+ 416, 415, 417,
+ 416, 417, 408,
+ 408, 417, 409,
+ 418, 408, 410,
+ 418, 410, 412,
+ 418, 412, 414,
+ 418, 414, 416,
+ 418, 416, 408,
+ 419, 411, 409,
+ 419, 413, 411,
+ 419, 415, 413,
+ 419, 417, 415,
+ 419, 409, 417,
+ 420, 421, 422,
+ 422, 421, 423,
+ 422, 423, 424,
+ 424, 423, 425,
+ 424, 425, 426,
+ 426, 425, 427,
+ 426, 427, 428,
+ 428, 427, 429,
+ 428, 429, 420,
+ 420, 429, 421,
+ 430, 420, 422,
+ 430, 422, 424,
+ 430, 424, 426,
+ 430, 426, 428,
+ 430, 428, 420,
+ 431, 423, 421,
+ 431, 425, 423,
+ 431, 427, 425,
+ 431, 429, 427,
+ 431, 421, 429,
+ 432, 433, 434,
+ 434, 433, 435,
+ 434, 435, 436,
+ 436, 435, 437,
+ 436, 437, 438,
+ 438, 437, 439,
+ 438, 439, 440,
+ 440, 439, 441,
+ 440, 441, 432,
+ 432, 441, 433,
+ 442, 432, 434,
+ 442, 434, 436,
+ 442, 436, 438,
+ 442, 438, 440,
+ 442, 440, 432,
+ 443, 435, 433,
+ 443, 437, 435,
+ 443, 439, 437,
+ 443, 441, 439,
+ 443, 433, 441,
+ 444, 445, 446,
+ 446, 445, 447,
+ 446, 447, 448,
+ 448, 447, 449,
+ 448, 449, 450,
+ 450, 449, 451,
+ 450, 451, 452,
+ 452, 451, 453,
+ 452, 453, 444,
+ 444, 453, 445,
+ 454, 444, 446,
+ 454, 446, 448,
+ 454, 448, 450,
+ 454, 450, 452,
+ 454, 452, 444,
+ 455, 447, 445,
+ 455, 449, 447,
+ 455, 451, 449,
+ 455, 453, 451,
+ 455, 445, 453,
+ 456, 457, 458,
+ 458, 457, 459,
+ 458, 459, 460,
+ 460, 459, 461,
+ 460, 461, 462,
+ 462, 461, 463,
+ 462, 463, 464,
+ 464, 463, 465,
+ 464, 465, 456,
+ 456, 465, 457,
+ 466, 456, 458,
+ 466, 458, 460,
+ 466, 460, 462,
+ 466, 462, 464,
+ 466, 464, 456,
+ 467, 459, 457,
+ 467, 461, 459,
+ 467, 463, 461,
+ 467, 465, 463,
+ 467, 457, 465,
+ 468, 469, 470,
+ 470, 469, 471,
+ 470, 471, 472,
+ 472, 471, 473,
+ 472, 473, 474,
+ 474, 473, 475,
+ 474, 475, 476,
+ 476, 475, 477,
+ 476, 477, 468,
+ 468, 477, 469,
+ 478, 468, 470,
+ 478, 470, 472,
+ 478, 472, 474,
+ 478, 474, 476,
+ 478, 476, 468,
+ 479, 471, 469,
+ 479, 473, 471,
+ 479, 475, 473,
+ 479, 477, 475,
+ 479, 469, 477,
+ 480, 481, 482,
+ 482, 481, 483,
+ 482, 483, 484,
+ 484, 483, 485,
+ 484, 485, 486,
+ 486, 485, 487,
+ 486, 487, 488,
+ 488, 487, 489,
+ 488, 489, 480,
+ 480, 489, 481,
+ 490, 480, 482,
+ 490, 482, 484,
+ 490, 484, 486,
+ 490, 486, 488,
+ 490, 488, 480,
+ 491, 483, 481,
+ 491, 485, 483,
+ 491, 487, 485,
+ 491, 489, 487,
+ 491, 481, 489,
+ 492, 493, 494,
+ 494, 493, 495,
+ 494, 495, 496,
+ 496, 495, 497,
+ 496, 497, 498,
+ 498, 497, 499,
+ 498, 499, 500,
+ 500, 499, 501,
+ 500, 501, 492,
+ 492, 501, 493,
+ 502, 492, 494,
+ 502, 494, 496,
+ 502, 496, 498,
+ 502, 498, 500,
+ 502, 500, 492,
+ 503, 495, 493,
+ 503, 497, 495,
+ 503, 499, 497,
+ 503, 501, 499,
+ 503, 493, 501,
+ 504, 505, 506,
+ 506, 505, 507,
+ 506, 507, 508,
+ 508, 507, 509,
+ 508, 509, 510,
+ 510, 509, 511,
+ 510, 511, 512,
+ 512, 511, 513,
+ 512, 513, 504,
+ 504, 513, 505,
+ 514, 504, 506,
+ 514, 506, 508,
+ 514, 508, 510,
+ 514, 510, 512,
+ 514, 512, 504,
+ 515, 507, 505,
+ 515, 509, 507,
+ 515, 511, 509,
+ 515, 513, 511,
+ 515, 505, 513,
+ 516, 517, 518,
+ 518, 517, 519,
+ 518, 519, 520,
+ 520, 519, 521,
+ 520, 521, 522,
+ 522, 521, 523,
+ 522, 523, 524,
+ 524, 523, 525,
+ 524, 525, 516,
+ 516, 525, 517,
+ 526, 516, 518,
+ 526, 518, 520,
+ 526, 520, 522,
+ 526, 522, 524,
+ 526, 524, 516,
+ 527, 519, 517,
+ 527, 521, 519,
+ 527, 523, 521,
+ 527, 525, 523,
+ 527, 517, 525,
+ 528, 529, 530,
+ 530, 529, 531,
+ 530, 531, 532,
+ 532, 531, 533,
+ 532, 533, 534,
+ 534, 533, 535,
+ 534, 535, 536,
+ 536, 535, 537,
+ 536, 537, 528,
+ 528, 537, 529,
+ 538, 528, 530,
+ 538, 530, 532,
+ 538, 532, 534,
+ 538, 534, 536,
+ 538, 536, 528,
+ 539, 531, 529,
+ 539, 533, 531,
+ 539, 535, 533,
+ 539, 537, 535,
+ 539, 529, 537,
+ 540, 541, 542,
+ 542, 541, 543,
+ 542, 543, 544,
+ 544, 543, 545,
+ 544, 545, 546,
+ 546, 545, 547,
+ 546, 547, 548,
+ 548, 547, 549,
+ 548, 549, 540,
+ 540, 549, 541,
+ 550, 540, 542,
+ 550, 542, 544,
+ 550, 544, 546,
+ 550, 546, 548,
+ 550, 548, 540,
+ 551, 543, 541,
+ 551, 545, 543,
+ 551, 547, 545,
+ 551, 549, 547,
+ 551, 541, 549,
+ 552, 553, 554,
+ 554, 553, 555,
+ 554, 555, 556,
+ 556, 555, 557,
+ 556, 557, 558,
+ 558, 557, 559,
+ 558, 559, 560,
+ 560, 559, 561,
+ 560, 561, 552,
+ 552, 561, 553,
+ 562, 552, 554,
+ 562, 554, 556,
+ 562, 556, 558,
+ 562, 558, 560,
+ 562, 560, 552,
+ 563, 555, 553,
+ 563, 557, 555,
+ 563, 559, 557,
+ 563, 561, 559,
+ 563, 553, 561,
+ 564, 565, 566,
+ 566, 565, 567,
+ 566, 567, 568,
+ 568, 567, 569,
+ 568, 569, 570,
+ 570, 569, 571,
+ 570, 571, 572,
+ 572, 571, 573,
+ 572, 573, 564,
+ 564, 573, 565,
+ 574, 564, 566,
+ 574, 566, 568,
+ 574, 568, 570,
+ 574, 570, 572,
+ 574, 572, 564,
+ 575, 567, 565,
+ 575, 569, 567,
+ 575, 571, 569,
+ 575, 573, 571,
+ 575, 565, 573,
+ 576, 577, 578,
+ 578, 577, 579,
+ 578, 579, 580,
+ 580, 579, 581,
+ 580, 581, 582,
+ 582, 581, 583,
+ 582, 583, 584,
+ 584, 583, 585,
+ 584, 585, 576,
+ 576, 585, 577,
+ 586, 576, 578,
+ 586, 578, 580,
+ 586, 580, 582,
+ 586, 582, 584,
+ 586, 584, 576,
+ 587, 579, 577,
+ 587, 581, 579,
+ 587, 583, 581,
+ 587, 585, 583,
+ 587, 577, 585,
+ 588, 589, 590,
+ 590, 589, 591,
+ 590, 591, 592,
+ 592, 591, 593,
+ 592, 593, 594,
+ 594, 593, 595,
+ 594, 595, 596,
+ 596, 595, 597,
+ 596, 597, 588,
+ 588, 597, 589,
+ 598, 588, 590,
+ 598, 590, 592,
+ 598, 592, 594,
+ 598, 594, 596,
+ 598, 596, 588,
+ 599, 591, 589,
+ 599, 593, 591,
+ 599, 595, 593,
+ 599, 597, 595,
+ 599, 589, 597,
+ 600, 601, 602,
+ 602, 601, 603,
+ 602, 603, 604,
+ 604, 603, 605,
+ 604, 605, 606,
+ 606, 605, 607,
+ 606, 607, 608,
+ 608, 607, 609,
+ 608, 609, 600,
+ 600, 609, 601,
+ 610, 600, 602,
+ 610, 602, 604,
+ 610, 604, 606,
+ 610, 606, 608,
+ 610, 608, 600,
+ 611, 603, 601,
+ 611, 605, 603,
+ 611, 607, 605,
+ 611, 609, 607,
+ 611, 601, 609,
+ 612, 613, 614,
+ 614, 613, 615,
+ 614, 615, 616,
+ 616, 615, 617,
+ 616, 617, 618,
+ 618, 617, 619,
+ 618, 619, 620,
+ 620, 619, 621,
+ 620, 621, 612,
+ 612, 621, 613,
+ 622, 612, 614,
+ 622, 614, 616,
+ 622, 616, 618,
+ 622, 618, 620,
+ 622, 620, 612,
+ 623, 615, 613,
+ 623, 617, 615,
+ 623, 619, 617,
+ 623, 621, 619,
+ 623, 613, 621,
+ 624, 625, 626,
+ 626, 625, 627,
+ 626, 627, 628,
+ 628, 627, 629,
+ 628, 629, 630,
+ 630, 629, 631,
+ 630, 631, 632,
+ 632, 631, 633,
+ 632, 633, 624,
+ 624, 633, 625,
+ 634, 624, 626,
+ 634, 626, 628,
+ 634, 628, 630,
+ 634, 630, 632,
+ 634, 632, 624,
+ 635, 627, 625,
+ 635, 629, 627,
+ 635, 631, 629,
+ 635, 633, 631,
+ 635, 625, 633,
+ 636, 637, 638,
+ 638, 637, 639,
+ 638, 639, 640,
+ 640, 639, 641,
+ 640, 641, 642,
+ 642, 641, 643,
+ 642, 643, 644,
+ 644, 643, 645,
+ 644, 645, 636,
+ 636, 645, 637,
+ 646, 636, 638,
+ 646, 638, 640,
+ 646, 640, 642,
+ 646, 642, 644,
+ 646, 644, 636,
+ 647, 639, 637,
+ 647, 641, 639,
+ 647, 643, 641,
+ 647, 645, 643,
+ 647, 637, 645,
+ 648, 649, 650,
+ 650, 649, 651,
+ 650, 651, 652,
+ 652, 651, 653,
+ 652, 653, 654,
+ 654, 653, 655,
+ 654, 655, 656,
+ 656, 655, 657,
+ 656, 657, 648,
+ 648, 657, 649,
+ 658, 648, 650,
+ 658, 650, 652,
+ 658, 652, 654,
+ 658, 654, 656,
+ 658, 656, 648,
+ 659, 651, 649,
+ 659, 653, 651,
+ 659, 655, 653,
+ 659, 657, 655,
+ 659, 649, 657,
+ 660, 661, 662,
+ 662, 661, 663,
+ 662, 663, 664,
+ 664, 663, 665,
+ 664, 665, 666,
+ 666, 665, 667,
+ 666, 667, 668,
+ 668, 667, 669,
+ 668, 669, 660,
+ 660, 669, 661,
+ 670, 660, 662,
+ 670, 662, 664,
+ 670, 664, 666,
+ 670, 666, 668,
+ 670, 668, 660,
+ 671, 663, 661,
+ 671, 665, 663,
+ 671, 667, 665,
+ 671, 669, 667,
+ 671, 661, 669,
+ 672, 673, 674,
+ 674, 673, 675,
+ 674, 675, 676,
+ 676, 675, 677,
+ 676, 677, 678,
+ 678, 677, 679,
+ 678, 679, 680,
+ 680, 679, 681,
+ 680, 681, 672,
+ 672, 681, 673,
+ 682, 672, 674,
+ 682, 674, 676,
+ 682, 676, 678,
+ 682, 678, 680,
+ 682, 680, 672,
+ 683, 675, 673,
+ 683, 677, 675,
+ 683, 679, 677,
+ 683, 681, 679,
+ 683, 673, 681,
+ 684, 685, 686,
+ 686, 685, 687,
+ 686, 687, 688,
+ 688, 687, 689,
+ 688, 689, 690,
+ 690, 689, 691,
+ 690, 691, 692,
+ 692, 691, 693,
+ 692, 693, 684,
+ 684, 693, 685,
+ 694, 684, 686,
+ 694, 686, 688,
+ 694, 688, 690,
+ 694, 690, 692,
+ 694, 692, 684,
+ 695, 687, 685,
+ 695, 689, 687,
+ 695, 691, 689,
+ 695, 693, 691,
+ 695, 685, 693,
+ 696, 697, 698,
+ 698, 697, 699,
+ 698, 699, 700,
+ 700, 699, 701,
+ 700, 701, 702,
+ 702, 701, 703,
+ 702, 703, 704,
+ 704, 703, 705,
+ 704, 705, 696,
+ 696, 705, 697,
+ 706, 696, 698,
+ 706, 698, 700,
+ 706, 700, 702,
+ 706, 702, 704,
+ 706, 704, 696,
+ 707, 699, 697,
+ 707, 701, 699,
+ 707, 703, 701,
+ 707, 705, 703,
+ 707, 697, 705,
+ 708, 709, 710,
+ 710, 709, 711,
+ 710, 711, 712,
+ 712, 711, 713,
+ 712, 713, 714,
+ 714, 713, 715,
+ 714, 715, 716,
+ 716, 715, 717,
+ 716, 717, 708,
+ 708, 717, 709,
+ 718, 708, 710,
+ 718, 710, 712,
+ 718, 712, 714,
+ 718, 714, 716,
+ 718, 716, 708,
+ 719, 711, 709,
+ 719, 713, 711,
+ 719, 715, 713,
+ 719, 717, 715,
+ 719, 709, 717,
+ 720, 721, 722,
+ 722, 721, 723,
+ 722, 723, 724,
+ 724, 723, 725,
+ 724, 725, 726,
+ 726, 725, 727,
+ 726, 727, 728,
+ 728, 727, 729,
+ 728, 729, 720,
+ 720, 729, 721,
+ 730, 720, 722,
+ 730, 722, 724,
+ 730, 724, 726,
+ 730, 726, 728,
+ 730, 728, 720,
+ 731, 723, 721,
+ 731, 725, 723,
+ 731, 727, 725,
+ 731, 729, 727,
+ 731, 721, 729,
+ 732, 733, 734,
+ 734, 733, 735,
+ 734, 735, 736,
+ 736, 735, 737,
+ 736, 737, 738,
+ 738, 737, 739,
+ 738, 739, 740,
+ 740, 739, 741,
+ 740, 741, 732,
+ 732, 741, 733,
+ 742, 732, 734,
+ 742, 734, 736,
+ 742, 736, 738,
+ 742, 738, 740,
+ 742, 740, 732,
+ 743, 735, 733,
+ 743, 737, 735,
+ 743, 739, 737,
+ 743, 741, 739,
+ 743, 733, 741,
+ 744, 745, 746,
+ 746, 745, 747,
+ 746, 747, 748,
+ 748, 747, 749,
+ 748, 749, 750,
+ 750, 749, 751,
+ 750, 751, 752,
+ 752, 751, 753,
+ 752, 753, 744,
+ 744, 753, 745,
+ 754, 744, 746,
+ 754, 746, 748,
+ 754, 748, 750,
+ 754, 750, 752,
+ 754, 752, 744,
+ 755, 747, 745,
+ 755, 749, 747,
+ 755, 751, 749,
+ 755, 753, 751,
+ 755, 745, 753,
+ 756, 757, 758,
+ 758, 757, 759,
+ 758, 759, 760,
+ 760, 759, 761,
+ 760, 761, 762,
+ 762, 761, 763,
+ 762, 763, 764,
+ 764, 763, 765,
+ 764, 765, 756,
+ 756, 765, 757,
+ 766, 756, 758,
+ 766, 758, 760,
+ 766, 760, 762,
+ 766, 762, 764,
+ 766, 764, 756,
+ 767, 759, 757,
+ 767, 761, 759,
+ 767, 763, 761,
+ 767, 765, 763,
+ 767, 757, 765
+};
+static const unsigned some_enclosures_properties[3840] =
+{
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0,
+ 3, 4, 0
+};
+
+#define NB_CYL_X 4
+#define NB_CYL_Y 4
+#define NB_CYL_Z 4
+#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
+#define CYL_VRTX_COUNT 12u
+#define CYL_TRG_COUNT 20u
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_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(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene */
+ ctx.positions = some_enclosures_vertices;
+ ctx.indices = some_enclosures_triangles;
+ ctx.properties = some_enclosures_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ some_enclosures_triangles_count, get_indices, get_media_from_properties,
+ some_enclosures_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_vertices_count(scn, &count));
+ CHK(count == NB_CYL * CYL_VRTX_COUNT);
+ OK(senc3d_scene_get_triangles_count(scn, &count));
+ CHK(count == NB_CYL * CYL_TRG_COUNT);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1 + NB_CYL);
+ FOR_EACH(e, 0, count) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ unsigned m;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ CHK(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &m));
+ CHK(header.primitives_count ==
+ (header.is_infinite /* Outermost enclosure: NB_CYL_X*NB_CYL_Y cylinders */
+ ? NB_CYL_X * NB_CYL_Y * CYL_TRG_COUNT
+ : (m == 0
+ ? CYL_TRG_COUNT /* Innermost enclosures: 1 cylinder */
+ : 2 * CYL_TRG_COUNT))); /* Other enclosures: 2 cylinders */
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_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_senc3d_some_triangles.c b/src/test_senc3d_some_triangles.c
@@ -0,0 +1,2737 @@
+/* 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
+ * 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 sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_some_triangles.
+ * This test is similar to test_SENC3D_many_triangles that creates a huge
+ * geometry by program. */
+
+#include "senc3d.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+/* Dump of star-geometry 'some_triangles'. */
+static const unsigned some_triangles_vertices_count = 536;
+static const double some_triangles_vertices[1608] =
+{
+ 1, 0, -1,
+ 1, 0, -0.8,
+ 1, 0, -0.6,
+ 1, 0, -0.4,
+ 1, 0, -0.2,
+ 1, 0, -5.55112e-17,
+ 1, 0, 0.2,
+ 1, 0, 0.4,
+ 1, 0, 0.6,
+ 1, 0, 0.8,
+ 1, 0, 1,
+ 0.866025, 0.5, -1,
+ 0.866025, 0.5, -0.8,
+ 0.866025, 0.5, -0.6,
+ 0.866025, 0.5, -0.4,
+ 0.866025, 0.5, -0.2,
+ 0.866025, 0.5, -5.55112e-17,
+ 0.866025, 0.5, 0.2,
+ 0.866025, 0.5, 0.4,
+ 0.866025, 0.5, 0.6,
+ 0.866025, 0.5, 0.8,
+ 0.866025, 0.5, 1,
+ 0.5, 0.866025, -1,
+ 0.5, 0.866025, -0.8,
+ 0.5, 0.866025, -0.6,
+ 0.5, 0.866025, -0.4,
+ 0.5, 0.866025, -0.2,
+ 0.5, 0.866025, -5.55112e-17,
+ 0.5, 0.866025, 0.2,
+ 0.5, 0.866025, 0.4,
+ 0.5, 0.866025, 0.6,
+ 0.5, 0.866025, 0.8,
+ 0.5, 0.866025, 1,
+ 6.12323e-17, 1, -1,
+ 6.12323e-17, 1, -0.8,
+ 6.12323e-17, 1, -0.6,
+ 6.12323e-17, 1, -0.4,
+ 6.12323e-17, 1, -0.2,
+ 6.12323e-17, 1, -5.55112e-17,
+ 6.12323e-17, 1, 0.2,
+ 6.12323e-17, 1, 0.4,
+ 6.12323e-17, 1, 0.6,
+ 6.12323e-17, 1, 0.8,
+ 6.12323e-17, 1, 1,
+ -0.5, 0.866025, -1,
+ -0.5, 0.866025, -0.8,
+ -0.5, 0.866025, -0.6,
+ -0.5, 0.866025, -0.4,
+ -0.5, 0.866025, -0.2,
+ -0.5, 0.866025, -5.55112e-17,
+ -0.5, 0.866025, 0.2,
+ -0.5, 0.866025, 0.4,
+ -0.5, 0.866025, 0.6,
+ -0.5, 0.866025, 0.8,
+ -0.5, 0.866025, 1,
+ -0.866025, 0.5, -1,
+ -0.866025, 0.5, -0.8,
+ -0.866025, 0.5, -0.6,
+ -0.866025, 0.5, -0.4,
+ -0.866025, 0.5, -0.2,
+ -0.866025, 0.5, -5.55112e-17,
+ -0.866025, 0.5, 0.2,
+ -0.866025, 0.5, 0.4,
+ -0.866025, 0.5, 0.6,
+ -0.866025, 0.5, 0.8,
+ -0.866025, 0.5, 1,
+ -1, 1.22465e-16, -1,
+ -1, 1.22465e-16, -0.8,
+ -1, 1.22465e-16, -0.6,
+ -1, 1.22465e-16, -0.4,
+ -1, 1.22465e-16, -0.2,
+ -1, 1.22465e-16, -5.55112e-17,
+ -1, 1.22465e-16, 0.2,
+ -1, 1.22465e-16, 0.4,
+ -1, 1.22465e-16, 0.6,
+ -1, 1.22465e-16, 0.8,
+ -1, 1.22465e-16, 1,
+ -0.866025, -0.5, -1,
+ -0.866025, -0.5, -0.8,
+ -0.866025, -0.5, -0.6,
+ -0.866025, -0.5, -0.4,
+ -0.866025, -0.5, -0.2,
+ -0.866025, -0.5, -5.55112e-17,
+ -0.866025, -0.5, 0.2,
+ -0.866025, -0.5, 0.4,
+ -0.866025, -0.5, 0.6,
+ -0.866025, -0.5, 0.8,
+ -0.866025, -0.5, 1,
+ -0.5, -0.866025, -1,
+ -0.5, -0.866025, -0.8,
+ -0.5, -0.866025, -0.6,
+ -0.5, -0.866025, -0.4,
+ -0.5, -0.866025, -0.2,
+ -0.5, -0.866025, -5.55112e-17,
+ -0.5, -0.866025, 0.2,
+ -0.5, -0.866025, 0.4,
+ -0.5, -0.866025, 0.6,
+ -0.5, -0.866025, 0.8,
+ -0.5, -0.866025, 1,
+ -1.83697e-16, -1, -1,
+ -1.83697e-16, -1, -0.8,
+ -1.83697e-16, -1, -0.6,
+ -1.83697e-16, -1, -0.4,
+ -1.83697e-16, -1, -0.2,
+ -1.83697e-16, -1, -5.55112e-17,
+ -1.83697e-16, -1, 0.2,
+ -1.83697e-16, -1, 0.4,
+ -1.83697e-16, -1, 0.6,
+ -1.83697e-16, -1, 0.8,
+ -1.83697e-16, -1, 1,
+ 0.5, -0.866025, -1,
+ 0.5, -0.866025, -0.8,
+ 0.5, -0.866025, -0.6,
+ 0.5, -0.866025, -0.4,
+ 0.5, -0.866025, -0.2,
+ 0.5, -0.866025, -5.55112e-17,
+ 0.5, -0.866025, 0.2,
+ 0.5, -0.866025, 0.4,
+ 0.5, -0.866025, 0.6,
+ 0.5, -0.866025, 0.8,
+ 0.5, -0.866025, 1,
+ 0.866025, -0.5, -1,
+ 0.866025, -0.5, -0.8,
+ 0.866025, -0.5, -0.6,
+ 0.866025, -0.5, -0.4,
+ 0.866025, -0.5, -0.2,
+ 0.866025, -0.5, -5.55112e-17,
+ 0.866025, -0.5, 0.2,
+ 0.866025, -0.5, 0.4,
+ 0.866025, -0.5, 0.6,
+ 0.866025, -0.5, 0.8,
+ 0.866025, -0.5, 1,
+ 0, 0, -1,
+ 0, 0, 1,
+ 1, 0, 9,
+ 1, 0, 9.2,
+ 1, 0, 9.4,
+ 1, 0, 9.6,
+ 1, 0, 9.8,
+ 1, 0, 10,
+ 1, 0, 10.2,
+ 1, 0, 10.4,
+ 1, 0, 10.6,
+ 1, 0, 10.8,
+ 1, 0, 11,
+ 0.866025, 0.5, 9,
+ 0.866025, 0.5, 9.2,
+ 0.866025, 0.5, 9.4,
+ 0.866025, 0.5, 9.6,
+ 0.866025, 0.5, 9.8,
+ 0.866025, 0.5, 10,
+ 0.866025, 0.5, 10.2,
+ 0.866025, 0.5, 10.4,
+ 0.866025, 0.5, 10.6,
+ 0.866025, 0.5, 10.8,
+ 0.866025, 0.5, 11,
+ 0.5, 0.866025, 9,
+ 0.5, 0.866025, 9.2,
+ 0.5, 0.866025, 9.4,
+ 0.5, 0.866025, 9.6,
+ 0.5, 0.866025, 9.8,
+ 0.5, 0.866025, 10,
+ 0.5, 0.866025, 10.2,
+ 0.5, 0.866025, 10.4,
+ 0.5, 0.866025, 10.6,
+ 0.5, 0.866025, 10.8,
+ 0.5, 0.866025, 11,
+ 6.12323e-17, 1, 9,
+ 6.12323e-17, 1, 9.2,
+ 6.12323e-17, 1, 9.4,
+ 6.12323e-17, 1, 9.6,
+ 6.12323e-17, 1, 9.8,
+ 6.12323e-17, 1, 10,
+ 6.12323e-17, 1, 10.2,
+ 6.12323e-17, 1, 10.4,
+ 6.12323e-17, 1, 10.6,
+ 6.12323e-17, 1, 10.8,
+ 6.12323e-17, 1, 11,
+ -0.5, 0.866025, 9,
+ -0.5, 0.866025, 9.2,
+ -0.5, 0.866025, 9.4,
+ -0.5, 0.866025, 9.6,
+ -0.5, 0.866025, 9.8,
+ -0.5, 0.866025, 10,
+ -0.5, 0.866025, 10.2,
+ -0.5, 0.866025, 10.4,
+ -0.5, 0.866025, 10.6,
+ -0.5, 0.866025, 10.8,
+ -0.5, 0.866025, 11,
+ -0.866025, 0.5, 9,
+ -0.866025, 0.5, 9.2,
+ -0.866025, 0.5, 9.4,
+ -0.866025, 0.5, 9.6,
+ -0.866025, 0.5, 9.8,
+ -0.866025, 0.5, 10,
+ -0.866025, 0.5, 10.2,
+ -0.866025, 0.5, 10.4,
+ -0.866025, 0.5, 10.6,
+ -0.866025, 0.5, 10.8,
+ -0.866025, 0.5, 11,
+ -1, 1.22465e-16, 9,
+ -1, 1.22465e-16, 9.2,
+ -1, 1.22465e-16, 9.4,
+ -1, 1.22465e-16, 9.6,
+ -1, 1.22465e-16, 9.8,
+ -1, 1.22465e-16, 10,
+ -1, 1.22465e-16, 10.2,
+ -1, 1.22465e-16, 10.4,
+ -1, 1.22465e-16, 10.6,
+ -1, 1.22465e-16, 10.8,
+ -1, 1.22465e-16, 11,
+ -0.866025, -0.5, 9,
+ -0.866025, -0.5, 9.2,
+ -0.866025, -0.5, 9.4,
+ -0.866025, -0.5, 9.6,
+ -0.866025, -0.5, 9.8,
+ -0.866025, -0.5, 10,
+ -0.866025, -0.5, 10.2,
+ -0.866025, -0.5, 10.4,
+ -0.866025, -0.5, 10.6,
+ -0.866025, -0.5, 10.8,
+ -0.866025, -0.5, 11,
+ -0.5, -0.866025, 9,
+ -0.5, -0.866025, 9.2,
+ -0.5, -0.866025, 9.4,
+ -0.5, -0.866025, 9.6,
+ -0.5, -0.866025, 9.8,
+ -0.5, -0.866025, 10,
+ -0.5, -0.866025, 10.2,
+ -0.5, -0.866025, 10.4,
+ -0.5, -0.866025, 10.6,
+ -0.5, -0.866025, 10.8,
+ -0.5, -0.866025, 11,
+ -1.83697e-16, -1, 9,
+ -1.83697e-16, -1, 9.2,
+ -1.83697e-16, -1, 9.4,
+ -1.83697e-16, -1, 9.6,
+ -1.83697e-16, -1, 9.8,
+ -1.83697e-16, -1, 10,
+ -1.83697e-16, -1, 10.2,
+ -1.83697e-16, -1, 10.4,
+ -1.83697e-16, -1, 10.6,
+ -1.83697e-16, -1, 10.8,
+ -1.83697e-16, -1, 11,
+ 0.5, -0.866025, 9,
+ 0.5, -0.866025, 9.2,
+ 0.5, -0.866025, 9.4,
+ 0.5, -0.866025, 9.6,
+ 0.5, -0.866025, 9.8,
+ 0.5, -0.866025, 10,
+ 0.5, -0.866025, 10.2,
+ 0.5, -0.866025, 10.4,
+ 0.5, -0.866025, 10.6,
+ 0.5, -0.866025, 10.8,
+ 0.5, -0.866025, 11,
+ 0.866025, -0.5, 9,
+ 0.866025, -0.5, 9.2,
+ 0.866025, -0.5, 9.4,
+ 0.866025, -0.5, 9.6,
+ 0.866025, -0.5, 9.8,
+ 0.866025, -0.5, 10,
+ 0.866025, -0.5, 10.2,
+ 0.866025, -0.5, 10.4,
+ 0.866025, -0.5, 10.6,
+ 0.866025, -0.5, 10.8,
+ 0.866025, -0.5, 11,
+ 0, 0, 9,
+ 0, 0, 11,
+ 1, 0, 19,
+ 1, 0, 19.2,
+ 1, 0, 19.4,
+ 1, 0, 19.6,
+ 1, 0, 19.8,
+ 1, 0, 20,
+ 1, 0, 20.2,
+ 1, 0, 20.4,
+ 1, 0, 20.6,
+ 1, 0, 20.8,
+ 1, 0, 21,
+ 0.866025, 0.5, 19,
+ 0.866025, 0.5, 19.2,
+ 0.866025, 0.5, 19.4,
+ 0.866025, 0.5, 19.6,
+ 0.866025, 0.5, 19.8,
+ 0.866025, 0.5, 20,
+ 0.866025, 0.5, 20.2,
+ 0.866025, 0.5, 20.4,
+ 0.866025, 0.5, 20.6,
+ 0.866025, 0.5, 20.8,
+ 0.866025, 0.5, 21,
+ 0.5, 0.866025, 19,
+ 0.5, 0.866025, 19.2,
+ 0.5, 0.866025, 19.4,
+ 0.5, 0.866025, 19.6,
+ 0.5, 0.866025, 19.8,
+ 0.5, 0.866025, 20,
+ 0.5, 0.866025, 20.2,
+ 0.5, 0.866025, 20.4,
+ 0.5, 0.866025, 20.6,
+ 0.5, 0.866025, 20.8,
+ 0.5, 0.866025, 21,
+ 6.12323e-17, 1, 19,
+ 6.12323e-17, 1, 19.2,
+ 6.12323e-17, 1, 19.4,
+ 6.12323e-17, 1, 19.6,
+ 6.12323e-17, 1, 19.8,
+ 6.12323e-17, 1, 20,
+ 6.12323e-17, 1, 20.2,
+ 6.12323e-17, 1, 20.4,
+ 6.12323e-17, 1, 20.6,
+ 6.12323e-17, 1, 20.8,
+ 6.12323e-17, 1, 21,
+ -0.5, 0.866025, 19,
+ -0.5, 0.866025, 19.2,
+ -0.5, 0.866025, 19.4,
+ -0.5, 0.866025, 19.6,
+ -0.5, 0.866025, 19.8,
+ -0.5, 0.866025, 20,
+ -0.5, 0.866025, 20.2,
+ -0.5, 0.866025, 20.4,
+ -0.5, 0.866025, 20.6,
+ -0.5, 0.866025, 20.8,
+ -0.5, 0.866025, 21,
+ -0.866025, 0.5, 19,
+ -0.866025, 0.5, 19.2,
+ -0.866025, 0.5, 19.4,
+ -0.866025, 0.5, 19.6,
+ -0.866025, 0.5, 19.8,
+ -0.866025, 0.5, 20,
+ -0.866025, 0.5, 20.2,
+ -0.866025, 0.5, 20.4,
+ -0.866025, 0.5, 20.6,
+ -0.866025, 0.5, 20.8,
+ -0.866025, 0.5, 21,
+ -1, 1.22465e-16, 19,
+ -1, 1.22465e-16, 19.2,
+ -1, 1.22465e-16, 19.4,
+ -1, 1.22465e-16, 19.6,
+ -1, 1.22465e-16, 19.8,
+ -1, 1.22465e-16, 20,
+ -1, 1.22465e-16, 20.2,
+ -1, 1.22465e-16, 20.4,
+ -1, 1.22465e-16, 20.6,
+ -1, 1.22465e-16, 20.8,
+ -1, 1.22465e-16, 21,
+ -0.866025, -0.5, 19,
+ -0.866025, -0.5, 19.2,
+ -0.866025, -0.5, 19.4,
+ -0.866025, -0.5, 19.6,
+ -0.866025, -0.5, 19.8,
+ -0.866025, -0.5, 20,
+ -0.866025, -0.5, 20.2,
+ -0.866025, -0.5, 20.4,
+ -0.866025, -0.5, 20.6,
+ -0.866025, -0.5, 20.8,
+ -0.866025, -0.5, 21,
+ -0.5, -0.866025, 19,
+ -0.5, -0.866025, 19.2,
+ -0.5, -0.866025, 19.4,
+ -0.5, -0.866025, 19.6,
+ -0.5, -0.866025, 19.8,
+ -0.5, -0.866025, 20,
+ -0.5, -0.866025, 20.2,
+ -0.5, -0.866025, 20.4,
+ -0.5, -0.866025, 20.6,
+ -0.5, -0.866025, 20.8,
+ -0.5, -0.866025, 21,
+ -1.83697e-16, -1, 19,
+ -1.83697e-16, -1, 19.2,
+ -1.83697e-16, -1, 19.4,
+ -1.83697e-16, -1, 19.6,
+ -1.83697e-16, -1, 19.8,
+ -1.83697e-16, -1, 20,
+ -1.83697e-16, -1, 20.2,
+ -1.83697e-16, -1, 20.4,
+ -1.83697e-16, -1, 20.6,
+ -1.83697e-16, -1, 20.8,
+ -1.83697e-16, -1, 21,
+ 0.5, -0.866025, 19,
+ 0.5, -0.866025, 19.2,
+ 0.5, -0.866025, 19.4,
+ 0.5, -0.866025, 19.6,
+ 0.5, -0.866025, 19.8,
+ 0.5, -0.866025, 20,
+ 0.5, -0.866025, 20.2,
+ 0.5, -0.866025, 20.4,
+ 0.5, -0.866025, 20.6,
+ 0.5, -0.866025, 20.8,
+ 0.5, -0.866025, 21,
+ 0.866025, -0.5, 19,
+ 0.866025, -0.5, 19.2,
+ 0.866025, -0.5, 19.4,
+ 0.866025, -0.5, 19.6,
+ 0.866025, -0.5, 19.8,
+ 0.866025, -0.5, 20,
+ 0.866025, -0.5, 20.2,
+ 0.866025, -0.5, 20.4,
+ 0.866025, -0.5, 20.6,
+ 0.866025, -0.5, 20.8,
+ 0.866025, -0.5, 21,
+ 0, 0, 19,
+ 0, 0, 21,
+ 1, 0, 29,
+ 1, 0, 29.2,
+ 1, 0, 29.4,
+ 1, 0, 29.6,
+ 1, 0, 29.8,
+ 1, 0, 30,
+ 1, 0, 30.2,
+ 1, 0, 30.4,
+ 1, 0, 30.6,
+ 1, 0, 30.8,
+ 1, 0, 31,
+ 0.866025, 0.5, 29,
+ 0.866025, 0.5, 29.2,
+ 0.866025, 0.5, 29.4,
+ 0.866025, 0.5, 29.6,
+ 0.866025, 0.5, 29.8,
+ 0.866025, 0.5, 30,
+ 0.866025, 0.5, 30.2,
+ 0.866025, 0.5, 30.4,
+ 0.866025, 0.5, 30.6,
+ 0.866025, 0.5, 30.8,
+ 0.866025, 0.5, 31,
+ 0.5, 0.866025, 29,
+ 0.5, 0.866025, 29.2,
+ 0.5, 0.866025, 29.4,
+ 0.5, 0.866025, 29.6,
+ 0.5, 0.866025, 29.8,
+ 0.5, 0.866025, 30,
+ 0.5, 0.866025, 30.2,
+ 0.5, 0.866025, 30.4,
+ 0.5, 0.866025, 30.6,
+ 0.5, 0.866025, 30.8,
+ 0.5, 0.866025, 31,
+ 6.12323e-17, 1, 29,
+ 6.12323e-17, 1, 29.2,
+ 6.12323e-17, 1, 29.4,
+ 6.12323e-17, 1, 29.6,
+ 6.12323e-17, 1, 29.8,
+ 6.12323e-17, 1, 30,
+ 6.12323e-17, 1, 30.2,
+ 6.12323e-17, 1, 30.4,
+ 6.12323e-17, 1, 30.6,
+ 6.12323e-17, 1, 30.8,
+ 6.12323e-17, 1, 31,
+ -0.5, 0.866025, 29,
+ -0.5, 0.866025, 29.2,
+ -0.5, 0.866025, 29.4,
+ -0.5, 0.866025, 29.6,
+ -0.5, 0.866025, 29.8,
+ -0.5, 0.866025, 30,
+ -0.5, 0.866025, 30.2,
+ -0.5, 0.866025, 30.4,
+ -0.5, 0.866025, 30.6,
+ -0.5, 0.866025, 30.8,
+ -0.5, 0.866025, 31,
+ -0.866025, 0.5, 29,
+ -0.866025, 0.5, 29.2,
+ -0.866025, 0.5, 29.4,
+ -0.866025, 0.5, 29.6,
+ -0.866025, 0.5, 29.8,
+ -0.866025, 0.5, 30,
+ -0.866025, 0.5, 30.2,
+ -0.866025, 0.5, 30.4,
+ -0.866025, 0.5, 30.6,
+ -0.866025, 0.5, 30.8,
+ -0.866025, 0.5, 31,
+ -1, 1.22465e-16, 29,
+ -1, 1.22465e-16, 29.2,
+ -1, 1.22465e-16, 29.4,
+ -1, 1.22465e-16, 29.6,
+ -1, 1.22465e-16, 29.8,
+ -1, 1.22465e-16, 30,
+ -1, 1.22465e-16, 30.2,
+ -1, 1.22465e-16, 30.4,
+ -1, 1.22465e-16, 30.6,
+ -1, 1.22465e-16, 30.8,
+ -1, 1.22465e-16, 31,
+ -0.866025, -0.5, 29,
+ -0.866025, -0.5, 29.2,
+ -0.866025, -0.5, 29.4,
+ -0.866025, -0.5, 29.6,
+ -0.866025, -0.5, 29.8,
+ -0.866025, -0.5, 30,
+ -0.866025, -0.5, 30.2,
+ -0.866025, -0.5, 30.4,
+ -0.866025, -0.5, 30.6,
+ -0.866025, -0.5, 30.8,
+ -0.866025, -0.5, 31,
+ -0.5, -0.866025, 29,
+ -0.5, -0.866025, 29.2,
+ -0.5, -0.866025, 29.4,
+ -0.5, -0.866025, 29.6,
+ -0.5, -0.866025, 29.8,
+ -0.5, -0.866025, 30,
+ -0.5, -0.866025, 30.2,
+ -0.5, -0.866025, 30.4,
+ -0.5, -0.866025, 30.6,
+ -0.5, -0.866025, 30.8,
+ -0.5, -0.866025, 31,
+ -1.83697e-16, -1, 29,
+ -1.83697e-16, -1, 29.2,
+ -1.83697e-16, -1, 29.4,
+ -1.83697e-16, -1, 29.6,
+ -1.83697e-16, -1, 29.8,
+ -1.83697e-16, -1, 30,
+ -1.83697e-16, -1, 30.2,
+ -1.83697e-16, -1, 30.4,
+ -1.83697e-16, -1, 30.6,
+ -1.83697e-16, -1, 30.8,
+ -1.83697e-16, -1, 31,
+ 0.5, -0.866025, 29,
+ 0.5, -0.866025, 29.2,
+ 0.5, -0.866025, 29.4,
+ 0.5, -0.866025, 29.6,
+ 0.5, -0.866025, 29.8,
+ 0.5, -0.866025, 30,
+ 0.5, -0.866025, 30.2,
+ 0.5, -0.866025, 30.4,
+ 0.5, -0.866025, 30.6,
+ 0.5, -0.866025, 30.8,
+ 0.5, -0.866025, 31,
+ 0.866025, -0.5, 29,
+ 0.866025, -0.5, 29.2,
+ 0.866025, -0.5, 29.4,
+ 0.866025, -0.5, 29.6,
+ 0.866025, -0.5, 29.8,
+ 0.866025, -0.5, 30,
+ 0.866025, -0.5, 30.2,
+ 0.866025, -0.5, 30.4,
+ 0.866025, -0.5, 30.6,
+ 0.866025, -0.5, 30.8,
+ 0.866025, -0.5, 31,
+ 0, 0, 29,
+ 0, 0, 31
+};
+static const unsigned some_triangles_triangles_count = 1056;
+static const unsigned some_triangles_triangles[3168] =
+{
+ 0, 1, 11,
+ 11, 1, 12,
+ 1, 2, 12,
+ 12, 2, 13,
+ 2, 3, 13,
+ 13, 3, 14,
+ 3, 4, 14,
+ 14, 4, 15,
+ 4, 5, 15,
+ 15, 5, 16,
+ 5, 6, 16,
+ 16, 6, 17,
+ 6, 7, 17,
+ 17, 7, 18,
+ 7, 8, 18,
+ 18, 8, 19,
+ 8, 9, 19,
+ 19, 9, 20,
+ 9, 10, 20,
+ 20, 10, 21,
+ 11, 12, 22,
+ 22, 12, 23,
+ 12, 13, 23,
+ 23, 13, 24,
+ 13, 14, 24,
+ 24, 14, 25,
+ 14, 15, 25,
+ 25, 15, 26,
+ 15, 16, 26,
+ 26, 16, 27,
+ 16, 17, 27,
+ 27, 17, 28,
+ 17, 18, 28,
+ 28, 18, 29,
+ 18, 19, 29,
+ 29, 19, 30,
+ 19, 20, 30,
+ 30, 20, 31,
+ 20, 21, 31,
+ 31, 21, 32,
+ 22, 23, 33,
+ 33, 23, 34,
+ 23, 24, 34,
+ 34, 24, 35,
+ 24, 25, 35,
+ 35, 25, 36,
+ 25, 26, 36,
+ 36, 26, 37,
+ 26, 27, 37,
+ 37, 27, 38,
+ 27, 28, 38,
+ 38, 28, 39,
+ 28, 29, 39,
+ 39, 29, 40,
+ 29, 30, 40,
+ 40, 30, 41,
+ 30, 31, 41,
+ 41, 31, 42,
+ 31, 32, 42,
+ 42, 32, 43,
+ 33, 34, 44,
+ 44, 34, 45,
+ 34, 35, 45,
+ 45, 35, 46,
+ 35, 36, 46,
+ 46, 36, 47,
+ 36, 37, 47,
+ 47, 37, 48,
+ 37, 38, 48,
+ 48, 38, 49,
+ 38, 39, 49,
+ 49, 39, 50,
+ 39, 40, 50,
+ 50, 40, 51,
+ 40, 41, 51,
+ 51, 41, 52,
+ 41, 42, 52,
+ 52, 42, 53,
+ 42, 43, 53,
+ 53, 43, 54,
+ 44, 45, 55,
+ 55, 45, 56,
+ 45, 46, 56,
+ 56, 46, 57,
+ 46, 47, 57,
+ 57, 47, 58,
+ 47, 48, 58,
+ 58, 48, 59,
+ 48, 49, 59,
+ 59, 49, 60,
+ 49, 50, 60,
+ 60, 50, 61,
+ 50, 51, 61,
+ 61, 51, 62,
+ 51, 52, 62,
+ 62, 52, 63,
+ 52, 53, 63,
+ 63, 53, 64,
+ 53, 54, 64,
+ 64, 54, 65,
+ 55, 56, 66,
+ 66, 56, 67,
+ 56, 57, 67,
+ 67, 57, 68,
+ 57, 58, 68,
+ 68, 58, 69,
+ 58, 59, 69,
+ 69, 59, 70,
+ 59, 60, 70,
+ 70, 60, 71,
+ 60, 61, 71,
+ 71, 61, 72,
+ 61, 62, 72,
+ 72, 62, 73,
+ 62, 63, 73,
+ 73, 63, 74,
+ 63, 64, 74,
+ 74, 64, 75,
+ 64, 65, 75,
+ 75, 65, 76,
+ 66, 67, 77,
+ 77, 67, 78,
+ 67, 68, 78,
+ 78, 68, 79,
+ 68, 69, 79,
+ 79, 69, 80,
+ 69, 70, 80,
+ 80, 70, 81,
+ 70, 71, 81,
+ 81, 71, 82,
+ 71, 72, 82,
+ 82, 72, 83,
+ 72, 73, 83,
+ 83, 73, 84,
+ 73, 74, 84,
+ 84, 74, 85,
+ 74, 75, 85,
+ 85, 75, 86,
+ 75, 76, 86,
+ 86, 76, 87,
+ 77, 78, 88,
+ 88, 78, 89,
+ 78, 79, 89,
+ 89, 79, 90,
+ 79, 80, 90,
+ 90, 80, 91,
+ 80, 81, 91,
+ 91, 81, 92,
+ 81, 82, 92,
+ 92, 82, 93,
+ 82, 83, 93,
+ 93, 83, 94,
+ 83, 84, 94,
+ 94, 84, 95,
+ 84, 85, 95,
+ 95, 85, 96,
+ 85, 86, 96,
+ 96, 86, 97,
+ 86, 87, 97,
+ 97, 87, 98,
+ 88, 89, 99,
+ 99, 89, 100,
+ 89, 90, 100,
+ 100, 90, 101,
+ 90, 91, 101,
+ 101, 91, 102,
+ 91, 92, 102,
+ 102, 92, 103,
+ 92, 93, 103,
+ 103, 93, 104,
+ 93, 94, 104,
+ 104, 94, 105,
+ 94, 95, 105,
+ 105, 95, 106,
+ 95, 96, 106,
+ 106, 96, 107,
+ 96, 97, 107,
+ 107, 97, 108,
+ 97, 98, 108,
+ 108, 98, 109,
+ 99, 100, 110,
+ 110, 100, 111,
+ 100, 101, 111,
+ 111, 101, 112,
+ 101, 102, 112,
+ 112, 102, 113,
+ 102, 103, 113,
+ 113, 103, 114,
+ 103, 104, 114,
+ 114, 104, 115,
+ 104, 105, 115,
+ 115, 105, 116,
+ 105, 106, 116,
+ 116, 106, 117,
+ 106, 107, 117,
+ 117, 107, 118,
+ 107, 108, 118,
+ 118, 108, 119,
+ 108, 109, 119,
+ 119, 109, 120,
+ 110, 111, 121,
+ 121, 111, 122,
+ 111, 112, 122,
+ 122, 112, 123,
+ 112, 113, 123,
+ 123, 113, 124,
+ 113, 114, 124,
+ 124, 114, 125,
+ 114, 115, 125,
+ 125, 115, 126,
+ 115, 116, 126,
+ 126, 116, 127,
+ 116, 117, 127,
+ 127, 117, 128,
+ 117, 118, 128,
+ 128, 118, 129,
+ 118, 119, 129,
+ 129, 119, 130,
+ 119, 120, 130,
+ 130, 120, 131,
+ 121, 122, 0,
+ 0, 122, 1,
+ 122, 123, 1,
+ 1, 123, 2,
+ 123, 124, 2,
+ 2, 124, 3,
+ 124, 125, 3,
+ 3, 125, 4,
+ 125, 126, 4,
+ 4, 126, 5,
+ 126, 127, 5,
+ 5, 127, 6,
+ 127, 128, 6,
+ 6, 128, 7,
+ 128, 129, 7,
+ 7, 129, 8,
+ 129, 130, 8,
+ 8, 130, 9,
+ 130, 131, 9,
+ 9, 131, 10,
+ 132, 0, 11,
+ 132, 11, 22,
+ 132, 22, 33,
+ 132, 33, 44,
+ 132, 44, 55,
+ 132, 55, 66,
+ 132, 66, 77,
+ 132, 77, 88,
+ 132, 88, 99,
+ 132, 99, 110,
+ 132, 110, 121,
+ 132, 121, 0,
+ 133, 21, 10,
+ 133, 32, 21,
+ 133, 43, 32,
+ 133, 54, 43,
+ 133, 65, 54,
+ 133, 76, 65,
+ 133, 87, 76,
+ 133, 98, 87,
+ 133, 109, 98,
+ 133, 120, 109,
+ 133, 131, 120,
+ 133, 10, 131,
+ 134, 135, 145,
+ 145, 135, 146,
+ 135, 136, 146,
+ 146, 136, 147,
+ 136, 137, 147,
+ 147, 137, 148,
+ 137, 138, 148,
+ 148, 138, 149,
+ 138, 139, 149,
+ 149, 139, 150,
+ 139, 140, 150,
+ 150, 140, 151,
+ 140, 141, 151,
+ 151, 141, 152,
+ 141, 142, 152,
+ 152, 142, 153,
+ 142, 143, 153,
+ 153, 143, 154,
+ 143, 144, 154,
+ 154, 144, 155,
+ 145, 146, 156,
+ 156, 146, 157,
+ 146, 147, 157,
+ 157, 147, 158,
+ 147, 148, 158,
+ 158, 148, 159,
+ 148, 149, 159,
+ 159, 149, 160,
+ 149, 150, 160,
+ 160, 150, 161,
+ 150, 151, 161,
+ 161, 151, 162,
+ 151, 152, 162,
+ 162, 152, 163,
+ 152, 153, 163,
+ 163, 153, 164,
+ 153, 154, 164,
+ 164, 154, 165,
+ 154, 155, 165,
+ 165, 155, 166,
+ 156, 157, 167,
+ 167, 157, 168,
+ 157, 158, 168,
+ 168, 158, 169,
+ 158, 159, 169,
+ 169, 159, 170,
+ 159, 160, 170,
+ 170, 160, 171,
+ 160, 161, 171,
+ 171, 161, 172,
+ 161, 162, 172,
+ 172, 162, 173,
+ 162, 163, 173,
+ 173, 163, 174,
+ 163, 164, 174,
+ 174, 164, 175,
+ 164, 165, 175,
+ 175, 165, 176,
+ 165, 166, 176,
+ 176, 166, 177,
+ 167, 168, 178,
+ 178, 168, 179,
+ 168, 169, 179,
+ 179, 169, 180,
+ 169, 170, 180,
+ 180, 170, 181,
+ 170, 171, 181,
+ 181, 171, 182,
+ 171, 172, 182,
+ 182, 172, 183,
+ 172, 173, 183,
+ 183, 173, 184,
+ 173, 174, 184,
+ 184, 174, 185,
+ 174, 175, 185,
+ 185, 175, 186,
+ 175, 176, 186,
+ 186, 176, 187,
+ 176, 177, 187,
+ 187, 177, 188,
+ 178, 179, 189,
+ 189, 179, 190,
+ 179, 180, 190,
+ 190, 180, 191,
+ 180, 181, 191,
+ 191, 181, 192,
+ 181, 182, 192,
+ 192, 182, 193,
+ 182, 183, 193,
+ 193, 183, 194,
+ 183, 184, 194,
+ 194, 184, 195,
+ 184, 185, 195,
+ 195, 185, 196,
+ 185, 186, 196,
+ 196, 186, 197,
+ 186, 187, 197,
+ 197, 187, 198,
+ 187, 188, 198,
+ 198, 188, 199,
+ 189, 190, 200,
+ 200, 190, 201,
+ 190, 191, 201,
+ 201, 191, 202,
+ 191, 192, 202,
+ 202, 192, 203,
+ 192, 193, 203,
+ 203, 193, 204,
+ 193, 194, 204,
+ 204, 194, 205,
+ 194, 195, 205,
+ 205, 195, 206,
+ 195, 196, 206,
+ 206, 196, 207,
+ 196, 197, 207,
+ 207, 197, 208,
+ 197, 198, 208,
+ 208, 198, 209,
+ 198, 199, 209,
+ 209, 199, 210,
+ 200, 201, 211,
+ 211, 201, 212,
+ 201, 202, 212,
+ 212, 202, 213,
+ 202, 203, 213,
+ 213, 203, 214,
+ 203, 204, 214,
+ 214, 204, 215,
+ 204, 205, 215,
+ 215, 205, 216,
+ 205, 206, 216,
+ 216, 206, 217,
+ 206, 207, 217,
+ 217, 207, 218,
+ 207, 208, 218,
+ 218, 208, 219,
+ 208, 209, 219,
+ 219, 209, 220,
+ 209, 210, 220,
+ 220, 210, 221,
+ 211, 212, 222,
+ 222, 212, 223,
+ 212, 213, 223,
+ 223, 213, 224,
+ 213, 214, 224,
+ 224, 214, 225,
+ 214, 215, 225,
+ 225, 215, 226,
+ 215, 216, 226,
+ 226, 216, 227,
+ 216, 217, 227,
+ 227, 217, 228,
+ 217, 218, 228,
+ 228, 218, 229,
+ 218, 219, 229,
+ 229, 219, 230,
+ 219, 220, 230,
+ 230, 220, 231,
+ 220, 221, 231,
+ 231, 221, 232,
+ 222, 223, 233,
+ 233, 223, 234,
+ 223, 224, 234,
+ 234, 224, 235,
+ 224, 225, 235,
+ 235, 225, 236,
+ 225, 226, 236,
+ 236, 226, 237,
+ 226, 227, 237,
+ 237, 227, 238,
+ 227, 228, 238,
+ 238, 228, 239,
+ 228, 229, 239,
+ 239, 229, 240,
+ 229, 230, 240,
+ 240, 230, 241,
+ 230, 231, 241,
+ 241, 231, 242,
+ 231, 232, 242,
+ 242, 232, 243,
+ 233, 234, 244,
+ 244, 234, 245,
+ 234, 235, 245,
+ 245, 235, 246,
+ 235, 236, 246,
+ 246, 236, 247,
+ 236, 237, 247,
+ 247, 237, 248,
+ 237, 238, 248,
+ 248, 238, 249,
+ 238, 239, 249,
+ 249, 239, 250,
+ 239, 240, 250,
+ 250, 240, 251,
+ 240, 241, 251,
+ 251, 241, 252,
+ 241, 242, 252,
+ 252, 242, 253,
+ 242, 243, 253,
+ 253, 243, 254,
+ 244, 245, 255,
+ 255, 245, 256,
+ 245, 246, 256,
+ 256, 246, 257,
+ 246, 247, 257,
+ 257, 247, 258,
+ 247, 248, 258,
+ 258, 248, 259,
+ 248, 249, 259,
+ 259, 249, 260,
+ 249, 250, 260,
+ 260, 250, 261,
+ 250, 251, 261,
+ 261, 251, 262,
+ 251, 252, 262,
+ 262, 252, 263,
+ 252, 253, 263,
+ 263, 253, 264,
+ 253, 254, 264,
+ 264, 254, 265,
+ 255, 256, 134,
+ 134, 256, 135,
+ 256, 257, 135,
+ 135, 257, 136,
+ 257, 258, 136,
+ 136, 258, 137,
+ 258, 259, 137,
+ 137, 259, 138,
+ 259, 260, 138,
+ 138, 260, 139,
+ 260, 261, 139,
+ 139, 261, 140,
+ 261, 262, 140,
+ 140, 262, 141,
+ 262, 263, 141,
+ 141, 263, 142,
+ 263, 264, 142,
+ 142, 264, 143,
+ 264, 265, 143,
+ 143, 265, 144,
+ 266, 134, 145,
+ 266, 145, 156,
+ 266, 156, 167,
+ 266, 167, 178,
+ 266, 178, 189,
+ 266, 189, 200,
+ 266, 200, 211,
+ 266, 211, 222,
+ 266, 222, 233,
+ 266, 233, 244,
+ 266, 244, 255,
+ 266, 255, 134,
+ 267, 155, 144,
+ 267, 166, 155,
+ 267, 177, 166,
+ 267, 188, 177,
+ 267, 199, 188,
+ 267, 210, 199,
+ 267, 221, 210,
+ 267, 232, 221,
+ 267, 243, 232,
+ 267, 254, 243,
+ 267, 265, 254,
+ 267, 144, 265,
+ 268, 269, 279,
+ 279, 269, 280,
+ 269, 270, 280,
+ 280, 270, 281,
+ 270, 271, 281,
+ 281, 271, 282,
+ 271, 272, 282,
+ 282, 272, 283,
+ 272, 273, 283,
+ 283, 273, 284,
+ 273, 274, 284,
+ 284, 274, 285,
+ 274, 275, 285,
+ 285, 275, 286,
+ 275, 276, 286,
+ 286, 276, 287,
+ 276, 277, 287,
+ 287, 277, 288,
+ 277, 278, 288,
+ 288, 278, 289,
+ 279, 280, 290,
+ 290, 280, 291,
+ 280, 281, 291,
+ 291, 281, 292,
+ 281, 282, 292,
+ 292, 282, 293,
+ 282, 283, 293,
+ 293, 283, 294,
+ 283, 284, 294,
+ 294, 284, 295,
+ 284, 285, 295,
+ 295, 285, 296,
+ 285, 286, 296,
+ 296, 286, 297,
+ 286, 287, 297,
+ 297, 287, 298,
+ 287, 288, 298,
+ 298, 288, 299,
+ 288, 289, 299,
+ 299, 289, 300,
+ 290, 291, 301,
+ 301, 291, 302,
+ 291, 292, 302,
+ 302, 292, 303,
+ 292, 293, 303,
+ 303, 293, 304,
+ 293, 294, 304,
+ 304, 294, 305,
+ 294, 295, 305,
+ 305, 295, 306,
+ 295, 296, 306,
+ 306, 296, 307,
+ 296, 297, 307,
+ 307, 297, 308,
+ 297, 298, 308,
+ 308, 298, 309,
+ 298, 299, 309,
+ 309, 299, 310,
+ 299, 300, 310,
+ 310, 300, 311,
+ 301, 302, 312,
+ 312, 302, 313,
+ 302, 303, 313,
+ 313, 303, 314,
+ 303, 304, 314,
+ 314, 304, 315,
+ 304, 305, 315,
+ 315, 305, 316,
+ 305, 306, 316,
+ 316, 306, 317,
+ 306, 307, 317,
+ 317, 307, 318,
+ 307, 308, 318,
+ 318, 308, 319,
+ 308, 309, 319,
+ 319, 309, 320,
+ 309, 310, 320,
+ 320, 310, 321,
+ 310, 311, 321,
+ 321, 311, 322,
+ 312, 313, 323,
+ 323, 313, 324,
+ 313, 314, 324,
+ 324, 314, 325,
+ 314, 315, 325,
+ 325, 315, 326,
+ 315, 316, 326,
+ 326, 316, 327,
+ 316, 317, 327,
+ 327, 317, 328,
+ 317, 318, 328,
+ 328, 318, 329,
+ 318, 319, 329,
+ 329, 319, 330,
+ 319, 320, 330,
+ 330, 320, 331,
+ 320, 321, 331,
+ 331, 321, 332,
+ 321, 322, 332,
+ 332, 322, 333,
+ 323, 324, 334,
+ 334, 324, 335,
+ 324, 325, 335,
+ 335, 325, 336,
+ 325, 326, 336,
+ 336, 326, 337,
+ 326, 327, 337,
+ 337, 327, 338,
+ 327, 328, 338,
+ 338, 328, 339,
+ 328, 329, 339,
+ 339, 329, 340,
+ 329, 330, 340,
+ 340, 330, 341,
+ 330, 331, 341,
+ 341, 331, 342,
+ 331, 332, 342,
+ 342, 332, 343,
+ 332, 333, 343,
+ 343, 333, 344,
+ 334, 335, 345,
+ 345, 335, 346,
+ 335, 336, 346,
+ 346, 336, 347,
+ 336, 337, 347,
+ 347, 337, 348,
+ 337, 338, 348,
+ 348, 338, 349,
+ 338, 339, 349,
+ 349, 339, 350,
+ 339, 340, 350,
+ 350, 340, 351,
+ 340, 341, 351,
+ 351, 341, 352,
+ 341, 342, 352,
+ 352, 342, 353,
+ 342, 343, 353,
+ 353, 343, 354,
+ 343, 344, 354,
+ 354, 344, 355,
+ 345, 346, 356,
+ 356, 346, 357,
+ 346, 347, 357,
+ 357, 347, 358,
+ 347, 348, 358,
+ 358, 348, 359,
+ 348, 349, 359,
+ 359, 349, 360,
+ 349, 350, 360,
+ 360, 350, 361,
+ 350, 351, 361,
+ 361, 351, 362,
+ 351, 352, 362,
+ 362, 352, 363,
+ 352, 353, 363,
+ 363, 353, 364,
+ 353, 354, 364,
+ 364, 354, 365,
+ 354, 355, 365,
+ 365, 355, 366,
+ 356, 357, 367,
+ 367, 357, 368,
+ 357, 358, 368,
+ 368, 358, 369,
+ 358, 359, 369,
+ 369, 359, 370,
+ 359, 360, 370,
+ 370, 360, 371,
+ 360, 361, 371,
+ 371, 361, 372,
+ 361, 362, 372,
+ 372, 362, 373,
+ 362, 363, 373,
+ 373, 363, 374,
+ 363, 364, 374,
+ 374, 364, 375,
+ 364, 365, 375,
+ 375, 365, 376,
+ 365, 366, 376,
+ 376, 366, 377,
+ 367, 368, 378,
+ 378, 368, 379,
+ 368, 369, 379,
+ 379, 369, 380,
+ 369, 370, 380,
+ 380, 370, 381,
+ 370, 371, 381,
+ 381, 371, 382,
+ 371, 372, 382,
+ 382, 372, 383,
+ 372, 373, 383,
+ 383, 373, 384,
+ 373, 374, 384,
+ 384, 374, 385,
+ 374, 375, 385,
+ 385, 375, 386,
+ 375, 376, 386,
+ 386, 376, 387,
+ 376, 377, 387,
+ 387, 377, 388,
+ 378, 379, 389,
+ 389, 379, 390,
+ 379, 380, 390,
+ 390, 380, 391,
+ 380, 381, 391,
+ 391, 381, 392,
+ 381, 382, 392,
+ 392, 382, 393,
+ 382, 383, 393,
+ 393, 383, 394,
+ 383, 384, 394,
+ 394, 384, 395,
+ 384, 385, 395,
+ 395, 385, 396,
+ 385, 386, 396,
+ 396, 386, 397,
+ 386, 387, 397,
+ 397, 387, 398,
+ 387, 388, 398,
+ 398, 388, 399,
+ 389, 390, 268,
+ 268, 390, 269,
+ 390, 391, 269,
+ 269, 391, 270,
+ 391, 392, 270,
+ 270, 392, 271,
+ 392, 393, 271,
+ 271, 393, 272,
+ 393, 394, 272,
+ 272, 394, 273,
+ 394, 395, 273,
+ 273, 395, 274,
+ 395, 396, 274,
+ 274, 396, 275,
+ 396, 397, 275,
+ 275, 397, 276,
+ 397, 398, 276,
+ 276, 398, 277,
+ 398, 399, 277,
+ 277, 399, 278,
+ 400, 268, 279,
+ 400, 279, 290,
+ 400, 290, 301,
+ 400, 301, 312,
+ 400, 312, 323,
+ 400, 323, 334,
+ 400, 334, 345,
+ 400, 345, 356,
+ 400, 356, 367,
+ 400, 367, 378,
+ 400, 378, 389,
+ 400, 389, 268,
+ 401, 289, 278,
+ 401, 300, 289,
+ 401, 311, 300,
+ 401, 322, 311,
+ 401, 333, 322,
+ 401, 344, 333,
+ 401, 355, 344,
+ 401, 366, 355,
+ 401, 377, 366,
+ 401, 388, 377,
+ 401, 399, 388,
+ 401, 278, 399,
+ 402, 403, 413,
+ 413, 403, 414,
+ 403, 404, 414,
+ 414, 404, 415,
+ 404, 405, 415,
+ 415, 405, 416,
+ 405, 406, 416,
+ 416, 406, 417,
+ 406, 407, 417,
+ 417, 407, 418,
+ 407, 408, 418,
+ 418, 408, 419,
+ 408, 409, 419,
+ 419, 409, 420,
+ 409, 410, 420,
+ 420, 410, 421,
+ 410, 411, 421,
+ 421, 411, 422,
+ 411, 412, 422,
+ 422, 412, 423,
+ 413, 414, 424,
+ 424, 414, 425,
+ 414, 415, 425,
+ 425, 415, 426,
+ 415, 416, 426,
+ 426, 416, 427,
+ 416, 417, 427,
+ 427, 417, 428,
+ 417, 418, 428,
+ 428, 418, 429,
+ 418, 419, 429,
+ 429, 419, 430,
+ 419, 420, 430,
+ 430, 420, 431,
+ 420, 421, 431,
+ 431, 421, 432,
+ 421, 422, 432,
+ 432, 422, 433,
+ 422, 423, 433,
+ 433, 423, 434,
+ 424, 425, 435,
+ 435, 425, 436,
+ 425, 426, 436,
+ 436, 426, 437,
+ 426, 427, 437,
+ 437, 427, 438,
+ 427, 428, 438,
+ 438, 428, 439,
+ 428, 429, 439,
+ 439, 429, 440,
+ 429, 430, 440,
+ 440, 430, 441,
+ 430, 431, 441,
+ 441, 431, 442,
+ 431, 432, 442,
+ 442, 432, 443,
+ 432, 433, 443,
+ 443, 433, 444,
+ 433, 434, 444,
+ 444, 434, 445,
+ 435, 436, 446,
+ 446, 436, 447,
+ 436, 437, 447,
+ 447, 437, 448,
+ 437, 438, 448,
+ 448, 438, 449,
+ 438, 439, 449,
+ 449, 439, 450,
+ 439, 440, 450,
+ 450, 440, 451,
+ 440, 441, 451,
+ 451, 441, 452,
+ 441, 442, 452,
+ 452, 442, 453,
+ 442, 443, 453,
+ 453, 443, 454,
+ 443, 444, 454,
+ 454, 444, 455,
+ 444, 445, 455,
+ 455, 445, 456,
+ 446, 447, 457,
+ 457, 447, 458,
+ 447, 448, 458,
+ 458, 448, 459,
+ 448, 449, 459,
+ 459, 449, 460,
+ 449, 450, 460,
+ 460, 450, 461,
+ 450, 451, 461,
+ 461, 451, 462,
+ 451, 452, 462,
+ 462, 452, 463,
+ 452, 453, 463,
+ 463, 453, 464,
+ 453, 454, 464,
+ 464, 454, 465,
+ 454, 455, 465,
+ 465, 455, 466,
+ 455, 456, 466,
+ 466, 456, 467,
+ 457, 458, 468,
+ 468, 458, 469,
+ 458, 459, 469,
+ 469, 459, 470,
+ 459, 460, 470,
+ 470, 460, 471,
+ 460, 461, 471,
+ 471, 461, 472,
+ 461, 462, 472,
+ 472, 462, 473,
+ 462, 463, 473,
+ 473, 463, 474,
+ 463, 464, 474,
+ 474, 464, 475,
+ 464, 465, 475,
+ 475, 465, 476,
+ 465, 466, 476,
+ 476, 466, 477,
+ 466, 467, 477,
+ 477, 467, 478,
+ 468, 469, 479,
+ 479, 469, 480,
+ 469, 470, 480,
+ 480, 470, 481,
+ 470, 471, 481,
+ 481, 471, 482,
+ 471, 472, 482,
+ 482, 472, 483,
+ 472, 473, 483,
+ 483, 473, 484,
+ 473, 474, 484,
+ 484, 474, 485,
+ 474, 475, 485,
+ 485, 475, 486,
+ 475, 476, 486,
+ 486, 476, 487,
+ 476, 477, 487,
+ 487, 477, 488,
+ 477, 478, 488,
+ 488, 478, 489,
+ 479, 480, 490,
+ 490, 480, 491,
+ 480, 481, 491,
+ 491, 481, 492,
+ 481, 482, 492,
+ 492, 482, 493,
+ 482, 483, 493,
+ 493, 483, 494,
+ 483, 484, 494,
+ 494, 484, 495,
+ 484, 485, 495,
+ 495, 485, 496,
+ 485, 486, 496,
+ 496, 486, 497,
+ 486, 487, 497,
+ 497, 487, 498,
+ 487, 488, 498,
+ 498, 488, 499,
+ 488, 489, 499,
+ 499, 489, 500,
+ 490, 491, 501,
+ 501, 491, 502,
+ 491, 492, 502,
+ 502, 492, 503,
+ 492, 493, 503,
+ 503, 493, 504,
+ 493, 494, 504,
+ 504, 494, 505,
+ 494, 495, 505,
+ 505, 495, 506,
+ 495, 496, 506,
+ 506, 496, 507,
+ 496, 497, 507,
+ 507, 497, 508,
+ 497, 498, 508,
+ 508, 498, 509,
+ 498, 499, 509,
+ 509, 499, 510,
+ 499, 500, 510,
+ 510, 500, 511,
+ 501, 502, 512,
+ 512, 502, 513,
+ 502, 503, 513,
+ 513, 503, 514,
+ 503, 504, 514,
+ 514, 504, 515,
+ 504, 505, 515,
+ 515, 505, 516,
+ 505, 506, 516,
+ 516, 506, 517,
+ 506, 507, 517,
+ 517, 507, 518,
+ 507, 508, 518,
+ 518, 508, 519,
+ 508, 509, 519,
+ 519, 509, 520,
+ 509, 510, 520,
+ 520, 510, 521,
+ 510, 511, 521,
+ 521, 511, 522,
+ 512, 513, 523,
+ 523, 513, 524,
+ 513, 514, 524,
+ 524, 514, 525,
+ 514, 515, 525,
+ 525, 515, 526,
+ 515, 516, 526,
+ 526, 516, 527,
+ 516, 517, 527,
+ 527, 517, 528,
+ 517, 518, 528,
+ 528, 518, 529,
+ 518, 519, 529,
+ 529, 519, 530,
+ 519, 520, 530,
+ 530, 520, 531,
+ 520, 521, 531,
+ 531, 521, 532,
+ 521, 522, 532,
+ 532, 522, 533,
+ 523, 524, 402,
+ 402, 524, 403,
+ 524, 525, 403,
+ 403, 525, 404,
+ 525, 526, 404,
+ 404, 526, 405,
+ 526, 527, 405,
+ 405, 527, 406,
+ 527, 528, 406,
+ 406, 528, 407,
+ 528, 529, 407,
+ 407, 529, 408,
+ 529, 530, 408,
+ 408, 530, 409,
+ 530, 531, 409,
+ 409, 531, 410,
+ 531, 532, 410,
+ 410, 532, 411,
+ 532, 533, 411,
+ 411, 533, 412,
+ 534, 402, 413,
+ 534, 413, 424,
+ 534, 424, 435,
+ 534, 435, 446,
+ 534, 446, 457,
+ 534, 457, 468,
+ 534, 468, 479,
+ 534, 479, 490,
+ 534, 490, 501,
+ 534, 501, 512,
+ 534, 512, 523,
+ 534, 523, 402,
+ 535, 423, 412,
+ 535, 434, 423,
+ 535, 445, 434,
+ 535, 456, 445,
+ 535, 467, 456,
+ 535, 478, 467,
+ 535, 489, 478,
+ 535, 500, 489,
+ 535, 511, 500,
+ 535, 522, 511,
+ 535, 533, 522,
+ 535, 412, 533
+};
+static const unsigned some_triangles_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_CYL 4
+#define CYL_VRTX_COUNT 134u
+#define CYL_TRG_COUNT 264u
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_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(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Create a scene */
+ ctx.positions = some_triangles_vertices;
+ ctx.indices = some_triangles_triangles;
+ ctx.properties = some_triangles_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ some_triangles_triangles_count, get_indices, get_media_from_properties,
+ some_triangles_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_vertices_count(scn, &count));
+ CHK(count == NB_CYL * CYL_VRTX_COUNT);
+ OK(senc3d_scene_get_triangles_count(scn, &count));
+ CHK(count == NB_CYL * CYL_TRG_COUNT);
+
+ OK(senc3d_scene_get_enclosure_count(scn, &count));
+ CHK(count == 1 + NB_CYL);
+ FOR_EACH(e, 0, count) {
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ OK(senc3d_scene_get_enclosure(scn, e, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+ CHK(header.primitives_count ==
+ (e ? CYL_TRG_COUNT : NB_CYL * CYL_TRG_COUNT));
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_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_senc3d_unspecified_medium.c b/src/test_senc3d_unspecified_medium.c
@@ -0,0 +1,327 @@
+/* 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
+* 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 sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_unspecified_properties.
+ * This test is similar to test_SENC3D_many_enclosures that creates a huge
+ * geometry by program. */
+
+#include "senc3d.h"
+#include "SENC3D_s3d_helper.h"
+#include "test_SENC3D_utils.h"
+
+#include <rsys/double3.h>
+
+#define SG3_UNSPECIFED_PROPERTY UINT_MAX
+
+/* Dump of star-geometry 'front_unspecified'. */
+static const unsigned front_unspecified_vertices_count = 8;
+static const double front_unspecified_vertices[24] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1
+};
+static const unsigned front_unspecified_triangles_count = 12;
+static const unsigned front_unspecified_triangles[36] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5
+};
+static const unsigned front_unspecified_properties[36] =
+{
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY
+};
+/* Dump of star-geometry 'front_half_unspecified'. */
+static const unsigned front_half_unspecified_vertices_count = 8;
+static const double front_half_unspecified_vertices[24] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1
+};
+static const unsigned front_half_unspecified_triangles_count = 12;
+static const unsigned front_half_unspecified_triangles[36] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5
+};
+static const unsigned front_half_unspecified_properties[36] =
+{
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ 0, 1, 0,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ 0, 1, 0,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ 0, 1, 0,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ 0, 1, 0,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ 0, 1, 0,
+ SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ 0, 1, 0
+};
+/* Dump of star-geometry 'all_defined'. */
+static const unsigned all_defined_vertices_count = 8;
+static const double all_defined_vertices[24] =
+{
+ 0.1, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1.1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1.1, 1
+};
+static const unsigned all_defined_triangles_count = 12;
+static const unsigned all_defined_triangles[36] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5
+};
+static const unsigned all_defined_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
+};
+
+static void
+test(const int convention)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ unsigned medium, expected_external_medium, expected_internal_medium;
+ unsigned gid;
+ enum senc3d_side side;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned i, t, ecount;
+ const int conv_front = (convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Geometry with no media information on both sides */
+ ctx.positions = front_unspecified_vertices;
+ ctx.indices = front_unspecified_triangles;
+ ctx.properties = front_unspecified_properties;
+ OK(senc3d_scene_create(dev, convention, front_unspecified_triangles_count,
+ get_indices, get_media_from_properties, front_unspecified_vertices_count,
+ get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 2);
+
+ FOR_EACH(i, 0, ecount) {
+ struct senc3d_enclosure* ee;
+ struct senc3d_enclosure_header hh;
+ unsigned cc;
+ OK(senc3d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ CHK(header.enclosure_id == i);
+ CHK(header.enclosed_media_count == 1);
+
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &medium));
+ /* Geometrical normals point outside the cube in input triangles:
+ * if convention is front, front medium (unspecified) is outside,
+ * that is medium 0's enclosure is infinite */
+ expected_external_medium = conv_front ? SENC3D_UNSPECIFIED_MEDIUM : 1;
+ expected_internal_medium = conv_front ? 1 : SENC3D_UNSPECIFIED_MEDIUM;
+
+ CHK(medium == (header.is_infinite
+ ? expected_external_medium : expected_internal_medium));
+ CHK(header.primitives_count == ntriangles);
+ CHK(header.unique_primitives_count == ntriangles);
+ CHK(header.vertices_count == nvertices);
+ CHK(header.is_infinite == (i == 0));
+
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, medium, &cc));
+ CHK(cc == 1);
+ OK(senc3d_scene_get_enclosure_by_medium(scn, medium, 0, &ee));
+ OK(senc3d_enclosure_get_header(ee, &hh));
+ CHK(header.enclosure_id == hh.enclosure_id);
+ OK(senc3d_enclosure_ref_put(ee));
+
+ FOR_EACH(t, 0, header.primitives_count) {
+ unsigned ind[3];
+ OK(senc3d_enclosure_get_triangle_id(enclosure, t, &gid, &side));
+ CHK(gid == t);
+ CHK(side == (medium == 1) ? SENC3D_BACK : SENC3D_FRONT);
+ OK(senc3d_enclosure_get_triangle(enclosure, t, ind));
+ }
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Same geometry, front media are defined for odd triangles */
+ ctx.positions = front_half_unspecified_vertices;
+ ctx.indices = front_half_unspecified_triangles;
+ ctx.properties = front_half_unspecified_properties;
+ OK(senc3d_scene_create(dev, convention, front_half_unspecified_triangles_count,
+ get_indices, get_media_from_properties, front_half_unspecified_vertices_count,
+ get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 2);
+
+ FOR_EACH(i, 0, ecount) {
+ unsigned expected_external_media_count, expected_internal_media_count,
+ expected_media_count;
+ OK(senc3d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ CHK(header.enclosure_id == i);
+
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &medium));
+ /* Geometrical normals point outside the cube in input triangles:
+ * 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(senc3d_enclosure_ref_put(enclosure));
+ }
+ OK(senc3d_scene_ref_put(scn));
+
+ /* Same geometry, all media are defined */
+ ctx.positions = all_defined_vertices;
+ ctx.indices = all_defined_triangles;
+ ctx.properties = all_defined_properties;
+ OK(senc3d_scene_create(dev, convention, all_defined_triangles_count,
+ get_indices, get_media_from_properties, all_defined_vertices_count,
+ get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 2);
+
+ FOR_EACH(i, 0, ecount) {
+ struct senc3d_enclosure* ee;
+ struct senc3d_enclosure_header hh;
+ unsigned cc;
+ OK(senc3d_scene_get_enclosure(scn, i, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ CHK(header.enclosure_id == i);
+ CHK(header.enclosed_media_count == 1);
+ OK(senc3d_enclosure_get_medium(enclosure, 0, &medium));
+ /* Geometrical normals point outside the cube in input triangles:
+ * 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.primitives_count == ntriangles);
+ CHK(header.unique_primitives_count == ntriangles);
+ CHK(header.vertices_count == nvertices);
+ CHK(header.is_infinite == (i == 0));
+
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, medium, &cc));
+ CHK(cc == 1);
+ OK(senc3d_scene_get_enclosure_by_medium(scn, medium, 0, &ee));
+ OK(senc3d_enclosure_get_header(ee, &hh));
+ CHK(header.enclosure_id == hh.enclosure_id);
+ OK(senc3d_enclosure_ref_put(ee));
+
+ FOR_EACH(t, 0, header.primitives_count) {
+ OK(senc3d_enclosure_get_triangle_id(enclosure, t, &gid, &side));
+ CHK(gid == t);
+ CHK(side == (medium == 1) ? SENC3D_BACK : SENC3D_FRONT);
+ }
+ OK(senc3d_enclosure_ref_put(enclosure));
+ }
+
+ SENC3D(scene_ref_put(scn));
+ SENC3D(device_ref_put(dev));
+
+ 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(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE);
+ test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE);
+ test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_OUTSIDE);
+ test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE);
+ return 0;
+}
diff --git a/src/test_senc3d_utils.h b/src/test_senc3d_utils.h
@@ -0,0 +1,271 @@
+/* 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
+ * 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_UTILS_H
+#define TEST_UTILS_H
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+#define OK(Expr) CHK((Expr) == RES_OK)
+#define BA(Expr) CHK((Expr) == RES_BAD_ARG)
+
+/*******************************************************************************
+ * Geometry
+ ******************************************************************************/
+/* Distorded cube */
+static const double box_vertices[8/*#vertices*/*3/*#coords per vertex*/] = {
+ 0.1, 0.0, 0.0,
+ 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 1.0, 1.0, 0.0,
+ 0.0, 0.0, 1.1,
+ 1.0, 0.0, 1.0,
+ 0.0, 1.0, 1.0,
+ 1.0, 1.1, 1.0
+};
+/* Need a true cube for some tests */
+static const double cube_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = {
+ 0.0, 0.0, 0.0,
+ 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 1.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0,
+ 1.0, 0.0, 1.0,
+ 0.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0
+};
+static const unsigned nvertices = sizeof(box_vertices) / sizeof(double[3]);
+STATIC_ASSERT(sizeof(box_vertices) == sizeof(cube_vertices),
+ The_2_geometries_must_have_the_same_number_of_vertices);
+
+/* The following array lists the indices toward the 3D vertices of each
+ * triangle.
+ * ,2---,3 ,2----3
+ * ,' | ,'/| ,'/| \ |
+ * 6----7' / | 6' / | \ | Y
+ * |', | / ,1 | / ,0---,1 |
+ * | ',|/,' |/,' | ,' o--X
+ * 4----5' 4----5' /
+ * Front, right Back, left and Z
+ * and Top faces bottom faces */
+static const unsigned
+box_indices[12/*#triangles*/*3/*#indices per triangle*/] = {
+ 0, 2, 1, 1, 2, 3, /* Front face */
+ 0, 4, 2, 2, 4, 6, /* Left face*/
+ 4, 5, 6, 6, 5, 7, /* Back face */
+ 3, 7, 1, 1, 7, 5, /* Right face */
+ 2, 6, 3, 3, 6, 7, /* Top face */
+ 0, 1, 4, 4, 1, 5 /* Bottom face */
+};
+static const unsigned
+ntriangles = sizeof(box_indices) / (3 * sizeof(*box_indices));
+
+struct context {
+ const double* positions;
+ const unsigned* indices;
+ const unsigned* front_media;
+ const unsigned* back_media;
+ const unsigned* properties;
+ void* custom;
+ double offset[3];
+ double scale;
+ char reverse_vrtx, reverse_med;
+};
+#define CONTEXT_NULL__ {\
+ NULL, NULL, NULL, NULL, NULL, NULL, {0,0,0}, 1, 0, 0\
+}
+
+static const unsigned medium0[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static const unsigned medium1[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+static const unsigned medium2[12] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
+static const unsigned medium1_3[12] = { 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1 };
+static const unsigned medium1_back0[12] = { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 };
+static const unsigned medium1_front0[12] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+
+static INLINE void
+get_indices(const unsigned itri, unsigned ids[3], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(ids && ctx);
+ ids[0] = ctx->indices[itri * 3 + 0];
+ ids[ctx->reverse_vrtx ? 2 : 1] = ctx->indices[itri * 3 + 1];
+ ids[ctx->reverse_vrtx ? 1 : 2] = ctx->indices[itri * 3 + 2];
+}
+
+static INLINE void
+get_position(const unsigned ivert, double pos[3], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(pos && ctx);
+ pos[0] = ctx->positions[ivert * 3 + 0] * ctx->scale + ctx->offset[0];
+ pos[1] = ctx->positions[ivert * 3 + 1] * ctx->scale + ctx->offset[1];
+ pos[2] = ctx->positions[ivert * 3 + 2] * ctx->scale + ctx->offset[2];
+}
+
+static INLINE void
+get_media(const unsigned itri, unsigned medium[2], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(medium && ctx);
+ medium[ctx->reverse_med ? 1 : 0] = ctx->front_media[itri];
+ medium[ctx->reverse_med ? 0 : 1] = ctx->back_media[itri];
+}
+
+static INLINE void
+get_media_from_properties(const unsigned itri, unsigned medium[2], void* context)
+{
+ const struct context* ctx = context;
+ ASSERT(medium && ctx);
+ medium[ctx->reverse_med ? 1 : 0] = ctx->properties[3 * itri + 0];
+ medium[ctx->reverse_med ? 0 : 1] = ctx->properties[3 * itri + 1];
+}
+
+/*******************************************************************************
+ * Miscellaneous
+ ******************************************************************************/
+static INLINE void
+dump_global
+ (struct senc3d_scene* scn,
+ const char* name)
+{
+ FILE* stream;
+ unsigned triangles_count, vertices_count, i;
+
+ ASSERT(scn && name);
+
+ OK(senc3d_scene_get_vertices_count(scn, &vertices_count));
+ OK(senc3d_scene_get_triangles_count(scn, &triangles_count));
+
+ stream = fopen(name, "w");
+ CHK(stream);
+ FOR_EACH(i, 0, vertices_count) {
+ double tmp[3];
+ OK(senc3d_scene_get_vertex(scn, i, tmp));
+ fprintf(stream, "v %g %g %g\n", SPLIT3(tmp));
+ }
+ FOR_EACH(i, 0, triangles_count) {
+ unsigned indices[3];
+ OK(senc3d_scene_get_triangle(scn, i, indices));
+ fprintf(stream, "f %lu %lu %lu\n", (unsigned long)(1 + indices[0]),
+ (unsigned long)(1 + indices[1]), (unsigned long)(1 + indices[2]));
+ }
+ fclose(stream);
+}
+
+static INLINE void
+dump_enclosure
+ (struct senc3d_scene* scn,
+ const unsigned enc,
+ const char* name)
+{
+ struct senc3d_enclosure* enclosure;
+ struct senc3d_enclosure_header header;
+ FILE* stream;
+ unsigned count, i;
+
+ ASSERT(scn && name);
+
+ SENC3D(scene_get_enclosure_count(scn, &count));
+ ASSERT(enc < count);
+ OK(senc3d_scene_get_enclosure(scn, enc, &enclosure));
+ OK(senc3d_enclosure_get_header(enclosure, &header));
+
+ stream = fopen(name, "w");
+ CHK(stream);
+ FOR_EACH(i, 0, header.vertices_count) {
+ double tmp[3];
+ OK(senc3d_enclosure_get_vertex(enclosure, i, tmp));
+ fprintf(stream, "v %g %g %g\n", SPLIT3(tmp));
+ }
+ FOR_EACH(i, 0, header.primitives_count) {
+ unsigned indices[3];
+ OK(senc3d_enclosure_get_triangle(enclosure, i, indices));
+ fprintf(stream, "f %lu %lu %lu\n", (unsigned long)(1+indices[0]),
+ (unsigned long)(1+indices[1]), (unsigned long)(1+indices[2]));
+ }
+ OK(senc3d_enclosure_ref_put(enclosure));
+ fclose(stream);
+}
+
+static INLINE void
+check_memory_allocator(struct mem_allocator* allocator)
+{
+ if(MEM_ALLOCATED_SIZE(allocator)) {
+ char dump[1024];
+ MEM_DUMP(allocator, dump, sizeof(dump));
+ fprintf(stderr, "%s\n", dump);
+ FATAL("Memory leaks.\n");
+ }
+}
+
+/*******************************************************************************
+ * Check functions
+ ******************************************************************************/
+/* Compare the itri-th triangle of enclosure with a triangle described by trg2 & vertices2 */
+static INLINE void
+cmp_trg
+ (const unsigned itri,
+ const struct senc3d_enclosure* enclosure,
+ const unsigned trg2[3],
+ const double* vertices2,
+ int* trg_eq,
+ int* trg_reversed)
+{
+ unsigned trg1[3];
+ double t1[3][3];
+ double t2[3][3];
+ unsigned trg1_eq[3] = { 3, 3, 3 };
+ unsigned i, j, fst_vrtx = 3;
+
+ ASSERT(enclosure && trg2 && vertices2 && trg_eq && trg_reversed);
+
+ OK(senc3d_enclosure_get_triangle(enclosure, itri, trg1));
+ FOR_EACH(i, 0, 3) {
+ OK(senc3d_enclosure_get_vertex(enclosure, trg1[i], t1[i]));
+ d3_set(t2[i], vertices2 + (3 * trg2[i]));
+ }
+ FOR_EACH(i, 0, 3) {
+ FOR_EACH(j, 0, 3) {
+ if(d3_eq(t1[i], t2[j])) {
+ trg1_eq[i] = j;
+ if(i == 0) fst_vrtx = j;
+ break;
+ }
+ }
+ }
+ FOR_EACH(i, 0, 3) {
+ if(trg1_eq[i] == 3) {
+ *trg_eq = 0;
+ return;
+ }
+ if(trg1_eq[i] == trg1_eq[(i + 1) % 3]
+ || trg1_eq[i] == trg1_eq[(i + 2) % 3]) {
+ *trg_eq = 0;
+ return;
+ }
+ }
+ /* Same 3 vertices */
+ ASSERT(fst_vrtx != 3);
+ *trg_eq = 1;
+
+ *trg_reversed = (trg1_eq[1] != (fst_vrtx + 1) % 3);
+ ASSERT(*trg_reversed != (trg1_eq[1] != (fst_vrtx + 2) % 3));
+}
+
+#endif /* TEST_UTILS_H */
diff --git a/src/test_senc3d_utils2.h b/src/test_senc3d_utils2.h
@@ -0,0 +1,107 @@
+/* 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
+ * 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_UTILS2_H
+#define TEST_UTILS2_H
+
+#if !defined(NB_CYL_X) || !defined(NB_CYL_Y) || !defined(NB_CYL_Z) | !defined(NB_CYL)
+#error "Macro definitions are missing"
+#endif
+
+#include "test_senc3d_utils.h"
+
+#include <star/s3dut.h>
+#include <rsys/double3.h>
+
+struct s3dut_context {
+ struct s3dut_mesh_data data;
+ struct context ctx;
+};
+
+static void
+get_s3dut_indices(const unsigned itri, unsigned ids[3], void* context)
+{
+ struct s3dut_context* ctx = context;
+ unsigned s3dut_itri, cyl_idx, v_offset;
+ ASSERT(ids && ctx);
+ ASSERT(itri < NB_CYL * ctx->data.nprimitives);
+ /* Get cyl_idx along with the s3dut vertice index */
+ s3dut_itri = itri % (unsigned)ctx->data.nprimitives;
+ cyl_idx = itri / (unsigned)ctx->data.nprimitives;
+ ASSERT(ctx->data.indices[s3dut_itri * 3 + 0] <= UINT_MAX
+ && ctx->data.indices[s3dut_itri * 3 + 1] <= UINT_MAX
+ && ctx->data.indices[s3dut_itri * 3 + 2] <= UINT_MAX);
+ /* Compute the vertex index in the user numbering
+ * from cyl_idx and s3dut data; vertex related getters
+ * will have to get the s3dut index back */
+ v_offset = cyl_idx * (unsigned)ctx->data.nvertices;
+ ids[0] = v_offset + (unsigned)ctx->data.indices[s3dut_itri * 3 + 0];
+ ids[ctx->ctx.reverse_vrtx ? 2 : 1]
+ = v_offset + (unsigned)ctx->data.indices[s3dut_itri * 3 + 1];
+ ids[ctx->ctx.reverse_vrtx ? 1 : 2]
+ = v_offset + (unsigned)ctx->data.indices[s3dut_itri * 3 + 2];
+}
+
+static void
+get_s3dut_position(const unsigned ivert, double pos[3], void* context)
+{
+ struct s3dut_context* ctx = context;
+ unsigned s3dut_ivert, cyl_idx;
+ int i, j, k;
+ double offset[3], tmp[3];
+ double center_x, center_y, scale, misalignment = 0;
+ ASSERT(pos && ctx);
+ ASSERT(ivert < NB_CYL * ctx->data.nvertices);
+ /* Get cyl_idx and cylinder imbrication along with the s3dut vertice index */
+ s3dut_ivert = ivert % (unsigned)ctx->data.nvertices;
+ cyl_idx = ivert / (unsigned)ctx->data.nvertices;
+ /* k th cylinder of the imbrication at grid position i,j */
+ i = (int)cyl_idx / (NB_CYL_Y * NB_CYL_Z);
+ j = (cyl_idx / NB_CYL_Z) % NB_CYL_Y;
+ k = cyl_idx % NB_CYL_Z;
+ ASSERT(i < NB_CYL_X && j < NB_CYL_Y && k < NB_CYL_Z);
+ ASSERT((unsigned)(i * NB_CYL_Y * NB_CYL_Z + j * NB_CYL_Z + k)
+ * ctx->data.nvertices + s3dut_ivert == ivert);
+ center_x = 2 * (1 + NB_CYL_Z) * (i - NB_CYL_X / 2);
+ center_y = 2 * (1 + NB_CYL_Z) * (j - NB_CYL_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 cylinders
+ * or some hits are missed */
+ misalignment = (k % 2) ? -0.01 : +0.01;
+#endif
+ d3(offset, center_x + misalignment, center_y + misalignment, 0);
+ d3_add(pos, d3_muld(tmp, ctx->data.positions + s3dut_ivert * 3, scale),
+ offset);
+}
+
+static void
+get_s3dut_media(const unsigned itri, unsigned medium[2], void* context)
+{
+ struct s3dut_context* ctx = context;
+ unsigned cyl_idx;
+ int k;
+ ASSERT(medium && ctx);
+ ASSERT(itri < NB_CYL * ctx->data.nprimitives);
+ /* Get cyl_idx */
+ cyl_idx = itri / (unsigned)ctx->data.nprimitives;
+ /* k th cylinder of the imbrication at some grid position */
+ k = cyl_idx % NB_CYL_Z;
+ medium[ctx->ctx.reverse_med ? SENC3D_BACK : SENC3D_FRONT] = (unsigned)k;
+ medium[ctx->ctx.reverse_med ? SENC3D_FRONT : SENC3D_BACK] = (unsigned)(k + 1);
+}
+#endif /* TEST_UTILS2_H */
diff --git a/src/test_senc_cube_behind_cube.c b/src/test_senc_cube_behind_cube.c
@@ -1,311 +0,0 @@
-/* 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
- * 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 sg3_geometry_dump_as_C_code feature
- * of star-geometry. It uses output from test_sg3_cube_behind_cube. */
-
-#include "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-/* Dump of star-geometry 'cube_behind_cube_2'. */
-static const unsigned cube_behind_cube_2_vertices_count = 16;
-static const double cube_behind_cube_2_vertices[48] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1,
- -1.5, -2, 20,
- 3, -2, 20,
- -2, 3, 20,
- 3, 3, 20,
- -2, -2, 25.5,
- 3, -2, 25,
- -2, 3, 25,
- 3, 3.5, 25
-};
-static const unsigned cube_behind_cube_2_triangles_count = 24;
-static const unsigned cube_behind_cube_2_triangles[72] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5,
- 8, 10, 9,
- 9, 10, 11,
- 8, 12, 10,
- 10, 12, 14,
- 12, 13, 14,
- 14, 13, 15,
- 11, 15, 9,
- 9, 15, 13,
- 10, 14, 11,
- 11, 14, 15,
- 8, 9, 12,
- 12, 9, 13
-};
-static const unsigned cube_behind_cube_2_properties[72] =
-{
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 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 'cube_behind_cube_3'. */
-static const unsigned cube_behind_cube_3_vertices_count = 24;
-static const double cube_behind_cube_3_vertices[72] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1,
- -1.5, -2, 20,
- 3, -2, 20,
- -2, 3, 20,
- 3, 3, 20,
- -2, -2, 25.5,
- 3, -2, 25,
- -2, 3, 25,
- 3, 3.5, 25,
- -2.3, -3, 30,
- 4, -3, 30,
- -3, 4, 30,
- 4, 4, 30,
- -3, -3, 37.7,
- 4, -3, 37,
- -3, 4, 37,
- 4, 4.7, 37
-};
-static const unsigned cube_behind_cube_3_triangles_count = 36;
-static const unsigned cube_behind_cube_3_triangles[108] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5,
- 8, 10, 9,
- 9, 10, 11,
- 8, 12, 10,
- 10, 12, 14,
- 12, 13, 14,
- 14, 13, 15,
- 11, 15, 9,
- 9, 15, 13,
- 10, 14, 11,
- 11, 14, 15,
- 8, 9, 12,
- 12, 9, 13,
- 16, 18, 17,
- 17, 18, 19,
- 16, 20, 18,
- 18, 20, 22,
- 20, 21, 22,
- 22, 21, 23,
- 19, 23, 17,
- 17, 23, 21,
- 18, 22, 19,
- 19, 22, 23,
- 16, 17, 20,
- 20, 17, 21
-};
-static const unsigned cube_behind_cube_3_properties[108] =
-{
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 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,
- 1, 0, 0,
- 1, 0, 0,
- 1, 0, 0,
- 1, 0, 0,
- 1, 0, 0,
- 1, 0, 0,
- 1, 0, 0,
- 1, 0, 0
-};
-
-/*
- cube_2 cube_3
-
- +-----------------------+
- | 3
- | |
- m1 | m0 |
- | |
- | |
- | |
- | |--> N
- | |
- | |
- +-----------------------+
- +------------+ +------------+
- | 2 | 2
- m0 | m1 | m0 | m1 |
- | | | |
- | |--> N | |--> N
- | | | |
- +------------+ +------------+
- +-----+ +-----+
- m0 | m1 1 m0 | m1 1
- | |--> N | |--> N
- +-----+ +-----+
- */
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct context ctx = CONTEXT_NULL__;
- unsigned i, ecount, maxm;
- (void)argc, (void)argv;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* Create a scene with the first and second cubes.
- * Both cubes have medium 1 inside and medium 0 outside,
- * the second cube is +Z from the first cube and is big enough
- * to prevent rays from the first cube to miss it. */
- ctx.positions = cube_behind_cube_2_vertices;
- ctx.indices = cube_behind_cube_2_triangles;
- ctx.properties = cube_behind_cube_2_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- cube_behind_cube_2_triangles_count, get_indices, get_media_from_properties,
- cube_behind_cube_2_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 3);
-
- FOR_EACH(i, 0, ecount) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- OK(senc_scene_get_enclosure(scn, i, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- ASSERT(header.enclosed_media_count == 1);
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_get_max_medium(scn, &maxm));
- CHK(maxm == 1);
- OK(senc_scene_ref_put(scn));
-
- /* Create a scene with the 3 cubes, same 2 first cubes as above
- * The third cube has medium 0 inside and medium 1 outside and is further
- * in +Z and bigger */
- ctx.positions = cube_behind_cube_3_vertices;
- ctx.indices = cube_behind_cube_3_triangles;
- ctx.properties = cube_behind_cube_3_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- cube_behind_cube_3_triangles_count, get_indices, get_media_from_properties,
- cube_behind_cube_3_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 4);
-
- FOR_EACH(i, 0, ecount) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- OK(senc_scene_get_enclosure(scn, i, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- /* Inside enclosures contain 1 single media */
- ASSERT(header.enclosed_media_count == (header.is_infinite ? 2u : 1u));
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_get_max_medium(scn, &maxm));
- CHK(maxm == 1);
-
- OK(senc_scene_ref_put(scn));
- OK(senc_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_senc_cube_in_cube.c b/src/test_senc_cube_in_cube.c
@@ -1,314 +0,0 @@
-/* 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
- * 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 sg3_geometry_dump_as_C_code feature
- * of star-geometry. It uses output from test_sg3_cube_in_cube. */
-
-#include "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-/*
- cube_2 cube_3
-
- +-------------------------+
- | B
- +-------------+ | +-------------+ |
- m1 | m0 M m1 | m1 | m0 M |
- | +------+ | | m0 | +------+ | |
- | | m1 S | | | | m1 S | |
- | | N <--| | | | | N <--| | |
- | +------+ | | | +------+ | |
- | N <--| | | N <--| |
- +-------------+ | +-------------+ |
- | N <--|
- +-------------------------+
- */
-
-
-/* Dump of star-geometry 'cube_in_cube_2'. */
-static const unsigned cube_in_cube_2_vertices_count = 16;
-static const double cube_in_cube_2_vertices[48] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1,
- -0.7, -1, -1,
- 2, -1, -1,
- -1, 2, -1,
- 2, 2, -1,
- -1, -1, 2.3,
- 2, -1, 2,
- -1, 2, 2,
- 2, 2.3, 2
-};
-static const unsigned cube_in_cube_2_triangles_count = 24;
-static const unsigned cube_in_cube_2_triangles[72] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5,
- 8, 9, 10,
- 9, 11, 10,
- 8, 10, 12,
- 10, 14, 12,
- 12, 14, 13,
- 14, 15, 13,
- 11, 9, 15,
- 9, 13, 15,
- 10, 11, 14,
- 11, 15, 14,
- 8, 12, 9,
- 12, 13, 9
-};
-static const unsigned cube_in_cube_2_properties[72] =
-{
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 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 'cube_in_cube_3'. */
-static const unsigned cube_in_cube_3_vertices_count = 24;
-static const double cube_in_cube_3_vertices[72] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1,
- -0.7, -1, -1,
- 2, -1, -1,
- -1, 2, -1,
- 2, 2, -1,
- -1, -1, 2.3,
- 2, -1, 2,
- -1, 2, 2,
- 2, 2.3, 2,
- -3, -4, -4,
- 6, -4, -4,
- -4, 6, -4,
- 6, 6, -4,
- -4, -4, 7,
- 6, -4, 6,
- -4, 6, 6,
- 6, 7, 6
-};
-static const unsigned cube_in_cube_3_triangles_count = 36;
-static const unsigned cube_in_cube_3_triangles[108] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5,
- 8, 9, 10,
- 9, 11, 10,
- 8, 10, 12,
- 10, 14, 12,
- 12, 14, 13,
- 14, 15, 13,
- 11, 9, 15,
- 9, 13, 15,
- 10, 11, 14,
- 11, 15, 14,
- 8, 12, 9,
- 12, 13, 9,
- 16, 17, 18,
- 17, 19, 18,
- 16, 18, 20,
- 18, 22, 20,
- 20, 22, 21,
- 22, 23, 21,
- 19, 17, 23,
- 17, 21, 23,
- 18, 19, 22,
- 19, 23, 22,
- 16, 20, 17,
- 20, 21, 17
-};
-static const unsigned cube_in_cube_3_properties[108] =
-{
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 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 senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct context ctx = CONTEXT_NULL__;
- unsigned e, ecount, maxm, e2;
- (void)argc, (void)argv;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* Create a scene with the first and second cubes.
- * The enclosure in the small contains medium 1, the external enclosure
- * contains medium 1, the enclosure between the small and medium cubes
- * contains medium 0. */
- ctx.positions = cube_in_cube_2_vertices;
- ctx.indices = cube_in_cube_2_triangles;
- ctx.properties = cube_in_cube_2_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- cube_in_cube_2_triangles_count, get_indices, get_media_from_properties,
- cube_in_cube_2_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 3);
-
- FOR_EACH(e, 0, ecount) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- unsigned m;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- ASSERT(header.enclosed_media_count == 1);
- OK(senc_enclosure_get_medium(enclosure, 0, &m));
- ASSERT(m <= 1);
- ASSERT((m == 0) == (header.primitives_count == cube_in_cube_2_triangles_count));
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_get_max_medium(scn, &maxm));
- CHK(maxm == 1);
- OK(senc_scene_ref_put(scn));
-
- /* Create a scene with the 3 cubes, same 2 first cubes as above.
- * The enclosure in the small cube contains medium 1, the external enclosure
- * contains medium 1, the enclosure between the small and medium cubes
- * contains medium 0 and the enclosure between the medium and big cubes
- * contains both media 0 and 1. */
- ctx.positions = cube_in_cube_3_vertices;
- ctx.indices = cube_in_cube_3_triangles;
- ctx.properties = cube_in_cube_3_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- cube_in_cube_3_triangles_count, get_indices, get_media_from_properties,
- cube_in_cube_3_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 4);
-
- e2 = ecount;
- FOR_EACH(e, 0, ecount) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_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);
- e2 = e;
- }
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_get_max_medium(scn, &maxm));
- CHK(maxm == 1);
-
- OK(senc_scene_ref_put(scn));
- OK(senc_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_senc_cube_on_cube.c b/src/test_senc_cube_on_cube.c
@@ -1,205 +0,0 @@
-/* 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
- * 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 sg3_geometry_dump_as_C_code feature
- * of star-geometry. It uses output from test_sg3_cube_on_cube. */
-
-#define _POSIX_C_SOURCE 200112L /* snprintf */
-
-#include "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-#include <stdio.h>
-
-/*
- +-----------------------+
- | 3
- | +------+ |
- m2 | m1 | m0 2 |
- | | |--> N |
- | +------+ |
- | | m0 1 |
- | | |--> N |
- | +------+ |
- |--> N |
- +-----------------------+
- */
-
-/* Dump of star-geometry 'cube_on_cube'. */
-static const unsigned cube_on_cube_vertices_count = 20;
-static const double cube_on_cube_vertices[60] =
-{
- 1, 1, 2,
- 2, 1, 2,
- 1, 2, 2,
- 2, 2, 2,
- 1, 1, 3,
- 2, 1, 3,
- 1, 2, 3,
- 2, 2, 3,
- 1, 1, 1,
- 2, 1, 1,
- 1, 2, 1,
- 2, 2, 1,
- 0.4, 0, 0,
- 4, 0, 0,
- 0, 4, 0,
- 4, 4, 0,
- 0, 0, 4.4,
- 4, 0, 4,
- 0, 4, 4,
- 4, 4.4, 4
-};
-static const unsigned cube_on_cube_triangles_count = 34;
-static const unsigned cube_on_cube_triangles[102] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5,
- 8, 10, 9,
- 9, 10, 11,
- 8, 0, 10,
- 10, 0, 2,
- 11, 3, 9,
- 9, 3, 1,
- 10, 2, 11,
- 11, 2, 3,
- 8, 9, 0,
- 0, 9, 1,
- 12, 13, 14,
- 13, 15, 14,
- 12, 14, 16,
- 14, 18, 16,
- 16, 18, 17,
- 18, 19, 17,
- 15, 13, 19,
- 13, 17, 19,
- 14, 15, 18,
- 15, 19, 18,
- 12, 16, 13,
- 16, 17, 13
-};
-static const unsigned cube_on_cube_properties[102] =
-{
- 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, 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
-};
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct context ctx = CONTEXT_NULL__;
- unsigned count, e;
- (void)argc, (void)argv;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* Create a scene with the cubes.
- * The enclosures in the small cubes contain medium 0, the external enclosure
- * contains medium 2, the enclosure between the small and big cubes
- * contains medium 1. */
- ctx.positions = cube_on_cube_vertices;
- ctx.indices = cube_on_cube_triangles;
- ctx.properties = cube_on_cube_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- cube_on_cube_triangles_count, get_indices, get_media_from_properties,
- cube_on_cube_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 4);
-
- OK(senc_scene_get_vertices_count(scn, &count));
- CHK(count == cube_on_cube_vertices_count);
-
- OK(senc_scene_get_triangles_count(scn, &count));
- CHK(count == cube_on_cube_triangles_count);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 4);
- FOR_EACH(e, 0, count) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- unsigned m;
- char name[128]; (void)name;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- CHK(header.enclosed_media_count == 1);
- OK(senc_enclosure_get_medium(enclosure, 0, &m));
- if(header.is_infinite) ASSERT(m == 2); /* External */
- else if(header.primitives_count == 12) ASSERT(m == 0); /* Internal */
- else ASSERT(m == 1); /* In between */
- OK(senc_enclosure_ref_put(enclosure));
-#ifdef DUMP_ENCLOSURES
- snprintf(name, sizeof(name), "test_cube_on_cube_%u.obj", e);
- dump_enclosure(scn, e, name);
-#endif
- }
-
- OK(senc_scene_ref_put(scn));
- OK(senc_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_senc_device.c b/src/test_senc_device.c
@@ -1,77 +0,0 @@
-/* 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
- * 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 "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/logger.h>
-
-#include <stdio.h>
-
-static INLINE void
-log_stream(const char* msg, void* ctx)
-{
- ASSERT(msg);
- (void)msg, (void)ctx;
- printf("%s\n", msg);
-}
-
-int
-main(int argc, char** argv)
-{
- struct logger logger;
- struct mem_allocator allocator;
- struct senc_device* dev;
- (void)argc, (void)argv;
-
- BA(senc_device_create(NULL, NULL, 0, 0, NULL));
- BA(senc_device_create(NULL, NULL, 0, 0, &dev));
- OK(senc_device_create(NULL, NULL, 1, 0, &dev));
- BA(senc_device_ref_get(NULL));
- OK(senc_device_ref_get(dev));
- BA(senc_device_ref_put(NULL));
- OK(senc_device_ref_put(dev));
- OK(senc_device_ref_put(dev));
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
-
- CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- BA(senc_device_create(NULL, &allocator, 1, 0, NULL));
- OK(senc_device_create(NULL, &allocator, 1, 0, &dev));
- OK(senc_device_ref_put(dev));
- CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
-
- 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);
-
- BA(senc_device_create(&logger, NULL, 1, 0, NULL));
- OK(senc_device_create(&logger, NULL, 1, 0, &dev));
- OK(senc_device_ref_put(dev));
-
- BA(senc_device_create(&logger, &allocator, 1, 0, NULL));
- OK(senc_device_create(&logger, &allocator, 1, 0, &dev));
- OK(senc_device_ref_put(dev));
-
- OK(senc_device_create(&logger, &allocator, SENC_NTHREADS_DEFAULT, 0, &dev));
- OK(senc_device_ref_put(dev));
-
- logger_release(&logger);
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
- return 0;
-}
diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c
@@ -1,248 +0,0 @@
-/* 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
-* 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 "senc.h"
-#include "senc_s3d_helper.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-#include <star/s3d.h>
-
-static void
-test(const int convention)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct senc_enclosure* enclosures[2] = { NULL, NULL };
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- struct s3d_device* s3d = NULL;
- struct s3d_scene* s3d_scn = NULL;
- struct s3d_shape* s3d_shp = NULL;
- struct s3d_vertex_data s3d_attribs;
- unsigned indices[2][3];
- unsigned medium;
- unsigned gid;
- enum senc_side side;
- double vrtx[3];
- struct context ctx = CONTEXT_NULL__;
- unsigned i, n, t, count;
- int conv;
- const int conv_front = (convention & SENC_CONVENTION_NORMAL_FRONT) != 0;
- const int conv_in = (convention & SENC_CONVENTION_NORMAL_INSIDE) != 0;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* A 3D cube.
- * 2 enclosures (inside, outside) sharing the same triangles,
- * but opposite sides */
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- OK(senc_scene_create(dev, convention, ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_convention(scn, &conv));
- CHK(conv == convention);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 2);
-
- OK(senc_scene_get_enclosure(scn, 0, &enclosure));
- BA(senc_enclosure_ref_get(NULL));
- OK(senc_enclosure_ref_get(enclosure));
- BA(senc_enclosure_ref_put(NULL));
- OK(senc_enclosure_ref_put(enclosure));
-
- BA(senc_enclosure_get_triangle(NULL, 0, indices[0]));
- BA(senc_enclosure_get_triangle(enclosure, ntriangles, indices[0]));
- BA(senc_enclosure_get_triangle(enclosure, 0, NULL));
- BA(senc_enclosure_get_triangle(NULL, ntriangles, indices[0]));
- BA(senc_enclosure_get_triangle(NULL, 0, NULL));
- BA(senc_enclosure_get_triangle(enclosure, ntriangles, NULL));
- BA(senc_enclosure_get_triangle(NULL, ntriangles, NULL));
- OK(senc_enclosure_get_triangle(enclosure, 0, indices[0]));
-
- BA(senc_enclosure_get_vertex(NULL, 0, vrtx));
- BA(senc_enclosure_get_vertex(enclosure, nvertices, vrtx));
- BA(senc_enclosure_get_vertex(enclosure, 0, NULL));
- BA(senc_enclosure_get_vertex(NULL, nvertices, vrtx));
- BA(senc_enclosure_get_vertex(NULL, 0, NULL));
- BA(senc_enclosure_get_vertex(enclosure, nvertices, NULL));
- BA(senc_enclosure_get_vertex(NULL, nvertices, NULL));
- OK(senc_enclosure_get_vertex(enclosure, 0, vrtx));
-
- BA(senc_enclosure_get_triangle_id(NULL, 0, &gid, NULL));
- BA(senc_enclosure_get_triangle_id(enclosure, ntriangles, &gid, NULL));
- BA(senc_enclosure_get_triangle_id(enclosure, 0, NULL, NULL));
- BA(senc_enclosure_get_triangle_id(NULL, ntriangles, &gid, NULL));
- BA(senc_enclosure_get_triangle_id(NULL, 0, NULL, NULL));
- BA(senc_enclosure_get_triangle_id(enclosure, ntriangles, NULL, NULL));
- BA(senc_enclosure_get_triangle_id(NULL, ntriangles, NULL, NULL));
- BA(senc_enclosure_get_triangle_id(enclosure, 0, &gid, NULL));
- BA(senc_enclosure_get_triangle_id(NULL, 0, &gid, &side));
- BA(senc_enclosure_get_triangle_id(enclosure, ntriangles, &gid, &side));
- BA(senc_enclosure_get_triangle_id(enclosure, 0, NULL, &side));
- BA(senc_enclosure_get_triangle_id(NULL, ntriangles, &gid, &side));
- BA(senc_enclosure_get_triangle_id(NULL, 0, NULL, &side));
- BA(senc_enclosure_get_triangle_id(enclosure, ntriangles, NULL, &side));
- BA(senc_enclosure_get_triangle_id(NULL, ntriangles, NULL, &side));
- OK(senc_enclosure_get_triangle_id(enclosure, 0, &gid, &side));
-
- BA(senc_enclosure_get_medium(NULL, 0, &medium));
- BA(senc_enclosure_get_medium(enclosure, 2, &medium));
- BA(senc_enclosure_get_medium(enclosure, 0, NULL));
- BA(senc_enclosure_get_medium(NULL, 2, &medium));
- BA(senc_enclosure_get_medium(NULL, 0, NULL));
- BA(senc_enclosure_get_medium(enclosure, 2, NULL));
- BA(senc_enclosure_get_medium(NULL, 2, NULL));
- OK(senc_enclosure_get_medium(enclosure, 0, &medium));
-
- OK(senc_enclosure_ref_put(enclosure));
-
- FOR_EACH(i, 0, count) {
- OK(senc_scene_get_enclosure(scn, i, &enclosure));
-
- BA(senc_enclosure_get_header(NULL, &header));
- BA(senc_enclosure_get_header(enclosure, NULL));
- BA(senc_enclosure_get_header(NULL, NULL));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == i);
- CHK(header.enclosed_media_count == 1);
- OK(senc_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input triangles:
- * 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.primitives_count == ntriangles);
- CHK(header.unique_primitives_count == ntriangles);
- CHK(header.vertices_count == nvertices);
- CHK(header.is_infinite == (i == 0));
-
- FOR_EACH(t, 0, header.primitives_count) {
- OK(senc_enclosure_get_triangle_id(enclosure, t, &gid, &side));
- CHK(gid == t);
- CHK(side == (medium == 0) ? SENC_FRONT : SENC_BACK);
- }
-
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- FOR_EACH(i, 0, 2)
- OK(senc_scene_get_enclosure(scn, i, enclosures + i));
- FOR_EACH(n, 0, ntriangles) {
- int same, reversed;
- /* Read same triangles in both enclosures */
- FOR_EACH(i, 0, 2)
- OK(senc_enclosure_get_triangle(enclosures[i], n, indices[i]));
- /* Same triangles and opposite sides for the 2 enclosures */
- FOR_EACH(i, 0, 3) CHK(indices[0][i] == indices[1][2 - i]);
- /* Enclosure 0 is outside (and contains medium 0 if convention is front).
- * Geometrical normals in output data point in the same direction that those
- * of input triangles for enclosure 0 iff convention is inside.
- * The opposite holds for enclosure 1. */
- cmp_trg(n, enclosures[0], box_indices + 3 * n, box_vertices, &same, &reversed);
- CHK((same && !reversed) == conv_in);
- cmp_trg(n, enclosures[1], box_indices + 3 * n, box_vertices, &same, &reversed);
- CHK(same && reversed == conv_in);
- }
- FOR_EACH(i, 0, 2)
- OK(senc_enclosure_ref_put(enclosures[i]));
-
- OK(senc_scene_ref_put(scn));
-
- /* Same 3D cube, but with a hole (incomplete).
- * 1 single enclosure including both sides of triangles */
-
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- OK(senc_scene_create(dev, convention, ntriangles - 1, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_frontier_segments_count(scn, &count));
- CHK(count == 3);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 1);
-
-#ifdef DUMP_ENCLOSURES
- dump_enclosure(scn, 0, "test_enclosure_hole.obj");
-#endif
-
- OK(senc_scene_get_enclosure(scn, 0, &enclosure));
-
- BA(senc_enclosure_get_header(NULL, &header));
- BA(senc_enclosure_get_header(enclosure, NULL));
- BA(senc_enclosure_get_header(NULL, NULL));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == 0);
- CHK(header.enclosed_media_count == 2);
- CHK(header.primitives_count == 2 * header.unique_primitives_count);
- CHK(header.unique_primitives_count == ntriangles - 1);
- CHK(header.vertices_count == nvertices);
- CHK(header.is_infinite == 1);
-
- FOR_EACH(t, 0, header.primitives_count) {
- OK(senc_enclosure_get_triangle_id(enclosure, t, &gid, &side));
- /* The first unique_triangle_count triangles of an enclosure
- * are unique triangles */
- if(t < header.unique_primitives_count) CHK(gid == t);
- CHK(side == (t < header.unique_primitives_count) ? SENC_FRONT : SENC_BACK);
- }
-
- /* Put geometry in a 3D view using helper functions */
- s3d_attribs.type = S3D_FLOAT3;
- s3d_attribs.usage = S3D_POSITION;
- s3d_attribs.get = senc_s3d_enclosure_get_position__;
- OK(s3d_device_create(NULL, &allocator, 0, &s3d));
- OK(s3d_scene_create(s3d, &s3d_scn));
- OK(s3d_shape_create_mesh(s3d, &s3d_shp));
- OK(s3d_mesh_setup_indexed_vertices(s3d_shp, header.primitives_count,
- senc_s3d_enclosure_get_indices__, header.vertices_count, &s3d_attribs,
- 1, enclosure));
- OK(s3d_scene_attach_shape(s3d_scn, s3d_shp));
- S3D(shape_ref_put(s3d_shp));
- S3D(device_ref_put(s3d));
- S3D(scene_ref_put(s3d_scn));
-
- SENC(scene_ref_put(scn));
- SENC(device_ref_put(dev));
- SENC(enclosure_ref_put(enclosure));
-
- 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(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE);
- test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE);
- test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_OUTSIDE);
- test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_OUTSIDE);
- return 0;
-}
diff --git a/src/test_senc_inconsistant_cube.c b/src/test_senc_inconsistant_cube.c
@@ -1,145 +0,0 @@
-/* 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
-* 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 "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-/* The following array lists the indices toward the 3D vertices of each
-* triangle.
-* ,6---,7 ,6----7
-* ,' | ,'/| ,' | \ | Y Z
-* 2----3' / | 2', | \ | | ,'
-* |', | / ,5 | ',4---,5 0----X
-* | ',|/,' | ,' | ,'
-* 0----1' 0----1'
-* Front, right Back, left and
-* and Top faces bottom faces */
-/* Triangle #1 rotation order is not consistant with other triangles */
-static unsigned
-inconsistant_box_indices[12/*#triangles*/ * 3/*#indices per triangle*/] = {
- 0, 1, 2, 1, 2, 3, /* Front face */
- 0, 4, 2, 2, 4, 6, /* Left face*/
- 4, 5, 6, 6, 5, 7, /* Back face */
- 3, 7, 1, 1, 7, 5, /* Right face */
- 2, 6, 3, 3, 6, 7, /* Top face */
- 0, 1, 4, 4, 1, 5 /* Bottom face */
-};
-static const unsigned inconsistant_box_ntriangles
-= sizeof(inconsistant_box_indices) / (3 * sizeof(*inconsistant_box_indices));
-
-/* Media definitions reflect triangle #1 inconsistancy */
-static const unsigned
-inconsistant_medium_front[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static const unsigned
-inconsistant_medium_back[12] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
-
-static void
-test(const int convention)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- int conv;
- int conv_front, conv_in;
- struct context ctx = CONTEXT_NULL__;
- unsigned i, e, ecount;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* A 3D cube.
- * 2 enclosures (inside, outside) sharing the same triangles,
- * but opposite sides.
- * What differs in this test is that triangle #0 vertices are given
- * in the opposite rotation order. */
- ctx.positions = box_vertices;
- ctx.indices = inconsistant_box_indices;
- ctx.front_media = inconsistant_medium_front;
- ctx.back_media = inconsistant_medium_back;
-
- OK(senc_scene_create(dev, convention, inconsistant_box_ntriangles,
- get_indices, get_media, nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 2);
-
- OK(senc_scene_get_convention(scn, &conv));
- CHK(conv == convention);
- conv_front = (conv & SENC_CONVENTION_NORMAL_FRONT) != 0;
- conv_in = (conv & SENC_CONVENTION_NORMAL_INSIDE) != 0;
-
- FOR_EACH(e, 0, ecount) {
- unsigned medium, expected_external_medium, expected_medium;
- char name[128];
- enum senc_side side, expected_side;
- unsigned gid;
- (void)name;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- CHK(header.enclosed_media_count == 1);
- OK(senc_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;
- expected_medium = (header.is_infinite ?
- expected_external_medium : !expected_external_medium);
- CHK(medium == expected_medium);
-
-#ifdef DUMP_ENCLOSURES
- sprintf(name, "test_inconsistant_cube_%s_%s_%u.obj",
- conv_front ? "front" : "back", conv_in ? "in" : "out", e);
- dump_enclosure(scn, e, name);
-#endif
-
- 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)
- ? SENC_FRONT : SENC_BACK;
- cmp_trg(i, enclosure,
- inconsistant_box_indices + (3 * i), box_vertices,
- &same, &reversed);
- /* Should be made of the same triangles */
- CHK(same);
- CHK(i ? reversed != fst_reversed : reversed == fst_reversed);
- OK(senc_enclosure_get_triangle_id(enclosure, i, &gid, &side));
- CHK(side == expected_side);
- }
- SENC(enclosure_ref_put(enclosure));
- }
-
- SENC(scene_ref_put(scn));
- SENC(device_ref_put(dev));
-
- 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(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE);
- test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE);
- test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_OUTSIDE);
- test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_OUTSIDE);
-
- return 0;
-}
diff --git a/src/test_senc_many_enclosures.c b/src/test_senc_many_enclosures.c
@@ -1,108 +0,0 @@
-/* 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
-* 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 is similar to test_senc_some_enclosures, but involves 64*64*64
- * cylinders instead of 4*4*4, thus making it impossible to define the geometry
- * through static arrays. */
-
-#define NB_CYL_X 32
-#define NB_CYL_Y 32
-#define NB_CYL_Z 64
- /* 64^3 = 262144 cylinders */
-#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
-
-#include "senc.h"
-#include "test_senc_utils.h"
-#include "test_senc_utils2.h"
-
-#include <star/s3dut.h>
-#include <rsys/clock_time.h>
-#include <rsys/double3.h>
-
-#include <stdio.h>
-#include <limits.h>
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct s3dut_mesh* cyl = NULL;
- struct s3dut_context ctx = { {NULL,NULL,0,0}, CONTEXT_NULL__ };
- unsigned count;
- unsigned cyl_trg_count, cyl_vrtx_count, e;
- char dump[64];
- struct time t0, t1;
- (void)argc, (void)argv;
-
- OK(mem_init_regular_allocator(&allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* A 20 triangles 12 vertices cylinder template */
- S3DUT(create_cylinder(&allocator, 1, 1, 3, 1, &cyl));
- S3DUT(mesh_get_data(cyl, &ctx.data));
- ASSERT(ctx.data.nprimitives < UINT_MAX);
- ASSERT(ctx.data.nvertices < UINT_MAX);
- cyl_trg_count = (unsigned)ctx.data.nprimitives;
- cyl_vrtx_count = (unsigned)ctx.data.nvertices;
-
- /* Create the scene with N_CYL cylinders.
- * There are NB_CYL_X * NB_CYL_Y imbrications of NB_CYL_Z cylinders each.
- * Each imbrication is located on a grid.
- * The get_s3du_xxx getters have to retrieve the cylinder from the
- * primitive and vertice indexes. */
- time_current(&t0);
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- NB_CYL * cyl_trg_count, get_s3dut_indices, get_s3dut_media,
- NB_CYL * cyl_vrtx_count, get_s3dut_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 created in: %s\n", dump);
- S3DUT(mesh_ref_put(cyl));
-
- OK(senc_scene_get_vertices_count(scn, &count));
- CHK(count == NB_CYL * cyl_vrtx_count);
- OK(senc_scene_get_triangles_count(scn, &count));
- CHK(count == NB_CYL * cyl_trg_count);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 1 + NB_CYL);
- FOR_EACH(e, 0, count) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- unsigned m;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- CHK(header.enclosed_media_count == 1);
- OK(senc_enclosure_get_medium(enclosure, 0, &m));
- CHK(header.primitives_count ==
- (header.is_infinite /* Outermost enclosure: NB_CYL_X*NB_CYL_Y cylinders */
- ? NB_CYL_X * NB_CYL_Y * cyl_trg_count
- : (m == 0
- ? cyl_trg_count /* Innermost enclosures: 1 cylinder */
- : 2 * cyl_trg_count))); /* Other enclosures: 2 cylinders */
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_ref_put(scn));
- OK(senc_device_ref_put(dev));
-
- check_memory_allocator(&allocator);
- mem_shutdown_regular_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
- return 0;
-}
diff --git a/src/test_senc_many_triangles.c b/src/test_senc_many_triangles.c
@@ -1,101 +0,0 @@
-/* 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
-* 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 is similar to test_senc_some_triangles, but involves 4*2562560
- * triangles instead of 4*1054, thus making it impossible to define the geometry
- * through static arrays. */
-
-#define NB_CYL_X 2
-#define NB_CYL_Y 1
-#define NB_CYL_Z 1
- /* 4 cylinders */
-#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
-
-#include "senc.h"
-#include "test_senc_utils.h"
-#include "test_senc_utils2.h"
-
-#include <star/s3dut.h>
-#include <rsys/clock_time.h>
-#include <rsys/double3.h>
-
-#include <stdio.h>
-#include <limits.h>
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct s3dut_mesh* cyl = NULL;
- struct s3dut_context ctx = { {NULL,NULL,0,0}, CONTEXT_NULL__ };
- unsigned m0 = 0;
- unsigned count;
- unsigned cyl_trg_count, cyl_vrtx_count, e;
- char dump[64];
- struct time t0, t1;
- (void)argc, (void)argv;
-
- OK(mem_init_regular_allocator(&allocator));
- OK(senc_device_create (NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* A 2,562,560 triangles 1,281,282 vertices cylinder template */
- S3DUT(create_cylinder(&allocator, 1, 2, 1280, 1000, &cyl));
- S3DUT(mesh_get_data(cyl, &ctx.data));
- ASSERT(ctx.data.nprimitives < UINT_MAX);
- ASSERT(ctx.data.nvertices < UINT_MAX);
- cyl_trg_count = (unsigned)ctx.data.nprimitives;
- cyl_vrtx_count = (unsigned)ctx.data.nvertices;
-
- /* Create the scene with 4 cylinders.
- * The get_s3du_xxx getters have to retrieve the cylinder from the
- * primitive and vertice indexes. */
- ctx.ctx.back_media = &m0;
- time_current(&t0);
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- NB_CYL* cyl_trg_count, get_s3dut_indices, get_s3dut_media,
- NB_CYL* cyl_vrtx_count, get_s3dut_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 created in: %s\n", dump);
- S3DUT(mesh_ref_put(cyl));
-
- OK(senc_scene_get_vertices_count(scn, &count));
- CHK(count == NB_CYL * cyl_vrtx_count);
- OK(senc_scene_get_triangles_count(scn, &count));
- CHK(count == NB_CYL * cyl_trg_count);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 1 + NB_CYL);
- FOR_EACH(e, 0, count) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- CHK(header.primitives_count ==
- e ? cyl_trg_count : NB_CYL * cyl_trg_count);
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_ref_put(scn));
- OK(senc_device_ref_put(dev));
-
- check_memory_allocator(&allocator);
- mem_shutdown_regular_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
- return 0;
-}
diff --git a/src/test_senc_sample_enclosure.c b/src/test_senc_sample_enclosure.c
@@ -1,124 +0,0 @@
-/* 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
-* 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 "senc.h"
-#include "senc_s3d_helper.h"
-#include "test_senc_utils.h"
-
-#include <rsys/float3.h>
-#include <rsys/double3.h>
-
-#include <star/s3d.h>
-#include <star/ssp.h>
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct senc_enclosure* enclosure = NULL;
- struct senc_enclosure_header header;
- struct s3d_device* s3d = NULL;
- struct s3d_scene* s3d_scn = NULL;
- struct s3d_scene_view* s3d_view = NULL;
- struct s3d_shape* s3d_shp = NULL;
- struct s3d_primitive prim;
- struct s3d_vertex_data vrtx_get;
- struct ssp_rng* rng;
- struct context ctx = CONTEXT_NULL__;
- int i;
- float st[2];
- (void)argc, (void)argv;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* A 3D cube, but with a hole (incomplete).
- * 1 single enclosure including both sides of triangles */
- ctx.positions = cube_vertices;
- ctx.indices = box_indices;
- ctx.front_media = medium0;
- ctx.back_media = medium0;
-
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles - 1, get_indices, get_media, nvertices, get_position, &ctx,
- &scn));
-
- OK(senc_scene_get_enclosure(scn, 0, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- /* Put enclosure in a 3D view... */
- vrtx_get.type = S3D_FLOAT3;
- vrtx_get.usage = S3D_POSITION;
- vrtx_get.get = senc_s3d_enclosure_get_position__;
- S3D(device_create(NULL, &allocator, 0, &s3d));
- S3D(scene_create(s3d, &s3d_scn));
- S3D(shape_create_mesh(s3d, &s3d_shp));
- S3D(mesh_setup_indexed_vertices(s3d_shp, header.primitives_count,
- senc_s3d_enclosure_get_indices__, header.vertices_count, &vrtx_get, 1,
- enclosure));
- S3D(scene_attach_shape(s3d_scn, s3d_shp));
- S3D(scene_view_create(s3d_scn, S3D_SAMPLE, &s3d_view));
-
- /* ... and sample it. */
- OK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng));
- FOR_EACH(i, 0, 10000) {
- struct s3d_attrib attrib;
- int n, c;
- S3D(scene_view_sample(s3d_view,
- ssp_rng_canonical_float(rng),
- ssp_rng_canonical_float(rng),
- ssp_rng_canonical_float(rng),
- &prim, st));
- S3D(primitive_get_attrib(&prim, S3D_POSITION, st, &attrib));
- c = 0;
- FOR_EACH(n, 0, 3)
- if(eq_eps(attrib.value[n], 0, FLT_EPSILON)
- || eq_eps(attrib.value[n], 1, FLT_EPSILON))
- c++;
- CHK(c == 1);
- S3D(primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, st, &attrib));
- c = 0;
- FOR_EACH(n, 0, 3)
- if(eq_eps(attrib.value[n], -1, FLT_EPSILON)
- || eq_eps(attrib.value[n], 1, FLT_EPSILON))
- c++;
- CHK(c == 1);
- c = 0;
- FOR_EACH(n, 0, 3)
- if(eq_eps(attrib.value[n], 0, FLT_EPSILON))
- c++;
- CHK(c == 2);
- }
-
- SENC(enclosure_ref_put(enclosure));
- SENC(scene_ref_put(scn));
- SENC(device_ref_put(dev));
-
- SSP(rng_ref_put(rng));
-
- S3D(shape_ref_put(s3d_shp));
- S3D(scene_view_ref_put(s3d_view));
- S3D(device_ref_put(s3d));
- S3D(scene_ref_put(s3d_scn));
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
-
- return 0;
-}
diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c
@@ -1,296 +0,0 @@
-/* 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
- * 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 "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/float3.h>
-#include <rsys/double3.h>
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct senc_enclosure* enc = NULL;
- struct senc_enclosure_header header;
- struct context ctx = CONTEXT_NULL__;
- unsigned medfront[2], medback[2], ind[3], ids[2];
- double vrtx[3];
- unsigned count, i, maxm;
- int convention;
- (void)argc, (void)argv;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* A 3D cube.
- * With this geometry front is inside with NORMAL_BACK convention,
- * outside with NORMAL_FRONT convention */
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- BA(senc_scene_create(NULL,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
- BA(senc_scene_create(dev,
- 0,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
- BA(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- 0, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
- BA(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, NULL, get_media,
- nvertices, get_position, &ctx, &scn));
- BA(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- 0, get_position, &ctx, &scn));
- BA(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, NULL, &ctx, &scn));
- BA(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, NULL));
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
-
- BA(senc_scene_get_convention(NULL, &convention));
- BA(senc_scene_get_convention(scn, NULL));
- BA(senc_scene_get_convention(NULL, NULL));
- OK(senc_scene_get_convention(scn, &convention));
- CHK(convention
- == (SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE));
-
- BA(senc_scene_get_triangles_count(NULL, &count));
- BA(senc_scene_get_triangles_count(scn, NULL));
- BA(senc_scene_get_triangles_count(NULL, NULL));
- OK(senc_scene_get_triangles_count(scn, &count));
- CHK(count == ntriangles);
-
- BA(senc_scene_get_vertices_count(NULL, &count));
- BA(senc_scene_get_vertices_count(scn, NULL));
- BA(senc_scene_get_vertices_count(NULL, NULL));
- OK(senc_scene_get_vertices_count(scn, &count));
- CHK(count == nvertices);
-
- BA(senc_scene_get_triangle(NULL, 0, ind));
- BA(senc_scene_get_triangle(scn, UINT_MAX, ind));
- BA(senc_scene_get_triangle(scn, 0, NULL));
- BA(senc_scene_get_triangle(NULL, UINT_MAX, ind));
- BA(senc_scene_get_triangle(NULL, 0, NULL));
- BA(senc_scene_get_triangle(scn, UINT_MAX, NULL));
- BA(senc_scene_get_triangle(NULL, UINT_MAX, NULL));
- OK(senc_scene_get_triangle(scn, 0, ind));
-
- BA(senc_scene_get_triangle_media(NULL, 0, ind));
- BA(senc_scene_get_triangle_media(scn, UINT_MAX, ind));
- BA(senc_scene_get_triangle_media(scn, 0, NULL));
- BA(senc_scene_get_triangle_media(NULL, UINT_MAX, ind));
- BA(senc_scene_get_triangle_media(NULL, 0, NULL));
- BA(senc_scene_get_triangle_media(scn, UINT_MAX, NULL));
- BA(senc_scene_get_triangle_media(NULL, UINT_MAX, NULL));
- OK(senc_scene_get_triangle_media(scn, 0, ind));
-
- BA(senc_scene_get_vertex(NULL, 0, vrtx));
- BA(senc_scene_get_vertex(scn, UINT_MAX, vrtx));
- BA(senc_scene_get_vertex(scn, 0, NULL));
- BA(senc_scene_get_vertex(NULL, UINT_MAX, vrtx));
- BA(senc_scene_get_vertex(NULL, 0, NULL));
- BA(senc_scene_get_vertex(scn, UINT_MAX, NULL));
- BA(senc_scene_get_vertex(NULL, UINT_MAX, NULL));
- OK(senc_scene_get_vertex(scn, 0, vrtx));
-
- BA(senc_scene_get_max_medium(NULL, &maxm));
- BA(senc_scene_get_max_medium(scn, NULL));
- BA(senc_scene_get_max_medium(NULL, NULL));
- OK(senc_scene_get_max_medium(scn, &maxm));
- CHK(maxm == 1);
-
- BA(senc_scene_get_enclosure_count(NULL, &count));
- BA(senc_scene_get_enclosure_count(scn, NULL));
- BA(senc_scene_get_enclosure_count(NULL, NULL));
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 2);
-
- BA(senc_scene_get_enclosure_count_by_medium(NULL, 0, &count));
- BA(senc_scene_get_enclosure_count_by_medium(scn, 100, &count));
- BA(senc_scene_get_enclosure_count_by_medium(scn, 0, NULL));
- BA(senc_scene_get_enclosure_count_by_medium(NULL, 100, &count));
- BA(senc_scene_get_enclosure_count_by_medium(NULL, 0, NULL));
- BA(senc_scene_get_enclosure_count_by_medium(scn, 100, NULL));
- BA(senc_scene_get_enclosure_count_by_medium(NULL, 100, NULL));
- OK(senc_scene_get_enclosure_count_by_medium(scn, 0, &count));
- CHK(count == 1);
- OK(senc_scene_get_enclosure_count_by_medium(scn, SENC_UNSPECIFIED_MEDIUM,
- &count));
- CHK(count == 0);
-
- BA(senc_scene_get_enclosure(NULL, 0, &enc));
- BA(senc_scene_get_enclosure(scn, UINT_MAX, &enc));
- BA(senc_scene_get_enclosure(scn, 0, NULL));
- BA(senc_scene_get_enclosure(NULL, UINT_MAX, &enc));
- BA(senc_scene_get_enclosure(NULL, 0, NULL));
- BA(senc_scene_get_enclosure(scn, UINT_MAX, NULL));
- BA(senc_scene_get_enclosure(NULL, UINT_MAX, NULL));
- OK(senc_scene_get_enclosure(scn, 0, &enc));
- OK(senc_enclosure_ref_put(enc));
-
- BA(senc_scene_get_enclosure_by_medium(NULL, 0, 0, &enc));
- BA(senc_scene_get_enclosure_by_medium(scn, 100, 0, &enc));
- BA(senc_scene_get_enclosure_by_medium(scn, 0, UINT_MAX, &enc));
- BA(senc_scene_get_enclosure_by_medium(scn, 0, 0, NULL));
- BA(senc_scene_get_enclosure_by_medium(NULL, 100, 0, &enc));
- BA(senc_scene_get_enclosure_by_medium(NULL, 0, UINT_MAX, &enc));
- BA(senc_scene_get_enclosure_by_medium(NULL, 0, 0, NULL));
- BA(senc_scene_get_enclosure_by_medium(scn, 100, UINT_MAX, &enc));
- BA(senc_scene_get_enclosure_by_medium(scn, 100, 0, NULL));
- BA(senc_scene_get_enclosure_by_medium(scn, 0, UINT_MAX, NULL));
- BA(senc_scene_get_enclosure_by_medium(scn, 100, UINT_MAX, NULL));
- BA(senc_scene_get_enclosure_by_medium(NULL, 0, UINT_MAX, NULL));
- BA(senc_scene_get_enclosure_by_medium(NULL, 100, 0, NULL));
- BA(senc_scene_get_enclosure_by_medium(NULL, 100, UINT_MAX, &enc));
- BA(senc_scene_get_enclosure_by_medium(NULL, 100, UINT_MAX, NULL));
- OK(senc_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
- OK(senc_enclosure_ref_put(enc));
- /* Index 0 is out of range for SENC_UNSPECIFIED_MEDIUM. */
- BA(senc_scene_get_enclosure_by_medium(scn, SENC_UNSPECIFIED_MEDIUM, 0, &enc));
-
- BA(senc_scene_get_triangle_enclosures(NULL, 0, ids));
- BA(senc_scene_get_triangle_enclosures(scn, UINT_MAX, ids));
- BA(senc_scene_get_triangle_enclosures(scn, 0, NULL));
- BA(senc_scene_get_triangle_enclosures(NULL, UINT_MAX, ids));
- BA(senc_scene_get_triangle_enclosures(NULL, 0, NULL));
- BA(senc_scene_get_triangle_enclosures(scn, UINT_MAX, NULL));
- BA(senc_scene_get_triangle_enclosures(NULL, UINT_MAX, NULL));
- OK(senc_scene_get_triangle_enclosures(scn, 0, ids));
-
- BA(senc_scene_get_frontier_segments_count(NULL, &count));
- BA(senc_scene_get_frontier_segments_count(scn, NULL));
- BA(senc_scene_get_frontier_segments_count(NULL, NULL));
- OK(senc_scene_get_frontier_segments_count(scn, &count));
- CHK(count == 0);
-
- BA(senc_scene_get_frontier_segment(NULL, 0, ids));
- BA(senc_scene_get_frontier_segment(scn, UINT_MAX, ids));
- BA(senc_scene_get_frontier_segment(scn, 0, NULL));
- BA(senc_scene_get_frontier_segment(NULL, UINT_MAX, ids));
- BA(senc_scene_get_frontier_segment(NULL, 0, NULL));
- BA(senc_scene_get_frontier_segment(scn, UINT_MAX, NULL));
- BA(senc_scene_get_frontier_segment(NULL, UINT_MAX, NULL));
-
- BA(senc_scene_ref_get(NULL));
- OK(senc_scene_ref_get(scn));
- BA(senc_scene_ref_put(NULL));
- OK(senc_scene_ref_put(scn));
-
- OK(senc_scene_ref_put(scn));
-
- /* Same geometry with SENC_UNSPECIFIED_MEDIUM */
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, NULL,
- nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_by_medium(scn, SENC_UNSPECIFIED_MEDIUM, 0, &enc));
- OK(senc_enclosure_ref_put(enc));
- BA(senc_scene_get_enclosure_by_medium(scn, SENC_UNSPECIFIED_MEDIUM, 100, &enc));
-
- OK(senc_scene_ref_put(scn));
-
- /* Same geometry with a hole (1 missing triangle) */
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles - 1, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_frontier_segments_count(scn, &count));
- CHK(count == 3);
- OK(senc_scene_get_frontier_segment(scn, 0, ids));
- BA(senc_scene_get_frontier_segment(scn, 3, ids));
-
- OK(senc_scene_ref_put(scn));
-
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_convention(scn, &convention));
- CHK(convention
- == (SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE));
- /* Check that medium 0 is inside */
- OK(senc_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
- OK(senc_enclosure_get_header(enc, &header));
- CHK(!header.is_infinite);
- OK(senc_enclosure_ref_put(enc));
-
- OK(senc_scene_get_triangle_media(scn, 0, medback));
- OK(senc_scene_ref_put(scn));
-
- /* Medium mismatch between neighbour segments, but OK */
- ctx.front_media = medium1_3;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
-
- OK(senc_scene_get_max_medium(scn, &maxm));
- CHK(maxm == 3);
- OK(senc_scene_get_enclosure_count_by_medium(scn, 0, &count));
- CHK(count == 0); /* Medium 0 unused */
- OK(senc_scene_get_enclosure_count_by_medium(scn, 1, &count));
- CHK(count == 2); /* Medium 1 used twice */
- OK(senc_scene_get_enclosure_count_by_medium(scn, 2, &count));
- CHK(count == 0); /* Medium 2 unused */
- OK(senc_scene_get_enclosure_count_by_medium(scn, 3, &count));
- CHK(count == 1); /* Medium 3 used */
-
- OK(senc_scene_ref_put(scn));
-
- ctx.front_media = medium0;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- ntriangles, get_indices, get_media,
- nvertices, get_position, &ctx, &scn));
- /* Check that medium 0 is outside */
- OK(senc_scene_get_enclosure_by_medium(scn, 0, 0, &enc));
- OK(senc_enclosure_get_header(enc, &header));
- CHK(header.is_infinite);
- OK(senc_enclosure_ref_put(enc));
-
- OK(senc_scene_get_triangle_media(scn, 0, medfront));
- FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);
-
- OK(senc_scene_ref_put(scn));
- OK(senc_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_senc_some_enclosures.c b/src/test_senc_some_enclosures.c
@@ -1,3427 +0,0 @@
-/* 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
- * 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 sg3_geometry_dump_as_C_code feature
- * of star-geometry. It uses output from test_sg3_some_enclosures.
- * This test is similar to test_senc_many_enclosures that creates a huge
- * geometry by program. */
-
-#include "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-/* Dump of star-geometry 'some_enclosures'. */
-static const unsigned some_enclosures_vertices_count = 768;
-static const double some_enclosures_vertices[2304] =
-{
- -19, -20, -0.5,
- -19, -20, 0.5,
- -19.691, -19.0489, -0.5,
- -19.691, -19.0489, 0.5,
- -20.809, -19.4122, -0.5,
- -20.809, -19.4122, 0.5,
- -20.809, -20.5878, -0.5,
- -20.809, -20.5878, 0.5,
- -19.691, -20.9511, -0.5,
- -19.691, -20.9511, 0.5,
- -20, -20, -0.5,
- -20, -20, 0.5,
- -18, -20, -1,
- -18, -20, 1,
- -19.382, -18.0979, -1,
- -19.382, -18.0979, 1,
- -21.618, -18.8244, -1,
- -21.618, -18.8244, 1,
- -21.618, -21.1756, -1,
- -21.618, -21.1756, 1,
- -19.382, -21.9021, -1,
- -19.382, -21.9021, 1,
- -20, -20, -1,
- -20, -20, 1,
- -17, -20, -1.5,
- -17, -20, 1.5,
- -19.0729, -17.1468, -1.5,
- -19.0729, -17.1468, 1.5,
- -22.4271, -18.2366, -1.5,
- -22.4271, -18.2366, 1.5,
- -22.4271, -21.7634, -1.5,
- -22.4271, -21.7634, 1.5,
- -19.0729, -22.8532, -1.5,
- -19.0729, -22.8532, 1.5,
- -20, -20, -1.5,
- -20, -20, 1.5,
- -16, -20, -2,
- -16, -20, 2,
- -18.7639, -16.1958, -2,
- -18.7639, -16.1958, 2,
- -23.2361, -17.6489, -2,
- -23.2361, -17.6489, 2,
- -23.2361, -22.3511, -2,
- -23.2361, -22.3511, 2,
- -18.7639, -23.8042, -2,
- -18.7639, -23.8042, 2,
- -20, -20, -2,
- -20, -20, 2,
- -19, -10, -0.5,
- -19, -10, 0.5,
- -19.691, -9.04894, -0.5,
- -19.691, -9.04894, 0.5,
- -20.809, -9.41221, -0.5,
- -20.809, -9.41221, 0.5,
- -20.809, -10.5878, -0.5,
- -20.809, -10.5878, 0.5,
- -19.691, -10.9511, -0.5,
- -19.691, -10.9511, 0.5,
- -20, -10, -0.5,
- -20, -10, 0.5,
- -18, -10, -1,
- -18, -10, 1,
- -19.382, -8.09789, -1,
- -19.382, -8.09789, 1,
- -21.618, -8.82443, -1,
- -21.618, -8.82443, 1,
- -21.618, -11.1756, -1,
- -21.618, -11.1756, 1,
- -19.382, -11.9021, -1,
- -19.382, -11.9021, 1,
- -20, -10, -1,
- -20, -10, 1,
- -17, -10, -1.5,
- -17, -10, 1.5,
- -19.0729, -7.14683, -1.5,
- -19.0729, -7.14683, 1.5,
- -22.4271, -8.23664, -1.5,
- -22.4271, -8.23664, 1.5,
- -22.4271, -11.7634, -1.5,
- -22.4271, -11.7634, 1.5,
- -19.0729, -12.8532, -1.5,
- -19.0729, -12.8532, 1.5,
- -20, -10, -1.5,
- -20, -10, 1.5,
- -16, -10, -2,
- -16, -10, 2,
- -18.7639, -6.19577, -2,
- -18.7639, -6.19577, 2,
- -23.2361, -7.64886, -2,
- -23.2361, -7.64886, 2,
- -23.2361, -12.3511, -2,
- -23.2361, -12.3511, 2,
- -18.7639, -13.8042, -2,
- -18.7639, -13.8042, 2,
- -20, -10, -2,
- -20, -10, 2,
- -19, 0, -0.5,
- -19, 0, 0.5,
- -19.691, 0.951057, -0.5,
- -19.691, 0.951057, 0.5,
- -20.809, 0.587785, -0.5,
- -20.809, 0.587785, 0.5,
- -20.809, -0.587785, -0.5,
- -20.809, -0.587785, 0.5,
- -19.691, -0.951057, -0.5,
- -19.691, -0.951057, 0.5,
- -20, 0, -0.5,
- -20, 0, 0.5,
- -18, 0, -1,
- -18, 0, 1,
- -19.382, 1.90211, -1,
- -19.382, 1.90211, 1,
- -21.618, 1.17557, -1,
- -21.618, 1.17557, 1,
- -21.618, -1.17557, -1,
- -21.618, -1.17557, 1,
- -19.382, -1.90211, -1,
- -19.382, -1.90211, 1,
- -20, 0, -1,
- -20, 0, 1,
- -17, 0, -1.5,
- -17, 0, 1.5,
- -19.0729, 2.85317, -1.5,
- -19.0729, 2.85317, 1.5,
- -22.4271, 1.76336, -1.5,
- -22.4271, 1.76336, 1.5,
- -22.4271, -1.76336, -1.5,
- -22.4271, -1.76336, 1.5,
- -19.0729, -2.85317, -1.5,
- -19.0729, -2.85317, 1.5,
- -20, 0, -1.5,
- -20, 0, 1.5,
- -16, 0, -2,
- -16, 0, 2,
- -18.7639, 3.80423, -2,
- -18.7639, 3.80423, 2,
- -23.2361, 2.35114, -2,
- -23.2361, 2.35114, 2,
- -23.2361, -2.35114, -2,
- -23.2361, -2.35114, 2,
- -18.7639, -3.80423, -2,
- -18.7639, -3.80423, 2,
- -20, 0, -2,
- -20, 0, 2,
- -19, 10, -0.5,
- -19, 10, 0.5,
- -19.691, 10.9511, -0.5,
- -19.691, 10.9511, 0.5,
- -20.809, 10.5878, -0.5,
- -20.809, 10.5878, 0.5,
- -20.809, 9.41221, -0.5,
- -20.809, 9.41221, 0.5,
- -19.691, 9.04894, -0.5,
- -19.691, 9.04894, 0.5,
- -20, 10, -0.5,
- -20, 10, 0.5,
- -18, 10, -1,
- -18, 10, 1,
- -19.382, 11.9021, -1,
- -19.382, 11.9021, 1,
- -21.618, 11.1756, -1,
- -21.618, 11.1756, 1,
- -21.618, 8.82443, -1,
- -21.618, 8.82443, 1,
- -19.382, 8.09789, -1,
- -19.382, 8.09789, 1,
- -20, 10, -1,
- -20, 10, 1,
- -17, 10, -1.5,
- -17, 10, 1.5,
- -19.0729, 12.8532, -1.5,
- -19.0729, 12.8532, 1.5,
- -22.4271, 11.7634, -1.5,
- -22.4271, 11.7634, 1.5,
- -22.4271, 8.23664, -1.5,
- -22.4271, 8.23664, 1.5,
- -19.0729, 7.14683, -1.5,
- -19.0729, 7.14683, 1.5,
- -20, 10, -1.5,
- -20, 10, 1.5,
- -16, 10, -2,
- -16, 10, 2,
- -18.7639, 13.8042, -2,
- -18.7639, 13.8042, 2,
- -23.2361, 12.3511, -2,
- -23.2361, 12.3511, 2,
- -23.2361, 7.64886, -2,
- -23.2361, 7.64886, 2,
- -18.7639, 6.19577, -2,
- -18.7639, 6.19577, 2,
- -20, 10, -2,
- -20, 10, 2,
- -9, -20, -0.5,
- -9, -20, 0.5,
- -9.69098, -19.0489, -0.5,
- -9.69098, -19.0489, 0.5,
- -10.809, -19.4122, -0.5,
- -10.809, -19.4122, 0.5,
- -10.809, -20.5878, -0.5,
- -10.809, -20.5878, 0.5,
- -9.69098, -20.9511, -0.5,
- -9.69098, -20.9511, 0.5,
- -10, -20, -0.5,
- -10, -20, 0.5,
- -8, -20, -1,
- -8, -20, 1,
- -9.38197, -18.0979, -1,
- -9.38197, -18.0979, 1,
- -11.618, -18.8244, -1,
- -11.618, -18.8244, 1,
- -11.618, -21.1756, -1,
- -11.618, -21.1756, 1,
- -9.38197, -21.9021, -1,
- -9.38197, -21.9021, 1,
- -10, -20, -1,
- -10, -20, 1,
- -7, -20, -1.5,
- -7, -20, 1.5,
- -9.07295, -17.1468, -1.5,
- -9.07295, -17.1468, 1.5,
- -12.4271, -18.2366, -1.5,
- -12.4271, -18.2366, 1.5,
- -12.4271, -21.7634, -1.5,
- -12.4271, -21.7634, 1.5,
- -9.07295, -22.8532, -1.5,
- -9.07295, -22.8532, 1.5,
- -10, -20, -1.5,
- -10, -20, 1.5,
- -6, -20, -2,
- -6, -20, 2,
- -8.76393, -16.1958, -2,
- -8.76393, -16.1958, 2,
- -13.2361, -17.6489, -2,
- -13.2361, -17.6489, 2,
- -13.2361, -22.3511, -2,
- -13.2361, -22.3511, 2,
- -8.76393, -23.8042, -2,
- -8.76393, -23.8042, 2,
- -10, -20, -2,
- -10, -20, 2,
- -9, -10, -0.5,
- -9, -10, 0.5,
- -9.69098, -9.04894, -0.5,
- -9.69098, -9.04894, 0.5,
- -10.809, -9.41221, -0.5,
- -10.809, -9.41221, 0.5,
- -10.809, -10.5878, -0.5,
- -10.809, -10.5878, 0.5,
- -9.69098, -10.9511, -0.5,
- -9.69098, -10.9511, 0.5,
- -10, -10, -0.5,
- -10, -10, 0.5,
- -8, -10, -1,
- -8, -10, 1,
- -9.38197, -8.09789, -1,
- -9.38197, -8.09789, 1,
- -11.618, -8.82443, -1,
- -11.618, -8.82443, 1,
- -11.618, -11.1756, -1,
- -11.618, -11.1756, 1,
- -9.38197, -11.9021, -1,
- -9.38197, -11.9021, 1,
- -10, -10, -1,
- -10, -10, 1,
- -7, -10, -1.5,
- -7, -10, 1.5,
- -9.07295, -7.14683, -1.5,
- -9.07295, -7.14683, 1.5,
- -12.4271, -8.23664, -1.5,
- -12.4271, -8.23664, 1.5,
- -12.4271, -11.7634, -1.5,
- -12.4271, -11.7634, 1.5,
- -9.07295, -12.8532, -1.5,
- -9.07295, -12.8532, 1.5,
- -10, -10, -1.5,
- -10, -10, 1.5,
- -6, -10, -2,
- -6, -10, 2,
- -8.76393, -6.19577, -2,
- -8.76393, -6.19577, 2,
- -13.2361, -7.64886, -2,
- -13.2361, -7.64886, 2,
- -13.2361, -12.3511, -2,
- -13.2361, -12.3511, 2,
- -8.76393, -13.8042, -2,
- -8.76393, -13.8042, 2,
- -10, -10, -2,
- -10, -10, 2,
- -9, 0, -0.5,
- -9, 0, 0.5,
- -9.69098, 0.951057, -0.5,
- -9.69098, 0.951057, 0.5,
- -10.809, 0.587785, -0.5,
- -10.809, 0.587785, 0.5,
- -10.809, -0.587785, -0.5,
- -10.809, -0.587785, 0.5,
- -9.69098, -0.951057, -0.5,
- -9.69098, -0.951057, 0.5,
- -10, 0, -0.5,
- -10, 0, 0.5,
- -8, 0, -1,
- -8, 0, 1,
- -9.38197, 1.90211, -1,
- -9.38197, 1.90211, 1,
- -11.618, 1.17557, -1,
- -11.618, 1.17557, 1,
- -11.618, -1.17557, -1,
- -11.618, -1.17557, 1,
- -9.38197, -1.90211, -1,
- -9.38197, -1.90211, 1,
- -10, 0, -1,
- -10, 0, 1,
- -7, 0, -1.5,
- -7, 0, 1.5,
- -9.07295, 2.85317, -1.5,
- -9.07295, 2.85317, 1.5,
- -12.4271, 1.76336, -1.5,
- -12.4271, 1.76336, 1.5,
- -12.4271, -1.76336, -1.5,
- -12.4271, -1.76336, 1.5,
- -9.07295, -2.85317, -1.5,
- -9.07295, -2.85317, 1.5,
- -10, 0, -1.5,
- -10, 0, 1.5,
- -6, 0, -2,
- -6, 0, 2,
- -8.76393, 3.80423, -2,
- -8.76393, 3.80423, 2,
- -13.2361, 2.35114, -2,
- -13.2361, 2.35114, 2,
- -13.2361, -2.35114, -2,
- -13.2361, -2.35114, 2,
- -8.76393, -3.80423, -2,
- -8.76393, -3.80423, 2,
- -10, 0, -2,
- -10, 0, 2,
- -9, 10, -0.5,
- -9, 10, 0.5,
- -9.69098, 10.9511, -0.5,
- -9.69098, 10.9511, 0.5,
- -10.809, 10.5878, -0.5,
- -10.809, 10.5878, 0.5,
- -10.809, 9.41221, -0.5,
- -10.809, 9.41221, 0.5,
- -9.69098, 9.04894, -0.5,
- -9.69098, 9.04894, 0.5,
- -10, 10, -0.5,
- -10, 10, 0.5,
- -8, 10, -1,
- -8, 10, 1,
- -9.38197, 11.9021, -1,
- -9.38197, 11.9021, 1,
- -11.618, 11.1756, -1,
- -11.618, 11.1756, 1,
- -11.618, 8.82443, -1,
- -11.618, 8.82443, 1,
- -9.38197, 8.09789, -1,
- -9.38197, 8.09789, 1,
- -10, 10, -1,
- -10, 10, 1,
- -7, 10, -1.5,
- -7, 10, 1.5,
- -9.07295, 12.8532, -1.5,
- -9.07295, 12.8532, 1.5,
- -12.4271, 11.7634, -1.5,
- -12.4271, 11.7634, 1.5,
- -12.4271, 8.23664, -1.5,
- -12.4271, 8.23664, 1.5,
- -9.07295, 7.14683, -1.5,
- -9.07295, 7.14683, 1.5,
- -10, 10, -1.5,
- -10, 10, 1.5,
- -6, 10, -2,
- -6, 10, 2,
- -8.76393, 13.8042, -2,
- -8.76393, 13.8042, 2,
- -13.2361, 12.3511, -2,
- -13.2361, 12.3511, 2,
- -13.2361, 7.64886, -2,
- -13.2361, 7.64886, 2,
- -8.76393, 6.19577, -2,
- -8.76393, 6.19577, 2,
- -10, 10, -2,
- -10, 10, 2,
- 1, -20, -0.5,
- 1, -20, 0.5,
- 0.309017, -19.0489, -0.5,
- 0.309017, -19.0489, 0.5,
- -0.809017, -19.4122, -0.5,
- -0.809017, -19.4122, 0.5,
- -0.809017, -20.5878, -0.5,
- -0.809017, -20.5878, 0.5,
- 0.309017, -20.9511, -0.5,
- 0.309017, -20.9511, 0.5,
- 0, -20, -0.5,
- 0, -20, 0.5,
- 2, -20, -1,
- 2, -20, 1,
- 0.618034, -18.0979, -1,
- 0.618034, -18.0979, 1,
- -1.61803, -18.8244, -1,
- -1.61803, -18.8244, 1,
- -1.61803, -21.1756, -1,
- -1.61803, -21.1756, 1,
- 0.618034, -21.9021, -1,
- 0.618034, -21.9021, 1,
- 0, -20, -1,
- 0, -20, 1,
- 3, -20, -1.5,
- 3, -20, 1.5,
- 0.927051, -17.1468, -1.5,
- 0.927051, -17.1468, 1.5,
- -2.42705, -18.2366, -1.5,
- -2.42705, -18.2366, 1.5,
- -2.42705, -21.7634, -1.5,
- -2.42705, -21.7634, 1.5,
- 0.927051, -22.8532, -1.5,
- 0.927051, -22.8532, 1.5,
- 0, -20, -1.5,
- 0, -20, 1.5,
- 4, -20, -2,
- 4, -20, 2,
- 1.23607, -16.1958, -2,
- 1.23607, -16.1958, 2,
- -3.23607, -17.6489, -2,
- -3.23607, -17.6489, 2,
- -3.23607, -22.3511, -2,
- -3.23607, -22.3511, 2,
- 1.23607, -23.8042, -2,
- 1.23607, -23.8042, 2,
- 0, -20, -2,
- 0, -20, 2,
- 1, -10, -0.5,
- 1, -10, 0.5,
- 0.309017, -9.04894, -0.5,
- 0.309017, -9.04894, 0.5,
- -0.809017, -9.41221, -0.5,
- -0.809017, -9.41221, 0.5,
- -0.809017, -10.5878, -0.5,
- -0.809017, -10.5878, 0.5,
- 0.309017, -10.9511, -0.5,
- 0.309017, -10.9511, 0.5,
- 0, -10, -0.5,
- 0, -10, 0.5,
- 2, -10, -1,
- 2, -10, 1,
- 0.618034, -8.09789, -1,
- 0.618034, -8.09789, 1,
- -1.61803, -8.82443, -1,
- -1.61803, -8.82443, 1,
- -1.61803, -11.1756, -1,
- -1.61803, -11.1756, 1,
- 0.618034, -11.9021, -1,
- 0.618034, -11.9021, 1,
- 0, -10, -1,
- 0, -10, 1,
- 3, -10, -1.5,
- 3, -10, 1.5,
- 0.927051, -7.14683, -1.5,
- 0.927051, -7.14683, 1.5,
- -2.42705, -8.23664, -1.5,
- -2.42705, -8.23664, 1.5,
- -2.42705, -11.7634, -1.5,
- -2.42705, -11.7634, 1.5,
- 0.927051, -12.8532, -1.5,
- 0.927051, -12.8532, 1.5,
- 0, -10, -1.5,
- 0, -10, 1.5,
- 4, -10, -2,
- 4, -10, 2,
- 1.23607, -6.19577, -2,
- 1.23607, -6.19577, 2,
- -3.23607, -7.64886, -2,
- -3.23607, -7.64886, 2,
- -3.23607, -12.3511, -2,
- -3.23607, -12.3511, 2,
- 1.23607, -13.8042, -2,
- 1.23607, -13.8042, 2,
- 0, -10, -2,
- 0, -10, 2,
- 1, 0, -0.5,
- 1, 0, 0.5,
- 0.309017, 0.951057, -0.5,
- 0.309017, 0.951057, 0.5,
- -0.809017, 0.587785, -0.5,
- -0.809017, 0.587785, 0.5,
- -0.809017, -0.587785, -0.5,
- -0.809017, -0.587785, 0.5,
- 0.309017, -0.951057, -0.5,
- 0.309017, -0.951057, 0.5,
- 0, 0, -0.5,
- 0, 0, 0.5,
- 2, 0, -1,
- 2, 0, 1,
- 0.618034, 1.90211, -1,
- 0.618034, 1.90211, 1,
- -1.61803, 1.17557, -1,
- -1.61803, 1.17557, 1,
- -1.61803, -1.17557, -1,
- -1.61803, -1.17557, 1,
- 0.618034, -1.90211, -1,
- 0.618034, -1.90211, 1,
- 0, 0, -1,
- 0, 0, 1,
- 3, 0, -1.5,
- 3, 0, 1.5,
- 0.927051, 2.85317, -1.5,
- 0.927051, 2.85317, 1.5,
- -2.42705, 1.76336, -1.5,
- -2.42705, 1.76336, 1.5,
- -2.42705, -1.76336, -1.5,
- -2.42705, -1.76336, 1.5,
- 0.927051, -2.85317, -1.5,
- 0.927051, -2.85317, 1.5,
- 0, 0, -1.5,
- 0, 0, 1.5,
- 4, 0, -2,
- 4, 0, 2,
- 1.23607, 3.80423, -2,
- 1.23607, 3.80423, 2,
- -3.23607, 2.35114, -2,
- -3.23607, 2.35114, 2,
- -3.23607, -2.35114, -2,
- -3.23607, -2.35114, 2,
- 1.23607, -3.80423, -2,
- 1.23607, -3.80423, 2,
- 0, 0, -2,
- 0, 0, 2,
- 1, 10, -0.5,
- 1, 10, 0.5,
- 0.309017, 10.9511, -0.5,
- 0.309017, 10.9511, 0.5,
- -0.809017, 10.5878, -0.5,
- -0.809017, 10.5878, 0.5,
- -0.809017, 9.41221, -0.5,
- -0.809017, 9.41221, 0.5,
- 0.309017, 9.04894, -0.5,
- 0.309017, 9.04894, 0.5,
- 0, 10, -0.5,
- 0, 10, 0.5,
- 2, 10, -1,
- 2, 10, 1,
- 0.618034, 11.9021, -1,
- 0.618034, 11.9021, 1,
- -1.61803, 11.1756, -1,
- -1.61803, 11.1756, 1,
- -1.61803, 8.82443, -1,
- -1.61803, 8.82443, 1,
- 0.618034, 8.09789, -1,
- 0.618034, 8.09789, 1,
- 0, 10, -1,
- 0, 10, 1,
- 3, 10, -1.5,
- 3, 10, 1.5,
- 0.927051, 12.8532, -1.5,
- 0.927051, 12.8532, 1.5,
- -2.42705, 11.7634, -1.5,
- -2.42705, 11.7634, 1.5,
- -2.42705, 8.23664, -1.5,
- -2.42705, 8.23664, 1.5,
- 0.927051, 7.14683, -1.5,
- 0.927051, 7.14683, 1.5,
- 0, 10, -1.5,
- 0, 10, 1.5,
- 4, 10, -2,
- 4, 10, 2,
- 1.23607, 13.8042, -2,
- 1.23607, 13.8042, 2,
- -3.23607, 12.3511, -2,
- -3.23607, 12.3511, 2,
- -3.23607, 7.64886, -2,
- -3.23607, 7.64886, 2,
- 1.23607, 6.19577, -2,
- 1.23607, 6.19577, 2,
- 0, 10, -2,
- 0, 10, 2,
- 11, -20, -0.5,
- 11, -20, 0.5,
- 10.309, -19.0489, -0.5,
- 10.309, -19.0489, 0.5,
- 9.19098, -19.4122, -0.5,
- 9.19098, -19.4122, 0.5,
- 9.19098, -20.5878, -0.5,
- 9.19098, -20.5878, 0.5,
- 10.309, -20.9511, -0.5,
- 10.309, -20.9511, 0.5,
- 10, -20, -0.5,
- 10, -20, 0.5,
- 12, -20, -1,
- 12, -20, 1,
- 10.618, -18.0979, -1,
- 10.618, -18.0979, 1,
- 8.38197, -18.8244, -1,
- 8.38197, -18.8244, 1,
- 8.38197, -21.1756, -1,
- 8.38197, -21.1756, 1,
- 10.618, -21.9021, -1,
- 10.618, -21.9021, 1,
- 10, -20, -1,
- 10, -20, 1,
- 13, -20, -1.5,
- 13, -20, 1.5,
- 10.9271, -17.1468, -1.5,
- 10.9271, -17.1468, 1.5,
- 7.57295, -18.2366, -1.5,
- 7.57295, -18.2366, 1.5,
- 7.57295, -21.7634, -1.5,
- 7.57295, -21.7634, 1.5,
- 10.9271, -22.8532, -1.5,
- 10.9271, -22.8532, 1.5,
- 10, -20, -1.5,
- 10, -20, 1.5,
- 14, -20, -2,
- 14, -20, 2,
- 11.2361, -16.1958, -2,
- 11.2361, -16.1958, 2,
- 6.76393, -17.6489, -2,
- 6.76393, -17.6489, 2,
- 6.76393, -22.3511, -2,
- 6.76393, -22.3511, 2,
- 11.2361, -23.8042, -2,
- 11.2361, -23.8042, 2,
- 10, -20, -2,
- 10, -20, 2,
- 11, -10, -0.5,
- 11, -10, 0.5,
- 10.309, -9.04894, -0.5,
- 10.309, -9.04894, 0.5,
- 9.19098, -9.41221, -0.5,
- 9.19098, -9.41221, 0.5,
- 9.19098, -10.5878, -0.5,
- 9.19098, -10.5878, 0.5,
- 10.309, -10.9511, -0.5,
- 10.309, -10.9511, 0.5,
- 10, -10, -0.5,
- 10, -10, 0.5,
- 12, -10, -1,
- 12, -10, 1,
- 10.618, -8.09789, -1,
- 10.618, -8.09789, 1,
- 8.38197, -8.82443, -1,
- 8.38197, -8.82443, 1,
- 8.38197, -11.1756, -1,
- 8.38197, -11.1756, 1,
- 10.618, -11.9021, -1,
- 10.618, -11.9021, 1,
- 10, -10, -1,
- 10, -10, 1,
- 13, -10, -1.5,
- 13, -10, 1.5,
- 10.9271, -7.14683, -1.5,
- 10.9271, -7.14683, 1.5,
- 7.57295, -8.23664, -1.5,
- 7.57295, -8.23664, 1.5,
- 7.57295, -11.7634, -1.5,
- 7.57295, -11.7634, 1.5,
- 10.9271, -12.8532, -1.5,
- 10.9271, -12.8532, 1.5,
- 10, -10, -1.5,
- 10, -10, 1.5,
- 14, -10, -2,
- 14, -10, 2,
- 11.2361, -6.19577, -2,
- 11.2361, -6.19577, 2,
- 6.76393, -7.64886, -2,
- 6.76393, -7.64886, 2,
- 6.76393, -12.3511, -2,
- 6.76393, -12.3511, 2,
- 11.2361, -13.8042, -2,
- 11.2361, -13.8042, 2,
- 10, -10, -2,
- 10, -10, 2,
- 11, 0, -0.5,
- 11, 0, 0.5,
- 10.309, 0.951057, -0.5,
- 10.309, 0.951057, 0.5,
- 9.19098, 0.587785, -0.5,
- 9.19098, 0.587785, 0.5,
- 9.19098, -0.587785, -0.5,
- 9.19098, -0.587785, 0.5,
- 10.309, -0.951057, -0.5,
- 10.309, -0.951057, 0.5,
- 10, 0, -0.5,
- 10, 0, 0.5,
- 12, 0, -1,
- 12, 0, 1,
- 10.618, 1.90211, -1,
- 10.618, 1.90211, 1,
- 8.38197, 1.17557, -1,
- 8.38197, 1.17557, 1,
- 8.38197, -1.17557, -1,
- 8.38197, -1.17557, 1,
- 10.618, -1.90211, -1,
- 10.618, -1.90211, 1,
- 10, 0, -1,
- 10, 0, 1,
- 13, 0, -1.5,
- 13, 0, 1.5,
- 10.9271, 2.85317, -1.5,
- 10.9271, 2.85317, 1.5,
- 7.57295, 1.76336, -1.5,
- 7.57295, 1.76336, 1.5,
- 7.57295, -1.76336, -1.5,
- 7.57295, -1.76336, 1.5,
- 10.9271, -2.85317, -1.5,
- 10.9271, -2.85317, 1.5,
- 10, 0, -1.5,
- 10, 0, 1.5,
- 14, 0, -2,
- 14, 0, 2,
- 11.2361, 3.80423, -2,
- 11.2361, 3.80423, 2,
- 6.76393, 2.35114, -2,
- 6.76393, 2.35114, 2,
- 6.76393, -2.35114, -2,
- 6.76393, -2.35114, 2,
- 11.2361, -3.80423, -2,
- 11.2361, -3.80423, 2,
- 10, 0, -2,
- 10, 0, 2,
- 11, 10, -0.5,
- 11, 10, 0.5,
- 10.309, 10.9511, -0.5,
- 10.309, 10.9511, 0.5,
- 9.19098, 10.5878, -0.5,
- 9.19098, 10.5878, 0.5,
- 9.19098, 9.41221, -0.5,
- 9.19098, 9.41221, 0.5,
- 10.309, 9.04894, -0.5,
- 10.309, 9.04894, 0.5,
- 10, 10, -0.5,
- 10, 10, 0.5,
- 12, 10, -1,
- 12, 10, 1,
- 10.618, 11.9021, -1,
- 10.618, 11.9021, 1,
- 8.38197, 11.1756, -1,
- 8.38197, 11.1756, 1,
- 8.38197, 8.82443, -1,
- 8.38197, 8.82443, 1,
- 10.618, 8.09789, -1,
- 10.618, 8.09789, 1,
- 10, 10, -1,
- 10, 10, 1,
- 13, 10, -1.5,
- 13, 10, 1.5,
- 10.9271, 12.8532, -1.5,
- 10.9271, 12.8532, 1.5,
- 7.57295, 11.7634, -1.5,
- 7.57295, 11.7634, 1.5,
- 7.57295, 8.23664, -1.5,
- 7.57295, 8.23664, 1.5,
- 10.9271, 7.14683, -1.5,
- 10.9271, 7.14683, 1.5,
- 10, 10, -1.5,
- 10, 10, 1.5,
- 14, 10, -2,
- 14, 10, 2,
- 11.2361, 13.8042, -2,
- 11.2361, 13.8042, 2,
- 6.76393, 12.3511, -2,
- 6.76393, 12.3511, 2,
- 6.76393, 7.64886, -2,
- 6.76393, 7.64886, 2,
- 11.2361, 6.19577, -2,
- 11.2361, 6.19577, 2,
- 10, 10, -2,
- 10, 10, 2
-};
-static const unsigned some_enclosures_triangles_count = 1280;
-static const unsigned some_enclosures_triangles[3840] =
-{
- 0, 1, 2,
- 2, 1, 3,
- 2, 3, 4,
- 4, 3, 5,
- 4, 5, 6,
- 6, 5, 7,
- 6, 7, 8,
- 8, 7, 9,
- 8, 9, 0,
- 0, 9, 1,
- 10, 0, 2,
- 10, 2, 4,
- 10, 4, 6,
- 10, 6, 8,
- 10, 8, 0,
- 11, 3, 1,
- 11, 5, 3,
- 11, 7, 5,
- 11, 9, 7,
- 11, 1, 9,
- 12, 13, 14,
- 14, 13, 15,
- 14, 15, 16,
- 16, 15, 17,
- 16, 17, 18,
- 18, 17, 19,
- 18, 19, 20,
- 20, 19, 21,
- 20, 21, 12,
- 12, 21, 13,
- 22, 12, 14,
- 22, 14, 16,
- 22, 16, 18,
- 22, 18, 20,
- 22, 20, 12,
- 23, 15, 13,
- 23, 17, 15,
- 23, 19, 17,
- 23, 21, 19,
- 23, 13, 21,
- 24, 25, 26,
- 26, 25, 27,
- 26, 27, 28,
- 28, 27, 29,
- 28, 29, 30,
- 30, 29, 31,
- 30, 31, 32,
- 32, 31, 33,
- 32, 33, 24,
- 24, 33, 25,
- 34, 24, 26,
- 34, 26, 28,
- 34, 28, 30,
- 34, 30, 32,
- 34, 32, 24,
- 35, 27, 25,
- 35, 29, 27,
- 35, 31, 29,
- 35, 33, 31,
- 35, 25, 33,
- 36, 37, 38,
- 38, 37, 39,
- 38, 39, 40,
- 40, 39, 41,
- 40, 41, 42,
- 42, 41, 43,
- 42, 43, 44,
- 44, 43, 45,
- 44, 45, 36,
- 36, 45, 37,
- 46, 36, 38,
- 46, 38, 40,
- 46, 40, 42,
- 46, 42, 44,
- 46, 44, 36,
- 47, 39, 37,
- 47, 41, 39,
- 47, 43, 41,
- 47, 45, 43,
- 47, 37, 45,
- 48, 49, 50,
- 50, 49, 51,
- 50, 51, 52,
- 52, 51, 53,
- 52, 53, 54,
- 54, 53, 55,
- 54, 55, 56,
- 56, 55, 57,
- 56, 57, 48,
- 48, 57, 49,
- 58, 48, 50,
- 58, 50, 52,
- 58, 52, 54,
- 58, 54, 56,
- 58, 56, 48,
- 59, 51, 49,
- 59, 53, 51,
- 59, 55, 53,
- 59, 57, 55,
- 59, 49, 57,
- 60, 61, 62,
- 62, 61, 63,
- 62, 63, 64,
- 64, 63, 65,
- 64, 65, 66,
- 66, 65, 67,
- 66, 67, 68,
- 68, 67, 69,
- 68, 69, 60,
- 60, 69, 61,
- 70, 60, 62,
- 70, 62, 64,
- 70, 64, 66,
- 70, 66, 68,
- 70, 68, 60,
- 71, 63, 61,
- 71, 65, 63,
- 71, 67, 65,
- 71, 69, 67,
- 71, 61, 69,
- 72, 73, 74,
- 74, 73, 75,
- 74, 75, 76,
- 76, 75, 77,
- 76, 77, 78,
- 78, 77, 79,
- 78, 79, 80,
- 80, 79, 81,
- 80, 81, 72,
- 72, 81, 73,
- 82, 72, 74,
- 82, 74, 76,
- 82, 76, 78,
- 82, 78, 80,
- 82, 80, 72,
- 83, 75, 73,
- 83, 77, 75,
- 83, 79, 77,
- 83, 81, 79,
- 83, 73, 81,
- 84, 85, 86,
- 86, 85, 87,
- 86, 87, 88,
- 88, 87, 89,
- 88, 89, 90,
- 90, 89, 91,
- 90, 91, 92,
- 92, 91, 93,
- 92, 93, 84,
- 84, 93, 85,
- 94, 84, 86,
- 94, 86, 88,
- 94, 88, 90,
- 94, 90, 92,
- 94, 92, 84,
- 95, 87, 85,
- 95, 89, 87,
- 95, 91, 89,
- 95, 93, 91,
- 95, 85, 93,
- 96, 97, 98,
- 98, 97, 99,
- 98, 99, 100,
- 100, 99, 101,
- 100, 101, 102,
- 102, 101, 103,
- 102, 103, 104,
- 104, 103, 105,
- 104, 105, 96,
- 96, 105, 97,
- 106, 96, 98,
- 106, 98, 100,
- 106, 100, 102,
- 106, 102, 104,
- 106, 104, 96,
- 107, 99, 97,
- 107, 101, 99,
- 107, 103, 101,
- 107, 105, 103,
- 107, 97, 105,
- 108, 109, 110,
- 110, 109, 111,
- 110, 111, 112,
- 112, 111, 113,
- 112, 113, 114,
- 114, 113, 115,
- 114, 115, 116,
- 116, 115, 117,
- 116, 117, 108,
- 108, 117, 109,
- 118, 108, 110,
- 118, 110, 112,
- 118, 112, 114,
- 118, 114, 116,
- 118, 116, 108,
- 119, 111, 109,
- 119, 113, 111,
- 119, 115, 113,
- 119, 117, 115,
- 119, 109, 117,
- 120, 121, 122,
- 122, 121, 123,
- 122, 123, 124,
- 124, 123, 125,
- 124, 125, 126,
- 126, 125, 127,
- 126, 127, 128,
- 128, 127, 129,
- 128, 129, 120,
- 120, 129, 121,
- 130, 120, 122,
- 130, 122, 124,
- 130, 124, 126,
- 130, 126, 128,
- 130, 128, 120,
- 131, 123, 121,
- 131, 125, 123,
- 131, 127, 125,
- 131, 129, 127,
- 131, 121, 129,
- 132, 133, 134,
- 134, 133, 135,
- 134, 135, 136,
- 136, 135, 137,
- 136, 137, 138,
- 138, 137, 139,
- 138, 139, 140,
- 140, 139, 141,
- 140, 141, 132,
- 132, 141, 133,
- 142, 132, 134,
- 142, 134, 136,
- 142, 136, 138,
- 142, 138, 140,
- 142, 140, 132,
- 143, 135, 133,
- 143, 137, 135,
- 143, 139, 137,
- 143, 141, 139,
- 143, 133, 141,
- 144, 145, 146,
- 146, 145, 147,
- 146, 147, 148,
- 148, 147, 149,
- 148, 149, 150,
- 150, 149, 151,
- 150, 151, 152,
- 152, 151, 153,
- 152, 153, 144,
- 144, 153, 145,
- 154, 144, 146,
- 154, 146, 148,
- 154, 148, 150,
- 154, 150, 152,
- 154, 152, 144,
- 155, 147, 145,
- 155, 149, 147,
- 155, 151, 149,
- 155, 153, 151,
- 155, 145, 153,
- 156, 157, 158,
- 158, 157, 159,
- 158, 159, 160,
- 160, 159, 161,
- 160, 161, 162,
- 162, 161, 163,
- 162, 163, 164,
- 164, 163, 165,
- 164, 165, 156,
- 156, 165, 157,
- 166, 156, 158,
- 166, 158, 160,
- 166, 160, 162,
- 166, 162, 164,
- 166, 164, 156,
- 167, 159, 157,
- 167, 161, 159,
- 167, 163, 161,
- 167, 165, 163,
- 167, 157, 165,
- 168, 169, 170,
- 170, 169, 171,
- 170, 171, 172,
- 172, 171, 173,
- 172, 173, 174,
- 174, 173, 175,
- 174, 175, 176,
- 176, 175, 177,
- 176, 177, 168,
- 168, 177, 169,
- 178, 168, 170,
- 178, 170, 172,
- 178, 172, 174,
- 178, 174, 176,
- 178, 176, 168,
- 179, 171, 169,
- 179, 173, 171,
- 179, 175, 173,
- 179, 177, 175,
- 179, 169, 177,
- 180, 181, 182,
- 182, 181, 183,
- 182, 183, 184,
- 184, 183, 185,
- 184, 185, 186,
- 186, 185, 187,
- 186, 187, 188,
- 188, 187, 189,
- 188, 189, 180,
- 180, 189, 181,
- 190, 180, 182,
- 190, 182, 184,
- 190, 184, 186,
- 190, 186, 188,
- 190, 188, 180,
- 191, 183, 181,
- 191, 185, 183,
- 191, 187, 185,
- 191, 189, 187,
- 191, 181, 189,
- 192, 193, 194,
- 194, 193, 195,
- 194, 195, 196,
- 196, 195, 197,
- 196, 197, 198,
- 198, 197, 199,
- 198, 199, 200,
- 200, 199, 201,
- 200, 201, 192,
- 192, 201, 193,
- 202, 192, 194,
- 202, 194, 196,
- 202, 196, 198,
- 202, 198, 200,
- 202, 200, 192,
- 203, 195, 193,
- 203, 197, 195,
- 203, 199, 197,
- 203, 201, 199,
- 203, 193, 201,
- 204, 205, 206,
- 206, 205, 207,
- 206, 207, 208,
- 208, 207, 209,
- 208, 209, 210,
- 210, 209, 211,
- 210, 211, 212,
- 212, 211, 213,
- 212, 213, 204,
- 204, 213, 205,
- 214, 204, 206,
- 214, 206, 208,
- 214, 208, 210,
- 214, 210, 212,
- 214, 212, 204,
- 215, 207, 205,
- 215, 209, 207,
- 215, 211, 209,
- 215, 213, 211,
- 215, 205, 213,
- 216, 217, 218,
- 218, 217, 219,
- 218, 219, 220,
- 220, 219, 221,
- 220, 221, 222,
- 222, 221, 223,
- 222, 223, 224,
- 224, 223, 225,
- 224, 225, 216,
- 216, 225, 217,
- 226, 216, 218,
- 226, 218, 220,
- 226, 220, 222,
- 226, 222, 224,
- 226, 224, 216,
- 227, 219, 217,
- 227, 221, 219,
- 227, 223, 221,
- 227, 225, 223,
- 227, 217, 225,
- 228, 229, 230,
- 230, 229, 231,
- 230, 231, 232,
- 232, 231, 233,
- 232, 233, 234,
- 234, 233, 235,
- 234, 235, 236,
- 236, 235, 237,
- 236, 237, 228,
- 228, 237, 229,
- 238, 228, 230,
- 238, 230, 232,
- 238, 232, 234,
- 238, 234, 236,
- 238, 236, 228,
- 239, 231, 229,
- 239, 233, 231,
- 239, 235, 233,
- 239, 237, 235,
- 239, 229, 237,
- 240, 241, 242,
- 242, 241, 243,
- 242, 243, 244,
- 244, 243, 245,
- 244, 245, 246,
- 246, 245, 247,
- 246, 247, 248,
- 248, 247, 249,
- 248, 249, 240,
- 240, 249, 241,
- 250, 240, 242,
- 250, 242, 244,
- 250, 244, 246,
- 250, 246, 248,
- 250, 248, 240,
- 251, 243, 241,
- 251, 245, 243,
- 251, 247, 245,
- 251, 249, 247,
- 251, 241, 249,
- 252, 253, 254,
- 254, 253, 255,
- 254, 255, 256,
- 256, 255, 257,
- 256, 257, 258,
- 258, 257, 259,
- 258, 259, 260,
- 260, 259, 261,
- 260, 261, 252,
- 252, 261, 253,
- 262, 252, 254,
- 262, 254, 256,
- 262, 256, 258,
- 262, 258, 260,
- 262, 260, 252,
- 263, 255, 253,
- 263, 257, 255,
- 263, 259, 257,
- 263, 261, 259,
- 263, 253, 261,
- 264, 265, 266,
- 266, 265, 267,
- 266, 267, 268,
- 268, 267, 269,
- 268, 269, 270,
- 270, 269, 271,
- 270, 271, 272,
- 272, 271, 273,
- 272, 273, 264,
- 264, 273, 265,
- 274, 264, 266,
- 274, 266, 268,
- 274, 268, 270,
- 274, 270, 272,
- 274, 272, 264,
- 275, 267, 265,
- 275, 269, 267,
- 275, 271, 269,
- 275, 273, 271,
- 275, 265, 273,
- 276, 277, 278,
- 278, 277, 279,
- 278, 279, 280,
- 280, 279, 281,
- 280, 281, 282,
- 282, 281, 283,
- 282, 283, 284,
- 284, 283, 285,
- 284, 285, 276,
- 276, 285, 277,
- 286, 276, 278,
- 286, 278, 280,
- 286, 280, 282,
- 286, 282, 284,
- 286, 284, 276,
- 287, 279, 277,
- 287, 281, 279,
- 287, 283, 281,
- 287, 285, 283,
- 287, 277, 285,
- 288, 289, 290,
- 290, 289, 291,
- 290, 291, 292,
- 292, 291, 293,
- 292, 293, 294,
- 294, 293, 295,
- 294, 295, 296,
- 296, 295, 297,
- 296, 297, 288,
- 288, 297, 289,
- 298, 288, 290,
- 298, 290, 292,
- 298, 292, 294,
- 298, 294, 296,
- 298, 296, 288,
- 299, 291, 289,
- 299, 293, 291,
- 299, 295, 293,
- 299, 297, 295,
- 299, 289, 297,
- 300, 301, 302,
- 302, 301, 303,
- 302, 303, 304,
- 304, 303, 305,
- 304, 305, 306,
- 306, 305, 307,
- 306, 307, 308,
- 308, 307, 309,
- 308, 309, 300,
- 300, 309, 301,
- 310, 300, 302,
- 310, 302, 304,
- 310, 304, 306,
- 310, 306, 308,
- 310, 308, 300,
- 311, 303, 301,
- 311, 305, 303,
- 311, 307, 305,
- 311, 309, 307,
- 311, 301, 309,
- 312, 313, 314,
- 314, 313, 315,
- 314, 315, 316,
- 316, 315, 317,
- 316, 317, 318,
- 318, 317, 319,
- 318, 319, 320,
- 320, 319, 321,
- 320, 321, 312,
- 312, 321, 313,
- 322, 312, 314,
- 322, 314, 316,
- 322, 316, 318,
- 322, 318, 320,
- 322, 320, 312,
- 323, 315, 313,
- 323, 317, 315,
- 323, 319, 317,
- 323, 321, 319,
- 323, 313, 321,
- 324, 325, 326,
- 326, 325, 327,
- 326, 327, 328,
- 328, 327, 329,
- 328, 329, 330,
- 330, 329, 331,
- 330, 331, 332,
- 332, 331, 333,
- 332, 333, 324,
- 324, 333, 325,
- 334, 324, 326,
- 334, 326, 328,
- 334, 328, 330,
- 334, 330, 332,
- 334, 332, 324,
- 335, 327, 325,
- 335, 329, 327,
- 335, 331, 329,
- 335, 333, 331,
- 335, 325, 333,
- 336, 337, 338,
- 338, 337, 339,
- 338, 339, 340,
- 340, 339, 341,
- 340, 341, 342,
- 342, 341, 343,
- 342, 343, 344,
- 344, 343, 345,
- 344, 345, 336,
- 336, 345, 337,
- 346, 336, 338,
- 346, 338, 340,
- 346, 340, 342,
- 346, 342, 344,
- 346, 344, 336,
- 347, 339, 337,
- 347, 341, 339,
- 347, 343, 341,
- 347, 345, 343,
- 347, 337, 345,
- 348, 349, 350,
- 350, 349, 351,
- 350, 351, 352,
- 352, 351, 353,
- 352, 353, 354,
- 354, 353, 355,
- 354, 355, 356,
- 356, 355, 357,
- 356, 357, 348,
- 348, 357, 349,
- 358, 348, 350,
- 358, 350, 352,
- 358, 352, 354,
- 358, 354, 356,
- 358, 356, 348,
- 359, 351, 349,
- 359, 353, 351,
- 359, 355, 353,
- 359, 357, 355,
- 359, 349, 357,
- 360, 361, 362,
- 362, 361, 363,
- 362, 363, 364,
- 364, 363, 365,
- 364, 365, 366,
- 366, 365, 367,
- 366, 367, 368,
- 368, 367, 369,
- 368, 369, 360,
- 360, 369, 361,
- 370, 360, 362,
- 370, 362, 364,
- 370, 364, 366,
- 370, 366, 368,
- 370, 368, 360,
- 371, 363, 361,
- 371, 365, 363,
- 371, 367, 365,
- 371, 369, 367,
- 371, 361, 369,
- 372, 373, 374,
- 374, 373, 375,
- 374, 375, 376,
- 376, 375, 377,
- 376, 377, 378,
- 378, 377, 379,
- 378, 379, 380,
- 380, 379, 381,
- 380, 381, 372,
- 372, 381, 373,
- 382, 372, 374,
- 382, 374, 376,
- 382, 376, 378,
- 382, 378, 380,
- 382, 380, 372,
- 383, 375, 373,
- 383, 377, 375,
- 383, 379, 377,
- 383, 381, 379,
- 383, 373, 381,
- 384, 385, 386,
- 386, 385, 387,
- 386, 387, 388,
- 388, 387, 389,
- 388, 389, 390,
- 390, 389, 391,
- 390, 391, 392,
- 392, 391, 393,
- 392, 393, 384,
- 384, 393, 385,
- 394, 384, 386,
- 394, 386, 388,
- 394, 388, 390,
- 394, 390, 392,
- 394, 392, 384,
- 395, 387, 385,
- 395, 389, 387,
- 395, 391, 389,
- 395, 393, 391,
- 395, 385, 393,
- 396, 397, 398,
- 398, 397, 399,
- 398, 399, 400,
- 400, 399, 401,
- 400, 401, 402,
- 402, 401, 403,
- 402, 403, 404,
- 404, 403, 405,
- 404, 405, 396,
- 396, 405, 397,
- 406, 396, 398,
- 406, 398, 400,
- 406, 400, 402,
- 406, 402, 404,
- 406, 404, 396,
- 407, 399, 397,
- 407, 401, 399,
- 407, 403, 401,
- 407, 405, 403,
- 407, 397, 405,
- 408, 409, 410,
- 410, 409, 411,
- 410, 411, 412,
- 412, 411, 413,
- 412, 413, 414,
- 414, 413, 415,
- 414, 415, 416,
- 416, 415, 417,
- 416, 417, 408,
- 408, 417, 409,
- 418, 408, 410,
- 418, 410, 412,
- 418, 412, 414,
- 418, 414, 416,
- 418, 416, 408,
- 419, 411, 409,
- 419, 413, 411,
- 419, 415, 413,
- 419, 417, 415,
- 419, 409, 417,
- 420, 421, 422,
- 422, 421, 423,
- 422, 423, 424,
- 424, 423, 425,
- 424, 425, 426,
- 426, 425, 427,
- 426, 427, 428,
- 428, 427, 429,
- 428, 429, 420,
- 420, 429, 421,
- 430, 420, 422,
- 430, 422, 424,
- 430, 424, 426,
- 430, 426, 428,
- 430, 428, 420,
- 431, 423, 421,
- 431, 425, 423,
- 431, 427, 425,
- 431, 429, 427,
- 431, 421, 429,
- 432, 433, 434,
- 434, 433, 435,
- 434, 435, 436,
- 436, 435, 437,
- 436, 437, 438,
- 438, 437, 439,
- 438, 439, 440,
- 440, 439, 441,
- 440, 441, 432,
- 432, 441, 433,
- 442, 432, 434,
- 442, 434, 436,
- 442, 436, 438,
- 442, 438, 440,
- 442, 440, 432,
- 443, 435, 433,
- 443, 437, 435,
- 443, 439, 437,
- 443, 441, 439,
- 443, 433, 441,
- 444, 445, 446,
- 446, 445, 447,
- 446, 447, 448,
- 448, 447, 449,
- 448, 449, 450,
- 450, 449, 451,
- 450, 451, 452,
- 452, 451, 453,
- 452, 453, 444,
- 444, 453, 445,
- 454, 444, 446,
- 454, 446, 448,
- 454, 448, 450,
- 454, 450, 452,
- 454, 452, 444,
- 455, 447, 445,
- 455, 449, 447,
- 455, 451, 449,
- 455, 453, 451,
- 455, 445, 453,
- 456, 457, 458,
- 458, 457, 459,
- 458, 459, 460,
- 460, 459, 461,
- 460, 461, 462,
- 462, 461, 463,
- 462, 463, 464,
- 464, 463, 465,
- 464, 465, 456,
- 456, 465, 457,
- 466, 456, 458,
- 466, 458, 460,
- 466, 460, 462,
- 466, 462, 464,
- 466, 464, 456,
- 467, 459, 457,
- 467, 461, 459,
- 467, 463, 461,
- 467, 465, 463,
- 467, 457, 465,
- 468, 469, 470,
- 470, 469, 471,
- 470, 471, 472,
- 472, 471, 473,
- 472, 473, 474,
- 474, 473, 475,
- 474, 475, 476,
- 476, 475, 477,
- 476, 477, 468,
- 468, 477, 469,
- 478, 468, 470,
- 478, 470, 472,
- 478, 472, 474,
- 478, 474, 476,
- 478, 476, 468,
- 479, 471, 469,
- 479, 473, 471,
- 479, 475, 473,
- 479, 477, 475,
- 479, 469, 477,
- 480, 481, 482,
- 482, 481, 483,
- 482, 483, 484,
- 484, 483, 485,
- 484, 485, 486,
- 486, 485, 487,
- 486, 487, 488,
- 488, 487, 489,
- 488, 489, 480,
- 480, 489, 481,
- 490, 480, 482,
- 490, 482, 484,
- 490, 484, 486,
- 490, 486, 488,
- 490, 488, 480,
- 491, 483, 481,
- 491, 485, 483,
- 491, 487, 485,
- 491, 489, 487,
- 491, 481, 489,
- 492, 493, 494,
- 494, 493, 495,
- 494, 495, 496,
- 496, 495, 497,
- 496, 497, 498,
- 498, 497, 499,
- 498, 499, 500,
- 500, 499, 501,
- 500, 501, 492,
- 492, 501, 493,
- 502, 492, 494,
- 502, 494, 496,
- 502, 496, 498,
- 502, 498, 500,
- 502, 500, 492,
- 503, 495, 493,
- 503, 497, 495,
- 503, 499, 497,
- 503, 501, 499,
- 503, 493, 501,
- 504, 505, 506,
- 506, 505, 507,
- 506, 507, 508,
- 508, 507, 509,
- 508, 509, 510,
- 510, 509, 511,
- 510, 511, 512,
- 512, 511, 513,
- 512, 513, 504,
- 504, 513, 505,
- 514, 504, 506,
- 514, 506, 508,
- 514, 508, 510,
- 514, 510, 512,
- 514, 512, 504,
- 515, 507, 505,
- 515, 509, 507,
- 515, 511, 509,
- 515, 513, 511,
- 515, 505, 513,
- 516, 517, 518,
- 518, 517, 519,
- 518, 519, 520,
- 520, 519, 521,
- 520, 521, 522,
- 522, 521, 523,
- 522, 523, 524,
- 524, 523, 525,
- 524, 525, 516,
- 516, 525, 517,
- 526, 516, 518,
- 526, 518, 520,
- 526, 520, 522,
- 526, 522, 524,
- 526, 524, 516,
- 527, 519, 517,
- 527, 521, 519,
- 527, 523, 521,
- 527, 525, 523,
- 527, 517, 525,
- 528, 529, 530,
- 530, 529, 531,
- 530, 531, 532,
- 532, 531, 533,
- 532, 533, 534,
- 534, 533, 535,
- 534, 535, 536,
- 536, 535, 537,
- 536, 537, 528,
- 528, 537, 529,
- 538, 528, 530,
- 538, 530, 532,
- 538, 532, 534,
- 538, 534, 536,
- 538, 536, 528,
- 539, 531, 529,
- 539, 533, 531,
- 539, 535, 533,
- 539, 537, 535,
- 539, 529, 537,
- 540, 541, 542,
- 542, 541, 543,
- 542, 543, 544,
- 544, 543, 545,
- 544, 545, 546,
- 546, 545, 547,
- 546, 547, 548,
- 548, 547, 549,
- 548, 549, 540,
- 540, 549, 541,
- 550, 540, 542,
- 550, 542, 544,
- 550, 544, 546,
- 550, 546, 548,
- 550, 548, 540,
- 551, 543, 541,
- 551, 545, 543,
- 551, 547, 545,
- 551, 549, 547,
- 551, 541, 549,
- 552, 553, 554,
- 554, 553, 555,
- 554, 555, 556,
- 556, 555, 557,
- 556, 557, 558,
- 558, 557, 559,
- 558, 559, 560,
- 560, 559, 561,
- 560, 561, 552,
- 552, 561, 553,
- 562, 552, 554,
- 562, 554, 556,
- 562, 556, 558,
- 562, 558, 560,
- 562, 560, 552,
- 563, 555, 553,
- 563, 557, 555,
- 563, 559, 557,
- 563, 561, 559,
- 563, 553, 561,
- 564, 565, 566,
- 566, 565, 567,
- 566, 567, 568,
- 568, 567, 569,
- 568, 569, 570,
- 570, 569, 571,
- 570, 571, 572,
- 572, 571, 573,
- 572, 573, 564,
- 564, 573, 565,
- 574, 564, 566,
- 574, 566, 568,
- 574, 568, 570,
- 574, 570, 572,
- 574, 572, 564,
- 575, 567, 565,
- 575, 569, 567,
- 575, 571, 569,
- 575, 573, 571,
- 575, 565, 573,
- 576, 577, 578,
- 578, 577, 579,
- 578, 579, 580,
- 580, 579, 581,
- 580, 581, 582,
- 582, 581, 583,
- 582, 583, 584,
- 584, 583, 585,
- 584, 585, 576,
- 576, 585, 577,
- 586, 576, 578,
- 586, 578, 580,
- 586, 580, 582,
- 586, 582, 584,
- 586, 584, 576,
- 587, 579, 577,
- 587, 581, 579,
- 587, 583, 581,
- 587, 585, 583,
- 587, 577, 585,
- 588, 589, 590,
- 590, 589, 591,
- 590, 591, 592,
- 592, 591, 593,
- 592, 593, 594,
- 594, 593, 595,
- 594, 595, 596,
- 596, 595, 597,
- 596, 597, 588,
- 588, 597, 589,
- 598, 588, 590,
- 598, 590, 592,
- 598, 592, 594,
- 598, 594, 596,
- 598, 596, 588,
- 599, 591, 589,
- 599, 593, 591,
- 599, 595, 593,
- 599, 597, 595,
- 599, 589, 597,
- 600, 601, 602,
- 602, 601, 603,
- 602, 603, 604,
- 604, 603, 605,
- 604, 605, 606,
- 606, 605, 607,
- 606, 607, 608,
- 608, 607, 609,
- 608, 609, 600,
- 600, 609, 601,
- 610, 600, 602,
- 610, 602, 604,
- 610, 604, 606,
- 610, 606, 608,
- 610, 608, 600,
- 611, 603, 601,
- 611, 605, 603,
- 611, 607, 605,
- 611, 609, 607,
- 611, 601, 609,
- 612, 613, 614,
- 614, 613, 615,
- 614, 615, 616,
- 616, 615, 617,
- 616, 617, 618,
- 618, 617, 619,
- 618, 619, 620,
- 620, 619, 621,
- 620, 621, 612,
- 612, 621, 613,
- 622, 612, 614,
- 622, 614, 616,
- 622, 616, 618,
- 622, 618, 620,
- 622, 620, 612,
- 623, 615, 613,
- 623, 617, 615,
- 623, 619, 617,
- 623, 621, 619,
- 623, 613, 621,
- 624, 625, 626,
- 626, 625, 627,
- 626, 627, 628,
- 628, 627, 629,
- 628, 629, 630,
- 630, 629, 631,
- 630, 631, 632,
- 632, 631, 633,
- 632, 633, 624,
- 624, 633, 625,
- 634, 624, 626,
- 634, 626, 628,
- 634, 628, 630,
- 634, 630, 632,
- 634, 632, 624,
- 635, 627, 625,
- 635, 629, 627,
- 635, 631, 629,
- 635, 633, 631,
- 635, 625, 633,
- 636, 637, 638,
- 638, 637, 639,
- 638, 639, 640,
- 640, 639, 641,
- 640, 641, 642,
- 642, 641, 643,
- 642, 643, 644,
- 644, 643, 645,
- 644, 645, 636,
- 636, 645, 637,
- 646, 636, 638,
- 646, 638, 640,
- 646, 640, 642,
- 646, 642, 644,
- 646, 644, 636,
- 647, 639, 637,
- 647, 641, 639,
- 647, 643, 641,
- 647, 645, 643,
- 647, 637, 645,
- 648, 649, 650,
- 650, 649, 651,
- 650, 651, 652,
- 652, 651, 653,
- 652, 653, 654,
- 654, 653, 655,
- 654, 655, 656,
- 656, 655, 657,
- 656, 657, 648,
- 648, 657, 649,
- 658, 648, 650,
- 658, 650, 652,
- 658, 652, 654,
- 658, 654, 656,
- 658, 656, 648,
- 659, 651, 649,
- 659, 653, 651,
- 659, 655, 653,
- 659, 657, 655,
- 659, 649, 657,
- 660, 661, 662,
- 662, 661, 663,
- 662, 663, 664,
- 664, 663, 665,
- 664, 665, 666,
- 666, 665, 667,
- 666, 667, 668,
- 668, 667, 669,
- 668, 669, 660,
- 660, 669, 661,
- 670, 660, 662,
- 670, 662, 664,
- 670, 664, 666,
- 670, 666, 668,
- 670, 668, 660,
- 671, 663, 661,
- 671, 665, 663,
- 671, 667, 665,
- 671, 669, 667,
- 671, 661, 669,
- 672, 673, 674,
- 674, 673, 675,
- 674, 675, 676,
- 676, 675, 677,
- 676, 677, 678,
- 678, 677, 679,
- 678, 679, 680,
- 680, 679, 681,
- 680, 681, 672,
- 672, 681, 673,
- 682, 672, 674,
- 682, 674, 676,
- 682, 676, 678,
- 682, 678, 680,
- 682, 680, 672,
- 683, 675, 673,
- 683, 677, 675,
- 683, 679, 677,
- 683, 681, 679,
- 683, 673, 681,
- 684, 685, 686,
- 686, 685, 687,
- 686, 687, 688,
- 688, 687, 689,
- 688, 689, 690,
- 690, 689, 691,
- 690, 691, 692,
- 692, 691, 693,
- 692, 693, 684,
- 684, 693, 685,
- 694, 684, 686,
- 694, 686, 688,
- 694, 688, 690,
- 694, 690, 692,
- 694, 692, 684,
- 695, 687, 685,
- 695, 689, 687,
- 695, 691, 689,
- 695, 693, 691,
- 695, 685, 693,
- 696, 697, 698,
- 698, 697, 699,
- 698, 699, 700,
- 700, 699, 701,
- 700, 701, 702,
- 702, 701, 703,
- 702, 703, 704,
- 704, 703, 705,
- 704, 705, 696,
- 696, 705, 697,
- 706, 696, 698,
- 706, 698, 700,
- 706, 700, 702,
- 706, 702, 704,
- 706, 704, 696,
- 707, 699, 697,
- 707, 701, 699,
- 707, 703, 701,
- 707, 705, 703,
- 707, 697, 705,
- 708, 709, 710,
- 710, 709, 711,
- 710, 711, 712,
- 712, 711, 713,
- 712, 713, 714,
- 714, 713, 715,
- 714, 715, 716,
- 716, 715, 717,
- 716, 717, 708,
- 708, 717, 709,
- 718, 708, 710,
- 718, 710, 712,
- 718, 712, 714,
- 718, 714, 716,
- 718, 716, 708,
- 719, 711, 709,
- 719, 713, 711,
- 719, 715, 713,
- 719, 717, 715,
- 719, 709, 717,
- 720, 721, 722,
- 722, 721, 723,
- 722, 723, 724,
- 724, 723, 725,
- 724, 725, 726,
- 726, 725, 727,
- 726, 727, 728,
- 728, 727, 729,
- 728, 729, 720,
- 720, 729, 721,
- 730, 720, 722,
- 730, 722, 724,
- 730, 724, 726,
- 730, 726, 728,
- 730, 728, 720,
- 731, 723, 721,
- 731, 725, 723,
- 731, 727, 725,
- 731, 729, 727,
- 731, 721, 729,
- 732, 733, 734,
- 734, 733, 735,
- 734, 735, 736,
- 736, 735, 737,
- 736, 737, 738,
- 738, 737, 739,
- 738, 739, 740,
- 740, 739, 741,
- 740, 741, 732,
- 732, 741, 733,
- 742, 732, 734,
- 742, 734, 736,
- 742, 736, 738,
- 742, 738, 740,
- 742, 740, 732,
- 743, 735, 733,
- 743, 737, 735,
- 743, 739, 737,
- 743, 741, 739,
- 743, 733, 741,
- 744, 745, 746,
- 746, 745, 747,
- 746, 747, 748,
- 748, 747, 749,
- 748, 749, 750,
- 750, 749, 751,
- 750, 751, 752,
- 752, 751, 753,
- 752, 753, 744,
- 744, 753, 745,
- 754, 744, 746,
- 754, 746, 748,
- 754, 748, 750,
- 754, 750, 752,
- 754, 752, 744,
- 755, 747, 745,
- 755, 749, 747,
- 755, 751, 749,
- 755, 753, 751,
- 755, 745, 753,
- 756, 757, 758,
- 758, 757, 759,
- 758, 759, 760,
- 760, 759, 761,
- 760, 761, 762,
- 762, 761, 763,
- 762, 763, 764,
- 764, 763, 765,
- 764, 765, 756,
- 756, 765, 757,
- 766, 756, 758,
- 766, 758, 760,
- 766, 760, 762,
- 766, 762, 764,
- 766, 764, 756,
- 767, 759, 757,
- 767, 761, 759,
- 767, 763, 761,
- 767, 765, 763,
- 767, 757, 765
-};
-static const unsigned some_enclosures_properties[3840] =
-{
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 0, 1, 0,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 3, 4, 0,
- 3, 4, 0,
- 3, 4, 0,
- 3, 4, 0
-};
-
-#define NB_CYL_X 4
-#define NB_CYL_Y 4
-#define NB_CYL_Z 4
-#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
-#define CYL_VRTX_COUNT 12u
-#define CYL_TRG_COUNT 20u
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_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(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* Create a scene */
- ctx.positions = some_enclosures_vertices;
- ctx.indices = some_enclosures_triangles;
- ctx.properties = some_enclosures_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- some_enclosures_triangles_count, get_indices, get_media_from_properties,
- some_enclosures_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_vertices_count(scn, &count));
- CHK(count == NB_CYL * CYL_VRTX_COUNT);
- OK(senc_scene_get_triangles_count(scn, &count));
- CHK(count == NB_CYL * CYL_TRG_COUNT);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 1 + NB_CYL);
- FOR_EACH(e, 0, count) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- unsigned m;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- CHK(header.enclosed_media_count == 1);
- OK(senc_enclosure_get_medium(enclosure, 0, &m));
- CHK(header.primitives_count ==
- (header.is_infinite /* Outermost enclosure: NB_CYL_X*NB_CYL_Y cylinders */
- ? NB_CYL_X * NB_CYL_Y * CYL_TRG_COUNT
- : (m == 0
- ? CYL_TRG_COUNT /* Innermost enclosures: 1 cylinder */
- : 2 * CYL_TRG_COUNT))); /* Other enclosures: 2 cylinders */
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_ref_put(scn));
- OK(senc_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_senc_some_triangles.c b/src/test_senc_some_triangles.c
@@ -1,2737 +0,0 @@
-/* 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
- * 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 sg3_geometry_dump_as_C_code feature
- * of star-geometry. It uses output from test_sg3_some_triangles.
- * This test is similar to test_senc_many_triangles that creates a huge
- * geometry by program. */
-
-#include "senc.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-/* Dump of star-geometry 'some_triangles'. */
-static const unsigned some_triangles_vertices_count = 536;
-static const double some_triangles_vertices[1608] =
-{
- 1, 0, -1,
- 1, 0, -0.8,
- 1, 0, -0.6,
- 1, 0, -0.4,
- 1, 0, -0.2,
- 1, 0, -5.55112e-17,
- 1, 0, 0.2,
- 1, 0, 0.4,
- 1, 0, 0.6,
- 1, 0, 0.8,
- 1, 0, 1,
- 0.866025, 0.5, -1,
- 0.866025, 0.5, -0.8,
- 0.866025, 0.5, -0.6,
- 0.866025, 0.5, -0.4,
- 0.866025, 0.5, -0.2,
- 0.866025, 0.5, -5.55112e-17,
- 0.866025, 0.5, 0.2,
- 0.866025, 0.5, 0.4,
- 0.866025, 0.5, 0.6,
- 0.866025, 0.5, 0.8,
- 0.866025, 0.5, 1,
- 0.5, 0.866025, -1,
- 0.5, 0.866025, -0.8,
- 0.5, 0.866025, -0.6,
- 0.5, 0.866025, -0.4,
- 0.5, 0.866025, -0.2,
- 0.5, 0.866025, -5.55112e-17,
- 0.5, 0.866025, 0.2,
- 0.5, 0.866025, 0.4,
- 0.5, 0.866025, 0.6,
- 0.5, 0.866025, 0.8,
- 0.5, 0.866025, 1,
- 6.12323e-17, 1, -1,
- 6.12323e-17, 1, -0.8,
- 6.12323e-17, 1, -0.6,
- 6.12323e-17, 1, -0.4,
- 6.12323e-17, 1, -0.2,
- 6.12323e-17, 1, -5.55112e-17,
- 6.12323e-17, 1, 0.2,
- 6.12323e-17, 1, 0.4,
- 6.12323e-17, 1, 0.6,
- 6.12323e-17, 1, 0.8,
- 6.12323e-17, 1, 1,
- -0.5, 0.866025, -1,
- -0.5, 0.866025, -0.8,
- -0.5, 0.866025, -0.6,
- -0.5, 0.866025, -0.4,
- -0.5, 0.866025, -0.2,
- -0.5, 0.866025, -5.55112e-17,
- -0.5, 0.866025, 0.2,
- -0.5, 0.866025, 0.4,
- -0.5, 0.866025, 0.6,
- -0.5, 0.866025, 0.8,
- -0.5, 0.866025, 1,
- -0.866025, 0.5, -1,
- -0.866025, 0.5, -0.8,
- -0.866025, 0.5, -0.6,
- -0.866025, 0.5, -0.4,
- -0.866025, 0.5, -0.2,
- -0.866025, 0.5, -5.55112e-17,
- -0.866025, 0.5, 0.2,
- -0.866025, 0.5, 0.4,
- -0.866025, 0.5, 0.6,
- -0.866025, 0.5, 0.8,
- -0.866025, 0.5, 1,
- -1, 1.22465e-16, -1,
- -1, 1.22465e-16, -0.8,
- -1, 1.22465e-16, -0.6,
- -1, 1.22465e-16, -0.4,
- -1, 1.22465e-16, -0.2,
- -1, 1.22465e-16, -5.55112e-17,
- -1, 1.22465e-16, 0.2,
- -1, 1.22465e-16, 0.4,
- -1, 1.22465e-16, 0.6,
- -1, 1.22465e-16, 0.8,
- -1, 1.22465e-16, 1,
- -0.866025, -0.5, -1,
- -0.866025, -0.5, -0.8,
- -0.866025, -0.5, -0.6,
- -0.866025, -0.5, -0.4,
- -0.866025, -0.5, -0.2,
- -0.866025, -0.5, -5.55112e-17,
- -0.866025, -0.5, 0.2,
- -0.866025, -0.5, 0.4,
- -0.866025, -0.5, 0.6,
- -0.866025, -0.5, 0.8,
- -0.866025, -0.5, 1,
- -0.5, -0.866025, -1,
- -0.5, -0.866025, -0.8,
- -0.5, -0.866025, -0.6,
- -0.5, -0.866025, -0.4,
- -0.5, -0.866025, -0.2,
- -0.5, -0.866025, -5.55112e-17,
- -0.5, -0.866025, 0.2,
- -0.5, -0.866025, 0.4,
- -0.5, -0.866025, 0.6,
- -0.5, -0.866025, 0.8,
- -0.5, -0.866025, 1,
- -1.83697e-16, -1, -1,
- -1.83697e-16, -1, -0.8,
- -1.83697e-16, -1, -0.6,
- -1.83697e-16, -1, -0.4,
- -1.83697e-16, -1, -0.2,
- -1.83697e-16, -1, -5.55112e-17,
- -1.83697e-16, -1, 0.2,
- -1.83697e-16, -1, 0.4,
- -1.83697e-16, -1, 0.6,
- -1.83697e-16, -1, 0.8,
- -1.83697e-16, -1, 1,
- 0.5, -0.866025, -1,
- 0.5, -0.866025, -0.8,
- 0.5, -0.866025, -0.6,
- 0.5, -0.866025, -0.4,
- 0.5, -0.866025, -0.2,
- 0.5, -0.866025, -5.55112e-17,
- 0.5, -0.866025, 0.2,
- 0.5, -0.866025, 0.4,
- 0.5, -0.866025, 0.6,
- 0.5, -0.866025, 0.8,
- 0.5, -0.866025, 1,
- 0.866025, -0.5, -1,
- 0.866025, -0.5, -0.8,
- 0.866025, -0.5, -0.6,
- 0.866025, -0.5, -0.4,
- 0.866025, -0.5, -0.2,
- 0.866025, -0.5, -5.55112e-17,
- 0.866025, -0.5, 0.2,
- 0.866025, -0.5, 0.4,
- 0.866025, -0.5, 0.6,
- 0.866025, -0.5, 0.8,
- 0.866025, -0.5, 1,
- 0, 0, -1,
- 0, 0, 1,
- 1, 0, 9,
- 1, 0, 9.2,
- 1, 0, 9.4,
- 1, 0, 9.6,
- 1, 0, 9.8,
- 1, 0, 10,
- 1, 0, 10.2,
- 1, 0, 10.4,
- 1, 0, 10.6,
- 1, 0, 10.8,
- 1, 0, 11,
- 0.866025, 0.5, 9,
- 0.866025, 0.5, 9.2,
- 0.866025, 0.5, 9.4,
- 0.866025, 0.5, 9.6,
- 0.866025, 0.5, 9.8,
- 0.866025, 0.5, 10,
- 0.866025, 0.5, 10.2,
- 0.866025, 0.5, 10.4,
- 0.866025, 0.5, 10.6,
- 0.866025, 0.5, 10.8,
- 0.866025, 0.5, 11,
- 0.5, 0.866025, 9,
- 0.5, 0.866025, 9.2,
- 0.5, 0.866025, 9.4,
- 0.5, 0.866025, 9.6,
- 0.5, 0.866025, 9.8,
- 0.5, 0.866025, 10,
- 0.5, 0.866025, 10.2,
- 0.5, 0.866025, 10.4,
- 0.5, 0.866025, 10.6,
- 0.5, 0.866025, 10.8,
- 0.5, 0.866025, 11,
- 6.12323e-17, 1, 9,
- 6.12323e-17, 1, 9.2,
- 6.12323e-17, 1, 9.4,
- 6.12323e-17, 1, 9.6,
- 6.12323e-17, 1, 9.8,
- 6.12323e-17, 1, 10,
- 6.12323e-17, 1, 10.2,
- 6.12323e-17, 1, 10.4,
- 6.12323e-17, 1, 10.6,
- 6.12323e-17, 1, 10.8,
- 6.12323e-17, 1, 11,
- -0.5, 0.866025, 9,
- -0.5, 0.866025, 9.2,
- -0.5, 0.866025, 9.4,
- -0.5, 0.866025, 9.6,
- -0.5, 0.866025, 9.8,
- -0.5, 0.866025, 10,
- -0.5, 0.866025, 10.2,
- -0.5, 0.866025, 10.4,
- -0.5, 0.866025, 10.6,
- -0.5, 0.866025, 10.8,
- -0.5, 0.866025, 11,
- -0.866025, 0.5, 9,
- -0.866025, 0.5, 9.2,
- -0.866025, 0.5, 9.4,
- -0.866025, 0.5, 9.6,
- -0.866025, 0.5, 9.8,
- -0.866025, 0.5, 10,
- -0.866025, 0.5, 10.2,
- -0.866025, 0.5, 10.4,
- -0.866025, 0.5, 10.6,
- -0.866025, 0.5, 10.8,
- -0.866025, 0.5, 11,
- -1, 1.22465e-16, 9,
- -1, 1.22465e-16, 9.2,
- -1, 1.22465e-16, 9.4,
- -1, 1.22465e-16, 9.6,
- -1, 1.22465e-16, 9.8,
- -1, 1.22465e-16, 10,
- -1, 1.22465e-16, 10.2,
- -1, 1.22465e-16, 10.4,
- -1, 1.22465e-16, 10.6,
- -1, 1.22465e-16, 10.8,
- -1, 1.22465e-16, 11,
- -0.866025, -0.5, 9,
- -0.866025, -0.5, 9.2,
- -0.866025, -0.5, 9.4,
- -0.866025, -0.5, 9.6,
- -0.866025, -0.5, 9.8,
- -0.866025, -0.5, 10,
- -0.866025, -0.5, 10.2,
- -0.866025, -0.5, 10.4,
- -0.866025, -0.5, 10.6,
- -0.866025, -0.5, 10.8,
- -0.866025, -0.5, 11,
- -0.5, -0.866025, 9,
- -0.5, -0.866025, 9.2,
- -0.5, -0.866025, 9.4,
- -0.5, -0.866025, 9.6,
- -0.5, -0.866025, 9.8,
- -0.5, -0.866025, 10,
- -0.5, -0.866025, 10.2,
- -0.5, -0.866025, 10.4,
- -0.5, -0.866025, 10.6,
- -0.5, -0.866025, 10.8,
- -0.5, -0.866025, 11,
- -1.83697e-16, -1, 9,
- -1.83697e-16, -1, 9.2,
- -1.83697e-16, -1, 9.4,
- -1.83697e-16, -1, 9.6,
- -1.83697e-16, -1, 9.8,
- -1.83697e-16, -1, 10,
- -1.83697e-16, -1, 10.2,
- -1.83697e-16, -1, 10.4,
- -1.83697e-16, -1, 10.6,
- -1.83697e-16, -1, 10.8,
- -1.83697e-16, -1, 11,
- 0.5, -0.866025, 9,
- 0.5, -0.866025, 9.2,
- 0.5, -0.866025, 9.4,
- 0.5, -0.866025, 9.6,
- 0.5, -0.866025, 9.8,
- 0.5, -0.866025, 10,
- 0.5, -0.866025, 10.2,
- 0.5, -0.866025, 10.4,
- 0.5, -0.866025, 10.6,
- 0.5, -0.866025, 10.8,
- 0.5, -0.866025, 11,
- 0.866025, -0.5, 9,
- 0.866025, -0.5, 9.2,
- 0.866025, -0.5, 9.4,
- 0.866025, -0.5, 9.6,
- 0.866025, -0.5, 9.8,
- 0.866025, -0.5, 10,
- 0.866025, -0.5, 10.2,
- 0.866025, -0.5, 10.4,
- 0.866025, -0.5, 10.6,
- 0.866025, -0.5, 10.8,
- 0.866025, -0.5, 11,
- 0, 0, 9,
- 0, 0, 11,
- 1, 0, 19,
- 1, 0, 19.2,
- 1, 0, 19.4,
- 1, 0, 19.6,
- 1, 0, 19.8,
- 1, 0, 20,
- 1, 0, 20.2,
- 1, 0, 20.4,
- 1, 0, 20.6,
- 1, 0, 20.8,
- 1, 0, 21,
- 0.866025, 0.5, 19,
- 0.866025, 0.5, 19.2,
- 0.866025, 0.5, 19.4,
- 0.866025, 0.5, 19.6,
- 0.866025, 0.5, 19.8,
- 0.866025, 0.5, 20,
- 0.866025, 0.5, 20.2,
- 0.866025, 0.5, 20.4,
- 0.866025, 0.5, 20.6,
- 0.866025, 0.5, 20.8,
- 0.866025, 0.5, 21,
- 0.5, 0.866025, 19,
- 0.5, 0.866025, 19.2,
- 0.5, 0.866025, 19.4,
- 0.5, 0.866025, 19.6,
- 0.5, 0.866025, 19.8,
- 0.5, 0.866025, 20,
- 0.5, 0.866025, 20.2,
- 0.5, 0.866025, 20.4,
- 0.5, 0.866025, 20.6,
- 0.5, 0.866025, 20.8,
- 0.5, 0.866025, 21,
- 6.12323e-17, 1, 19,
- 6.12323e-17, 1, 19.2,
- 6.12323e-17, 1, 19.4,
- 6.12323e-17, 1, 19.6,
- 6.12323e-17, 1, 19.8,
- 6.12323e-17, 1, 20,
- 6.12323e-17, 1, 20.2,
- 6.12323e-17, 1, 20.4,
- 6.12323e-17, 1, 20.6,
- 6.12323e-17, 1, 20.8,
- 6.12323e-17, 1, 21,
- -0.5, 0.866025, 19,
- -0.5, 0.866025, 19.2,
- -0.5, 0.866025, 19.4,
- -0.5, 0.866025, 19.6,
- -0.5, 0.866025, 19.8,
- -0.5, 0.866025, 20,
- -0.5, 0.866025, 20.2,
- -0.5, 0.866025, 20.4,
- -0.5, 0.866025, 20.6,
- -0.5, 0.866025, 20.8,
- -0.5, 0.866025, 21,
- -0.866025, 0.5, 19,
- -0.866025, 0.5, 19.2,
- -0.866025, 0.5, 19.4,
- -0.866025, 0.5, 19.6,
- -0.866025, 0.5, 19.8,
- -0.866025, 0.5, 20,
- -0.866025, 0.5, 20.2,
- -0.866025, 0.5, 20.4,
- -0.866025, 0.5, 20.6,
- -0.866025, 0.5, 20.8,
- -0.866025, 0.5, 21,
- -1, 1.22465e-16, 19,
- -1, 1.22465e-16, 19.2,
- -1, 1.22465e-16, 19.4,
- -1, 1.22465e-16, 19.6,
- -1, 1.22465e-16, 19.8,
- -1, 1.22465e-16, 20,
- -1, 1.22465e-16, 20.2,
- -1, 1.22465e-16, 20.4,
- -1, 1.22465e-16, 20.6,
- -1, 1.22465e-16, 20.8,
- -1, 1.22465e-16, 21,
- -0.866025, -0.5, 19,
- -0.866025, -0.5, 19.2,
- -0.866025, -0.5, 19.4,
- -0.866025, -0.5, 19.6,
- -0.866025, -0.5, 19.8,
- -0.866025, -0.5, 20,
- -0.866025, -0.5, 20.2,
- -0.866025, -0.5, 20.4,
- -0.866025, -0.5, 20.6,
- -0.866025, -0.5, 20.8,
- -0.866025, -0.5, 21,
- -0.5, -0.866025, 19,
- -0.5, -0.866025, 19.2,
- -0.5, -0.866025, 19.4,
- -0.5, -0.866025, 19.6,
- -0.5, -0.866025, 19.8,
- -0.5, -0.866025, 20,
- -0.5, -0.866025, 20.2,
- -0.5, -0.866025, 20.4,
- -0.5, -0.866025, 20.6,
- -0.5, -0.866025, 20.8,
- -0.5, -0.866025, 21,
- -1.83697e-16, -1, 19,
- -1.83697e-16, -1, 19.2,
- -1.83697e-16, -1, 19.4,
- -1.83697e-16, -1, 19.6,
- -1.83697e-16, -1, 19.8,
- -1.83697e-16, -1, 20,
- -1.83697e-16, -1, 20.2,
- -1.83697e-16, -1, 20.4,
- -1.83697e-16, -1, 20.6,
- -1.83697e-16, -1, 20.8,
- -1.83697e-16, -1, 21,
- 0.5, -0.866025, 19,
- 0.5, -0.866025, 19.2,
- 0.5, -0.866025, 19.4,
- 0.5, -0.866025, 19.6,
- 0.5, -0.866025, 19.8,
- 0.5, -0.866025, 20,
- 0.5, -0.866025, 20.2,
- 0.5, -0.866025, 20.4,
- 0.5, -0.866025, 20.6,
- 0.5, -0.866025, 20.8,
- 0.5, -0.866025, 21,
- 0.866025, -0.5, 19,
- 0.866025, -0.5, 19.2,
- 0.866025, -0.5, 19.4,
- 0.866025, -0.5, 19.6,
- 0.866025, -0.5, 19.8,
- 0.866025, -0.5, 20,
- 0.866025, -0.5, 20.2,
- 0.866025, -0.5, 20.4,
- 0.866025, -0.5, 20.6,
- 0.866025, -0.5, 20.8,
- 0.866025, -0.5, 21,
- 0, 0, 19,
- 0, 0, 21,
- 1, 0, 29,
- 1, 0, 29.2,
- 1, 0, 29.4,
- 1, 0, 29.6,
- 1, 0, 29.8,
- 1, 0, 30,
- 1, 0, 30.2,
- 1, 0, 30.4,
- 1, 0, 30.6,
- 1, 0, 30.8,
- 1, 0, 31,
- 0.866025, 0.5, 29,
- 0.866025, 0.5, 29.2,
- 0.866025, 0.5, 29.4,
- 0.866025, 0.5, 29.6,
- 0.866025, 0.5, 29.8,
- 0.866025, 0.5, 30,
- 0.866025, 0.5, 30.2,
- 0.866025, 0.5, 30.4,
- 0.866025, 0.5, 30.6,
- 0.866025, 0.5, 30.8,
- 0.866025, 0.5, 31,
- 0.5, 0.866025, 29,
- 0.5, 0.866025, 29.2,
- 0.5, 0.866025, 29.4,
- 0.5, 0.866025, 29.6,
- 0.5, 0.866025, 29.8,
- 0.5, 0.866025, 30,
- 0.5, 0.866025, 30.2,
- 0.5, 0.866025, 30.4,
- 0.5, 0.866025, 30.6,
- 0.5, 0.866025, 30.8,
- 0.5, 0.866025, 31,
- 6.12323e-17, 1, 29,
- 6.12323e-17, 1, 29.2,
- 6.12323e-17, 1, 29.4,
- 6.12323e-17, 1, 29.6,
- 6.12323e-17, 1, 29.8,
- 6.12323e-17, 1, 30,
- 6.12323e-17, 1, 30.2,
- 6.12323e-17, 1, 30.4,
- 6.12323e-17, 1, 30.6,
- 6.12323e-17, 1, 30.8,
- 6.12323e-17, 1, 31,
- -0.5, 0.866025, 29,
- -0.5, 0.866025, 29.2,
- -0.5, 0.866025, 29.4,
- -0.5, 0.866025, 29.6,
- -0.5, 0.866025, 29.8,
- -0.5, 0.866025, 30,
- -0.5, 0.866025, 30.2,
- -0.5, 0.866025, 30.4,
- -0.5, 0.866025, 30.6,
- -0.5, 0.866025, 30.8,
- -0.5, 0.866025, 31,
- -0.866025, 0.5, 29,
- -0.866025, 0.5, 29.2,
- -0.866025, 0.5, 29.4,
- -0.866025, 0.5, 29.6,
- -0.866025, 0.5, 29.8,
- -0.866025, 0.5, 30,
- -0.866025, 0.5, 30.2,
- -0.866025, 0.5, 30.4,
- -0.866025, 0.5, 30.6,
- -0.866025, 0.5, 30.8,
- -0.866025, 0.5, 31,
- -1, 1.22465e-16, 29,
- -1, 1.22465e-16, 29.2,
- -1, 1.22465e-16, 29.4,
- -1, 1.22465e-16, 29.6,
- -1, 1.22465e-16, 29.8,
- -1, 1.22465e-16, 30,
- -1, 1.22465e-16, 30.2,
- -1, 1.22465e-16, 30.4,
- -1, 1.22465e-16, 30.6,
- -1, 1.22465e-16, 30.8,
- -1, 1.22465e-16, 31,
- -0.866025, -0.5, 29,
- -0.866025, -0.5, 29.2,
- -0.866025, -0.5, 29.4,
- -0.866025, -0.5, 29.6,
- -0.866025, -0.5, 29.8,
- -0.866025, -0.5, 30,
- -0.866025, -0.5, 30.2,
- -0.866025, -0.5, 30.4,
- -0.866025, -0.5, 30.6,
- -0.866025, -0.5, 30.8,
- -0.866025, -0.5, 31,
- -0.5, -0.866025, 29,
- -0.5, -0.866025, 29.2,
- -0.5, -0.866025, 29.4,
- -0.5, -0.866025, 29.6,
- -0.5, -0.866025, 29.8,
- -0.5, -0.866025, 30,
- -0.5, -0.866025, 30.2,
- -0.5, -0.866025, 30.4,
- -0.5, -0.866025, 30.6,
- -0.5, -0.866025, 30.8,
- -0.5, -0.866025, 31,
- -1.83697e-16, -1, 29,
- -1.83697e-16, -1, 29.2,
- -1.83697e-16, -1, 29.4,
- -1.83697e-16, -1, 29.6,
- -1.83697e-16, -1, 29.8,
- -1.83697e-16, -1, 30,
- -1.83697e-16, -1, 30.2,
- -1.83697e-16, -1, 30.4,
- -1.83697e-16, -1, 30.6,
- -1.83697e-16, -1, 30.8,
- -1.83697e-16, -1, 31,
- 0.5, -0.866025, 29,
- 0.5, -0.866025, 29.2,
- 0.5, -0.866025, 29.4,
- 0.5, -0.866025, 29.6,
- 0.5, -0.866025, 29.8,
- 0.5, -0.866025, 30,
- 0.5, -0.866025, 30.2,
- 0.5, -0.866025, 30.4,
- 0.5, -0.866025, 30.6,
- 0.5, -0.866025, 30.8,
- 0.5, -0.866025, 31,
- 0.866025, -0.5, 29,
- 0.866025, -0.5, 29.2,
- 0.866025, -0.5, 29.4,
- 0.866025, -0.5, 29.6,
- 0.866025, -0.5, 29.8,
- 0.866025, -0.5, 30,
- 0.866025, -0.5, 30.2,
- 0.866025, -0.5, 30.4,
- 0.866025, -0.5, 30.6,
- 0.866025, -0.5, 30.8,
- 0.866025, -0.5, 31,
- 0, 0, 29,
- 0, 0, 31
-};
-static const unsigned some_triangles_triangles_count = 1056;
-static const unsigned some_triangles_triangles[3168] =
-{
- 0, 1, 11,
- 11, 1, 12,
- 1, 2, 12,
- 12, 2, 13,
- 2, 3, 13,
- 13, 3, 14,
- 3, 4, 14,
- 14, 4, 15,
- 4, 5, 15,
- 15, 5, 16,
- 5, 6, 16,
- 16, 6, 17,
- 6, 7, 17,
- 17, 7, 18,
- 7, 8, 18,
- 18, 8, 19,
- 8, 9, 19,
- 19, 9, 20,
- 9, 10, 20,
- 20, 10, 21,
- 11, 12, 22,
- 22, 12, 23,
- 12, 13, 23,
- 23, 13, 24,
- 13, 14, 24,
- 24, 14, 25,
- 14, 15, 25,
- 25, 15, 26,
- 15, 16, 26,
- 26, 16, 27,
- 16, 17, 27,
- 27, 17, 28,
- 17, 18, 28,
- 28, 18, 29,
- 18, 19, 29,
- 29, 19, 30,
- 19, 20, 30,
- 30, 20, 31,
- 20, 21, 31,
- 31, 21, 32,
- 22, 23, 33,
- 33, 23, 34,
- 23, 24, 34,
- 34, 24, 35,
- 24, 25, 35,
- 35, 25, 36,
- 25, 26, 36,
- 36, 26, 37,
- 26, 27, 37,
- 37, 27, 38,
- 27, 28, 38,
- 38, 28, 39,
- 28, 29, 39,
- 39, 29, 40,
- 29, 30, 40,
- 40, 30, 41,
- 30, 31, 41,
- 41, 31, 42,
- 31, 32, 42,
- 42, 32, 43,
- 33, 34, 44,
- 44, 34, 45,
- 34, 35, 45,
- 45, 35, 46,
- 35, 36, 46,
- 46, 36, 47,
- 36, 37, 47,
- 47, 37, 48,
- 37, 38, 48,
- 48, 38, 49,
- 38, 39, 49,
- 49, 39, 50,
- 39, 40, 50,
- 50, 40, 51,
- 40, 41, 51,
- 51, 41, 52,
- 41, 42, 52,
- 52, 42, 53,
- 42, 43, 53,
- 53, 43, 54,
- 44, 45, 55,
- 55, 45, 56,
- 45, 46, 56,
- 56, 46, 57,
- 46, 47, 57,
- 57, 47, 58,
- 47, 48, 58,
- 58, 48, 59,
- 48, 49, 59,
- 59, 49, 60,
- 49, 50, 60,
- 60, 50, 61,
- 50, 51, 61,
- 61, 51, 62,
- 51, 52, 62,
- 62, 52, 63,
- 52, 53, 63,
- 63, 53, 64,
- 53, 54, 64,
- 64, 54, 65,
- 55, 56, 66,
- 66, 56, 67,
- 56, 57, 67,
- 67, 57, 68,
- 57, 58, 68,
- 68, 58, 69,
- 58, 59, 69,
- 69, 59, 70,
- 59, 60, 70,
- 70, 60, 71,
- 60, 61, 71,
- 71, 61, 72,
- 61, 62, 72,
- 72, 62, 73,
- 62, 63, 73,
- 73, 63, 74,
- 63, 64, 74,
- 74, 64, 75,
- 64, 65, 75,
- 75, 65, 76,
- 66, 67, 77,
- 77, 67, 78,
- 67, 68, 78,
- 78, 68, 79,
- 68, 69, 79,
- 79, 69, 80,
- 69, 70, 80,
- 80, 70, 81,
- 70, 71, 81,
- 81, 71, 82,
- 71, 72, 82,
- 82, 72, 83,
- 72, 73, 83,
- 83, 73, 84,
- 73, 74, 84,
- 84, 74, 85,
- 74, 75, 85,
- 85, 75, 86,
- 75, 76, 86,
- 86, 76, 87,
- 77, 78, 88,
- 88, 78, 89,
- 78, 79, 89,
- 89, 79, 90,
- 79, 80, 90,
- 90, 80, 91,
- 80, 81, 91,
- 91, 81, 92,
- 81, 82, 92,
- 92, 82, 93,
- 82, 83, 93,
- 93, 83, 94,
- 83, 84, 94,
- 94, 84, 95,
- 84, 85, 95,
- 95, 85, 96,
- 85, 86, 96,
- 96, 86, 97,
- 86, 87, 97,
- 97, 87, 98,
- 88, 89, 99,
- 99, 89, 100,
- 89, 90, 100,
- 100, 90, 101,
- 90, 91, 101,
- 101, 91, 102,
- 91, 92, 102,
- 102, 92, 103,
- 92, 93, 103,
- 103, 93, 104,
- 93, 94, 104,
- 104, 94, 105,
- 94, 95, 105,
- 105, 95, 106,
- 95, 96, 106,
- 106, 96, 107,
- 96, 97, 107,
- 107, 97, 108,
- 97, 98, 108,
- 108, 98, 109,
- 99, 100, 110,
- 110, 100, 111,
- 100, 101, 111,
- 111, 101, 112,
- 101, 102, 112,
- 112, 102, 113,
- 102, 103, 113,
- 113, 103, 114,
- 103, 104, 114,
- 114, 104, 115,
- 104, 105, 115,
- 115, 105, 116,
- 105, 106, 116,
- 116, 106, 117,
- 106, 107, 117,
- 117, 107, 118,
- 107, 108, 118,
- 118, 108, 119,
- 108, 109, 119,
- 119, 109, 120,
- 110, 111, 121,
- 121, 111, 122,
- 111, 112, 122,
- 122, 112, 123,
- 112, 113, 123,
- 123, 113, 124,
- 113, 114, 124,
- 124, 114, 125,
- 114, 115, 125,
- 125, 115, 126,
- 115, 116, 126,
- 126, 116, 127,
- 116, 117, 127,
- 127, 117, 128,
- 117, 118, 128,
- 128, 118, 129,
- 118, 119, 129,
- 129, 119, 130,
- 119, 120, 130,
- 130, 120, 131,
- 121, 122, 0,
- 0, 122, 1,
- 122, 123, 1,
- 1, 123, 2,
- 123, 124, 2,
- 2, 124, 3,
- 124, 125, 3,
- 3, 125, 4,
- 125, 126, 4,
- 4, 126, 5,
- 126, 127, 5,
- 5, 127, 6,
- 127, 128, 6,
- 6, 128, 7,
- 128, 129, 7,
- 7, 129, 8,
- 129, 130, 8,
- 8, 130, 9,
- 130, 131, 9,
- 9, 131, 10,
- 132, 0, 11,
- 132, 11, 22,
- 132, 22, 33,
- 132, 33, 44,
- 132, 44, 55,
- 132, 55, 66,
- 132, 66, 77,
- 132, 77, 88,
- 132, 88, 99,
- 132, 99, 110,
- 132, 110, 121,
- 132, 121, 0,
- 133, 21, 10,
- 133, 32, 21,
- 133, 43, 32,
- 133, 54, 43,
- 133, 65, 54,
- 133, 76, 65,
- 133, 87, 76,
- 133, 98, 87,
- 133, 109, 98,
- 133, 120, 109,
- 133, 131, 120,
- 133, 10, 131,
- 134, 135, 145,
- 145, 135, 146,
- 135, 136, 146,
- 146, 136, 147,
- 136, 137, 147,
- 147, 137, 148,
- 137, 138, 148,
- 148, 138, 149,
- 138, 139, 149,
- 149, 139, 150,
- 139, 140, 150,
- 150, 140, 151,
- 140, 141, 151,
- 151, 141, 152,
- 141, 142, 152,
- 152, 142, 153,
- 142, 143, 153,
- 153, 143, 154,
- 143, 144, 154,
- 154, 144, 155,
- 145, 146, 156,
- 156, 146, 157,
- 146, 147, 157,
- 157, 147, 158,
- 147, 148, 158,
- 158, 148, 159,
- 148, 149, 159,
- 159, 149, 160,
- 149, 150, 160,
- 160, 150, 161,
- 150, 151, 161,
- 161, 151, 162,
- 151, 152, 162,
- 162, 152, 163,
- 152, 153, 163,
- 163, 153, 164,
- 153, 154, 164,
- 164, 154, 165,
- 154, 155, 165,
- 165, 155, 166,
- 156, 157, 167,
- 167, 157, 168,
- 157, 158, 168,
- 168, 158, 169,
- 158, 159, 169,
- 169, 159, 170,
- 159, 160, 170,
- 170, 160, 171,
- 160, 161, 171,
- 171, 161, 172,
- 161, 162, 172,
- 172, 162, 173,
- 162, 163, 173,
- 173, 163, 174,
- 163, 164, 174,
- 174, 164, 175,
- 164, 165, 175,
- 175, 165, 176,
- 165, 166, 176,
- 176, 166, 177,
- 167, 168, 178,
- 178, 168, 179,
- 168, 169, 179,
- 179, 169, 180,
- 169, 170, 180,
- 180, 170, 181,
- 170, 171, 181,
- 181, 171, 182,
- 171, 172, 182,
- 182, 172, 183,
- 172, 173, 183,
- 183, 173, 184,
- 173, 174, 184,
- 184, 174, 185,
- 174, 175, 185,
- 185, 175, 186,
- 175, 176, 186,
- 186, 176, 187,
- 176, 177, 187,
- 187, 177, 188,
- 178, 179, 189,
- 189, 179, 190,
- 179, 180, 190,
- 190, 180, 191,
- 180, 181, 191,
- 191, 181, 192,
- 181, 182, 192,
- 192, 182, 193,
- 182, 183, 193,
- 193, 183, 194,
- 183, 184, 194,
- 194, 184, 195,
- 184, 185, 195,
- 195, 185, 196,
- 185, 186, 196,
- 196, 186, 197,
- 186, 187, 197,
- 197, 187, 198,
- 187, 188, 198,
- 198, 188, 199,
- 189, 190, 200,
- 200, 190, 201,
- 190, 191, 201,
- 201, 191, 202,
- 191, 192, 202,
- 202, 192, 203,
- 192, 193, 203,
- 203, 193, 204,
- 193, 194, 204,
- 204, 194, 205,
- 194, 195, 205,
- 205, 195, 206,
- 195, 196, 206,
- 206, 196, 207,
- 196, 197, 207,
- 207, 197, 208,
- 197, 198, 208,
- 208, 198, 209,
- 198, 199, 209,
- 209, 199, 210,
- 200, 201, 211,
- 211, 201, 212,
- 201, 202, 212,
- 212, 202, 213,
- 202, 203, 213,
- 213, 203, 214,
- 203, 204, 214,
- 214, 204, 215,
- 204, 205, 215,
- 215, 205, 216,
- 205, 206, 216,
- 216, 206, 217,
- 206, 207, 217,
- 217, 207, 218,
- 207, 208, 218,
- 218, 208, 219,
- 208, 209, 219,
- 219, 209, 220,
- 209, 210, 220,
- 220, 210, 221,
- 211, 212, 222,
- 222, 212, 223,
- 212, 213, 223,
- 223, 213, 224,
- 213, 214, 224,
- 224, 214, 225,
- 214, 215, 225,
- 225, 215, 226,
- 215, 216, 226,
- 226, 216, 227,
- 216, 217, 227,
- 227, 217, 228,
- 217, 218, 228,
- 228, 218, 229,
- 218, 219, 229,
- 229, 219, 230,
- 219, 220, 230,
- 230, 220, 231,
- 220, 221, 231,
- 231, 221, 232,
- 222, 223, 233,
- 233, 223, 234,
- 223, 224, 234,
- 234, 224, 235,
- 224, 225, 235,
- 235, 225, 236,
- 225, 226, 236,
- 236, 226, 237,
- 226, 227, 237,
- 237, 227, 238,
- 227, 228, 238,
- 238, 228, 239,
- 228, 229, 239,
- 239, 229, 240,
- 229, 230, 240,
- 240, 230, 241,
- 230, 231, 241,
- 241, 231, 242,
- 231, 232, 242,
- 242, 232, 243,
- 233, 234, 244,
- 244, 234, 245,
- 234, 235, 245,
- 245, 235, 246,
- 235, 236, 246,
- 246, 236, 247,
- 236, 237, 247,
- 247, 237, 248,
- 237, 238, 248,
- 248, 238, 249,
- 238, 239, 249,
- 249, 239, 250,
- 239, 240, 250,
- 250, 240, 251,
- 240, 241, 251,
- 251, 241, 252,
- 241, 242, 252,
- 252, 242, 253,
- 242, 243, 253,
- 253, 243, 254,
- 244, 245, 255,
- 255, 245, 256,
- 245, 246, 256,
- 256, 246, 257,
- 246, 247, 257,
- 257, 247, 258,
- 247, 248, 258,
- 258, 248, 259,
- 248, 249, 259,
- 259, 249, 260,
- 249, 250, 260,
- 260, 250, 261,
- 250, 251, 261,
- 261, 251, 262,
- 251, 252, 262,
- 262, 252, 263,
- 252, 253, 263,
- 263, 253, 264,
- 253, 254, 264,
- 264, 254, 265,
- 255, 256, 134,
- 134, 256, 135,
- 256, 257, 135,
- 135, 257, 136,
- 257, 258, 136,
- 136, 258, 137,
- 258, 259, 137,
- 137, 259, 138,
- 259, 260, 138,
- 138, 260, 139,
- 260, 261, 139,
- 139, 261, 140,
- 261, 262, 140,
- 140, 262, 141,
- 262, 263, 141,
- 141, 263, 142,
- 263, 264, 142,
- 142, 264, 143,
- 264, 265, 143,
- 143, 265, 144,
- 266, 134, 145,
- 266, 145, 156,
- 266, 156, 167,
- 266, 167, 178,
- 266, 178, 189,
- 266, 189, 200,
- 266, 200, 211,
- 266, 211, 222,
- 266, 222, 233,
- 266, 233, 244,
- 266, 244, 255,
- 266, 255, 134,
- 267, 155, 144,
- 267, 166, 155,
- 267, 177, 166,
- 267, 188, 177,
- 267, 199, 188,
- 267, 210, 199,
- 267, 221, 210,
- 267, 232, 221,
- 267, 243, 232,
- 267, 254, 243,
- 267, 265, 254,
- 267, 144, 265,
- 268, 269, 279,
- 279, 269, 280,
- 269, 270, 280,
- 280, 270, 281,
- 270, 271, 281,
- 281, 271, 282,
- 271, 272, 282,
- 282, 272, 283,
- 272, 273, 283,
- 283, 273, 284,
- 273, 274, 284,
- 284, 274, 285,
- 274, 275, 285,
- 285, 275, 286,
- 275, 276, 286,
- 286, 276, 287,
- 276, 277, 287,
- 287, 277, 288,
- 277, 278, 288,
- 288, 278, 289,
- 279, 280, 290,
- 290, 280, 291,
- 280, 281, 291,
- 291, 281, 292,
- 281, 282, 292,
- 292, 282, 293,
- 282, 283, 293,
- 293, 283, 294,
- 283, 284, 294,
- 294, 284, 295,
- 284, 285, 295,
- 295, 285, 296,
- 285, 286, 296,
- 296, 286, 297,
- 286, 287, 297,
- 297, 287, 298,
- 287, 288, 298,
- 298, 288, 299,
- 288, 289, 299,
- 299, 289, 300,
- 290, 291, 301,
- 301, 291, 302,
- 291, 292, 302,
- 302, 292, 303,
- 292, 293, 303,
- 303, 293, 304,
- 293, 294, 304,
- 304, 294, 305,
- 294, 295, 305,
- 305, 295, 306,
- 295, 296, 306,
- 306, 296, 307,
- 296, 297, 307,
- 307, 297, 308,
- 297, 298, 308,
- 308, 298, 309,
- 298, 299, 309,
- 309, 299, 310,
- 299, 300, 310,
- 310, 300, 311,
- 301, 302, 312,
- 312, 302, 313,
- 302, 303, 313,
- 313, 303, 314,
- 303, 304, 314,
- 314, 304, 315,
- 304, 305, 315,
- 315, 305, 316,
- 305, 306, 316,
- 316, 306, 317,
- 306, 307, 317,
- 317, 307, 318,
- 307, 308, 318,
- 318, 308, 319,
- 308, 309, 319,
- 319, 309, 320,
- 309, 310, 320,
- 320, 310, 321,
- 310, 311, 321,
- 321, 311, 322,
- 312, 313, 323,
- 323, 313, 324,
- 313, 314, 324,
- 324, 314, 325,
- 314, 315, 325,
- 325, 315, 326,
- 315, 316, 326,
- 326, 316, 327,
- 316, 317, 327,
- 327, 317, 328,
- 317, 318, 328,
- 328, 318, 329,
- 318, 319, 329,
- 329, 319, 330,
- 319, 320, 330,
- 330, 320, 331,
- 320, 321, 331,
- 331, 321, 332,
- 321, 322, 332,
- 332, 322, 333,
- 323, 324, 334,
- 334, 324, 335,
- 324, 325, 335,
- 335, 325, 336,
- 325, 326, 336,
- 336, 326, 337,
- 326, 327, 337,
- 337, 327, 338,
- 327, 328, 338,
- 338, 328, 339,
- 328, 329, 339,
- 339, 329, 340,
- 329, 330, 340,
- 340, 330, 341,
- 330, 331, 341,
- 341, 331, 342,
- 331, 332, 342,
- 342, 332, 343,
- 332, 333, 343,
- 343, 333, 344,
- 334, 335, 345,
- 345, 335, 346,
- 335, 336, 346,
- 346, 336, 347,
- 336, 337, 347,
- 347, 337, 348,
- 337, 338, 348,
- 348, 338, 349,
- 338, 339, 349,
- 349, 339, 350,
- 339, 340, 350,
- 350, 340, 351,
- 340, 341, 351,
- 351, 341, 352,
- 341, 342, 352,
- 352, 342, 353,
- 342, 343, 353,
- 353, 343, 354,
- 343, 344, 354,
- 354, 344, 355,
- 345, 346, 356,
- 356, 346, 357,
- 346, 347, 357,
- 357, 347, 358,
- 347, 348, 358,
- 358, 348, 359,
- 348, 349, 359,
- 359, 349, 360,
- 349, 350, 360,
- 360, 350, 361,
- 350, 351, 361,
- 361, 351, 362,
- 351, 352, 362,
- 362, 352, 363,
- 352, 353, 363,
- 363, 353, 364,
- 353, 354, 364,
- 364, 354, 365,
- 354, 355, 365,
- 365, 355, 366,
- 356, 357, 367,
- 367, 357, 368,
- 357, 358, 368,
- 368, 358, 369,
- 358, 359, 369,
- 369, 359, 370,
- 359, 360, 370,
- 370, 360, 371,
- 360, 361, 371,
- 371, 361, 372,
- 361, 362, 372,
- 372, 362, 373,
- 362, 363, 373,
- 373, 363, 374,
- 363, 364, 374,
- 374, 364, 375,
- 364, 365, 375,
- 375, 365, 376,
- 365, 366, 376,
- 376, 366, 377,
- 367, 368, 378,
- 378, 368, 379,
- 368, 369, 379,
- 379, 369, 380,
- 369, 370, 380,
- 380, 370, 381,
- 370, 371, 381,
- 381, 371, 382,
- 371, 372, 382,
- 382, 372, 383,
- 372, 373, 383,
- 383, 373, 384,
- 373, 374, 384,
- 384, 374, 385,
- 374, 375, 385,
- 385, 375, 386,
- 375, 376, 386,
- 386, 376, 387,
- 376, 377, 387,
- 387, 377, 388,
- 378, 379, 389,
- 389, 379, 390,
- 379, 380, 390,
- 390, 380, 391,
- 380, 381, 391,
- 391, 381, 392,
- 381, 382, 392,
- 392, 382, 393,
- 382, 383, 393,
- 393, 383, 394,
- 383, 384, 394,
- 394, 384, 395,
- 384, 385, 395,
- 395, 385, 396,
- 385, 386, 396,
- 396, 386, 397,
- 386, 387, 397,
- 397, 387, 398,
- 387, 388, 398,
- 398, 388, 399,
- 389, 390, 268,
- 268, 390, 269,
- 390, 391, 269,
- 269, 391, 270,
- 391, 392, 270,
- 270, 392, 271,
- 392, 393, 271,
- 271, 393, 272,
- 393, 394, 272,
- 272, 394, 273,
- 394, 395, 273,
- 273, 395, 274,
- 395, 396, 274,
- 274, 396, 275,
- 396, 397, 275,
- 275, 397, 276,
- 397, 398, 276,
- 276, 398, 277,
- 398, 399, 277,
- 277, 399, 278,
- 400, 268, 279,
- 400, 279, 290,
- 400, 290, 301,
- 400, 301, 312,
- 400, 312, 323,
- 400, 323, 334,
- 400, 334, 345,
- 400, 345, 356,
- 400, 356, 367,
- 400, 367, 378,
- 400, 378, 389,
- 400, 389, 268,
- 401, 289, 278,
- 401, 300, 289,
- 401, 311, 300,
- 401, 322, 311,
- 401, 333, 322,
- 401, 344, 333,
- 401, 355, 344,
- 401, 366, 355,
- 401, 377, 366,
- 401, 388, 377,
- 401, 399, 388,
- 401, 278, 399,
- 402, 403, 413,
- 413, 403, 414,
- 403, 404, 414,
- 414, 404, 415,
- 404, 405, 415,
- 415, 405, 416,
- 405, 406, 416,
- 416, 406, 417,
- 406, 407, 417,
- 417, 407, 418,
- 407, 408, 418,
- 418, 408, 419,
- 408, 409, 419,
- 419, 409, 420,
- 409, 410, 420,
- 420, 410, 421,
- 410, 411, 421,
- 421, 411, 422,
- 411, 412, 422,
- 422, 412, 423,
- 413, 414, 424,
- 424, 414, 425,
- 414, 415, 425,
- 425, 415, 426,
- 415, 416, 426,
- 426, 416, 427,
- 416, 417, 427,
- 427, 417, 428,
- 417, 418, 428,
- 428, 418, 429,
- 418, 419, 429,
- 429, 419, 430,
- 419, 420, 430,
- 430, 420, 431,
- 420, 421, 431,
- 431, 421, 432,
- 421, 422, 432,
- 432, 422, 433,
- 422, 423, 433,
- 433, 423, 434,
- 424, 425, 435,
- 435, 425, 436,
- 425, 426, 436,
- 436, 426, 437,
- 426, 427, 437,
- 437, 427, 438,
- 427, 428, 438,
- 438, 428, 439,
- 428, 429, 439,
- 439, 429, 440,
- 429, 430, 440,
- 440, 430, 441,
- 430, 431, 441,
- 441, 431, 442,
- 431, 432, 442,
- 442, 432, 443,
- 432, 433, 443,
- 443, 433, 444,
- 433, 434, 444,
- 444, 434, 445,
- 435, 436, 446,
- 446, 436, 447,
- 436, 437, 447,
- 447, 437, 448,
- 437, 438, 448,
- 448, 438, 449,
- 438, 439, 449,
- 449, 439, 450,
- 439, 440, 450,
- 450, 440, 451,
- 440, 441, 451,
- 451, 441, 452,
- 441, 442, 452,
- 452, 442, 453,
- 442, 443, 453,
- 453, 443, 454,
- 443, 444, 454,
- 454, 444, 455,
- 444, 445, 455,
- 455, 445, 456,
- 446, 447, 457,
- 457, 447, 458,
- 447, 448, 458,
- 458, 448, 459,
- 448, 449, 459,
- 459, 449, 460,
- 449, 450, 460,
- 460, 450, 461,
- 450, 451, 461,
- 461, 451, 462,
- 451, 452, 462,
- 462, 452, 463,
- 452, 453, 463,
- 463, 453, 464,
- 453, 454, 464,
- 464, 454, 465,
- 454, 455, 465,
- 465, 455, 466,
- 455, 456, 466,
- 466, 456, 467,
- 457, 458, 468,
- 468, 458, 469,
- 458, 459, 469,
- 469, 459, 470,
- 459, 460, 470,
- 470, 460, 471,
- 460, 461, 471,
- 471, 461, 472,
- 461, 462, 472,
- 472, 462, 473,
- 462, 463, 473,
- 473, 463, 474,
- 463, 464, 474,
- 474, 464, 475,
- 464, 465, 475,
- 475, 465, 476,
- 465, 466, 476,
- 476, 466, 477,
- 466, 467, 477,
- 477, 467, 478,
- 468, 469, 479,
- 479, 469, 480,
- 469, 470, 480,
- 480, 470, 481,
- 470, 471, 481,
- 481, 471, 482,
- 471, 472, 482,
- 482, 472, 483,
- 472, 473, 483,
- 483, 473, 484,
- 473, 474, 484,
- 484, 474, 485,
- 474, 475, 485,
- 485, 475, 486,
- 475, 476, 486,
- 486, 476, 487,
- 476, 477, 487,
- 487, 477, 488,
- 477, 478, 488,
- 488, 478, 489,
- 479, 480, 490,
- 490, 480, 491,
- 480, 481, 491,
- 491, 481, 492,
- 481, 482, 492,
- 492, 482, 493,
- 482, 483, 493,
- 493, 483, 494,
- 483, 484, 494,
- 494, 484, 495,
- 484, 485, 495,
- 495, 485, 496,
- 485, 486, 496,
- 496, 486, 497,
- 486, 487, 497,
- 497, 487, 498,
- 487, 488, 498,
- 498, 488, 499,
- 488, 489, 499,
- 499, 489, 500,
- 490, 491, 501,
- 501, 491, 502,
- 491, 492, 502,
- 502, 492, 503,
- 492, 493, 503,
- 503, 493, 504,
- 493, 494, 504,
- 504, 494, 505,
- 494, 495, 505,
- 505, 495, 506,
- 495, 496, 506,
- 506, 496, 507,
- 496, 497, 507,
- 507, 497, 508,
- 497, 498, 508,
- 508, 498, 509,
- 498, 499, 509,
- 509, 499, 510,
- 499, 500, 510,
- 510, 500, 511,
- 501, 502, 512,
- 512, 502, 513,
- 502, 503, 513,
- 513, 503, 514,
- 503, 504, 514,
- 514, 504, 515,
- 504, 505, 515,
- 515, 505, 516,
- 505, 506, 516,
- 516, 506, 517,
- 506, 507, 517,
- 517, 507, 518,
- 507, 508, 518,
- 518, 508, 519,
- 508, 509, 519,
- 519, 509, 520,
- 509, 510, 520,
- 520, 510, 521,
- 510, 511, 521,
- 521, 511, 522,
- 512, 513, 523,
- 523, 513, 524,
- 513, 514, 524,
- 524, 514, 525,
- 514, 515, 525,
- 525, 515, 526,
- 515, 516, 526,
- 526, 516, 527,
- 516, 517, 527,
- 527, 517, 528,
- 517, 518, 528,
- 528, 518, 529,
- 518, 519, 529,
- 529, 519, 530,
- 519, 520, 530,
- 530, 520, 531,
- 520, 521, 531,
- 531, 521, 532,
- 521, 522, 532,
- 532, 522, 533,
- 523, 524, 402,
- 402, 524, 403,
- 524, 525, 403,
- 403, 525, 404,
- 525, 526, 404,
- 404, 526, 405,
- 526, 527, 405,
- 405, 527, 406,
- 527, 528, 406,
- 406, 528, 407,
- 528, 529, 407,
- 407, 529, 408,
- 529, 530, 408,
- 408, 530, 409,
- 530, 531, 409,
- 409, 531, 410,
- 531, 532, 410,
- 410, 532, 411,
- 532, 533, 411,
- 411, 533, 412,
- 534, 402, 413,
- 534, 413, 424,
- 534, 424, 435,
- 534, 435, 446,
- 534, 446, 457,
- 534, 457, 468,
- 534, 468, 479,
- 534, 479, 490,
- 534, 490, 501,
- 534, 501, 512,
- 534, 512, 523,
- 534, 523, 402,
- 535, 423, 412,
- 535, 434, 423,
- 535, 445, 434,
- 535, 456, 445,
- 535, 467, 456,
- 535, 478, 467,
- 535, 489, 478,
- 535, 500, 489,
- 535, 511, 500,
- 535, 522, 511,
- 535, 533, 522,
- 535, 412, 533
-};
-static const unsigned some_triangles_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_CYL 4
-#define CYL_VRTX_COUNT 134u
-#define CYL_TRG_COUNT 264u
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_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(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* Create a scene */
- ctx.positions = some_triangles_vertices;
- ctx.indices = some_triangles_triangles;
- ctx.properties = some_triangles_properties;
- OK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE,
- some_triangles_triangles_count, get_indices, get_media_from_properties,
- some_triangles_vertices_count, get_position, &ctx, &scn));
-
- OK(senc_scene_get_vertices_count(scn, &count));
- CHK(count == NB_CYL * CYL_VRTX_COUNT);
- OK(senc_scene_get_triangles_count(scn, &count));
- CHK(count == NB_CYL * CYL_TRG_COUNT);
-
- OK(senc_scene_get_enclosure_count(scn, &count));
- CHK(count == 1 + NB_CYL);
- FOR_EACH(e, 0, count) {
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- OK(senc_scene_get_enclosure(scn, e, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
- CHK(header.primitives_count ==
- (e ? CYL_TRG_COUNT : NB_CYL * CYL_TRG_COUNT));
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- OK(senc_scene_ref_put(scn));
- OK(senc_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_senc_unspecified_medium.c b/src/test_senc_unspecified_medium.c
@@ -1,327 +0,0 @@
-/* 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
-* 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 sg3_geometry_dump_as_C_code feature
- * of star-geometry. It uses output from test_sg3_unspecified_properties.
- * This test is similar to test_senc_many_enclosures that creates a huge
- * geometry by program. */
-
-#include "senc.h"
-#include "senc_s3d_helper.h"
-#include "test_senc_utils.h"
-
-#include <rsys/double3.h>
-
-#define SG3_UNSPECIFED_PROPERTY UINT_MAX
-
-/* Dump of star-geometry 'front_unspecified'. */
-static const unsigned front_unspecified_vertices_count = 8;
-static const double front_unspecified_vertices[24] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1
-};
-static const unsigned front_unspecified_triangles_count = 12;
-static const unsigned front_unspecified_triangles[36] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5
-};
-static const unsigned front_unspecified_properties[36] =
-{
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY
-};
-/* Dump of star-geometry 'front_half_unspecified'. */
-static const unsigned front_half_unspecified_vertices_count = 8;
-static const double front_half_unspecified_vertices[24] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1
-};
-static const unsigned front_half_unspecified_triangles_count = 12;
-static const unsigned front_half_unspecified_triangles[36] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5
-};
-static const unsigned front_half_unspecified_properties[36] =
-{
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- 0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- 0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- 0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- 0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- 0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- 0, 1, 0
-};
-/* Dump of star-geometry 'all_defined'. */
-static const unsigned all_defined_vertices_count = 8;
-static const double all_defined_vertices[24] =
-{
- 0.1, 0, 0,
- 1, 0, 0,
- 0, 1, 0,
- 1, 1, 0,
- 0, 0, 1.1,
- 1, 0, 1,
- 0, 1, 1,
- 1, 1.1, 1
-};
-static const unsigned all_defined_triangles_count = 12;
-static const unsigned all_defined_triangles[36] =
-{
- 0, 2, 1,
- 1, 2, 3,
- 0, 4, 2,
- 2, 4, 6,
- 4, 5, 6,
- 6, 5, 7,
- 3, 7, 1,
- 1, 7, 5,
- 2, 6, 3,
- 3, 6, 7,
- 0, 1, 4,
- 4, 1, 5
-};
-static const unsigned all_defined_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
-};
-
-static void
-test(const int convention)
-{
- struct mem_allocator allocator;
- struct senc_device* dev = NULL;
- struct senc_scene* scn = NULL;
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- unsigned medium, expected_external_medium, expected_internal_medium;
- unsigned gid;
- enum senc_side side;
- struct context ctx = CONTEXT_NULL__;
- unsigned i, t, ecount;
- const int conv_front = (convention & SENC_CONVENTION_NORMAL_FRONT) != 0;
-
- OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev));
-
- /* Geometry with no media information on both sides */
- ctx.positions = front_unspecified_vertices;
- ctx.indices = front_unspecified_triangles;
- ctx.properties = front_unspecified_properties;
- OK(senc_scene_create(dev, convention, front_unspecified_triangles_count,
- get_indices, get_media_from_properties, front_unspecified_vertices_count,
- get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 2);
-
- FOR_EACH(i, 0, ecount) {
- struct senc_enclosure* ee;
- struct senc_enclosure_header hh;
- unsigned cc;
- OK(senc_scene_get_enclosure(scn, i, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == i);
- CHK(header.enclosed_media_count == 1);
-
- OK(senc_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input triangles:
- * if convention is front, front medium (unspecified) is outside,
- * that is medium 0's enclosure is infinite */
- expected_external_medium = conv_front ? SENC_UNSPECIFIED_MEDIUM : 1;
- expected_internal_medium = conv_front ? 1 : SENC_UNSPECIFIED_MEDIUM;
-
- CHK(medium == (header.is_infinite
- ? expected_external_medium : expected_internal_medium));
- CHK(header.primitives_count == ntriangles);
- CHK(header.unique_primitives_count == ntriangles);
- CHK(header.vertices_count == nvertices);
- CHK(header.is_infinite == (i == 0));
-
- OK(senc_scene_get_enclosure_count_by_medium(scn, medium, &cc));
- CHK(cc == 1);
- OK(senc_scene_get_enclosure_by_medium(scn, medium, 0, &ee));
- OK(senc_enclosure_get_header(ee, &hh));
- CHK(header.enclosure_id == hh.enclosure_id);
- OK(senc_enclosure_ref_put(ee));
-
- FOR_EACH(t, 0, header.primitives_count) {
- unsigned ind[3];
- OK(senc_enclosure_get_triangle_id(enclosure, t, &gid, &side));
- CHK(gid == t);
- CHK(side == (medium == 1) ? SENC_BACK : SENC_FRONT);
- OK(senc_enclosure_get_triangle(enclosure, t, ind));
- }
- OK(senc_enclosure_ref_put(enclosure));
- }
- OK(senc_scene_ref_put(scn));
-
- /* Same geometry, front media are defined for odd triangles */
- ctx.positions = front_half_unspecified_vertices;
- ctx.indices = front_half_unspecified_triangles;
- ctx.properties = front_half_unspecified_properties;
- OK(senc_scene_create(dev, convention, front_half_unspecified_triangles_count,
- get_indices, get_media_from_properties, front_half_unspecified_vertices_count,
- get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 2);
-
- FOR_EACH(i, 0, ecount) {
- unsigned expected_external_media_count, expected_internal_media_count,
- expected_media_count;
- OK(senc_scene_get_enclosure(scn, i, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == i);
-
- OK(senc_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input triangles:
- * 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(senc_enclosure_ref_put(enclosure));
- }
- OK(senc_scene_ref_put(scn));
-
- /* Same geometry, all media are defined */
- ctx.positions = all_defined_vertices;
- ctx.indices = all_defined_triangles;
- ctx.properties = all_defined_properties;
- OK(senc_scene_create(dev, convention, all_defined_triangles_count,
- get_indices, get_media_from_properties, all_defined_vertices_count,
- get_position, &ctx, &scn));
-
- OK(senc_scene_get_enclosure_count(scn, &ecount));
- CHK(ecount == 2);
-
- FOR_EACH(i, 0, ecount) {
- struct senc_enclosure* ee;
- struct senc_enclosure_header hh;
- unsigned cc;
- OK(senc_scene_get_enclosure(scn, i, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- CHK(header.enclosure_id == i);
- CHK(header.enclosed_media_count == 1);
- OK(senc_enclosure_get_medium(enclosure, 0, &medium));
- /* Geometrical normals point outside the cube in input triangles:
- * 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.primitives_count == ntriangles);
- CHK(header.unique_primitives_count == ntriangles);
- CHK(header.vertices_count == nvertices);
- CHK(header.is_infinite == (i == 0));
-
- OK(senc_scene_get_enclosure_count_by_medium(scn, medium, &cc));
- CHK(cc == 1);
- OK(senc_scene_get_enclosure_by_medium(scn, medium, 0, &ee));
- OK(senc_enclosure_get_header(ee, &hh));
- CHK(header.enclosure_id == hh.enclosure_id);
- OK(senc_enclosure_ref_put(ee));
-
- FOR_EACH(t, 0, header.primitives_count) {
- OK(senc_enclosure_get_triangle_id(enclosure, t, &gid, &side));
- CHK(gid == t);
- CHK(side == (medium == 1) ? SENC_BACK : SENC_FRONT);
- }
- OK(senc_enclosure_ref_put(enclosure));
- }
-
- SENC(scene_ref_put(scn));
- SENC(device_ref_put(dev));
-
- 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(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE);
- test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE);
- test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_OUTSIDE);
- test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_OUTSIDE);
- return 0;
-}
diff --git a/src/test_senc_utils.h b/src/test_senc_utils.h
@@ -1,271 +0,0 @@
-/* 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
- * 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_UTILS_H
-#define TEST_UTILS_H
-
-#include <rsys/rsys.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/double3.h>
-
-#include <stdio.h>
-
-#define OK(Expr) CHK((Expr) == RES_OK)
-#define BA(Expr) CHK((Expr) == RES_BAD_ARG)
-
-/*******************************************************************************
- * Geometry
- ******************************************************************************/
-/* Distorded cube */
-static const double box_vertices[8/*#vertices*/*3/*#coords per vertex*/] = {
- 0.1, 0.0, 0.0,
- 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 1.0, 1.0, 0.0,
- 0.0, 0.0, 1.1,
- 1.0, 0.0, 1.0,
- 0.0, 1.0, 1.0,
- 1.0, 1.1, 1.0
-};
-/* Need a true cube for some tests */
-static const double cube_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = {
- 0.0, 0.0, 0.0,
- 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 1.0, 1.0, 0.0,
- 0.0, 0.0, 1.0,
- 1.0, 0.0, 1.0,
- 0.0, 1.0, 1.0,
- 1.0, 1.0, 1.0
-};
-static const unsigned nvertices = sizeof(box_vertices) / sizeof(double[3]);
-STATIC_ASSERT(sizeof(box_vertices) == sizeof(cube_vertices),
- The_2_geometries_must_have_the_same_number_of_vertices);
-
-/* The following array lists the indices toward the 3D vertices of each
- * triangle.
- * ,2---,3 ,2----3
- * ,' | ,'/| ,'/| \ |
- * 6----7' / | 6' / | \ | Y
- * |', | / ,1 | / ,0---,1 |
- * | ',|/,' |/,' | ,' o--X
- * 4----5' 4----5' /
- * Front, right Back, left and Z
- * and Top faces bottom faces */
-static const unsigned
-box_indices[12/*#triangles*/*3/*#indices per triangle*/] = {
- 0, 2, 1, 1, 2, 3, /* Front face */
- 0, 4, 2, 2, 4, 6, /* Left face*/
- 4, 5, 6, 6, 5, 7, /* Back face */
- 3, 7, 1, 1, 7, 5, /* Right face */
- 2, 6, 3, 3, 6, 7, /* Top face */
- 0, 1, 4, 4, 1, 5 /* Bottom face */
-};
-static const unsigned
-ntriangles = sizeof(box_indices) / (3 * sizeof(*box_indices));
-
-struct context {
- const double* positions;
- const unsigned* indices;
- const unsigned* front_media;
- const unsigned* back_media;
- const unsigned* properties;
- void* custom;
- double offset[3];
- double scale;
- char reverse_vrtx, reverse_med;
-};
-#define CONTEXT_NULL__ {\
- NULL, NULL, NULL, NULL, NULL, NULL, {0,0,0}, 1, 0, 0\
-}
-
-static const unsigned medium0[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static const unsigned medium1[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
-static const unsigned medium2[12] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
-static const unsigned medium1_3[12] = { 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1 };
-static const unsigned medium1_back0[12] = { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 };
-static const unsigned medium1_front0[12] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
-
-static INLINE void
-get_indices(const unsigned itri, unsigned ids[3], void* context)
-{
- const struct context* ctx = context;
- ASSERT(ids && ctx);
- ids[0] = ctx->indices[itri * 3 + 0];
- ids[ctx->reverse_vrtx ? 2 : 1] = ctx->indices[itri * 3 + 1];
- ids[ctx->reverse_vrtx ? 1 : 2] = ctx->indices[itri * 3 + 2];
-}
-
-static INLINE void
-get_position(const unsigned ivert, double pos[3], void* context)
-{
- const struct context* ctx = context;
- ASSERT(pos && ctx);
- pos[0] = ctx->positions[ivert * 3 + 0] * ctx->scale + ctx->offset[0];
- pos[1] = ctx->positions[ivert * 3 + 1] * ctx->scale + ctx->offset[1];
- pos[2] = ctx->positions[ivert * 3 + 2] * ctx->scale + ctx->offset[2];
-}
-
-static INLINE void
-get_media(const unsigned itri, unsigned medium[2], void* context)
-{
- const struct context* ctx = context;
- ASSERT(medium && ctx);
- medium[ctx->reverse_med ? 1 : 0] = ctx->front_media[itri];
- medium[ctx->reverse_med ? 0 : 1] = ctx->back_media[itri];
-}
-
-static INLINE void
-get_media_from_properties(const unsigned itri, unsigned medium[2], void* context)
-{
- const struct context* ctx = context;
- ASSERT(medium && ctx);
- medium[ctx->reverse_med ? 1 : 0] = ctx->properties[3 * itri + 0];
- medium[ctx->reverse_med ? 0 : 1] = ctx->properties[3 * itri + 1];
-}
-
-/*******************************************************************************
- * Miscellaneous
- ******************************************************************************/
-static INLINE void
-dump_global
- (struct senc_scene* scn,
- const char* name)
-{
- FILE* stream;
- unsigned triangles_count, vertices_count, i;
-
- ASSERT(scn && name);
-
- OK(senc_scene_get_vertices_count(scn, &vertices_count));
- OK(senc_scene_get_triangles_count(scn, &triangles_count));
-
- stream = fopen(name, "w");
- CHK(stream);
- FOR_EACH(i, 0, vertices_count) {
- double tmp[3];
- OK(senc_scene_get_vertex(scn, i, tmp));
- fprintf(stream, "v %g %g %g\n", SPLIT3(tmp));
- }
- FOR_EACH(i, 0, triangles_count) {
- unsigned indices[3];
- OK(senc_scene_get_triangle(scn, i, indices));
- fprintf(stream, "f %lu %lu %lu\n", (unsigned long)(1 + indices[0]),
- (unsigned long)(1 + indices[1]), (unsigned long)(1 + indices[2]));
- }
- fclose(stream);
-}
-
-static INLINE void
-dump_enclosure
- (struct senc_scene* scn,
- const unsigned enc,
- const char* name)
-{
- struct senc_enclosure* enclosure;
- struct senc_enclosure_header header;
- FILE* stream;
- unsigned count, i;
-
- ASSERT(scn && name);
-
- SENC(scene_get_enclosure_count(scn, &count));
- ASSERT(enc < count);
- OK(senc_scene_get_enclosure(scn, enc, &enclosure));
- OK(senc_enclosure_get_header(enclosure, &header));
-
- stream = fopen(name, "w");
- CHK(stream);
- FOR_EACH(i, 0, header.vertices_count) {
- double tmp[3];
- OK(senc_enclosure_get_vertex(enclosure, i, tmp));
- fprintf(stream, "v %g %g %g\n", SPLIT3(tmp));
- }
- FOR_EACH(i, 0, header.primitives_count) {
- unsigned indices[3];
- OK(senc_enclosure_get_triangle(enclosure, i, indices));
- fprintf(stream, "f %lu %lu %lu\n", (unsigned long)(1+indices[0]),
- (unsigned long)(1+indices[1]), (unsigned long)(1+indices[2]));
- }
- OK(senc_enclosure_ref_put(enclosure));
- fclose(stream);
-}
-
-static INLINE void
-check_memory_allocator(struct mem_allocator* allocator)
-{
- if(MEM_ALLOCATED_SIZE(allocator)) {
- char dump[1024];
- MEM_DUMP(allocator, dump, sizeof(dump));
- fprintf(stderr, "%s\n", dump);
- FATAL("Memory leaks.\n");
- }
-}
-
-/*******************************************************************************
- * Check functions
- ******************************************************************************/
-/* Compare the itri-th triangle of enclosure with a triangle described by trg2 & vertices2 */
-static INLINE void
-cmp_trg
- (const unsigned itri,
- const struct senc_enclosure* enclosure,
- const unsigned trg2[3],
- const double* vertices2,
- int* trg_eq,
- int* trg_reversed)
-{
- unsigned trg1[3];
- double t1[3][3];
- double t2[3][3];
- unsigned trg1_eq[3] = { 3, 3, 3 };
- unsigned i, j, fst_vrtx = 3;
-
- ASSERT(enclosure && trg2 && vertices2 && trg_eq && trg_reversed);
-
- OK(senc_enclosure_get_triangle(enclosure, itri, trg1));
- FOR_EACH(i, 0, 3) {
- OK(senc_enclosure_get_vertex(enclosure, trg1[i], t1[i]));
- d3_set(t2[i], vertices2 + (3 * trg2[i]));
- }
- FOR_EACH(i, 0, 3) {
- FOR_EACH(j, 0, 3) {
- if(d3_eq(t1[i], t2[j])) {
- trg1_eq[i] = j;
- if(i == 0) fst_vrtx = j;
- break;
- }
- }
- }
- FOR_EACH(i, 0, 3) {
- if(trg1_eq[i] == 3) {
- *trg_eq = 0;
- return;
- }
- if(trg1_eq[i] == trg1_eq[(i + 1) % 3]
- || trg1_eq[i] == trg1_eq[(i + 2) % 3]) {
- *trg_eq = 0;
- return;
- }
- }
- /* Same 3 vertices */
- ASSERT(fst_vrtx != 3);
- *trg_eq = 1;
-
- *trg_reversed = (trg1_eq[1] != (fst_vrtx + 1) % 3);
- ASSERT(*trg_reversed != (trg1_eq[1] != (fst_vrtx + 2) % 3));
-}
-
-#endif /* TEST_UTILS_H */
diff --git a/src/test_senc_utils2.h b/src/test_senc_utils2.h
@@ -1,107 +0,0 @@
-/* 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
- * 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_UTILS2_H
-#define TEST_UTILS2_H
-
-#if !defined(NB_CYL_X) || !defined(NB_CYL_Y) || !defined(NB_CYL_Z) | !defined(NB_CYL)
-#error "Macro definitions are missing"
-#endif
-
-#include "test_senc_utils.h"
-
-#include <star/s3dut.h>
-#include <rsys/double3.h>
-
-struct s3dut_context {
- struct s3dut_mesh_data data;
- struct context ctx;
-};
-
-static void
-get_s3dut_indices(const unsigned itri, unsigned ids[3], void* context)
-{
- struct s3dut_context* ctx = context;
- unsigned s3dut_itri, cyl_idx, v_offset;
- ASSERT(ids && ctx);
- ASSERT(itri < NB_CYL * ctx->data.nprimitives);
- /* Get cyl_idx along with the s3dut vertice index */
- s3dut_itri = itri % (unsigned)ctx->data.nprimitives;
- cyl_idx = itri / (unsigned)ctx->data.nprimitives;
- ASSERT(ctx->data.indices[s3dut_itri * 3 + 0] <= UINT_MAX
- && ctx->data.indices[s3dut_itri * 3 + 1] <= UINT_MAX
- && ctx->data.indices[s3dut_itri * 3 + 2] <= UINT_MAX);
- /* Compute the vertex index in the user numbering
- * from cyl_idx and s3dut data; vertex related getters
- * will have to get the s3dut index back */
- v_offset = cyl_idx * (unsigned)ctx->data.nvertices;
- ids[0] = v_offset + (unsigned)ctx->data.indices[s3dut_itri * 3 + 0];
- ids[ctx->ctx.reverse_vrtx ? 2 : 1]
- = v_offset + (unsigned)ctx->data.indices[s3dut_itri * 3 + 1];
- ids[ctx->ctx.reverse_vrtx ? 1 : 2]
- = v_offset + (unsigned)ctx->data.indices[s3dut_itri * 3 + 2];
-}
-
-static void
-get_s3dut_position(const unsigned ivert, double pos[3], void* context)
-{
- struct s3dut_context* ctx = context;
- unsigned s3dut_ivert, cyl_idx;
- int i, j, k;
- double offset[3], tmp[3];
- double center_x, center_y, scale, misalignment = 0;
- ASSERT(pos && ctx);
- ASSERT(ivert < NB_CYL * ctx->data.nvertices);
- /* Get cyl_idx and cylinder imbrication along with the s3dut vertice index */
- s3dut_ivert = ivert % (unsigned)ctx->data.nvertices;
- cyl_idx = ivert / (unsigned)ctx->data.nvertices;
- /* k th cylinder of the imbrication at grid position i,j */
- i = (int)cyl_idx / (NB_CYL_Y * NB_CYL_Z);
- j = (cyl_idx / NB_CYL_Z) % NB_CYL_Y;
- k = cyl_idx % NB_CYL_Z;
- ASSERT(i < NB_CYL_X && j < NB_CYL_Y && k < NB_CYL_Z);
- ASSERT((unsigned)(i * NB_CYL_Y * NB_CYL_Z + j * NB_CYL_Z + k)
- * ctx->data.nvertices + s3dut_ivert == ivert);
- center_x = 2 * (1 + NB_CYL_Z) * (i - NB_CYL_X / 2);
- center_y = 2 * (1 + NB_CYL_Z) * (j - NB_CYL_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 cylinders
- * or some hits are missed */
- misalignment = (k % 2) ? -0.01 : +0.01;
-#endif
- d3(offset, center_x + misalignment, center_y + misalignment, 0);
- d3_add(pos, d3_muld(tmp, ctx->data.positions + s3dut_ivert * 3, scale),
- offset);
-}
-
-static void
-get_s3dut_media(const unsigned itri, unsigned medium[2], void* context)
-{
- struct s3dut_context* ctx = context;
- unsigned cyl_idx;
- int k;
- ASSERT(medium && ctx);
- ASSERT(itri < NB_CYL * ctx->data.nprimitives);
- /* Get cyl_idx */
- cyl_idx = itri / (unsigned)ctx->data.nprimitives;
- /* k th cylinder of the imbrication at some grid position */
- k = cyl_idx % NB_CYL_Z;
- medium[ctx->ctx.reverse_med ? SENC_BACK : SENC_FRONT] = (unsigned)k;
- medium[ctx->ctx.reverse_med ? SENC_FRONT : SENC_BACK] = (unsigned)(k + 1);
-}
-#endif /* TEST_UTILS2_H */