solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

ssol_object.c (7371B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016, 2018 CNRS
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "ssol.h"
     18 #include "ssol_device_c.h"
     19 #include "ssol_object_c.h"
     20 #include "ssol_shape_c.h"
     21 
     22 #include <star/s3d.h>
     23 
     24 #include <rsys/ref_count.h>
     25 #include <rsys/rsys.h>
     26 #include <rsys/mem_allocator.h>
     27 #include <rsys/double3.h>
     28 
     29 /*******************************************************************************
     30  * Helper functions
     31  ******************************************************************************/
     32 static void
     33 object_release(ref_T* ref)
     34 {
     35   struct ssol_device* dev;
     36   struct ssol_object* object = CONTAINER_OF(ref, struct ssol_object, ref);
     37   ASSERT(ref);
     38   dev = object->dev;
     39   ASSERT(dev && dev->allocator);
     40   SSOL(object_clear(object));
     41   darray_shaded_shape_release(&object->shaded_shapes);
     42   htable_shaded_shape_release(&object->shaded_shapes_rt);
     43   htable_shaded_shape_release(&object->shaded_shapes_samp);
     44   if(object->scn_rt) S3D(scene_ref_put(object->scn_rt));
     45   if(object->scn_samp) S3D(scene_ref_put(object->scn_samp));
     46   MEM_RM(dev->allocator, object);
     47   SSOL(device_ref_put(dev));
     48 }
     49 
     50 /*******************************************************************************
     51  * Exported ssol_object functions
     52  ******************************************************************************/
     53 res_T
     54 ssol_object_create
     55   (struct ssol_device* dev,
     56    struct ssol_object** out_object)
     57 {
     58   struct ssol_object* object = NULL;
     59   res_T res = RES_OK;
     60 
     61   if(!dev || !out_object) {
     62     res = RES_BAD_ARG;
     63     goto error;
     64   }
     65 
     66   object = MEM_CALLOC(dev->allocator, 1, sizeof(struct ssol_object));
     67   if(!object) {
     68     res = RES_MEM_ERR;
     69     goto error;
     70   }
     71   SSOL(device_ref_get(dev));
     72   object->dev = dev;
     73   ref_init(&object->ref);
     74   darray_shaded_shape_init(dev->allocator, &object->shaded_shapes);
     75   htable_shaded_shape_init(dev->allocator, &object->shaded_shapes_rt);
     76   htable_shaded_shape_init(dev->allocator, &object->shaded_shapes_samp);
     77 
     78   /* Create the Star-3D RT scene to instantiate through the instance */
     79   res = s3d_scene_create(dev->s3d, &object->scn_rt);
     80   if(res != RES_OK) goto error;
     81   /* Create the Star-3D sampling scene to instantiated through the instance */
     82   res = s3d_scene_create(dev->s3d, &object->scn_samp);
     83   if(res != RES_OK) goto error;
     84 
     85 exit:
     86   if(out_object) *out_object = object;
     87   return res;
     88 error:
     89   if(object) {
     90     SSOL(object_ref_put(object));
     91     object = NULL;
     92   }
     93   goto exit;
     94 }
     95 res_T
     96 ssol_object_ref_get(struct ssol_object* object)
     97 {
     98   if(!object) return RES_BAD_ARG;
     99   ref_get(&object->ref);
    100   return RES_OK;
    101 }
    102 
    103 res_T
    104 ssol_object_ref_put(struct ssol_object* object)
    105 {
    106   if(!object) return RES_BAD_ARG;
    107   ref_put(&object->ref, object_release);
    108   return RES_OK;
    109 }
    110 
    111 res_T
    112 ssol_object_add_shaded_shape
    113   (struct ssol_object* object,
    114    struct ssol_shape* shape,
    115    struct ssol_material* front,
    116    struct ssol_material* back)
    117 {
    118   enum {
    119     ATTACH_S3D_RT, ATTACH_S3D_SAMP, REGISTER_RT, REGISTER_SAMP, REGISTER_SHAPE
    120   };
    121   struct shaded_shape* shaded_shape;
    122   unsigned id_rt, id_samp;
    123   size_t i;
    124   int mask = 0;
    125   res_T res = RES_OK;
    126 
    127   if(!object || !shape || !front || !back) {
    128     res = RES_BAD_ARG;
    129     goto error;
    130   }
    131 
    132   S3D(shape_get_id(shape->shape_rt, &id_rt));
    133   S3D(shape_get_id(shape->shape_samp, &id_samp));
    134   if(htable_shaded_shape_find(&object->shaded_shapes_rt, &id_rt)) {
    135     log_warning
    136       (object->dev, "%s: the object already own the shape.\n", FUNC_NAME);
    137     goto exit;
    138   }
    139 
    140   /* Add the shape RT to the RT scene of the object */
    141   res = s3d_scene_attach_shape(object->scn_rt, shape->shape_rt);
    142   if(res != RES_OK) goto error;
    143   mask |= BIT(ATTACH_S3D_RT);
    144 
    145   /* Add the shape samp to the sampling scene of the object */
    146   res = s3d_scene_attach_shape(object->scn_samp, shape->shape_samp);
    147   if(res != RES_OK) goto error;
    148   mask |= BIT(ATTACH_S3D_SAMP);
    149 
    150   /* Ask for a shaded shape identifier */
    151   i = darray_shaded_shape_size_get(&object->shaded_shapes);
    152   res = darray_shaded_shape_resize(&object->shaded_shapes, i+1);
    153   if(res != RES_OK) goto error;
    154   mask |= BIT(REGISTER_SHAPE);
    155 
    156   /* Register the RT shape identifer */
    157     res = htable_shaded_shape_set(&object->shaded_shapes_rt, &id_rt, &i);
    158   if(res != RES_OK) goto error;
    159   mask |= BIT(REGISTER_RT);
    160 
    161   /* Register the samp shape identifier */
    162   res = htable_shaded_shape_set(&object->shaded_shapes_samp, &id_samp, &i);
    163   if(res != RES_OK) goto error;
    164   mask |= BIT(REGISTER_SAMP);
    165 
    166   /* Setup the object shaded shape */
    167   object->scn_rt_area += shape->shape_rt_area;
    168   object->scn_samp_area += shape->shape_samp_area;
    169   SSOL(shape_ref_get(shape));
    170   SSOL(material_ref_get(front));
    171   SSOL(material_ref_get(back));
    172   shaded_shape = darray_shaded_shape_data_get(&object->shaded_shapes)+i;
    173   shaded_shape->shape = shape;
    174   shaded_shape->mtl_front = front;
    175   shaded_shape->mtl_back = back;
    176 
    177 exit:
    178   return res;
    179 error:
    180   if(mask & BIT(ATTACH_S3D_RT)) {
    181     S3D(scene_detach_shape(object->scn_rt, shape->shape_rt));
    182   }
    183   if(mask & BIT(ATTACH_S3D_SAMP)) {
    184     S3D(scene_detach_shape(object->scn_samp, shape->shape_samp));
    185   }
    186   if(mask & BIT(REGISTER_SHAPE)) {
    187     darray_shaded_shape_pop_back(&object->shaded_shapes);
    188   }
    189   if(mask & BIT(REGISTER_RT)) {
    190     i = htable_shaded_shape_erase(&object->shaded_shapes_rt, &id_rt);
    191     ASSERT(i == 1);
    192   }
    193   if(mask & BIT(REGISTER_SAMP)) {
    194     i = htable_shaded_shape_erase(&object->shaded_shapes_samp, &id_samp);
    195     ASSERT(i == 1);
    196   }
    197   goto exit;
    198 }
    199 
    200 res_T
    201 ssol_object_clear(struct ssol_object* obj)
    202 {
    203   size_t i, n;
    204   if(!obj) return RES_BAD_ARG;
    205 
    206   n = darray_shaded_shape_size_get(&obj->shaded_shapes);
    207   FOR_EACH(i, 0, n) {
    208     struct shaded_shape* s = darray_shaded_shape_data_get(&obj->shaded_shapes)+i;
    209     SSOL(shape_ref_put(s->shape));
    210     SSOL(material_ref_put(s->mtl_front));
    211     SSOL(material_ref_put(s->mtl_back));
    212   }
    213   darray_shaded_shape_clear(&obj->shaded_shapes);
    214   htable_shaded_shape_clear(&obj->shaded_shapes_rt);
    215   htable_shaded_shape_clear(&obj->shaded_shapes_samp);
    216 
    217   obj->scn_rt_area = 0;
    218   obj->scn_samp_area = 0;
    219 
    220   S3D(scene_clear(obj->scn_rt));
    221   S3D(scene_clear(obj->scn_samp));
    222 
    223   return RES_OK;
    224 }
    225 
    226 res_T
    227 ssol_object_get_area(const struct ssol_object* object, double* area)
    228 {
    229   if(!object || !area) return RES_BAD_ARG;;
    230   /* the area of the 3D surface */
    231   *area = object->scn_rt_area;
    232   return RES_OK;
    233 }
    234 
    235 /*******************************************************************************
    236  * Local function
    237  ******************************************************************************/
    238 int
    239 object_has_shape(struct ssol_object* obj, const struct ssol_shape* shape)
    240 {
    241   unsigned id;
    242   ASSERT(obj && shape);
    243   S3D(shape_get_id(shape->shape_rt, &id));
    244   return htable_shaded_shape_find(&obj->shaded_shapes_rt, &id) != NULL;
    245 }