diff options
author | perepelits.m <perepelits.m@samsung.com> | 2015-12-01 16:38:48 -0800 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2015-12-01 16:39:29 -0800 |
commit | 32c33ed64dda542c7cfc952fc656bb711260441b (patch) | |
tree | 214c3ecb383578f9ddf77aa79b5938252fcfb481 /src/modules/evas/model_savers | |
parent | c421e519b0e834053023a600e8cad5b77173b4ad (diff) | |
download | efl-32c33ed64dda542c7cfc952fc656bb711260441b.tar.gz |
evas: refactor model's savers and loaders.
Summary:
Move common part to a separated document.
Make code more readable using smaller functions. (from Task T2713)
Reviewers: cedric, raster, Hermet
Subscribers: artem.popov
Differential Revision: https://phab.enlightenment.org/D3373
Diffstat (limited to 'src/modules/evas/model_savers')
3 files changed, 226 insertions, 135 deletions
diff --git a/src/modules/evas/model_savers/eet/evas_model_save_eet.c b/src/modules/evas/model_savers/eet/evas_model_save_eet.c index ff43a3f851..ebe68ec041 100644 --- a/src/modules/evas/model_savers/eet/evas_model_save_eet.c +++ b/src/modules/evas/model_savers/eet/evas_model_save_eet.c @@ -192,4 +192,3 @@ evas_model_save_file_eet(const Evas_Canvas3D_Mesh *mesh, _evas_canvas3d_eet_file_free(); } - diff --git a/src/modules/evas/model_savers/obj/evas_model_save_obj.c b/src/modules/evas/model_savers/obj/evas_model_save_obj.c index d9be3dce44..09e5c723c6 100644 --- a/src/modules/evas/model_savers/obj/evas_model_save_obj.c +++ b/src/modules/evas/model_savers/obj/evas_model_save_obj.c @@ -1,86 +1,71 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <stdlib.h> -#include <time.h> -#include "stdio.h" -#include "evas_common_private.h" -#include "evas_private.h" - -#define OPEN_FILE(extension)\ - FILE * _##extension##_file = fopen(_##extension##_file_name, "w+"); - -#define SAVE_GEOMETRICS(a, format) \ - vb = &f->vertices[a]; \ - if (vb->data != NULL) \ - { \ - fprintf(_obj_file, "o %s\n",_obj_file_name); \ - src = (float *)vb->data; \ - for (i = 0; i < pd->vertex_count; i++) \ - { \ - fprintf(_obj_file, format, src[0], src[1]); \ - if (a != EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD) \ - fprintf(_obj_file, " %.4f", src[2]); \ - fprintf(_obj_file, "\n"); \ - src += f->vertices[a].element_count; \ - } \ - } +#include "evas_model_load_save_common.h" + +static unsigned short* +_init_obj_indices_data(Evas_Model_Load_Save_Header header) +{ + unsigned short *i_data; + int i = 0; + + if (header.existence_of_positions) i++; + if (header.existence_of_normals) i++; + if (header.existence_of_tex_coords) i++; + i_data = calloc(header.vertices_count * i, sizeof(unsigned short)); + + return i_data; +} static void -_write_point(FILE * obj_file, +_vertex_data_free_cb(void *data) +{ + eina_stringshare_del(data); +} + +static void +_write_point(FILE *obj_file, int num, int num_of_point, - Eina_Bool existence_of_normal, - Eina_Bool existence_of_tex_point) + Evas_Model_Load_Save_Header header, + unsigned short *i_data) { - if (num_of_point == 1) + if (num_of_point == 0) fprintf(obj_file, "f "); - if (existence_of_normal) + if (header.existence_of_normals) { - if (existence_of_tex_point) - fprintf(obj_file, "%i/%i/%i ", num, num, num); + if (header.existence_of_tex_coords) + fprintf(obj_file, "%hu/%hu/%hu ", i_data[num], + i_data[num + header.vertices_count], + i_data[num + 2 * header.vertices_count]); else - fprintf(obj_file, "%i//%i ", num, num); + fprintf(obj_file, "%hu//%hu ", i_data[num], + i_data[num + header.vertices_count]); } else { - if (existence_of_tex_point) - fprintf(obj_file, "%i/%i ", num, num); + if (header.existence_of_tex_coords) + fprintf(obj_file, "%hu/%hu ", i_data[num], + i_data[num + header.vertices_count]); else - fprintf(obj_file, "%i ", num); + fprintf(obj_file, "%hu ", i_data[num]); } - if (num_of_point == 3) + if (num_of_point == 2) fprintf(obj_file, "\n"); } -static void -_save_mesh(Evas_Canvas3D_Mesh_Data *pd, const char *_obj_file_name, Evas_Canvas3D_Mesh_Frame *f) +static inline Eina_Bool +_write_obj_header(FILE *file, + const char *_mtl_file_name) { - Evas_Canvas3D_Vertex_Buffer *vb; time_t current_time; char* c_time_string; - int i; - float *src; - Eina_Bool existence_of_normal, existence_of_tex_point; - OPEN_FILE(obj) - if (!_obj_file) - { - ERR("File open '%s' for save failed", _obj_file_name); - return; - } - fprintf(_obj_file, "# Evas_3D saver OBJ v0.03 \n");//_obj_file created in macro - /* Adding time comment to .obj file. */ current_time = time(NULL); if (current_time == ((time_t)-1)) { ERR("Failure to compute the current time."); - fclose(_obj_file); - return; + return EINA_FALSE; } c_time_string = ctime(¤t_time); @@ -88,38 +73,117 @@ _save_mesh(Evas_Canvas3D_Mesh_Data *pd, const char *_obj_file_name, Evas_Canvas3 if (c_time_string == NULL) { ERR("Failure to convert the current time."); - fclose(_obj_file); - return; + return EINA_FALSE; + } + + fprintf(file, "# Evas_Canvas3D saver OBJ v0.03 \n"); + fprintf(file, "# Current time is %s \n", c_time_string); + fprintf(file, "mtllib %s \n\n", _mtl_file_name); + + return EINA_TRUE; +} + +static inline void +_write_obj_vertex_data(FILE *file, + Evas_Model_Load_Save_Header header, + Evas_Model_Load_Save_Data data, + unsigned short *i_data) +{ + int i, j; + int v = -1; + Eina_Stringshare *str, *cur_str, *cur_index; + unsigned short cur_hu; + + eina_init(); + Eina_Hash *vb; +#define WRITE_OBJ_VERTEX_DATA(name, num, format) \ + if (header.existence_of_##name) \ + { \ + cur_hu = 0; \ + v++; \ + vb = eina_hash_string_superfast_new(_vertex_data_free_cb); \ + for (i = 0; i < header.vertices_count; i++) \ + { \ + str = eina_stringshare_printf(" "); \ + for (j = 0; j < num; j++) \ + str = eina_stringshare_printf("%s %f", str, \ + data.name[i * num + j]); \ + cur_index = eina_hash_find(vb, str); \ + if (!cur_index) \ + { \ + cur_hu++; \ + cur_str = eina_stringshare_printf("%hu", cur_hu); \ + eina_hash_add(vb, str, cur_str); \ + i_data[v * header.vertices_count + i] = cur_hu; \ + fprintf(file, "%s%s\n", format, str); \ + } \ + else sscanf(cur_index, "%hu", \ + i_data + v * header.vertices_count + i); \ + } \ + eina_hash_free(vb); \ } + WRITE_OBJ_VERTEX_DATA(positions, 3, "v") + WRITE_OBJ_VERTEX_DATA(tex_coords, 2, "vt") + WRITE_OBJ_VERTEX_DATA(normals, 3, "vn") +#undef WRITE_OBJ_VERTEX_DATA + eina_shutdown(); +} - fprintf(_obj_file,"# Current time is %s \n", c_time_string); - fprintf(_obj_file,"mtllib %s.mtl \n\n", _obj_file_name); +static inline void +_write_obj_index_data(FILE *file, + Evas_Model_Load_Save_Header header, + Evas_Model_Load_Save_Data data, + unsigned short *i_data) +{ + int i; + int ic; + ic = header.indices_count ? header.indices_count : header.vertices_count; + for (i = 0; i < ic; i++) + _write_point(file, data.indices[i], i % 3, header, i_data); +} + +static void +_save_mesh(Evas_Canvas3D_Mesh_Data *pd, + const char *_obj_file_name, + const char *_mtl_file_name, + Evas_Canvas3D_Mesh_Frame *f) +{ + Evas_Model_Load_Save_Header header; + Evas_Model_Load_Save_Data data; + unsigned short *index_data; - /* Adding geometrics to file. */ - if (f == NULL) + if (!evas_model_save_header_from_mesh(pd, f, &header)) return; + + index_data = _init_obj_indices_data(header); + if (index_data == NULL) { - ERR("Not existing mesh frame."); - fclose(_obj_file); + ERR("Allocation of index data is failed."); return; } - SAVE_GEOMETRICS(EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION, "v %.4f %.4f") - SAVE_GEOMETRICS(EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL, "vn %.4f %.4f") - SAVE_GEOMETRICS(EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD, "vt %.4f %.4f") + evas_model_save_data_from_mesh(pd, f, header, &data); - existence_of_normal = (f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL].data != NULL); - existence_of_tex_point = (f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD].data != NULL); + FILE * _obj_file = fopen(_obj_file_name, "w+"); + if (!_obj_file) + { + ERR("File open '%s' for save failed", _obj_file_name); + free(index_data); + return; + } - fprintf(_obj_file,"usemtl Material\n s off\n"); - for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1 + if (!_write_obj_header(_obj_file, _mtl_file_name)) { - _write_point(_obj_file, i, 1, existence_of_normal, existence_of_tex_point); - i++; - _write_point(_obj_file, i, 2, existence_of_normal, existence_of_tex_point); - i++; - _write_point(_obj_file, i, 3, existence_of_normal, existence_of_tex_point); + fclose(_obj_file); + free(index_data); + return; } + + _write_obj_vertex_data(_obj_file, header, data, index_data); + fprintf(_obj_file,"usemtl Material\n s off\n"); + _write_obj_index_data(_obj_file, header, data, index_data); fclose(_obj_file); + free(index_data); + free(data.indices); } static void @@ -127,13 +191,13 @@ _save_material(Evas_Canvas3D_Mesh_Data *pd EINA_UNUSED, const char *_mtl_file_name, Evas_Canvas3D_Material_Data *mat) { - OPEN_FILE(mtl) + FILE * _mtl_file = fopen(_mtl_file_name, "w+"); if (!_mtl_file) { ERR("File open '%s' for save failed", _mtl_file_name); return; } - fprintf(_mtl_file, "# Evas_3D saver OBJ v0.03 \n");//_mtl_file created in macro + fprintf(_mtl_file, "# Evas_Canvas3D saver OBJ v0.03 \n");//_mtl_file created in macro fprintf(_mtl_file, "# Material Count: 1 \n\n"); fprintf(_mtl_file, "newmtl Material \n"); fprintf(_mtl_file, "Ns 1.000000 \n");//exp factor for specular highlight @@ -157,7 +221,9 @@ _save_material(Evas_Canvas3D_Mesh_Data *pd EINA_UNUSED, } void -evas_model_save_file_obj(const Evas_Canvas3D_Mesh *mesh, const char *_obj_file_name, Evas_Canvas3D_Mesh_Frame *f) +evas_model_save_file_obj(const Evas_Canvas3D_Mesh *mesh, + const char *_obj_file_name, + Evas_Canvas3D_Mesh_Frame *f) { int len; char *_mtl_file_name, *_without_extention; @@ -166,18 +232,15 @@ evas_model_save_file_obj(const Evas_Canvas3D_Mesh *mesh, const char *_obj_file_n len = strlen(_obj_file_name); _without_extention = (char *)malloc(len - 3); _mtl_file_name = (char *)malloc(len + 1); + eina_strlcpy(_without_extention, _obj_file_name, len - 3); + eina_str_join(_mtl_file_name, len + 1, '.', _without_extention, "mtl"); + free(_without_extention); Evas_Canvas3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_CANVAS3D_MESH_CLASS); - _save_mesh(pd, _obj_file_name, f); - mat = eo_data_scope_get(f->material, EVAS_CANVAS3D_MATERIAL_CLASS); - if (mat != NULL) - { - eina_strlcpy(_without_extention, _obj_file_name, len - 3); - eina_str_join(_mtl_file_name, len + 1, '.', _without_extention, "mtl"); - _save_material(pd, _mtl_file_name, mat); - } - free(_without_extention); + if (mat != NULL) _save_material(pd, _mtl_file_name, mat); + _save_mesh(pd, _obj_file_name, _mtl_file_name, f); + free(_mtl_file_name); } diff --git a/src/modules/evas/model_savers/ply/evas_model_save_ply.c b/src/modules/evas/model_savers/ply/evas_model_save_ply.c index 0be42f7f86..8da8f741ea 100644 --- a/src/modules/evas/model_savers/ply/evas_model_save_ply.c +++ b/src/modules/evas/model_savers/ply/evas_model_save_ply.c @@ -1,21 +1,80 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "evas_model_load_save_common.h" -#include <stdlib.h> -#include <time.h> -#include "stdio.h" -#include "math.h" -#include "evas_common_private.h" -#include "evas_private.h" +static inline void +_write_ply_header(FILE *file, Evas_Model_Load_Save_Header header) +{ + const char *pf = "property float", *puc = "property uchar"; + fprintf(file, "ply\n" \ + "format ascii 1.0\n" \ + "comment Created by EFL evas_canvas3d_mesh_saver_ply.c version 2 " \ + "(sub 0) - www.enlightenment.org, source file: ''\n"); + fprintf(file, "element vertex %d\n", header.vertices_count); + + if (header.existence_of_positions) + fprintf(file, "%s x\n%s y\n%s z\n", pf, pf, pf); + if (header.existence_of_normals) + fprintf(file, "%s nx\n%s ny\n%s nz\n", pf, pf, pf); + if (header.existence_of_tex_coords) + fprintf(file, "%s s\n%s t\n", pf, pf); + if (header.existence_of_colors) + fprintf(file, "%s red\n%s green\n%s blue\n", puc, puc, puc); + + fprintf(file, "element face %d\n" \ + "property list uchar uint vertex_indices\n" \ + "end_header\n", header.indices_count / 3); +} + +static inline void +_write_ply_vertex_data(FILE *file, + Evas_Model_Load_Save_Header header, + Evas_Model_Load_Save_Data data) +{ + int i, j; + for (i = 0; i < header.vertices_count; i++) + { +#define WRITE_PLY_VERTEX_DATA(name, num)\ + if (header.existence_of_##name)\ + for (j = 0; j < num; j++, data.name++)\ + fprintf(file, "%f ", data.name[0]); + WRITE_PLY_VERTEX_DATA(positions, 3) + WRITE_PLY_VERTEX_DATA(normals, 3) + WRITE_PLY_VERTEX_DATA(tex_coords, 2) +#undef WRITE_PLY_VERTEX_DATA + + if (header.existence_of_colors) + { + for (j = 0; j < 3; j++, data.colors++) + fprintf(file, "%.0f ", round(data.colors[0] * 255)); + data.colors++; + } + fprintf(file, "\n"); + } +} + +static inline void +_write_ply_index_data(FILE *file, + Evas_Model_Load_Save_Header header, + Evas_Model_Load_Save_Data data) +{ + int i, triangles_count = header.indices_count / 3; + for (i = 0; i < triangles_count; i++, data.indices += 3) + fprintf(file, "3 %d %d %d\n", data.indices[0], + data.indices[1], + data.indices[2]); +} void -evas_model_save_file_ply(const Evas_Canvas3D_Mesh *mesh, const char *file, Evas_Canvas3D_Mesh_Frame *f) +evas_model_save_file_ply(const Evas_Canvas3D_Mesh *mesh, + const char *file, + Evas_Canvas3D_Mesh_Frame *f) { - float *src_pos, *src_nor, *src_tex, *src_col; - int i; + Evas_Model_Load_Save_Header header; + Evas_Model_Load_Save_Data data; Evas_Canvas3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_CANVAS3D_MESH_CLASS); + if (!evas_model_save_header_from_mesh(pd, f, &header)) return; + evas_model_save_data_from_mesh(pd, f, header, &data); + FILE *_ply_file = fopen(file, "w+"); if (!_ply_file) { @@ -23,40 +82,10 @@ evas_model_save_file_ply(const Evas_Canvas3D_Mesh *mesh, const char *file, Evas_ return; } - fprintf(_ply_file,"ply\nformat ascii 1.0\ncomment Created by EFL evas_canvas3d_mesh_saver_ply.c" \ - "version 1 (sub 0) - www.enlightenment.org, source file: ''\n"); - fprintf(_ply_file,"element vertex %d\n", pd->vertex_count); - fprintf(_ply_file,"property float x\nproperty float y\nproperty float z\n" \ - "property float nx\nproperty float ny\nproperty float nz\n" \ - "property float s\nproperty float t\n" \ - "property uchar red\nproperty uchar green\nproperty uchar blue\n"); - fprintf(_ply_file,"element face %d\nproperty list uchar uint vertex_indices\nend_header\n", - pd->index_count / 3); - - src_pos = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION])->data; - src_nor = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL])->data; - src_tex = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD])->data; - src_col = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR])->data; - - for (i = 0; i < pd->vertex_count; i++) - { - fprintf(_ply_file,"%f %f %f %f %f %f %f %f %.0f %.0f %.0f\n", - src_pos[0], src_pos[1], src_pos[2], - src_nor[0], src_nor[1], src_nor[2], - src_tex[0], src_tex[1], - round(src_col[0] * 255), round(src_col[1] * 255), round(src_col[2] * 255)); - src_pos += 3; - src_nor += 3; - src_tex += 2; - src_col += 4; - } - - unsigned short* indices = (unsigned short*) pd->indices; - - for (i = 0; i < pd->index_count / 3; i++) - { - fprintf(_ply_file,"3 %d %d %d\n", indices[3 * i], indices[3 * i + 1], indices[3 * i + 2]); - } + _write_ply_header(_ply_file, header); + _write_ply_vertex_data(_ply_file, header, data); + _write_ply_index_data(_ply_file, header, data); + free(data.indices); fclose(_ply_file); } |