diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 9a0d3e81fb..07ff7c75c8 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -224,7 +224,8 @@ lib/evas/canvas/evas_canvas3d_node_callback.h lib_evas_libevas_la_SOURCES += \ lib/evas/common3d/save_load/evas_model_load.c \ lib/evas/common3d/save_load/evas_model_save.c \ -lib/evas/common3d/save_load/evas_model_load_save_common.c \ +lib/evas/common3d/save_load/evas_model_common.c \ +lib/evas/common3d/save_load/evas_model_common.h \ modules/evas/model_loaders/eet/evas_model_load_eet.c \ modules/evas/model_loaders/md2/evas_model_load_md2.c \ modules/evas/model_loaders/obj/evas_model_load_obj.c \ diff --git a/src/lib/evas/common3d/save_load/evas_model_load_save_common.c b/src/lib/evas/common3d/save_load/evas_model_common.c similarity index 99% rename from src/lib/evas/common3d/save_load/evas_model_load_save_common.c rename to src/lib/evas/common3d/save_load/evas_model_common.c index 190ba5982c..612bccd5c8 100644 --- a/src/lib/evas/common3d/save_load/evas_model_load_save_common.c +++ b/src/lib/evas/common3d/save_load/evas_model_common.c @@ -1,4 +1,4 @@ -#include "evas_model_load_save_common.h" +#include "evas_model_common.h" # define SAVE_MESH_INDICES_COPY \ if (header.indices_count) \ diff --git a/src/lib/evas/common3d/save_load/evas_model_load_save_common.h b/src/lib/evas/common3d/save_load/evas_model_common.h similarity index 100% rename from src/lib/evas/common3d/save_load/evas_model_load_save_common.h rename to src/lib/evas/common3d/save_load/evas_model_common.h diff --git a/src/modules/evas/model_loaders/eet/evas_model_load_eet.c b/src/modules/evas/model_loaders/eet/evas_model_load_eet.c index ea742086a2..a36dff4f34 100644 --- a/src/modules/evas/model_loaders/eet/evas_model_load_eet.c +++ b/src/modules/evas/model_loaders/eet/evas_model_load_eet.c @@ -128,3 +128,5 @@ evas_model_load_file_eet(Evas_Canvas3D_Mesh *mesh, Eina_File *file) _evas_canvas3d_eet_file_free(); } + + diff --git a/src/modules/evas/model_loaders/ply/evas_model_load_ply.c b/src/modules/evas/model_loaders/ply/evas_model_load_ply.c index 971e951613..1beef18a94 100644 --- a/src/modules/evas/model_loaders/ply/evas_model_load_ply.c +++ b/src/modules/evas/model_loaders/ply/evas_model_load_ply.c @@ -1,4 +1,44 @@ -#include "evas_model_load_save_common.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "stdio.h" +#include "evas_common_private.h" +#include "evas_private.h" +#include + +/* set value to position [x][y] to array name which have. */ +#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y)) + +/* Structures for reading data from file. */ +typedef struct _PLY_Header PLY_Header; + +struct _PLY_Header +{ + int vertices_count; + int triangles_count; + Eina_Bool existence_of_geometries; + Eina_Bool existence_of_normals; + Eina_Bool existence_of_texcoords; + Eina_Bool existence_of_colors; +}; + +/* create new header */ +static inline PLY_Header +_new_ply_header() +{ + PLY_Header header; + + header.vertices_count = 0; + header.triangles_count = 0; + header.existence_of_geometries = EINA_FALSE; + header.existence_of_normals = EINA_FALSE; + header.existence_of_texcoords = EINA_FALSE; + header.existence_of_colors = EINA_FALSE; + + return header; +} static inline char * _to_next_line(char *current) @@ -41,8 +81,8 @@ _read_data(float *array, int place, int count, char *current, float divider) return current; } -static inline Eina_Bool -_read_ply_header(char *map, Evas_Model_Load_Save_Header *header) +static inline PLY_Header +_read_header(char *map)//Check properties of mesh in .ply file. { eina_init(); @@ -50,29 +90,30 @@ _read_ply_header(char *map, Evas_Model_Load_Save_Header *header) int vertex_lines, triangles = 0, vertices_in_current_face = 0; char **helping_pointer; char *current; + PLY_Header header; + header = _new_ply_header(); helping_pointer = eina_str_split(map, "vertex ", 0); if (helping_pointer == NULL) { ERR("File have not kayword vertex. It is necessary."); - return EINA_FALSE; + return header; } - sscanf(helping_pointer[1], "%d", &header->vertices_count); - + sscanf(helping_pointer[1], "%d", &header.vertices_count); free(helping_pointer); helping_pointer = eina_str_split(map, "end_header\n", 0); if (helping_pointer == NULL) { ERR("File have not kayword end_header. It is necessary."); - return EINA_FALSE; + return header; } current = helping_pointer[1]; - vertex_lines = header->vertices_count; + vertex_lines = header.vertices_count; while (*current != '\0') { if (vertex_lines == 1) @@ -98,7 +139,8 @@ _read_ply_header(char *map, Evas_Model_Load_Save_Header *header) current++; } - header->indices_count = 3 * triangles; + header.triangles_count = triangles; + free(helping_pointer); /* analyse flags used when file was saved in blender */ helping_pointer = eina_str_split(map, "property float ", 0); @@ -106,124 +148,243 @@ _read_ply_header(char *map, Evas_Model_Load_Save_Header *header) if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'x') && (helping_pointer[2] != NULL) && (*helping_pointer[2] == 'y') && (helping_pointer[3] != NULL) && (*helping_pointer[3] == 'z')) - header->existence_of_positions = EINA_TRUE; - else return EINA_FALSE; + header.existence_of_geometries = EINA_TRUE; + else return header; if ((helping_pointer[4] != NULL) && (*helping_pointer[4] == 'n') && (helping_pointer[5] != NULL) && (*helping_pointer[5] == 'n') && (helping_pointer[6] != NULL) && (*helping_pointer[6] == 'n')) - header->existence_of_normals = EINA_TRUE; + header.existence_of_normals = EINA_TRUE; - if ((header->existence_of_normals && + if ((header.existence_of_normals && ((helping_pointer[7] != NULL) && (*helping_pointer[7] == 's') && (helping_pointer[8] != NULL) && (*helping_pointer[8] == 't'))) || - (!header->existence_of_normals && + (!header.existence_of_normals && ((helping_pointer[4] != NULL) && (*helping_pointer[4] == 's') && (helping_pointer[5] != NULL) && (*helping_pointer[5] == 't')))) - header->existence_of_tex_coords = EINA_TRUE; + header.existence_of_texcoords = EINA_TRUE; helping_pointer = eina_str_split(map, "property uchar ", 0); if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'r') && (helping_pointer[2] != NULL) && (*helping_pointer[2] == 'g') && (helping_pointer[3] != NULL) && (*helping_pointer[3] == 'b')) - header->existence_of_colors = EINA_TRUE; - - if (!header->existence_of_positions) - { - ERR("File have not x, y, or z field as the first 3 float fields. They are necessary."); - return EINA_FALSE; - } + header.existence_of_colors = EINA_TRUE; free(helping_pointer); - return EINA_TRUE; -} -static inline void -_read_ply_vertex_data(Evas_Model_Load_Save_Header header, - char **current, - Evas_Model_Load_Save_Data data) -{ - int i; - for (i = 0; i < header.vertices_count; i++) - { - *current = _read_data(data.positions, i, 3, *current, 1.0); - if (header.existence_of_normals) - *current = _read_data(data.normals, i, 3, *current, 1.0); - if (header.existence_of_tex_coords) - *current = _read_data(data.tex_coords, i, 2, *current, 1.0); - if (header.existence_of_colors) - *current = _read_data(data.colors, i, 3, *current, 255.0); - *current = _to_begin_of_line(*current); - } -} - -static inline void -_read_ply_indices_data(Evas_Model_Load_Save_Header header, - char **current, - Evas_Model_Load_Save_Data data) -{ - int i, j, count_of_triangles_in_line = 0; - - for (i = 0; i < header.indices_count;) - { - sscanf (*current,"%d", &count_of_triangles_in_line); - count_of_triangles_in_line -= 2; - *current = _to_next_number(*current, 1); - - sscanf (*current,"%hu", data.indices + i); - - for (j = 0; j < count_of_triangles_in_line; j++) - { - if (j > 0) - data.indices[i] = data.indices[i - 3]; - *current = _to_next_number(*current, 1); - sscanf (*current,"%hu %hu", - data.indices + i + 1, - data.indices + i + 2); - i+=3; - } - *current = _to_next_line(*current); - } + return header; } void evas_model_load_file_ply(Evas_Canvas3D_Mesh *mesh, Eina_File *file) { - char *current = NULL, *map = NULL; - Evas_Model_Load_Save_Header header; - Evas_Model_Load_Save_Data data; - Evas_Model_Load_Save_Stride stride; + Evas_Canvas3D_Mesh_Data *pd; + int i = 0, j = 0, count_of_triangles_in_line = 0; + float *pos, *nor, *tex, *col; + int stride_pos, stride_nor, stride_tex, stride_col; + char *current, *map; + PLY_Header header; + float *_vertices_ply = NULL, *_normals_ply = NULL; + float *_tex_coords_ply = NULL, *_colors_ply = NULL; + char **helping_pointer; map = eina_file_map_all(file, EINA_FILE_SEQUENTIAL); + if (map == NULL) { ERR("Failed to create map from file %s\n", eina_file_filename_get(file)); return; } - header = evas_model_load_save_header_new(); - if(!_read_ply_header(map, &header)) return; + header = _read_header(map); - if (!evas_model_load_allocate_data_due_to_header(header, &data)) + if (!header.existence_of_geometries) { - ERR("Memory allocation is failed."); + ERR("File have not x, y, or z field as the first 3 float fields. They are necessary."); return; } - current = eina_str_split(map, "end_header\n", 0)[1]; - _read_ply_vertex_data(header, ¤t, data); - _read_ply_indices_data(header, ¤t, data); - evas_model_load_vertex_data_to_mesh(mesh, header, data, &stride); - evas_model_load_indices_data_to_mesh(mesh, header, data); - evas_model_load_vertex_data_unmap(mesh, 0, header); - evas_model_load_aabb_add_to_frame(mesh, 0, stride); + helping_pointer = eina_str_split(map, "end_header\n", 0); + + if (helping_pointer == NULL) + { + ERR("File have not kayword end_header. It is necessary."); + return; + } + + current = helping_pointer[1]; + + _vertices_ply = malloc(header.vertices_count * 3 * sizeof(float)); + if (header.existence_of_normals) + _normals_ply = malloc(header.vertices_count * 3 * sizeof(float)); + if (header.existence_of_texcoords) + _tex_coords_ply = malloc(header.vertices_count * 2 * sizeof(float)); + if (header.existence_of_colors) + _colors_ply = malloc(header.vertices_count * 3 * sizeof(float)); + unsigned short *_indices = malloc(header.triangles_count * 3 * sizeof(unsigned short)); + + if ((header.existence_of_geometries && (_vertices_ply == NULL)) || + (header.existence_of_normals && (_normals_ply == NULL)) || + (header.existence_of_texcoords && (_tex_coords_ply == NULL)) || + (header.existence_of_colors && (_colors_ply == NULL)) || + (_indices == NULL)) + { + ERR("Allocate memory is failed."); + free(_vertices_ply); + free(_normals_ply); + free(_tex_coords_ply); + free(_colors_ply); + free(_indices); + return; + } + + for (i = 0; i < header.vertices_count; i++) + { + current = _read_data(_vertices_ply, i, 3, current, 1.0); + if (header.existence_of_normals) + current = _read_data(_normals_ply, i, 3, current, 1.0); + if (header.existence_of_texcoords) + current = _read_data(_tex_coords_ply, i, 2, current, 1.0); + if (header.existence_of_colors) + current = _read_data(_colors_ply, i, 3, current, 255.0); + current = _to_begin_of_line(current); + } + + for (i = 0; i < header.triangles_count * 3;) + { + sscanf (current,"%d", &count_of_triangles_in_line); + count_of_triangles_in_line -= 2; + current = _to_next_number(current, 1); + + sscanf (current,"%hu", _indices + i); + + for (j = 0; j < count_of_triangles_in_line; j++) + { + if (j > 0) + _indices[i] = _indices[i - 3]; + current = _to_next_number(current, 1); + sscanf (current,"%hu %hu", + _indices + i + 1, + _indices + i + 2); + i+=3; + } + current = _to_next_line(current); + } + + /* prepare of mesh and take pointers to data which must be read */ + eo_do(mesh, + evas_canvas3d_mesh_vertex_count_set(header.vertices_count), + evas_canvas3d_mesh_vertex_assembly_set(EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLES), + evas_canvas3d_mesh_frame_add(0), + evas_canvas3d_mesh_frame_vertex_data_copy_set(0, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION, 0, NULL), + evas_canvas3d_mesh_frame_vertex_data_copy_set(0, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL, 0, NULL), + evas_canvas3d_mesh_frame_vertex_data_copy_set(0, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD, 0, NULL), + evas_canvas3d_mesh_frame_vertex_data_copy_set(0, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR, 0, NULL), + + pos = (float *)evas_canvas3d_mesh_frame_vertex_data_map(0, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION), + nor = (float *)evas_canvas3d_mesh_frame_vertex_data_map(0, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL), + tex = (float *)evas_canvas3d_mesh_frame_vertex_data_map(0, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD), + col = (float *)evas_canvas3d_mesh_frame_vertex_data_map(0, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR), + + stride_pos = evas_canvas3d_mesh_frame_vertex_stride_get(0, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION), + stride_nor = evas_canvas3d_mesh_frame_vertex_stride_get(0, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL), + stride_tex = evas_canvas3d_mesh_frame_vertex_stride_get(0, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD), + stride_col = evas_canvas3d_mesh_frame_vertex_stride_get(0, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR)); + + if (stride_pos == 0) stride_pos = sizeof(float) * 3; + if (stride_nor == 0) stride_nor = sizeof(float) * 3; + if (stride_tex == 0) stride_tex = sizeof(float) * 2; + if (stride_col == 0) stride_col = sizeof(float) * 4; + + + for (j = 0; j < header.vertices_count; j++) + { + float *p, *n, *t, *c; + + p = (float *)((char *)pos + stride_pos * j); + n = (float *)((char *)nor + stride_nor * j); + t = (float *)((char *)tex + stride_tex * j); + c = (float *)((char *)col + stride_col * j); + + + p[0] = ARRAY_2D(_vertices_ply, j, 0, 3); + p[1] = ARRAY_2D(_vertices_ply, j, 1, 3); + p[2] = ARRAY_2D(_vertices_ply, j, 2, 3); + + if (header.existence_of_normals) + { + n[0] = ARRAY_2D(_normals_ply, j, 0, 3); + n[1] = ARRAY_2D(_normals_ply, j, 1, 3); + n[2] = ARRAY_2D(_normals_ply, j, 2, 3); + } + else + { + n[0] = 0.0; + n[1] = 0.0; + n[2] = 0.0; + } + + if (header.existence_of_texcoords) + { + t[0] = ARRAY_2D(_tex_coords_ply, j, 0, 2); + t[1] = ARRAY_2D(_tex_coords_ply, j, 1, 2); + } + else + { + t[0] = 0.0; + t[1] = 0.0; + } + + if (header.existence_of_colors) + { + c[0] = ARRAY_2D(_colors_ply, j, 0, 3); + c[1] = ARRAY_2D(_colors_ply, j, 1, 3); + c[2] = ARRAY_2D(_colors_ply, j, 2, 3); + c[3] = 1.0; + } + else + { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + c[3] = 1.0; + } + } + + eo_do(mesh, + evas_canvas3d_mesh_index_data_copy_set(EVAS_CANVAS3D_INDEX_FORMAT_UNSIGNED_SHORT, + header.triangles_count * 3, + _indices)); + + free(helping_pointer); + free(_vertices_ply); + if (header.existence_of_normals) + free(_normals_ply); + if (header.existence_of_texcoords) + free(_tex_coords_ply); + if (header.existence_of_colors) + free(_colors_ply); + free(_indices); + + /* Unmap vertex buffer. */ + eo_do(mesh, + evas_canvas3d_mesh_frame_vertex_data_unmap(0, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION), + evas_canvas3d_mesh_frame_vertex_data_unmap(0, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL), + evas_canvas3d_mesh_frame_vertex_data_unmap(0, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD), + evas_canvas3d_mesh_frame_vertex_data_unmap(0, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR)); + + pd = eo_data_scope_get(mesh, EVAS_CANVAS3D_MESH_CLASS); + + if (!evas_canvas3d_mesh_aabb_add_to_frame(pd, 0, stride_pos)) + { + ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0); + } if (map) { eina_file_map_free(file, map); map = NULL; } - - evas_model_load_save_data_free(header, &data); } + 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 ebe68ec041..ff43a3f851 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,3 +192,4 @@ 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 8789ce44eb..d9be3dce44 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,71 +1,86 @@ -#include "evas_model_load_save_common.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -static unsigned short* -_init_obj_indices_data(Evas_Model_Load_Save_Header header) -{ - unsigned short *i_data; - int i = 0; +#include +#include +#include "stdio.h" +#include "evas_common_private.h" +#include "evas_private.h" - 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)); +#define OPEN_FILE(extension)\ + FILE * _##extension##_file = fopen(_##extension##_file_name, "w+"); - return i_data; -} +#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; \ + } \ + } static void -_vertex_data_free_cb(void *data) -{ - eina_stringshare_del(data); -} - -static void -_write_point(FILE *obj_file, +_write_point(FILE * obj_file, int num, int num_of_point, - Evas_Model_Load_Save_Header header, - unsigned short *i_data) + Eina_Bool existence_of_normal, + Eina_Bool existence_of_tex_point) { - if (num_of_point == 0) + if (num_of_point == 1) fprintf(obj_file, "f "); - if (header.existence_of_normals) + if (existence_of_normal) { - 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]); + if (existence_of_tex_point) + fprintf(obj_file, "%i/%i/%i ", num, num, num); else - fprintf(obj_file, "%hu//%hu ", i_data[num], - i_data[num + header.vertices_count]); + fprintf(obj_file, "%i//%i ", num, num); } else { - if (header.existence_of_tex_coords) - fprintf(obj_file, "%hu/%hu ", i_data[num], - i_data[num + header.vertices_count]); + if (existence_of_tex_point) + fprintf(obj_file, "%i/%i ", num, num); else - fprintf(obj_file, "%hu ", i_data[num]); + fprintf(obj_file, "%i ", num); } - if (num_of_point == 2) + if (num_of_point == 3) fprintf(obj_file, "\n"); } -static inline Eina_Bool -_write_obj_header(FILE *file, - const char *_mtl_file_name) +static void +_save_mesh(Evas_Canvas3D_Mesh_Data *pd, const char *_obj_file_name, Evas_Canvas3D_Mesh_Frame *f) { + 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."); - return EINA_FALSE; + fclose(_obj_file); + return; } c_time_string = ctime(¤t_time); @@ -73,117 +88,38 @@ _write_obj_header(FILE *file, if (c_time_string == NULL) { ERR("Failure to convert the current time."); - 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(); -} - -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; - - if (!evas_model_save_header_from_mesh(pd, f, &header)) return; - - index_data = _init_obj_indices_data(header); - if (index_data == NULL) - { - ERR("Allocation of index data is failed."); - return; - } - - evas_model_save_data_from_mesh(pd, f, header, &data); - - FILE * _obj_file = fopen(_obj_file_name, "wb+"); - if (!_obj_file) - { - ERR("File open '%s' for save failed", _obj_file_name); - free(index_data); - return; - } - - if (!_write_obj_header(_obj_file, _mtl_file_name)) - { fclose(_obj_file); - free(index_data); return; } - _write_obj_vertex_data(_obj_file, header, data, index_data); + fprintf(_obj_file,"# Current time is %s \n", c_time_string); + fprintf(_obj_file,"mtllib %s.mtl \n\n", _obj_file_name); + + /* Adding geometrics to file. */ + if (f == NULL) + { + ERR("Not existing mesh frame."); + fclose(_obj_file); + 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") + + 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); + fprintf(_obj_file,"usemtl Material\n s off\n"); - _write_obj_index_data(_obj_file, header, data, index_data); + for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1 + { + _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); - free(data.indices); } static void @@ -191,13 +127,13 @@ _save_material(Evas_Canvas3D_Mesh_Data *pd EINA_UNUSED, const char *_mtl_file_name, Evas_Canvas3D_Material_Data *mat) { - FILE * _mtl_file = fopen(_mtl_file_name, "wb+"); + OPEN_FILE(mtl) if (!_mtl_file) { ERR("File open '%s' for save failed", _mtl_file_name); return; } - fprintf(_mtl_file, "# Evas_Canvas3D saver OBJ v0.03 \n");//_mtl_file created in macro + fprintf(_mtl_file, "# Evas_3D 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 @@ -221,9 +157,7 @@ _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; @@ -232,15 +166,18 @@ evas_model_save_file_obj(const Evas_Canvas3D_Mesh *mesh, 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); + } - if (mat != NULL) _save_material(pd, _mtl_file_name, mat); - _save_mesh(pd, _obj_file_name, _mtl_file_name, f); - + free(_without_extention); 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 805f267bc0..0be42f7f86 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,91 +1,62 @@ -#include "evas_model_load_save_common.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -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]); -} +#include +#include +#include "stdio.h" +#include "math.h" +#include "evas_common_private.h" +#include "evas_private.h" 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) { - Evas_Model_Load_Save_Header header; - Evas_Model_Load_Save_Data data; + float *src_pos, *src_nor, *src_tex, *src_col; + int i; 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, "wb+"); + FILE *_ply_file = fopen(file, "w+"); if (!_ply_file) { ERR("File open '%s' for save failed", file); return; } - _write_ply_header(_ply_file, header); - _write_ply_vertex_data(_ply_file, header, data); - _write_ply_index_data(_ply_file, header, data); + 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]); + } - free(data.indices); fclose(_ply_file); }