-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v0.0.18 | Supports Texture Coordinates and Normals #17
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
DracoPy.egg-info/ | ||
MANIFEST | ||
_skbuild/ | ||
venv/* | ||
.eggs/* | ||
*.so | ||
.idea/ | ||
.vscode/ | ||
dist/ | ||
bunny_test.drc | ||
*secret.json | ||
__pycache__/ | ||
__pycache__/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,14 @@ | ||
import os | ||
import DracoPy | ||
|
||
with open('bunny.drc', 'rb') as draco_file: | ||
testdata_directory = "testdata_files" | ||
|
||
with open(os.path.join(testdata_directory, "Avocado.bin"), "rb") as draco_file: | ||
file_content = draco_file.read() | ||
mesh_object = DracoPy.decode_buffer_to_mesh(file_content) | ||
print('number of points in original file: {0}'.format(len(mesh_object.points))) | ||
print('number of faces in original file: {0}'.format(len(mesh_object.faces))) | ||
encoding_test = DracoPy.encode_mesh_to_buffer(mesh_object.points, mesh_object.faces) | ||
print('number of faces in original file: {0}'.format(len(mesh_object.tex_coord))) | ||
print('number of normal in original file: {0}'.format(len(mesh_object.normals))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. normal -> normals |
||
encoding_test = DracoPy.encode_mesh_to_buffer(mesh_object.points, mesh_object.face) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. faces? |
||
with open('bunny_test.drc', 'wb') as test_file: | ||
test_file.write(encoding_test) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,10 +15,10 @@ def read(fname): | |
setup_requires = [] | ||
try: | ||
cmake_version = LegacyVersion(get_cmake_version()) | ||
if cmake_version < LegacyVersion("3.5") or cmake_version >= LegacyVersion("3.15"): | ||
setup_requires.append('cmake<3.15') | ||
if cmake_version < LegacyVersion("3.5") or cmake_version >= LegacyVersion("3.20"): | ||
setup_requires.append('cmake<3.20') | ||
except SKBuildError: | ||
setup_requires.append('cmake<3.15') | ||
setup_requires.append('cmake<3.20') | ||
|
||
# If you want to re-build the cython cpp file (DracoPy.cpp), run: | ||
# cython --cplus -3 -I./_skbuild/linux-x86_64-3.6/cmake-install/include/draco/ ./src/DracoPy.pyx | ||
|
@@ -50,12 +50,11 @@ def read(fname): | |
'-std=c++11','-O3' | ||
] | ||
|
||
|
||
setup( | ||
name='DracoPy', | ||
version='0.0.19', | ||
description = 'Python wrapper for Google\'s Draco Mesh Compression Library', | ||
author = 'Manuel Castro', | ||
author = 'Manuel Castro :: Contributors :: Fatih Erol, Faru Nuri Sonmez', | ||
author_email = 'macastro@princeton.edu', | ||
url = 'https://github.com/seung-lab/DracoPy', | ||
long_description=read('README.md'), | ||
|
@@ -69,7 +68,7 @@ def read(fname): | |
setuptools.Extension( | ||
'DracoPy', | ||
sources=[ os.path.join(src_dir, 'DracoPy.cpp') ], | ||
depends=[ os.path.join(src_dir, 'DracoPy.h') ], | ||
depends=[ os.path.join(src_dir, 'DracoPy.h'), os.path.join(src_dir, 'DracoPy.pyx')], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is right. The |
||
language='c++', | ||
include_dirs = [ os.path.join(CMAKE_INSTALL_DIR(), 'include/')], | ||
extra_compile_args=extra_compile_args, | ||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,8 +8,7 @@ | |
#include "draco/point_cloud/point_cloud_builder.h" | ||
|
||
namespace DracoFunctions { | ||
|
||
enum decoding_status { successful, not_draco_encoded, no_position_attribute, failed_during_decoding }; | ||
enum decoding_status { successful, not_draco_encoded, no_position_attribute, failed_during_decoding, no_tex_coord_attribute, no_normal_coord_attribute }; | ||
enum encoding_status { successful_encoding, failed_during_encoding }; | ||
|
||
struct PointCloudObject { | ||
|
@@ -27,6 +26,7 @@ namespace DracoFunctions { | |
struct MeshObject : PointCloudObject { | ||
std::vector<float> normals; | ||
std::vector<unsigned int> faces; | ||
std::vector<float> tex_coord; | ||
}; | ||
|
||
struct EncodedObject { | ||
|
@@ -35,11 +35,18 @@ namespace DracoFunctions { | |
}; | ||
|
||
MeshObject decode_buffer(const char *buffer, std::size_t buffer_len) { | ||
|
||
std::cout << "Decode Buffer" << "Begin" << std::endl; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please either hide the |
||
|
||
MeshObject meshObject; | ||
draco::DecoderBuffer decoderBuffer; | ||
decoderBuffer.Init(buffer, buffer_len); | ||
draco::Decoder decoder; | ||
|
||
auto statusor = decoder.DecodeMeshFromBuffer(&decoderBuffer); | ||
|
||
std::cout << "Decode Buffer " << "Status : "<< std::boolalpha << statusor.ok() << std::endl; | ||
|
||
if (!statusor.ok()) { | ||
std::string status_string = statusor.status().error_msg_string(); | ||
if (status_string.compare("Not a Draco file.") || status_string.compare("Failed to parse Draco header.")) { | ||
|
@@ -50,15 +57,27 @@ namespace DracoFunctions { | |
} | ||
return meshObject; | ||
} | ||
|
||
std::unique_ptr<draco::Mesh> in_mesh = std::move(statusor).value(); | ||
draco::Mesh *mesh = in_mesh.get(); | ||
//Position Attribute ID | ||
const int pos_att_id = mesh->GetNamedAttributeId(draco::GeometryAttribute::POSITION); | ||
std::cout << "Decode Buffer " << "Attribute Position : " << pos_att_id << std::endl; | ||
|
||
|
||
|
||
if (pos_att_id < 0) { | ||
meshObject.decode_status = no_position_attribute; | ||
return meshObject; | ||
} | ||
|
||
std::cout << "Decode Buffer " << "Mesh Number Points : " << 3 * mesh->num_points() << std::endl; | ||
meshObject.points.reserve(3 * mesh->num_points()); | ||
std::cout << "Decode Buffer " << "Mesh Number Faces : " << 3 * mesh->num_faces() << std::endl; | ||
meshObject.faces.reserve(3 * mesh->num_faces()); | ||
|
||
|
||
|
||
const auto *const pos_att = mesh->attribute(pos_att_id); | ||
std::array<float, 3> pos_val; | ||
for (draco::PointIndex v(0); v < mesh->num_points(); ++v) { | ||
|
@@ -76,6 +95,40 @@ namespace DracoFunctions { | |
meshObject.faces.push_back(*(reinterpret_cast<const uint32_t *>(&(f[1])))); | ||
meshObject.faces.push_back(*(reinterpret_cast<const uint32_t *>(&(f[2])))); | ||
} | ||
|
||
const int tex_att_id = mesh->GetNamedAttributeId(draco::GeometryAttribute::TEX_COORD); | ||
if(tex_att_id >= 0) { | ||
|
||
const auto *const tex_att = mesh->attribute(tex_att_id); | ||
meshObject.tex_coord.reserve(tex_att->size()); | ||
std::array<float, 2> tex_val; | ||
std::cout << "Decode Buffer " << "Attribute Tex Coord : " << tex_att->size() << std::endl; | ||
|
||
for (draco::PointIndex v(0); v < tex_att->size(); ++v) { | ||
if (!tex_att->ConvertValue<float, 2>(tex_att->mapped_index(v), &tex_val[0])) { | ||
std::cout << "Convert Error" << std::endl; | ||
meshObject.decode_status = no_tex_coord_attribute; | ||
} | ||
meshObject.tex_coord.push_back(tex_val[0]); | ||
meshObject.tex_coord.push_back(tex_val[1]); | ||
} | ||
} | ||
|
||
const int normal_att_id = mesh->GetNamedAttributeId(draco::GeometryAttribute::NORMAL); | ||
const auto *const normal_att = mesh->attribute(normal_att_id); | ||
meshObject.normals.reserve(normal_att->size()); | ||
std::array<float, 3> normal_val; | ||
std::cout << "Decode Buffer" << "Attribute Normal Coord : " << normal_att->size() << std::endl; | ||
for (draco::PointIndex v(0); v < normal_att->size(); ++v){ | ||
if (!normal_att->ConvertValue<float, 3>(normal_att->mapped_index(v), &normal_val[0])){ | ||
std::cout << "Convert Error" << std::endl; | ||
meshObject.decode_status = no_normal_coord_attribute; | ||
} | ||
meshObject.normals.push_back(normal_val[0]); | ||
meshObject.normals.push_back(normal_val[1]); | ||
meshObject.normals.push_back(normal_val[3]); | ||
} | ||
|
||
const draco::GeometryMetadata *metadata = mesh->GetMetadata(); | ||
meshObject.encoding_options_set = false; | ||
if (metadata) { | ||
|
@@ -161,12 +214,13 @@ namespace DracoFunctions { | |
} | ||
} | ||
|
||
EncodedObject encode_mesh(const std::vector<float> &points, const std::vector<unsigned int> &faces, | ||
int quantization_bits, int compression_level, float quantization_range, const float *quantization_origin, bool create_metadata) { | ||
EncodedObject encode_mesh(const std::vector<float> &points, const std::vector<unsigned int> &faces, const std::vector<float> &normals, int quantization_bits, | ||
int compression_level, float quantization_range, const float *quantization_origin, bool create_metadata) { | ||
draco::TriangleSoupMeshBuilder mb; | ||
mb.Start(faces.size()); | ||
const int pos_att_id = | ||
mb.AddAttribute(draco::GeometryAttribute::POSITION, 3, draco::DataType::DT_FLOAT32); | ||
|
||
const int pos_att_id = mb.AddAttribute(draco::GeometryAttribute::POSITION, 3, draco::DataType::DT_FLOAT32); //attribute_type, num_components, data_type | ||
std::cout << "POSITION :" << pos_att_id << std::endl; | ||
|
||
for (std::size_t i = 0; i <= faces.size() - 3; i += 3) { | ||
auto point1Index = faces[i]*3; | ||
|
@@ -175,6 +229,9 @@ namespace DracoFunctions { | |
mb.SetAttributeValuesForFace(pos_att_id, draco::FaceIndex(i), draco::Vector3f(points[point1Index], points[point1Index+1], points[point1Index+2]).data(), draco::Vector3f(points[point2Index], points[point2Index+1], points[point2Index+2]).data(), draco::Vector3f(points[point3Index], points[point3Index+1], points[point3Index+2]).data()); | ||
} | ||
|
||
const int tex_att_id = mb.AddAttribute(draco::GeometryAttribute::TEX_COORD, 2, draco::DataType::DT_FLOAT32); | ||
std::cout << "TEX_COORD :" << tex_att_id << std::endl; | ||
|
||
std::unique_ptr<draco::Mesh> ptr_mesh = mb.Finalize(); | ||
draco::Mesh *mesh = ptr_mesh.get(); | ||
draco::Encoder encoder; | ||
|
@@ -183,6 +240,7 @@ namespace DracoFunctions { | |
const draco::Status status = encoder.EncodeMeshToBuffer(*mesh, &buffer); | ||
EncodedObject encodedMeshObject; | ||
encodedMeshObject.buffer = *((std::vector<unsigned char> *)buffer.buffer()); | ||
|
||
if (status.ok()) { | ||
encodedMeshObject.encode_status = successful_encoding; | ||
} else { | ||
|
@@ -199,7 +257,6 @@ namespace DracoFunctions { | |
pcb.Start(num_points); | ||
const int pos_att_id = | ||
pcb.AddAttribute(draco::GeometryAttribute::POSITION, 3, draco::DataType::DT_FLOAT32); | ||
|
||
for (draco::PointIndex i(0); i < num_points; i++) { | ||
pcb.SetAttributeValueForPoint(pos_att_id, i, points.data() + 3 * i.value()); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,10 @@ class DracoMesh(DracoPointCloud): | |
def normals(self): | ||
return self.data_struct['normals'] | ||
|
||
@property | ||
def tex_coord(self): | ||
return self.data_struct['tex_coord'] | ||
|
||
class EncodingOptions(object): | ||
def __init__(self, quantization_bits, quantization_range, quantization_origin): | ||
self.quantization_bits = quantization_bits | ||
|
@@ -70,7 +74,7 @@ class FileTypeException(Exception): | |
class EncodingFailedException(Exception): | ||
pass | ||
|
||
def encode_mesh_to_buffer(points, faces, quantization_bits=14, compression_level=1, quantization_range=-1, quantization_origin=None, create_metadata=False): | ||
def encode_mesh_to_buffer(points, faces, normals, quantization_bits=14, compression_level=1, quantization_range=-1, quantization_origin=None, create_metadata=False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a breaking change. Can |
||
""" | ||
Encode a list or numpy array of points/vertices (float) and faces (unsigned int) to a draco buffer. | ||
Quantization bits should be an integer between 0 and 31 | ||
|
@@ -87,7 +91,7 @@ def encode_mesh_to_buffer(points, faces, quantization_bits=14, compression_level | |
quant_origin = <float *>PyMem_Malloc(sizeof(float) * num_dims) | ||
for dim in range(num_dims): | ||
quant_origin[dim] = quantization_origin[dim] | ||
encoded_mesh = DracoPy.encode_mesh(points, faces, quantization_bits, compression_level, quantization_range, quant_origin, create_metadata) | ||
encoded_mesh = DracoPy.encode_mesh(points, faces, normals, quantization_bits, compression_level, quantization_range, quant_origin, create_metadata) | ||
if quant_origin != NULL: | ||
PyMem_Free(quant_origin) | ||
if encoded_mesh.encode_status == DracoPy.encoding_status.successful_encoding: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be the number of texture coordinates?