star-enclosures-3d

Extract enclosures from 3D geometry
git clone git://git.meso-star.fr/star-enclosures-3d.git
Log | Files | Refs | README | LICENSE

commit 5b4777016232fe029febe5cab4eda0638ceddc01
parent a56c082439cb679a890af1f7e8179f346a22bbfc
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 24 Sep 2018 10:33:55 +0200

Add a convention for normals' orientation in output

Diffstat:
Msrc/senc.h | 51+++++++++++++++++++++++++++++++++++++++++++--------
Msrc/senc_scene.c | 12+++++++-----
Msrc/senc_scene_analyze.c | 62++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/senc_scene_c.h | 2+-
Msrc/test_senc_cube_behind_cube.c | 3++-
Msrc/test_senc_cube_in_cube.c | 3++-
Msrc/test_senc_cube_on_cube.c | 3++-
Msrc/test_senc_descriptor.c | 3++-
Msrc/test_senc_enclosure.c | 6++++--
Msrc/test_senc_inconsistant_cube.c | 47+++++++++++++++++++++++++++++------------------
Msrc/test_senc_many_enclosures.c | 3++-
Msrc/test_senc_many_triangles.c | 3++-
Msrc/test_senc_sample_enclosure.c | 3++-
Msrc/test_senc_scene.c | 45++++++++++++++++++++++++++-------------------
14 files changed, 168 insertions(+), 78 deletions(-)

diff --git a/src/senc.h b/src/senc.h @@ -73,12 +73,47 @@ struct senc_enclosure_header { char is_infinite; }; -/* Type used to define the convention for Front / Back sides. - * When looking at the Front side, vertices (in the order they are given in - * triangle definitions) can be seen either CW or CCW. */ -enum senc_side_convention { - SENC_CONVENTION_CW, /* Order is ClockWise */ - SENC_CONVENTION_CCW /* Order is CounterClockWise */ +/* We consider the geometrical normal Ng to a triangle V0 V1 V2 + * that verifies "(V0, V0V1, V0V2, Ng) is a direct system" + * (right-handed system). + * + * The user can set the convention used to determine which side of + * a triangle is to be considered front/back by using the flags : + * SENC_CONVENTION_NORMAL_FRONT => Ng points toward the front side, + * SENC_CONVENTION_NORMAL_BACK => Ng points toward the back side. + * + * Additionaly the user can set the convention used to output enclosures + * so that Ng points toward the enclosure or on the opposite direction + * (for a closed enclosure Ng points toward the inside or toward the outside) + * by using the flags : + * SENC_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure, + * SENC_CONVENTION_NORMAL_OUTSIDE => Ng points to the opposite of the enclosure. + * + * Note that normals in output data can be opposite to normals in input data + * (vertices are then given in reverse order). + * + * Also note that both sides of a triangle can be part of the same enclosure; + * in this case the 2 sides will be given with opposite Ng (meaning they + * will be given with opposite vertices order). + */ +enum senc_convention { + /* + * Convention regarding FRONT/BACK sides in input data + */ + + /* Geometrical normals point toward the front side */ + SENC_CONVENTION_NORMAL_FRONT = BIT(0), + /* Geometrical normals point toward the back side */ + SENC_CONVENTION_NORMAL_BACK = BIT(1), + + /* + * Convention regarding geometrical normals in output data + */ + + /* Geometrical normals point toward the enclosure */ + SENC_CONVENTION_NORMAL_INSIDE = BIT(2), + /* Geometrical normals point to the opposite of the enclosure */ + SENC_CONVENTION_NORMAL_OUTSIDE = BIT(3) }; BEGIN_DECLS @@ -112,7 +147,7 @@ senc_device_ref_put SENC_API res_T senc_scene_create (struct senc_device* device, - const enum senc_side_convention front_side_convention, + const enum senc_convention convention, struct senc_scene** scene); /* Add a new set of vertices and triangles to the scene. @@ -141,7 +176,7 @@ senc_scene_analyze SENC_API res_T senc_scene_get_convention (const struct senc_scene* scene, - enum senc_side_convention* front_side_convention); + enum senc_convention* convention); SENC_API res_T senc_scene_get_triangles_count diff --git a/src/senc_scene.c b/src/senc_scene.c @@ -48,14 +48,16 @@ scene_release(ref_T * ref) res_T senc_scene_create (struct senc_device* dev, - const enum senc_side_convention conv, + const enum senc_convention conv, struct senc_scene** out_scn) { struct senc_scene* scn = NULL; res_T res = RES_OK; if(!dev || !out_scn - || (conv != SENC_CONVENTION_CW && conv != SENC_CONVENTION_CCW)) + /* Convention must be set both regarding FRONT/BACK and INSIDE/OUTSIDE */ + || !(conv & (SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_BACK)) + || !(conv & (SENC_CONVENTION_NORMAL_INSIDE | SENC_CONVENTION_NORMAL_OUTSIDE))) return RES_BAD_ARG; scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct senc_scene)); @@ -286,10 +288,10 @@ error: res_T senc_scene_get_convention (const struct senc_scene* scn, - enum senc_side_convention* front_side_convention) + enum senc_convention* convention) { - if(!scn || !front_side_convention) return RES_BAD_ARG; - *front_side_convention = scn->convention; + if(!scn || !convention) return RES_BAD_ARG; + *convention = scn->convention; return RES_OK; } diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c @@ -402,9 +402,9 @@ extract_connex_components norm = d3_normalize(normal, normal); ASSERT(norm); (void)norm; - /* Geometrical normal points toward the front side - * if convention is CW, toward back side if CCW */ - if(TRGSIDE_IS_FRONT(side_id) == (scn->convention == SENC_CONVENTION_CW)) { + /* Orient the geometrical normal according to the convention */ + if(TRGSIDE_IS_FRONT(side_id) + == ((scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0)) { max_z_nz += normal[2]; } else { max_z_nz -= normal[2]; @@ -826,11 +826,11 @@ collect_and_link_neighbours const trg_id_t crt_id = current->trg_id; const trg_id_t ccw_id = ccw_neighbour->trg_id; /* Facing sides of triangles */ - const int cw = (scn->convention == SENC_CONVENTION_CW); + const int front = ((scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0); const enum side_id crt_side - = current->normal_toward_next_neighbour == cw ? SIDE_FRONT : SIDE_BACK; + = current->normal_toward_next_neighbour == front ? SIDE_FRONT : SIDE_BACK; const enum side_id ccw_side - = ccw_neighbour->normal_toward_next_neighbour == cw ? + = ccw_neighbour->normal_toward_next_neighbour == front ? SIDE_BACK : SIDE_FRONT; /* Index of sides in trgsides */ const side_id_t crt_side_idx = TRGIDxSIDE_2_TRGSIDE(crt_id, crt_side); @@ -874,23 +874,33 @@ build_result struct triangle_enc* triangles_enc; const struct triangle_comp* triangles_comp; struct htable_vrtx_id vtable; + struct senc_scene* scn; + enum senc_convention convention; + int output_normal_in, normals_front, normals_back; int64_t tt; int64_t ee; ASSERT(desc && connex_components && triangles_comp_array); alloc = descriptor_get_allocator(desc); + scn = desc->scene; + convention = scn->convention; + output_normal_in = (scn->convention & SENC_CONVENTION_NORMAL_INSIDE) != 0; + normals_front = (scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0; + normals_back = (scn->convention & SENC_CONVENTION_NORMAL_BACK) != 0; + ASSERT(normals_back != normals_front); + ASSERT(output_normal_in != ((scn->convention & SENC_CONVENTION_NORMAL_OUTSIDE) != 0)); ASSERT(darray_ptr_component_descriptor_size_get(connex_components) <= COMPONENT_MAX__); cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components); enclosures = darray_enclosure_data_get(&desc->enclosures); - triangles_in = darray_triangle_in_cdata_get(&desc->scene->triangles_in); + 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, desc->scene->nutris); + darray_triangle_enc_resize(&desc->triangles_enc, scn->nutris); if(tmp_res != RES_OK) *res = tmp_res; }/* Implicit barrier here. */ if(*res != RES_OK) return; @@ -898,7 +908,7 @@ build_result /* Build global enclosure information */ #pragma omp for - for(tt = 0; tt < (int64_t)desc->scene->nutris; tt++) { + for(tt = 0; tt < (int64_t) scn->nutris; tt++) { trg_id_t t = (trg_id_t)tt; const component_id_t cf_id = triangles_comp[t].component[SIDE_FRONT]; const component_id_t cb_id = triangles_comp[t].component[SIDE_BACK]; @@ -940,7 +950,7 @@ build_result enc->header.is_infinite = (e == 0); ASSERT(darray_uchar_size_get(&enc->tmp_enclosed_media) <= UINT_MAX); - ASSERT(enc->header.enclosed_media_count <= desc->scene->nmeds); + ASSERT(enc->header.enclosed_media_count <= scn->nmeds); OK2(bool_array_of_media_to_darray_media (&enc->enclosed_media, &enc->tmp_enclosed_media)); enc->header.enclosed_media_count @@ -970,8 +980,7 @@ build_result (size_t)(enc->side_count * 0.6))); /* New vertex numbering scheme local to the enclosure */ htable_vrtx_id_clear(&vtable); - ASSERT(desc->scene->nutris - == darray_triangle_in_size_get(&desc->scene->triangles_in)); + ASSERT(scn->nutris == 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); @@ -1006,21 +1015,38 @@ build_result ASSERT(triangles_enc[t].enclosure[SIDE_FRONT] == e || triangles_enc[t].enclosure[SIDE_BACK] == e); if(triangles_enc[t].enclosure[SIDE_FRONT] == e) { + /* Front side of the original triangle is member of the enclosure */ + int input_normal_in = normals_front; + int revert_triangle = (input_normal_in != output_normal_in); ++enc->header.triangle_count; trg = darray_triangle_in_data_get(&enc->sides) + fst_idx++; - - FOR_EACH(i, 0, 2) trg->medium[i] = trg_in->medium[i]; + FOR_EACH(i, 0, 2) { + int ii = revert_triangle ? 1 - i : i; + trg->medium[i] = trg_in->medium[ii]; + } trg->global_id = trg_in->global_id; - FOR_EACH(i, 0, 3) trg->vertice_id[i] = vertice_id[i]; + FOR_EACH(i, 0, 3) { + int ii = revert_triangle ? 2 - i : i; + trg->vertice_id[i] = vertice_id[ii]; + } } if(triangles_enc[t].enclosure[SIDE_BACK] == e) { + /* Back side of the original triangle is member of the enclosure */ + int input_normal_in = normals_back; + int revert_triangle = (input_normal_in != output_normal_in); ++enc->header.triangle_count; + /* If both sides are in the enclosure, put the second side at the end */ trg = darray_triangle_in_data_get(&enc->sides) + ((triangles_enc[t].enclosure[SIDE_FRONT] == e) ? --sgd_idx : fst_idx++); - - FOR_EACH(i, 0, 2) trg->medium[i] = trg_in->medium[1 - i]; + FOR_EACH(i, 0, 2) { + int ii = revert_triangle ? 1 - i : i; + trg->medium[i] = trg_in->medium[ii]; + } trg->global_id = trg_in->global_id; - FOR_EACH(i, 0, 3) trg->vertice_id[i] = vertice_id[2 - i]; + FOR_EACH(i, 0, 3) { + int ii = revert_triangle ? 2 - i : i; + trg->vertice_id[i] = vertice_id[ii]; + } } if(fst_idx == sgd_idx) break; } diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h @@ -197,7 +197,7 @@ side_range_init(struct mem_allocator* alloc, struct side_range* data) struct senc_scene { /* Front / Back sides convention */ - enum senc_side_convention convention; + enum senc_convention convention; /* Triangle information as given by user; no duplicates here */ struct darray_triangle_in triangles_in; diff --git a/src/test_senc_cube_behind_cube.c b/src/test_senc_cube_behind_cube.c @@ -34,7 +34,8 @@ main(int argc, char** argv) (NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); /* Create the scene */ - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); ctx.positions = box_vertices; ctx.indices = box_indices; diff --git a/src/test_senc_cube_in_cube.c b/src/test_senc_cube_in_cube.c @@ -34,7 +34,8 @@ main(int argc, char** argv) (NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); /* Create the scene */ - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); ctx.positions = box_vertices; ctx.indices = box_indices; diff --git a/src/test_senc_cube_on_cube.c b/src/test_senc_cube_on_cube.c @@ -57,7 +57,8 @@ main(int argc, char** argv) (NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); /* Create the scene */ - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); ctx.positions = cube_vertices; /* Need true cubes for cubes #1 and #2 */ ctx.indices = box_indices; diff --git a/src/test_senc_descriptor.c b/src/test_senc_descriptor.c @@ -39,7 +39,8 @@ main(int argc, char** argv) CHK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); /* A 3D cube */ ctx.positions = box_vertices; diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c @@ -47,7 +47,8 @@ main(int argc, char** argv) CHK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); s3d_attribs.type = S3D_FLOAT3; s3d_attribs.usage = S3D_POSITION; @@ -187,7 +188,8 @@ main(int argc, char** argv) /* Same 3D cube, but with a hole (incomplete). * 1 single enclosure including both sides of triangles */ - CHK(senc_scene_create(dev, SENC_CONVENTION_CCW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); ctx.positions = box_vertices; ctx.indices = box_indices; diff --git a/src/test_senc_inconsistant_cube.c b/src/test_senc_inconsistant_cube.c @@ -64,6 +64,7 @@ cmp_trg unsigned i, j, fst_vrtx = 3; ASSERT(enclosure && trg2 && vertices2 && trg_eq && trg_reversed); + CHK(senc_enclosure_get_triangle(enclosure, itri, trg1) == RES_OK); FOR_EACH(i, 0, 3) { CHK(senc_enclosure_get_vertex(enclosure, trg1[i], t1[i]) == RES_OK); @@ -98,7 +99,7 @@ cmp_trg } void -test(enum senc_side_convention convention) +test(enum senc_convention convention) { struct mem_allocator allocator; struct senc_descriptor* desc = NULL; @@ -107,6 +108,7 @@ test(enum senc_side_convention convention) struct senc_enclosure* enclosure; struct senc_enclosure_header header; enum senc_side_convention conv; + int conv_front, conv_in; struct context ctx; unsigned i, e, ecount; @@ -140,36 +142,42 @@ test(enum senc_side_convention convention) CHK(senc_scene_get_convention(scn, &conv) == RES_OK); CHK(conv == convention); + conv_front = (conv & SENC_CONVENTION_NORMAL_FRONT) != 0; + conv_in = (conv & SENC_CONVENTION_NORMAL_INSIDE) != 0; FOR_EACH(e, 0, ecount) { - unsigned medium, expected_external_medium; + unsigned medium, expected_external_medium, expected_medium; char name[128]; - int common; + int front_inside; + int expected_side; CHK(senc_descriptor_get_enclosure(desc, e, &enclosure) == RES_OK); CHK(senc_enclosure_get_header(enclosure, &header) == RES_OK); CHK(header.enclosed_media_count == 1); CHK(senc_enclosure_get_medium(enclosure, 0, &medium) == RES_OK); - /* If CW the external enclosure's medium should be 0, 1 if CCW */ - expected_external_medium = (conv == SENC_CONVENTION_CW) ? 0 : 1; - CHK(header.is_infinite == (medium == expected_external_medium)); - /* Common media, for non reversed triangles */ - common = (conv == SENC_CONVENTION_CW) - ? !header.is_infinite : header.is_infinite; - - snprintf(name, sizeof(name), "test_inconsistant_cube_%s_%u.obj", - (conv == SENC_CONVENTION_CW) ? "cw" : "ccw", e); + /* If NORMAL_FRONT the external enclosure's medium should be 0, 1 if NORMAL_BACK */ + expected_external_medium = conv_front ? 0 : 1; + expected_medium = (header.is_infinite ? expected_external_medium : !expected_external_medium); + CHK(medium == expected_medium); + /* Common media, for non input triangles */ + front_inside = (conv_front == conv_in); + expected_side = front_inside ? 0 : 1; + + snprintf(name, sizeof(name), "test_inconsistant_cube_%s_%s_%u.obj", + conv_front ? "front" : "back", conv_in ? "in" : "out", e); dump_enclosure(desc, e, name); FOR_EACH(i, 0, header.triangle_count) { - int same, reversed; + int same, reversed, fst_reversed; + unsigned med[2]; + fst_reversed = (e == 0) == conv_in; + CHK(senc_enclosure_get_triangle_media(enclosure, i, med) == RES_OK); + CHK(med[expected_side] == medium); cmp_trg(i, enclosure, inconsistant_box_indices + (3 * i), box_vertices, &same, &reversed); /* Should be made of the same triangles */ CHK(same); - /* Triangle #0 always differs because it was given in the opposite order - * Depending on the convention, it is the only one to be/not to be reversed */ - CHK(reversed == (i == 0 ? !common : common)); + CHK(i ? reversed != fst_reversed : reversed == fst_reversed); } SENC(enclosure_ref_put(enclosure)); } @@ -187,7 +195,10 @@ int main(int argc, char** argv) { (void) argc, (void) argv; - test(SENC_CONVENTION_CW); - test(SENC_CONVENTION_CCW); + test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE); + test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE); + test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_OUTSIDE); + test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_OUTSIDE); + return 0; } \ No newline at end of file diff --git a/src/test_senc_many_enclosures.c b/src/test_senc_many_enclosures.c @@ -90,7 +90,8 @@ main(int argc, char** argv) /* 64^3 = 262144 cylinders */ #define NB_CYL (NB_CYL_1 * NB_CYL_1 * NB_CYL_1) /* Create the scene */ - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); ctx.ctx.positions = NULL; ctx.ctx.indices = NULL; diff --git a/src/test_senc_many_triangles.c b/src/test_senc_many_triangles.c @@ -87,7 +87,8 @@ main(int argc, char** argv) #define NB_CYL 4 /* Create the scene */ - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); ctx.ctx.positions = NULL; ctx.ctx.indices = NULL; diff --git a/src/test_senc_sample_enclosure.c b/src/test_senc_sample_enclosure.c @@ -48,7 +48,8 @@ main(int argc, char** argv) CHK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); vrtx_get.type = S3D_FLOAT3; vrtx_get.usage = S3D_POSITION; diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c @@ -29,7 +29,7 @@ main(int argc, char** argv) struct senc_enclosure* enc = NULL; struct senc_enclosure_header header; struct context ctx; - unsigned medcw[2], medccw[2]; + unsigned medfront[2], medback[2]; unsigned count, i, maxm; enum senc_side_convention convention; (void)argc, (void)argv; @@ -38,20 +38,24 @@ main(int argc, char** argv) CHK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc_scene_create(NULL, SENC_CONVENTION_CW, &scn) == RES_BAD_ARG); - CHK(senc_scene_create(dev, 5, &scn) == RES_BAD_ARG); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, NULL) == RES_BAD_ARG); - CHK(senc_scene_create(NULL, 5, &scn) == RES_BAD_ARG); - CHK(senc_scene_create(NULL, SENC_CONVENTION_CW, NULL) == RES_BAD_ARG); - CHK(senc_scene_create(dev, 5, NULL) == RES_BAD_ARG); - CHK(senc_scene_create(NULL, 5, NULL) == RES_BAD_ARG); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(NULL, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_BAD_ARG); + CHK(senc_scene_create(dev, 0, &scn) == RES_BAD_ARG); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, NULL) == RES_BAD_ARG); + CHK(senc_scene_create(NULL, 0, &scn) == RES_BAD_ARG); + CHK(senc_scene_create(NULL, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, NULL) == RES_BAD_ARG); + CHK(senc_scene_create(dev, 0, NULL) == RES_BAD_ARG); + CHK(senc_scene_create(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); CHK(senc_scene_get_convention(NULL, &convention) == RES_BAD_ARG); CHK(senc_scene_get_convention(scn, NULL) == RES_BAD_ARG); CHK(senc_scene_get_convention(NULL, NULL) == RES_BAD_ARG); CHK(senc_scene_get_convention(scn, &convention) == RES_OK); - CHK(convention == SENC_CONVENTION_CW); + CHK(convention == (SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE)); CHK(senc_scene_get_triangles_count(NULL, &count) == RES_BAD_ARG); CHK(senc_scene_get_triangles_count(scn, NULL) == RES_BAD_ARG); @@ -78,8 +82,8 @@ main(int argc, char** argv) CHK(count == 0); /* A 3D cube. - * With this geometry front is inside with CCW convention, - * outside with CW convention */ + * With this geometry front is inside with NORMAL_BACK convention, + * outside with NORMAL_FRONT convention */ ctx.positions = box_vertices; ctx.indices = box_indices; ctx.scale = 1; @@ -127,9 +131,10 @@ main(int argc, char** argv) CHK(senc_scene_ref_put(scn) == RES_OK); CHK(senc_descriptor_ref_put(desc) == RES_OK); - CHK(senc_scene_create(dev, SENC_CONVENTION_CCW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); CHK(senc_scene_get_convention(scn, &convention) == RES_OK); - CHK(convention == SENC_CONVENTION_CCW); + CHK(convention == (SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE)); CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, get_global_id, nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -145,12 +150,13 @@ main(int argc, char** argv) /* gid has been set to gid_face. */ CHK(gid == gid_face[i]); } - CHK(senc_descriptor_get_global_triangle_media(desc, 0, medccw) == RES_OK); + CHK(senc_descriptor_get_global_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); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, get_global_id, nvertices, get_position, &ctx) == RES_OK); /* Medium mismatch between neighbour segments, but OK */ @@ -171,7 +177,8 @@ main(int argc, char** argv) ctx.front_media = medium0; CHK(senc_scene_ref_put(scn) == RES_OK); CHK(senc_descriptor_ref_put(desc) == RES_OK); - CHK(senc_scene_create(dev, SENC_CONVENTION_CW, &scn) == RES_OK); + CHK(senc_scene_create(dev, + SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, NULL, nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -187,8 +194,8 @@ main(int argc, char** argv) /* Default gid: triangle rank. */ CHK(gid == i); } - CHK(senc_descriptor_get_global_triangle_media(desc, 0, medcw) == RES_OK); - FOR_EACH(i, 0, 2) CHK(medccw[i] == medcw[i]); + CHK(senc_descriptor_get_global_triangle_media(desc, 0, medfront) == RES_OK); + FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]); /* Invalid vertex ID */ CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, NULL,