forked from enlightenment/efl
Revert "evas: refactor model's savers and loaders."
This reverts commit 32c33ed64d
.
This refactor broke the evas test cases for the model loaders and savers. I gave
it a week to get fixed but a first try did not succeed and its blocks a lot of
other automated testing. To be honest, it should have never gone it when it
breaks existing test cases. Once fixed this refactor can happily go in.
Fixes T2905
This commit is contained in:
parent
842a75423f
commit
96a9d75e0c
|
@ -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 \
|
||||
|
|
|
@ -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) \
|
|
@ -128,3 +128,5 @@ evas_model_load_file_eet(Evas_Canvas3D_Mesh *mesh, Eina_File *file)
|
|||
|
||||
_evas_canvas3d_eet_file_free();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,44 @@
|
|||
#include "evas_model_load_save_common.h"
|
||||
#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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -192,3 +192,4 @@ evas_model_save_file_eet(const Evas_Canvas3D_Mesh *mesh,
|
|||
|
||||
_evas_canvas3d_eet_file_free();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <time.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
static void
|
||||
_vertex_data_free_cb(void *data)
|
||||
{
|
||||
eina_stringshare_del(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
|
||||
_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);
|
||||
}
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <time.h>
|
||||
#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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue