star-uvm

Spatial structuring of unstructured volumetric meshes
git clone git://git.meso-star.fr/star-uvm.git
Log | Files | Refs | README | LICENSE

commit 59b190fe3b8c1dae705cf860ed39087c49df10bd
parent 98d026e481b5286f800b45d9548072f1e3132acd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 19 Jan 2021 16:54:36 +0100

Add the suvm_volume_compute_hash function

Diffstat:
Mcmake/CMakeLists.txt | 2+-
Msrc/suvm.h | 14++++++++++++++
Msrc/suvm_volume.c | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 126 insertions(+), 2 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -25,7 +25,7 @@ option(NO_TEST "Do not build tests" OFF) ################################################################################ find_package(Embree 3.6 REQUIRED) find_package(RCMake 0.4 REQUIRED) -find_package(RSys 0.10 REQUIRED) +find_package(RSys 0.12 REQUIRED) find_package(StarTetraHedra) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) diff --git a/src/suvm.h b/src/suvm.h @@ -16,6 +16,7 @@ #ifndef SUVM_H #define SUVM_H +#include <rsys/hash.h> #include <rsys/rsys.h> #include <float.h> @@ -40,6 +41,13 @@ /* Maximum number of vertices per volumetric primitive */ #define SUVM_PRIMITIVE_MAX_VERTICES_COUNT 4 +enum suvm_volume_cpnt_flag { + SUVM_POSITIONS = BIT(0), + SUVM_INDICES = BIT(1), + SUVM_PRIMITIVE_DATA = BIT(2), + SUVM_VERTEX_DATA = BIT(3) +}; + struct suvm_data { void (*get)(const size_t id, void* data, void* ctx); /* Data getter */ size_t size; /* Size of the data in bytes */ @@ -215,6 +223,12 @@ suvm_volume_get_primitive const size_t iprim, /* In [0, suvm_volume_get_primitives_count[ */ struct suvm_primitive* prim); +SUVM_API res_T +suvm_volume_compute_hash + (const struct suvm_volume* volume, + const int cpnt_mask, /* Combination of suvm_volume_cpnt_flag */ + hash256_T hash); + /******************************************************************************* * Primitive API ******************************************************************************/ diff --git a/src/suvm_volume.c b/src/suvm_volume.c @@ -23,6 +23,18 @@ #include <rsys/dynamic_array_size_t.h> #include <rsys/ref_count.h> +struct hash_context { + struct cpnt { + const void* mem; + size_t size; /* Size in bytes */ + size_t chunk_min; /* Inclusive */ + size_t chunk_max; /* Exclusive */ + } cpnts[4]; + int ncpnts; + int icpnt; +}; +static const struct hash_context HASH_CONTEXT_NULL; + /* Generate the dynamic array of RTCBuildPrimitive */ #define DARRAY_NAME rtc_prim #define DARRAY_DATA struct RTCBuildPrimitive @@ -86,8 +98,14 @@ buffer_init_from_data /* Fill the buffer with the submitted data */ FOR_EACH(idata, 0, ndata) { - void* elmt = (char*)buf->mem + idata*buf->elmt_stride; + char* elmt = (char*)buf->mem + idata*buf->elmt_stride; data->get(idata, elmt, context); + + /* Clean up padding bytes to initialise them regarding their possible + * hashing by the suvm_volume_compute_hash function */ + if(buf->elmt_stride != buf->elmt_size) { + memset(elmt + buf->elmt_size, 0, buf->elmt_stride - buf->elmt_size); + } } exit: @@ -515,6 +533,31 @@ fixup_tetrahedra_normals(struct suvm_volume* vol) } static void +get_chunk(char dst[64], const size_t ichunk, void* context) +{ + struct hash_context* ctx = context; + const struct cpnt* cpnt = NULL; + const char* chunk = NULL; + size_t cpnt_offset = 0; + size_t chunk_sz = 0; + ASSERT(dst && ctx); + + cpnt = ctx->cpnts + ctx->icpnt; + ASSERT(cpnt->chunk_min <= ichunk); + ASSERT(cpnt->chunk_max > ichunk); + + cpnt_offset = (ichunk - cpnt->chunk_min) * 64; + chunk = (const char*)cpnt->mem + cpnt_offset; + chunk_sz = MMIN(cpnt->size - cpnt_offset, 64); + memcpy(dst, chunk, chunk_sz); + if(chunk_sz < 64) memset(dst + chunk_sz, 0, 64 - chunk_sz); + + if(ichunk == cpnt->chunk_max - 1) { + ++ctx->icpnt; + } +} + +static void volume_release(ref_T* ref) { struct suvm_volume* vol = NULL; @@ -654,3 +697,70 @@ suvm_volume_get_primitive volume_primitive_setup(vol, iprim, prim); return RES_OK; } + +res_T +suvm_volume_compute_hash + (const struct suvm_volume* vol, + const int cpnt_mask, + hash256_T hash) +{ + struct chunked_data_desc chunked_data = CHUNKED_DATA_DESC_NULL; + struct hash_context ctx = HASH_CONTEXT_NULL; + size_t sz = 0; + int i = 0; + res_T res = RES_OK; + + if(!vol || !hash) { + res = RES_OK; + goto error; + } + + if(cpnt_mask & SUVM_POSITIONS) { + ctx.cpnts[i].mem = darray_float_cdata_get(&vol->positions); + ctx.cpnts[i].size = darray_float_size_get(&vol->positions) * sizeof(float); + ++i; + } + if(cpnt_mask & SUVM_INDICES) { + ctx.cpnts[i].mem = darray_u32_cdata_get(&vol->indices); + ctx.cpnts[i].size = darray_u32_size_get(&vol->indices) * sizeof(uint32_t); + ++i; + } + if(cpnt_mask & SUVM_PRIMITIVE_DATA) { + ctx.cpnts[i].mem = vol->prim_data.mem; + ctx.cpnts[i].size = vol->prim_data.size * vol->prim_data.elmt_stride; + ++i; + } + if(cpnt_mask & SUVM_VERTEX_DATA) { + ctx.cpnts[i].mem = vol->vert_data.mem; + ctx.cpnts[i].size = vol->vert_data.size * vol->vert_data.elmt_stride; + ++i; + } + ctx.ncpnts = i; + + FOR_EACH(i, 0, ctx.ncpnts) { + const size_t nchunks = (ctx.cpnts[i].size + 63/*ceil*/) / 64; + if(i == ctx.ncpnts-1) { + sz += ctx.cpnts[i].size; + } else { + sz += nchunks * 64; + } + if(i == 0) { + ctx.cpnts[i].chunk_min = 0; + ctx.cpnts[i].chunk_max = nchunks; + } else { + ctx.cpnts[i].chunk_max = ctx.cpnts[i-1].chunk_max; + ctx.cpnts[i].chunk_max = ctx.cpnts[i-1].chunk_max + nchunks; + } + } + ctx.icpnt = 0; + + chunked_data.get_chunk512 = get_chunk; + chunked_data.size = sz; + chunked_data.context = &ctx; + hash_sha256_chunked_data(&chunked_data, hash); + +exit: + return res; +error: + goto exit; +}