forked from enlightenment/efl
evas: Evas_3D - add .ply export/import.
Summary: .ply format is important for relation blender and EFl, because in blender exist only two mesh export API: bpy.ops.import_mesh.ply and bpy.ops.import_mesh.stl. One of them is necessary for .edc 3D generator. Which I writing now. Sorry, it isn't like image loader. Refactoring of import/export will be soon. Reviewers: Oleksander, artem.popov, Hermet, raster, cedric Reviewed By: cedric Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D1544 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
parent
c59fba68de
commit
d896dfb342
|
@ -194,7 +194,9 @@ lib/evas/canvas/evas_3d_mesh_loader_obj.c \
|
||||||
lib/evas/canvas/evas_3d_mesh_saver_obj.c \
|
lib/evas/canvas/evas_3d_mesh_saver_obj.c \
|
||||||
lib/evas/canvas/evas_3d_mesh_loader_eet.c \
|
lib/evas/canvas/evas_3d_mesh_loader_eet.c \
|
||||||
lib/evas/canvas/evas_3d_mesh_saver_eet.c \
|
lib/evas/canvas/evas_3d_mesh_saver_eet.c \
|
||||||
lib/evas/canvas/evas_3d_eet.c
|
lib/evas/canvas/evas_3d_eet.c \
|
||||||
|
lib/evas/canvas/evas_3d_mesh_loader_ply.c \
|
||||||
|
lib/evas/canvas/evas_3d_mesh_saver_ply.c
|
||||||
|
|
||||||
# Engine
|
# Engine
|
||||||
lib_evas_libevas_la_SOURCES += \
|
lib_evas_libevas_la_SOURCES += \
|
||||||
|
|
|
@ -208,6 +208,11 @@ evas_3d_eet_SOURCES = evas-3d-eet.c
|
||||||
evas_3d_eet_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
evas_3d_eet_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
||||||
evas_3d_eet_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
|
evas_3d_eet_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
|
||||||
|
|
||||||
|
EXTRA_PROGRAMS += evas_3d_ply
|
||||||
|
evas_3d_ply_SOURCES = evas-3d-ply.c
|
||||||
|
evas_3d_ply_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
||||||
|
evas_3d_ply_CPPFLAGS = $(ECORE_EVAS_COMMON_CPPFLAGS)
|
||||||
|
|
||||||
EXTRA_PROGRAMS += evas_3d_frustum
|
EXTRA_PROGRAMS += evas_3d_frustum
|
||||||
evas_3d_frustum_SOURCES = evas-3d-frustum.c
|
evas_3d_frustum_SOURCES = evas-3d-frustum.c
|
||||||
evas_3d_frustum_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
evas_3d_frustum_LDADD = $(ECORE_EVAS_COMMON_LDADD) @EFL_PTHREAD_LIBS@
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
/**
|
||||||
|
* Simple Evas example illustrating import/export of .ply format.
|
||||||
|
*
|
||||||
|
* Read meshes from "tested_man_all_with_mods.ply", "tested_man_only_geometry.ply" and "tested_man_without_UVs.ply".
|
||||||
|
* After that cheange some properties of material.
|
||||||
|
* After that save material to "saved_man.mtl"
|
||||||
|
* and geometry to "saved_man_all_with_mods.ply", "saved_man_only_geometry.ply" and "saved_man_without_UVs.ply".
|
||||||
|
*
|
||||||
|
* @verbatim
|
||||||
|
* gcc -o evas-3d-ply evas-3d-ply.c `pkg-config --libs --cflags evas ecore ecore-evas eo`
|
||||||
|
* @endverbatim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EFL_EO_API_SUPPORT
|
||||||
|
#define EFL_BETA_API_SUPPORT
|
||||||
|
|
||||||
|
#include <Eo.h>
|
||||||
|
#include <Evas.h>
|
||||||
|
#include <Ecore.h>
|
||||||
|
#include <Ecore_Evas.h>
|
||||||
|
|
||||||
|
#define WIDTH 1024
|
||||||
|
#define HEIGHT 1024
|
||||||
|
|
||||||
|
#define NUMBER_OF_MESHES 32
|
||||||
|
|
||||||
|
int draw_mode[2] = {EVAS_3D_SHADE_MODE_PHONG, EVAS_3D_SHADE_MODE_VERTEX_COLOR};
|
||||||
|
|
||||||
|
Ecore_Evas *ecore_evas = NULL;
|
||||||
|
Evas *evas = NULL;
|
||||||
|
Eo *background = NULL;
|
||||||
|
Eo *image = NULL;
|
||||||
|
|
||||||
|
Eo *scene = NULL;
|
||||||
|
Eo *root_node = NULL;
|
||||||
|
Eo *camera_node = NULL;
|
||||||
|
Eo *light_node = NULL;
|
||||||
|
Eo *camera = NULL;
|
||||||
|
|
||||||
|
Eo *mesh_node[NUMBER_OF_MESHES];
|
||||||
|
Eo *mesh[NUMBER_OF_MESHES];
|
||||||
|
|
||||||
|
Eo *material = NULL;
|
||||||
|
Eo *texture = NULL;
|
||||||
|
Eo *light = NULL;
|
||||||
|
Ecore_Animator *anim = NULL;
|
||||||
|
|
||||||
|
char *folder = "ply_files";
|
||||||
|
char *path_file[8] = {"ply_files/Normal_UVs_Colors.ply",
|
||||||
|
"ply_files/Normal_UVs_NoColors.ply",
|
||||||
|
"ply_files/Normal_NoUVs_Colors.ply",
|
||||||
|
"ply_files/Normal_NoUVs_NoColors.ply",
|
||||||
|
"ply_files/NoNormal_UVs_Colors.ply",
|
||||||
|
"ply_files/NoNormal_UVs_NoColors.ply",
|
||||||
|
"ply_files/NoNormal_NoUVs_Colors.ply",
|
||||||
|
"ply_files/NoNormal_NoUVs_NoColors.ply"};
|
||||||
|
char *file_name[8] = {"Normal_UVs_Colors.ply",
|
||||||
|
"Normal_UVs_NoColors.ply",
|
||||||
|
"Normal_NoUVs_Colors.ply",
|
||||||
|
"Normal_NoUVs_NoColors.ply",
|
||||||
|
"NoNormal_UVs_Colors.ply",
|
||||||
|
"NoNormal_UVs_NoColors.ply",
|
||||||
|
"NoNormal_NoUVs_Colors.ply",
|
||||||
|
"NoNormal_NoUVs_NoColors.ply"};
|
||||||
|
|
||||||
|
static float angle = 0;
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_animate_scene(void *data)
|
||||||
|
{
|
||||||
|
angle += 0.5;
|
||||||
|
|
||||||
|
eo_do((Evas_3D_Node *)data, evas_3d_node_orientation_angle_axis_set(angle, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
/* Rotate */
|
||||||
|
if (angle > 360.0) angle -= 360.0f;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_on_delete(Ecore_Evas *ee EINA_UNUSED)
|
||||||
|
{
|
||||||
|
ecore_main_loop_quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_on_canvas_resize(Ecore_Evas *ee)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
|
||||||
|
eo_do(background, evas_obj_size_set(w, h));
|
||||||
|
eo_do(image, evas_obj_size_set(w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUMBER_OF_MESHES; i++)
|
||||||
|
{
|
||||||
|
mesh_node[i] = NULL;
|
||||||
|
mesh[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Unless Evas 3D supports Software renderer, we set gl backened forcely.
|
||||||
|
setenv("ECORE_EVAS_ENGINE", "opengl_x11", 1);
|
||||||
|
|
||||||
|
if (!ecore_evas_init()) return 0;
|
||||||
|
|
||||||
|
ecore_evas = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
|
||||||
|
|
||||||
|
if (!ecore_evas) return 0;
|
||||||
|
|
||||||
|
ecore_evas_callback_delete_request_set(ecore_evas, _on_delete);
|
||||||
|
ecore_evas_callback_resize_set(ecore_evas, _on_canvas_resize);
|
||||||
|
ecore_evas_show(ecore_evas);
|
||||||
|
|
||||||
|
evas = ecore_evas_get(ecore_evas);
|
||||||
|
|
||||||
|
/* Add a scene object .*/
|
||||||
|
scene = eo_add(EVAS_3D_SCENE_CLASS, evas);
|
||||||
|
|
||||||
|
/* Add the root node for the scene. */
|
||||||
|
root_node = eo_add(EVAS_3D_NODE_CLASS, evas,
|
||||||
|
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_NODE));
|
||||||
|
|
||||||
|
/* Add the camera. */
|
||||||
|
camera = eo_add(EVAS_3D_CAMERA_CLASS, evas);
|
||||||
|
eo_do(camera,
|
||||||
|
evas_3d_camera_projection_perspective_set(60.0, 1.0, 1.0, 500.0));
|
||||||
|
|
||||||
|
camera_node = eo_add(EVAS_3D_NODE_CLASS, evas,
|
||||||
|
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_CAMERA));
|
||||||
|
eo_do(camera_node,
|
||||||
|
evas_3d_node_camera_set(camera));
|
||||||
|
eo_do(root_node,
|
||||||
|
evas_3d_node_member_add(camera_node));
|
||||||
|
eo_do(camera_node,
|
||||||
|
evas_3d_node_position_set(200.0, 0.0, 0.0),
|
||||||
|
evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 0.0,
|
||||||
|
EVAS_3D_SPACE_PARENT, 0.0, 0.0, 1.0));
|
||||||
|
/* Add the light. */
|
||||||
|
light = eo_add(EVAS_3D_LIGHT_CLASS, evas);
|
||||||
|
eo_do(light,
|
||||||
|
evas_3d_light_ambient_set(1.0, 1.0, 1.0, 1.0),
|
||||||
|
evas_3d_light_diffuse_set(1.0, 1.0, 1.0, 1.0),
|
||||||
|
evas_3d_light_specular_set(1.0, 1.0, 1.0, 1.0),
|
||||||
|
evas_3d_light_directional_set(EINA_TRUE));
|
||||||
|
|
||||||
|
light_node = eo_add(EVAS_3D_NODE_CLASS, evas,
|
||||||
|
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_LIGHT));
|
||||||
|
eo_do(light_node,
|
||||||
|
evas_3d_node_light_set(light),
|
||||||
|
evas_3d_node_position_set(1000.0, 0.0, 1000.0),
|
||||||
|
evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 0.0,
|
||||||
|
EVAS_3D_SPACE_PARENT, 0.0, 1.0, 0.0));
|
||||||
|
eo_do(root_node,
|
||||||
|
evas_3d_node_member_add(light_node));
|
||||||
|
|
||||||
|
material = eo_add(EVAS_3D_MATERIAL_CLASS, evas);
|
||||||
|
texture = eo_add(EVAS_3D_TEXTURE_CLASS, evas);
|
||||||
|
eo_do(texture,
|
||||||
|
evas_3d_texture_file_set("indian_DIFF3.png", NULL),
|
||||||
|
evas_3d_texture_filter_set(EVAS_3D_TEXTURE_FILTER_NEAREST,
|
||||||
|
EVAS_3D_TEXTURE_FILTER_NEAREST),
|
||||||
|
evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT,
|
||||||
|
EVAS_3D_WRAP_MODE_REPEAT));
|
||||||
|
eo_do(material,
|
||||||
|
evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE, texture),
|
||||||
|
evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, EINA_TRUE),
|
||||||
|
evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, EINA_TRUE),
|
||||||
|
evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, EINA_TRUE),
|
||||||
|
evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE),
|
||||||
|
evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT,
|
||||||
|
0.01, 0.01, 0.01, 1.0),
|
||||||
|
evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE,
|
||||||
|
1.0, 1.0, 1.0, 1.0),
|
||||||
|
evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR,
|
||||||
|
1.0, 1.0, 1.0, 1.0),
|
||||||
|
evas_3d_material_shininess_set(50.0));
|
||||||
|
|
||||||
|
/* Add the meshes. */
|
||||||
|
for (i = 0; i < NUMBER_OF_MESHES; i++)
|
||||||
|
{
|
||||||
|
mesh[i] = eo_add(EVAS_3D_MESH_CLASS, evas);
|
||||||
|
|
||||||
|
eo_do(mesh[i],
|
||||||
|
evas_3d_mesh_file_set(EVAS_3D_MESH_FILE_TYPE_PLY, path_file[i % 8], NULL),
|
||||||
|
evas_3d_mesh_frame_material_set(0, material),
|
||||||
|
evas_3d_mesh_shade_mode_set(draw_mode[(i % 16) / 8]));
|
||||||
|
|
||||||
|
snprintf(buffer, PATH_MAX, "%s/Saved_%s", folder, file_name[i % 8]);
|
||||||
|
eo_do(mesh[i], evas_3d_mesh_save(EVAS_3D_MESH_FILE_TYPE_PLY, buffer, NULL));
|
||||||
|
|
||||||
|
if (i > 15)
|
||||||
|
eo_do(mesh[i],
|
||||||
|
evas_3d_mesh_file_set(EVAS_3D_MESH_FILE_TYPE_PLY, path_file[i % 8], NULL),
|
||||||
|
evas_3d_mesh_frame_material_set(0, material),
|
||||||
|
evas_3d_mesh_shade_mode_set(draw_mode[(i % 16) / 8]));
|
||||||
|
|
||||||
|
mesh_node[i] = eo_add(EVAS_3D_NODE_CLASS, evas,
|
||||||
|
evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH));
|
||||||
|
eo_do(root_node, evas_3d_node_member_add(mesh_node[i]));
|
||||||
|
eo_do(mesh_node[i],
|
||||||
|
evas_3d_node_mesh_add(mesh[i]),
|
||||||
|
evas_3d_node_position_set(0, ((i % 4) * 40) + ((i / 16) * 10) - 80, (((i % 16) / 4) * 10) - 40),
|
||||||
|
evas_3d_node_scale_set(0.3, 0.3, 0.3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up scene. */
|
||||||
|
eo_do(scene,
|
||||||
|
evas_3d_scene_root_node_set(root_node),
|
||||||
|
evas_3d_scene_camera_node_set(camera_node),
|
||||||
|
evas_3d_scene_background_color_set(0.7, 0.7, 0.7, 1.0),
|
||||||
|
evas_3d_scene_size_set(WIDTH, HEIGHT));
|
||||||
|
|
||||||
|
/* Add a background rectangle objects. */
|
||||||
|
background = eo_add(EVAS_RECTANGLE_CLASS, evas);
|
||||||
|
eo_do(background,
|
||||||
|
evas_obj_color_set(100, 100, 100, 255),
|
||||||
|
evas_obj_size_set(WIDTH, HEIGHT),
|
||||||
|
evas_obj_visibility_set(EINA_TRUE));
|
||||||
|
|
||||||
|
/* Add an image object for 3D scene rendering. */
|
||||||
|
image = evas_object_image_filled_add(evas);
|
||||||
|
eo_do(image,
|
||||||
|
evas_obj_size_set(WIDTH, HEIGHT),
|
||||||
|
evas_obj_visibility_set(EINA_TRUE));
|
||||||
|
|
||||||
|
/* Set the image object as render target for 3D scene. */
|
||||||
|
eo_do(image, evas_obj_image_scene_set(scene));
|
||||||
|
|
||||||
|
ecore_animator_frametime_set(0.01);
|
||||||
|
for (i = 0; i < NUMBER_OF_MESHES; i++)
|
||||||
|
anim = ecore_animator_add(_animate_scene, mesh_node[i]);
|
||||||
|
|
||||||
|
/* Enter main loop. */
|
||||||
|
ecore_main_loop_begin();
|
||||||
|
|
||||||
|
ecore_animator_del(anim);
|
||||||
|
ecore_evas_free(ecore_evas);
|
||||||
|
ecore_evas_shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -726,9 +726,11 @@ typedef enum _Evas_3D_Material_Attrib
|
||||||
*/
|
*/
|
||||||
typedef enum _Evas_3D_Mesh_File_Type
|
typedef enum _Evas_3D_Mesh_File_Type
|
||||||
{
|
{
|
||||||
EVAS_3D_MESH_FILE_TYPE_MD2 = 0, /**< Quake's MD2 mesh file format */
|
EVAS_3D_MESH_FILE_TYPE_NONE = 0, /**< Noone from read formats */
|
||||||
EVAS_3D_MESH_FILE_TYPE_OBJ,
|
EVAS_3D_MESH_FILE_TYPE_MD2, /**< Quake's MD2 mesh file format */
|
||||||
EVAS_3D_MESH_FILE_TYPE_EET,
|
EVAS_3D_MESH_FILE_TYPE_OBJ, /**< Wavefront OBJ file format */
|
||||||
|
EVAS_3D_MESH_FILE_TYPE_EET, /**< EET - own EFL file format */
|
||||||
|
EVAS_3D_MESH_FILE_TYPE_PLY, /**< Stanford PLY mesh file format */
|
||||||
} Evas_3D_Mesh_File_Type;
|
} Evas_3D_Mesh_File_Type;
|
||||||
|
|
||||||
#include "canvas/evas_image.eo.h"
|
#include "canvas/evas_image.eo.h"
|
||||||
|
|
|
@ -27,9 +27,7 @@ evas_3d_mesh_frame_free(Evas_3D_Mesh_Frame *frame)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (frame->material)
|
if (frame->material)
|
||||||
{
|
evas_3d_material_mesh_del(frame->material, frame->mesh);
|
||||||
evas_3d_material_mesh_del(frame->material, frame->mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < EVAS_3D_VERTEX_ATTRIB_COUNT; i++)
|
for (i = 0; i < EVAS_3D_VERTEX_ATTRIB_COUNT; i++)
|
||||||
{
|
{
|
||||||
|
@ -790,6 +788,9 @@ _evas_3d_mesh_file_set(Eo *obj, Evas_3D_Mesh_Data *pd, Evas_3D_Mesh_File_Type ty
|
||||||
case EVAS_3D_MESH_FILE_TYPE_EET:
|
case EVAS_3D_MESH_FILE_TYPE_EET:
|
||||||
evas_3d_mesh_file_eet_set(obj, file);
|
evas_3d_mesh_file_eet_set(obj, file);
|
||||||
break;
|
break;
|
||||||
|
case EVAS_3D_MESH_FILE_TYPE_PLY:
|
||||||
|
evas_3d_mesh_file_ply_set(obj, file);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ERR("Invalid mesh file type.");
|
ERR("Invalid mesh file type.");
|
||||||
break;
|
break;
|
||||||
|
@ -802,34 +803,25 @@ _evas_3d_mesh_save(Eo *obj, Evas_3D_Mesh_Data *pd, Evas_3D_Mesh_File_Type type,
|
||||||
{
|
{
|
||||||
if ((file == NULL) || (obj == NULL) || (pd == NULL)) return;
|
if ((file == NULL) || (obj == NULL) || (pd == NULL)) return;
|
||||||
|
|
||||||
|
Evas_3D_Mesh_Frame *f = evas_3d_mesh_frame_find(pd, 0);
|
||||||
|
|
||||||
|
if (f == NULL)
|
||||||
|
{
|
||||||
|
ERR("Not existing mesh frame.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EVAS_3D_MESH_FILE_TYPE_OBJ:
|
case EVAS_3D_MESH_FILE_TYPE_OBJ:
|
||||||
{
|
evas_3d_mesh_save_obj(obj, file, f);//file without extension!
|
||||||
Evas_3D_Mesh_Frame *f = evas_3d_mesh_frame_find(pd, 0);
|
break;
|
||||||
|
|
||||||
if (f == NULL)
|
|
||||||
{
|
|
||||||
ERR("Not existing mesh frame.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
evas_3d_mesh_save_obj(obj, file, f);//file without extension!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVAS_3D_MESH_FILE_TYPE_EET:
|
case EVAS_3D_MESH_FILE_TYPE_EET:
|
||||||
{
|
evas_3d_mesh_save_eet(obj, file, f);
|
||||||
Evas_3D_Mesh_Frame *f = evas_3d_mesh_frame_find(pd, 0);
|
break;
|
||||||
|
case EVAS_3D_MESH_FILE_TYPE_PLY:
|
||||||
if (f == NULL)
|
evas_3d_mesh_save_ply(obj, file, f);
|
||||||
{
|
break;
|
||||||
ERR("Not existing mesh frame.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
evas_3d_mesh_save_eet(obj, file, f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
ERR("Invalid mesh file type.");
|
ERR("Invalid mesh file type.");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface)
|
||||||
/**
|
/**
|
||||||
* Load mesh data from file.
|
* Load mesh data from file.
|
||||||
*
|
*
|
||||||
* Loading a mesh from existing file is supported. Currently, only MD2, OBJ and EET file
|
* Loading a mesh from existing file is supported. Currently, only MD2, OBJ, PLY and EET file
|
||||||
* formats are supported.
|
* formats are supported.
|
||||||
*
|
*
|
||||||
* @ingroup Evas_3D_Mesh
|
* @ingroup Evas_3D_Mesh
|
||||||
|
@ -24,7 +24,7 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface)
|
||||||
/**
|
/**
|
||||||
* Save mesh data to file.
|
* Save mesh data to file.
|
||||||
*
|
*
|
||||||
* Saving a mesh to file is supported. Currently, only OBJ and EET file
|
* Saving a mesh to file is supported. Currently, only OBJ, PLY and EET file
|
||||||
* format are supported.
|
* format are supported.
|
||||||
*
|
*
|
||||||
* @ingroup Evas_3D_Mesh
|
* @ingroup Evas_3D_Mesh
|
||||||
|
|
|
@ -0,0 +1,401 @@
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline char*
|
||||||
|
_file_to_buf(const char *file, long *length)//prepare text file for reading
|
||||||
|
{
|
||||||
|
FILE *file_for_print;
|
||||||
|
char *buf;
|
||||||
|
int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread"
|
||||||
|
|
||||||
|
*length = 0;
|
||||||
|
file_for_print = fopen(file, "rb");
|
||||||
|
if (!file_for_print) return NULL;
|
||||||
|
fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file
|
||||||
|
*length = ftell(file_for_print);//set current position of file_for_print
|
||||||
|
buf = malloc(*length + 1);
|
||||||
|
fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file
|
||||||
|
unused = fread(buf, *length, 1, file_for_print);
|
||||||
|
fclose(file_for_print);
|
||||||
|
buf[*length] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
while (*current != '\n') current++;
|
||||||
|
current++;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
_to_begin_of_line(char *current)
|
||||||
|
{
|
||||||
|
while (*current != '\n') current--;
|
||||||
|
current++;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
_to_next_number(char *current, int count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
while (*current != ' ') current++;
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
_read_data(float *array, int place, int count, char *current, float divider)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
sscanf (current,"%f", &ARRAY_2D(array, place, i, count));
|
||||||
|
ARRAY_2D(array, place, i, count) /= divider;
|
||||||
|
current = _to_next_number(current, 1);
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline PLY_Header
|
||||||
|
_read_header(char *start)//Check properties of mesh in .ply file.
|
||||||
|
{
|
||||||
|
eina_init();
|
||||||
|
|
||||||
|
Eina_Bool reading_vertices = EINA_TRUE, check_next_char = EINA_FALSE;
|
||||||
|
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(start, "vertex ", 0);
|
||||||
|
|
||||||
|
if (helping_pointer == NULL)
|
||||||
|
{
|
||||||
|
ERR("File have not kayword vertex. It is necessary.");
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf(helping_pointer[1], "%d", &header.vertices_count);
|
||||||
|
|
||||||
|
free(helping_pointer);
|
||||||
|
helping_pointer = eina_str_split(start, "end_header\n", 0);
|
||||||
|
|
||||||
|
if (helping_pointer == NULL)
|
||||||
|
{
|
||||||
|
ERR("File have not kayword end_header. It is necessary.");
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = helping_pointer[1];
|
||||||
|
|
||||||
|
vertex_lines = header.vertices_count;
|
||||||
|
while (*current != '\0')
|
||||||
|
{
|
||||||
|
if (vertex_lines == 1)
|
||||||
|
reading_vertices = EINA_FALSE;
|
||||||
|
if (*current == '\n')
|
||||||
|
{
|
||||||
|
if (reading_vertices)
|
||||||
|
vertex_lines--;
|
||||||
|
else
|
||||||
|
check_next_char = EINA_TRUE;
|
||||||
|
}
|
||||||
|
if (check_next_char)
|
||||||
|
{
|
||||||
|
if ((*current <= '9') && (*current >= '0'))
|
||||||
|
vertices_in_current_face = (vertices_in_current_face * 10) + (*current - '0');
|
||||||
|
else if (*current >= ' ')
|
||||||
|
{
|
||||||
|
triangles += (vertices_in_current_face - 2);
|
||||||
|
vertices_in_current_face = 0;
|
||||||
|
check_next_char = EINA_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
header.triangles_count = triangles;
|
||||||
|
free(helping_pointer);
|
||||||
|
|
||||||
|
/* analyse flags used when file was saved in blender */
|
||||||
|
helping_pointer = eina_str_split(start, "property float ", 0);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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 &&
|
||||||
|
((helping_pointer[4] != NULL) && (*helping_pointer[4] == 's') &&
|
||||||
|
(helping_pointer[5] != NULL) && (*helping_pointer[5] == 't'))))
|
||||||
|
header.existence_of_texcoords = EINA_TRUE;
|
||||||
|
|
||||||
|
helping_pointer = eina_str_split(start, "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_3d_mesh_file_ply_set(Evas_3D_Mesh *mesh, const char *file)
|
||||||
|
{
|
||||||
|
long length;
|
||||||
|
Evas_3D_Mesh_Data *pd;
|
||||||
|
int i = 0, j = 0, k = 0, count_of_triangles_in_line = 0;
|
||||||
|
float *pos, *nor, *tex, *col;
|
||||||
|
int stride_pos, stride_nor, stride_tex, stride_col;
|
||||||
|
char *start, *current;
|
||||||
|
PLY_Header header;
|
||||||
|
float *_vertices_ply = NULL, *_normals_ply = NULL, *_tex_coords_ply = NULL, *_colors_ply = NULL;
|
||||||
|
char **helping_pointer;
|
||||||
|
|
||||||
|
start = _file_to_buf(file, &length);
|
||||||
|
|
||||||
|
if (start == NULL)
|
||||||
|
{
|
||||||
|
ERR("Buffer is empty after preparation file for reading.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
header = _read_header(start);
|
||||||
|
|
||||||
|
if (!header.existence_of_geometries)
|
||||||
|
{
|
||||||
|
ERR("File have not x, y, or z field as the first 3 float fields. They are necessary.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
helping_pointer = eina_str_split(start, "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));
|
||||||
|
int *_triangles = malloc(header.triangles_count * 3 * sizeof(int));
|
||||||
|
|
||||||
|
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)) ||
|
||||||
|
(_triangles == NULL))
|
||||||
|
{
|
||||||
|
ERR("Allocate memory is failed.");
|
||||||
|
free(start);
|
||||||
|
free(_vertices_ply);
|
||||||
|
free(_normals_ply);
|
||||||
|
free(_tex_coords_ply);
|
||||||
|
free(_colors_ply);
|
||||||
|
free(_triangles);
|
||||||
|
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;)
|
||||||
|
{
|
||||||
|
sscanf (current,"%d", &count_of_triangles_in_line);
|
||||||
|
count_of_triangles_in_line -= 2;
|
||||||
|
current = _to_next_number(current, 1);
|
||||||
|
|
||||||
|
sscanf (current,"%i", &ARRAY_2D(_triangles, i, 0, 3));
|
||||||
|
|
||||||
|
for (j = 0; j < count_of_triangles_in_line; j++)
|
||||||
|
{
|
||||||
|
if (j > 0)
|
||||||
|
ARRAY_2D(_triangles, i, 0, 3) = ARRAY_2D(_triangles, (i - 1), 0, 3);
|
||||||
|
current = _to_next_number(current, 1);
|
||||||
|
sscanf (current,"%i %i",
|
||||||
|
&ARRAY_2D(_triangles, i, 1, 3),
|
||||||
|
&ARRAY_2D(_triangles, i, 2, 3));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
current = _to_next_line(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare of mesh and take pointers to data which must be read */
|
||||||
|
eo_do(mesh,
|
||||||
|
evas_3d_mesh_vertex_count_set(header.triangles_count * 3),
|
||||||
|
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
|
||||||
|
evas_3d_mesh_frame_add(0),
|
||||||
|
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
|
||||||
|
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
|
||||||
|
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
|
||||||
|
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_COLOR, 0, NULL),
|
||||||
|
|
||||||
|
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
|
||||||
|
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
|
||||||
|
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
|
||||||
|
col = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_COLOR),
|
||||||
|
|
||||||
|
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
|
||||||
|
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
|
||||||
|
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD),
|
||||||
|
stride_col = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_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.triangles_count; j++)
|
||||||
|
{
|
||||||
|
for (k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
float *p, *n, *t, *c;
|
||||||
|
|
||||||
|
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
|
||||||
|
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
|
||||||
|
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
|
||||||
|
c = (float *)((char *)col + stride_col * (j * 3 + k));
|
||||||
|
|
||||||
|
p[0] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
|
||||||
|
p[1] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
|
||||||
|
p[2] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
|
||||||
|
|
||||||
|
if (header.existence_of_normals)
|
||||||
|
{
|
||||||
|
n[0] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
|
||||||
|
n[1] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
|
||||||
|
n[2] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 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, ARRAY_2D(_triangles, j, k, 3), 0, 2);
|
||||||
|
t[1] = ARRAY_2D(_tex_coords_ply, ARRAY_2D(_triangles, j, k, 3), 1, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t[0] = 0.0;
|
||||||
|
t[1] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.existence_of_colors)
|
||||||
|
{
|
||||||
|
c[0] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
|
||||||
|
c[1] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
|
||||||
|
c[2] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
|
||||||
|
c[3] = 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[0] = 0.0;
|
||||||
|
c[1] = 0.0;
|
||||||
|
c[2] = 0.0;
|
||||||
|
c[3] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(_triangles);
|
||||||
|
|
||||||
|
/* Unmap vertex buffer. */
|
||||||
|
eo_do(mesh,
|
||||||
|
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
|
||||||
|
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
|
||||||
|
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD),
|
||||||
|
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_COLOR));
|
||||||
|
|
||||||
|
pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
|
||||||
|
|
||||||
|
if (!evas_3d_mesh_aabb_add_to_frame(pd, 0, stride_pos))
|
||||||
|
{
|
||||||
|
ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "evas_common_private.h"
|
||||||
|
#include "evas_private.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
evas_3d_mesh_save_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f)
|
||||||
|
{
|
||||||
|
float *src_pos, *src_nor, *src_tex, *src_col;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
|
||||||
|
FILE *_ply_file = fopen(file, "w+");
|
||||||
|
|
||||||
|
fprintf(_ply_file,"ply\nformat ascii 1.0\ncomment Created by EFL evas_3d_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->vertex_count / 3);
|
||||||
|
|
||||||
|
src_pos = (float*)(&f->vertices[EVAS_3D_VERTEX_POSITION])->data;
|
||||||
|
src_nor = (float*)(&f->vertices[EVAS_3D_VERTEX_NORMAL])->data;
|
||||||
|
src_tex = (float*)(&f->vertices[EVAS_3D_VERTEX_TEXCOORD])->data;
|
||||||
|
src_col = (float*)(&f->vertices[EVAS_3D_VERTEX_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pd->vertex_count;)
|
||||||
|
{
|
||||||
|
fprintf(_ply_file,"3 %d %d %d\n", i, i + 1, i + 2);
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(_ply_file);
|
||||||
|
}
|
|
@ -1613,6 +1613,8 @@ void evas_3d_mesh_file_obj_set(Evas_3D_Mesh *mesh, const char *file);
|
||||||
Eina_Bool evas_3d_mesh_aabb_add_to_frame(Evas_3D_Mesh_Data *pd, int frame, int stride);
|
Eina_Bool evas_3d_mesh_aabb_add_to_frame(Evas_3D_Mesh_Data *pd, int frame, int stride);
|
||||||
void evas_3d_mesh_file_eet_set(Evas_3D_Mesh *mesh, const char *file);
|
void evas_3d_mesh_file_eet_set(Evas_3D_Mesh *mesh, const char *file);
|
||||||
void evas_3d_mesh_save_eet(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
|
void evas_3d_mesh_save_eet(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
|
||||||
|
void evas_3d_mesh_file_ply_set(Evas_3D_Mesh *mesh, const char *file);
|
||||||
|
void evas_3d_mesh_save_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
|
||||||
|
|
||||||
/* Texture functions. */
|
/* Texture functions. */
|
||||||
void evas_3d_texture_material_add(Evas_3D_Texture *texture, Evas_3D_Material *material);
|
void evas_3d_texture_material_add(Evas_3D_Texture *texture, Evas_3D_Material *material);
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
#define TESTS_MESH_DIR TESTS_SRC_DIR"/meshes"
|
#define TESTS_MESH_DIR TESTS_SRC_DIR"/meshes"
|
||||||
#define TESTS_OBJ_MESH_DIR TESTS_MESH_DIR"/obj"
|
#define TESTS_OBJ_MESH_DIR TESTS_MESH_DIR"/obj"
|
||||||
#define TESTS_MD2_MESH_DIR TESTS_MESH_DIR"/md2"
|
#define TESTS_MD2_MESH_DIR TESTS_MESH_DIR"/md2"
|
||||||
|
#define TESTS_PLY_MESH_DIR TESTS_MESH_DIR"/ply"
|
||||||
|
|
||||||
#define COMPARE_GEOMETRICS(a, component) \
|
#define COMPARE_GEOMETRICS(a) \
|
||||||
vb1 = &f1->vertices[a]; \
|
vb1 = &f1->vertices[a]; \
|
||||||
vb2 = &f2->vertices[a]; \
|
vb2 = &f2->vertices[a]; \
|
||||||
if ((vb1->data == NULL) || (vb2->data == NULL)) \
|
if ((vb1->data == NULL) || (vb2->data == NULL)) \
|
||||||
|
@ -33,21 +34,21 @@
|
||||||
src2 += f2->vertices[a].element_count; \
|
src2 += f2->vertices[a].element_count; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_MESHES_IN_FOLDER(folder, type) \
|
#define CHECK_MESHES_IN_FOLDER(folder, type, type_to_check) \
|
||||||
it = eina_file_direct_ls(folder); \
|
it = eina_file_direct_ls(folder); \
|
||||||
EINA_ITERATOR_FOREACH(it, file) \
|
EINA_ITERATOR_FOREACH(it, file) \
|
||||||
{ \
|
{ \
|
||||||
mesh = eo_add(EVAS_3D_MESH_CLASS, e); \
|
mesh = eo_add(EVAS_3D_MESH_CLASS, e); \
|
||||||
mesh2 = eo_add(EVAS_3D_MESH_CLASS, e); \
|
mesh2 = eo_add(EVAS_3D_MESH_CLASS, e); \
|
||||||
fail_if(mesh == NULL); \
|
fail_if(mesh == NULL); \
|
||||||
fail_if(mesh2 == NULL); \
|
fail_if(mesh2 == NULL); \
|
||||||
eo_do(mesh, evas_3d_mesh_file_set(type, file->path, NULL)); \
|
eo_do(mesh, evas_3d_mesh_file_set(type, file->path, NULL)); \
|
||||||
eo_do(mesh, evas_3d_mesh_save(EVAS_3D_MESH_FILE_TYPE_EET, buffer, NULL)); \
|
eo_do(mesh, evas_3d_mesh_save(type_to_check, buffer, NULL)); \
|
||||||
eo_do(mesh2, evas_3d_mesh_file_set(EVAS_3D_MESH_FILE_TYPE_EET, buffer, NULL)); \
|
eo_do(mesh2, evas_3d_mesh_file_set(type_to_check, buffer, NULL)); \
|
||||||
res = _compare_meshes(mesh, mesh2); \
|
res = _compare_meshes(mesh, mesh2); \
|
||||||
fail_if(res == 1); \
|
fail_if(res == 1); \
|
||||||
eo_del(mesh2); \
|
eo_del(mesh2); \
|
||||||
eo_del(mesh); \
|
eo_del(mesh); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static Evas_3D_Mesh_Frame *
|
static Evas_3D_Mesh_Frame *
|
||||||
|
@ -86,9 +87,10 @@ static int _compare_meshes(Evas_3D_Mesh *mesh1, Evas_3D_Mesh *mesh2)
|
||||||
if ((pd1->vertex_count) != (pd2->vertex_count))
|
if ((pd1->vertex_count) != (pd2->vertex_count))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
COMPARE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, position)
|
COMPARE_GEOMETRICS(EVAS_3D_VERTEX_POSITION)
|
||||||
COMPARE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, normal)
|
COMPARE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL)
|
||||||
COMPARE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, texcoord)
|
COMPARE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,8 +99,7 @@ START_TEST(evas_object_mesh_loader_saver)
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
Evas *e = _setup_evas();
|
Evas *e = _setup_evas();
|
||||||
Eina_Tmpstr *tmp;
|
Eina_Tmpstr *tmp;
|
||||||
Eo *mesh;
|
Eo *mesh, *mesh2;
|
||||||
Eo *mesh2;
|
|
||||||
Eina_Iterator *it;
|
Eina_Iterator *it;
|
||||||
char *file_mask = strdup("evas_test_mesh_XXXXXX");
|
char *file_mask = strdup("evas_test_mesh_XXXXXX");
|
||||||
int res = 0, tmpfd;
|
int res = 0, tmpfd;
|
||||||
|
@ -110,8 +111,10 @@ START_TEST(evas_object_mesh_loader_saver)
|
||||||
|
|
||||||
snprintf(buffer, PATH_MAX, "%s", tmp);
|
snprintf(buffer, PATH_MAX, "%s", tmp);
|
||||||
|
|
||||||
CHECK_MESHES_IN_FOLDER(TESTS_OBJ_MESH_DIR, EVAS_3D_MESH_FILE_TYPE_OBJ)
|
CHECK_MESHES_IN_FOLDER(TESTS_OBJ_MESH_DIR, EVAS_3D_MESH_FILE_TYPE_OBJ, EVAS_3D_MESH_FILE_TYPE_EET)
|
||||||
CHECK_MESHES_IN_FOLDER(TESTS_MD2_MESH_DIR, EVAS_3D_MESH_FILE_TYPE_MD2)
|
CHECK_MESHES_IN_FOLDER(TESTS_MD2_MESH_DIR, EVAS_3D_MESH_FILE_TYPE_MD2, EVAS_3D_MESH_FILE_TYPE_EET)
|
||||||
|
CHECK_MESHES_IN_FOLDER(TESTS_PLY_MESH_DIR, EVAS_3D_MESH_FILE_TYPE_PLY, EVAS_3D_MESH_FILE_TYPE_EET)
|
||||||
|
CHECK_MESHES_IN_FOLDER(TESTS_PLY_MESH_DIR, EVAS_3D_MESH_FILE_TYPE_PLY, EVAS_3D_MESH_FILE_TYPE_PLY)
|
||||||
|
|
||||||
eina_iterator_free(it);
|
eina_iterator_free(it);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue