jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=01a32f64c0ffbe2ce048f8eb016d685913558cf5

commit 01a32f64c0ffbe2ce048f8eb016d685913558cf5
Author: perepelits.m <perepelit...@samsung.com>
Date:   Thu Dec 10 16:37:30 2015 +0900

    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)
    
    I did it again because somehow test is passing now. It seems like this test 
suite is unstable.
    Please, let me know if there are any errors after running distcheck.
    
    Reviewers: cedric, raster, Hermet, stefan_schmidt
    
    Subscribers: jpeg, artem.popov
    
    Differential Revision: https://phab.enlightenment.org/D3420
---
 src/Makefile_Evas.am                               |   4 +-
 ...odel_common.c => evas_model_load_save_common.c} |   2 +-
 ...odel_common.h => evas_model_load_save_common.h} |   0
 .../evas/model_loaders/eet/evas_model_load_eet.c   |   2 -
 .../evas/model_loaders/ply/evas_model_load_ply.c   | 319 +++++----------------
 .../evas/model_savers/eet/evas_model_save_eet.c    |  20 +-
 .../evas/model_savers/obj/evas_model_save_obj.c    | 239 +++++++++------
 .../evas/model_savers/ply/evas_model_save_ply.c    | 121 +++++---
 8 files changed, 317 insertions(+), 390 deletions(-)

diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 3f7dd39..d76356d 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -224,8 +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_common.c \
-lib/evas/common3d/save_load/evas_model_common.h \
+lib/evas/common3d/save_load/evas_model_load_save_common.c \
+lib/evas/common3d/save_load/evas_model_load_save_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_common.c 
b/src/lib/evas/common3d/save_load/evas_model_load_save_common.c
similarity index 99%
rename from src/lib/evas/common3d/save_load/evas_model_common.c
rename to src/lib/evas/common3d/save_load/evas_model_load_save_common.c
index 612bccd..190ba59 100644
--- a/src/lib/evas/common3d/save_load/evas_model_common.c
+++ b/src/lib/evas/common3d/save_load/evas_model_load_save_common.c
@@ -1,4 +1,4 @@
-#include "evas_model_common.h"
+#include "evas_model_load_save_common.h"
 
 # define SAVE_MESH_INDICES_COPY                                           \
    if (header.indices_count)                                              \
diff --git a/src/lib/evas/common3d/save_load/evas_model_common.h 
b/src/lib/evas/common3d/save_load/evas_model_load_save_common.h
similarity index 100%
rename from src/lib/evas/common3d/save_load/evas_model_common.h
rename to src/lib/evas/common3d/save_load/evas_model_load_save_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 f5b1b6b..e049e2c 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
@@ -127,5 +127,3 @@ evas_model_load_file_eet(Evas_Canvas3D_Mesh *mesh, 
Eina_File *file)
 
    _evas_canvas3d_eet_file_free(eet_file);
 }
-
-
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 1beef18..971e951 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,44 +1,4 @@
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include "stdio.h"
-#include "evas_common_private.h"
-#include "evas_private.h"
-#include <Eina.h>
-
-/* 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;
-}
+#include "evas_model_load_save_common.h"
 
 static inline char *
 _to_next_line(char *current)
@@ -81,8 +41,8 @@ _read_data(float *array, int place, int count, char *current, 
float divider)
    return current;
 }
 
-static inline PLY_Header
-_read_header(char *map)//Check properties of mesh in .ply file.
+static inline Eina_Bool
+_read_ply_header(char *map, Evas_Model_Load_Save_Header *header)
 {
    eina_init();
 
@@ -90,30 +50,29 @@ _read_header(char *map)//Check properties of mesh in .ply 
file.
    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 header;
+        return EINA_FALSE;
      }
 
-   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 header;
+        return EINA_FALSE;
      }
 
    current = helping_pointer[1];
 
-   vertex_lines = header.vertices_count;
+   vertex_lines = header->vertices_count;
    while (*current != '\0')
      {
         if (vertex_lines == 1)
@@ -139,8 +98,7 @@ _read_header(char *map)//Check properties of mesh in .ply 
file.
         current++;
      }
 
-   header.triangles_count = triangles;
-   free(helping_pointer);
+   header->indices_count = 3 * triangles;
 
       /* analyse flags used when file was saved in blender */
    helping_pointer = eina_str_split(map, "property float ", 0);
@@ -148,243 +106,124 @@ _read_header(char *map)//Check properties of mesh in 
.ply file.
    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_geometries = EINA_TRUE;
-   else return header;
+     header->existence_of_positions = EINA_TRUE;
+   else return EINA_FALSE;
 
    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_texcoords = EINA_TRUE;
+     header->existence_of_tex_coords = 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;
-
-   free(helping_pointer);
-
-   return header;
-}
-
-void
-evas_model_load_file_ply(Evas_Canvas3D_Mesh *mesh, Eina_File *file)
-{
-   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);
+     header->existence_of_colors = EINA_TRUE;
 
-   if (map == NULL)
-     {
-        ERR("Failed to create map from file %s\n", 
eina_file_filename_get(file));
-        return;
-     }
-
-   header = _read_header(map);
-
-   if (!header.existence_of_geometries)
+   if (!header->existence_of_positions)
      {
         ERR("File have not x, y, or z field as the first 3 float fields. They 
are necessary.");
-        return;
+        return EINA_FALSE;
      }
 
-   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;
-     }
+   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(_vertices_ply, i, 3, current, 1.0);
+        *current = _read_data(data.positions, 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);
+          *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(_colors_ply, i, 3, current, 255.0);
-        current = _to_begin_of_line(current);
+          *current = _read_data(data.colors, i, 3, *current, 255.0);
+        *current = _to_begin_of_line(*current);
      }
+}
 
-   for (i = 0; i < header.triangles_count * 3;)
+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);
+        sscanf (*current,"%d", &count_of_triangles_in_line);
         count_of_triangles_in_line -= 2;
-        current = _to_next_number(current, 1);
+        *current = _to_next_number(*current, 1);
 
-        sscanf (current,"%hu", _indices + i);
+        sscanf (*current,"%hu", data.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);
+               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);
+        *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;
-          }
+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;
 
-        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;
-          }
+   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;
      }
 
-   eo_do(mesh,
-         
evas_canvas3d_mesh_index_data_copy_set(EVAS_CANVAS3D_INDEX_FORMAT_UNSIGNED_SHORT,
-                                                header.triangles_count * 3,
-                                                _indices));
+   header = evas_model_load_save_header_new();
+   if(!_read_ply_header(map, &header)) return;
 
-   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))
+   if (!evas_model_load_allocate_data_due_to_header(header, &data))
      {
-        ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
+        ERR("Memory allocation is failed.");
+        return;
      }
 
+   current = eina_str_split(map, "end_header\n", 0)[1];
+   _read_ply_vertex_data(header, &current, data);
+   _read_ply_indices_data(header, &current, 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);
+
    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 0ac7e66..183dada 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
@@ -41,18 +41,17 @@ _set_geometry_to_eet_file_from_mesh(Evas_Canvas3D_Mesh_Data 
*mesh,
    if (vb->data == NULL)\
      {\
         ERR("Reading of geometrics is failed.");\
-        free(vertices);\
-        free(geometry);\
-        free(geometries);\
-        return;\
      }\
-   src = (float *)vb->data;\
-   for (i = 0; i < mesh->vertex_count; i++)\
+   else\
      {\
-        vertices[i].component.x = src[0];\
-        vertices[i].component.y = src[1];\
-        command_for_z_component\
-        src += f->vertices[a].element_count;\
+        src = (float *)vb->data;\
+        for (i = 0; i < mesh->vertex_count; i++)\
+          {\
+             vertices[i].component.x = src[0];\
+             vertices[i].component.y = src[1];\
+             command_for_z_component\
+             src += f->vertices[a].element_count;\
+          }\
      }
    geometry->vertices = vertices;
    SAVE_GEOMETRICS(EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION, position, 
vertices[i].position.z = src[2];)
@@ -190,4 +189,3 @@ evas_model_save_file_eet(const Evas_Canvas3D_Mesh *mesh,
 
    _evas_canvas3d_eet_file_free(eet_file);
 }
-
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 d9be3dc..09e5c72 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(&current_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 0be42f7..8da8f74 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);
 }

-- 


Reply via email to