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