test_svx_utils.h (6210B)
1 /* Copyright (C) 2018, 2020-2025 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 2018 Université Paul Sabatier 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #ifndef TEST_SVX_UTILS_H 18 #define TEST_SVX_UTILS_H 19 20 #include <rsys/double2.h> 21 #include <rsys/double3.h> 22 #include <rsys/image.h> 23 #include <rsys/mem_allocator.h> 24 25 #include <stdio.h> 26 27 enum data_type { 28 TYPE_CHAR, 29 TYPE_INT, 30 TYPE_LONG, 31 TYPE_FLOAT, 32 TYPE_DOUBLE 33 }; 34 35 struct camera { 36 double pos[3]; 37 double x[3], y[3], z[3]; /* Frame */ 38 }; 39 40 struct ray { 41 double org[3]; 42 double dir[3]; 43 double range[3]; 44 }; 45 46 static INLINE void 47 camera_init 48 (struct camera* cam, 49 const double pos[3], 50 const double tgt[3], 51 const double up[3], 52 const double proj_ratio) 53 { 54 const double fov_x = PI * 0.25; 55 double d = 0.0; 56 CHK(cam != NULL); 57 58 d3_set(cam->pos, pos); 59 d = d3_normalize(cam->z, d3_sub(cam->z, tgt, pos)); CHK(d != 0); 60 d = d3_normalize(cam->x, d3_cross(cam->x, cam->z, up)); CHK(d != 0); 61 d = d3_normalize(cam->y, d3_cross(cam->y, cam->z, cam->x)); CHK(d != 0); 62 d3_divd(cam->z, cam->z, tan(fov_x*0.5)); 63 d3_divd(cam->y, cam->y, proj_ratio); 64 } 65 66 static INLINE void 67 camera_ray 68 (const struct camera* cam, 69 const double pixel[2], 70 struct ray* ray) 71 { 72 double x[3], y[3], f; 73 CHK(cam && pixel && ray); 74 75 d3_muld(x, cam->x, pixel[0]*2.0 - 1.0); 76 d3_muld(y, cam->y, pixel[1]*2.0 - 1.0); 77 d3_add(ray->dir, d3_add(ray->dir, x, y), cam->z); 78 f = d3_normalize(ray->dir, ray->dir); CHK(f != 0); 79 d3_set(ray->org, cam->pos); 80 d2(ray->range, 0, INF); 81 } 82 83 84 static INLINE const char* 85 data_type_to_string(const enum data_type type) 86 { 87 switch(type) { 88 case TYPE_CHAR: return "char"; 89 case TYPE_INT: return "int"; 90 case TYPE_LONG: return "long"; 91 case TYPE_FLOAT: return "float"; 92 case TYPE_DOUBLE: return "double"; 93 default: FATAL("Unreachable code.\n"); 94 } 95 } 96 97 static INLINE void 98 write_leaf_vertices 99 (const struct svx_voxel* leaf, 100 const size_t ileaf, 101 void* context) 102 { 103 FILE* stream = context; 104 (void)ileaf; 105 CHK(stream != NULL); 106 CHK(leaf != NULL); 107 fprintf(stream, 108 "%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n" 109 "%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n", 110 leaf->lower[0], leaf->lower[1], leaf->lower[2], 111 leaf->upper[0], leaf->lower[1], leaf->lower[2], 112 leaf->lower[0], leaf->upper[1], leaf->lower[2], 113 leaf->upper[0], leaf->upper[1], leaf->lower[2], 114 leaf->lower[0], leaf->lower[1], leaf->upper[2], 115 leaf->upper[0], leaf->lower[1], leaf->upper[2], 116 leaf->lower[0], leaf->upper[1], leaf->upper[2], 117 leaf->upper[0], leaf->upper[1], leaf->upper[2]); 118 } 119 120 static INLINE void 121 write_leaf_cells 122 (const struct svx_voxel* leaf, 123 const size_t ileaf, 124 void* context) 125 { 126 FILE* stream = context; 127 CHK(stream != NULL); 128 CHK(leaf != NULL); 129 fprintf(stream, "8 %lu %lu %lu %lu %lu %lu %lu %lu\n", 130 (unsigned long)(ileaf*8 + 0), 131 (unsigned long)(ileaf*8 + 1), 132 (unsigned long)(ileaf*8 + 2), 133 (unsigned long)(ileaf*8 + 3), 134 (unsigned long)(ileaf*8 + 4), 135 (unsigned long)(ileaf*8 + 5), 136 (unsigned long)(ileaf*8 + 6), 137 (unsigned long)(ileaf*8 + 7)); 138 } 139 140 static INLINE void 141 dump_data 142 (FILE* stream, 143 struct svx_tree* tree, 144 const enum data_type type, 145 const size_t numcomps, 146 void (*write_leaf_data) 147 (const struct svx_voxel* leaf, const size_t ileaf, void* ctx)) 148 { 149 struct svx_tree_desc desc; 150 size_t ileaf; 151 152 CHK(stream != NULL); 153 CHK(tree != NULL); 154 CHK(write_leaf_data); 155 156 fprintf(stream, "# vtk DataFile Version 2.0\n"); 157 fprintf(stream, "Volume\n"); 158 fprintf(stream, "ASCII\n"); 159 fprintf(stream, "DATASET UNSTRUCTURED_GRID\n"); 160 161 CHK(svx_tree_get_desc(tree, &desc) == RES_OK); 162 CHK(desc.type == SVX_OCTREE); /* FIXME currently only octree are supported */ 163 fprintf(stream, "POINTS %lu float\n", (unsigned long)(desc.nleaves* 8)); 164 CHK(svx_tree_for_each_leaf(tree, write_leaf_vertices, stream) == RES_OK); 165 166 fprintf(stream, "CELLS %lu %lu\n", 167 (unsigned long)desc.nleaves, 168 (unsigned long)(desc.nleaves*(8/*#verts per leaf*/ + 1/*1st field of a cell*/))); 169 CHK(svx_tree_for_each_leaf(tree, write_leaf_cells, stream) == RES_OK); 170 171 fprintf(stream, "CELL_TYPES %lu\n", (unsigned long)desc.nleaves); 172 FOR_EACH(ileaf, 0, desc.nleaves) fprintf(stream, "11\n"); 173 174 fprintf(stream, "CELL_DATA %lu\n", (unsigned long)desc.nleaves); 175 fprintf(stream, "SCALARS K %s %lu\n", 176 data_type_to_string(type), (unsigned long)numcomps); 177 fprintf(stream, "LOOKUP_TABLE default\n"); 178 CHK(svx_tree_for_each_leaf(tree, write_leaf_data, stream) == RES_OK); 179 } 180 181 static INLINE void 182 check_img_eq(const struct image* img0, const struct image* img1) 183 { 184 size_t ix, iy; 185 size_t pixsz; 186 187 CHK(img0 && img1); 188 CHK(img0->format == IMAGE_RGB8); 189 CHK(img1->format == IMAGE_RGB8); 190 CHK(img0->width == img1->width); 191 CHK(img0->height == img1->height); 192 CHK(img0->pitch == img1->pitch); 193 194 pixsz = sizeof_image_format(img0->format); 195 196 FOR_EACH(iy, 0, img0->height) { 197 const char* row0 = img0->pixels + iy * img0->pitch; 198 const char* row1 = img1->pixels + iy * img1->pitch; 199 FOR_EACH(ix, 0, img0->width) { 200 const uint8_t* pix0 = (const uint8_t*)(row0 + ix*pixsz); 201 const uint8_t* pix1 = (const uint8_t*)(row1 + ix*pixsz); 202 CHK(pix0[0] == pix1[0]); 203 CHK(pix0[1] == pix1[1]); 204 CHK(pix0[2] == pix1[2]); 205 } 206 } 207 } 208 209 static INLINE void 210 check_memory_allocator(struct mem_allocator* allocator) 211 { 212 if(MEM_ALLOCATED_SIZE(allocator)) { 213 char dump[512]; 214 MEM_DUMP(allocator, dump, sizeof(dump)/sizeof(char)); 215 fprintf(stderr, "%s\n", dump); 216 FATAL("Memory leaks\n"); 217 } 218 } 219 220 #endif /* TEST_SVX_UTILS_H */ 221