solstice_dump.c (4654B)
1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com) 2 * Copyright (C) 2016-2018 CNRS 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 #include "solstice_c.h" 18 #include <solstice/ssol.h> 19 20 struct dump_context { 21 FILE* output; 22 size_t ids_offset; 23 enum solstice_args_dump_split_mode split_mode; 24 }; 25 26 /******************************************************************************* 27 * Helper functions 28 ******************************************************************************/ 29 static void 30 dump_instantiated_shaded_shape 31 (struct ssol_instantiated_shaded_shape* sshape, struct dump_context* ctx) 32 { 33 unsigned i, ntris, nverts; 34 enum ssol_material_type type; 35 const char* mtl; 36 ASSERT(sshape && ctx); 37 38 SSOL(material_get_type(sshape->mtl_front, &type)); 39 switch(type) { 40 case SSOL_MATERIAL_DIELECTRIC: mtl = "dielectric"; break; 41 case SSOL_MATERIAL_MATTE: mtl = "matte"; break; 42 case SSOL_MATERIAL_MIRROR: mtl = "mirror"; break; 43 case SSOL_MATERIAL_THIN_DIELECTRIC: mtl = "thin_dielectric"; break; 44 case SSOL_MATERIAL_VIRTUAL: mtl = "virtual"; break; 45 default: FATAL("Unexpected Solstice Solver material type.\n"); break; 46 } 47 48 fprintf(ctx->output, "usemtl %s\n", mtl); 49 50 SSOL(shape_get_vertices_count(sshape->shape, &nverts)); 51 FOR_EACH(i, 0, nverts) { 52 double pos[3]; 53 SSOL(instantiated_shaded_shape_get_vertex_attrib 54 (sshape, i, SSOL_POSITION, pos)); 55 fprintf(ctx->output, "v %g %g %g\n", SPLIT3(pos)); 56 } 57 58 SSOL(shape_get_triangles_count(sshape->shape, &ntris)); 59 FOR_EACH(i, 0, ntris) { 60 unsigned ids[3]; 61 SSOL(shape_get_triangle_indices(sshape->shape, i, ids)); 62 /* Note that in the obj fileformat the first index is 1 rather than 0 */ 63 fprintf(ctx->output, "f %lu %lu %lu\n", 64 (unsigned long)(ids[0] + 1 + ctx->ids_offset), 65 (unsigned long)(ids[1] + 1 + ctx->ids_offset), 66 (unsigned long)(ids[2] + 1 + ctx->ids_offset)); 67 } 68 69 if(ctx->split_mode == SOLSTICE_ARGS_DUMP_SPLIT_OBJECT) { 70 fprintf(ctx->output, "---\n"); 71 ctx->ids_offset = 0; 72 } else { 73 ctx->ids_offset += nverts; 74 } 75 } 76 77 static res_T 78 dump_instance(struct ssol_instance* instance, void* context) 79 { 80 struct dump_context* ctx = context; 81 size_t i, n; 82 ASSERT(instance && ctx); 83 84 SSOL(instance_get_shaded_shapes_count(instance, &n)); 85 FOR_EACH(i, 0, n) { 86 struct ssol_instantiated_shaded_shape sshape; 87 SSOL(instance_get_shaded_shape(instance, i, &sshape)); 88 dump_instantiated_shaded_shape(&sshape, ctx); 89 } 90 91 return RES_OK; 92 } 93 94 static res_T 95 dump_geometry 96 (const struct sanim_node* n, const double transform[12], void* data) 97 { 98 struct solstice_node* node; 99 struct dump_context* ctx = data; 100 res_T res = RES_OK; 101 ASSERT(n && data); 102 (void)transform; 103 104 node = CONTAINER_OF(n, struct solstice_node, anim); 105 if(node->type != SOLSTICE_NODE_GEOMETRY) return RES_OK; 106 fprintf(ctx->output, "g %s\n", solstice_node_get_name(node)); 107 res = dump_instance(node->instance, data); 108 if(res != RES_OK) return res; 109 110 if(ctx->split_mode == SOLSTICE_ARGS_DUMP_SPLIT_GEOMETRY) { 111 fprintf(ctx->output, "---\n"); 112 ctx->ids_offset = 0; 113 } 114 return RES_OK; 115 } 116 117 /******************************************************************************* 118 * Local functions 119 ******************************************************************************/ 120 res_T 121 solstice_dump(struct solstice* solstice) 122 { 123 struct dump_context ctx; 124 size_t i, n; 125 res_T res = RES_OK; 126 ASSERT(solstice && solstice->dump_format == SOLSTICE_ARGS_DUMP_OBJ); 127 128 ctx.output = solstice->output; 129 ctx.ids_offset = 0; 130 ctx.split_mode = solstice->dump_split_mode; 131 132 n = darray_nodes_size_get(&solstice->roots); 133 FOR_EACH(i, 0, n) { 134 struct solstice_node* node = darray_nodes_data_get(&solstice->roots)[i]; 135 136 fprintf(solstice->output, "# %s\n", solstice_node_get_name(node)); 137 138 res = sanim_node_visit_tree(&node->anim, NULL, &ctx, dump_geometry); 139 if(res != RES_OK) { 140 fprintf(stderr, "Could not dump the solstice geometry.\n"); 141 goto error; 142 } 143 } 144 145 exit: 146 return res; 147 error: 148 goto exit; 149 } 150