aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/evas/model_savers/obj/evas_model_save_obj.c
blob: 1cc7e8a74485f8441a9bbfc378f663dbebd80818 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#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];\
   fprintf(_obj_file, "o %s\n",_obj_file_name);\
   if (vb->data == NULL)\
     {\
        ERR("Reading of geometrics is failed.");\
        fclose(_obj_file);\
        return;\
     }\
   src = (float *)vb->data;\
   for (i = 0; i < pd->vertex_count; i++)\
     {\
        fprintf(_obj_file, format, src[0], src[1], src[2]);\
        src += f->vertices[a].element_count;\
     }

static void
_save_mesh(Evas_3D_Mesh_Data *pd, const char *_obj_file_name, Evas_3D_Mesh_Frame *f)
{
   Evas_3D_Vertex_Buffer *vb;
   time_t current_time;
   char* c_time_string;
   int    i;
   float *src;

   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;
     }

   c_time_string = ctime(&current_time);

   if (c_time_string == NULL)
     {
        ERR("Failure to convert the current time.");
        fclose(_obj_file);
        return;
     }

   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_3D_VERTEX_POSITION, "v %.4f %.4f %.4f \n")
   SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f %.4f \n")
   SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f %.4f \n")
   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
     {
        fprintf(_obj_file,"f %i/%i/%i ", i, i, i);
        i++;
        fprintf(_obj_file,"%i/%i/%i ", i, i, i);
        i++;
        fprintf(_obj_file,"%i/%i/%i \n", i, i, i);
     }
   fclose(_obj_file);
}

static void
_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED, const char *_mtl_file_name, Evas_3D_Mesh_Frame *f)
{
   Evas_3D_Material_Data *mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);

   OPEN_FILE(mtl)
   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, "# Material Count: 1 \n\n");
   fprintf(_mtl_file, "newmtl Material \n");
   fprintf(_mtl_file, "Ns 1.000000 \n");//exp factor for specular highlight
   fprintf(_mtl_file, "Ka %.6f %.6f %.6f \n",
           (float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.r,
           (float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.g,
           (float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.b);
   fprintf(_mtl_file, "Kd %.6f %.6f %.6f \n",
           (float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.r,
           (float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.g,
           (float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.b);
   fprintf(_mtl_file, "Ks %.6f %.6f %.6f \n",
           (float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.r,
           (float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.g,
           (float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.b);
   fprintf(_mtl_file, "Ni 1.000000 \n");//optical density
   fprintf(_mtl_file, "d 1.000000 \n");//a factor d of 1.0 is fully opaque material
   fprintf(_mtl_file, "illum 2 \n");//illumination properties

   fclose(_mtl_file);
}

void
evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *_obj_file_name, Evas_3D_Mesh_Frame *f)
{
   int len;
   char *without_extention, *_mtl_extension, *_mtl_file_name;

   len = strlen(_obj_file_name);
   without_extention = (char*)malloc((len - 4) * sizeof(char));
   _mtl_extension = ".mtl";
   _mtl_file_name = (char *)malloc(len * sizeof(char));

   memcpy(without_extention, _obj_file_name, len-4);
   strcpy(_mtl_file_name, without_extention);
   strcpy(_mtl_file_name + len - 4, _mtl_extension);

   Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
   _save_mesh(pd, _obj_file_name, f);
   _save_material(pd, _mtl_file_name, f);

   free(without_extention);
   free(_mtl_file_name);
}