star-enclosures-2d

Extract enclosures from 2D geometry
git clone git://git.meso-star.fr/star-enclosures-2d.git
Log | Files | Refs | README | LICENSE

test_senc2d_utils2.h (4183B)


      1 /* Copyright (C) 2018-2021, 2023, 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 TEST_SENC2_UTILS2_H
     17 #define TEST_SENC2_UTILS2_H
     18 
     19 #if !defined(NB_CIRC_X) ||  !defined(NB_CIRC_Y) || !defined(NB_CIRC_Z) | !defined(NB_CIRC)
     20 #error "Macro definitions are missing"
     21 #endif
     22 
     23 #include "test_senc2d_utils.h"
     24 
     25 #include <rsys/double2.h>
     26 #include <rsys/stretchy_array.h>
     27 
     28 static void
     29 get_ctx_indices(const unsigned iseg, unsigned ids[2], void* context)
     30 {
     31   struct context* ctx = context;
     32   unsigned template_iseg, circ_idx, v_offset;
     33   unsigned circ_seg_count, circ_vrtx_count;
     34   ASSERT(ids && ctx);
     35   /* Get circ_idx along with the template vertice index */
     36   circ_seg_count = (unsigned)sa_size(ctx->indices) / 2;
     37   circ_vrtx_count = (unsigned)sa_size(ctx->positions) / 2;
     38   ASSERT(iseg < NB_CIRC * circ_seg_count);
     39   template_iseg = iseg % circ_seg_count;
     40   circ_idx = iseg / circ_seg_count;
     41   ASSERT(ctx->indices[template_iseg * 2 + 0] <= UINT_MAX
     42     && ctx->indices[template_iseg * 2 + 1] <= UINT_MAX);
     43   /* Compute the vertex index in the user numbering
     44    * from circ_idx and template data; vertex related getters
     45    * will have to get the template index back */
     46   v_offset = circ_idx * circ_vrtx_count;
     47   ids[ctx->reverse_vrtx ? 1 : 0]
     48     = v_offset + (unsigned)ctx->indices[template_iseg * 2 + 0];
     49   ids[ctx->reverse_vrtx ? 0 : 1]
     50     = v_offset + (unsigned)ctx->indices[template_iseg * 2 + 1];
     51 }
     52 
     53 static void
     54 get_ctx_position(const unsigned ivert, double pos[2], void* context)
     55 {
     56   struct context* ctx = context;
     57   unsigned ctx_ivert, circ_idx;
     58   unsigned circ_seg_count, circ_vrtx_count;
     59   int i, j, k;
     60   double offset[2], tmp[2];
     61   double center_x, center_y, scale, misalignment = 0;
     62   ASSERT(pos && ctx); (void)circ_vrtx_count;
     63   /* Get circ_idx and circle imbrication along with the vertice index */
     64   circ_seg_count = (unsigned)sa_size(ctx->indices) / 2;
     65   circ_vrtx_count = (unsigned)sa_size(ctx->positions) / 2;
     66   ASSERT(ivert < NB_CIRC * circ_vrtx_count);
     67   ctx_ivert = ivert % circ_seg_count;
     68   circ_idx = ivert / circ_seg_count;
     69   /* k th circle of the imbrication at grid position i,j */
     70   i = (int)circ_idx / (NB_CIRC_Y * NB_CIRC_Z);
     71   j = (circ_idx / NB_CIRC_Z) % NB_CIRC_Y;
     72   k = circ_idx % NB_CIRC_Z;
     73   ASSERT(i < NB_CIRC_X && j < NB_CIRC_Y && k < NB_CIRC_Z);
     74   ASSERT((unsigned)(i * NB_CIRC_Y * NB_CIRC_Z + j * NB_CIRC_Z + k)
     75     * circ_vrtx_count + ctx_ivert == ivert);
     76   center_x = 2 * (1 + NB_CIRC_Z) * (i - NB_CIRC_X / 2);
     77   center_y = 2 * (1 + NB_CIRC_Z) * (j - NB_CIRC_Y / 2);
     78   /* Compute scale and offset from imbrication */
     79   scale = k + 1;
     80 #ifdef MITIGATE_EMBREE_181
     81   /* Mitigate Embree issue #181
     82    * We cannot keep perfect alignment of circles
     83    * or some hits are missed */
     84   misalignment = (k % 2) ? -0.01 : +0.01;
     85 #endif
     86   d2(offset, center_x + misalignment, center_y + misalignment);
     87   d2_add(pos, d2_muld(tmp, ctx->positions + ctx_ivert * 2, scale),
     88     offset);
     89 }
     90 
     91 static void
     92 get_ctx_media(const unsigned iseg, unsigned medium[2], void* context)
     93 {
     94   struct context* ctx = context;
     95   unsigned circ_idx;
     96   unsigned circ_seg_count;
     97   int k;
     98   ASSERT(medium && ctx);
     99   /* Get circ_idx */
    100   circ_seg_count = (unsigned)sa_size(ctx->indices) / 2;
    101   ASSERT(iseg < NB_CIRC * circ_seg_count);
    102   circ_idx = iseg / circ_seg_count;
    103   /* k th circle of the imbrication at some grid position */
    104   k = circ_idx % NB_CIRC_Z;
    105   medium[ctx->reverse_med ? SENC2D_BACK : SENC2D_FRONT] = (unsigned)k;
    106   medium[ctx->reverse_med ? SENC2D_FRONT : SENC2D_BACK] = (unsigned)(k + 1);
    107 }
    108 
    109 #endif /* TEST_SENC2_UTILS2_H */