test_sdis_mesh.h (4810B)
1 /* Copyright (C) 2016-2025 |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_SDIS_MESH_H 17 #define TEST_SDIS_MESH_H 18 19 #include <rsys/rsys.h> 20 #include <rsys/stretchy_array.h> 21 22 struct mesh { 23 double* positions; /* List of double 3 */ 24 size_t* indices; /* List of size_t 3 */ 25 }; 26 #define MESH_NULL__ {NULL, NULL} 27 static const struct mesh MESH_NULL = MESH_NULL__; 28 29 static INLINE void 30 mesh_init(struct mesh* mesh) 31 { 32 CHK(mesh); 33 *mesh = MESH_NULL; 34 } 35 36 static INLINE void 37 mesh_release(struct mesh* mesh) 38 { 39 CHK(mesh); 40 sa_release(mesh->positions); 41 sa_release(mesh->indices); 42 } 43 44 /* Number of vertices */ 45 static INLINE size_t 46 mesh_nvertices(const struct mesh* mesh) 47 { 48 CHK(mesh); 49 return sa_size(mesh->positions) / 3/* #coords per vertex */; 50 } 51 52 static INLINE size_t 53 mesh_2d_nvertices(const struct mesh* mesh) 54 { 55 CHK(mesh); 56 return sa_size(mesh->positions) / 2/* #coords per vertex */; 57 } 58 59 /* Number of triangles */ 60 static INLINE size_t 61 mesh_ntriangles(const struct mesh* mesh) 62 { 63 CHK(mesh); 64 return sa_size(mesh->indices) / 3/* #indices per triangle */; 65 } 66 67 static INLINE size_t 68 mesh_2d_nsegments(const struct mesh* mesh) 69 { 70 CHK(mesh); 71 return sa_size(mesh->indices) / 2/* #indices per segment */; 72 } 73 74 static INLINE void 75 mesh_append 76 (struct mesh* mesh, 77 const double* in_positions, 78 const size_t in_nvertices, 79 const size_t* in_indices, 80 const size_t in_ntriangles, 81 const double in_translate[3]) /* May be NULL */ 82 { 83 double translate[3] = {0, 0, 0}; 84 double* positions = NULL; 85 size_t* indices = NULL; 86 size_t ivert = 0; 87 size_t i = 0; 88 CHK(mesh != NULL); 89 90 ivert = mesh_nvertices(mesh); 91 positions = sa_add(mesh->positions, in_nvertices*3); 92 indices = sa_add(mesh->indices, in_ntriangles*3); 93 94 if(in_translate) { 95 translate[0] = in_translate[0]; 96 translate[1] = in_translate[1]; 97 translate[2] = in_translate[2]; 98 } 99 100 FOR_EACH(i, 0, in_nvertices) { 101 positions[i*3 + 0] = in_positions[i*3 + 0] + translate[0]; 102 positions[i*3 + 1] = in_positions[i*3 + 1] + translate[1]; 103 positions[i*3 + 2] = in_positions[i*3 + 2] + translate[2]; 104 } 105 106 FOR_EACH(i, 0, in_ntriangles) { 107 indices[i*3 + 0] = in_indices[i*3 + 0] + ivert; 108 indices[i*3 + 1] = in_indices[i*3 + 1] + ivert; 109 indices[i*3 + 2] = in_indices[i*3 + 2] + ivert; 110 } 111 } 112 113 static INLINE void 114 mesh_2d_append 115 (struct mesh* mesh, 116 const double* in_positions, 117 const size_t in_nvertices, 118 const size_t* in_indices, 119 const size_t in_nsegments, 120 const double in_translate[2]) /* May be NULL */ 121 { 122 double translate[2] = {0, 0}; 123 double* positions = NULL; 124 size_t* indices = NULL; 125 size_t ivert = 0; 126 size_t i = 0; 127 CHK(mesh != NULL); 128 129 ivert = mesh_2d_nvertices(mesh); 130 positions = sa_add(mesh->positions, in_nvertices*2); 131 indices = sa_add(mesh->indices, in_nsegments*2); 132 133 if(in_translate) { 134 translate[0] = in_translate[0]; 135 translate[1] = in_translate[1]; 136 } 137 138 FOR_EACH(i, 0, in_nvertices) { 139 positions[i*2 + 0] = in_positions[i*2 + 0] + translate[0]; 140 positions[i*2 + 1] = in_positions[i*2 + 1] + translate[1]; 141 } 142 143 FOR_EACH(i, 0, in_nsegments) { 144 indices[i*2 + 0] = in_indices[i*2 + 0] + ivert; 145 indices[i*2 + 1] = in_indices[i*2 + 1] + ivert; 146 } 147 } 148 149 static INLINE void 150 mesh_dump(const struct mesh* mesh, FILE* stream) 151 { 152 size_t i, n; 153 CHK(mesh != NULL); 154 155 n = mesh_nvertices(mesh); 156 FOR_EACH(i, 0, n) { 157 fprintf(stream, "v %g %g %g\n", SPLIT3(mesh->positions+i*3)); 158 } 159 160 n = mesh_ntriangles(mesh); 161 FOR_EACH(i, 0, n) { 162 fprintf(stream, "f %lu %lu %lu\n", 163 (unsigned long)(mesh->indices[i*3+0] + 1), 164 (unsigned long)(mesh->indices[i*3+1] + 1), 165 (unsigned long)(mesh->indices[i*3+2] + 1)); 166 } 167 fflush(stream); 168 } 169 170 static INLINE void 171 mesh_2d_dump(const struct mesh* mesh, FILE* stream) 172 { 173 size_t i, n; 174 CHK(mesh != NULL); 175 176 n = mesh_2d_nvertices(mesh); 177 FOR_EACH(i, 0, n) { 178 fprintf(stream, "v %g %g\n", SPLIT2(mesh->positions+i*2)); 179 } 180 181 n = mesh_2d_nsegments(mesh); 182 FOR_EACH(i, 0, n) { 183 fprintf(stream, "l %lu %lu\n", 184 (unsigned long)(mesh->indices[i*2+0] + 1), 185 (unsigned long)(mesh->indices[i*2+1] + 1)); 186 } 187 fflush(stream); 188 } 189 190 #endif /* TEST_SDIS_MESH_H */