Added a encode feature on the c++ wrapper. Added more tests and some refactoring

This commit is contained in:
Federico De Felici 2018-05-13 09:52:45 +02:00
parent 676b05bd22
commit 96a1a3c276
17 changed files with 457535 additions and 145 deletions

View File

@ -884,27 +884,36 @@ else ()
endif ()
if (BUILD_MAYA_PLUGIN)
add_library(dracodec_maya
add_library(draco_maya_wrapper
MODULE
${draco_version_sources}
$<TARGET_OBJECTS:draco_maya_plugin>
$<TARGET_OBJECTS:draco_compression_attributes_pred_schemes_enc>
$<TARGET_OBJECTS:draco_attributes>
$<TARGET_OBJECTS:draco_compression_attributes_dec>
$<TARGET_OBJECTS:draco_compression_decode>
$<TARGET_OBJECTS:draco_compression_mesh_dec>
$<TARGET_OBJECTS:draco_compression_point_cloud_dec>
$<TARGET_OBJECTS:draco_compression_attributes_enc>
$<TARGET_OBJECTS:draco_compression_encode>
$<TARGET_OBJECTS:draco_compression_mesh_enc>
$<TARGET_OBJECTS:draco_compression_point_cloud_enc>
$<TARGET_OBJECTS:draco_core>
$<TARGET_OBJECTS:draco_core_bit_coders>
$<TARGET_OBJECTS:draco_dec_config>
$<TARGET_OBJECTS:draco_enc_config>
$<TARGET_OBJECTS:draco_dec_config>
$<TARGET_OBJECTS:draco_io>
$<TARGET_OBJECTS:draco_mesh>
$<TARGET_OBJECTS:draco_metadata>
$<TARGET_OBJECTS:draco_metadata_dec>
$<TARGET_OBJECTS:draco_point_cloud>
$<TARGET_OBJECTS:draco_points_dec>)
$<TARGET_OBJECTS:draco_points_dec>
$<TARGET_OBJECTS:draco_metadata_enc>
$<TARGET_OBJECTS:draco_points_enc>)
# For Mac, we need to build a .bundle for plugin.
if (APPLE)
set_target_properties(dracodec_maya PROPERTIES BUNDLE true)
set_target_properties(draco_maya_wrapper PROPERTIES BUNDLE true)
endif ()
endif ()
@ -928,7 +937,7 @@ else ()
set_target_properties(dracodec_unity PROPERTIES SOVERSION 1)
endif ()
if (BUILD_MAYA_PLUGIN)
set_target_properties(dracodec_maya PROPERTIES SOVERSION 1)
set_target_properties(draco_maya_wrapper PROPERTIES SOVERSION 1)
endif ()
endif ()
@ -992,7 +1001,7 @@ else ()
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
endif ()
if (BUILD_MAYA_PLUGIN)
install(TARGETS dracodec_maya
install(TARGETS draco_maya_wrapper
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
endif ()

View File

@ -1,6 +1,68 @@
Description
===========
# Description
Plugin which add support for Draco files (.drc) in Autodesk Maya.
Plugin which add support for Draco files in Autodesk Maya.
Currently is supported drc file import on Windows 64bit, from the import menu or by drag & drop
# Features
The following feature are offered:
* Support .drc format: TRIANGULAR MESH (no POINT CLOUD)
* Import .drc file into Maya by Import menu
* Import .drc file into Maya by Drag & Drop
With the following contraints:
* Import attributes limited to: Vertices, Normals and Uvs
# Supported OS / Maya Version
Currently the plugin works on the following OS:
* Windows x64
and tested against Maya versions:
* Maya 2017
* Maya 2018
# Installation
[TODO]: Describe installation steps
# Usage
[TODO]: Describe usate steps
# Build From Source
You can build the plugins on your own for OSX/Win/Linux. Source code for the wrapper is here: [src/draco/maya/](../src/draco/maya). Following is detailed building instruction.
### Mac OS X
On Mac OS X, run the following command to generate Xcode projects:
~~~~~ bash
$ cmake path/to/draco -G Xcode -DBUILD_MAYA_PLUGIN=ON
~~~~~
Then open the project use Xcode and build.
You should be able to find the library under:
~~~~ bash
path/to/build/Debug(or Release)/draco_maya_wrapper.bundle
~~~~
### Windows
On Windows, run the following command to generate Visual Studio projects:
32-bit version:
~~~~~ bash
cmake path/to/draco -G "Visual Studio 15 2017" -DBUILD_MAYA_PLUGIN=ON -DBUILD_SHARED_LIBS=ON
~~~~~
64-bit version:
~~~~~ bash
cmake path/to/draco -G "Visual Studio 15 2017 Win64" -DBUILD_MAYA_PLUGIN=ON -DBUILD_SHARED_LIBS=ON
~~~~~
Then open the project use VS and build.
You should be able to find the library under:
~~~~ bash
path/to/build/Debug(or Release)/draco_maya_wrapper.dll
~~~~
### Linux
[TODO]

Binary file not shown.

BIN
maya/draco_maya_wrapper.dll Normal file

Binary file not shown.

View File

@ -17,17 +17,39 @@ class Drc2PyMesh(ctypes.Structure):
("normals_num", ctypes.c_uint),
("normals", ctypes.POINTER(ctypes.c_float)),
("uvs_num", ctypes.c_uint),
("uvs_real_num", ctypes.c_uint),
("uvs", ctypes.POINTER(ctypes.c_float))
]
class DrcMesh:
def __init__(self):
self.faces = []
self.faces_len = 0
self.faces_num = 0
self.vertices = []
self.vertices_len = 0
self.vertices_num = 0
self.normals = []
self.normals_len = 0
self.normals_num = 0
self.uvs = []
self.uvs_len = 0
self.uvs_num = 0
# TODO: Add integration for UNIX
def array_to_ptr(array, size, ctype):
carr = (ctype * size)(*array)
return ctypes.cast(carr, ctypes.POINTER(ctype))
# TODO: Add integration for reading Linux lib
class Draco:
def __init__(self):
# Lib loading
dir_path = os.path.dirname(os.path.realpath(__file__))
lib_path = os.path.join(dir_path, 'dracodec_maya')
lib_path = os.path.join(dir_path, 'draco_maya_wrapper')
self.drc_lib = ctypes.CDLL(lib_path)
# Mapping free funct
# Mapping decode funct
self.drc_decode = self.drc_lib.drc2py_decode
self.drc_decode.argtype = [ ctypes.POINTER(ctypes.c_char), ctypes.c_uint, ctypes.POINTER(ctypes.POINTER(Drc2PyMesh)) ]
self.drc_decode.restype = ctypes.c_uint
@ -35,6 +57,10 @@ class Draco:
self.drc_free = self.drc_lib.drc2py_free
self.drc_free.argtype = ctypes.POINTER(ctypes.POINTER(Drc2PyMesh))
self.drc_free.restype = None
# Mapping encode funct
self.drc_encode = self.drc_lib.drc2py_encode
self.drc_encode.argtype = [ ctypes.POINTER(Drc2PyMesh), ctypes.c_char_p ]
self.drc_encode.restype = ctypes.c_uint
def decode(self, file_path):
# Open drc file
@ -77,3 +103,23 @@ class Draco:
self.drc_free(ctypes.byref(mesh_ptr))
mesh_ptr = None
return result;
def encode(self, mesh_data: DrcMesh, file: str):
mesh = Drc2PyMesh()
mesh.faces = array_to_ptr(mesh_data.faces, mesh_data.faces_num * 3, ctypes.c_uint)
mesh.faces_num = ctypes.c_uint(mesh_data.faces_num)
mesh.vertices = array_to_ptr(mesh_data.vertices, mesh_data.vertices_num * 3, ctypes.c_float)
mesh.vertices_num = ctypes.c_uint(mesh_data.vertices_num)
mesh.normals = array_to_ptr(mesh_data.normals, mesh_data.normals_num * 3, ctypes.c_float)
mesh.normals_num = ctypes.c_uint(mesh_data.normals_num)
mesh.uvs = array_to_ptr(mesh_data.uvs, mesh_data.uvs_num * 3, ctypes.c_float)
mesh.uvs_num = ctypes.c_uint(mesh_data.uvs_num)
mesh_ptr = ctypes.byref(mesh)
file_ptr = ctypes.c_char_p(file.encode())
self.drc_encode(mesh_ptr, file_ptr)
#self.string(ctypes.c_char_p(file.encode()))

View File

@ -1,21 +0,0 @@
from dracodec_maya import Draco
drc = Draco()
mesh = drc.decode('bunny.drc')
print("\n==== FACES ====")
print(mesh.faces_num)
print(mesh.faces_len)
print(mesh.faces[0:10])
print("\n==== VERTICES ====")
print(mesh.vertices_num)
print(mesh.vertices_len)
print(mesh.vertices[0:10])
print("\n==== NORMALS ====")
print(mesh.normals_num)
print(mesh.normals_len)
print(mesh.normals) #This mesh has no normals
print("\n==== UVS ====")
print(mesh.uvs_num)
print(mesh.uvs_len)
print(mesh.uvs) #This mesh has no uvs

Binary file not shown.

104285
maya/test/bunny.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
maya/test/bunny_uv.drc Normal file

Binary file not shown.

352871
maya/test/bunny_uv.obj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
import unittest
import os
import sys
dir_path = os.path.dirname(os.path.realpath(__file__))
root_path = os.path.join(dir_path, '..')
sys.path.insert(0, root_path)
def file_del(file_path):
if os.path.isfile(file_path):
os.remove(file_path)
from draco_maya_wrapper import Draco, DrcMesh
class DracoTest(unittest.TestCase):
def setUp(self):
self.drc = Draco()
def test_decode_bunny_drc(self):
mesh = self.drc.decode(os.path.join(dir_path, 'bunny.drc'))
# Faces check
self.assertEqual(69451, mesh.faces_num, 'Number of faces')
self.assertEqual(208353, mesh.faces_len,'Length of faces array precalculated')
self.assertEqual(208353, len(mesh.faces),'Length of faces array by len')
# Vertices check
self.assertEqual(34834, mesh.vertices_num, 'Number of vertices')
self.assertEqual(104502, mesh.vertices_len,'Length of vertices array precalculated')
self.assertEqual(104502, len(mesh.vertices),'Length of vertices array by len')
# Normals check
self.assertEqual(0, mesh.normals_num, 'Number of normals')
self.assertEqual(0, mesh.normals_len,'Length of normals array precalculated')
self.assertEqual(0, len(mesh.normals),'Length of normals array by len')
# Uvs check
self.assertEqual(0, mesh.uvs_num, 'Number of uvs')
self.assertEqual(0, mesh.uvs_len,'Length of uvs ')
self.assertEqual(0, len(mesh.uvs),'Length of uvs array by len')
def test_decode_trooper_drc(self):
mesh = self.drc.decode(os.path.join(dir_path, 'stormtrooper.drc'))
# Faces check
self.assertEqual(6518, mesh.faces_num, 'Number of faces')
self.assertEqual(19554, mesh.faces_len,'Length of faces array precalculated')
self.assertEqual(19554, len(mesh.faces),'Length of faces array by len')
# Vertices check
self.assertEqual(5176, mesh.vertices_num, 'Number of vertices')
self.assertEqual(15528, mesh.vertices_len,'Length of vertices array precalculated')
self.assertEqual(15528, len(mesh.vertices),'Length of vertices array by len')
# Normals check
self.assertEqual(5176, mesh.normals_num, 'Number of normals')
self.assertEqual(15528, mesh.normals_len, 'Length of normals array precalculated')
self.assertEqual(15528, len(mesh.normals),'Length of normals array by len')
# Uvs check
self.assertEqual(5176, mesh.uvs_num, 'Number of uvs')
self.assertEqual(10352, mesh.uvs_len, 'Length of uvs array')
self.assertEqual(10352, len(mesh.uvs), 'Length of uvs array by len')
def test_decode_unexistent_drc(self):
self.assertRaises(Exception, self.drc.decode, 'unexistent.drc')
def test_encode_triangle_mesh(self):
mesh = DrcMesh()
mesh.faces = [0, 1, 2]
mesh.faces_num = 1
mesh.vertices = [0, 0, 0, 1, 1, 1, 2, 2, 2]
mesh.vertices_num = 3
file = os.path.join(dir_path,'triangle.drc')
file_del(file)
self.drc.encode(mesh, file)
self.assertTrue(os.path.isfile(file), 'File should exists!')
file_del(file)
def test_encode_and_decode_triangle_mesh(self):
mesh = DrcMesh()
mesh.faces = [0, 1, 2]
mesh.faces_num = 1
mesh.vertices = [0, 0, 0, 1, 1, 1, 2, 2, 2]
mesh.vertices_num = 3
file = os.path.join(dir_path,'triangle.drc')
file_del(file)
self.drc.encode(mesh, file)
dmesh = self.drc.decode(file)
# Faces check
self.assertEqual(1, dmesh.faces_num, 'Number of faces')
self.assertEqual(3, dmesh.faces_len,'Length of faces array precalculated')
self.assertEqual([0, 1, 2], dmesh.faces, 'Face Array')
# Vertices check
self.assertEqual(3, dmesh.vertices_num, 'Number of vertices')
self.assertEqual(9, dmesh.vertices_len,'Length of vertices array precalculated')
self.assertEqual([0, 0, 0, 1, 1, 1, 2, 2, 2], dmesh.vertices, 'Vertex Array')
file_del(file)
def test_decode_and_encode_stoormtrup_drc(self):
# Step1: decode
mesh = self.drc.decode(os.path.join(dir_path, 'stormtrooper.drc'))
# Step2: encode
file = os.path.join(dir_path,'stormtrooper_copy.drc')
file_del(file)
self.drc.encode(mesh, file)
# Step3: re-decode and test
dmesh = self.drc.decode(file)
# Faces check
self.assertEqual(6518, dmesh.faces_num, 'Number of faces')
self.assertEqual(19554, dmesh.faces_len,'Length of faces array precalculated')
self.assertEqual(19554, len(dmesh.faces),'Length of faces array by len')
# Vertices check
self.assertEqual(5176, dmesh.vertices_num, 'Number of vertices')
self.assertEqual(15528, dmesh.vertices_len,'Length of vertices array precalculated')
self.assertEqual(15528, len(dmesh.vertices),'Length of vertices array by len')
# Normals check
self.assertEqual(5176, dmesh.normals_num, 'Number of normals')
self.assertEqual(15528, dmesh.normals_len, 'Length of normals array precalculated')
self.assertEqual(15528, len(dmesh.normals),'Length of normals array by len')
file_del(file)
if __name__ == '__main__':
unittest.main()

View File

@ -1,58 +0,0 @@
import unittest
import os
import sys
dir_path = os.path.dirname(os.path.realpath(__file__))
root_path = os.path.join(dir_path, '..')
sys.path.insert(0, root_path)
from dracodec_maya import Draco
class DracoTest(unittest.TestCase):
def setUp(self):
self.drc = Draco()
def test_valid_bunny_drc(self):
mesh = self.drc.decode(os.path.join(dir_path, 'bunny.drc'))
# Faces check
self.assertEqual(69451, mesh.faces_num, 'Number of faces')
self.assertEqual(208353, mesh.faces_len,'Length of faces array precalculated')
self.assertEqual(208353, len(mesh.faces),'Length of faces array by len')
# Vertices check
self.assertEqual(34834, mesh.vertices_num, 'Number of vertices')
self.assertEqual(104502, mesh.vertices_len,'Length of vertices array precalculated')
self.assertEqual(104502, len(mesh.vertices),'Length of vertices array by len')
# Normals check
self.assertEqual(0, mesh.normals_num, 'Number of normals')
self.assertEqual(0, mesh.normals_len,'Length of normals array precalculated')
self.assertEqual(0, len(mesh.normals),'Length of normals array by len')
# Uvs check
self.assertEqual(0, mesh.uvs_num, 'Number of uvs')
self.assertEqual(0, mesh.uvs_len,'Length of uvs ')
self.assertEqual(0, len(mesh.uvs),'Length of uvs array by len')
def test_valid_trooper_drc(self):
mesh = self.drc.decode(os.path.join(dir_path, 'stormtrooper.drc'))
# Faces check
self.assertEqual(6518, mesh.faces_num, 'Number of faces')
self.assertEqual(19554, mesh.faces_len,'Length of faces array precalculated')
self.assertEqual(19554, len(mesh.faces),'Length of faces array by len')
# Vertices check
self.assertEqual(5176, mesh.vertices_num, 'Number of vertices')
self.assertEqual(15528, mesh.vertices_len,'Length of vertices array precalculated')
self.assertEqual(15528, len(mesh.vertices),'Length of vertices array by len')
# Normals check
self.assertEqual(5176, mesh.normals_num, 'Number of normals')
self.assertEqual(15528, mesh.normals_len, 'Length of normals array precalculated')
self.assertEqual(15528, len(mesh.normals),'Length of normals array by len')
# Uvs check
self.assertEqual(5176, mesh.uvs_num, 'Number of uvs')
self.assertEqual(10352, mesh.uvs_len, 'Length of uvs array')
self.assertEqual(10352, len(mesh.uvs), 'Length of uvs array by len')
def test_unexistent_drc(self):
self.assertRaises(Exception, self.drc.decode, 'unexistent.drc')
if __name__ == '__main__':
unittest.main()

BIN
maya/test/trig.drc Normal file

Binary file not shown.

9
maya/test/trig.obj Normal file
View File

@ -0,0 +1,9 @@
# This file uses centimeters as units for non-parametric coordinates.
v -0.500000 -0.000000 -0.917102
v 0.500000 -0.000000 -0.917102
v -0.500000 0.000000 -1.917102
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
f 1/1 2/2 3/3

Binary file not shown.

View File

@ -21,7 +21,6 @@ namespace draco {
int num_faces = drc_mesh->num_faces();
out_mesh->faces = new int[num_faces*3];
out_mesh->faces_num = num_faces;
for (int i = 0; i < num_faces; i++) {
const draco::Mesh::Face &face = drc_mesh->face(draco::FaceIndex(i));
out_mesh->faces[i * 3 + 0] = face[0].value();
@ -30,25 +29,27 @@ namespace draco {
}
}
static void decode_vertices(std::unique_ptr<draco::Mesh> &drc_mesh, Drc2PyMesh* out_mesh) {
const auto pos_att = drc_mesh->GetNamedAttribute(draco::GeometryAttribute::POSITION);
if (pos_att == nullptr) {
out_mesh->vertices = new float[0];
out_mesh->vertices_num = 0;
return;
}
int num_vertices = drc_mesh->num_points();
out_mesh->vertices = new float[num_vertices * 3];
out_mesh->vertices_num = num_vertices;
const auto pos_att = drc_mesh->GetNamedAttribute(draco::GeometryAttribute::POSITION);
for (int i = 0; i < num_vertices; i++) {
draco::PointIndex pi(i);
const draco::AttributeValueIndex val_index = pos_att->mapped_index(pi);
float out_vertex[3];
bool is_ok = pos_att->ConvertValue<float, 3>(val_index, out_vertex);
if (!is_ok) return;
out_mesh->vertices[i * 3 + 0] = out_vertex[0];
out_mesh->vertices[i * 3 + 1] = out_vertex[1];
out_mesh->vertices[i * 3 + 2] = out_vertex[2];
}
}
static void decode_normals(std::unique_ptr<draco::Mesh> &drc_mesh, Drc2PyMesh* out_mesh) {
const auto normal_att = drc_mesh->GetNamedAttribute(draco::GeometryAttribute::NORMAL);
if (normal_att == nullptr) {
@ -56,7 +57,6 @@ namespace draco {
out_mesh->normals_num = 0;
return;
}
int num_normals = drc_mesh->num_points();
out_mesh->normals = new float[num_normals * 3];
out_mesh->normals_num = num_normals;
@ -64,41 +64,35 @@ namespace draco {
for (int i = 0; i < num_normals; i++) {
draco::PointIndex pi(i);
const draco::AttributeValueIndex val_index = normal_att->mapped_index(pi);
float out_normal[3];
bool is_ok = normal_att->ConvertValue<float, 3>(val_index, out_normal);
if (!is_ok) return;
out_mesh->normals[i * 3 + 0] = out_normal[0];
out_mesh->normals[i * 3 + 1] = out_normal[1];
out_mesh->normals[i * 3 + 2] = out_normal[2];
}
}
static void decode_uvs(std::unique_ptr<draco::Mesh> &drc_mesh, Drc2PyMesh* out_mesh) {
const auto uv_att = drc_mesh->GetNamedAttribute(draco::GeometryAttribute::TEX_COORD);
if (uv_att == nullptr) {
out_mesh->uvs = new float[0];
out_mesh->uvs_num = 0;
out_mesh->uvs_real_num = 0;
return;
}
int num_uvs = drc_mesh->num_points();
out_mesh->uvs = new float[num_uvs * 2];
out_mesh->uvs_num = num_uvs;
out_mesh->uvs_real_num = uv_att->size();
for (int i = 0; i < num_uvs; i++) {
draco::PointIndex pi(i);
const draco::AttributeValueIndex val_index = uv_att->mapped_index(pi);
float out_uv[2];
//bool is_ok = uv_att->ConvertValue<float, 3>(val_index, out_uv);
bool is_ok = uv_att->ConvertValue<float, 2>(val_index, out_uv);
if (!is_ok) return;
out_mesh->uvs[i * 2 + 0] = out_uv[0];
out_mesh->uvs[i * 2 + 1] = out_uv[1];
//out_mesh->uvs[i * 3 + 2] = out_uv[2];
}
}
@ -129,22 +123,22 @@ namespace draco {
*mesh_ptr = nullptr;
}
int drc2py_decode(char *data, unsigned int length, Drc2PyMesh **res_mesh) {
DecodeResult drc2py_decode(char *data, unsigned int length, Drc2PyMesh **res_mesh) {
draco::DecoderBuffer buffer;
buffer.Init(data, length);
auto type_statusor = draco::Decoder::GetEncodedGeometryType(&buffer);
if (!type_statusor.ok()) {
return -1;
return DecodeResult::KO_GEOMETRY_TYPE_INVALID;
}
const draco::EncodedGeometryType geom_type = type_statusor.value();
if (geom_type != draco::TRIANGULAR_MESH) {
return -2;
return DecodeResult::KO_TRIANGULAR_MESH_NOT_FOUND;
}
draco::Decoder decoder;
auto statusor = decoder.DecodeMeshFromBuffer(&buffer);
if (!statusor.ok()) {
return -3;
return DecodeResult::KO_MESH_DECODING;
}
std::unique_ptr<draco::Mesh> drc_mesh = std::move(statusor).value();
@ -153,41 +147,100 @@ namespace draco {
decode_vertices(drc_mesh, *res_mesh);
decode_normals(drc_mesh, *res_mesh);
decode_uvs(drc_mesh, *res_mesh);
return 0;
return DecodeResult::OK;
}
/*
// Get color attributes.
const auto color_att =
in_mesh->GetNamedAttribute(draco::GeometryAttribute::COLOR);
if (color_att != nullptr) {
unity_mesh->color = new float[in_mesh->num_points() * 3];
unity_mesh->has_color = true;
for (draco::PointIndex i(0); i < in_mesh->num_points(); ++i) {
const draco::AttributeValueIndex val_index = color_att->mapped_index(i);
if (!color_att->ConvertValue<float, 3>(
val_index, unity_mesh->color + i.value() * 3)) {
ReleaseMayaMesh(&unity_mesh);
return -8;
}
//As encode refereces see https://github.com/google/draco/issues/116
EncodeResult drc2py_encode(Drc2PyMesh *in_mesh, char* file_path) {
if (in_mesh->faces_num == 0) return EncodeResult::KO_WRONG_INPUT;
if (in_mesh->vertices_num == 0) return EncodeResult::KO_WRONG_INPUT;
// TODO: Add check to protect against quad faces. At the moment only Tringular faces are supported
std::unique_ptr<draco::Mesh> drc_mesh(new draco::Mesh());
// Marshall Faces
int num_faces = in_mesh->faces_num;
drc_mesh->SetNumFaces(num_faces);
for (int i = 0; i < num_faces; ++i) {
Mesh::Face face;
face[0] = in_mesh->faces[i * 3 + 0];
face[1] = in_mesh->faces[i * 3 + 1];
face[2] = in_mesh->faces[i * 3 + 2];
drc_mesh->SetFace(FaceIndex(i), face);
}
}
// Get texture coordinates attributes.
const auto texcoord_att =
in_mesh->GetNamedAttribute(draco::GeometryAttribute::TEX_COORD);
if (texcoord_att != nullptr) {
unity_mesh->texcoord = new float[in_mesh->num_points() * 2];
unity_mesh->has_texcoord = true;
for (draco::PointIndex i(0); i < in_mesh->num_points(); ++i) {
const draco::AttributeValueIndex val_index =
texcoord_att->mapped_index(i);
if (!texcoord_att->ConvertValue<float, 3>(
val_index, unity_mesh->texcoord + i.value() * 3)) {
ReleaseMayaMesh(&unity_mesh);
return -8;
}
// Marshall Vertices
int num_points = in_mesh->vertices_num;
drc_mesh->set_num_points(num_points);
GeometryAttribute va;
va.Init(GeometryAttribute::POSITION, nullptr, 3, DT_FLOAT32, false, sizeof(float) * 3, 0);
int pos_att_id = drc_mesh->AddAttribute(va, true, num_points);
float point[3];
for (int i = 0; i < num_points; ++i) {
point[0] = in_mesh->vertices[i * 3 + 0];
point[1] = in_mesh->vertices[i * 3 + 1];
point[2] = in_mesh->vertices[i * 3 + 2];
drc_mesh->attribute(pos_att_id)->SetAttributeValue(AttributeValueIndex(i), point);
}
}
*/
// Marshall Normals
int num_normals = in_mesh->normals_num;
int norm_att_id;
if (num_normals > 0) {
GeometryAttribute va;
va.Init(GeometryAttribute::NORMAL, nullptr, 3, DT_FLOAT32, false, sizeof(float) * 3, 0);
norm_att_id = drc_mesh->AddAttribute(va, true, num_normals);
float norm[3];
for (int i = 0; i < num_normals; ++i) {
norm[0] = in_mesh->normals[i * 3 + 0];
norm[1] = in_mesh->normals[i * 3 + 1];
norm[2] = in_mesh->normals[i * 3 + 2];
drc_mesh->attribute(norm_att_id)->SetAttributeValue(AttributeValueIndex(i), norm);
}
}
// Marshall Uvs
int num_uvs = in_mesh->uvs_num;
int uv_att_id;
if (num_uvs > 0) {
GeometryAttribute va;
va.Init(GeometryAttribute::TEX_COORD, nullptr, 2, DT_FLOAT32, false, sizeof(float) * 2, 0);
uv_att_id = drc_mesh->AddAttribute(va, true, num_uvs);
float uv[3];
for (int i = 0; i < num_uvs; ++i) {
uv[0] = in_mesh->uvs[i * 2 + 0];
uv[1] = in_mesh->uvs[i * 2 + 1];
drc_mesh->attribute(uv_att_id)->SetAttributeValue(AttributeValueIndex(i), uv);
}
}
// Deduplicate Attribs and Points
#ifdef DRACO_ATTRIBUTE_DEDUPLICATION_SUPPORTED
drc_mesh->DeduplicateAttributeValues();
drc_mesh->DeduplicatePointIds();
#endif
// Encode Mesh
draco::Encoder encoder; //Use default encode settings (See draco_encoder.cc Options struct)
draco::EncoderBuffer buffer;
const draco::Status status = encoder.EncodeMeshToBuffer(*drc_mesh, &buffer);
if (!status.ok()) {
//Use status.error_msg() to check the error
return EncodeResult::KO_MESH_ENCODING;
}
// Save to file
std::string file = file_path;
std::ofstream out_file(file, std::ios::binary);
if (!out_file) {
return EncodeResult::KO_FILE_CREATION;
}
out_file.write(buffer.data(), buffer.size());
return EncodeResult::OK;
}
} // namespace maya
} // namespace draco

View File

@ -13,8 +13,10 @@
#ifndef DRACO_MAYA_PLUGIN_H_
#define DRACO_MAYA_PLUGIN_H_
#include "draco/compression/config/compression_shared.h"
//#include "draco/compression/config/compression_shared.h"
#include "draco/compression/decode.h"
#include "draco/compression/encode.h"
#include <fstream>
#ifdef BUILD_MAYA_PLUGIN
@ -28,6 +30,11 @@
namespace draco {
namespace maya {
enum class EncodeResult { OK=0, KO_WRONG_INPUT=-1, KO_MESH_ENCODING=-2, KO_FILE_CREATION=-3 };
enum class DecodeResult { OK=0, KO_GEOMETRY_TYPE_INVALID = -1, KO_TRIANGULAR_MESH_NOT_FOUND = -2, KO_MESH_DECODING = -3 };
extern "C" {
struct EXPORT_API Drc2PyMesh {
Drc2PyMesh()
@ -38,6 +45,7 @@ namespace draco {
normals_num(0),
normals(nullptr),
uvs_num(0),
uvs_real_num(0),
uvs(nullptr) {}
int faces_num;
int* faces;
@ -46,11 +54,13 @@ namespace draco {
int normals_num;
float* normals;
int uvs_num;
int uvs_real_num;
float* uvs;
};
EXPORT_API int drc2py_decode(char *data, unsigned int length, Drc2PyMesh **res_mesh);
EXPORT_API DecodeResult drc2py_decode(char *data, unsigned int length, Drc2PyMesh **res_mesh);
EXPORT_API void drc2py_free(Drc2PyMesh **res_mesh);
EXPORT_API EncodeResult drc2py_encode(Drc2PyMesh *in_mesh, char* file_path);
} // extern "C"
} // namespace maya