star-cpr

Clip 2D meshes with 2D polygons
git clone git://git.meso-star.fr/star-cpr.git
Log | Files | Refs | README | LICENSE

scpr.h (12023B)


      1 /* Copyright (C) 2016-2018, 2021-2024 |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 SCPR_H
     17 #define SCPR_H
     18 
     19 #include <rsys/rsys.h>
     20 
     21 /* Library symbol management */
     22 #if defined(SCPR_SHARED_BUILD) /* Build shared library */
     23   #define SCPR_API extern EXPORT_SYM
     24 #elif defined(SCPR_STATIC_BUILD) /* Use/build static library */
     25   #define SCPR_API extern LOCAL_SYM
     26 #else /* Use shared library */
     27   #define SCPR_API extern IMPORT_SYM
     28 #endif
     29 
     30 /* Helper macro that asserts if the invocation of the scpr function `Func'
     31  * returns an error. */
     32 #ifndef NDEBUG
     33   #define SCPR(Func) ASSERT(scpr_##Func == RES_OK)
     34 #else
     35   #define SCPR(Func) scpr_##Func
     36 #endif
     37 
     38 enum scpr_operation {
     39   SCPR_AND, /* Keep the mesh part that intersects the clip polygon */
     40   SCPR_SUB, /* Remove the mesh part that intersects the clip polygon */
     41   SCPR_OPERATIONS_COUNT__
     42 };
     43 
     44 enum scpr_join_type {
     45   SCPR_JOIN_SQUARE,
     46   SCPR_JOIN_ROUND,
     47   SCPR_JOIN_MITER,
     48   SCPR_JOIN_TYPES_COUNT__
     49 };
     50 
     51 /* Forward declaration */
     52 struct mem_allocator;
     53 
     54 /* Forward declaration of the star-cpr opaque data types. These data types are
     55  * ref counted. Once created the caller implicitly owns the created data, i.e.
     56  * its reference counter is set to 1. The scpr_<TYPE>_ref_<get|put> functions
     57  * get or release a reference on the data, i.e. they increment or decrement the
     58  * reference counter, respectively. When this counter reaches 0, the object is
     59  * silently destroyed and cannot be used anymore. */
     60 struct scpr_device;
     61 struct scpr_polygon;
     62 struct scpr_mesh;
     63 struct scpr_intersector;
     64 
     65 /* Input arguments of the scpr_device_create function */
     66 struct scpr_device_create_args {
     67   struct logger* logger; /* NULL <=> default logger */
     68   struct mem_allocator* allocator; /* NULL <=> default allocator */
     69   int verbosity_level;
     70   int precision; /* Number of decimal place preserved; in [0 8] */
     71 };
     72 #define SCPR_DEVICE_CREATE_ARGS_DEFAULT__ { \
     73   NULL, NULL, 1, 6 \
     74 }
     75 static const struct scpr_device_create_args SCPR_DEVICE_CREATE_ARGS_DEFAULT =
     76   SCPR_DEVICE_CREATE_ARGS_DEFAULT__;
     77 
     78 /* A struct to represent segments when calling user callbacks. */
     79 struct scpr_callback_segment {
     80   struct scpr_polygon* polygon;
     81   size_t component;
     82   size_t first_vertex;
     83   size_t last_vertex;
     84 };
     85 
     86 /* A struct holding callbacks that are called when carying an intersection check
     87  * on a bunch of segments.
     88  * If a callbacks is NULL, the corresponding events are unreported, but at least
     89  * 1 callback must be non NULL.
     90  * If a callback call returns non-zero, the whole scpr_intersector_check call
     91  * exits whith a RES_BAD_ARG error status without further processing. */
     92 struct scpr_intersector_check_callbacks {
     93   int(*simple_intersection)
     94     (struct scpr_callback_segment* segment1,
     95      struct scpr_callback_segment* segment2,
     96      void* ctx);
     97   int(*overlapping_segments)
     98     (struct scpr_callback_segment* segment1,
     99      struct scpr_callback_segment* segment2,
    100      void* ctx);
    101 };
    102 #define SCPR_INTERSECTOR_CHECK_CALLBACKS_NULL__ { NULL, NULL }
    103 
    104 BEGIN_DECLS
    105 
    106 /*******************************************************************************
    107  * star-scpr Device. It is an handle toward the Stardis library. It manages the
    108  * star-scpr resources.
    109  ******************************************************************************/
    110 SCPR_API res_T
    111 scpr_device_create
    112   (const struct scpr_device_create_args* args,
    113    struct scpr_device** dev);
    114 
    115 SCPR_API res_T
    116 scpr_device_ref_get
    117   (struct scpr_device* dev);
    118 
    119 SCPR_API res_T
    120 scpr_device_ref_put
    121   (struct scpr_device* dev);
    122 
    123 /* Get the range for polygon and mesh vertices.
    124  * The range depends on the precision parameter of the device and is
    125  * [-2^(46-precision) + 2^(46-precision)]. */
    126 SCPR_API res_T
    127 scpr_device_get_range
    128   (const struct scpr_device* dev,
    129    double range[2]);
    130 
    131 /* Check if values are in range */
    132 SCPR_API res_T
    133 scpr_device_in_range
    134   (const struct scpr_device* dev,
    135    const double* values,
    136    const size_t count,
    137    int* in_range);
    138 
    139 /* Scale a set of values.
    140  * Internal representation for vertices in star-cpr is in interger format.
    141  * The process of converting reals to integers is named scaling (and the reverse
    142  * process is named unscaling). */
    143 SCPR_API res_T
    144 scpr_device_scale
    145   (const struct scpr_device* dev,
    146    const double* values,
    147    const size_t count,
    148    int64_t* scaled);
    149 
    150 /* Unscale a set of values.
    151  * Internal representation for vertices in star-cpr is in interger format.
    152  * The process of converting reals to integers is named scaling (and the reverse
    153  * process is named unscaling). */
    154 SCPR_API res_T
    155 scpr_device_unscale
    156   (const struct scpr_device* dev,
    157    const int64_t* values,
    158    const size_t count,
    159    double* unscaled);
    160 
    161 /*******************************************************************************
    162  * Type of polygons, as manipulated by star-cpr.
    163  * Polygons can be made of any number of paths and are subject to a range limit
    164  * and a precision (see device).
    165  * Polygons inside/outside regions are defined by their winding numbers
    166  * considering the Even-Odd convention.
    167  * E.g. a CCW path inside a CW one defines a hole.
    168  ******************************************************************************/
    169 SCPR_API res_T
    170 scpr_polygon_create
    171   (struct scpr_device* dev,
    172    struct scpr_polygon** polygon);
    173 
    174 SCPR_API res_T
    175 scpr_polygon_create_copy
    176   (struct scpr_device* dev,
    177    const struct scpr_polygon* src_polygon,
    178    struct scpr_polygon** polygon);
    179 
    180 SCPR_API res_T
    181 scpr_polygon_ref_get
    182   (struct scpr_polygon* polygon);
    183 
    184 SCPR_API res_T
    185 scpr_polygon_ref_put
    186   (struct scpr_polygon* polygon);
    187 
    188 /* The number of components and vertices can be changed due to a
    189  * simplification process and one should not take for granted that the number of
    190  * components and vertices stay as provided at construction time.
    191  * The actual counts and coordinates should be retrieved using the appropriate
    192  * getters. */
    193 SCPR_API res_T
    194 scpr_polygon_setup_indexed_vertices
    195   (struct scpr_polygon* polygon,
    196    const size_t ncomponents, /* #connex components */
    197    void (*get_nverts)(const size_t icomponent, size_t *nverts, void* ctx),
    198    void (*get_position)
    199      (const size_t icomponent, const size_t ivert, double pos[2], void* ctx),
    200    void* data); /* Client data set as the last param of the callbacks */
    201 
    202 SCPR_API res_T
    203 scpr_polygon_in_bbox
    204   (struct scpr_polygon* polygon,
    205    const double lower[2],
    206    const double upper[2],
    207    int* inside);
    208 
    209 SCPR_API res_T
    210 scpr_offset_polygon
    211   (struct scpr_polygon* polygon,
    212    const double offset, /* Can be either positive or negative */
    213    const enum scpr_join_type join_type);
    214 
    215 SCPR_API res_T
    216 scpr_polygon_get_components_count
    217   (const struct scpr_polygon* polygon,
    218    size_t* ncomps);
    219 
    220 SCPR_API res_T
    221 scpr_polygon_get_vertices_count
    222   (const struct scpr_polygon* polygon,
    223    const size_t icomponent,
    224    size_t* nverts);
    225 
    226 SCPR_API res_T
    227 scpr_polygon_get_position
    228   (const struct scpr_polygon* polygon,
    229    const size_t icomponent,
    230    const size_t ivert,
    231    double position[2]);
    232 
    233 /* Get the polygon component orientation.
    234  * Only meaningful for simple polygons. */
    235 SCPR_API res_T
    236 scpr_polygon_is_component_cw
    237   (const struct scpr_polygon* polygon,
    238    const size_t icomponent,
    239    int* cw);
    240 
    241 /* Reverse the polygon component orientation.
    242  * Only meaningful for simple polygons. */
    243 SCPR_API res_T
    244 scpr_polygon_reverse_component
    245   (struct scpr_polygon* polygon,
    246    const size_t icomponent);
    247 
    248 /* Logical comparison for polygons.
    249  * Component order and orientation are not considered. */
    250 SCPR_API res_T
    251 scpr_polygon_eq
    252   (const struct scpr_polygon* polygon1,
    253    const struct scpr_polygon* polygon2,
    254    int* is_eq);
    255 
    256 /* Return a vertex that is inside a component. */
    257 SCPR_API res_T
    258 scpr_get_vertex_in_component
    259   (const struct scpr_polygon* polygon,
    260    const size_t icomponent,
    261    double vertex[2]);
    262 
    263 /* Check if a vertex is in a component. */
    264 SCPR_API res_T
    265 scpr_is_vertex_in_component
    266   (const struct scpr_polygon* polygon,
    267    const size_t icomponent,
    268    const double vertex[2],
    269    int* situation); /* +1: inside, 0: on, -1: outside */
    270 
    271 /* Check if a component is inside a component, given the 2 components are not
    272  * equal and do not overlap (they can be adjoining).
    273  * Only meaningful for simple components. */
    274 SCPR_API res_T
    275 scpr_is_component_in_component
    276   (const struct scpr_polygon* polygon1,
    277    const size_t icomponent1,
    278    const struct scpr_polygon* polygon2,
    279    const size_t icomponent2,
    280    int* c1_is_in_c2);
    281 
    282 SCPR_API res_T
    283 scpr_polygon_dump_to_obj
    284   (struct scpr_polygon* polygon,
    285    FILE* stream);
    286 
    287 SCPR_API res_T
    288 scpr_polygon_dump_component_to_obj
    289   (struct scpr_polygon* polygon,
    290    const size_t icomponent,
    291    FILE* stream);
    292 
    293 /*******************************************************************************
    294  * Type of meshes, as manipulated by star-cpr.
    295  * Meshes can be made of any number of triangles and are subject to a range
    296  * limit and a precision (see device).
    297  ******************************************************************************/
    298 SCPR_API res_T
    299 scpr_mesh_create
    300   (struct scpr_device* dev,
    301    struct scpr_mesh** mesh);
    302 
    303 SCPR_API res_T
    304 scpr_mesh_ref_get
    305   (struct scpr_mesh* mesh);
    306 
    307 SCPR_API res_T
    308 scpr_mesh_ref_put
    309   (struct scpr_mesh* mesh);
    310 
    311 SCPR_API res_T
    312 scpr_mesh_setup_indexed_vertices
    313   (struct scpr_mesh* mesh,
    314    const size_t ntris, /* #triangles */
    315    void (*get_indices)(const size_t itri, size_t ids[3], void* ctx),
    316    const size_t nverts, /* #vertices */
    317    void (*get_position)(const size_t ivert, double pos[2], void* ctx),
    318    void* data); /* Client data set as the last param of the callbacks */
    319 
    320 /* Clip the mesh against the polygon using the EvenOdd filling rule. */
    321 SCPR_API res_T
    322 scpr_mesh_clip
    323   (struct scpr_mesh* mesh, /* Candidate mesh to clip */
    324    const enum scpr_operation op, /* Clip operation */
    325    struct scpr_polygon* polygon); /* Clip polygon */
    326 
    327 SCPR_API res_T
    328 scpr_mesh_get_triangles_count
    329   (const struct scpr_mesh* mesh,
    330    size_t* ntris);
    331 
    332 SCPR_API res_T
    333 scpr_mesh_get_vertices_count
    334   (const struct scpr_mesh* mesh,
    335    size_t* nverts);
    336 
    337 SCPR_API res_T
    338 scpr_mesh_get_indices
    339   (const struct scpr_mesh* mesh,
    340    const size_t itri,
    341    size_t ids[3]);
    342 
    343 SCPR_API res_T
    344 scpr_mesh_get_position
    345   (const struct scpr_mesh* mesh,
    346    const size_t ivert,
    347    double position[2]);
    348 
    349 /*******************************************************************************
    350  * An intersector provide a way to check for polygon intersections, either
    351  * self intersections or intersections between polygons.
    352  ******************************************************************************/
    353 SCPR_API res_T
    354 scpr_intersector_create
    355   (struct scpr_device* dev,
    356    struct scpr_intersector** intersector);
    357 
    358 SCPR_API res_T
    359 scpr_intersector_ref_get
    360   (struct scpr_intersector* intersector);
    361 
    362 SCPR_API res_T
    363 scpr_intersector_ref_put
    364   (struct scpr_intersector* intersector);
    365 
    366 /* Register a polygon for further analysis */
    367 SCPR_API res_T
    368 scpr_intersector_register_polygon
    369   (struct scpr_intersector* intersector,
    370    struct scpr_polygon* polygon);
    371 
    372 /* Register a polygon's component for further analysis */
    373 SCPR_API res_T
    374 scpr_intersector_register_component
    375   (struct scpr_intersector* intersector,
    376    struct scpr_polygon* polygon,
    377    const size_t icomponent);
    378 
    379 SCPR_API res_T
    380 scpr_intersector_check
    381   (struct scpr_intersector* intersector,
    382    struct scpr_intersector_check_callbacks* callbacks,
    383    void* data); /* Client data set as the last param of the callbacks */
    384 
    385 END_DECLS
    386 
    387 #endif /* SCPR_H */
    388