mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-08-12 03:39:06 +08:00
Added a encode feature on the c++ wrapper. Added more tests and some refactoring
This commit is contained in:
parent
676b05bd22
commit
96a1a3c276
@ -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 ()
|
||||
|
||||
|
@ -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]
|
||||
|
||||
|
BIN
maya/bunny.drc
BIN
maya/bunny.drc
Binary file not shown.
BIN
maya/draco_maya_wrapper.dll
Normal file
BIN
maya/draco_maya_wrapper.dll
Normal file
Binary file not shown.
@ -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()))
|
@ -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
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
BIN
maya/test/bunny_uv.drc
Normal file
Binary file not shown.
352871
maya/test/bunny_uv.obj
Normal file
352871
maya/test/bunny_uv.obj
Normal file
File diff suppressed because it is too large
Load Diff
124
maya/test/draco_maya_wrapper_test.py
Normal file
124
maya/test/draco_maya_wrapper_test.py
Normal 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()
|
@ -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
BIN
maya/test/trig.drc
Normal file
Binary file not shown.
9
maya/test/trig.obj
Normal file
9
maya/test/trig.obj
Normal 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.
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user