31 #include <draco/metadata/geometry_metadata.h> 48 template <
typename LvrArrType,
typename DataType,
int numComponents>
53 throw std::invalid_argument(
"attribute is not existing");
56 LvrArrType data(
new DataType[attribute->size() * numComponents]);
58 std::array<DataType, numComponents> tmp;
59 for (draco::AttributeValueIndex i(0); i < attribute->size(); ++i)
61 if (!attribute->ConvertValue<
DataType, numComponents>(i, &tmp[0]))
63 throw std::invalid_argument(
"attribute seems to have an incorrect structur");
66 for (
int j = 0; j < numComponents; j++)
68 data[i.value() * numComponents + j] = tmp[j];
82 void createTextures(std::vector<int32_t>& drcTextures, std::vector<GlTexture*>& lvrTextures)
84 unsigned long size = drcTextures.size();
85 unsigned long index = 0;
90 int id = drcTextures[index++];
91 int height = drcTextures[index++];
92 int width = drcTextures[index++];
94 int pixelDat = height * width * 3;
95 unsigned char* pixel =
new unsigned char[pixelDat];
98 for (
int i = 0; i < pixelDat; ++i)
100 pixel[i] = (
unsigned char)drcTextures[index++];
105 lvrTextures.push_back(glTexture);
116 void createTextures(std::vector<int32_t>& drcTextures, std::vector<Texture>& lvrTextures)
118 unsigned long size = drcTextures.size();
119 unsigned long index = 0;
124 int id = drcTextures[index++];
125 int height = drcTextures[index++];
126 int width = drcTextures[index++];
128 int pixelDat = height * width * 3;
129 unsigned char* pixel =
new unsigned char[pixelDat];
132 for (
int i = 0; i < pixelDat; ++i)
134 pixel[i] = (
unsigned char)drcTextures[index++];
137 Texture texture(
id, width, height, 3, 1, 1, pixel);
138 lvrTextures.push_back(texture);
157 if (!geometry->GetMetadata())
162 const draco::AttributeMetadata* attributeMeta =
163 geometry->GetMetadata()->GetAttributeMetadataByStringEntry(key, value);
170 return geometry->GetAttributeByUniqueId(attributeMeta->att_unique_id());
182 auto status = decoder.DecodePointCloudFromBuffer(&buffer);
186 std::cerr <<
"An error occurred while decoding file:" 187 <<
" " << status.status() << std::endl;
193 std::unique_ptr<draco::PointCloud> dracoPointCloud = std::move(status).value();
198 const draco::PointAttribute* attribute =
199 dracoPointCloud->GetNamedAttribute(draco::GeometryAttribute::POSITION);
200 floatArr data = loadAttributeFromDraco<floatArr, float, 3>(attribute);
201 modelPtr->m_pointCloud->setPointArray(data, attribute->size());
203 catch (
const std::invalid_argument& ia)
206 std::cerr <<
"Error loading positions: " << ia.what() << std::endl;
213 const draco::PointAttribute* attribute =
214 dracoPointCloud->GetNamedAttribute(draco::GeometryAttribute::NORMAL);
215 floatArr data = loadAttributeFromDraco<floatArr, float, 3>(attribute);
216 modelPtr->m_pointCloud->setNormalArray(data, attribute->size());
218 catch (
const std::invalid_argument& ia)
225 const draco::PointAttribute* attribute =
226 dracoPointCloud->GetNamedAttribute(draco::GeometryAttribute::COLOR);
227 ucharArr data = loadAttributeFromDraco<ucharArr, unsigned char, 3>(attribute);
228 modelPtr->m_pointCloud->setColorArray(data, attribute->size());
230 catch (
const std::invalid_argument& ia)
270 auto status = decoder.DecodeMeshFromBuffer(&buffer);
274 std::cerr <<
"An error occurred while decoding file:" 275 <<
" " << status.status() << std::endl;
281 std::unique_ptr<draco::Mesh> dracoMesh = std::move(status).value();
283 auto metadata = dracoMesh->GetMetadata();
288 std::vector<int32_t> texture;
290 if (metadata->GetEntryIntArray(
"texture", &texture))
292 std::vector<Texture> textures;
296 modelPtr->m_mesh->setTextures(textures);
303 std::vector<int32_t> dat;
305 if (metadata->GetEntryIntArray(
"material", &dat))
307 vector<Material> materials;
308 for (
int i = 0; i < dat.size() / 4; i++)
312 rgb[0] =
static_cast<unsigned char>(dat[4 * i + 0]);
313 rgb[0] =
static_cast<unsigned char>(dat[4 * i + 1]);
314 rgb[0] =
static_cast<unsigned char>(dat[4 * i + 2]);
321 materials.push_back(m);
324 modelPtr->m_mesh->setMaterials(materials);
331 const draco::PointAttribute* attribute =
332 dracoMesh->GetNamedAttribute(draco::GeometryAttribute::POSITION);
333 floatArr data = loadAttributeFromDraco<floatArr, float, 3>(attribute);
334 modelPtr->m_mesh->setVertices(data, attribute->size());
336 catch (
const std::invalid_argument& ia)
339 std::cerr <<
"Error loading positions: " << ia.what() << std::endl;
346 const draco::PointAttribute* attribute =
347 dracoMesh->GetNamedAttribute(draco::GeometryAttribute::NORMAL);
348 floatArr data = loadAttributeFromDraco<floatArr, float, 3>(attribute);
349 modelPtr->m_mesh->setVertexNormals(data);
351 catch (
const std::invalid_argument& ia)
358 const draco::PointAttribute* attribute =
359 dracoMesh->GetNamedAttribute(draco::GeometryAttribute::COLOR);
360 ucharArr data = loadAttributeFromDraco<ucharArr, unsigned char, 3>(attribute);
361 modelPtr->m_mesh->setVertexColors(data);
363 catch (
const std::invalid_argument& ia)
394 const draco::PointAttribute* attribute =
395 dracoMesh->GetNamedAttribute(draco::GeometryAttribute::TEX_COORD);
396 floatArr data = loadAttributeFromDraco<floatArr, float, 3>(attribute);
397 modelPtr->m_mesh->setTextureCoordinates(data);
399 catch (
const std::invalid_argument& ia)
404 const draco::PointAttribute* matIndexAttribute =
406 if (matIndexAttribute)
408 indexArray data(
new uint32_t[dracoMesh->num_faces()]);
411 for (draco::FaceIndex i(0); i < dracoMesh->num_faces(); i++)
413 if (!matIndexAttribute->ConvertValue<uint32_t, 1>(
414 matIndexAttribute->mapped_index(dracoMesh->face(i)[0]), &tmp))
416 data =
uintArr(
new uint32_t[dracoMesh->num_faces()]);
420 data[i.value()] = tmp;
423 modelPtr->m_mesh->setFaceMaterialIndices(data);
427 const draco::PointAttribute* faceAttribute =
428 dracoMesh->GetNamedAttribute(draco::GeometryAttribute::Type::POSITION);
429 uintArr faceArr(
new unsigned int[dracoMesh->num_faces() * 3]);
430 for (draco::FaceIndex i(0); i < dracoMesh->num_faces(); ++i)
432 faceArr[i.value() * 3 + 0] = faceAttribute->mapped_index(dracoMesh->face(i)[0]).value();
433 faceArr[i.value() * 3 + 1] = faceAttribute->mapped_index(dracoMesh->face(i)[1]).value();
434 faceArr[i.value() * 3 + 2] = faceAttribute->mapped_index(dracoMesh->face(i)[2]).value();
436 modelPtr->m_mesh->setFaceIndices(faceArr, dracoMesh->num_faces());
443 draco::Decoder decoder;
445 if (type == draco::TRIANGULAR_MESH)
449 else if (type == draco::POINT_CLOUD)
A class to handle point information with an arbitrarily large number of attribute channels...
A material that stores information about color and texture of a cluster.
std::shared_ptr< MeshBuffer > MeshBufferPtr
boost::shared_array< unsigned int > uintArr
void createTextures(std::vector< int32_t > &drcTextures, std::vector< GlTexture *> &lvrTextures)
transforms the int32_t vector with texture data into actual GlTextures
Decodes a draco comptressed file into a lvr model.
boost::shared_array< unsigned char > ucharArr
ModelPtr readMesh(draco::DecoderBuffer &buffer, draco::Decoder &decoder)
loads a mesh from the decoderBuffer and converts it into the lvr structure
std::shared_ptr< PointBuffer > PointBufferPtr
Handle to access textures of the mesh.
const draco::PointAttribute * getDracoAttributeByAttributeMetadata(draco::PointCloud *geometry, std::string key, std::string value)
delivers PointAttribute by searching for given Attribute Metadata Entries
boost::shared_array< unsigned int > indexArray
ModelPtr decodeDraco(draco::DecoderBuffer &buffer, draco::EncodedGeometryType type)
delivers ModelPtr from draco DecoderBuffer
This class represents a texture.
boost::shared_array< float > floatArr
std::shared_ptr< Model > ModelPtr
boost::optional< Rgb8Color > m_color
Optional color.
std::array< uint8_t, 3 > Rgb8Color
GLuint m_texIndex
The texture index of the texture.
LvrArrType loadAttributeFromDraco(const draco::PointAttribute *attribute)
loads any GeometryAttribute from draco pointcloud and returns its values
boost::optional< TextureHandle > m_texture
Optional texture handle.
The MeshBuffer Mesh representation for I/O modules.
ModelPtr readPointCloud(draco::DecoderBuffer &buffer, draco::Decoder &decoder)
loads a pointcloud from the decoderBuffer and converts it into the lvr structure