commit 3c33496b28657f576404c487b0bbdf4a3f834344
parent 10345c084a53917caa88af238cb8e3313a27fbcf
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 18 Oct 2016 16:34:31 +0200
Implement the SGF 3D scene
Diffstat:
7 files changed, 253 insertions(+), 16 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -50,6 +50,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SGF_FILES_SRC
sgf_device.c
sgf_estimator.c
+ sgf_scene.c
sgf_shape.c)
set(SGF_FILES_INC_API sgf.h)
set(SGF_FILES_INC
diff --git a/src/sgf.h b/src/sgf.h
@@ -159,7 +159,7 @@ sgf_shape3d_setup
******************************************************************************/
SGF_API res_T
sgf_scene3d_create
- (struct sgf_device,
+ (struct sgf_device* dev,
struct sgf_scene** scn);
SGF_API res_T
diff --git a/src/sgf_device.c b/src/sgf_device.c
@@ -123,3 +123,17 @@ log_error(struct sgf_device* dev, const char* msg, ...)
}
+void
+log_warning(struct sgf_device* dev, const char* msg, ...)
+{
+ va_list vargs;
+ res_T res; (void)res;
+ ASSERT(dev && msg);
+
+ if(!dev->verbose) return;
+
+ va_start(vargs, msg);
+ res = logger_vprint(dev->logger, LOG_WARNING, msg, vargs);
+ ASSERT(res == RES_OK);
+ va_end(vargs);
+}
diff --git a/src/sgf_device_c.h b/src/sgf_device_c.h
@@ -43,6 +43,18 @@ log_error
#endif
;
+/* Conditionally log a message on the LOG_WARNING stream of the device logger,
+ * with respect to the device verbose flag */
+extern LOCAL_SYM void
+log_warning
+ (struct sgf_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
#endif /* SGF_DEVICE_C_H */
diff --git a/src/sgf_scene.c b/src/sgf_scene.c
@@ -0,0 +1,186 @@
+/* Copyright (C) 2015-2016 EDF S.A., France (syrthes-support@edf.fr)
+ *
+ * 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 "sgf.h"
+#include "sgf_device_c.h"
+#include "sgf_shape_c.h"
+
+#include <rsys/hash_table.h>
+#include <rsys/ref_count.h>
+
+#include <star/s3d.h>
+
+/* Define the htable_shape data structure */
+#define HTABLE_NAME shape
+#define HTABLE_KEY unsigned /* S3D object instance identifier */
+#define HTABLE_DATA struct sgf_shape*
+#include <rsys/hash_table.h>
+
+struct sgf_scene {
+ struct s3d_scene* s3d_scn;
+ struct htable_shape shapes; /* Map S3D shape id to its SGF shape */
+
+ ref_T ref;
+ struct sgf_device* dev;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+scene_release(ref_T* ref)
+{
+ struct sgf_device* dev;
+ struct sgf_scene* scn;
+ ASSERT(ref);
+ scn = CONTAINER_OF(ref, struct sgf_scene, ref);
+ dev = scn->dev;
+ SGF(scene_clear(scn));
+ if(scn->s3d_scn) S3D(scene_ref_put(scn->s3d_scn));
+ htable_shape_release(&scn->shapes);
+ MEM_RM(dev->allocator, scn);
+ SGF(device_ref_put(dev));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sgf_scene3d_create(struct sgf_device* dev, struct sgf_scene** out_scn)
+{
+ struct sgf_scene* scn = NULL;
+ res_T res = RES_OK;
+
+ if(!dev || !out_scn) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct sgf_scene));
+ if(!scn) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&scn->ref);
+ SGF(device_ref_get(dev));
+ scn->dev = dev;
+ htable_shape_init(dev->allocator, &scn->shapes);
+
+ res = s3d_scene_create(dev->s3d, &scn->s3d_scn);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(out_scn) *out_scn = scn;
+error:
+ if(scn) {
+ SGF(scene_ref_put(scn));
+ scn = NULL;
+ }
+ goto exit;
+}
+
+res_T
+sgf_scene_ref_get(struct sgf_scene* scn)
+{
+ if(!scn) return RES_BAD_ARG;
+ ref_get(&scn->ref);
+ return RES_OK;
+}
+
+res_T
+sgf_scene_ref_put(struct sgf_scene* scn)
+{
+ if(!scn) return RES_BAD_ARG;
+ ref_put(&scn->ref, scene_release);
+ return RES_OK;
+}
+
+res_T
+sgf_scene_attach_shape(struct sgf_scene* scn, struct sgf_shape* shape)
+{
+ unsigned id;
+ struct sgf_shape** pshape;
+ res_T res = RES_OK;
+
+ if(!scn || !shape) return RES_BAD_ARG;
+
+ res = s3d_scene_attach_shape(scn->s3d_scn, shape->s3d_shape);
+ if(res != RES_OK) return res;
+
+ S3D(shape_get_id(shape->s3d_shape, &id));
+ pshape = htable_shape_find(&scn->shapes, &id);
+ if(pshape) { /* Already attached */
+ ASSERT(*pshape == shape);
+ log_warning(scn->dev,
+ "%s: the shape is already attached to the scene.\n", FUNC_NAME);
+ return RES_OK;
+ }
+
+ res = htable_shape_set(&scn->shapes, &id, &shape);
+ if(res != RES_OK) {
+ S3D(scene_detach_shape(scn->s3d_scn, shape->s3d_shape));
+ return res;
+ }
+ SGF(shape_ref_get(shape));
+ return RES_OK;
+}
+
+res_T
+sgf_scene_detach_shape(struct sgf_scene* scn, struct sgf_shape* shape)
+{
+ struct sgf_shape** pshape;
+ unsigned id;
+ size_t n;
+ (void)n;
+
+ if(!scn || !shape) return RES_BAD_ARG;
+
+ /* Retrieve the shape identifier */
+ S3D(shape_get_id(shape->s3d_shape, &id));
+
+ /* Check that the shape is effectively attached to the scene */
+ pshape = htable_shape_find(&scn->shapes, &id);
+ if(!pshape) {
+ log_error(scn->dev,
+ "%s: the shape is not attached to the scene.\n", FUNC_NAME);
+ return RES_BAD_ARG;
+ }
+ ASSERT(shape == *pshape);
+
+ n = htable_shape_erase(&scn->shapes, &id);
+ ASSERT(n == 1);
+ S3D(scene_detach_shape(scn->s3d_scn, shape->s3d_shape));
+ SGF(shape_ref_put(shape));
+ return RES_OK;
+}
+
+res_T
+sgf_scene_clear(struct sgf_scene* scn)
+{
+ struct htable_shape_iterator it, end;
+ if(!scn) return RES_BAD_ARG;
+
+ htable_shape_begin(&scn->shapes, &it);
+ htable_shape_end(&scn->shapes, &end);
+ while(!htable_shape_iterator_eq(&it, &end)) {
+ struct sgf_shape* shape = *htable_shape_iterator_data_get(&it);
+ SGF(shape_ref_put(shape));
+ htable_shape_iterator_next(&it);
+ }
+ htable_shape_clear(&scn->shapes);
+ S3D(scene_clear(scn->s3d_scn));
+ return RES_OK;
+}
+
diff --git a/src/sgf_shape.c b/src/sgf_shape.c
@@ -15,24 +15,10 @@
#include "sgf.h"
#include "sgf_device_c.h"
-
-#include <rsys/dynamic_array_double.h>
-#include <rsys/ref_count.h>
+#include "sgf_shape_c.h"
#include <star/s3d.h>
-struct sgf_shape {
- struct s3d_shape* s3d_shape;
- struct darray_double abs; /* Per primitive absorption */
- struct darray_double emi; /* Per primitive emissivity */
- struct darray_double refl; /* Per primitive reflectivity */
- struct darray_double spec; /* Per primitive specularity */
- size_t nbands; /* #spectral bands */
-
- ref_T ref;
- struct sgf_device* dev;
-};
-
/*******************************************************************************
* Local functions
******************************************************************************/
diff --git a/src/sgf_shape_c.h b/src/sgf_shape_c.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2015-2016 EDF S.A., France (syrthes-support@edf.fr)
+ *
+ * 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/>. */
+
+#ifndef SGF_SHAPE_C_H
+#define SGF_SHAPE_C_H
+
+#include <rsys/dynamic_array_double.h>
+#include <rsys/ref_count.h>
+
+struct s3d_shape;
+struct sgf_device;
+
+struct sgf_shape {
+ struct s3d_shape* s3d_shape;
+ struct darray_double abs; /* Per primitive absorption */
+ struct darray_double emi; /* Per primitive emissivity */
+ struct darray_double refl; /* Per primitive reflectivity */
+ struct darray_double spec; /* Per primitive specularity */
+ size_t nbands; /* #spectral bands */
+
+ ref_T ref;
+ struct sgf_device* dev;
+};
+
+#endif /* SGF_SHAPE_C_H */
+