star-3dut

Generate meshes of simple geometric shapes
git clone git://git.meso-star.fr/star-3dut.git
Log | Files | Refs | README | LICENSE

s3dut_mesh.c (3526B)


      1 /* Copyright (C) 2016, 2017, 2020, 2021, 2023 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "s3dut.h"
     17 #include "s3dut_mesh.h"
     18 
     19 #include <rsys/mem_allocator.h>
     20 
     21 /*******************************************************************************
     22  * Helper functions
     23  ******************************************************************************/
     24 static void
     25 release_mesh(ref_T* ref)
     26 {
     27   struct s3dut_mesh* mesh;
     28   ASSERT(ref);
     29   mesh = CONTAINER_OF(ref, struct s3dut_mesh, ref);
     30   darray_double_release(&mesh->coords);
     31   darray_size_t_release(&mesh->ids);
     32   MEM_RM(mesh->allocator, mesh);
     33 }
     34 
     35 /*******************************************************************************
     36  * Exported functions
     37  ******************************************************************************/
     38 res_T
     39 s3dut_mesh_ref_get(struct s3dut_mesh* mesh)
     40 {
     41   if(!mesh) return RES_BAD_ARG;
     42   ref_get(&mesh->ref);
     43   return RES_OK;
     44 }
     45 
     46 res_T
     47 s3dut_mesh_ref_put(struct s3dut_mesh* mesh)
     48 {
     49   if(!mesh) return RES_BAD_ARG;
     50   ref_put(&mesh->ref, release_mesh);
     51   return RES_OK;
     52 }
     53 
     54 res_T
     55 s3dut_mesh_get_data(const struct s3dut_mesh* mesh, struct s3dut_mesh_data* data)
     56 {
     57   size_t ncoords, nids;
     58   if(!mesh || !data) return RES_BAD_ARG;
     59 
     60   data->positions = darray_double_cdata_get(&mesh->coords);
     61   data->indices = darray_size_t_cdata_get(&mesh->ids);
     62 
     63   ncoords = darray_double_size_get(&mesh->coords);
     64   nids = darray_size_t_size_get(&mesh->ids);
     65   ASSERT(ncoords % 3 == 0); /* Only 3D coordinates are supported */
     66   ASSERT(nids % 3 == 0); /* Only triangular primitives are supported */
     67 
     68   data->nvertices = ncoords / 3;
     69   data->nprimitives = nids / 3;
     70 
     71   return RES_OK;
     72 }
     73 
     74 /*******************************************************************************
     75  * Local function
     76  ******************************************************************************/
     77 res_T
     78 mesh_create
     79   (struct mem_allocator* allocator,
     80    const enum s3dut_mesh_type type,
     81    const size_t nvertices,
     82    const size_t ntriangles,
     83    struct s3dut_mesh** out_mesh)
     84 {
     85   struct s3dut_mesh* mesh = NULL;
     86   struct mem_allocator* mem_allocator;
     87   res_T res = RES_OK;
     88 
     89   if(!out_mesh) {
     90     res = RES_BAD_ARG;
     91     goto error;
     92   }
     93 
     94   mem_allocator = allocator ? allocator : &mem_default_allocator;
     95   mesh = MEM_CALLOC(mem_allocator, 1, sizeof(struct s3dut_mesh));
     96   if(!mesh) {
     97     res = RES_MEM_ERR;
     98     goto error;
     99   }
    100   mesh->allocator = mem_allocator;
    101   mesh->type = type;
    102   ref_init(&mesh->ref);
    103   darray_double_init(mem_allocator, &mesh->coords);
    104   darray_size_t_init(mem_allocator, &mesh->ids);
    105 
    106   res = darray_double_resize(&mesh->coords, nvertices*3/*#coords*/);
    107   if(res != RES_OK) goto error;
    108   res = darray_size_t_resize(&mesh->ids, ntriangles*3/*#ids per triangle*/);
    109   if(res != RES_OK) goto error;
    110 
    111 exit:
    112   if(out_mesh) *out_mesh = mesh;
    113   return res;
    114 error:
    115   if(mesh) {
    116     S3DUT(mesh_ref_put(mesh));
    117     mesh = NULL;
    118   }
    119   goto exit;
    120 }
    121