commit 540f554e72d993c378c2234abaf9e51c6cad8d79
parent 39229d66530452f2981389409df646172141cdad
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 11 Feb 2019 15:45:04 +0100
Add API calls to access to geometry frontiers
Diffstat:
5 files changed, 112 insertions(+), 14 deletions(-)
diff --git a/src/senc2d.h b/src/senc2d.h
@@ -278,6 +278,17 @@ senc2d_descriptor_get_global_segment_global_id
unsigned* gid);
SENC2D_API res_T
+senc2d_descriptor_get_frontier_vertices_count
+ (const struct senc2d_descriptor* descriptor,
+ unsigned* count); /* Number of frontier vertices. */
+
+SENC2D_API res_T
+senc2d_descriptor_get_frontier_vertex
+ (const struct senc2d_descriptor* descriptor,
+ const unsigned iver,
+ unsigned* vrtx_id);
+
+SENC2D_API res_T
senc2d_descriptor_ref_get
(struct senc2d_descriptor* descriptor);
diff --git a/src/senc2d_descriptor.c b/src/senc2d_descriptor.c
@@ -37,6 +37,7 @@ descriptor_release(ref_T * ref)
darray_segment_enc_release(&desc->segments_enc);
darray_enclosure_release(&desc->enclosures);
darray_enc_ids_array_release(&desc->enc_ids_array_by_medium);
+ darray_vrtx_id_release(&desc->frontiers);
MEM_RM(scn->dev->allocator, desc);
SENC2D(scene_ref_put(scn));
@@ -61,6 +62,7 @@ descriptor_create(struct senc2d_scene* scn)
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, scn->nmeds));
+ darray_vrtx_id_init(scn->dev->allocator, &desc->frontiers);
/* Enclosure 0 is always defined for infinite */
OK(darray_enclosure_resize(&desc->enclosures, 1));
desc->enclosures_count = 1;
@@ -276,6 +278,35 @@ senc2d_descriptor_get_global_segment_global_id
}
res_T
+senc2d_descriptor_get_frontier_vertices_count
+ (const struct senc2d_descriptor* desc,
+ unsigned* count)
+{
+ size_t tmp;
+ if(!desc || !count)
+ return RES_BAD_ARG;
+ tmp = darray_vrtx_id_size_get(&desc->frontiers);
+ ASSERT(tmp < UINT_MAX);
+ *count = (unsigned)tmp;
+ return RES_OK;
+}
+
+res_T
+senc2d_descriptor_get_frontier_vertex
+ (const struct senc2d_descriptor* desc,
+ const unsigned iver,
+ unsigned* vrtx_id)
+{
+ vrtx_id_t vrtx;
+ if(!vrtx_id || !desc
+ || iver >= darray_vrtx_id_size_get(&desc->frontiers))
+ return RES_BAD_ARG;
+ vrtx = darray_vrtx_id_cdata_get(&desc->frontiers)[iver];
+ *vrtx_id = (unsigned)vrtx; /* Back to API type */
+ return RES_OK;
+}
+
+res_T
senc2d_descriptor_ref_get(struct senc2d_descriptor* desc)
{
if(!desc) return RES_BAD_ARG;
diff --git a/src/senc2d_descriptor_c.h b/src/senc2d_descriptor_c.h
@@ -94,6 +94,8 @@ struct senc2d_descriptor {
struct darray_enc_ids_array enc_ids_array_by_medium;
seg_id_t segment_count;
vrtx_id_t vertices_count;
+ /* Store frontiers */
+ struct darray_vrtx_id frontiers;
ref_T ref;
};
diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c
@@ -669,6 +669,7 @@ collect_and_link_neighbours
struct segside* segsides,
struct darray_segment_tmp* segments_tmp_array,
struct darray_neighbourhood* neighbourhood_by_vertex,
+ struct darray_vrtx_id* frontiers,
/* Shared error status.
* We accept to overwrite an error with a different error */
res_T* res)
@@ -686,7 +687,7 @@ collect_and_link_neighbours
seg_id_t s;
ASSERT(scn && segsides && segments_tmp_array
- && neighbourhood_by_vertex && res);
+ && neighbourhood_by_vertex && frontiers && res);
ASSERT((size_t)scn->nuverts + (size_t)scn->nusegs + 2 <= EDGE_MAX__);
segments_in = darray_segment_in_cdata_get(&scn->segments_in);
@@ -875,12 +876,12 @@ collect_and_link_neighbours
* - different media on its sides */
if(neighbour_count == 1
&& p_crt_side->medium != p_ccw_side->medium)
+#pragma omp critical
{
log_warn(scn->dev,
- "%s: found possible hole involving segment %lu.\n"
- " Vertex: %g %g %g\n",
- FUNC_NAME, (unsigned long)segments_in[crt_id].global_id,
- SPLIT3(vertices[v].vec));
+ "%s: found possible frontier involving segment %lu.\n",
+ FUNC_NAME, (unsigned long)segments_in[crt_id].global_id);
+ darray_vrtx_id_push_back(frontiers, &v);
}
}
}
@@ -892,6 +893,7 @@ build_result
(struct senc2d_descriptor* desc,
const struct darray_ptr_component_descriptor* connex_components,
const struct darray_segment_comp* segments_comp_array,
+ struct darray_vrtx_id* frontiers,
/* Shared error status.
* We accept to overwrite an error with a different error */
res_T* res)
@@ -910,7 +912,7 @@ build_result
int64_t sg;
int64_t ee;
- ASSERT(desc && connex_components && segments_comp_array && res);
+ ASSERT(desc && connex_components && segments_comp_array && frontiers && res);
alloc = descriptor_get_allocator(desc);
scn = desc->scene;
@@ -918,7 +920,8 @@ build_result
normals_front = (scn->convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0;
normals_back = (scn->convention & SENC2D_CONVENTION_NORMAL_BACK) != 0;
ASSERT(normals_back != normals_front);
- ASSERT(output_normal_in != ((scn->convention & SENC2D_CONVENTION_NORMAL_OUTSIDE) != 0));
+ ASSERT(output_normal_in !=
+ ((scn->convention & SENC2D_CONVENTION_NORMAL_OUTSIDE) != 0));
ASSERT(darray_ptr_component_descriptor_size_get(connex_components)
<= COMPONENT_MAX__);
cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components);
@@ -1083,6 +1086,10 @@ build_result
*res = tmp_res;
} /* No barrier here */
htable_vrtx_id_release(&vtable);
+ /* The first thread here copies frontiers into descriptor */
+#pragma omp single nowait
+ darray_vrtx_id_copy_and_clear(&desc->frontiers, frontiers);
+ /* No barrier here */
}
/*******************************************************************************
@@ -1101,6 +1108,9 @@ senc2d_scene_analyze
* They are refered to by arrays of ids. */
struct darray_ptr_component_descriptor connex_components;
char connex_components_initialized = 0;
+ /* Array of frontiers vertices */
+ struct darray_vrtx_id frontiers;
+ char frontiers_initialized = 0;
/* Store by-segment components */
struct darray_segment_comp segments_comp;
char segments_comp_initialized = 0;
@@ -1129,6 +1139,8 @@ senc2d_scene_analyze
darray_segment_tmp_init(scn->dev->allocator, &segments_tmp);
segments_tmp_initialized = 1;
+ darray_vrtx_id_init(scn->dev->allocator, &frontiers);
+ frontiers_initialized = 1;
OK(darray_segment_tmp_resize(&segments_tmp, scn->nusegs));
segsides
@@ -1160,7 +1172,7 @@ senc2d_scene_analyze
{
/* Step 1: build neighbourhoods */
collect_and_link_neighbours(scn, segsides, &segments_tmp,
- &neighbourhood_by_vertex, &res);
+ &neighbourhood_by_vertex, &frontiers, &res);
/* No barrier at the end of step 1: data used in step 1 cannot be
* released / data produced by step 1 cannot be used
* until next sync point */
@@ -1257,7 +1269,8 @@ senc2d_scene_analyze
} /* No barrier here */
/* Step 4: Build result */
- build_result(desc, &connex_components, &segments_comp, &res);
+ build_result(desc, &connex_components, &segments_comp, &frontiers,
+ &res);
/* No barrier at the end of step 4: data used in step 4 cannot be
* released / data produced by step 4 cannot be used
* until next sync point */
@@ -1300,6 +1313,7 @@ exit:
darray_neighbourhood_release(&neighbourhood_by_vertex);
if(segments_tmp_initialized) darray_segment_tmp_release(&segments_tmp);
if(segments_comp_initialized) darray_segment_comp_release(&segments_comp);
+ if(frontiers_initialized) darray_vrtx_id_release(&frontiers);
if(segsides) MEM_RM(scn->dev->allocator, segsides);
if(desc) *out_desc = desc;
diff --git a/src/test_senc2d_descriptor.c b/src/test_senc2d_descriptor.c
@@ -157,10 +157,10 @@ main(int argc, char** argv)
CHK(senc2d_descriptor_get_global_segment_media(desc, 0, media) == RES_OK);
CHK(media[0] == ctx.front_media[0] && media[1] == ctx.back_media[1]);
- CHK(senc2d_descriptor_get_global_segment_enclosures(
- NULL, 0, enclosures) == RES_BAD_ARG);
- CHK(senc2d_descriptor_get_global_segment_enclosures(
- NULL, nvertices, enclosures) == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_global_segment_enclosures(NULL, 0, enclosures)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_global_segment_enclosures(NULL, nvertices, enclosures)
+ == RES_BAD_ARG);
CHK(senc2d_descriptor_get_global_segment_enclosures(desc, 0, NULL)
== RES_BAD_ARG);
CHK(senc2d_descriptor_get_global_segment_enclosures(desc, 0, enclosures)
@@ -191,10 +191,50 @@ main(int argc, char** argv)
nvertices, get_position, &ctx) == RES_BAD_ARG);
CHK(senc2d_scene_ref_put(scn) == RES_OK);
- CHK(senc2d_device_ref_put(dev) == RES_OK);
if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+ desc = NULL;
CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
+ /* Same square with a hole (last segment is missing) */
+ CHK(senc2d_scene_create(dev,
+ SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
+ == RES_OK);
+
+ CHK(senc2d_scene_add_geometry(scn, nsegments - 1, get_indices, get_media,
+ NULL, nvertices, get_position, &ctx) == RES_OK);
+
+ CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
+
+ CHK(senc2d_descriptor_get_frontier_vertices_count(NULL, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertices_count(desc, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertices_count(NULL, &count)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertices_count(desc, &count)
+ == RES_OK);
+
+ CHK(senc2d_descriptor_get_frontier_vertex(NULL, count, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(desc, count, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(NULL, 0, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(NULL, count, indices)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(desc, 0, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(desc, count, indices)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(NULL, 0, indices)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_frontier_vertex(desc, 0, indices)
+ == RES_OK);
+
+ CHK(senc2d_scene_ref_put(scn) == RES_OK);
+ CHK(senc2d_device_ref_put(dev) == RES_OK);
+ if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
+
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
CHK(mem_allocated_size() == 0);