commit 19274ee8374934b6b8b0feced157fdd0ba3082c4
parent f714362a43df38fc2418344e8153905dcbd9f44c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 20 Dec 2019 17:27:43 +0100
Remove most of API.
Just keep enclosures extraction from a single deduplicated geometry.
Diffstat:
28 files changed, 861 insertions(+), 1182 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -63,13 +63,13 @@ set(SENC_FILES_INC_API
senc_s3d_wrapper.h)
set(SENC_FILES_INC
- senc_descriptor_c.h
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_scene_analyze_c.h
+ senc_side_range.h)
set(SENC_FILES_DOC COPYING README.md)
diff --git a/src/senc.h b/src/senc.h
@@ -56,7 +56,6 @@ struct mem_allocator;
* 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_descriptor;
struct senc_device;
struct senc_scene;
struct senc_enclosure;
@@ -156,83 +155,28 @@ senc_device_ref_put
* StarEnclosures scene. A scene is a collection of triangles. Each triangle is
* defined with a medium on each side.
******************************************************************************/
-/* Creates an empty scene */
+/* 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,
- struct senc_scene** scene);
-
-/* Reserve memory according to anticipated scene size. */
-SENC_API res_T
-senc_scene_reserve
- (struct senc_scene* scene,
- const unsigned vertices_count,
+ /* Number of triangles */
const unsigned triangles_count,
- const unsigned media_count);
-
-/* Add a new set of vertices and triangles to the scene.
- * Vertices can be duplicates and are silently deduplicated on the fly.
- * Triangles can be duplicates as long as media are compatible on both sides.
- * Valid triangle duplicates are silently deduplicated, invalid duplicates
- * trigger an error (add_geometry returns RES_BAD_ARG).
- * The special value SENC_UNDEFINED_MEDIUM denotes an undefined medium.
- * It can be used to define the 2 sides of a triangle at different times.
- * Media on duplicate triangles are consider compatible if:
- * - the merge_triangle callback is provided and returns RES_OK,
- * - or media are identical or SENC_UNDEFINED_MEDIUM.
- * When deduplicating triangles, the first occurence remains (with its
- * original index in user world, regardless of deduplication); the only
- * situation where deduplication changes a previously recorded media is from
- * SENC_UNDEFINED_MEDIUM to any defined medium.
- * The add_triangle and merge_triangle callbacks can be used for attribute
- * management (including triangle IDs) and to record media incompatibilities
- * for a subsequent report; they allow the client app to store its own data.
- * By returning an error, they can also stop the add_geometry call. */
-SENC_API res_T
-senc_scene_add_geometry
- (struct senc_scene* scene,
- /* Number of added triangles */
- const unsigned triangles_count,
- /* User function that provides vertices ids for added triangles */
- void(*indices)(const unsigned itri, unsigned ids[3], void* context),
- /* User function that provides media ids for added triangles */
- void(*media) /* Can be NULL <=> SENC_UNDEFINED_MEDIUM medium used */
+ /* User function that provides vertices ids for triangles */
+ void(*get_indices)(const unsigned itri, unsigned ids[3], void* context),
+ /* User function that provides media ids for triangles */
+ void(*get_media) /* Can be NULL <=> SENC_UNDEFINED_MEDIUM medium used */
(const unsigned itri, unsigned med[2], void* context),
- /* Number of added vertices */
+ /* Number of vertices */
const unsigned vertices_count,
- /* User function that provides coordinates for added vertices */
- void(*position)(const unsigned ivert, double pos[3], void* context),
- /* Called for each new triangle so that the client app can manage its own
- * triangle data/properties/attributes.
- * If return is not RES_OK, add_geometry stops immediately and returns
- * whatever value add_triangle returned. */
- res_T(*add_triangle) /* Can be NULL */
- (const unsigned global_id, const unsigned itri, void* context),
- /* Called if the IVERTth triangle of the current add_geometry is equal to
- * the global_id_th global triangle so that the client app can try to merge
- * its own triangle data or record a possible media conflict.
- * The reversed_triangle arg indicates if the triangle vertices' order is
- * the same it was when the triangle was first added.
- * triangle_media and merge_media contain the involved media.
- * If those media are incompatible and merge_triangle returns RES_OK the
- * process will continue with the next triangle and possibly end in success.
- * If return is not RES_OK, add_geometry stops immediately and returns
- * whatever value merge_triangle returned.
- * If merge_triangle is NULL, a strict media compatibility is required for
- * add_geometry to success: add_geometry would stop and return RES_BAD_ARG
- * on the first occurence of duplicate triangle with incompatible media. */
- res_T(*merge_triangle) /* Can be NULL */
- (const unsigned global_id, const unsigned itri, const int reversed_triangle,
- const unsigned triangle_media[2], const unsigned merge_media[2],
- void* context),
- void* context);
-
-/* Returns a descriptor of the scene that holds the analysis' result. */
-SENC_API res_T
-senc_scene_analyze
- (struct senc_scene* scene,
- struct senc_descriptor** descriptor);
+ /* User function that provides coordinates for vertices */
+ void(*get_position)(const unsigned ivert, double pos[3], 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
@@ -246,33 +190,16 @@ senc_scene_get_triangles_count
(const struct senc_scene* scene,
unsigned* count);
-/* Returns the number of unique triangles in the scene (remaining
- * triangles after deduplication). */
-SENC_API res_T
-senc_scene_get_unique_triangles_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the number of unique sides with SENC_UNDEFINED_MEDIUM medium. */
+/* Returns the itri_th triangle vertices' indices. */
SENC_API res_T
-senc_scene_get_unique_sides_without_medium_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the itri_th unique triangle; the returned indices are
- * unique vertex indices.
- * Can be called anytime, before or after a call to analyze. */
-SENC_API res_T
-senc_scene_get_unique_triangle
+senc_scene_get_triangle
(const struct senc_scene* scene,
const unsigned itri,
unsigned indices[3]);
-/* Returns the itri_th unique triangle; the returned indices are
- * unique vertex indices.
- * Can be called anytime, before or after a call to analyze. */
+/* Returns the media for the itri_th triangle. */
SENC_API res_T
-senc_scene_get_unique_triangle_media
+senc_scene_get_triangle_media
(const struct senc_scene* scene,
const unsigned itri,
unsigned media[2]);
@@ -283,145 +210,81 @@ senc_scene_get_vertices_count
(const struct senc_scene* scene,
unsigned* count);
-/* Returns the number of unique vertices in the scene (remaining
- * vertices after deduplication). */
-SENC_API res_T
-senc_scene_get_unique_vertices_count
- (const struct senc_scene* scene,
- unsigned* count);
-
-/* Returns the coordinates of the ivert_th unique vertex.
- * Can be called anytime, before or after a call to analyze. */
+/* Returns the coordinates of the ivert_th vertex. */
SENC_API res_T
-senc_scene_get_unique_vertex
+senc_scene_get_vertex
(const struct senc_scene* scene,
const unsigned ivert,
double coord[3]);
-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 descriptor. It is an handle toward an analyze result.
- ******************************************************************************/
/* Returns the greater medium id found in added geometry. In API calls using a
* medium, any value in the [0 max_medium_id[ range is valid. However there can
* be unused ids (no geometry refered to this medium id). */
SENC_API res_T
-senc_descriptor_get_max_medium
- (const struct senc_descriptor* descriptor,
+senc_scene_get_max_medium
+ (const struct senc_scene* scene,
unsigned* max_medium_id);
/* Returns the number of enclosures. */
SENC_API res_T
-senc_descriptor_get_enclosure_count
- (const struct senc_descriptor* descriptor,
+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. */
SENC_API res_T
-senc_descriptor_get_enclosure_count_by_medium
- (const struct senc_descriptor* descriptor,
+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_descriptor_get_enclosure
- (struct senc_descriptor* descriptor,
+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. */
SENC_API res_T
-senc_descriptor_get_enclosure_by_medium
- (struct senc_descriptor* descriptor,
+senc_scene_get_enclosure_by_medium
+ (struct senc_scene* scene,
const unsigned imed,
const unsigned idx,
struct senc_enclosure** enclosure);
-/* Returns the number of unique triangles (no duplicates here) in the whole
- * geometry. */
-SENC_API res_T
-senc_descriptor_get_global_triangles_count
- (const struct senc_descriptor* descriptor,
- unsigned* count);
-
-/* Returns the number of unique vertices (no duplicates here) in the whole
- * geometry. */
-SENC_API res_T
-senc_descriptor_get_global_vertices_count
- (const struct senc_descriptor* descriptor,
- unsigned* count); /* Number of unique vertices. */
-
-/* Returns the itri_th global unique triangles; the returned indices are global
- * unique vertex indices. */
-SENC_API res_T
-senc_descriptor_get_global_triangle
- (const struct senc_descriptor* descriptor,
- const unsigned itri,
- unsigned indices[3]);
-
-/* Returns the coordinates of the ivert_th global unique vertex. */
-SENC_API res_T
-senc_descriptor_get_global_vertex
- (const struct senc_descriptor* descriptor,
- const unsigned ivert,
- double coord[3]);
-
-/* Returns the front and back media ids of the itri_th global unique
- * triangles. */
-SENC_API res_T
-senc_descriptor_get_global_triangle_media
- (const struct senc_descriptor* descriptor,
- const unsigned itri,
- unsigned media[2]);
-
-/* Returns the enclosures the itri_th global unique triangles front and back
- * sides are member of. */
+/* Returns the enclosures the itri_th triangle front and back sides are member
+ * of. */
SENC_API res_T
-senc_descriptor_get_global_triangle_enclosures
- (const struct senc_descriptor* descriptor,
+senc_scene_get_triangle_enclosures
+ (const struct senc_scene* scene,
const unsigned itri,
unsigned enclosures[2]);
-/* Returns the global id of the itri_th global unique triangle, that is the
- * triangle index in user world regardless of deduplication. */
-SENC_API res_T
-senc_descriptor_get_global_triangle_global_id
- (const struct senc_descriptor* descriptor,
- const unsigned itri,
- unsigned* gid);
-
/* 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_descriptor_get_frontier_segments_count
- (const struct senc_descriptor* descriptor,
+senc_scene_get_frontier_segments_count
+ (const struct senc_scene* scene,
unsigned* count);
/* Returns the iseg_th frontier segment; the returned indices are global unique
* vertex indices. */
SENC_API res_T
-senc_descriptor_get_frontier_segment
- (const struct senc_descriptor* descriptor,
+senc_scene_get_frontier_segment
+ (const struct senc_scene* scene,
const unsigned iseg,
unsigned vrtx_id[2]);
SENC_API res_T
-senc_descriptor_ref_get
- (struct senc_descriptor* descriptor);
+senc_scene_ref_get
+ (struct senc_scene* scene);
SENC_API res_T
-senc_descriptor_ref_put
- (struct senc_descriptor* descriptor);
+senc_scene_ref_put
+ (struct senc_scene* scene);
/*******************************************************************************
* StarEnclosures enclosure. It is an handle toward an enclosure.
diff --git a/src/senc_descriptor.c b/src/senc_descriptor.c
@@ -13,8 +13,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#include "senc_descriptor_c.h"
-#include "senc_device_c.h"
#include "senc_enclosure_c.h"
#include "senc_scene_c.h"
#include "senc.h"
@@ -23,108 +21,47 @@
#include <rsys/double3.h>
#include <rsys/mem_allocator.h>
- /*******************************************************************************
- * Helper function
- ******************************************************************************/
-static void
-descriptor_release(ref_T * ref)
-{
- struct senc_scene* scn = NULL;
- struct senc_descriptor* desc = NULL;
- ASSERT(ref);
- desc = CONTAINER_OF(ref, struct senc_descriptor, ref);
- scn = desc->scene;
- darray_triangle_enc_release(&desc->triangles_enc);
- darray_enclosure_release(&desc->enclosures);
- darray_enc_ids_array_release(&desc->enc_ids_array_by_medium);
- darray_frontier_edge_release(&desc->frontiers);
-
- MEM_RM(scn->dev->allocator, desc);
- SENC(scene_ref_put(scn));
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-struct senc_descriptor*
-descriptor_create(struct senc_scene* scn)
-{
- struct senc_descriptor* desc;
- res_T res = RES_OK;
- ASSERT(scn);
- desc = MEM_CALLOC(scn->dev->allocator, 1, sizeof(struct senc_descriptor));
- if(desc) {
- desc->scene = scn;
- SENC(scene_ref_get(desc->scene));
- ref_init(&desc->ref);
- darray_triangle_enc_init(scn->dev->allocator, &desc->triangles_enc);
- darray_enclosure_init(scn->dev->allocator, &desc->enclosures);
- darray_enc_ids_array_init(scn->dev->allocator,
- &desc->enc_ids_array_by_medium);
- OK(darray_enc_ids_array_resize(&desc->enc_ids_array_by_medium,
- 1 + scn->next_medium_idx)); /* +1 is for undef */
- darray_frontier_edge_init(scn->dev->allocator, &desc->frontiers);
- /* Enclosure 0 is always defined for infinite */
- OK(darray_enclosure_resize(&desc->enclosures, 1));
- desc->enclosures_count = 1;
- desc->triangle_count = scn->nutris;
- desc->vertices_count = scn->nuverts;
- }
-end:
- return desc;
-error:
- if(desc) SENC(descriptor_ref_put(desc));
- goto end;
-}
-
-struct mem_allocator*
- descriptor_get_allocator(struct senc_descriptor* desc)
-{
- ASSERT(desc);
- return desc->scene->dev->allocator;
-}
-
/*******************************************************************************
* Exported functions
******************************************************************************/
res_T
-senc_descriptor_get_max_medium
- (const struct senc_descriptor* desc, unsigned* max_medium_id)
+senc_scene_get_max_medium
+ (const struct senc_scene* scn, unsigned* max_medium_id)
{
- if(!desc || !max_medium_id) return RES_BAD_ARG;
- ASSERT(desc->scene->next_medium_idx < UINT_MAX); /* API type */
- *max_medium_id = (unsigned)desc->scene->next_medium_idx - 1;
+ if(!scn || !max_medium_id) return RES_BAD_ARG;
+ ASSERT(scn->next_medium_idx < UINT_MAX); /* API type */
+ *max_medium_id = (unsigned)scn->next_medium_idx - 1;
return RES_OK;
}
res_T
-senc_descriptor_get_enclosure_count
- (const struct senc_descriptor* desc, unsigned* count)
+senc_scene_get_enclosure_count
+ (const struct senc_scene* scn, unsigned* count)
{
size_t tmp;
- if(!desc || !count) return RES_BAD_ARG;
- tmp = darray_enclosure_size_get(&desc->enclosures);
+ if(!scn || !count) return RES_BAD_ARG;
+ tmp = darray_enclosure_size_get(&scn->analyze.enclosures);
ASSERT(tmp < UINT_MAX); /* API type */
- ASSERT(desc->enclosures_count == tmp);
+ ASSERT(scn->analyze.enclosures_count == tmp);
*count = (unsigned)tmp;
return RES_OK;
}
res_T
-senc_descriptor_get_enclosure_count_by_medium
- (const struct senc_descriptor* desc,
+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(!desc || !count
- || (imed != SENC_UNDEFINED_MEDIUM && imed >= desc->scene->next_medium_idx))
+ if(!scn || !count
+ || (imed != SENC_UNDEFINED_MEDIUM && imed >= scn->next_medium_idx))
return RES_BAD_ARG;
- ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
- == 1 + desc->scene->next_medium_idx);
- m_idx = (imed == SENC_UNDEFINED_MEDIUM) ? desc->scene->next_medium_idx : imed;
- enc_ids = darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium)
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ m_idx = (imed == SENC_UNDEFINED_MEDIUM) ? scn->next_medium_idx : imed;
+ enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
+ m_idx;
tmp = darray_enc_id_size_get(enc_ids);
ASSERT(tmp < UINT_MAX); /* API type */
@@ -133,23 +70,24 @@ senc_descriptor_get_enclosure_count_by_medium
}
FINLINE res_T
-senc_descriptor_get_enclosure
- (struct senc_descriptor* desc,
+senc_scene_get_enclosure
+ (struct senc_scene* scn,
const unsigned idx,
struct senc_enclosure** out_enc)
{
struct senc_enclosure* enc;
- if(!desc || idx >= darray_enclosure_size_get(&desc->enclosures) || !out_enc)
+ if(!scn || idx >= darray_enclosure_size_get(&scn->analyze.enclosures)
+ || !out_enc)
return RES_BAD_ARG;
- enc = enclosure_create(desc, idx);
+ enc = enclosure_create(scn, idx);
if(!enc) return RES_MEM_ERR;
*out_enc = enc;
return RES_OK;
}
res_T
-senc_descriptor_get_enclosure_by_medium
- (struct senc_descriptor* desc,
+senc_scene_get_enclosure_by_medium
+ (struct senc_scene* scn,
const unsigned imed,
const unsigned idx,
struct senc_enclosure** out_enc)
@@ -157,111 +95,31 @@ senc_descriptor_get_enclosure_by_medium
size_t m_idx;
const struct darray_enc_id* enc_ids;
unsigned index;
- if(!desc || !out_enc
- || (imed != SENC_UNDEFINED_MEDIUM && imed >= desc->scene->next_medium_idx))
+ if(!scn || !out_enc
+ || (imed != SENC_UNDEFINED_MEDIUM && imed >= scn->next_medium_idx))
return RES_BAD_ARG;
- ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
- == 1 + desc->scene->next_medium_idx);
- m_idx = (imed == SENC_UNDEFINED_MEDIUM) ? desc->scene->next_medium_idx : imed;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ m_idx = (imed == SENC_UNDEFINED_MEDIUM) ? scn->next_medium_idx : imed;
enc_ids =
- darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium) + m_idx;
+ darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG;
index = darray_enc_id_cdata_get(enc_ids)[idx];
- return senc_descriptor_get_enclosure(desc, index, out_enc);
-}
-
-res_T
-senc_descriptor_get_global_triangles_count
- (const struct senc_descriptor* desc,
- unsigned* count)
-{
- if(!desc || !count) return RES_BAD_ARG;
- ASSERT(desc->triangle_count < UINT_MAX);
- *count = (unsigned)desc->triangle_count; /* Back to API type */
- return RES_OK;
+ return senc_scene_get_enclosure(scn, index, out_enc);
}
res_T
-senc_descriptor_get_global_vertices_count
- (const struct senc_descriptor* desc,
- unsigned* count)
-{
- if(!desc || !count) return RES_BAD_ARG;
- if(desc->vertices_count >= UINT_MAX)
- return RES_BAD_ARG;
- *count = (unsigned)desc->vertices_count; /* Back to API type */
- return RES_OK;
-}
-
-res_T
-senc_descriptor_get_global_triangle
- (const struct senc_descriptor* desc,
- const unsigned itri,
- unsigned indices[3])
-{
- const struct triangle_in* trg;
- int i;
- if(!indices || ! desc
- || itri >= darray_triangle_in_size_get(&desc->scene->triangles_in))
- return RES_BAD_ARG;
- trg = darray_triangle_in_cdata_get(&desc->scene->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_descriptor_get_global_vertex
- (const struct senc_descriptor* desc,
- const unsigned ivert,
- double vrtx[3])
-{
- const union double3* v;
- if(!vrtx || !desc
- || ivert >= darray_position_size_get(&desc->scene->vertices))
- return RES_BAD_ARG;
-
- v = darray_position_cdata_get(&desc->scene->vertices) + ivert;
- d3_set(vrtx, v->vec);
- return RES_OK;
-}
-
-res_T
-senc_descriptor_get_global_triangle_media
- (const struct senc_descriptor* desc,
- const unsigned itri,
- unsigned media[2])
-{
- const struct triangle_in* trg;
- int i;
- if(!media || !desc
- || itri >= darray_triangle_in_size_get(&desc->scene->triangles_in))
- return RES_BAD_ARG;
- trg = darray_triangle_in_cdata_get(&desc->scene->triangles_in) + itri;
- FOR_EACH(i, 0, 2) {
-#if (UINT_MAX < MEDIUM_MAX__)
- ASSERT(trg->medium[i] < UINT_MAX);
-#endif
- media[i] = (unsigned)trg->medium[i]; /* Back to API type */
- }
- return RES_OK;
-}
-
-res_T
-senc_descriptor_get_global_triangle_enclosures
- (const struct senc_descriptor* desc,
+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 || !desc
- || itri >= darray_triangle_enc_size_get(&desc->triangles_enc))
+ if(!enclosures || !scn
+ || itri >= darray_triangle_enc_size_get(&scn->analyze.triangles_enc))
return RES_BAD_ARG;
- trg = darray_triangle_enc_cdata_get(&desc->triangles_enc) + itri;
+ 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);
@@ -272,62 +130,31 @@ senc_descriptor_get_global_triangle_enclosures
}
res_T
-senc_descriptor_get_global_triangle_global_id
- (const struct senc_descriptor* desc,
- const unsigned itri,
- unsigned* gid)
-{
- const struct triangle_in* trg;
- if(!gid || !desc
- || itri >= darray_triangle_in_size_get(&desc->scene->triangles_in))
- return RES_BAD_ARG;
- trg = darray_triangle_in_cdata_get(&desc->scene->triangles_in) + itri;
- *gid = trg->global_id;
- return RES_OK;
-}
-
-res_T
-senc_descriptor_get_frontier_segments_count
- (const struct senc_descriptor* desc,
+senc_scene_get_frontier_segments_count
+ (const struct senc_scene* scn,
unsigned* count)
{
size_t tmp;
- if(!desc || !count)
+ if(!scn || !count)
return RES_BAD_ARG;
- tmp = darray_frontier_edge_size_get(&desc->frontiers);
+ tmp = darray_frontier_edge_size_get(&scn->analyze.frontiers);
ASSERT(tmp < UINT_MAX);
*count = (unsigned)tmp;
return RES_OK;
}
res_T
-senc_descriptor_get_frontier_segment
- (const struct senc_descriptor* desc,
+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 || !desc
- || iseg >= darray_frontier_edge_size_get(&desc->frontiers))
+ if(!vrtx_id || !scn
+ || iseg >= darray_frontier_edge_size_get(&scn->analyze.frontiers))
return RES_BAD_ARG;
- edge = darray_frontier_edge_cdata_get(&desc->frontiers) + iseg;
+ 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;
}
-
-res_T
-senc_descriptor_ref_get(struct senc_descriptor* desc)
-{
- if(!desc) return RES_BAD_ARG;
- ref_get(&desc->ref);
- return RES_OK;
-}
-
-res_T
-senc_descriptor_ref_put(struct senc_descriptor* desc)
-{
- if(!desc) return RES_BAD_ARG;
- ref_put(&desc->ref, descriptor_release);
- return RES_OK;
-}
diff --git a/src/senc_descriptor_c.h b/src/senc_descriptor_c.h
@@ -16,153 +16,6 @@
#ifndef SENC_DESCRIPTOR_C_H
#define SENC_DESCRIPTOR_C_H
-#include <rsys/ref_count.h>
-#include <rsys/dynamic_array.h>
-#include "senc.h"
-#include "senc_enclosure_data.h"
-#include "senc_internal_types.h"
-
-struct senc_scene;
-struct mem_allocator;
-
-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>
-
-#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>
-
-/* 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>
-
-struct senc_descriptor {
- struct senc_scene* scene;
- 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;
- trg_id_t triangle_count;
- vrtx_id_t vertices_count;
- /* Store frontiers */
- struct darray_frontier_edge frontiers;
-
- ref_T ref;
-};
-
-struct senc_descriptor*
-descriptor_create(struct senc_scene* scn);
-
-struct mem_allocator*
-descriptor_get_allocator(struct senc_descriptor* desc);
#endif /* SENC_DESCRIPTOR_C_H */
diff --git a/src/senc_enclosure.c b/src/senc_enclosure.c
@@ -14,8 +14,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "senc_enclosure_c.h"
-#include "senc_descriptor_c.h"
+#include "senc_enclosure_data.h"
#include "senc_scene_c.h"
+#include "senc_device_c.h"
#include "senc.h"
#include <rsys/rsys.h>
@@ -30,13 +31,12 @@ static void
enclosure_release(ref_T * ref)
{
struct senc_enclosure* enclosure = NULL;
- struct senc_descriptor* desc = NULL;
+ struct senc_scene* scn = NULL;
ASSERT(ref);
enclosure = CONTAINER_OF(ref, struct senc_enclosure, ref);
- desc = enclosure->desc;
-
- MEM_RM(descriptor_get_allocator(desc), enclosure);
- SENC(descriptor_ref_put(desc));
+ scn = enclosure->scene;
+ MEM_RM(scn->dev->allocator, enclosure);
+ SENC(scene_ref_put(scn));
}
/*******************************************************************************
@@ -44,20 +44,19 @@ enclosure_release(ref_T * ref)
******************************************************************************/
struct senc_enclosure*
enclosure_create
- (struct senc_descriptor* desc,
+ (struct senc_scene* scn,
const unsigned idx)
{
struct senc_enclosure* enc;
- ASSERT(desc && idx < darray_enclosure_size_get(&desc->enclosures));
- enc = MEM_CALLOC(descriptor_get_allocator(desc),
- 1, sizeof(struct senc_enclosure));
+ 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(&desc->enclosures) + idx;
- SENC(descriptor_ref_get(desc));
- enc->desc = desc;
+ = darray_enclosure_data_get(&scn->analyze.enclosures) + idx;
+ enc->scene = scn;
enc->data = data;
ref_init(&enc->ref);
+ SENC(scene_ref_get(scn));
}
return enc;
}
@@ -109,7 +108,7 @@ senc_enclosure_get_vertex
const vrtx_id_t idx
= darray_vrtx_id_cdata_get(&enclosure->data->vertices)[ivert];
const union double3* positions
- = darray_position_cdata_get(&enclosure->desc->scene->vertices);
+ = darray_position_cdata_get(&enclosure->scene->vertices);
ASSERT(darray_vrtx_id_size_get(&enclosure->data->vertices)
== enclosure->data->header.vertices_count);
d3_set(coord, positions[idx].vec);
diff --git a/src/senc_enclosure_c.h b/src/senc_enclosure_c.h
@@ -21,17 +21,17 @@
#include "senc.h"
struct enclosure_data;
-struct senc_descriptor;
+struct senc_scene;
struct senc_enclosure {
const struct enclosure_data* data;
- struct senc_descriptor* desc;
+ struct senc_scene* scene;
ref_T ref;
};
struct senc_enclosure*
enclosure_create
- (struct senc_descriptor* desc,
+ (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
@@ -16,17 +16,27 @@
#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 "senc.h"
-#include "senc_scene_c.h"
-#include "senc_internal_types.h"
+#include <rsys/hash_table.h>
#include <limits.h>
+#define DARRAY_NAME vrtx_id
+#define DARRAY_DATA vrtx_id_t
+#include <rsys/dynamic_array.h>
+
+#define HTABLE_NAME vrtx_id
+#define HTABLE_KEY vrtx_id_t
+#define HTABLE_DATA vrtx_id_t
+#include <rsys/hash_table.h>
+
struct side_enc {
vrtx_id_t vertice_id[3];
side_id_t side_id;
@@ -93,23 +103,23 @@ static FINLINE res_T
bool_array_of_media_to_darray_media
(struct darray_media* dst,
const struct darray_uchar* src,
- const medium_id_t undef_idx)
+ const medium_id_t next_medium_idx)
{
res_T res = RES_OK;
- medium_id_t i;
+ unsigned m_idx;
const unsigned char* data;
ASSERT(src && dst);
data = darray_uchar_cdata_get(src);
- ASSERT(undef_idx + 1 == darray_uchar_size_get(src));
- ASSERT(undef_idx < MEDIUM_MAX__);
+ ASSERT(next_medium_idx + 1 == darray_uchar_size_get(src));
+ ASSERT(next_medium_idx < MEDIUM_MAX__);
darray_media_clear(dst);
if(res != RES_OK) goto error;
- FOR_EACH(i, 0, undef_idx + 1) {
- medium_id_t v = (i == undef_idx) ? SENC_UNDEFINED_MEDIUM : i;
- if(!data[i]) continue;
- res = darray_media_push_back(dst, &v);
+ FOR_EACH(m_idx, 0, next_medium_idx + 1) {
+ medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC_UNDEFINED_MEDIUM;
+ if(!data[m_idx]) continue;
+ res = darray_media_push_back(dst, &medium);
if(res != RES_OK) goto error;
}
end:
@@ -202,4 +212,24 @@ error:
return res;
}
+#define DARRAY_NAME enclosure
+#define DARRAY_DATA struct enclosure_data
+#define DARRAY_FUNCTOR_INIT enclosure_data_init
+#define DARRAY_FUNCTOR_COPY enclosure_data_copy
+#define DARRAY_FUNCTOR_RELEASE enclosure_data_release
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE enclosure_data_copy_and_release
+#include <rsys/dynamic_array.h>
+
+#define DARRAY_NAME enc_id
+#define DARRAY_DATA enclosure_id_t
+#include <rsys/dynamic_array.h>
+
+#define DARRAY_NAME enc_ids_array
+#define DARRAY_DATA struct darray_enc_id
+#define DARRAY_FUNCTOR_INIT darray_enc_id_init
+#define DARRAY_FUNCTOR_COPY darray_enc_id_copy
+#define DARRAY_FUNCTOR_RELEASE darray_enc_id_release
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_enc_id_copy_and_release
+#include <rsys/dynamic_array.h>
+
#endif /* SENC_ENCLOSURE_DATA_H */
diff --git a/src/senc_internal_types.h b/src/senc_internal_types.h
@@ -16,6 +16,8 @@
#ifndef SENC_INTERNAL_TYPES_H
#define SENC_INTERNAL_TYPES_H
+#include "senc.h"
+
#include <rsys/math.h>
#include <stdint.h>
diff --git a/src/senc_s3d_wrapper.h b/src/senc_s3d_wrapper.h
@@ -22,29 +22,29 @@
#include <rsys/float3.h>
static FINLINE void
-senc_descriptor_get_global_indices__
+senc_scene_get_global_indices__
(const unsigned itri,
unsigned indices[3],
void* ctx)
{
- const struct senc_descriptor* descriptor = ctx;
+ const struct senc_scene* scene = ctx;
res_T r;
- ASSERT(indices && ctx);
- r = senc_descriptor_get_global_triangle(descriptor, itri, indices);
+ ASSERT(indices && scene);
+ r = senc_scene_get_triangle(scene, itri, indices);
ASSERT(r == RES_OK); (void)r;
}
static FINLINE void
-senc_descriptor_get_global_vertices__
+senc_scene_get_global_vertices__
(const unsigned ivert,
float coord[3],
void* ctx)
{
- const struct senc_descriptor* descriptor = ctx;
+ const struct senc_scene* scene = ctx;
double tmp[3];
res_T r;
- ASSERT(coord && ctx);
- r = senc_descriptor_get_global_vertex(descriptor, ivert, tmp);
+ ASSERT(coord && scene);
+ r = senc_scene_get_vertex(scene, ivert, tmp);
ASSERT(r == RES_OK); (void)r;
f3_set_d3(coord, tmp);
}
diff --git a/src/senc_scene.c b/src/senc_scene.c
@@ -16,6 +16,7 @@
#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>
@@ -36,9 +37,13 @@ scene_release(ref_T * ref)
dev = scn->dev;
darray_triangle_in_release(&scn->triangles_in);
darray_position_release(&scn->vertices);
- htable_vrtx_release(&scn->unique_vertices);
- htable_trg_release(&scn->unique_triangles);
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));
}
@@ -59,12 +64,23 @@ 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;
+ const struct triangle_in* trg;
res_T res = RES_OK;
- if(!dev || !out_scn
+ if(!dev || !out_scn || !indices || !position
/* Convention must be set both regarding FRONT/BACK and INSIDE/OUTSIDE */
|| !(conv & (SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_BACK))
|| !(conv & (SENC_CONVENTION_NORMAL_INSIDE | SENC_CONVENTION_NORMAL_OUTSIDE)))
@@ -80,243 +96,132 @@ senc_scene_create
SENC(device_ref_get(dev));
scn->dev = dev;
scn->convention = conv;
- scn->ntris = 0;
- scn->nutris = 0;
+ scn->ntris = ntris;
scn->next_medium_idx = 0;
- scn->nverts = 0;
- scn->nuverts = 0;
- scn->sides_with_defined_medium_count = 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, &scn->unique_vertices);
- htable_trg_init(dev->allocator, &scn->unique_triangles);
+ htable_vrtx_init(dev->allocator, &unique_vertices);
+ htable_trg_init(dev->allocator, &unique_triangles);
darray_side_range_init(dev->allocator, &scn->media_use);
-exit:
- if(scn) *out_scn = scn;
- return res;
-error:
- if(scn) {
- SENC(scene_ref_put(scn));
- scn = NULL;
- }
- goto exit;
-}
+ 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;
-res_T
-senc_scene_reserve
- (struct senc_scene* scn,
- const unsigned vertices_count,
- const unsigned triangles_count,
- const unsigned media_count)
-{
- res_T res = RES_OK;
- if(!scn) return RES_BAD_ARG;
-
- OK(darray_position_reserve(&scn->vertices, vertices_count));
- OK(darray_triangle_in_reserve(&scn->triangles_in, triangles_count));
- OK(htable_vrtx_reserve(&scn->unique_vertices, vertices_count));
- OK(htable_trg_reserve(&scn->unique_triangles, triangles_count));
- OK(darray_side_range_reserve(&scn->media_use, media_count));
-
-end:
- return res;
-error:
- goto end;
-}
-
-res_T
-senc_scene_add_geometry
- (struct senc_scene* scn,
- 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),
- res_T(*add_triangle)(const unsigned, const unsigned, void*),
- res_T(*merge_triangle)(const unsigned, const unsigned, const int,
- const unsigned*, const unsigned*, void*),
- void* ctx)
-{
- struct darray_vrtx_id unique_vertice_ids;
- unsigned i;
- vrtx_id_t actual_nverts = 0;
- vrtx_id_t actual_nuverts = 0;
- trg_id_t actual_ntris = 0;
- trg_id_t actual_nutris = 0;
- const struct triangle_in* trg;
- res_T res = RES_OK;
-
- if(!scn
- || !indices || !position
- || !nverts || ((size_t)scn->nverts + (size_t)nverts) > VRTX_MAX__
- || !ntris || ((size_t)scn->ntris + (size_t)ntris) > TRG_MAX__)
+ if(!scn || !indices || !position || !nverts || !ntris)
return RES_BAD_ARG;
- /* Make room for new geometry; suppose no more duplicates. */
- darray_vrtx_id_init(scn->dev->allocator, &unique_vertice_ids);
- OK(darray_vrtx_id_reserve(&unique_vertice_ids, nverts));
- OK(darray_position_reserve(&scn->vertices, scn->nuverts + nverts));
- OK(darray_triangle_in_reserve(&scn->triangles_in, scn->nutris + ntris));
- OK(htable_vrtx_reserve(&scn->unique_vertices, scn->nuverts + nverts));
- OK(htable_trg_reserve(&scn->unique_triangles, scn->nutris + ntris));
+ 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));
trg = darray_triangle_in_cdata_get(&scn->triangles_in);
- /* Get geometry */
+ /* Get vertices */
FOR_EACH(i, 0, nverts) {
vrtx_id_t* p_vrtx;
union double3 tmp;
- vrtx_id_t unique_v;
/* API: position needs an unsigned */
position(i, tmp.vec, ctx);
- p_vrtx = htable_vrtx_find(&scn->unique_vertices, &tmp);
+ p_vrtx = htable_vrtx_find(&unique_vertices, &tmp);
if(p_vrtx) {
/* Duplicate vertex */
- unique_v = *p_vrtx;
- } else {
- /* New vertex */
- unique_v = scn->nuverts + actual_nuverts;
- ASSERT(unique_v == htable_vrtx_size_get(&scn->unique_vertices));
- OK(darray_position_push_back(&scn->vertices, &tmp));
- OK(htable_vrtx_set(&scn->unique_vertices, &tmp, &unique_v));
- ++actual_nuverts;
+ log_err(scn->dev, "%s: vertex %u is a duplicate.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
}
- /* The unique ID for vertex i is unique_v */
- ASSERT(i == darray_vrtx_id_size_get(&unique_vertice_ids));
- OK(darray_vrtx_id_push_back(&unique_vertice_ids, &unique_v));
- ++actual_nverts;
+ /* New vertex */
+ ASSERT(i == htable_vrtx_size_get(&unique_vertices));
+ OK(darray_position_push_back(&scn->vertices, &tmp));
+ OK(htable_vrtx_set(&unique_vertices, &tmp, &i));
}
-
+ /* Get triangles */
FOR_EACH(i, 0, ntris) {
int j;
unsigned med[2] = { SENC_UNDEFINED_MEDIUM, SENC_UNDEFINED_MEDIUM };
unsigned ind[3];
union vrtx_id3 trg_key;
- struct triangle_in tmp, *range_adjust_ptr = NULL;
+ struct triangle_in tmp;
trg_id_t* p_trg;
- char reversed;
- /* Triangle index in user world regardless of deduplication. */
- tmp.global_id = (unsigned)(scn->ntris + i);
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] < darray_vrtx_id_size_get(&unique_vertice_ids));
- /* Find the unique ID for this vertex */
- tmp.vertice_id[j] = darray_vrtx_id_cdata_get(&unique_vertice_ids)[ind[j]];
+ ASSERT(ind[j] <= VRTX_MAX__);
+ tmp.vertice_id[j] = (vrtx_id_t)ind[j];
}
if(tmp.vertice_id[0] == tmp.vertice_id[1]
|| tmp.vertice_id[0] == tmp.vertice_id[2]
- || tmp.vertice_id[1] == tmp.vertice_id[2]) {
- const union double3* positions
- = darray_position_cdata_get(&scn->vertices);
- log_err(scn->dev, "%s: triangle %lu is degenerate.\n",
- FUNC_NAME, (unsigned long)tmp.global_id);
- log_err(scn->dev, " (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
- SPLIT3(positions[trg[i].vertice_id[0]].vec),
- SPLIT3(positions[trg[i].vertice_id[1]].vec),
- SPLIT3(positions[trg[i].vertice_id[2]].vec));
+ || 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 */
- FOR_EACH(j, 0, 2) {
- if(med[j] != SENC_UNDEFINED_MEDIUM && med[j] >= scn->next_medium_idx) {
- ASSERT(med[j] < MEDIUM_MAX__);
- scn->next_medium_idx = med[j] + 1;
- darray_side_range_resize(&scn->media_use, scn->next_medium_idx);
- }
- tmp.medium[j] = (medium_id_t)med[j];
- }
- /* Find duplicate triangles */
- reversed = trg_make_key(&trg_key, tmp.vertice_id);
- p_trg = htable_trg_find(&scn->unique_triangles, &trg_key);
+ trg_make_key(&trg_key, tmp.vertice_id);
+ p_trg = htable_trg_find(&unique_triangles, &trg_key);
if(p_trg) {
- /* Duplicate triangle. Need to check duplicate validity */
- union vrtx_id3 utrg_key;
- char ureversed = trg_make_key(&utrg_key, trg[*p_trg].vertice_id);
- int same = (reversed == ureversed);
- const medium_id_t* umed;
- ASSERT(trg_key_eq(&trg_key, &utrg_key));
- if(!same) SWAP(unsigned, tmp.medium[0], tmp.medium[1]);
- umed = trg[*p_trg].medium;
- if(merge_triangle) {
- /* Let the client app rule. */
- unsigned smed[2], mmed[2];
- FOR_EACH(j, 0, 2) {
- smed[j] = (unsigned)umed[j];
- mmed[j] = (unsigned)tmp.medium[j];
- }
- OK(merge_triangle(trg[*p_trg].global_id, i, same, smed, mmed, ctx));
- /* If merge_triangle returns OK its OK even if media are incompatible. */
- } else {
- if(!compatible_medium(umed[0], tmp.medium[0])
- || !compatible_medium(umed[1], tmp.medium[1]))
- {
- res = RES_BAD_ARG;
- goto error;
- }
- }
- /* Legit duplicate (or accepted by merge_triangle): replace undef media. */
- range_adjust_ptr = darray_triangle_in_data_get(&scn->triangles_in) + *p_trg;
- /* Replace possible undefined media */
- FOR_EACH(j, 0, 2) {
- if(range_adjust_ptr->medium[j] == SENC_UNDEFINED_MEDIUM
- && tmp.medium[j] != SENC_UNDEFINED_MEDIUM) {
- range_adjust_ptr->medium[j] = tmp.medium[j];
- scn->sides_with_defined_medium_count++;
- }
- }
- } else {
- /* New triangle */
- trg_id_t u = scn->nutris + actual_nutris;
- if (add_triangle)
- OK(add_triangle(tmp.global_id, i, ctx));
- OK(darray_triangle_in_push_back(&scn->triangles_in, &tmp));
- range_adjust_ptr = darray_triangle_in_data_get(&scn->triangles_in) + u;
- FOR_EACH(j, 0, 2) {
- if(tmp.medium[j] != SENC_UNDEFINED_MEDIUM)
- scn->sides_with_defined_medium_count++;
- }
- ASSERT(u == htable_trg_size_get(&scn->unique_triangles));
- OK(htable_trg_set(&scn->unique_triangles, &trg_key, &u));
- ++actual_nutris;
+ /* Duplicate triangle */
+ log_err(scn->dev, "%s: triangle %u is a duplicate.\n",
+ FUNC_NAME, i);
+ res = RES_BAD_ARG;
+ goto error;
}
- if(range_adjust_ptr) {
- ptrdiff_t u = range_adjust_ptr - trg;
- ASSERT(u < scn->nutris + actual_nutris && u < TRG_MAX__);
- FOR_EACH(j, 0, 2) {
- struct side_range* media_use;
- if(tmp.medium[j] == SENC_UNDEFINED_MEDIUM) continue;
- ASSERT(tmp.medium[j] < scn->next_medium_idx);
- media_use = darray_side_range_data_get(&scn->media_use) + tmp.medium[j];
- media_use->first =
- MMIN(media_use->first, TRGIDxSIDE_2_TRGSIDE((trg_id_t)u, j));
- ASSERT(media_use->first < 2 * (scn->nutris + actual_nutris + 1));
- media_use->last =
- MMAX(media_use->last, TRGIDxSIDE_2_TRGSIDE((trg_id_t)u, j));
- ASSERT(media_use->last < 2 * (scn->nutris + actual_nutris + 1));
- ASSERT(media_use->first <= media_use->last);
+ /* 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_UNDEFINED_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_UNDEFINED_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);
}
- ++actual_ntris;
+ 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 undef */
+ /* Proceed to the analyze */
+ OK(scene_analyze(scn));
+
exit:
- darray_vrtx_id_release(&unique_vertice_ids);
- /* Update sizes */
- scn->nuverts += actual_nuverts;
- scn->nverts += actual_nverts;
- scn->nutris += actual_nutris;
- scn->ntris += actual_ntris;
- ASSERT(scn->nuverts == htable_vrtx_size_get(&scn->unique_vertices));
- ASSERT(scn->nutris == htable_trg_size_get(&scn->unique_triangles));
+ 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;
}
@@ -328,7 +233,6 @@ senc_scene_get_convention
if(!scn || !convention) return RES_BAD_ARG;
*convention = scn->convention;
return RES_OK;
-
}
res_T
@@ -342,28 +246,7 @@ senc_scene_get_triangles_count
}
res_T
-senc_scene_get_unique_triangles_count
- (const struct senc_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- *count = scn->nutris;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_unique_sides_without_medium_count
- (const struct senc_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- ASSERT(2 * scn->nutris >= scn->sides_with_defined_medium_count);
- *count = 2 * scn->nutris - scn->sides_with_defined_medium_count;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_unique_triangle
+senc_scene_get_triangle
(const struct senc_scene* scn,
const unsigned itri,
unsigned indices[3])
@@ -383,7 +266,7 @@ senc_scene_get_unique_triangle
}
res_T
-senc_scene_get_unique_triangle_media
+senc_scene_get_triangle_media
(const struct senc_scene* scn,
const unsigned itri,
unsigned media[2])
@@ -413,17 +296,7 @@ senc_scene_get_vertices_count
}
res_T
-senc_scene_get_unique_vertices_count
- (const struct senc_scene* scn,
- unsigned* count)
-{
- if(!scn || !count) return RES_BAD_ARG;
- *count = scn->nuverts;
- return RES_OK;
-}
-
-res_T
-senc_scene_get_unique_vertex
+senc_scene_get_vertex
(const struct senc_scene* scn,
const unsigned ivert,
double coord[3])
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -130,7 +130,7 @@ self_hit_filter
static void
extract_connex_components
- (struct senc_descriptor* desc,
+ (struct senc_scene* scn,
struct trgside* trgsides,
struct darray_ptr_component_descriptor* connex_components,
const struct darray_triangle_tmp* triangles_tmp_array,
@@ -143,9 +143,8 @@ extract_connex_components
{
/* This function is called from an omp parallel block and executed
* concurrently. */
- struct senc_scene* scn;
struct mem_allocator* alloc;
- int64_t mm, undefs;
+ int64_t m_idx;
struct darray_side_id stack;
struct darray_side_id ids_of_sides_around_max_z_vertex;
const union double3* positions;
@@ -159,51 +158,38 @@ extract_connex_components
unsigned char* current_media = NULL;
size_t sz, ii;
- ASSERT(trgsides && desc && connex_components && triangles_tmp_array
+ ASSERT(scn && trgsides && connex_components && triangles_tmp_array
&& triangles_comp_array && s3d_view && component_count && p_res);
- alloc = descriptor_get_allocator(desc);
- scn = desc->scene;
+ 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->nutris, sizeof(unsigned char));
+ processed = MEM_CALLOC(alloc, scn->ntris, sizeof(unsigned char));
if(!processed) {
*p_res = RES_MEM_ERR;
return;
}
- /* If there are sides with undefined medium, its like another medium */
- undefs = (scn->sides_with_defined_medium_count < 2 * scn->nutris) ? 1 : 0;
- #pragma omp single
- {
- if(undefs) {
- /* Range is unknown, process each side */
- struct side_range und;
- und.first = 0;
- und.last = 2 * scn->nutris - 1;
- darray_side_range_push_back(&scn->media_use, &und);
- }
- } /* Implicit barrier here */
-
#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->nutris) {
+ 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(mm, 0, 2) {
- const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, mm);
- medium_id_t medium = trg_in->medium[mm];
- if(medium == SENC_UNDEFINED_MEDIUM) medium = scn->next_medium_idx;
- ASSERT(media_use[medium].first <= side && side
- <= media_use[medium].last);
+ FOR_EACH(s, 0, 2) {
+ const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, s);
+ medium_id_t medium = trg_in->medium[s];
+ m_idx = (medium == SENC_UNDEFINED_MEDIUM) ? 0 : medium + 1;
+ ASSERT(media_use[m_idx].first <= side && side
+ <= media_use[m_idx].last);
}
}
} /* Implicit barrier here */
@@ -212,13 +198,12 @@ extract_connex_components
/* We loop on sides to build connex components. */
#pragma omp for schedule(dynamic) nowait
/* Process all media, including undef */
- for(mm = 0; mm < undefs + (int64_t)scn->next_medium_idx; mm++) {
- const medium_id_t m_idx = (medium_id_t)mm;
- const medium_id_t m = (mm == scn->next_medium_idx)
- ? SENC_UNDEFINED_MEDIUM : (medium_id_t)mm;
- /* Any not-already-used side is used as a starting point */
+ for(m_idx = 0; m_idx < 1 + (int64_t)scn->next_medium_idx; m_idx++) {
+ const medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC_UNDEFINED_MEDIUM;
+ /* media_use 0 is for SENC_UNDEFINED_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__;
@@ -230,19 +215,19 @@ extract_connex_components
if(*p_res != RES_OK) continue;
if(first_side_not_in_component == SIDE_NULL__)
continue; /* Unused medium */
- ASSERT(first_side_not_in_component < 2 * scn->nutris);
+ 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, m);
+ (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->nutris);
+ ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->ntris);
darray_side_id_clear(¤t_component);
if(*p_res != RES_OK) break;
@@ -254,16 +239,18 @@ extract_connex_components
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(&desc->scene->triangles_in)[tid].medium[s];
- ASSERT(side_med == m);
+ = 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) {
- memset(current_media, 0, 1 + scn->next_medium_idx); /* +1 for possible undef */
+ /* current_media 0 is for SENC_UNDEFINED_MEDIUM, n+1 is for n */
+ memset(current_media, 0, 1 + scn->next_medium_idx);
} else {
- current_media = MEM_CALLOC(alloc, 1 + scn->next_medium_idx, sizeof(unsigned char));
+ current_media = MEM_CALLOC(alloc, 1 + scn->next_medium_idx,
+ sizeof(*current_media));
if(!current_media) {
*p_res = RES_MEM_ERR;
continue;
@@ -279,7 +266,7 @@ extract_connex_components
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->nutris);
+ ASSERT(crt_trg_id < scn->ntris);
if(*p_res != RES_OK) break;
@@ -331,8 +318,8 @@ extract_connex_components
unsigned char* nbour_used = processed + nbour_trg_id;
const struct trgside* neighbour = trgsides + neighbour_id;
medium_id_t nbour_med_idx = (neighbour->medium == SENC_UNDEFINED_MEDIUM)
- ? scn->next_medium_idx : neighbour->medium;
- if(neighbour->medium < m
+ ? 0 : neighbour->medium + 1;
+ if(neighbour->medium < medium
|| (*nbour_used & SIDE_CANCELED_FLAG(nbour_side_id)))
{
/* 1) Not the same medium.
@@ -384,7 +371,7 @@ extract_connex_components
if(!cc) *p_res = RES_MEM_ERR;
if(*p_res != RES_OK) break;
- ASSERT(m == trgsides[start_side_id].medium);
+ 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;
@@ -411,7 +398,7 @@ extract_connex_components
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 >= m);
+ ASSERT(trgsides[s].medium >= medium);
cmp[sid] = cc->cc_id;
}
@@ -507,16 +494,16 @@ extract_connex_components
attribs.get = get_scn_position;
/* Put geometry in a 3D view */
- OK(s3d_device_create(desc->scene->dev->logger, alloc, 0, &s3d));
+ 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(desc->scene->nutris < UINT_MAX);
- ASSERT(desc->scene->nuverts < UINT_MAX);
+ ASSERT(scn->ntris < UINT_MAX);
+ ASSERT(scn->nverts < UINT_MAX);
OK(s3d_mesh_setup_indexed_vertices(s3d_shp,
- (unsigned)desc->scene->nutris, get_scn_indices,
- (unsigned)desc->scene->nuverts, &attribs, 1, scn));
+ (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));
@@ -538,7 +525,7 @@ extract_connex_components
component_id_t c;
ASSERT(ATOMIC_GET(component_count) ==
(int)darray_ptr_component_descriptor_size_get(connex_components));
- FOR_EACH(t_, 0, scn->nutris) {
+ 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__);
@@ -549,14 +536,13 @@ extract_connex_components
darray_ptr_component_descriptor_data_get(connex_components);
ASSERT(components[c] != NULL && components[c]->cc_id == c);
}
- ASSERT(desc->triangle_count == scn->nutris);
} /* Implicit barrier here */
#endif
}
static void
group_connex_components
- (struct senc_descriptor* desc,
+ (struct senc_scene* scn,
struct trgside* trgsides,
struct darray_triangle_comp* triangles_comp,
struct darray_ptr_component_descriptor* connex_components,
@@ -575,15 +561,15 @@ group_connex_components
int64_t ccc;
(void)trgsides;
- ASSERT(desc && trgsides && triangles_comp && connex_components
+ ASSERT(scn && trgsides && triangles_comp && connex_components
&& s3d_view && next_enclosure_id && res);
- ASSERT(desc->enclosures_count == 1);
+ ASSERT(scn->analyze.enclosures_count == 1);
descriptors = darray_ptr_component_descriptor_data_get(connex_components);
tmp = darray_ptr_component_descriptor_size_get(connex_components);
ASSERT(tmp <= COMPONENT_MAX__);
cc_count = (component_id_t)tmp;
- positions = darray_position_cdata_get(&desc->scene->vertices);
+ positions = darray_position_cdata_get(&scn->vertices);
/* Cast rays to find links between connex components */
#pragma omp for
@@ -601,7 +587,7 @@ group_connex_components
if(*res != RES_OK) continue;
ASSERT(cc->cc_id == c);
ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
- ASSERT(cc->max_z_vrtx_id < desc->scene->nverts);
+ ASSERT(cc->max_z_vrtx_id < scn->nverts);
max_vrtx = positions[cc->max_z_vrtx_id].vec;
if(cc->is_outer_border) {
@@ -633,13 +619,13 @@ group_connex_components
darray_triangle_comp_cdata_get(triangles_comp) + hit_trg_id;
enum senc_side hit_side =
((hit.normal[2] < 0) /* Facing geometrical normal of hit */
- == ((desc->scene->convention & SENC_CONVENTION_NORMAL_FRONT) != 0))
+ == ((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 < desc->scene->nutris);
+ ASSERT(hit_trg_id < scn->ntris);
/* Not really the root until following links */
cc->cc_group_root = hit_trg_comp->component[hit_side];
@@ -654,13 +640,14 @@ group_connex_components
#pragma omp single
{
res_T tmp_res = RES_OK;
- desc->enclosures_count = (enclosure_id_t)ATOMIC_GET(next_enclosure_id);
- tmp_res = darray_enclosure_resize(&desc->enclosures, desc->enclosures_count);
+ scn->analyze.enclosures_count = (enclosure_id_t)ATOMIC_GET(next_enclosure_id);
+ tmp_res = darray_enclosure_resize(&scn->analyze.enclosures,
+ scn->analyze.enclosures_count);
if(tmp_res != RES_OK) {
*res = tmp_res;
} else {
struct enclosure_data* enclosures
- = darray_enclosure_data_get(&desc->enclosures);
+ = darray_enclosure_data_get(&scn->analyze.enclosures);
FOR_EACH(ccc, 0, cc_count) {
component_id_t c = (component_id_t)ccc;
struct cc_descriptor* const cc = descriptors[c];
@@ -688,7 +675,7 @@ group_connex_components
enc->side_range.last = MMAX(enc->side_range.last, cc->side_range.last);
enc->side_count += cc->side_count;
tmp_res = bool_array_of_media_merge(&enc->tmp_enclosed_media, cc->media,
- desc->scene->next_medium_idx + 1);
+ scn->next_medium_idx + 1);
if(tmp_res != RES_OK) {
*res = tmp_res;
break;
@@ -731,7 +718,7 @@ collect_and_link_neighbours
res_T tmp_res;
ASSERT(scn && trgsides && triangles_tmp_array && frontiers && res);
- ASSERT((size_t)scn->nuverts + (size_t)scn->nutris + 2 <= EDGE_MAX__);
+ 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);
@@ -740,18 +727,18 @@ collect_and_link_neighbours
triangles_tmp = darray_triangle_tmp_data_get(triangles_tmp_array);
vertices = darray_position_cdata_get(&scn->vertices);
- ASSERT(scn->nutris == darray_triangle_tmp_size_get(triangles_tmp_array));
+ 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->nuverts + scn->nutris)
- : (edge_id_t)((scn->nuverts + scn->nutris) / (0.75 * thread_count)));
+ ? (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->nutris) {
+ FOR_EACH(t, 0, scn->ntris) {
struct trg_edge edge;
unsigned char ee;
FOR_EACH(ee, 0, 3) {
@@ -912,9 +899,8 @@ collect_and_link_neighbours
previous = darray_neighbour_cdata_get(neighbour_list) + i - 1;
prev_id = previous->trg_id;
log_err(scn->dev,
- "%s: found 2 overlying triangles (%lu & %lu).\n", FUNC_NAME,
- (unsigned long)triangles_in[crt_id].global_id,
- (unsigned long)triangles_in[prev_id].global_id);
+ "%s: found 2 overlying triangles (%u & %u).\n", FUNC_NAME,
+ (unsigned)crt_id, (unsigned)prev_id);
tmp_res = RES_BAD_OP;
goto tmp_error;
}
@@ -945,7 +931,7 @@ collect_and_link_neighbours
struct trg_edge disc;
log_warn(scn->dev,
"%s: found frontier involving triangle %lu.\n",
- FUNC_NAME, (unsigned long)triangles_in[crt_id].global_id);
+ FUNC_NAME, (unsigned)crt_id);
disc.vrtx0 = v0;
disc.vrtx1 = v1;
darray_frontier_edge_push_back(frontiers, &disc);
@@ -961,7 +947,7 @@ tmp_error:
static void
build_result
- (struct senc_descriptor* desc,
+ (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,
@@ -978,15 +964,13 @@ build_result
struct triangle_enc* triangles_enc;
const struct triangle_comp* triangles_comp;
struct htable_vrtx_id vtable;
- struct senc_scene* scn;
int output_normal_in, normals_front, normals_back;
int64_t tt;
int64_t ee;
- ASSERT(desc && connex_components && triangles_comp_array && frontiers && res);
+ ASSERT(scn && connex_components && triangles_comp_array && frontiers && res);
- alloc = descriptor_get_allocator(desc);
- scn = desc->scene;
+ 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;
@@ -996,22 +980,22 @@ build_result
ASSERT(darray_ptr_component_descriptor_size_get(connex_components)
<= COMPONENT_MAX__);
cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components);
- enclosures = darray_enclosure_data_get(&desc->enclosures);
+ enclosures = darray_enclosure_data_get(&scn->analyze.enclosures);
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(&desc->triangles_enc, scn->nutris);
+ 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(&desc->triangles_enc);
+ 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->nutris; tt++) {
+ 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];
@@ -1030,9 +1014,9 @@ build_result
* openmp block as a given enclosure is processed by a single thread */
htable_vrtx_id_init(alloc, &vtable);
- ASSERT(desc->enclosures_count <= ENCLOSURE_MAX__);
+ ASSERT(scn->analyze.enclosures_count <= ENCLOSURE_MAX__);
#pragma omp for schedule(dynamic) nowait
- for(ee = 0; ee < (int64_t)desc->enclosures_count; ee++) {
+ for(ee = 0; ee < (int64_t)scn->analyze.enclosures_count; ee++) {
const enclosure_id_t e = (enclosure_id_t)ee;
struct enclosure_data* enc = enclosures + e;
trg_id_t fst_idx = 0;
@@ -1062,18 +1046,17 @@ build_result
/* Add this enclosure in relevant by-medium lists */
FOR_EACH(m, 0, enc->header.enclosed_media_count) {
- medium_id_t medium = darray_media_data_get(&enc->enclosed_media)[m];
- size_t m_idx = (medium == SENC_UNDEFINED_MEDIUM)
- ? scn->next_medium_idx : medium;
- struct darray_enc_id* enc_ids_by_medium;
+ medium_id_t medium = darray_media_cdata_get(&enc->enclosed_media)[m];
+ unsigned m_idx = (medium == SENC_UNDEFINED_MEDIUM) ? 0 : medium + 1;
+ struct darray_enc_id* enc_ids_array_by_medium;
ASSERT(medium == SENC_UNDEFINED_MEDIUM || medium < scn->next_medium_idx);
- ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
== 1 + scn->next_medium_idx);
- enc_ids_by_medium =
- darray_enc_ids_array_data_get(&desc->enc_ids_array_by_medium) + m_idx;
+ enc_ids_array_by_medium =
+ darray_enc_ids_array_data_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
#pragma omp critical
{
- tmp_res = darray_enc_id_push_back(enc_ids_by_medium, &e);
+ tmp_res = darray_enc_id_push_back(enc_ids_array_by_medium, &e);
}
if(tmp_res != RES_OK) {
*res = tmp_res;
@@ -1089,7 +1072,7 @@ build_result
(size_t)(enc->side_count * 0.6)));
/* New vertex numbering scheme local to the enclosure */
htable_vrtx_id_clear(&vtable);
- ASSERT(scn->nutris == darray_triangle_in_size_get(&scn->triangles_in));
+ 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);
@@ -1133,7 +1116,7 @@ build_result
int ii = revert_triangle ? 2 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(trg_in->global_id, SENC_FRONT);
+ 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 */
@@ -1147,7 +1130,7 @@ build_result
int ii = revert_triangle ? 2 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(trg_in->global_id, SENC_BACK);
+ side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_BACK);
}
if(fst_idx == sgd_idx) break;
}
@@ -1159,7 +1142,7 @@ build_result
htable_vrtx_id_release(&vtable);
/* The first thread here copies frontiers into descriptor */
#pragma omp single nowait
- darray_frontier_edge_copy_and_clear(&desc->frontiers, frontiers);
+ darray_frontier_edge_copy_and_clear(&scn->analyze.frontiers, frontiers);
/* No barrier here */
}
@@ -1167,11 +1150,9 @@ build_result
* Exported functions
******************************************************************************/
res_T
-senc_scene_analyze
- (struct senc_scene* scn,
- struct senc_descriptor** out_desc)
+scene_analyze
+ (struct senc_scene* scn)
{
- struct senc_descriptor* desc = NULL;
/* By triangle tmp data */
struct darray_triangle_tmp triangles_tmp;
char triangles_tmp_initialized = 0;
@@ -1194,24 +1175,18 @@ senc_scene_analyze
res_T res = RES_OK;
res_T res2 = RES_OK;
- if(!scn || !out_desc) return RES_BAD_ARG;
-
- desc = descriptor_create(scn);
- if(!desc) {
- res = RES_MEM_ERR;
- goto error;
- }
+ if(!scn) return RES_BAD_ARG;
- if(!scn->nutris) goto exit;
+ 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->nutris));
+ OK(darray_triangle_tmp_resize(&triangles_tmp, scn->ntris));
trgsides
- = MEM_CALLOC(scn->dev->allocator, 2 * scn->nutris, sizeof(struct trgside));
+ = MEM_CALLOC(scn->dev->allocator, 2 * scn->ntris, sizeof(struct trgside));
if(!trgsides) {
res = RES_MEM_ERR;
goto error;
@@ -1220,7 +1195,7 @@ senc_scene_analyze
else {
/* Initialise trgsides to allow assert code */
size_t i;
- FOR_EACH(i, 0, 2 * scn->nutris)
+ FOR_EACH(i, 0, 2 * scn->ntris)
init_trgside(scn->dev->allocator, trgsides + i);
}
#endif
@@ -1249,7 +1224,7 @@ senc_scene_analyze
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->nutris));
+ OK2(darray_triangle_comp_resize(&triangles_comp, scn->ntris));
tmp_error:
if(tmp_res != RES_OK) res2 = tmp_res;
}
@@ -1269,7 +1244,7 @@ senc_scene_analyze
}
/* Step 2: extract triangle connex components */
- extract_connex_components(desc, trgsides, &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
@@ -1296,7 +1271,7 @@ senc_scene_analyze
} /* No barrier here */
/* Step 3: group components */
- group_connex_components(desc, trgsides, &triangles_comp,
+ 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 */
@@ -1319,7 +1294,7 @@ senc_scene_analyze
} /* No barrier here */
/* Step 4: Build result */
- build_result(desc, &connex_components, &triangles_comp, &frontiers, &res);
+ 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 */
@@ -1364,11 +1339,8 @@ exit:
if(frontiers_initialized)
darray_frontier_edge_release(&frontiers);
if(trgsides) MEM_RM(scn->dev->allocator, trgsides);
- if(desc) *out_desc = desc;
return res;
error:
- if(desc) SENC(descriptor_ref_put(desc));
- desc = NULL;
goto exit;
}
diff --git a/src/senc_scene_analyze_c.h b/src/senc_scene_analyze_c.h
@@ -16,14 +16,15 @@
#ifndef SENC_SCNENE_ANALYZE_C_H
#define SENC_SCNENE_ANALYZE_C_H
-#include "senc_scene_c.h"
#include "senc_internal_types.h"
-#include "senc_descriptor_c.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)
{
@@ -194,4 +195,7 @@ neighbourhood_copy_and_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
@@ -13,21 +13,118 @@
* 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_C_H
-#define SENC_SCNENE_C_H
+#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;
-#define HTABLE_NAME vrtx_id
-#define HTABLE_KEY vrtx_id_t
-#define HTABLE_DATA vrtx_id_t
-#include <rsys/hash_table.h>
+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 {
@@ -48,8 +145,6 @@ struct triangle_in {
vrtx_id_t vertice_id[3];
/* Ids of this triangle's media */
medium_id_t medium[2];
- /* Triangle index in user world regardless of deduplication. */
- unsigned global_id;
};
static FINLINE void
@@ -59,7 +154,6 @@ triangle_in_init(struct mem_allocator* alloc, struct triangle_in* trg) {
ASSERT(trg);
FOR_EACH(i, 0, 3) trg->vertice_id[i] = VRTX_NULL__;
FOR_EACH(i, 0, 2) trg->medium[i] = SENC_UNDEFINED_MEDIUM;
- trg->global_id = 0;
}
#define DARRAY_NAME triangle_in
@@ -95,10 +189,6 @@ vrtx_eq(const union double3* v1, const union double3* v2)
#define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
#include <rsys/hash_table.h>
-#define DARRAY_NAME vrtx_id
-#define DARRAY_DATA vrtx_id_t
-#include <rsys/dynamic_array.h>
-
union vrtx_id3 {
struct {
vrtx_id_t v0, v1, v2;
@@ -177,51 +267,37 @@ trg_key_eq(const union vrtx_id3* k1, const union vrtx_id3* k2)
#define HTABLE_KEY_FUNCTOR_EQ trg_key_eq
#include <rsys/hash_table.h>
-struct side_range {
- side_id_t first, last;
+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;
};
-static FINLINE void
-side_range_init(struct mem_allocator* alloc, struct side_range* data)
-{
- ASSERT(data);
- (void)alloc;
- data->first = SIDE_NULL__;
- data->last = 0;
-}
-#define DARRAY_NAME side_range
-#define DARRAY_DATA struct side_range
-#define DARRAY_FUNCTOR_INIT side_range_init
-#include <rsys/dynamic_array.h>
struct senc_scene {
/* Front / Back sides convention */
int convention;
-
- /* Triangle information as given by user; no duplicates here */
+ /* Triangle information as given by user */
struct darray_triangle_in triangles_in;
-
- /* Vertex information as given by user; no duplicates here */
+ /* Vertex information as given by user */
struct darray_position vertices;
-
- /* Htables used to detect duplicate vertices.
- * As we rely on edges (i.e. vertice IDs) to build
- * neighbourhoods, we need vertice unicity. */
- /* Keep each unique vertex; no duplicates here. */
- struct htable_vrtx unique_vertices;
-
- /* Htables used to detect duplicate triangles. */
- /* Keep each unique triangle; no duplicates here. */
- struct htable_trg unique_triangles;
/* Keep sizes */
- trg_id_t ntris, nutris; /* Trg count, unique trg count */
- vrtx_id_t nverts, nuverts; /* Vrtx count, unique vrtx count */
+ trg_id_t ntris; /* Trg count */
+ vrtx_id_t nverts; /* Vrtx count */
medium_id_t next_medium_idx;
+ /* media_use 0 is for SENC_UNDEFINED_MEDIUM, n+1 is for n */
struct darray_side_range media_use;
- side_id_t sides_with_defined_medium_count;
+
+ /* The descriptor of the analyze */
+ struct descriptor analyze;
ref_T ref;
struct senc_device* dev;
};
-#endif /* SENC_SCNENE_C_H */
+#endif /* SENC_SCENE_C_H */
diff --git a/src/senc_side_range.h b/src/senc_side_range.h
@@ -0,0 +1,44 @@
+/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#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_senc_add_n_merge.c b/src/test_senc_add_n_merge.c
@@ -60,7 +60,7 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i;
struct add_geom_ctx add_geom_ctx;
unsigned media[12];
diff --git a/src/test_senc_cube_behind_cube.c b/src/test_senc_cube_behind_cube.c
@@ -18,99 +18,256 @@
#include <rsys/double3.h>
+ /* Dump of star-geometry 'cube_behind_cube_2'. */
+static const double cube_behind_cube_2_vertices[48] =
+{
+ 0.100000, 0.000000, 0.000000,
+ 1.000000, 0.000000, 0.000000,
+ 0.000000, 1.000000, 0.000000,
+ 1.000000, 1.000000, 0.000000,
+ 0.000000, 0.000000, 1.100000,
+ 1.000000, 0.000000, 1.000000,
+ 0.000000, 1.000000, 1.000000,
+ 1.000000, 1.100000, 1.000000,
+ -1.500000, -2.000000, 20.000000,
+ 3.000000, -2.000000, 20.000000,
+ -2.000000, 3.000000, 20.000000,
+ 3.000000, 3.000000, 20.000000,
+ -2.000000, -2.000000, 25.500000,
+ 3.000000, -2.000000, 25.000000,
+ -2.000000, 3.000000, 25.000000,
+ 3.000000, 3.500000, 25.000000
+};
+static const unsigned cube_behind_cube_2_vertices_count = 16;
+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_triangles_count = 24;
+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 double cube_behind_cube_3_vertices[72] =
+{
+ 0.100000, 0.000000, 0.000000,
+ 1.000000, 0.000000, 0.000000,
+ 0.000000, 1.000000, 0.000000,
+ 1.000000, 1.000000, 0.000000,
+ 0.000000, 0.000000, 1.100000,
+ 1.000000, 0.000000, 1.000000,
+ 0.000000, 1.000000, 1.000000,
+ 1.000000, 1.100000, 1.000000,
+ -1.500000, -2.000000, 20.000000,
+ 3.000000, -2.000000, 20.000000,
+ -2.000000, 3.000000, 20.000000,
+ 3.000000, 3.000000, 20.000000,
+ -2.000000, -2.000000, 25.500000,
+ 3.000000, -2.000000, 25.000000,
+ -2.000000, 3.000000, 25.000000,
+ 3.000000, 3.500000, 25.000000,
+ -2.300000, -3.000000, 30.000000,
+ 4.000000, -3.000000, 30.000000,
+ -3.000000, 4.000000, 30.000000,
+ 4.000000, 4.000000, 30.000000,
+ -3.000000, -3.000000, 37.700000,
+ 4.000000, -3.000000, 37.000000,
+ -3.000000, 4.000000, 37.000000,
+ 4.000000, 4.700000, 37.000000
+};
+static const unsigned cube_behind_cube_3_vertices_count = 24;
+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_triangles_count = 36;
+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
+};
+
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, ecount, maxm;
(void)argc, (void)argv;
CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
CHK(senc_device_create
- (NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK);
+ (NULL, &allocator, 1, 1, &dev) == RES_OK);
- /* Create the scene */
+ /* Create a scene with the first and second cubes */
+ ctx.positions = cube_behind_cube_2_vertices;
+ ctx.indices = cube_behind_cube_2_triangles;
+ ctx.properties = cube_behind_cube_2_properties;
CHK(senc_scene_create(dev,
- SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK);
-
- ctx.positions = box_vertices;
- ctx.indices = box_indices;
- ctx.scale = 1;
- ctx.reverse_vrtx = 0;
- ctx.reverse_med = 0;
- d3(ctx.offset, 0, 0, 0);
- ctx.front_media = medium0;
- ctx.back_media = medium1;
-
- /* First cube */
- CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- /* +Z from the first cube,
- * big enough to prevent rays from the first cube to miss this one */
- d3(ctx.offset, -2, -2, 20);
- ctx.scale = 5;
-
- /* Second cube */
- CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
-
- CHK(senc_scene_analyze(scn, &desc) == RES_OK);
-
- CHK(senc_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ 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) == RES_OK);
+
+ CHK(senc_scene_get_enclosure_count(scn, &ecount) == RES_OK);
CHK(ecount == 3);
FOR_EACH(i, 0, ecount) {
struct senc_enclosure* enclosure;
struct senc_enclosure_header header;
- CHK(senc_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
+ CHK(senc_scene_get_enclosure(scn, i, &enclosure) == RES_OK);
CHK(senc_enclosure_get_header(enclosure, &header) == RES_OK);
ASSERT(header.enclosed_media_count == 1);
CHK(senc_enclosure_ref_put(enclosure) == RES_OK);
}
- CHK(senc_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ CHK(senc_scene_get_max_medium(scn, &maxm) == RES_OK);
CHK(maxm == 1);
- check_desc(desc);
-
- /* Even further in +Z, even bigger */
- d3(ctx.offset, -3, -3, 30);
- ctx.scale = 7;
- /* Front/back media have been exchanged: external enclosure shows 2 media */
- ctx.front_media = medium1;
- ctx.back_media = medium0;
-
- /* Third cube */
- CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
- nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
+ CHK(senc_scene_ref_put(scn) == RES_OK);
- if(desc) CHK(senc_descriptor_ref_put(desc) == RES_OK);
- desc = NULL;
- CHK(senc_scene_analyze(scn, &desc) == RES_OK);
+ /* Create a scene with the 3 cubes */
+ ctx.positions = cube_behind_cube_3_vertices;
+ ctx.indices = cube_behind_cube_3_triangles;
+ ctx.properties = cube_behind_cube_3_properties;
+ CHK(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) == RES_OK);
- CHK(senc_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
+ CHK(senc_scene_get_enclosure_count(scn, &ecount) == RES_OK);
CHK(ecount == 4);
FOR_EACH(i, 0, ecount) {
struct senc_enclosure* enclosure;
struct senc_enclosure_header header;
- CHK(senc_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK);
+ CHK(senc_scene_get_enclosure(scn, i, &enclosure) == RES_OK);
CHK(senc_enclosure_get_header(enclosure, &header) == RES_OK);
ASSERT(header.enclosed_media_count == (header.is_infinite ? 2u : 1u));
CHK(senc_enclosure_ref_put(enclosure) == RES_OK);
}
- CHK(senc_descriptor_get_max_medium(desc, &maxm) == RES_OK);
+ CHK(senc_scene_get_max_medium(scn, &maxm) == RES_OK);
CHK(maxm == 1);
- check_desc(desc);
CHK(senc_scene_ref_put(scn) == RES_OK);
CHK(senc_device_ref_put(dev) == RES_OK);
- if(desc) CHK(senc_descriptor_ref_put(desc) == RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_senc_cube_in_cube.c b/src/test_senc_cube_in_cube.c
@@ -22,10 +22,10 @@ int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, ecount, maxm;
(void)argc, (void)argv;
diff --git a/src/test_senc_cube_on_cube.c b/src/test_senc_cube_on_cube.c
@@ -45,10 +45,10 @@ int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned count, i;
(void)argc, (void)argv;
@@ -107,10 +107,10 @@ main(int argc, char** argv)
CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK);
CHK(count == 4);
- CHK(senc_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_vertices_count(desc, &count) == RES_OK);
CHK(count == 20);
- CHK(senc_descriptor_get_global_triangles_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_triangles_count(desc, &count) == RES_OK);
CHK(count == 34);
CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK);
diff --git a/src/test_senc_descriptor.c b/src/test_senc_descriptor.c
@@ -25,9 +25,9 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_enclosure* enc = NULL;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned count, maxm;
unsigned indices[3];
double coord[3];
@@ -115,61 +115,61 @@ main(int argc, char** argv)
CHK(senc_descriptor_get_enclosure_by_medium(NULL, 9, 9, NULL) == RES_BAD_ARG);
CHK(senc_descriptor_get_enclosure_by_medium(desc, 0, 0, &enc) == RES_OK);
- CHK(senc_descriptor_get_global_vertices_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_vertices_count(desc, NULL) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_vertices_count(NULL, &count) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_vertices_count(desc, NULL) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_vertices_count(desc, &count) == RES_OK);
CHK(count == nvertices);
- CHK(senc_descriptor_get_global_triangles_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangles_count(desc, NULL) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangles_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_triangles_count(NULL, &count) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_triangles_count(desc, NULL) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_triangles_count(desc, &count) == RES_OK);
CHK(count == ntriangles);
- CHK(senc_descriptor_get_global_triangle(NULL, 0, indices) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle(NULL, ntriangles, indices)
+ CHK(senc_descriptor_get_triangle(NULL, 0, indices) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_triangle(NULL, ntriangles, indices)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle(desc, 0, NULL) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle(desc, 0, indices) == RES_OK);
+ CHK(senc_descriptor_get_triangle(desc, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_triangle(desc, 0, indices) == RES_OK);
CHK(indices[0] == box_indices[0]
&& indices[1] == box_indices[1]
&& indices[2] == box_indices[2]);
- CHK(senc_descriptor_get_global_vertex(NULL, 0, coord) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_vertex(NULL, nvertices, coord)
+ CHK(senc_descriptor_get_vertex(NULL, 0, coord) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_vertex(NULL, nvertices, coord)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_vertex(desc, 0, NULL) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_vertex(desc, 0, coord) == RES_OK);
+ CHK(senc_descriptor_get_vertex(desc, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_descriptor_get_vertex(desc, 0, coord) == RES_OK);
CHK(coord[0] == box_vertices[0]
&& coord[1] == box_vertices[1]
&& coord[2] == box_vertices[2]);
- CHK(senc_descriptor_get_global_triangle_media(NULL, 0, media)
+ CHK(senc_descriptor_get_triangle_media(NULL, 0, media)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_media(NULL, nvertices, media)
+ CHK(senc_descriptor_get_triangle_media(NULL, nvertices, media)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_media(desc, 0, NULL)
+ CHK(senc_descriptor_get_triangle_media(desc, 0, NULL)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_media(desc, 0, media) == RES_OK);
+ CHK(senc_descriptor_get_triangle_media(desc, 0, media) == RES_OK);
CHK(media[0] == ctx.front_media[0]
&& media[1] == ctx.back_media[1]);
- CHK(senc_descriptor_get_global_triangle_enclosures(
+ CHK(senc_descriptor_get_triangle_enclosures(
NULL, 0, enclosures) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_enclosures(
+ CHK(senc_descriptor_get_triangle_enclosures(
NULL, nvertices, enclosures) == RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_enclosures(desc, 0, NULL)
+ CHK(senc_descriptor_get_triangle_enclosures(desc, 0, NULL)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_enclosures(desc, 0, enclosures)
+ CHK(senc_descriptor_get_triangle_enclosures(desc, 0, enclosures)
== RES_OK);
CHK(enclosures[0] == 0 && enclosures[1] == 1);
- CHK(senc_descriptor_get_global_triangle_global_id(NULL, 0, indices)
+ CHK(senc_descriptor_get_triangle_global_id(NULL, 0, indices)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_global_id(NULL, nvertices, indices)
+ CHK(senc_descriptor_get_triangle_global_id(NULL, nvertices, indices)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_global_id(desc, 0, NULL)
+ CHK(senc_descriptor_get_triangle_global_id(desc, 0, NULL)
== RES_BAD_ARG);
- CHK(senc_descriptor_get_global_triangle_global_id(desc, 0, indices)
+ CHK(senc_descriptor_get_triangle_global_id(desc, 0, indices)
== RES_OK);
/* No duplicates: user id is unique vertex id */
CHK(indices[0] == 0);
@@ -181,11 +181,11 @@ main(int argc, char** argv)
nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc_scene_analyze(scn, &desc) == RES_OK);
- CHK(senc_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_vertices_count(desc, &count) == RES_OK);
/* Duplicate vertices have been replaced */
CHK(count == nvertices);
- CHK(senc_descriptor_get_global_triangles_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_triangles_count(desc, &count) == RES_OK);
/* Duplicate triangles have been replaced */
CHK(count == ntriangles);
diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c
@@ -25,7 +25,7 @@ static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
struct senc_enclosure* enclosures[2] = { NULL, NULL };
@@ -40,7 +40,7 @@ test(const int convention)
unsigned gid;
enum senc_side side;
double vrtx[3];
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, n, t, ecount;
int conv;
const int conv_front = (convention & SENC_CONVENTION_NORMAL_FRONT) != 0;
diff --git a/src/test_senc_inconsistant_cube.c b/src/test_senc_inconsistant_cube.c
@@ -52,14 +52,14 @@ static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
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;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, e, ecount;
CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
diff --git a/src/test_senc_many_enclosures.c b/src/test_senc_many_enclosures.c
@@ -24,7 +24,7 @@
struct s3dut_context {
struct s3dut_mesh_data data;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
};
static void
@@ -69,7 +69,7 @@ int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
struct s3dut_mesh* cyl = NULL;
@@ -138,9 +138,9 @@ main(int argc, char** argv)
/* dump_global(desc, "test_many_enclosures.obj"); */
- CHK(senc_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_vertices_count(desc, &count) == RES_OK);
CHK(count == NB_CYL * cyl_vrtx_count);
- CHK(senc_descriptor_get_global_triangles_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_triangles_count(desc, &count) == RES_OK);
CHK(count == NB_CYL * cyl_trg_count);
CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK);
diff --git a/src/test_senc_many_triangles.c b/src/test_senc_many_triangles.c
@@ -24,7 +24,7 @@
struct s3dut_context {
struct s3dut_mesh_data data;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
};
static void
@@ -69,7 +69,7 @@ int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
struct s3dut_mesh* cyl = NULL;
@@ -123,9 +123,9 @@ main(int argc, char** argv)
/* dump_global(desc, "test_many_triangles.obj"); */
- CHK(senc_descriptor_get_global_vertices_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_vertices_count(desc, &count) == RES_OK);
CHK(count == NB_CYL * cyl_vrtx_count);
- CHK(senc_descriptor_get_global_triangles_count(desc, &count) == RES_OK);
+ CHK(senc_descriptor_get_triangles_count(desc, &count) == RES_OK);
CHK(count == NB_CYL * cyl_trg_count);
CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK);
diff --git a/src/test_senc_sample_enclosure.c b/src/test_senc_sample_enclosure.c
@@ -27,7 +27,7 @@ int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
struct senc_enclosure* enclosure = NULL;
@@ -39,7 +39,7 @@ main(int argc, char** argv)
struct s3d_primitive prim;
struct s3d_vertex_data vrtx_get;
struct ssp_rng* rng;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
int i;
float st[2];
(void)argc, (void)argv;
diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c
@@ -25,10 +25,10 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_enclosure* enc = NULL;
struct senc_enclosure_header header;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned medfront[2], medback[2], ind[3];
double vrtx[3];
unsigned count, i, maxm;
@@ -67,10 +67,10 @@ main(int argc, char** argv)
CHK(senc_scene_get_triangles_count(scn, &count) == RES_OK);
CHK(count == 0);
- CHK(senc_scene_get_unique_triangles_count(NULL, &count) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangles_count(scn, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangles_count(NULL, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangles_count(scn, &count) == RES_OK);
+ CHK(senc_scene_get_triangles_count(NULL, &count) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangles_count(scn, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangles_count(NULL, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangles_count(scn, &count) == RES_OK);
CHK(count == 0);
CHK(senc_scene_get_vertices_count(NULL, &count) == RES_BAD_ARG);
@@ -122,39 +122,39 @@ main(int argc, char** argv)
CHK(senc_scene_get_triangles_count(scn, &count) == RES_OK);
CHK(count == ntriangles);
- CHK(senc_scene_get_unique_triangles_count(scn, &count) == RES_OK);
+ CHK(senc_scene_get_triangles_count(scn, &count) == RES_OK);
CHK(count == ntriangles);
CHK(senc_scene_get_vertices_count(scn, &count) == RES_OK);
CHK(count == nvertices);
CHK(senc_scene_get_unique_vertices_count(scn, &count) == RES_OK);
CHK(count == nvertices);
- CHK(senc_scene_get_unique_triangle(NULL, 0, ind) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(scn, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(scn, 0, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(NULL, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(scn, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle(scn, 0, ind) == RES_OK);
-
- CHK(senc_scene_get_unique_triangle_media(NULL, 0, ind) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(scn, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(scn, 0, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(NULL, UINT_MAX, ind) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(scn, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_triangle_media(scn, 0, ind) == RES_OK);
-
- CHK(senc_scene_get_unique_vertex(NULL, 0, vrtx) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(scn, UINT_MAX, vrtx) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(scn, 0, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(NULL, UINT_MAX, vrtx) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(NULL, 0, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(scn, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
- CHK(senc_scene_get_unique_vertex(scn, 0, vrtx) == RES_OK);
+ CHK(senc_scene_get_triangle(NULL, 0, ind) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(scn, UINT_MAX, ind) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(scn, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(NULL, UINT_MAX, ind) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(scn, UINT_MAX, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle(scn, 0, ind) == RES_OK);
+
+ CHK(senc_scene_get_triangle_media(NULL, 0, ind) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(scn, UINT_MAX, ind) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(scn, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(NULL, UINT_MAX, ind) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(scn, UINT_MAX, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_triangle_media(scn, 0, ind) == RES_OK);
+
+ CHK(senc_scene_get_vertex(NULL, 0, vrtx) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(scn, UINT_MAX, vrtx) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(scn, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(NULL, UINT_MAX, vrtx) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(NULL, 0, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(scn, UINT_MAX, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(NULL, UINT_MAX, NULL) == RES_BAD_ARG);
+ CHK(senc_scene_get_vertex(scn, 0, vrtx) == RES_OK);
CHK(senc_scene_analyze(NULL, NULL) == RES_BAD_ARG);
CHK(senc_scene_analyze(scn, NULL) == RES_BAD_ARG);
@@ -187,12 +187,12 @@ main(int argc, char** argv)
FOR_EACH(i, 0, ntriangles) {
unsigned gid;
- CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK);
+ CHK(senc_descriptor_get_triangle_global_id(desc, i, &gid) == RES_OK);
/* Check numbering shift */
CHK(gid == (i ? i + 1 : 0));
}
- CHK(senc_descriptor_get_global_triangle_media(desc, 0, medback) == RES_OK);
+ CHK(senc_descriptor_get_triangle_media(desc, 0, medback) == RES_OK);
ctx.front_media = medium1_3;
CHK(senc_scene_ref_put(scn) == RES_OK);
CHK(senc_descriptor_ref_put(desc) == RES_OK);
@@ -234,12 +234,12 @@ main(int argc, char** argv)
FOR_EACH(i, 0, ntriangles) {
unsigned gid;
- CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK);
+ CHK(senc_descriptor_get_triangle_global_id(desc, i, &gid) == RES_OK);
/* Check numbering shift */
CHK(gid == (i ? i + 1 : 0));
}
- CHK(senc_descriptor_get_global_triangle_media(desc, 0, medfront) == RES_OK);
+ CHK(senc_descriptor_get_triangle_media(desc, 0, medfront) == RES_OK);
FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);
/* Invalid vertex ID */
diff --git a/src/test_senc_undefined_medium.c b/src/test_senc_undefined_medium.c
@@ -23,7 +23,7 @@ static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
struct senc_enclosure* enclosure;
@@ -31,7 +31,7 @@ test(const int convention)
unsigned medium, expected_external_medium, expected_internal_medium;
unsigned gid;
enum senc_side side;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, t, ecount, vcount, tcount, scount;
unsigned media[12];
unsigned rev_box_indices[sizeof(box_indices) / sizeof(*box_indices)];
@@ -140,18 +140,18 @@ test(const int convention)
/* Get the deduplicated geometry without (successful) analyze */
OK(senc_scene_get_unique_vertices_count(scn, &vcount));
CHK(vcount == nvertices);
- OK(senc_scene_get_unique_triangles_count(scn, &tcount));
+ OK(senc_scene_get_triangles_count(scn, &tcount));
CHK(tcount == ntriangles);
FOR_EACH(i, 0, tcount) {
int j;
unsigned med[2], ids[3];
- OK(senc_scene_get_unique_triangle(scn, i, ids));
- OK(senc_scene_get_unique_triangle_media(scn, i, med));
+ OK(senc_scene_get_triangle(scn, i, ids));
+ OK(senc_scene_get_triangle_media(scn, i, med));
CHK(med[0] == ((i % 2) ? 0 : SENC_UNDEFINED_MEDIUM) && med[1] == 1);
FOR_EACH(j, 0, 3) {
double pos[3];
CHK(ids[j] < vcount);
- OK(senc_scene_get_unique_vertex(scn, ids[j], pos));
+ OK(senc_scene_get_vertex(scn, ids[j], pos));
}
}
@@ -178,18 +178,18 @@ test(const int convention)
/* Get the deduplicated geometry without (successful) analyze */
OK(senc_scene_get_unique_vertices_count(scn, &vcount));
CHK(vcount == nvertices);
- OK(senc_scene_get_unique_triangles_count(scn, &tcount));
+ OK(senc_scene_get_triangles_count(scn, &tcount));
CHK(tcount == ntriangles);
FOR_EACH(i, 0, tcount) {
int j;
unsigned med[2], ids[3];
- OK(senc_scene_get_unique_triangle(scn, i, ids));
- OK(senc_scene_get_unique_triangle_media(scn, i, med));
+ OK(senc_scene_get_triangle(scn, i, ids));
+ OK(senc_scene_get_triangle_media(scn, i, med));
CHK(med[0] == 0 && med[1] == 1);
FOR_EACH(j, 0, 3) {
double pos[3];
CHK(ids[j] < vcount);
- OK(senc_scene_get_unique_vertex(scn, ids[j], pos));
+ OK(senc_scene_get_vertex(scn, ids[j], pos));
}
}
@@ -216,7 +216,7 @@ test(const int convention)
/* Scene is still OK and can be analyzed */
OK(senc_scene_analyze(scn, &desc));
- OK(senc_descriptor_get_global_triangles_count(desc, &tcount));
+ OK(senc_descriptor_get_triangles_count(desc, &tcount));
CHK(tcount == sizeof(media) / sizeof(*media));
OK(senc_descriptor_get_enclosure_count(desc, &ecount));
diff --git a/src/test_senc_undefined_medium_attr.c b/src/test_senc_undefined_medium_attr.c
@@ -85,7 +85,7 @@ merge_trg
compat &= (triangle_media[i] == SENC_UNDEFINED_MEDIUM
|| merge_media[i] == SENC_UNDEFINED_MEDIUM
|| triangle_media[i] == merge_media[i]);
- if (!compat) return RES_BAD_ARG;
+ if(!compat) return RES_BAD_ARG;
merge_ctx = ctx->custom;
res = darray_intface_id_resize(&merge_ctx->global_interf_data, global_id + 1);
if(res != RES_OK) return res;
@@ -110,7 +110,7 @@ static void
test(const int convention)
{
struct mem_allocator allocator;
- struct senc_descriptor* desc = NULL;
+ struct descriptor* desc = NULL;
struct senc_device* dev = NULL;
struct senc_scene* scn = NULL;
struct senc_enclosure* enclosure;
@@ -118,7 +118,7 @@ test(const int convention)
unsigned medium, expected_external_medium, expected_internal_medium;
unsigned gid;
enum senc_side side;
- struct context ctx;
+ struct context ctx = CONTEXT_NULL__;
unsigned i, t, ecount, vcount, tcount, scount;
unsigned media[12], interface_ids[12] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
unsigned rev_box_indices[sizeof(box_indices) / sizeof(*box_indices)];
@@ -238,18 +238,18 @@ test(const int convention)
/* Get the deduplicated geometry without (successful) analyze */
OK(senc_scene_get_unique_vertices_count(scn, &vcount));
CHK(vcount == nvertices);
- OK(senc_scene_get_unique_triangles_count(scn, &tcount));
+ OK(senc_scene_get_triangles_count(scn, &tcount));
CHK(tcount == ntriangles);
FOR_EACH(i, 0, tcount) {
int j;
unsigned med[2], ids[3];
- OK(senc_scene_get_unique_triangle(scn, i, ids));
- OK(senc_scene_get_unique_triangle_media(scn, i, med));
+ OK(senc_scene_get_triangle(scn, i, ids));
+ OK(senc_scene_get_triangle_media(scn, i, med));
CHK(med[0] == ((i % 2) ? 0 : SENC_UNDEFINED_MEDIUM) && med[1] == 1);
FOR_EACH(j, 0, 3) {
double pos[3];
CHK(ids[j] < vcount);
- OK(senc_scene_get_unique_vertex(scn, ids[j], pos));
+ OK(senc_scene_get_vertex(scn, ids[j], pos));
}
}
@@ -276,18 +276,18 @@ test(const int convention)
/* Get the deduplicated geometry without (successful) analyze */
OK(senc_scene_get_unique_vertices_count(scn, &vcount));
CHK(vcount == nvertices);
- OK(senc_scene_get_unique_triangles_count(scn, &tcount));
+ OK(senc_scene_get_triangles_count(scn, &tcount));
CHK(tcount == ntriangles);
FOR_EACH(i, 0, tcount) {
int j;
unsigned med[2], ids[3];
- OK(senc_scene_get_unique_triangle(scn, i, ids));
- OK(senc_scene_get_unique_triangle_media(scn, i, med));
+ OK(senc_scene_get_triangle(scn, i, ids));
+ OK(senc_scene_get_triangle_media(scn, i, med));
CHK(med[0] == 0 && med[1] == 1);
FOR_EACH(j, 0, 3) {
double pos[3];
CHK(ids[j] < vcount);
- OK(senc_scene_get_unique_vertex(scn, ids[j], pos));
+ OK(senc_scene_get_vertex(scn, ids[j], pos));
}
}
@@ -314,7 +314,7 @@ test(const int convention)
/* Scene is still OK and can be analyzed */
OK(senc_scene_analyze(scn, &desc));
- OK(senc_descriptor_get_global_triangles_count(desc, &tcount));
+ OK(senc_descriptor_get_triangles_count(desc, &tcount));
CHK(tcount == sizeof(media) / sizeof(*media));
OK(senc_descriptor_get_enclosure_count(desc, &ecount));
diff --git a/src/test_senc_utils.h b/src/test_senc_utils.h
@@ -81,11 +81,15 @@ struct context {
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 };
@@ -123,32 +127,41 @@ get_media(const unsigned itri, unsigned medium[2], void* context)
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_descriptor* desc,
+ (struct senc_scene* scn,
const char* name)
{
FILE* stream;
unsigned triangles_count, vertices_count, i;
- ASSERT(desc && name);
+ ASSERT(scn && name);
- CHK(senc_descriptor_get_global_vertices_count(desc, &vertices_count) == RES_OK);
- CHK(senc_descriptor_get_global_triangles_count(desc, &triangles_count) == RES_OK);
+ CHK(senc_scene_get_vertices_count(scn, &vertices_count) == RES_OK);
+ CHK(senc_scene_get_triangles_count(scn, &triangles_count) == RES_OK);
stream = fopen(name, "w");
CHK(stream);
FOR_EACH(i, 0, vertices_count) {
double tmp[3];
- CHK(senc_descriptor_get_global_vertex(desc, i, tmp) == RES_OK);
+ CHK(senc_scene_get_vertex(scn, i, tmp) == RES_OK);
fprintf(stream, "v %g %g %g\n", SPLIT3(tmp));
}
FOR_EACH(i, 0, triangles_count) {
unsigned indices[3];
- CHK(senc_descriptor_get_global_triangle(desc, i, indices) == RES_OK);
+ CHK(senc_scene_get_triangle(scn, i, indices) == RES_OK);
fprintf(stream, "f %lu %lu %lu\n", (unsigned long)(1 + indices[0]),
(unsigned long)(1 + indices[1]), (unsigned long)(1 + indices[2]));
}
@@ -157,7 +170,7 @@ dump_global
static INLINE void
dump_enclosure
- (struct senc_descriptor* desc,
+ (struct senc_scene* scn,
const unsigned enc,
const char* name)
{
@@ -166,11 +179,11 @@ dump_enclosure
FILE* stream;
unsigned count, i;
- ASSERT(desc && name);
+ ASSERT(scn && name);
- SENC(descriptor_get_enclosure_count(desc, &count));
+ SENC(scene_get_enclosure_count(scn, &count));
ASSERT(enc < count);
- CHK(senc_descriptor_get_enclosure(desc, enc, &enclosure) == RES_OK);
+ CHK(senc_scene_get_enclosure(scn, enc, &enclosure) == RES_OK);
CHK(senc_enclosure_get_header(enclosure, &header) == RES_OK);
stream = fopen(name, "w");
@@ -204,40 +217,6 @@ check_memory_allocator(struct mem_allocator* allocator)
/*******************************************************************************
* Check functions
******************************************************************************/
-static INLINE void check_desc(struct senc_descriptor* desc)
-{
- unsigned maxm, ecount, i;
- size_t e_cpt = 0;
- CHK(senc_descriptor_get_max_medium(desc, &maxm) == RES_OK);
- CHK(senc_descriptor_get_enclosure_count(desc, &ecount) == RES_OK);
- for(i = 0; i <= maxm; i++) {
- unsigned j, ecount_bym;
- unsigned found = 0;
- CHK(senc_descriptor_get_enclosure_count_by_medium(desc, i, &ecount_bym) == RES_OK);
- /* Can be 0 if media numbering is not compact */
- FOR_EACH(j, 0, ecount_bym) {
- struct senc_enclosure* enc;
- struct senc_enclosure_header h;
- unsigned k;
- int f = 0;
- CHK(senc_descriptor_get_enclosure_by_medium(desc, i, j, &enc) == RES_OK);
- CHK(senc_enclosure_get_header(enc, &h) == RES_OK);
- ASSERT(h.enclosed_media_count);
- FOR_EACH(k, 0, h.enclosed_media_count) {
- unsigned m;
- CHK(senc_enclosure_get_medium(enc, k, &m) == RES_OK);
- found += (m == i);
- f += (m == i);
- }
- ASSERT(f == 1); /* Single reference expected */
- CHK(senc_enclosure_ref_put(enc) == RES_OK);
- }
- ASSERT(found == ecount_bym); /* All the enclosures enclose medim i */
- e_cpt += ecount_bym;
- }
- ASSERT(e_cpt >= ecount); /* Every enc has been visited at least once */
-}
-
/* Compare the itri-th triangle of enclosure with a triangle described by trg2 & vertices2 */
static INLINE void
cmp_trg