senc3d_descriptor.c (7935B)
1 /* Copyright (C) 2018-2020, 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 #include "senc3d_enclosure_c.h" 17 #include "senc3d_scene_c.h" 18 #include "senc3d.h" 19 20 #include <rsys/rsys.h> 21 #include <rsys/double3.h> 22 #include <rsys/mem_allocator.h> 23 24 /****************************************************************************** 25 * Exported functions 26 *****************************************************************************/ 27 res_T 28 senc3d_scene_get_max_medium 29 (const struct senc3d_scene* scn, medium_id_t* max_medium_id) 30 { 31 if(!scn || !max_medium_id) return RES_BAD_ARG; 32 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 33 == darray_side_range_size_get(&scn->media_use)); 34 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 35 if(darray_side_range_size_get(&scn->media_use) == 1) 36 *max_medium_id = SENC3D_UNSPECIFIED_MEDIUM; 37 else { 38 size_t sz = darray_side_range_size_get(&scn->media_use) - 2; 39 ASSERT(sz <= MEDIUM_MAX__); 40 *max_medium_id = (medium_id_t)sz; 41 } 42 return RES_OK; 43 } 44 45 res_T 46 senc3d_scene_get_enclosure_count 47 (const struct senc3d_scene* scn, enclosure_id_t* count) 48 { 49 if(!scn || !count) return RES_BAD_ARG; 50 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 51 return RES_BAD_OP; 52 ASSERT(scn->analyze.enclosures_count == 53 darray_enclosure_size_get(&scn->analyze.enclosures)); 54 *count = scn->analyze.enclosures_count; 55 return RES_OK; 56 } 57 58 res_T 59 senc3d_scene_get_enclosure_count_by_medium 60 (const struct senc3d_scene* scn, 61 const medium_id_t imed, 62 enclosure_id_t* count) 63 { 64 size_t tmp; 65 size_t m_idx; 66 const struct darray_enc_id* enc_ids; 67 if(!scn || !count) return RES_BAD_ARG; 68 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 69 == darray_side_range_size_get(&scn->media_use)); 70 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 71 if(imed != SENC3D_UNSPECIFIED_MEDIUM 72 && imed >= darray_side_range_size_get(&scn->media_use)) 73 return RES_BAD_ARG; 74 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 75 return RES_BAD_OP; 76 m_idx = medium_id_2_medium_idx(imed); 77 enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) 78 + m_idx; 79 tmp = darray_enc_id_size_get(enc_ids); 80 ASSERT(tmp <= ENCLOSURE_MAX__); /* API type */ 81 *count = (enclosure_id_t)tmp; 82 return RES_OK; 83 } 84 85 FINLINE res_T 86 senc3d_scene_get_enclosure 87 (struct senc3d_scene* scn, 88 const enclosure_id_t idx, 89 struct senc3d_enclosure** out_enc) 90 { 91 struct senc3d_enclosure* enc; 92 if(!scn || !out_enc) return RES_BAD_ARG; 93 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 94 == darray_side_range_size_get(&scn->media_use)); 95 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 96 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 97 return RES_BAD_OP; 98 if(idx >= darray_enclosure_size_get(&scn->analyze.enclosures)) 99 return RES_BAD_ARG; 100 enc = enclosure_create(scn, idx); 101 if(!enc) return RES_MEM_ERR; 102 *out_enc = enc; 103 return RES_OK; 104 } 105 106 res_T 107 senc3d_scene_get_enclosure_by_medium 108 (struct senc3d_scene* scn, 109 const medium_id_t imed, 110 const enclosure_id_t idx, 111 struct senc3d_enclosure** out_enc) 112 { 113 size_t m_idx; 114 const struct darray_enc_id* enc_ids; 115 enclosure_id_t index; 116 if(!scn || !out_enc) return RES_BAD_ARG; 117 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 118 == darray_side_range_size_get(&scn->media_use)); 119 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 120 if(imed != SENC3D_UNSPECIFIED_MEDIUM 121 && imed >= darray_side_range_size_get(&scn->media_use)) 122 return RES_BAD_ARG; 123 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 124 return RES_BAD_OP; 125 m_idx = medium_id_2_medium_idx(imed); 126 enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) 127 + m_idx; 128 if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG; 129 index = darray_enc_id_cdata_get(enc_ids)[idx]; 130 return senc3d_scene_get_enclosure(scn, index, out_enc); 131 } 132 133 res_T 134 senc3d_scene_get_triangle_enclosures 135 (const struct senc3d_scene* scn, 136 const trg_id_t itri, 137 enclosure_id_t enclosures[2]) 138 { 139 const struct triangle_enc* trg; 140 int i; 141 if(!enclosures || !scn) return RES_BAD_ARG; 142 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 143 == darray_side_range_size_get(&scn->media_use)); 144 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 145 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 146 return RES_BAD_OP; 147 if(itri >= darray_triangle_enc_size_get(&scn->analyze.triangles_enc)) 148 return RES_BAD_ARG; 149 trg = darray_triangle_enc_cdata_get(&scn->analyze.triangles_enc) + itri; 150 FOR_EACH(i, 0, 2) enclosures[i] = trg->enclosure[i]; 151 return RES_OK; 152 } 153 154 res_T 155 senc3d_scene_get_frontier_segments_count 156 (const struct senc3d_scene* scn, 157 vrtx_id_t* count) 158 { 159 size_t tmp; 160 if(!scn || !count) 161 return RES_BAD_ARG; 162 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 163 == darray_side_range_size_get(&scn->media_use)); 164 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 165 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 166 return RES_BAD_OP; 167 tmp = darray_frontier_edge_size_get(&scn->analyze.frontiers); 168 ASSERT(tmp <= VRTX_MAX__); 169 *count = (vrtx_id_t)tmp; /* Back to API type */ 170 return RES_OK; 171 } 172 173 res_T 174 senc3d_scene_get_frontier_segment 175 (const struct senc3d_scene* scn, 176 const unsigned iseg, /* There is no defined type for segment IDs */ 177 vrtx_id_t vrtx_id[2], 178 unsigned* trg_id) 179 { 180 const struct frontier_edge* edge; 181 if(!vrtx_id || !scn || !trg_id 182 || iseg >= darray_frontier_edge_size_get(&scn->analyze.frontiers)) 183 return RES_BAD_ARG; 184 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 185 == darray_side_range_size_get(&scn->media_use)); 186 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 187 if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 188 return RES_BAD_OP; 189 edge = darray_frontier_edge_cdata_get(&scn->analyze.frontiers) + iseg; 190 ASSERT(edge->vrtx0 <= VRTX_MAX__); 191 ASSERT(edge->vrtx1 <= VRTX_MAX__); 192 vrtx_id[0] = edge->vrtx0; 193 vrtx_id[1] = edge->vrtx1; 194 *trg_id = edge->trg; 195 return RES_OK; 196 } 197 198 res_T 199 senc3d_scene_get_overlapping_triangles_count 200 (const struct senc3d_scene* scn, 201 vrtx_id_t* count) 202 { 203 size_t tmp; 204 if(!scn || !count) 205 return RES_BAD_ARG; 206 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 207 == darray_side_range_size_get(&scn->media_use)); 208 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 209 tmp = darray_trg_id_size_get(&scn->analyze.overlapping_ids); 210 ASSERT(tmp <= VRTX_MAX__); 211 *count = (trg_id_t)tmp; /* Back to API type */ 212 return RES_OK; 213 } 214 215 res_T 216 senc3d_scene_get_overlapping_triangle 217 (const struct senc3d_scene* scn, 218 const unsigned idx, 219 unsigned* trg_id) 220 { 221 if(!scn || !trg_id 222 || idx >= darray_trg_id_size_get(&scn->analyze.overlapping_ids)) 223 return RES_BAD_ARG; 224 ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) 225 == darray_side_range_size_get(&scn->media_use)); 226 ASSERT(darray_side_range_size_get(&scn->media_use) >= 1); 227 *trg_id = darray_trg_id_cdata_get(&scn->analyze.overlapping_ids)[idx]; 228 return RES_OK; 229 }