Skip to content

Commit

Permalink
support point clouds
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Feb 28, 2021
1 parent 103831b commit cbd4b24
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 143 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ endif()
list(APPEND draco_c_sources
"${CMAKE_CURRENT_SOURCE_DIR}/src/decoder.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/mesh.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/point_cloud.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/point_attribute.cc"
)

Expand Down
60 changes: 37 additions & 23 deletions include/c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,48 +101,56 @@ EXPORT_API int64_t dracoPointAttrByteOffset(const draco_point_attr* pa);

EXPORT_API uint32_t dracoPointAttrUniqueId(const draco_point_attr* pa);

// draco::PointCloud

typedef struct draco_point_cloud draco_point_cloud;

EXPORT_API draco_point_cloud* dracoNewPointCloud();

EXPORT_API void dracoPointCloudRelease(draco_point_cloud *pc);

EXPORT_API uint32_t dracoPointCloudNumPoints(const draco_point_cloud *pc);

EXPORT_API int32_t dracoPointCloudNumAttrs(const draco_point_cloud *pc);

EXPORT_API const draco_point_attr* dracoPointCloudGetAttribute(const draco_point_cloud *pc, int32_t att_id);

EXPORT_API int32_t dracoPointCloudGetNamedAttributeId(const draco_point_cloud *pc, draco_geometry_type geo_type);

EXPORT_API const draco_point_attr* dracoPointCloudGetAttributeByUniqueId(const draco_point_cloud *pc, uint32_t unique_id);

EXPORT_API bool dracoPointCloudGetAttributeData(const draco_point_cloud *pc,
const draco_point_attr *pa,
draco_data_type data_type,
const size_t out_size,
void *out_values);

// draco::Mesh

typedef struct draco_mesh draco_mesh;
typedef struct draco_point_cloud draco_mesh;

EXPORT_API draco_mesh* dracoNewMesh();

EXPORT_API void dracoMeshRelease(draco_mesh *mesh);

EXPORT_API uint32_t dracoMeshNumFaces(const draco_mesh *mesh);

EXPORT_API uint32_t dracoMeshNumPoints(const draco_mesh *mesh);

EXPORT_API int32_t dracoMeshNumAttrs(const draco_mesh *mesh);

// Queries an array of 3*face_count elements containing the triangle indices.
// out_values must be allocated to contain at least 3*face_count uint16_t elements.
// out_size must be exactly 3*face_count*sizeof(uint16_t), else out_values
// won´t be filled and returns false.
// won't be filled and returns false.
EXPORT_API bool dracoMeshGetTrianglesUint16(const draco_mesh *mesh,
const size_t out_size,
uint16_t *out_values);

// Queries an array of 3*face_count elements containing the triangle indices.
// out_values must be allocated to contain at least 3*face_count uint32_t elements.
// out_size must be exactly 3*face_count*sizeof(uint32_t), else out_values
// won´t be filled and returns false.
// won't be filled and returns false.
EXPORT_API bool dracoMeshGetTrianglesUint32(const draco_mesh *mesh,
const size_t out_size,
uint32_t *out_values);

EXPORT_API const draco_point_attr* dracoMeshGetAttribute(const draco_mesh *mesh, int32_t att_id);

EXPORT_API int32_t dracoMeshGetNamedAttributeId(const draco_mesh *mesh, draco_geometry_type geo_type);

EXPORT_API const draco_point_attr* dracoMeshGetAttributeByUniqueId(const draco_mesh *mesh, uint32_t unique_id);

EXPORT_API bool dracoMeshGetAttributeData(const draco_mesh *mesh,
const draco_point_attr *pa,
draco_data_type data_type,
const size_t out_size,
void *out_values);

// draco::Decoder

typedef struct draco_decoder draco_decoder;
Expand All @@ -151,10 +159,16 @@ EXPORT_API draco_decoder* dracoNewDecoder();

EXPORT_API void dracoDecoderRelease(draco_decoder *decoder);

EXPORT_API draco_status* dracoDecoderArrayToMesh(draco_decoder *decoder,
const char *data,
size_t data_size,
draco_mesh *out_mesh);
EXPORT_API draco_status* dracoDecoderDecodeMesh(draco_decoder *decoder,
const char *data,
size_t data_size,
draco_mesh *out_mesh);


EXPORT_API draco_status* dracoDecoderDecodePointCloud(draco_decoder *decoder,
const char *data,
size_t data_size,
draco_point_cloud *out_pc);

#ifdef __cplusplus
}
Expand Down
16 changes: 8 additions & 8 deletions src/c_api_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ draco_mesh *DecodeToDracoMesh(const std::string &file_name) {

auto mesh = dracoNewMesh();
auto decoder = dracoNewDecoder();
dracoDecoderArrayToMesh(decoder, data.data(), data.size(), mesh);
dracoDecoderDecodeMesh(decoder, data.data(), data.size(), mesh);
dracoDecoderRelease(decoder);
return mesh;
}
Expand All @@ -45,24 +45,24 @@ TEST(DracoCAPITest, TestDecode) {
ASSERT_NE(mesh, nullptr);
auto num_faces = dracoMeshNumFaces(mesh);
ASSERT_EQ(num_faces, 170);
ASSERT_EQ(dracoMeshNumPoints(mesh), 99);
auto num_attrs = dracoMeshNumAttrs(mesh);
ASSERT_EQ(dracoPointCloudNumPoints(mesh), 99);
auto num_attrs = dracoPointCloudNumAttrs(mesh);
ASSERT_EQ(num_attrs, 2);

auto indices_size = 3 * num_faces * sizeof(uint32_t);
uint32_t *indices = (uint32_t *)malloc(indices_size);
ASSERT_TRUE(dracoMeshGetTrianglesUint32(mesh, indices_size, indices));
free(indices);

auto pa1 = dracoMeshGetAttribute(mesh, 0);
auto pa1 = dracoPointCloudGetAttribute(mesh, 0);
ASSERT_EQ(dracoPointAttrType(pa1), GT_POSITION);
ASSERT_EQ(dracoPointAttrDataType(pa1), DT_FLOAT32);
ASSERT_EQ(dracoPointAttrNumComponents(pa1), 3);
ASSERT_FALSE(dracoPointAttrNormalized(pa1));
ASSERT_EQ(dracoPointAttrByteStride(pa1), 12);
ASSERT_EQ(dracoPointAttrUniqueId(pa1), 0);

auto pa2 = dracoMeshGetAttribute(mesh, 1);
auto pa2 = dracoPointCloudGetAttribute(mesh, 1);
ASSERT_EQ(dracoPointAttrType(pa2), GT_NORMAL);
ASSERT_EQ(dracoPointAttrDataType(pa2), DT_FLOAT32);
ASSERT_EQ(dracoPointAttrNumComponents(pa2), 3);
Expand All @@ -72,9 +72,9 @@ TEST(DracoCAPITest, TestDecode) {

auto arr_size = 3*99*sizeof(float);
auto arr = (float *)malloc(arr_size);
ASSERT_TRUE(dracoMeshGetAttributeData(mesh, pa2, DT_FLOAT32, arr_size, arr));
ASSERT_FALSE(dracoMeshGetAttributeData(mesh, pa2, DT_FLOAT32, arr_size+1, arr));
ASSERT_FALSE(dracoMeshGetAttributeData(mesh, pa2, DT_FLOAT32, arr_size-1, arr));
ASSERT_TRUE(dracoPointCloudGetAttributeData(mesh, pa2, DT_FLOAT32, arr_size, arr));
ASSERT_FALSE(dracoPointCloudGetAttributeData(mesh, pa2, DT_FLOAT32, arr_size+1, arr));
ASSERT_FALSE(dracoPointCloudGetAttributeData(mesh, pa2, DT_FLOAT32, arr_size-1, arr));

dracoMeshRelease(mesh);
}
Expand Down
19 changes: 15 additions & 4 deletions src/decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,24 @@ void dracoDecoderRelease(draco_decoder *decoder) {
free(decoder);
}

draco_status* dracoDecoderArrayToMesh(draco_decoder *decoder,
const char *data,
size_t data_size,
draco_mesh *out_mesh) {
draco_status* dracoDecoderDecodeMesh(draco_decoder *decoder,
const char *data,
size_t data_size,
draco_mesh *out_mesh) {
draco::DecoderBuffer buffer;
buffer.Init(data, data_size);
auto m = reinterpret_cast<draco::Mesh*>(out_mesh);
const auto &last_status_ = reinterpret_cast<draco::Decoder*>(decoder)->DecodeBufferToGeometry(&buffer, m);
return reinterpret_cast<draco_status*>(new draco::Status(last_status_));
}

draco_status* dracoDecoderDecodePointCloud(draco_decoder *decoder,
const char *data,
size_t data_size,
draco_point_cloud *out_pc) {
draco::DecoderBuffer buffer;
buffer.Init(data, data_size);
auto m = reinterpret_cast<draco::PointCloud*>(out_pc);
const auto &last_status_ = reinterpret_cast<draco::Decoder*>(decoder)->DecodeBufferToGeometry(&buffer, m);
return reinterpret_cast<draco_status*>(new draco::Status(last_status_));
}
108 changes: 0 additions & 108 deletions src/mesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ uint32_t dracoMeshNumFaces(const draco_mesh *mesh) {
return reinterpret_cast<const draco::Mesh*>(mesh)->num_faces();
}


uint32_t dracoMeshNumPoints(const draco_mesh *mesh) {
return reinterpret_cast<const draco::Mesh*>(mesh)->num_points();
}

int32_t dracoMeshNumAttrs(const draco_mesh *mesh) {
return reinterpret_cast<const draco::Mesh*>(mesh)->num_attributes();
}

template <typename T>
bool GetTrianglesArray(const draco::Mesh *m, const size_t out_size,
T *out_values) {
Expand Down Expand Up @@ -58,102 +49,3 @@ bool dracoMeshGetTrianglesUint32(const draco_mesh *mesh, const size_t out_size,

return GetTrianglesArray(m, out_size, out_values);
}

const draco_point_attr* dracoMeshGetAttribute(const draco_mesh *mesh, int32_t att_id) {
auto m = reinterpret_cast<const draco::Mesh*>(mesh);
if (att_id < 0 || att_id > m->num_attributes()) {
return nullptr;
}
auto attr = m->attribute(att_id);
return reinterpret_cast<const draco_point_attr*>(attr);
}

const draco_point_attr* dracoMeshGetAttributeByUniqueId(const draco_mesh *mesh, uint32_t unique_id) {
auto m = reinterpret_cast<const draco::Mesh*>(mesh);
auto attr = m->GetAttributeByUniqueId(unique_id);
return reinterpret_cast<const draco_point_attr*>(attr);
}


int32_t dracoMeshGetNamedAttributeId(const draco_mesh *mesh, draco_geometry_type geo_type) {
auto type = static_cast<draco::GeometryAttribute::Type>(geo_type);
return reinterpret_cast<const draco::Mesh*>(mesh)->GetNamedAttributeId(type);
}

template <class T>
static bool GetAttributeDataArrayForAllPoints(const draco::PointCloud *pc,
const draco::PointAttribute *pa,
draco::DataType type,
size_t out_size,
void *out_values) {
const int components = pa->num_components();
const int num_points = pc->num_points();
const int data_size = num_points * components * sizeof(T);
if (data_size != out_size) {
return false;
}
const bool requested_type_matches = pa->data_type() == type;
if (requested_type_matches && pa->is_mapping_identity()) {
// Copy values directly to the output vector.
const auto ptr = pa->GetAddress(draco::AttributeValueIndex(0));
::memcpy(out_values, ptr, data_size);
return true;
}

// Copy values one by one.
std::vector<T> values(components);
int entry_id = 0;

T *const typed_output = reinterpret_cast<T *>(out_values);
for (draco::PointIndex i(0); i < num_points; ++i) {
const draco::AttributeValueIndex val_index = pa->mapped_index(i);
if (requested_type_matches) {
pa->GetValue(val_index, values.data());
} else {
if (!pa->ConvertValue<T>(val_index, values.data())) {
return false;
}
}
for (int j = 0; j < components; ++j) {
typed_output[entry_id++] = values[j];
}
}
return true;
}

bool dracoMeshGetAttributeData(const draco_mesh *pc,
const draco_point_attr *pa,
draco_data_type data_type,
const size_t out_size,
void *out_values) {
auto pcc = reinterpret_cast<const draco::Mesh*>(pc);
auto pac = reinterpret_cast<const draco::PointAttribute*>(pa);
switch (data_type) {
case DT_INT8:
return GetAttributeDataArrayForAllPoints<int8_t>(pcc, pac, draco::DT_INT8,
out_size, out_values);
case DT_INT16:
return GetAttributeDataArrayForAllPoints<int16_t>(pcc, pac, draco::DT_INT16,
out_size, out_values);
case DT_INT32:
return GetAttributeDataArrayForAllPoints<int32_t>(pcc, pac, draco::DT_INT32,
out_size, out_values);
case DT_UINT8:
return GetAttributeDataArrayForAllPoints<uint8_t>(pcc, pac, draco::DT_UINT8,
out_size, out_values);
case DT_UINT16:
return GetAttributeDataArrayForAllPoints<uint16_t>(pcc, pac, draco::DT_UINT16,
out_size, out_values);
case DT_UINT32:
return GetAttributeDataArrayForAllPoints<uint32_t>(pcc, pac, draco::DT_UINT32,
out_size, out_values);
case DT_FLOAT32:
return GetAttributeDataArrayForAllPoints<float>(pcc, pac, draco::DT_FLOAT32,
out_size, out_values);
case DT_FLOAT64:
return GetAttributeDataArrayForAllPoints<double>(pcc, pac, draco::DT_FLOAT64,
out_size, out_values);
default:
return false;
}
}
Loading

0 comments on commit cbd4b24

Please sign in to comment.