star-2d

Contour structuring for efficient 2D geometric queries
git clone git://git.meso-star.fr/star-2d.git
Log | Files | Refs | README | LICENSE

commit fe052cd51bcfc28b62bd26ae3bf7d3c242efeb83
parent 17f2ac4e9322ab6b88ab7ea33524c1938436ffc8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 20 Jun 2016 11:33:38 +0200

Implement the s2d_shape API

Diffstat:
Mcmake/CMakeLists.txt | 6++++--
Msrc/s2d_device.c | 2++
Msrc/s2d_device_c.h | 7+++++++
Msrc/s2d_line_segments.h | 12++++++++++--
Asrc/s2d_shape.c | 254+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/s2d_shape_c.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 328 insertions(+), 4 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -57,12 +57,14 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(S2D_FILES_SRC s2d_device.c - s2d_line_segments.c) + s2d_line_segments.c + s2d_shape.c) set(S2D_FILES_INC_API s2d.h) set(S2D_FILES_INC s2d_buffer.h s2d_device_c.h - s2d_line_segments.h) + s2d_line_segments.h + s2d_shape_c.h) set(S2D_FILES_DOC COPYING.fr COPYING.en README.md) # Prepend each file in the `S2D_FILES_<SRC|INC>' list by `S2D_SOURCE_DIR' diff --git a/src/s2d_device.c b/src/s2d_device.c @@ -41,6 +41,7 @@ device_release(ref_T* ref) struct s2d_device* dev; ASSERT(ref); dev = CONTAINER_OF(ref, struct s2d_device, ref); + flist_name_release(&dev->names); rtcDeleteDevice(dev->rtc); MEM_RM(dev->allocator, dev); } @@ -73,6 +74,7 @@ s2d_device_create dev->logger = logger ? logger : LOGGER_DEFAULT; dev->allocator = allocator; dev->verbose = verbose; + flist_name_init(allocator, &dev->names); ref_init(&dev->ref); dev->rtc = rtcNewDevice(verbose ? "verbose=1" : NULL); diff --git a/src/s2d_device_c.h b/src/s2d_device_c.h @@ -32,6 +32,11 @@ #include "s2d_backend.h" #include <rsys/ref_count.h> +#include <rsys/free_list.h> + +struct name { FITEM; }; +#define FITEM_TYPE name +#include <rsys/free_list.h> struct s2d_device { int verbose; @@ -40,6 +45,8 @@ struct s2d_device { RTCDevice rtc; /* Embree device */ + struct flist_name names; /* List of shape id */ + ref_T ref; }; diff --git a/src/s2d_line_segments.h b/src/s2d_line_segments.h @@ -52,10 +52,17 @@ enum buffer_type { VERTEX_BUFFER = BIT(1) }; +/* Filter function and its associated user defined data */ +struct hit_filter { + s2d_hit_filter_function_T func; + void* data; +}; + struct line_segments { /* Segmented contour */ struct index_buffer* indices; struct vertex_buffer* attribs[S2D_ATTRIBS_COUNT__]; enum s2d_type attribs_type[S2D_ATTRIBS_COUNT__]; + struct hit_filter filter; int resize_mask; /* Combination of buffer_type */ int update_mask; /* Combination of buffer_type */ @@ -66,7 +73,7 @@ struct line_segments { /* Segmented contour */ extern LOCAL_SYM res_T line_segments_create (struct s2d_device* dev, - struct line_segments* line); + struct line_segments** line); extern LOCAL_SYM void line_segments_ref_get @@ -98,7 +105,8 @@ line_segments_get_pos extern LOCAL_SYM float* line_segments_get_attr - (struct line_segments* line); + (struct line_segments* line, + const enum s2d_attrib_usage usage); extern LOCAL_SYM float line_segments_compute_length diff --git a/src/s2d_shape.c b/src/s2d_shape.c @@ -0,0 +1,254 @@ +/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com) + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. */ + +#include "s2d.h" +#include "s2d_c.h" +#include "s2d_device_c.h" +#include "s2d_line_segments.h" +#include "s2d_shape_c.h" + +#include <rsys/mem_allocator.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +shape_release(ref_T* ref) +{ + struct s2d_shape* shape; + struct s2d_device* dev; + ASSERT(ref); + shape = CONTAINER_OF(ref, struct s2d_shape, ref); + dev = shape->dev; + + /* The shape should not be attached */ + ASSERT(is_list_empty(&shape->scene_attachment)); + line_segments_ref_put(shape->line); + MEM_RM(dev->allocator, shape); + S2D(device_ref_put(dev)); +} + +/******************************************************************************* + * Exported s2d_shape functions + ******************************************************************************/ +res_T +s2d_shape_create_line_segments + (struct s2d_device* dev, struct s2d_shape** out_shape) +{ + struct s2d_shape* shape = NULL; + res_T res = RES_OK; + if(!dev || !out_shape) { + res = RES_BAD_ARG; + goto error; + } + + shape = (struct s2d_shape*) + MEM_CALLOC(dev->allocator, 1, sizeof(struct s2d_shape)); + if(!shape) { + res = RES_MEM_ERR; + goto error; + } + list_init(&shape->scene_attachment); + S2D(device_ref_get(dev)); + shape->dev = dev; + ref_init(&shape->ref); + shape->id = flist_name_add(&dev->names); + shape->is_enabled = 1; + shape->flip_contour = 0; + + res = line_segments_create(dev, &shape->line); + if(res != RES_OK) goto error; + +exit: + if(out_shape) *out_shape = shape; + return res; +error: + if(shape) { + S2D(shape_ref_put(shape)); + shape = NULL; + } + goto exit; +} + +res_T +s2d_shape_ref_get(struct s2d_shape* shape) +{ + if(!shape) return RES_BAD_ARG; + ref_get(&shape->ref); + return RES_OK; +} + +res_T +s2d_shape_ref_put(struct s2d_shape* shape) +{ + if(!shape) return RES_BAD_ARG; + ref_put(&shape->ref, shape_release); + return RES_OK; +} + +res_T +s2d_shape_get_id(struct s2d_shape* shape, unsigned* id) +{ + if(!shape || !id) return RES_BAD_ARG; + *id = shape->id.index; + return RES_OK; +} + +res_T +s2d_shape_enable(struct s2d_shape* shape, const char enable) +{ + if(!shape) return RES_BAD_ARG; + shape->is_enabled = enable; + return RES_BAD_ARG; +} + +res_T +s2d_shape_is_enabled(struct s2d_shape* shape, char* is_enabled) +{ + if(!shape || !is_enabled) return RES_BAD_ARG; + *is_enabled = shape->is_enabled; + return RES_OK; +} + +res_T +s2d_shape_flip_contour(struct s2d_shape* shape) +{ + if(!shape) return RES_BAD_ARG; + shape->flip_contour ^= 1; + return RES_OK; +} + +res_T +s2d_line_segments_setup_indexed_vertices + (struct s2d_shape* shape, + const unsigned nsegments, + void (*get_indices) + (const unsigned isegment, unsigned ids[2], void* ctx), + const unsigned nverts, + struct s2d_vertex_data attribs[], + const unsigned nattribs, + void* data) +{ + if(!shape) return RES_BAD_ARG; + return line_segments_setup_indexed_vertices + (shape->line, nsegments, get_indices, nverts, attribs, nattribs, data); +} + +res_T +s2d_line_segments_copy(const struct s2d_shape* src, struct s2d_shape* dst) +{ + if(!src || !dst) return RES_BAD_ARG; + if(src == dst) return RES_OK; + dst->flip_contour = src->flip_contour; + dst->is_enabled = src->is_enabled; + line_segments_copy_indexed_vertices(src->line, dst->line); + return RES_OK; +} + +res_T +s2d_line_segments_get_vertices_count + (const struct s2d_shape* shape, unsigned* nverts) +{ + if(!shape || !nverts) return RES_BAD_ARG; + *nverts = (unsigned)line_segments_get_nverts(shape->line); + return RES_OK; +} + +res_T +s2d_line_segments_get_vertex_attrib + (const struct s2d_shape* shape, + const unsigned ivert, + const enum s2d_attrib_usage usage, + struct s2d_attrib* attrib) +{ + const float* data; + unsigned i, dim; + + if(!shape + || (unsigned)usage >= S2D_ATTRIBS_COUNT__ + || !shape->line->attribs[usage] + || !attrib + || ivert >= (unsigned)line_segments_get_nverts(shape->line)) + return RES_BAD_ARG; + + attrib->usage = usage; + attrib->type = shape->line->attribs_type[usage]; + + dim = s2d_type_get_dimension(attrib->type); + data = line_segments_get_attr(shape->line, usage) + ivert * dim; + FOR_EACH(i, 0, dim) attrib->value[i] = data[i]; + return RES_OK; +} + +res_T +s2d_line_segments_get_segments_count + (const struct s2d_shape* shape, unsigned* nsegments) +{ + if(!shape || !nsegments) return RES_BAD_ARG; + *nsegments = (unsigned)line_segments_get_nsegments(shape->line); + return RES_OK; +} + +res_T +s2d_line_segments_get_segment_indices + (const struct s2d_shape* shape, + const unsigned isegment, + unsigned ids[2]) +{ + const unsigned* data; + if(!shape + || !ids + || isegment >= (unsigned)line_segments_get_nsegments(shape->line)) + return RES_BAD_ARG; + + data = line_segments_get_ids(shape->line) + isegment * 2/*#ids per segment*/; + ids[0] = data[0]; + ids[1] = data[1]; + return RES_OK; +} + +res_T +s2d_line_segments_set_hit_filter_function + (struct s2d_shape* shape, + s2d_hit_filter_function_T func, + void* data) +{ + if(!shape) return RES_BAD_ARG; + shape->line->filter.func = func; + shape->line->filter.data = data; + return RES_OK; +} + +res_T +s2d_line_segments_get_hit_filter_data(struct s2d_shape* shape, void** data) +{ + if(!shape || !data) return RES_BAD_ARG; + *data = shape->line->filter.data; + return RES_OK; +} + diff --git a/src/s2d_shape_c.h b/src/s2d_shape_c.h @@ -0,0 +1,51 @@ +/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com) + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. */ + +#ifndef S2D_SHAPE_C_H +#define S2D_SHAPE_C_H + +#include <rsys/list.h> +#include <rsys/ref_count.h> + +struct s3d_device; +struct line_segments; + +struct s2d_shape { + struct list_node scene_attachment; + struct fid id; /* Uname identifier of the shape */ + + char flip_contour; + char is_enabled; + + struct line_segments* line; + struct s2d_device* dev; + ref_T ref; +}; + +#endif /* S2D_SHAPE_C_H */ +