star-3d

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

test_s3d_shape.c (15988B)


      1 /* Copyright (C) 2015-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 "s3d.h"
     17 #include "test_s3d_cbox.h"
     18 #include "test_s3d_utils.h"
     19 
     20 #include <rsys/float3.h>
     21 #include <rsys/math.h>
     22 
     23 static int
     24 filter_none
     25   (const struct s3d_hit* hit,
     26    const float org[3],
     27    const float dir[3],
     28    const float range[2],
     29    void* ray_data,
     30    void* filter_data)
     31 {
     32   (void)hit, (void)org, (void)dir, (void)range, (void)ray_data, (void)filter_data;
     33   return 0;
     34 }
     35 
     36 int
     37 main(int argc, char** argv)
     38 {
     39   struct mem_allocator allocator;
     40   struct s3d_device* dev;
     41   struct s3d_shape* shape;
     42   struct s3d_shape* shape_copy;
     43   struct s3d_shape* inst;
     44   struct s3d_scene* scn;
     45   struct s3d_vertex_data attribs[4];
     46   struct s3d_attrib attr;
     47   unsigned nverts, ntris;
     48   unsigned ids[3];
     49   float pos[3];
     50   float trans[12];
     51   const unsigned cbox_ntris = cbox_walls_ntris;
     52   const unsigned cbox_nverts = cbox_walls_nverts;
     53   unsigned id;
     54   void* data = (void*)&cbox_walls_desc;
     55   char c;
     56   (void)argc, (void)argv;
     57 
     58   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     59 
     60   CHK(s3d_device_create(NULL, &allocator, 0, &dev) == RES_OK);
     61   CHK(s3d_scene_create(dev, &scn) == RES_OK);
     62 
     63   CHK(s3d_shape_create_mesh(NULL, NULL) == RES_BAD_ARG);
     64   CHK(s3d_shape_create_mesh(dev, NULL) == RES_BAD_ARG);
     65   CHK(s3d_shape_create_mesh(NULL, &shape) == RES_BAD_ARG);
     66   CHK(s3d_shape_create_mesh(dev, &shape) == RES_OK);
     67 
     68   CHK(s3d_shape_get_id(NULL, NULL) == RES_BAD_ARG);
     69   CHK(s3d_shape_get_id(shape, NULL) == RES_BAD_ARG);
     70   CHK(s3d_shape_get_id(NULL, &id) == RES_BAD_ARG);
     71   CHK(s3d_shape_get_id(shape, &id) == RES_OK);
     72   CHK(id != S3D_INVALID_ID);
     73 
     74   CHK(s3d_scene_attach_shape(NULL, NULL) == RES_BAD_ARG);
     75   CHK(s3d_scene_attach_shape(scn, NULL) == RES_BAD_ARG);
     76   CHK(s3d_scene_attach_shape(NULL, shape) == RES_BAD_ARG);
     77   CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
     78 
     79   CHK(s3d_scene_detach_shape(NULL, NULL) == RES_BAD_ARG);
     80   CHK(s3d_scene_detach_shape(scn, NULL) == RES_BAD_ARG);
     81   CHK(s3d_scene_detach_shape(NULL, shape) == RES_BAD_ARG);
     82   CHK(s3d_scene_detach_shape(scn, shape) == RES_OK);
     83 
     84   attribs[0].type = S3D_FLOAT3;
     85   attribs[0].usage = S3D_POSITION;
     86   attribs[0].get = cbox_get_position;
     87   CHK(s3d_mesh_setup_indexed_vertices
     88     (NULL, 0, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     89   CHK(s3d_mesh_setup_indexed_vertices
     90     (shape, 0, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     91   CHK(s3d_mesh_setup_indexed_vertices
     92     (NULL, cbox_ntris, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     93   CHK(s3d_mesh_setup_indexed_vertices
     94     (shape, cbox_ntris, NULL, 0, NULL, 1, data) == RES_BAD_ARG);
     95   CHK(s3d_mesh_setup_indexed_vertices
     96     (NULL, 0, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
     97   CHK(s3d_mesh_setup_indexed_vertices
     98     (shape, 0, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
     99   CHK(s3d_mesh_setup_indexed_vertices
    100     (NULL, cbox_ntris, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
    101   CHK(s3d_mesh_setup_indexed_vertices
    102     (shape, cbox_ntris, cbox_get_ids, 0, NULL, 1, data) == RES_BAD_ARG);
    103   CHK(s3d_mesh_setup_indexed_vertices
    104     (NULL, 0, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    105   CHK(s3d_mesh_setup_indexed_vertices
    106     (shape, 0, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    107   CHK(s3d_mesh_setup_indexed_vertices
    108     (NULL, cbox_ntris, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    109   CHK(s3d_mesh_setup_indexed_vertices
    110     (shape, cbox_ntris, NULL, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    111   CHK(s3d_mesh_setup_indexed_vertices
    112     (NULL, 0, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    113   CHK(s3d_mesh_setup_indexed_vertices
    114     (shape, 0, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    115   CHK(s3d_mesh_setup_indexed_vertices
    116     (NULL, cbox_ntris, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    117   CHK(s3d_mesh_setup_indexed_vertices
    118     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, NULL, 1, data) == RES_BAD_ARG);
    119   CHK(s3d_mesh_setup_indexed_vertices
    120     (NULL, 0, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    121   CHK(s3d_mesh_setup_indexed_vertices
    122     (shape, 0, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    123   CHK(s3d_mesh_setup_indexed_vertices
    124     (NULL, cbox_ntris, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    125   CHK(s3d_mesh_setup_indexed_vertices
    126     (shape, cbox_ntris, NULL, 0, attribs, 1, data) == RES_BAD_ARG);
    127   CHK(s3d_mesh_setup_indexed_vertices
    128     (NULL, 0, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    129   CHK(s3d_mesh_setup_indexed_vertices
    130     (shape, 0, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    131   CHK(s3d_mesh_setup_indexed_vertices
    132     (NULL, cbox_ntris, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    133   CHK(s3d_mesh_setup_indexed_vertices
    134     (shape, cbox_ntris, cbox_get_ids, 0, attribs, 1, data) == RES_BAD_ARG);
    135   CHK(s3d_mesh_setup_indexed_vertices
    136     (NULL, 0, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    137   CHK(s3d_mesh_setup_indexed_vertices
    138     (shape, 0, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    139   CHK(s3d_mesh_setup_indexed_vertices
    140     (NULL, cbox_ntris, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    141   CHK(s3d_mesh_setup_indexed_vertices
    142     (shape, cbox_ntris, NULL, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    143   CHK(s3d_mesh_setup_indexed_vertices
    144     (NULL, 0, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    145   CHK(s3d_mesh_setup_indexed_vertices
    146     (shape, 0, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    147   CHK(s3d_mesh_setup_indexed_vertices
    148     (NULL, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    149   CHK(s3d_mesh_setup_indexed_vertices
    150     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_OK);
    151   CHK(s3d_mesh_setup_indexed_vertices
    152     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 0, data) == RES_BAD_ARG);
    153 
    154   attribs[0] = S3D_VERTEX_DATA_NULL;
    155   CHK(s3d_mesh_setup_indexed_vertices
    156     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    157 
    158   attribs[0].type = S3D_FLOAT3;
    159   attribs[0].usage = S3D_POSITION;
    160   attribs[0].get = S3D_KEEP;
    161   CHK(s3d_mesh_setup_indexed_vertices
    162     (shape, cbox_ntris, cbox_get_ids, cbox_nverts, attribs, 1, data) == RES_OK);
    163 
    164   attribs[0].get = cbox_get_position;
    165   CHK(s3d_mesh_setup_indexed_vertices
    166     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 1, data) == RES_OK);
    167 
    168   attribs[0].type = S3D_FLOAT3;
    169   attribs[0].usage = S3D_ATTRIB_0;
    170   attribs[0].get = cbox_get_normal;
    171   CHK(s3d_mesh_setup_indexed_vertices
    172     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 1, data) == RES_BAD_ARG);
    173 
    174   attribs[1].type = S3D_FLOAT3;
    175   attribs[1].usage = S3D_POSITION;
    176   attribs[1].get = S3D_KEEP;
    177   CHK(s3d_mesh_setup_indexed_vertices
    178     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 2, data) == RES_OK);
    179 
    180   attribs[2].type = S3D_FLOAT2;
    181   attribs[2].usage = S3D_ATTRIB_2;
    182   attribs[2].get = cbox_get_uv;
    183   CHK(s3d_mesh_setup_indexed_vertices
    184     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_OK);
    185 
    186   attribs[0].get = S3D_KEEP;
    187   attribs[1].get = S3D_KEEP;
    188   attribs[2].get = S3D_KEEP;
    189   CHK(s3d_mesh_setup_indexed_vertices
    190     (shape, 2, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_BAD_ARG);
    191   CHK(s3d_mesh_setup_indexed_vertices
    192     (shape, cbox_ntris, S3D_KEEP, cbox_nverts+1, attribs, 3, data) == RES_BAD_ARG);
    193   CHK(s3d_mesh_setup_indexed_vertices
    194     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_OK);
    195 
    196   attribs[2].type = S3D_FLOAT3;
    197   CHK(s3d_mesh_setup_indexed_vertices
    198     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 3, data) == RES_BAD_ARG);
    199 
    200   attribs[0].get = cbox_get_position;
    201   CHK(s3d_mesh_setup_indexed_vertices
    202     (shape, cbox_ntris, S3D_KEEP, cbox_nverts, attribs, 2, data) == RES_OK);
    203 
    204   CHK(s3d_mesh_get_vertices_count(NULL, NULL) == RES_BAD_ARG);
    205   CHK(s3d_mesh_get_vertices_count(shape, NULL) == RES_BAD_ARG);
    206   CHK(s3d_mesh_get_vertices_count(NULL, &nverts) == RES_BAD_ARG);
    207   CHK(s3d_mesh_get_vertices_count(shape, &nverts) == RES_OK);
    208   CHK(nverts == cbox_nverts);
    209 
    210   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    211   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    212   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    213   CHK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG);
    214   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_POSITION, NULL) == RES_BAD_ARG);
    215   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_POSITION, NULL) == RES_BAD_ARG);
    216   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_POSITION, NULL) == RES_BAD_ARG);
    217   CHK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_POSITION, NULL) == RES_BAD_ARG);
    218   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    219   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    220   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    221   CHK(s3d_mesh_get_vertex_attrib(shape, 0, S3D_ATTRIBS_COUNT__, &attr) == RES_BAD_ARG);
    222   CHK(s3d_mesh_get_vertex_attrib(NULL, nverts, S3D_POSITION, &attr) == RES_BAD_ARG);
    223   CHK(s3d_mesh_get_vertex_attrib(shape, nverts, S3D_POSITION, &attr) == RES_BAD_ARG);
    224   CHK(s3d_mesh_get_vertex_attrib(NULL, 0, S3D_POSITION, &attr) == RES_BAD_ARG);
    225   FOR_EACH(id, 0, nverts) {
    226     cbox_get_position(id, pos, data);
    227 
    228     CHK(s3d_mesh_get_vertex_attrib(shape, id, S3D_POSITION, &attr) == RES_OK);
    229     CHK(attr.type == S3D_FLOAT3);
    230     CHK(attr.usage == S3D_POSITION);
    231     CHK(f3_eq_eps(attr.value, pos, 1.e-6f) == 1);
    232 
    233     CHK(s3d_mesh_get_vertex_attrib(shape, id, S3D_ATTRIB_0, &attr) == RES_OK);
    234     CHK(attr.type == S3D_FLOAT3);
    235     CHK(attr.usage == S3D_ATTRIB_0);
    236     CHK(f3_eq_eps(attr.value, pos, 1.e-6f) == 1);
    237   }
    238   CHK(s3d_mesh_get_vertex_attrib(shape, id, S3D_ATTRIB_1, &attr) == RES_BAD_ARG);
    239 
    240   CHK(s3d_mesh_get_triangles_count(NULL, NULL) == RES_BAD_ARG);
    241   CHK(s3d_mesh_get_triangles_count(shape, NULL) == RES_BAD_ARG);
    242   CHK(s3d_mesh_get_triangles_count(NULL, &ntris) == RES_BAD_ARG);
    243   CHK(s3d_mesh_get_triangles_count(shape, &ntris) == RES_OK);
    244   CHK(ntris == cbox_ntris);
    245 
    246   CHK(s3d_mesh_get_triangle_indices(NULL, ntris, NULL) == RES_BAD_ARG);
    247   CHK(s3d_mesh_get_triangle_indices(shape, ntris, NULL) == RES_BAD_ARG);
    248   CHK(s3d_mesh_get_triangle_indices(NULL, 0, NULL) == RES_BAD_ARG);
    249   CHK(s3d_mesh_get_triangle_indices(shape, 0, NULL) == RES_BAD_ARG);
    250   CHK(s3d_mesh_get_triangle_indices(NULL, ntris, ids) == RES_BAD_ARG);
    251   CHK(s3d_mesh_get_triangle_indices(shape, ntris, ids) == RES_BAD_ARG);
    252   CHK(s3d_mesh_get_triangle_indices(NULL, 0, ids) == RES_BAD_ARG);
    253 
    254   FOR_EACH(id, 0, ntris) {
    255     unsigned indices[3];
    256     CHK(s3d_mesh_get_triangle_indices(shape, id, ids) == RES_OK);
    257     cbox_get_ids(id, indices, data);
    258     CHK(ids[0] == indices[0]);
    259     CHK(ids[1] == indices[1]);
    260     CHK(ids[2] == indices[2]);
    261   }
    262 
    263   CHK(s3d_shape_is_enabled(NULL, NULL) == RES_BAD_ARG);
    264   CHK(s3d_shape_is_enabled(shape, NULL) == RES_BAD_ARG);
    265   CHK(s3d_shape_is_enabled(NULL, &c) == RES_BAD_ARG);
    266   CHK(s3d_shape_is_enabled(shape, &c) == RES_OK);
    267   CHK(c != 0);
    268 
    269   CHK(s3d_shape_enable(NULL, 0) == RES_BAD_ARG);
    270   CHK(s3d_shape_enable(shape, 0) == RES_OK);
    271   CHK(s3d_shape_is_enabled(shape, &c) == RES_OK);
    272   CHK(c == 0);
    273 
    274   CHK(s3d_shape_flip_surface(NULL) == RES_BAD_ARG);
    275   CHK(s3d_shape_flip_surface(shape) == RES_OK);
    276   CHK(s3d_shape_flip_surface(shape) == RES_OK);
    277 
    278   CHK(s3d_mesh_set_hit_filter_function(NULL, NULL, NULL) == RES_BAD_ARG);
    279   CHK(s3d_mesh_set_hit_filter_function(shape, NULL, NULL) == RES_OK);
    280   CHK(s3d_mesh_set_hit_filter_function(NULL, filter_none, NULL) == RES_BAD_ARG);
    281   CHK(s3d_mesh_set_hit_filter_function(shape, filter_none, NULL) == RES_OK);
    282 
    283   CHK(s3d_mesh_get_hit_filter_data(NULL, NULL) == RES_BAD_ARG);
    284   CHK(s3d_mesh_get_hit_filter_data(shape, NULL) == RES_BAD_ARG);
    285   CHK(s3d_mesh_get_hit_filter_data(NULL, &data) == RES_BAD_ARG);
    286   CHK(s3d_mesh_get_hit_filter_data(shape, &data) == RES_OK);
    287   CHK(data == NULL);
    288 
    289   CHK(s3d_mesh_set_hit_filter_function(shape, NULL, NULL) == RES_OK);
    290   CHK(s3d_mesh_get_hit_filter_data(shape, &data) == RES_OK);
    291   CHK(data == NULL);
    292   CHK(s3d_mesh_set_hit_filter_function
    293     (shape, filter_none, (void*)((uintptr_t)0xDEADBEEF)) == RES_OK);
    294   CHK(s3d_mesh_get_hit_filter_data(shape, &data) == RES_OK);
    295   CHK((uintptr_t)data == 0xDEADBEEF);
    296 
    297   CHK(s3d_scene_attach_shape(scn, shape) == RES_OK);
    298 
    299   CHK(s3d_scene_instantiate(scn, &inst) == RES_OK);
    300 
    301   CHK(s3d_instance_set_position(NULL, NULL) == RES_BAD_ARG);
    302   CHK(s3d_instance_set_position(inst, NULL) == RES_BAD_ARG);
    303   CHK(s3d_instance_set_position(NULL, pos) == RES_BAD_ARG);
    304   CHK(s3d_instance_set_position(inst, pos) == RES_OK);
    305   CHK(s3d_instance_set_position(shape, pos) == RES_BAD_ARG);
    306 
    307   CHK(s3d_instance_translate(NULL, -1, NULL) == RES_BAD_ARG);
    308   CHK(s3d_instance_translate(inst, -1, NULL) == RES_BAD_ARG);
    309   CHK(s3d_instance_translate(NULL, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    310   CHK(s3d_instance_translate(inst, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    311   CHK(s3d_instance_translate(NULL, -1, pos) == RES_BAD_ARG);
    312   CHK(s3d_instance_translate(inst, -1, pos) == RES_BAD_ARG);
    313   CHK(s3d_instance_translate(NULL, S3D_LOCAL_TRANSFORM, pos) == RES_BAD_ARG);
    314   CHK(s3d_instance_translate(inst, S3D_LOCAL_TRANSFORM, pos) == RES_OK);
    315   CHK(s3d_instance_translate(inst, S3D_WORLD_TRANSFORM, pos) == RES_OK);
    316   CHK(s3d_instance_translate(shape, S3D_WORLD_TRANSFORM, pos) == RES_BAD_ARG);
    317 
    318   CHK(s3d_instance_transform(NULL, -1, NULL) == RES_BAD_ARG);
    319   CHK(s3d_instance_transform(inst, -1, NULL) == RES_BAD_ARG);
    320   CHK(s3d_instance_transform(NULL, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    321   CHK(s3d_instance_transform(inst, S3D_LOCAL_TRANSFORM, NULL) == RES_BAD_ARG);
    322   CHK(s3d_instance_transform(NULL, -1, trans) == RES_BAD_ARG);
    323   CHK(s3d_instance_transform(inst, -1, trans) == RES_BAD_ARG);
    324   CHK(s3d_instance_transform(NULL, S3D_LOCAL_TRANSFORM, trans) == RES_BAD_ARG);
    325   CHK(s3d_instance_transform(inst, S3D_LOCAL_TRANSFORM, trans) == RES_OK);
    326   CHK(s3d_instance_transform(inst, S3D_WORLD_TRANSFORM, trans) == RES_OK);
    327   CHK(s3d_instance_transform(shape, S3D_LOCAL_TRANSFORM, trans) == RES_BAD_ARG);
    328 
    329   CHK(s3d_instance_set_transform(NULL, NULL) == RES_BAD_ARG);
    330   CHK(s3d_instance_set_transform(inst, NULL) == RES_BAD_ARG);
    331   CHK(s3d_instance_set_transform(NULL, trans) == RES_BAD_ARG);
    332   CHK(s3d_instance_set_transform(shape, trans) == RES_BAD_ARG);
    333   CHK(s3d_instance_set_transform(inst, trans) == RES_OK);
    334 
    335   CHK(s3d_shape_flip_surface(inst) == RES_OK);
    336 
    337   CHK(s3d_shape_create_mesh(dev, &shape_copy) == RES_OK);
    338   CHK(s3d_mesh_copy(NULL, NULL) == RES_BAD_ARG);
    339   CHK(s3d_mesh_copy(shape, NULL) == RES_BAD_ARG);
    340   CHK(s3d_mesh_copy(NULL, shape_copy) == RES_BAD_ARG);
    341   CHK(s3d_mesh_copy(shape, shape_copy) == RES_OK);
    342 
    343   CHK(s3d_shape_ref_get(NULL) == RES_BAD_ARG);
    344   CHK(s3d_shape_ref_get(shape) == RES_OK);
    345   CHK(s3d_shape_ref_put(NULL) == RES_BAD_ARG);
    346   CHK(s3d_shape_ref_put(shape) == RES_OK);
    347   CHK(s3d_shape_ref_put(shape) == RES_OK);
    348   CHK(s3d_shape_ref_put(inst) == RES_OK);
    349   CHK(s3d_shape_ref_put(shape_copy) == RES_OK);
    350   CHK(s3d_scene_ref_put(scn) == RES_OK);
    351 
    352   CHK(s3d_device_ref_put(dev) == RES_OK);;
    353 
    354   check_memory_allocator(&allocator);
    355   mem_shutdown_proxy_allocator(&allocator);
    356   CHK(mem_allocated_size() == 0);
    357   return 0;
    358 }
    359