commit 550986ff92c37186a466d04bf2809b1de26f9b45
parent f3c2adce4b40ff2754520b420cc5cff2598e7a80
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 13 Jul 2022 12:00:04 +0200
Load material properties
Diffstat:
5 files changed, 221 insertions(+), 11 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -39,7 +39,12 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
include(rcmake)
include(rcmake_runtime)
-include_directories(${RSys_INCLUDE_DIR})
+include_directories(
+ ${MruMtl_INCLUDE_DIR}
+ ${RSys_INCLUDE_DIR}
+ ${Star3D_INCLUDE_DIR}
+ ${StarMesh_INCLUDE_DIR}
+ ${StarBuffer_INCLUDE_DIR})
################################################################################
# Configure and define targets
@@ -52,6 +57,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(RNGRD_FILES_SRC
rngrd.c
rngrd_log.c
+ rngrd_setup_materials.c
rngrd_setup_mesh.c)
set(RNGRD_FILES_INC
rngrd_c.h
@@ -66,7 +72,7 @@ rcmake_prepend_path(RNGRD_FILES_INC_API ${RNGRD_SOURCE_DIR})
rcmake_prepend_path(RNGRD_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
add_library(rngrd SHARED ${RNGRD_FILES_SRC} ${RNGRD_FILES_INC} ${RNGRD_FILES_INC_API})
-target_link_libraries(rngrd RSys Star3D StarMesh)
+target_link_libraries(rngrd MruMtl RSys Star3D StarMesh)
if(CMAKE_COMPILER_IS_GNUCC)
target_link_libraries(rngrd m)
diff --git a/src/rngrd.c b/src/rngrd.c
@@ -78,10 +78,10 @@ create_rngrd
res = RES_MEM_ERR;
goto error;
}
-
ref_init(&ground->ref);
ground->allocator = allocator;
- ground->verbose = args->verbose ;
+ ground->verbose = args->verbose;
+ darray_mtl_init(ground->allocator, &ground->mtls);
if(args->logger) {
ground->logger = args->logger;
} else {
@@ -101,14 +101,20 @@ error:
if(ground) { RNGRD(ref_put(ground)); ground = NULL; }
goto exit;
}
+
static void
release_rngrd(ref_T* ref)
{
struct rngrd* ground = CONTAINER_OF(ref, struct rngrd, ref);
+ size_t i;
ASSERT(ref);
if(ground->logger == &ground->logger__) logger_release(&ground->logger__);
if(ground->s3d) S3D(device_ref_put(ground->s3d));
if(ground->s3d_view) S3D(scene_view_ref_put(ground->s3d_view));
+ FOR_EACH(i, 0, darray_mtl_size_get(&ground->mtls)) {
+ struct mrumtl* mtl = darray_mtl_data_get(&ground->mtls)[i];
+ if(mtl) MRUMTL(ref_put(mtl));
+ }
MEM_RM(ground->allocator, ground);
}
@@ -128,12 +134,8 @@ rngrd_create
res = setup_mesh(ground, args);
if(res != RES_OK) goto error;
-
- /* TODO */
-#if 0
- res = setup_materials(args, ground);
+ res = setup_materials(ground, args);
if(res != RES_OK) goto error;
-#endif
exit:
if(out_ground) *out_ground = ground;
diff --git a/src/rngrd_c.h b/src/rngrd_c.h
@@ -21,14 +21,33 @@
#ifndef RNGRD_C_H
#define RNGRD_C_H
+#include <modradurb/mrumtl.h>
+
+#include <rsys/dynamic_array.h>
#include <rsys/logger.h>
#include <rsys/ref_count.h>
struct rngrd_create_args;
+struct mrumtl;
+
+static INLINE res_T
+mtl_init(struct mem_allocator* allocator, struct mrumtl** mtl)
+{
+ (void)allocator;
+ *mtl = NULL;
+ return RES_OK;
+}
+
+/* Generate the dynamic array of materials */
+#define DARRAY_NAME mtl
+#define DARRAY_DATA struct mrumtl*
+#define DARRAY_FUNCTOR_INIT mtl_init
+#include <rsys/dynamic_array.h>
struct rngrd {
struct s3d_device* s3d;
struct s3d_scene_view* s3d_view;
+ struct darray_mtl mtls;
int verbose;
struct logger* logger;
@@ -42,4 +61,9 @@ setup_mesh
(struct rngrd* ground,
const struct rngrd_create_args* args);
+extern LOCAL_SYM res_T
+setup_materials
+ (struct rngrd* ground,
+ const struct rngrd_create_args* args);
+
#endif /* RNGRD_C_H */
diff --git a/src/rngrd_setup_materials.c b/src/rngrd_setup_materials.c
@@ -0,0 +1,179 @@
+/* Copyright (C) 2022 Centre National de la Recherche Scientifique
+ * Copyright (C) 2022 Institut de Physique du Globe de Paris
+ * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université de Reims Champagne-Ardenne
+ * Copyright (C) 2022 Université de Versaille Saint-Quentin
+ * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.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/>. */
+
+#define _POSIX_C_SOURCE 200112L /* strtok_r */
+
+#include "rngrd.h"
+#include "rngrd_c.h"
+#include "rngrd_log.h"
+
+#include <rsys/cstr.h>
+#include <rsys/text_reader.h>
+
+#include <string.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+parse_mtl(struct rngrd* ground, struct txtrdr* txtrdr, struct mrumtl** out_mtl)
+{
+ char* tk = NULL;
+ char* tk_ctx = NULL;
+ struct mrumtl_create_args args = MRUMTL_CREATE_ARGS_DEFAULT;
+ struct mrumtl* mtl = NULL;
+ res_T res = RES_OK;
+ ASSERT(ground && txtrdr && out_mtl);
+
+ res = txtrdr_read_line(txtrdr);
+ if(res != RES_OK) {
+ log_err(ground, "%s: can't read the line `%lu' -- %s\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ res_to_cstr(res));
+ goto error;
+ }
+
+ if(!txtrdr_get_cline(txtrdr)) {
+ const size_t nexpect = darray_mtl_size_get(&ground->mtls);
+ const size_t nparsed = (size_t)(out_mtl - darray_mtl_cdata_get(&ground->mtls));
+ log_err(ground,
+ "%s:%lu: missing a material filename. "
+ "Expecting %lu material%s while %lu %s parsed.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ (unsigned long)nexpect, nexpect == 1 ? " " : "s ",
+ (unsigned long)nparsed, nparsed > 1 ? "were" : "was");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ tk = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx);
+ ASSERT(tk);
+
+ args.verbose = ground->verbose;
+ res = mrumtl_create(&args, &mtl);
+ if(res != RES_OK) {
+ log_err(ground, "%s:%lu: could not create the MruMtl data structure\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
+ goto error;
+ }
+
+ res = mrumtl_load(mtl, tk);
+ if(res != RES_OK) goto error;
+
+ tk = strtok_r(NULL, " \t", &tk_ctx);
+ if(tk) {
+ log_warn(ground, "%s:%lu: unexpected text `%s'\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ }
+
+exit:
+ *out_mtl = mtl;
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_mtllst(struct rngrd* ground, const struct rngrd_create_args* args)
+{
+ struct txtrdr* txtrdr = NULL;
+ char* tk = NULL;
+ char* tk_ctx = NULL;
+ size_t imtl = 0;
+ unsigned long nmtls = 0;
+ res_T res = RES_OK;
+ ASSERT(ground && args);
+
+ res = txtrdr_file(ground->allocator, args->mtllst_filename, '#', &txtrdr);
+ if(res != RES_OK) {
+ log_err(ground, "Could not create text reader to parse file `%s' -- %s\n",
+ args->mtllst_filename, res_to_cstr(res));
+ goto error;
+ }
+
+ res = txtrdr_read_line(txtrdr);
+ if(res != RES_OK) {
+ log_err(ground, "%s: can't read the line %lu --%s\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ res_to_cstr(res));
+ goto error;
+ }
+
+ if(!txtrdr_get_cline(txtrdr)) {
+ log_err(ground, "%s: file cannot be empty\n", txtrdr_get_name(txtrdr));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ tk = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx);
+ ASSERT(tk);
+
+ res = cstr_to_ulong(tk, &nmtls);
+ if(res == RES_OK && nmtls == 0) res = RES_BAD_ARG;
+ if(res != RES_OK) {
+ log_err(ground, "%s:%lu: invalid number of materials %lu\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ nmtls);
+ goto error;
+ }
+
+ res = darray_mtl_resize(&ground->mtls, nmtls);
+ if(res != RES_OK) {
+ log_err(ground, "%s: could not allocate the list of %lu materials -- %s\n",
+ txtrdr_get_name(txtrdr), nmtls, res_to_cstr(res));
+ goto error;
+ }
+
+ tk = strtok_r(NULL, " \t", &tk_ctx);
+ if(tk) {
+ log_warn(ground, "%s:%lu: unexpected text `%s'\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ }
+
+ FOR_EACH(imtl, 0, nmtls) {
+ struct mrumtl** mtl = darray_mtl_data_get(&ground->mtls)+imtl;
+ res = parse_mtl(ground, txtrdr, mtl);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ if(txtrdr) txtrdr_ref_put(txtrdr);
+ return res;
+error:
+ goto exit;
+}
+
+/*******************************************************************************
+ * Local function
+ ******************************************************************************/
+res_T
+setup_materials(struct rngrd* ground, const struct rngrd_create_args* args)
+{
+ res_T res = RES_OK;
+ ASSERT(ground && args);
+
+ res = parse_mtllst(ground, args);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/rngrd_setup_mesh.c b/src/rngrd_setup_mesh.c
@@ -253,7 +253,6 @@ error:
goto exit;
}
-
/*******************************************************************************
* Local function
******************************************************************************/
@@ -264,7 +263,7 @@ setup_mesh(struct rngrd* ground, const struct rngrd_create_args* args)
struct smsh_desc smsh_desc = SMSH_DESC_NULL;
struct smsh* smsh = NULL;
res_T res = RES_OK;
- ASSERT(args);
+ ASSERT(ground && args);
/* Create the Star-Mesh loader */
smsh_args.logger = ground->logger;