star-enclosures-2d

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

commit b5c3b1d88a08b50eb22015ac3b8313644fbbd782
parent 772e86fd3822edd7038bb986d54d496e6e257b18
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 12 Sep 2018 16:30:31 +0200

Fix Front/Back convention

Additionally convention can now be chosen

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/senc2d.h | 14++++++++++++++
Msrc/senc2d_scene.c | 17++++++++++++++++-
Msrc/senc2d_scene_analyze.c | 49+++++++++++++++++++++++++++++++++++++++----------
Msrc/senc2d_scene_analyze_c.h | 3+++
Msrc/senc2d_scene_c.h | 3+++
Msrc/test_senc2d_descriptor.c | 2+-
Msrc/test_senc2d_enclosure.c | 4++--
Asrc/test_senc2d_inconsistant_square.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_senc2d_many_enclosures.c | 2+-
Msrc/test_senc2d_many_segments.c | 2+-
Msrc/test_senc2d_sample_enclosure.c | 2+-
Msrc/test_senc2d_scene.c | 47+++++++++++++++++++++++++++++++++++++++--------
Msrc/test_senc2d_square_behind_square.c | 2+-
Msrc/test_senc2d_square_in_square.c | 2+-
Msrc/test_senc2d_square_on_square.c | 2+-
16 files changed, 311 insertions(+), 28 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -125,6 +125,7 @@ if(NOT NO_TEST) new_test(test_senc2d_descriptor) new_test(test_senc2d_device) new_test(test_senc2d_enclosure) + new_test(test_senc2d_inconsistant_square) new_test(test_senc2d_many_enclosures) new_test(test_senc2d_many_segments) new_test(test_senc2d_sample_enclosure) diff --git a/src/senc2d.h b/src/senc2d.h @@ -73,6 +73,14 @@ struct senc2d_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 + * segment definitions) can be seen either CW or CCW. */ +enum senc2d_side_convention { + SENC2D_CONVENTION_CW, /* Order is ClockWise */ + SENC2D_CONVENTION_CCW /* Order is CounterClockWise */ +}; + BEGIN_DECLS /******************************************************************************* @@ -104,6 +112,7 @@ senc2d_device_ref_put SENC2D_API res_T senc2d_scene_create (struct senc2d_device* device, + const enum senc2d_side_convention front_side_convention, struct senc2d_scene** scene); /* Add a new set of vertices and segments to the scene. @@ -130,6 +139,11 @@ senc2d_scene_analyze struct senc2d_descriptor** descriptor); SENC2D_API res_T +senc2d_scene_get_convention + (const struct senc2d_scene* scene, + enum senc2d_side_convention* front_side_convention); + +SENC2D_API res_T senc2d_scene_get_segments_count (const struct senc2d_scene* scene, unsigned* count); diff --git a/src/senc2d_scene.c b/src/senc2d_scene.c @@ -48,12 +48,15 @@ scene_release(ref_T * ref) res_T senc2d_scene_create (struct senc2d_device* dev, + const enum senc2d_side_convention conv, struct senc2d_scene** out_scn) { struct senc2d_scene* scn = NULL; res_T res = RES_OK; - if(!dev || !out_scn) return RES_BAD_ARG; + if(!dev || !out_scn + || (conv != SENC2D_CONVENTION_CW && conv != SENC2D_CONVENTION_CCW)) + return RES_BAD_ARG; scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct senc2d_scene)); if(!scn) { @@ -64,6 +67,7 @@ senc2d_scene_create ref_init(&scn->ref); SENC2D(device_ref_get(dev)); scn->dev = dev; + scn->convention = conv; scn->ngeoms = 0; scn->nsegs = 0; scn->nusegs = 0; @@ -277,6 +281,17 @@ error: } res_T +senc2d_scene_get_convention + (const struct senc2d_scene* scn, + enum senc2d_side_convention* front_side_convention) +{ + if(!scn || !front_side_convention) return RES_BAD_ARG; + *front_side_convention = scn->convention; + return RES_OK; + +} + +res_T senc2d_scene_get_segments_count (const struct senc2d_scene* scn, unsigned* count) diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -384,7 +384,7 @@ canceled: /* To garanty that segments with 2 sides in the component total to 0 * regardless of numeric accuracy, we need to prevent them to - * contribute (remember than x + y - x - y can be non-zero). */ + * contribute (remember than x + y - y == 0 can be false). */ ASSERT(seg_comp->component[SIDE_FRONT] == cc->cc_id || seg_comp->component[SIDE_BACK] == cc->cc_id); if(seg_comp->component[SIDE_FRONT] == seg_comp->component[SIDE_BACK]) @@ -392,15 +392,16 @@ canceled: d2_sub(edge, vertices[seg_in->vertice_id[1]].vec, vertices[seg_in->vertice_id[0]].vec); - d2(normal, edge[1], -edge[0]); + d2(normal, -edge[1], +edge[0]); norm = d2_normalize(normal, normal); ASSERT(norm); (void)norm; - /* Geometrical normal points toward the back side */ - if(SEGSIDE_IS_FRONT(side_id)) { - max_y_ny -= normal[1]; - } else { + /* Geometrical normal points toward the front side + * if convention is CW, toward back side if CCW */ + if(SEGSIDE_IS_FRONT(side_id) == (scn->convention == SENC2D_CONVENTION_CW)) { max_y_ny += normal[1]; + } else { + max_y_ny -= normal[1]; } } cc->is_outer_border = (max_y_ny < 0); @@ -732,6 +733,10 @@ collect_and_link_neighbours = darray_neighbour_data_get(neighbourhood) + i; const struct segment_in* seg_in = segments_in + neighbour_info->seg_id; struct segment_tmp* neighbour = segments_tmp + neighbour_info->seg_id; + + union double2 n; /* Geometrical normal to neighbour segment */ + const int is_reversed = neighbour_info->common_vertex_rank; + other_vrtx = seg_in->vertice_id[(neighbour_info->common_vertex_rank + 1) % 2]; max_y = MMAX(vertices[other_vrtx].pos.y, vertices[common_vrtx].pos.y); @@ -741,9 +746,29 @@ collect_and_link_neighbours d2_sub(disp, vertices[other_vrtx].vec, vertices[common_vrtx].vec); ASSERT(disp[0] || disp[1]); neighbour_info->angle = atan2(disp[1], disp[0]); + if(is_reversed) + d2(n.vec, +disp[1], -disp[0]); + else + d2(n.vec, -disp[1], +disp[0]); if(neighbour_info->angle < 0) neighbour_info->angle += 2 * PI; - /* Due to catastrophic cancelation, -eps+2pi translates to 2pi */ - ASSERT(0 <= neighbour_info->angle && neighbour_info->angle <= 2 * PI); + + /* Normal orientation calculation. */ + if(neighbour_info->angle <= PI / 4) { + ASSERT(n.pos.y); + neighbour_info->normal_toward_next_neighbour = (n.pos.y > 0); + } else if(neighbour_info->angle <= 3 * PI / 4) { + ASSERT(n.pos.x); + neighbour_info->normal_toward_next_neighbour = (n.pos.x < 0); + } else if(neighbour_info->angle <= 5 * PI / 4) { + ASSERT(n.pos.y); + neighbour_info->normal_toward_next_neighbour = (n.pos.y < 0); + } else if(neighbour_info->angle <= 7 * PI / 4) { + ASSERT(n.pos.x); + neighbour_info->normal_toward_next_neighbour = (n.pos.x > 0); + } else { + ASSERT(n.pos.y); + neighbour_info->normal_toward_next_neighbour = (n.pos.y > 0); + } } /* Sort segments by rotation angle */ qsort(darray_neighbour_data_get(neighbourhood), neighbour_count, @@ -766,8 +791,12 @@ collect_and_link_neighbours const seg_id_t crt_id = current->seg_id; const seg_id_t ccw_id = ccw_neighbour->seg_id; /* Facing sides of segments */ - const enum side_id crt_side = crt_end ? SIDE_BACK : SIDE_FRONT; - const enum side_id ccw_side = ccw_end ? SIDE_FRONT : SIDE_BACK; + const int cw = (scn->convention == SENC2D_CONVENTION_CW); + const enum side_id crt_side + = current->normal_toward_next_neighbour == cw ? SIDE_FRONT : SIDE_BACK; + const enum side_id ccw_side + = ccw_neighbour->normal_toward_next_neighbour == cw ? + SIDE_BACK : SIDE_FRONT; /* Index of sides in segsides */ const side_id_t crt_side_idx = SEGIDxSIDE_2_SEGSIDE(crt_id, crt_side); const side_id_t ccw_side_idx = SEGIDxSIDE_2_SEGSIDE(ccw_id, ccw_side); diff --git a/src/senc2d_scene_analyze_c.h b/src/senc2d_scene_analyze_c.h @@ -137,6 +137,9 @@ struct neighbour_info { seg_id_t seg_id; /* Rank of the vertex in the segment (in [0 1]) */ unsigned char common_vertex_rank; + /* Does the geometrical normal point towards the next neighbour + * (if not, it points towards the previous one)? */ + unsigned char normal_toward_next_neighbour; }; #define DARRAY_NAME neighbour #define DARRAY_DATA struct neighbour_info diff --git a/src/senc2d_scene_c.h b/src/senc2d_scene_c.h @@ -154,6 +154,9 @@ side_range_init(struct mem_allocator* alloc, struct side_range* data) #include <rsys/dynamic_array.h> struct senc2d_scene { + /* Front / Back sides convention */ + enum senc2d_side_convention convention; + /* Segment information as given by user; no duplicates here */ struct darray_segment_in segments_in; diff --git a/src/test_senc2d_descriptor.c b/src/test_senc2d_descriptor.c @@ -39,7 +39,7 @@ main(int argc, char** argv) CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); /* A 2D square */ ctx.positions = box_vertices; diff --git a/src/test_senc2d_enclosure.c b/src/test_senc2d_enclosure.c @@ -47,7 +47,7 @@ main(int argc, char** argv) CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); s2d_attribs.type = S2D_FLOAT2; s2d_attribs.usage = S2D_POSITION; @@ -185,7 +185,7 @@ main(int argc, char** argv) /* Same 2D square, but with a hole (incomplete). * 1 single enclosure including both sides of segments */ - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CCW, &scn) == RES_OK); ctx.positions = box_vertices; ctx.indices = box_indices; diff --git a/src/test_senc2d_inconsistant_square.c b/src/test_senc2d_inconsistant_square.c @@ -0,0 +1,186 @@ +/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "senc2d.h" +#include "senc2d_s2d_wrapper.h" +#include "test_senc2d_utils.h" + +#include <rsys/double2.h> + +/* The following array lists the indices toward the 2D vertices of each +* segment. + * Y + * 2----3 | + * | | 0----X + * | | + * 0----1 +/* Segment #1 order is not consistant with other segments */ +static unsigned +inconsistant_box_indices[4/*#segments*/ * 2/*#indices per segment*/] = { + 2, 0, + 2, 3, + 3, 1, + 1, 0 +}; +static const unsigned inconsistant_box_nsegments += sizeof(inconsistant_box_indices) / (2 * sizeof(*inconsistant_box_indices)); + +/* Media definitions reflect segment #1 inconsistancy */ +static const unsigned +inconsistant_medium_front[4] = { 1, 0, 0, 0 }; +static const unsigned +inconsistant_medium_back[4] = { 0, 1, 1, 1 }; + +void +cmp_seg + (const unsigned iseg, + const struct senc2d_enclosure* enclosure, + const unsigned seg2[2], + const double* vertices2, + int* seg_eq, + int* seg_reversed) +{ + unsigned seg1[2]; + double s1[2][2]; + double s2[2][2]; + unsigned seg1_eq[2] = { 2, 2 }; + unsigned i, j; + + ASSERT(enclosure && seg2 && vertices2 && seg_eq && seg_reversed); + CHK(senc2d_enclosure_get_segment(enclosure, iseg, seg1) == RES_OK); + FOR_EACH(i, 0, 2) { + CHK(senc2d_enclosure_get_vertex(enclosure, seg1[i], s1[i]) == RES_OK); + d2_set(s2[i], vertices2 + (2 * seg2[i])); + } + FOR_EACH(i, 0, 2) { + FOR_EACH(j, 0, 2) { + if (d2_eq(s1[i], s2[j])) { + seg1_eq[i] = j; + break; + } + } + } + FOR_EACH(i, 0, 2) { + if(seg1_eq[i] == 2) { + *seg_eq = 0; + return; + } + if(seg1_eq[i] == seg1_eq[(i + 1) % 2]) { + *seg_eq = 0; + return; + } + } + /* Same 2 vertices */ + *seg_eq = 1; + + *seg_reversed = (0 != seg1_eq[0]); + ASSERT(*seg_reversed == (1 != seg1_eq[1])); +} + +void +test(enum senc2d_side_convention convention) +{ + struct mem_allocator allocator; + struct senc2d_descriptor* desc = NULL; + struct senc2d_device* dev = NULL; + struct senc2d_scene* scn = NULL; + struct senc2d_enclosure* enclosure; + struct senc2d_enclosure_header header; + enum senc2d_side_convention conv; + struct context ctx; + unsigned i, e, ecount; + + CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); + CHK(senc2d_device_create(NULL, &allocator, 1, 1, &dev) + == RES_OK); + + CHK(senc2d_scene_create(dev, convention, &scn) == RES_OK); + + /* A 2D square. + * 2 enclosures (inside, outside) sharing the same segments, + * but opposite sides. + * What differs in this test is that segment #0 vertices are given + * in the opposite order. */ + ctx.positions = box_vertices; + ctx.indices = inconsistant_box_indices; + ctx.scale = 1; + ctx.reverse_vrtx = 0; + ctx.reverse_med = 0; + d2(ctx.offset, 0, 0); + ctx.front_media = inconsistant_medium_front; + ctx.back_media = inconsistant_medium_back; + + CHK(senc2d_scene_add_geometry(scn, inconsistant_box_nsegments, get_indices, + get_media, NULL, nvertices, get_position, &ctx) == RES_OK); + + CHK(senc2d_scene_analyze(scn, &desc) == RES_OK); + + CHK(senc2d_descriptor_get_enclosure_count(desc, &ecount) == RES_OK); + CHK(ecount == 2); + + CHK(senc2d_scene_get_convention(scn, &conv) == RES_OK); + CHK(conv == convention); + + FOR_EACH(e, 0, ecount) { + unsigned medium, expected_external_medium; + char name[128]; + int common; + CHK(senc2d_descriptor_get_enclosure(desc, e, &enclosure) == RES_OK); + CHK(senc2d_enclosure_get_header(enclosure, &header) == RES_OK); + CHK(header.enclosed_media_count == 1); + CHK(senc2d_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 == SENC2D_CONVENTION_CW ? 0 : 1; + CHK(header.is_infinite == (medium == expected_external_medium)); + /* Common media, for non reversed segments */ + common = (conv == SENC2D_CONVENTION_CW) + ? !header.is_infinite : header.is_infinite; + + snprintf(name, sizeof(name), "test_inconsistant_square_%s_%u.obj", + (conv == SENC2D_CONVENTION_CW) ? "cw" : "ccw", e); + dump_enclosure(desc, e, name); + + FOR_EACH(i, 0, header.segment_count) { + int same, reversed; + cmp_seg(i, enclosure, + inconsistant_box_indices + (2 * i), box_vertices, + &same, &reversed); + /* Should be made of the same segments */ + CHK(same); + /* Segment #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)); + } + SENC2D(enclosure_ref_put(enclosure)); + } + + + SENC2D(scene_ref_put(scn)); + SENC2D(device_ref_put(dev)); + SENC2D(descriptor_ref_put(desc)); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); +} + +int main(int argc, char** argv) +{ + (void) argc, (void) argv; + + test(SENC2D_CONVENTION_CW); + test(SENC2D_CONVENTION_CCW); + return 0; +} +\ No newline at end of file diff --git a/src/test_senc2d_many_enclosures.c b/src/test_senc2d_many_enclosures.c @@ -76,7 +76,7 @@ main(int argc, char** argv) /* 64^3 = 262144 circles */ #define NB_CIRC (NB_CIRC_1 * NB_CIRC_1 * NB_CIRC_1) /* Create the scene */ - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); ctx.positions = NULL; ctx.indices = NULL; diff --git a/src/test_senc2d_many_segments.c b/src/test_senc2d_many_segments.c @@ -73,7 +73,7 @@ main(int argc, char** argv) #define NB_CIRC 4 /* Create the scene */ - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); ctx.positions = NULL; ctx.indices = NULL; diff --git a/src/test_senc2d_sample_enclosure.c b/src/test_senc2d_sample_enclosure.c @@ -48,7 +48,7 @@ main(int argc, char** argv) CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); vrtx_get.type = S2D_FLOAT2; vrtx_get.usage = S2D_POSITION; diff --git a/src/test_senc2d_scene.c b/src/test_senc2d_scene.c @@ -26,18 +26,32 @@ main(int argc, char** argv) struct senc2d_device* dev = NULL; struct senc2d_scene* scn = NULL; struct senc2d_descriptor* desc = NULL; + struct senc2d_enclosure* enc = NULL; + struct senc2d_enclosure_header header; struct context ctx; + unsigned medcw[2], medccw[2]; unsigned count, i, maxm; + enum senc2d_side_convention convention; (void)argc, (void)argv; CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); CHK(senc2d_device_create(NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); - CHK(senc2d_scene_create(NULL, &scn) == RES_BAD_ARG); - CHK(senc2d_scene_create(dev, NULL) == RES_BAD_ARG); - CHK(senc2d_scene_create(NULL, NULL) == RES_BAD_ARG); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(NULL, SENC2D_CONVENTION_CW, &scn) == RES_BAD_ARG); + CHK(senc2d_scene_create(dev, 5, &scn) == RES_BAD_ARG); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_create(NULL, 5, &scn) == RES_BAD_ARG); + CHK(senc2d_scene_create(NULL, SENC2D_CONVENTION_CW, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_create(dev, 5, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_create(NULL, 5, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); + + CHK(senc2d_scene_get_convention(NULL, &convention) == RES_BAD_ARG); + CHK(senc2d_scene_get_convention(scn, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_convention(NULL, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_convention(scn, &convention) == RES_OK); + CHK(convention == SENC2D_CONVENTION_CW); CHK(senc2d_scene_get_segments_count(NULL, &count) == RES_BAD_ARG); CHK(senc2d_scene_get_segments_count(scn, NULL) == RES_BAD_ARG); @@ -63,7 +77,9 @@ main(int argc, char** argv) CHK(senc2d_scene_get_unique_vertices_count(scn, &count) == RES_OK); CHK(count == 0); - /* A 2D square */ + /* A 2D square + * With this geometry front is inside with CCW convention, + * outside with CW convention */ ctx.positions = box_vertices; ctx.indices = box_indices; ctx.scale = 1; @@ -111,10 +127,17 @@ main(int argc, char** argv) CHK(senc2d_scene_ref_put(scn) == RES_OK); CHK(senc2d_descriptor_ref_put(desc) == RES_OK); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CCW, &scn) == RES_OK); + CHK(senc2d_scene_get_convention(scn, &convention) == RES_OK); + CHK(convention == SENC2D_CONVENTION_CCW); CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media, get_global_id, nvertices, get_position, &ctx) == RES_OK); CHK(senc2d_scene_analyze(scn, &desc) == RES_OK); + /* Check that medium 0 is inside */ + CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 0, &enc) == RES_OK); + CHK(senc2d_enclosure_get_header(enc, &header) == RES_OK); + CHK(!header.is_infinite); + CHK(senc2d_enclosure_ref_put(enc) == RES_OK); FOR_EACH(i, 0, nsegments) { unsigned gid; @@ -122,11 +145,12 @@ main(int argc, char** argv) /* gid has been set to gid_face. */ CHK(gid == gid_face[i]); } + CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medccw) == RES_OK); ctx.front_media = medium1_3; CHK(senc2d_scene_ref_put(scn) == RES_OK); CHK(senc2d_descriptor_ref_put(desc) == RES_OK); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media, get_global_id, nvertices, get_position, &ctx) == RES_OK); /* Medium mismatch between neighbour segments, but OK */ @@ -147,10 +171,15 @@ main(int argc, char** argv) ctx.front_media = medium0; CHK(senc2d_scene_ref_put(scn) == RES_OK); CHK(senc2d_descriptor_ref_put(desc) == RES_OK); - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media, NULL, nvertices, get_position, &ctx) == RES_OK); CHK(senc2d_scene_analyze(scn, &desc) == RES_OK); + /* Check that medium 0 is outside */ + CHK(senc2d_descriptor_get_enclosure_by_medium(desc, 0, 0, &enc) == RES_OK); + CHK(senc2d_enclosure_get_header(enc, &header) == RES_OK); + CHK(header.is_infinite); + CHK(senc2d_enclosure_ref_put(enc) == RES_OK); FOR_EACH(i, 0, nsegments) { unsigned gid; @@ -158,6 +187,8 @@ main(int argc, char** argv) /* Default gid: segments rank. */ CHK(gid == i); } + CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medcw) == RES_OK); + FOR_EACH(i, 0, 2) CHK(medccw[i] == medcw[i]); /* Invalid vertex ID */ CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media, NULL, diff --git a/src/test_senc2d_square_behind_square.c b/src/test_senc2d_square_behind_square.c @@ -34,7 +34,7 @@ main(int argc, char** argv) (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); /* Create the scene */ - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); ctx.positions = box_vertices; ctx.indices = box_indices; diff --git a/src/test_senc2d_square_in_square.c b/src/test_senc2d_square_in_square.c @@ -34,7 +34,7 @@ main(int argc, char** argv) (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); /* Create the scene */ - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); ctx.positions = box_vertices; ctx.indices = box_indices; diff --git a/src/test_senc2d_square_on_square.c b/src/test_senc2d_square_on_square.c @@ -57,7 +57,7 @@ main(int argc, char** argv) (NULL, &allocator, SENC2D_NTHREADS_DEFAULT, 1, &dev) == RES_OK); /* Create the scene */ - CHK(senc2d_scene_create(dev, &scn) == RES_OK); + CHK(senc2d_scene_create(dev, SENC2D_CONVENTION_CW, &scn) == RES_OK); ctx.positions = square_vertices; /* Need true squares for squares #1 and #2 */ ctx.indices = box_indices;