star-geometry-2d

Cleaning and decorating 2D geometries
git clone git://git.meso-star.fr/star-geometry-2d.git
Log | Files | Refs | README | LICENSE

sg2d_geometry.h (8057B)


      1 /* Copyright (C) 2019, 2020, 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 #ifndef SG2D_GEOMETRY_H__
     17 #define SG2D_GEOMETRY_H__
     18 
     19 #include "sg2d.h"
     20 #include "sg2d_misc.h"
     21 
     22 #include <rsys/ref_count.h>
     23 #include <rsys/dynamic_array.h>
     24 #include <rsys/dynamic_array_uint.h>
     25 #include <rsys/hash_table.h>
     26 
     27 /* Forward declaration of external opaque data types */
     28 
     29 /******************************************************************************
     30  * A type to store segments
     31  *****************************************************************************/
     32 struct segment {
     33   vrtx_id_t vertex_ids[2];
     34   /* FRONT/BACK/INTERFACE property */
     35   prop_id_t properties[SG2D_PROP_TYPES_COUNT__];
     36   /* ID of the segment in user world, i.e. without deduplication */
     37   seg_id_t user_id;
     38 };
     39 #define SEG_UNDEF__ {\
     40   { SG2D_UNSPECIFIED_PROPERTY, SG2D_UNSPECIFIED_PROPERTY },\
     41   { SG2D_UNSPECIFIED_PROPERTY, SG2D_UNSPECIFIED_PROPERTY, SG2D_UNSPECIFIED_PROPERTY },\
     42   SG2D_UNSPECIFIED_PROPERTY\
     43 }
     44 #define DARRAY_NAME segment
     45 #define DARRAY_DATA struct segment
     46 #include <rsys/dynamic_array.h>
     47 
     48 /******************************************************************************
     49  * A type to store vertices
     50  *****************************************************************************/
     51 struct vertex {
     52   double coord[2];
     53 };
     54 #define DARRAY_NAME vertex
     55 #define DARRAY_DATA struct vertex
     56 #include <rsys/dynamic_array.h>
     57 
     58 /******************************************************************************
     59  * A type to map segment vertices to IDs in unique_segments
     60  *****************************************************************************/
     61 struct vrtx_id2 { vrtx_id_t x[2]; };
     62 
     63 static FINLINE int
     64 seg_key_eq(const struct vrtx_id2* k1, const struct vrtx_id2* k2)
     65 {
     66   ASSERT(k1 && k2 && k1->x[0] < k1->x[1] && k2->x[0] < k2->x[1]);
     67   return (k1->x[0] == k2->x[0]) && (k1->x[1] == k2->x[1]);
     68 }
     69 
     70 #define HTABLE_NAME seg
     71 #define HTABLE_KEY struct vrtx_id2
     72 #define HTABLE_DATA seg_id_t
     73 #define HTABLE_KEY_FUNCTOR_EQ seg_key_eq
     74 #include <rsys/hash_table.h>
     75 
     76 /******************************************************************************
     77  * A type to map vertex coordinates to IDs in unique_vertices
     78  *****************************************************************************/
     79 static FINLINE int
     80 vrtx_eq(const struct vertex* v1, const struct vertex* v2)
     81 {
     82   int i;
     83   ASSERT(v1 && v2);
     84   FOR_EACH(i, 0, 2) if(v1->coord[i] != v2->coord[i]) return 0;
     85   return 1;
     86 }
     87 
     88 #define HTABLE_NAME vrtx
     89 #define HTABLE_KEY struct vertex
     90 #define HTABLE_DATA vrtx_id_t
     91 #define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
     92 #include <rsys/hash_table.h>
     93 
     94 /******************************************************************************
     95  * Types to record sources and values of segment descriptions.
     96  *****************************************************************************/
     97 
     98  /* A type to store a value and the files defining this value
     99   * (usualy a single file) */
    100 struct definition {
    101   /* The value */
    102   prop_id_t property_value;
    103   /* The IDs of the geometry sets that defined the value */
    104   struct darray_uint set_ids;
    105 };
    106 
    107 static FINLINE void
    108 init_definition
    109   (struct mem_allocator* alloc,
    110    struct definition* data)
    111 {
    112   ASSERT(alloc && data);
    113   data->property_value = SG2D_UNSPECIFIED_PROPERTY;
    114   darray_uint_init(alloc, &data->set_ids);
    115 }
    116 
    117 static INLINE res_T
    118 copy_definition
    119   (struct definition* dst,
    120    const struct definition* src)
    121 {
    122   res_T res = RES_OK;
    123   ASSERT(dst && src);
    124   dst->property_value = src->property_value;
    125   ERR(darray_uint_copy(&dst->set_ids, &src->set_ids));
    126 exit:
    127   return res;
    128 error:
    129   goto exit;
    130 }
    131 
    132 static FINLINE void
    133 release_definition
    134   (struct definition* data)
    135 {
    136   ASSERT(data);
    137   darray_uint_release(&data->set_ids);
    138 }
    139 
    140 #define DARRAY_NAME definition
    141 #define DARRAY_DATA struct definition
    142 #define DARRAY_FUNCTOR_INIT init_definition
    143 #define DARRAY_FUNCTOR_COPY copy_definition
    144 #define DARRAY_FUNCTOR_RELEASE release_definition
    145 #include <rsys/dynamic_array.h>
    146 
    147 /* A type to accumulate information for a segment.
    148  * If there is more than 1 definition / field, it is a conflict */
    149 struct seg_descriptions {
    150   struct darray_definition defs[SG2D_PROP_TYPES_COUNT__];
    151   int merge_conflict;
    152   int properties_conflict;
    153   char defs_include_unspecified;
    154   char property_defined[SG2D_PROP_TYPES_COUNT__];
    155 };
    156 
    157 static FINLINE void
    158 init_seg_descriptions
    159   (struct mem_allocator* alloc,
    160    struct seg_descriptions* data)
    161 {
    162   int i;
    163   ASSERT(alloc && data);
    164   FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__)
    165     darray_definition_init(alloc, data->defs + i);
    166   data->merge_conflict = 0;
    167   data->properties_conflict = 0;
    168   data->defs_include_unspecified = 0;
    169   FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__)
    170     data->property_defined[i] = 0;
    171 }
    172 
    173 static INLINE res_T
    174 copy_seg_descriptions
    175   (struct seg_descriptions* dst,
    176    const struct seg_descriptions* src)
    177 {
    178   res_T res = RES_OK;
    179   int i;
    180   ASSERT(dst && src);
    181   FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__)
    182     ERR(darray_definition_copy(&dst->defs[i], &src->defs[i]));
    183   dst->merge_conflict = src->merge_conflict;
    184   dst->properties_conflict = src->properties_conflict;
    185   dst->defs_include_unspecified = src->defs_include_unspecified;
    186   FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__)
    187     dst->property_defined[i] = src->property_defined[i];
    188 exit:
    189   return res;
    190 error:
    191   goto exit;
    192 }
    193 
    194 static FINLINE void
    195 release_seg_descriptions
    196   (struct seg_descriptions* data)
    197 {
    198   int i;
    199   ASSERT(data);
    200   FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__)
    201     darray_definition_release(data->defs + i);
    202 }
    203 
    204 #define DARRAY_NAME seg_descriptions
    205 #define DARRAY_DATA struct seg_descriptions
    206 #define DARRAY_FUNCTOR_INIT init_seg_descriptions
    207 #define DARRAY_FUNCTOR_COPY copy_seg_descriptions
    208 #define DARRAY_FUNCTOR_RELEASE release_seg_descriptions
    209 #include <rsys/dynamic_array.h>
    210 
    211 /******************************************************************************
    212  * Types to store geometry amid sg2d_geometry_add calls.
    213  *****************************************************************************/
    214 struct sg2d_geometry {
    215   /* Record unique (i.e. deduplicated) segments */
    216   struct darray_segment unique_segments;
    217   /* Record coordinates for unique (i.e. deduplicated) vertices */
    218   struct darray_vertex unique_vertices;
    219 
    220   /* A table to map segment vertices to IDs in unique_segments */
    221   struct htable_seg unique_segments_ids;
    222   /* A table to map vertex coordinates to IDs in unique_vertices */
    223   struct htable_vrtx unique_vertices_ids;
    224 
    225   /* Record which set defined what */
    226   struct darray_seg_descriptions seg_descriptions;
    227   
    228   /* Counts */
    229   unsigned set_id;
    230   seg_id_t segment_count_including_duplicates;
    231   side_id_t sides_with_defined_medium_count;
    232   seg_id_t seg_with_unspecified_sides_count;
    233   seg_id_t seg_with_unspecified_intface_count;
    234   seg_id_t merge_conflict_count;
    235   seg_id_t properties_conflict_count;
    236   
    237   struct sg2d_device* dev;
    238   ref_T ref;
    239 };
    240 
    241 /******************************************************************************
    242  * Local functions
    243  *****************************************************************************/
    244 
    245 extern LOCAL_SYM res_T
    246 geometry_register_segment
    247   (struct sg2d_geometry* geometry,
    248    const struct segment* segment,
    249    const seg_id_t segment_unique_id,
    250    const unsigned set_id,
    251    const int merge_conflict);
    252 
    253 /* Add new undefined segment descriptions to a geometry */
    254 extern LOCAL_SYM res_T
    255 geometry_enlarge_seg_descriptions
    256   (struct sg2d_geometry* geom,
    257    const seg_id_t sz);
    258 
    259 #endif /* SG2D_GEOMETRY_H__ */