summaryrefslogtreecommitdiff
path: root/src/modules/evas/model_savers
diff options
context:
space:
mode:
authorBogdan Devichev <b.devichev@samsung.com>2015-02-11 18:13:58 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-02-11 18:31:53 +0100
commit150613086643af46b02acc958252aa553ac89903 (patch)
treea7ea8cf91ffc10998bf700bce41f21d9700bb882 /src/modules/evas/model_savers
parentc6c6233b50e0328d461158247a4e7db3b5890362 (diff)
evas: Evas_3D - iport/export of Obj format can be read even if obj-file does not have normals or tex-coords.
Summary: This commit fixed several bugs, and show what was be fixed. Bugs: - When designer save obj file in Blender, he/she can set flags (fig 1). Normals and UV coords flags was necessary for obj loader. Loader crushed when they are not set as true. It fixed by this commit. - Another loaders set default values to data which aren't in loading file, so mesh need more memory for unused data. It fixed by this commit for obj and will be fixed for another formats in future. - Saver saved incorrect data if normals or tex_coords was not set in mesh in evas. Now it fixed. - Saver failed if it save mesh without material. It fixed and in this case material file is not created now. - Also fixed some leaks and undefined behavior which valgrind shows. Example: - Example shows cases described above. Example use files saved with different flags for it. Resources: - man_mesh is replaced by several smaller file, to use them for showing new features and fixes. For example, similar to that models can be added when implement work with material for obj, work with different flags for obj loader/saver etc. (big count of man_meshes is to much memory). - texture for home is flipped, because of bug with texture in efl to see if tex_coords is incorrect. Test: - test should be rewritten in future, because another formats still use default values for normals and tex_coords. And test can not pass for all types of obj file because of standardization for any format in him. Test Plan: Test suit will be rewritten after correcting of other formats (they will set NULL to file when save an empty data (like mesh without normals)) Reviewers: Hermet, raster, cedric Reviewed By: cedric Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D1957 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/modules/evas/model_savers')
-rw-r--r--src/modules/evas/model_savers/obj/evas_model_save_obj.c107
1 files changed, 72 insertions, 35 deletions
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 1cc7e8a744..00f8a76cc4 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
@@ -9,25 +9,54 @@
9#include "evas_private.h" 9#include "evas_private.h"
10 10
11#define OPEN_FILE(extension)\ 11#define OPEN_FILE(extension)\
12 FILE * _##extension##_file = fopen(_##extension##_file_name, "w+");\ 12 FILE * _##extension##_file = fopen(_##extension##_file_name, "w+");
13 13
14#define SAVE_GEOMETRICS(a, format)\ 14#define SAVE_GEOMETRICS(a, format) \
15 vb = &f->vertices[a];\ 15 vb = &f->vertices[a]; \
16 fprintf(_obj_file, "o %s\n",_obj_file_name);\ 16 if (vb->data != NULL) \
17 if (vb->data == NULL)\ 17 { \
18 {\ 18 fprintf(_obj_file, "o %s\n",_obj_file_name); \
19 ERR("Reading of geometrics is failed.");\ 19 src = (float *)vb->data; \
20 fclose(_obj_file);\ 20 for (i = 0; i < pd->vertex_count; i++) \
21 return;\ 21 { \
22 }\ 22 fprintf(_obj_file, format, src[0], src[1]); \
23 src = (float *)vb->data;\ 23 if (a != EVAS_3D_VERTEX_TEXCOORD) \
24 for (i = 0; i < pd->vertex_count; i++)\ 24 fprintf(_obj_file, " %.4f", src[2]); \
25 {\ 25 fprintf(_obj_file, "\n"); \
26 fprintf(_obj_file, format, src[0], src[1], src[2]);\ 26 src += f->vertices[a].element_count; \
27 src += f->vertices[a].element_count;\ 27 } \
28 } 28 }
29 29
30static void 30static void
31_write_point(FILE * obj_file,
32 int num,
33 int num_of_point,
34 Eina_Bool existence_of_normal,
35 Eina_Bool existence_of_tex_point)
36{
37 if (num_of_point == 1)
38 fprintf(obj_file, "f ");
39
40 if (existence_of_normal)
41 {
42 if (existence_of_tex_point)
43 fprintf(obj_file, "%i/%i/%i ", num, num, num);
44 else
45 fprintf(obj_file, "%i//%i ", num, num);
46 }
47 else
48 {
49 if (existence_of_tex_point)
50 fprintf(obj_file, "%i/%i ", num, num);
51 else
52 fprintf(obj_file, "%i ", num);
53 }
54
55 if (num_of_point == 3)
56 fprintf(obj_file, "\n");
57}
58
59static void
31_save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame *f) 60_save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame *f)
32{ 61{
33 Evas_3D_Vertex_Buffer *vb; 62 Evas_3D_Vertex_Buffer *vb;
@@ -35,6 +64,7 @@ _save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame
35 char* c_time_string; 64 char* c_time_string;
36 int i; 65 int i;
37 float *src; 66 float *src;
67 Eina_Bool existence_of_normal, existence_of_tex_point;
38 68
39 OPEN_FILE(obj) 69 OPEN_FILE(obj)
40 if (!_obj_file) 70 if (!_obj_file)
@@ -73,26 +103,30 @@ _save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame
73 return; 103 return;
74 } 104 }
75 105
76 SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, "v %.4f %.4f %.4f \n") 106 SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, "v %.4f %.4f")
77 SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f %.4f \n") 107 SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f")
78 SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f %.4f \n") 108 SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f")
109
110 existence_of_normal = (f->vertices[EVAS_3D_VERTEX_NORMAL].data != NULL);
111 existence_of_tex_point = (f->vertices[EVAS_3D_VERTEX_TEXCOORD].data != NULL);
112
79 fprintf(_obj_file,"usemtl Material\n s off\n"); 113 fprintf(_obj_file,"usemtl Material\n s off\n");
80 for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1 114 for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1
81 { 115 {
82 fprintf(_obj_file,"f %i/%i/%i ", i, i, i); 116 _write_point(_obj_file, i, 1, existence_of_normal, existence_of_tex_point);
83 i++; 117 i++;
84 fprintf(_obj_file,"%i/%i/%i ", i, i, i); 118 _write_point(_obj_file, i, 2, existence_of_normal, existence_of_tex_point);
85 i++; 119 i++;
86 fprintf(_obj_file,"%i/%i/%i \n", i, i, i); 120 _write_point(_obj_file, i, 3, existence_of_normal, existence_of_tex_point);
87 } 121 }
88 fclose(_obj_file); 122 fclose(_obj_file);
89} 123}
90 124
91static void 125static void
92_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED, const char *_mtl_file_name, Evas_3D_Mesh_Frame *f) 126_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED,
127 const char *_mtl_file_name,
128 Evas_3D_Material_Data *mat)
93{ 129{
94 Evas_3D_Material_Data *mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
95
96 OPEN_FILE(mtl) 130 OPEN_FILE(mtl)
97 if (!_mtl_file) 131 if (!_mtl_file)
98 { 132 {
@@ -126,21 +160,24 @@ void
126evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *_obj_file_name, Evas_3D_Mesh_Frame *f) 160evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *_obj_file_name, Evas_3D_Mesh_Frame *f)
127{ 161{
128 int len; 162 int len;
129 char *without_extention, *_mtl_extension, *_mtl_file_name; 163 char *_mtl_file_name, *_without_extention;
164 Evas_3D_Material_Data *mat;
130 165
131 len = strlen(_obj_file_name); 166 len = strlen(_obj_file_name);
132 without_extention = (char*)malloc((len - 4) * sizeof(char)); 167 _without_extention = (char *)malloc(len - 3);
133 _mtl_extension = ".mtl"; 168 _mtl_file_name = (char *)malloc(len + 1);
134 _mtl_file_name = (char *)malloc(len * sizeof(char));
135
136 memcpy(without_extention, _obj_file_name, len-4);
137 strcpy(_mtl_file_name, without_extention);
138 strcpy(_mtl_file_name + len - 4, _mtl_extension);
139 169
140 Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS); 170 Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
141 _save_mesh(pd, _obj_file_name, f); 171 _save_mesh(pd, _obj_file_name, f);
142 _save_material(pd, _mtl_file_name, f);
143 172
144 free(without_extention); 173 mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
174 if (mat != NULL)
175 {
176 eina_strlcpy(_without_extention, _obj_file_name, len - 3);
177 eina_str_join(_mtl_file_name, len + 1, '.', _without_extention, "mtl");
178 _save_material(pd, _mtl_file_name, mat);
179 }
180
181 free(_without_extention);
145 free(_mtl_file_name); 182 free(_mtl_file_name);
146} 183}