star-3d

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

commit 2032710b9aab7c02cc55bf4af237d4ade1f479a3
parent 33e91495fd3f5db1d379b5944a6b90be0c4b15dd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 17 Jun 2015 12:16:54 +0200

Fix the scene clear|detach_shape function

The `clear' and `detach_shape' process could be called on a scene on
which a `begin_trace' was invoked. These actions deleted back-end data
that must be valid during the whole trace session.

Now, the `clear' and `detach_shape' functions return a RES_BAD_OP code if
they are called on a traceable scene.

Diffstat:
Msrc/s3d.h | 9+++++----
Msrc/s3d_scene.c | 12+++++++-----
Msrc/test_s3d_scene.c | 6++++++
3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/s3d.h b/src/s3d.h @@ -221,10 +221,11 @@ s3d_scene_clear /* Synchronize the scene geometry with the geometry of its attached shapes. If * a s3d_scene_begin_trace is already active on `scn' or one of its attached - * instance a RES_BAD_OP error is returned. On success no other begin trace can - * be invoked on `scn' and its attached instances until s3d_scene_end_trace is - * called. A s3d_scene_trace_ray operation can be invoked on `scn' only between - * a s3d_scene_begin_trace and s3d_scene_end_trace call. */ + * instance a RES_BAD_OP error is returned. On success neither another begin + * trace nor a clear or shape_detach can be invoked on `scn' and its attached + * instances until s3d_scene_end_trace is called. A s3d_scene_trace_ray + * operation can be invoked on `scn' only between a s3d_scene_begin_trace and + * s3d_scene_end_trace call. */ S3D_API res_T s3d_scene_begin_trace (struct s3d_scene* scn); diff --git a/src/s3d_scene.c b/src/s3d_scene.c @@ -144,7 +144,6 @@ scene_build_clear(struct s3d_scene* scn) } } darray_inst_clear(&scn->instances); - scn->is_rtc_scn_outdated = 0; scn->build_type = BUILD_NONE; } @@ -326,6 +325,7 @@ scene_detach_shape_mesh(struct s3d_scene* scn, struct s3d_shape* shape) if(mesh->geom.irtc != RTC_INVALID_GEOMETRY_ID) { rtcDeleteGeometry(scn->rtc_scn, mesh->geom.irtc); mesh->geom.irtc = RTC_INVALID_GEOMETRY_ID; + scn->is_rtc_scn_outdated = 1; } mesh_ref_put(mesh); htable_mesh_erase(&scn->cached_meshes, &shape); @@ -389,8 +389,10 @@ scene_build(struct s3d_scene* scn, const enum build_type type) if(res != RES_OK) goto error; } - if(scn->is_rtc_scn_outdated) + if(scn->is_rtc_scn_outdated) { rtcCommit(scn->rtc_scn); + scn->is_rtc_scn_outdated = 0; + } scn->build_type = type; @@ -533,6 +535,7 @@ s3d_scene_detach_shape(struct s3d_scene* scn, struct s3d_shape* shape) { char is_attached; if(!scn || !shape) return RES_BAD_ARG; + if(scn->build_type != BUILD_NONE) return RES_BAD_OP; if(!(S3D(shape_is_attached(shape, &is_attached)), is_attached)) return RES_BAD_ARG; #ifndef NDEBUG @@ -554,9 +557,8 @@ res_T s3d_scene_clear(struct s3d_scene* scn) { struct list_node* node, *tmp; - if(!scn) - return RES_BAD_ARG; - + if(!scn) return RES_BAD_ARG; + if(scn->build_type != BUILD_NONE) return RES_BAD_OP; LIST_FOR_EACH_SAFE(node, tmp, &scn->shapes) { struct s3d_shape* shape = CONTAINER_OF (node, struct s3d_shape, scene_attachment); diff --git a/src/test_s3d_scene.c b/src/test_s3d_scene.c @@ -89,6 +89,7 @@ main(int argc, char** argv) CHECK(s3d_scene_is_traceable(scn, &b), RES_OK); CHECK(b, 0); + CHECK(s3d_scene_attach_shape(scn, shapes[0]), RES_OK); CHECK(s3d_scene_begin_trace(NULL), RES_BAD_ARG); CHECK(s3d_scene_begin_trace(scn), RES_OK); CHECK(s3d_scene_begin_trace(scn), RES_BAD_OP); @@ -96,6 +97,9 @@ main(int argc, char** argv) CHECK(s3d_scene_is_traceable(scn, &b), RES_OK); CHECK(b, 1); + CHECK(s3d_scene_clear(scn), RES_BAD_OP); + CHECK(s3d_scene_detach_shape(scn, shapes[0]), RES_BAD_OP); + CHECK(s3d_scene_end_trace(NULL), RES_BAD_ARG); CHECK(s3d_scene_end_trace(scn), RES_OK); CHECK(s3d_scene_end_trace(scn), RES_BAD_OP); @@ -103,6 +107,8 @@ main(int argc, char** argv) CHECK(s3d_scene_is_traceable(scn, &b), RES_OK); CHECK(b, 0); + CHECK(s3d_scene_detach_shape(scn, shapes[0]), RES_OK); + CHECK(s3d_shape_ref_put(shapes[0]), RES_OK); CHECK(s3d_shape_ref_put(shapes[1]), RES_OK); CHECK(s3d_shape_ref_put(shapes[2]), RES_OK);