31 #include <draco/metadata/geometry_metadata.h>
52 template <
typename ArrayType,
typename DataType,
int size>
54 draco::GeometryAttribute::Type geometryType,
draco::DataType dracoDataType,
59 throw std::invalid_argument(
"attribute is not existing");
62 draco::PointAttribute attribute;
63 attribute.Init(geometryType,
nullptr, size, dracoDataType,
normalized,
sizeof(
DataType) * size,
65 int attribute_id = drcPointcloud->AddAttribute(attribute,
true, numPoints);
67 std::array<DataType, size> tmp;
68 for (
int i = 0; i < numPoints; ++i)
70 for (
int j = 0; j < size; ++j)
72 tmp[j] = array[i * size + j];
75 drcPointcloud->attribute(attribute_id)
76 ->SetAttributeValue(draco::AttributeValueIndex(i), &tmp);
92 for (
int i = 0; i < numTextures; ++i)
98 int width = lvrTexture->
m_width;
99 unsigned char* pixel = lvrTexture->
m_pixels;
102 unsigned long pixelDat = (
unsigned long)height * width * 3;
105 textureValue->push_back(index);
106 textureValue->push_back(height);
107 textureValue->push_back(width);
110 for (
unsigned long j = 0; j < pixelDat; ++j)
112 textureValue->push_back((int32_t)pixel[j]);
125 void saveTextures(std::vector<int32_t>* textureValue, vector<Texture>& textures)
127 for (
int i = 0; i < textures.size(); ++i)
130 Texture lvrTexture = textures[i];
131 int index = lvrTexture.
m_index;
133 int width = lvrTexture.
m_width;
134 unsigned char* pixel = lvrTexture.
m_data;
137 unsigned long pixelDat = (
unsigned long)height * width * 3;
140 textureValue->push_back(index);
141 textureValue->push_back(height);
142 textureValue->push_back(width);
145 for (
unsigned long j = 0; j < pixelDat; ++j)
147 textureValue->push_back((int32_t)pixel[j]);
163 draco::PointCloud pointCloud;
164 draco::GeometryMetadata* metadata =
new draco::GeometryMetadata();
168 size_t numPoints = modelPtr->m_pointCloud->numPoints();
169 pointCloud.set_num_points(numPoints);
174 floatArr coordinates = modelPtr->m_pointCloud->getPointArray();
175 saveAttributeToDraco<floatArr, float, 3>(coordinates, &pointCloud,
176 draco::GeometryAttribute::Type::POSITION,
177 draco::DT_FLOAT32, numPoints,
false);
179 catch (
const std::invalid_argument& ia)
181 std::cerr <<
"No point coordinates could be found in the pointcloud" << std::endl;
182 return std::unique_ptr<draco::EncoderBuffer>(
nullptr);
188 floatArr normals = modelPtr->m_pointCloud->getNormalArray();
191 saveAttributeToDraco<floatArr, float, 3>(normals, &pointCloud,
192 draco::GeometryAttribute::Type::NORMAL,
193 draco::DT_FLOAT32, numElem,
true);
196 catch (
const std::invalid_argument& ia)
208 saveAttributeToDraco<ucharArr, unsigned char, 3>(
colors, &pointCloud,
209 draco::GeometryAttribute::Type::COLOR,
210 draco::DT_UINT8, numElem,
false);
213 catch (
const std::invalid_argument& ia)
256 pointCloud.AddMetadata(std::unique_ptr<draco::GeometryMetadata>(metadata));
259 std::unique_ptr<draco::EncoderBuffer> buffer(
new draco::EncoderBuffer());
260 auto status = encoder.EncodePointCloudToBuffer(pointCloud, buffer.get());
264 std::cerr <<
"An error occurred:"
265 <<
" " << status.error_msg_string() << std::endl;
266 return std::unique_ptr<draco::EncoderBuffer>(
nullptr);
283 draco::GeometryMetadata* metadata =
new draco::GeometryMetadata();
287 size_t numVertices = modelPtr->m_mesh->numVertices();
288 floatArr vertices = modelPtr->m_mesh->getVertices();
289 floatArr vertexNormals = modelPtr->m_mesh->getVertexNormals();
290 ucharArr vertexColors = modelPtr->m_mesh->getVertexColors(w);
291 bool hasVertexColors = modelPtr->m_mesh->hasVertexColors();
292 bool hasFaceColors = modelPtr->m_mesh->hasFaceColors();
293 bool hasVertexNormals = modelPtr->m_mesh->hasVertexNormals();
294 bool hasFaceNormals = modelPtr->m_mesh->hasFaceNormals();
302 size_t numVertexTextureCoordinates = numVertices;
303 floatArr vertexTextureCoordinates = modelPtr->m_mesh->getTextureCoordinates();
305 size_t numFaces = modelPtr->m_mesh->numFaces();
306 uintArr faces = modelPtr->m_mesh->getFaceIndices();
308 std::vector<Texture> textures = modelPtr->m_mesh->getTextures();
309 std::vector<Material> materials = modelPtr->m_mesh->getMaterials();
311 indexArray faceMaterialIndices = modelPtr->m_mesh->getFaceMaterialIndices();
314 mesh.set_num_points(numFaces * 3);
315 mesh.SetNumFaces(numFaces);
318 int verticesAttId = -1;
319 int vertexNormalsAttId = -1;
320 int vertexColorsAttId = -1;
321 int vertexConfidencesAttId = -1;
322 int vertexIntensitiesAttId = -1;
323 int vertexTextureCoordinatesAttId = -1;
324 int faceMaterialIndicesAttId = -1;
330 bool faceIndexed = (faceMaterialIndices != 0);
334 draco::GeometryAttribute attribute;
335 attribute.Init(draco::GeometryAttribute::POSITION,
nullptr, 3, draco::DT_FLOAT32,
false,
336 sizeof(
float) * 3, 0);
338 mesh.AddAttribute(attribute,
true, faceIndexed ? numFaces * 3 : numVertices);
339 mesh.SetAttributeElementType(verticesAttId,
340 draco::MeshAttributeElementType::MESH_VERTEX_ATTRIBUTE);
343 if (hasVertexNormals)
345 draco::GeometryAttribute attribute;
346 attribute.Init(draco::GeometryAttribute::NORMAL,
nullptr, 3, draco::DT_FLOAT32,
true,
347 sizeof(
float) * 3, 0);
349 mesh.AddAttribute(attribute,
true, faceIndexed ? numFaces * 3 : numVertices);
350 mesh.SetAttributeElementType(vertexNormalsAttId,
351 draco::MeshAttributeElementType::MESH_VERTEX_ATTRIBUTE);
356 draco::GeometryAttribute attribute;
357 attribute.Init(draco::GeometryAttribute::COLOR,
nullptr, 3, draco::DT_UINT8,
false,
358 sizeof(uint8_t) * 3, 0);
360 mesh.AddAttribute(attribute,
true, faceIndexed ? numFaces * 3 : numVertices);
361 mesh.SetAttributeElementType(vertexColorsAttId,
362 draco::MeshAttributeElementType::MESH_VERTEX_ATTRIBUTE);
399 if (vertexTextureCoordinates)
401 draco::GeometryAttribute attribute;
402 attribute.Init(draco::GeometryAttribute::TEX_COORD,
nullptr, 3, draco::DT_FLOAT32,
false,
403 sizeof(
float) * 3, 0);
404 vertexTextureCoordinatesAttId =
mesh.AddAttribute(
405 attribute,
true, faceIndexed ? numFaces * 3 : numVertexTextureCoordinates);
406 mesh.SetAttributeElementType(vertexTextureCoordinatesAttId,
407 draco::MeshAttributeElementType::MESH_VERTEX_ATTRIBUTE);
410 if (faceMaterialIndices)
412 draco::GeometryAttribute attribute;
413 attribute.Init(draco::GeometryAttribute::GENERIC,
nullptr, 1, draco::DT_UINT32,
false,
414 sizeof(uint32_t), 0);
415 faceMaterialIndicesAttId =
416 mesh.AddAttribute(attribute,
true, faceIndexed ? numFaces * 3 : numFaces);
417 mesh.SetAttributeElementType(faceMaterialIndicesAttId,
418 draco::MeshAttributeElementType::MESH_FACE_ATTRIBUTE);
420 draco::AttributeMetadata* attributeMeta =
new draco::AttributeMetadata();
421 attributeMeta->set_att_unique_id(faceMaterialIndicesAttId);
422 attributeMeta->AddEntryString(
"name",
"materialindex");
424 metadata->AddAttributeMetadata(std::unique_ptr<draco::AttributeMetadata>(attributeMeta));
428 if (faceMaterialIndices && materials.size())
430 std::vector<int32_t> materialData;
432 for (
int i = 0; i < materials.size(); i++)
434 boost::optional<TextureHandle> opt_texture_index = materials[i].m_texture;
435 boost::optional<Rgb8Color> opt_mat_color = materials[i].m_color;
439 materialData.push_back(mat_color[0]);
440 materialData.push_back(mat_color[1]);
441 materialData.push_back(mat_color[2]);
446 materialData.push_back(126);
447 materialData.push_back(126);
448 materialData.push_back(126);
451 if(opt_texture_index)
454 materialData.push_back(handle.
idx());
459 materialData.push_back(-1);
464 metadata->AddEntryIntArray(
"material", materialData);
469 std::vector<int32_t> textureValue;
471 metadata->AddEntryIntArray(
"texture", textureValue);
478 draco::Mesh::Face face;
479 for (draco::FaceIndex i(0); i < numFaces; i++)
484 face[0] = draco::PointIndex(i.value() * 3 + 0);
485 face[1] = draco::PointIndex(i.value() * 3 + 1);
486 face[2] = draco::PointIndex(i.value() * 3 + 2);
487 mesh.SetFace(i, face);
490 mesh.attribute(verticesAttId)
491 ->SetAttributeValue(draco::AttributeValueIndex(face[0].value()),
492 vertices.get() + faces[3 * i.value() + 0] * 3);
493 mesh.attribute(verticesAttId)
494 ->SetAttributeValue(draco::AttributeValueIndex(face[1].value()),
495 vertices.get() + faces[3 * i.value() + 1] * 3);
496 mesh.attribute(verticesAttId)
497 ->SetAttributeValue(draco::AttributeValueIndex(face[2].value()),
498 vertices.get() + faces[3 * i.value() + 2] * 3);
503 mesh.attribute(vertexNormalsAttId)
504 ->SetAttributeValue(draco::AttributeValueIndex(face[0].value()),
505 vertexNormals.get() + faces[3 * i.value() + 0] * 3);
506 mesh.attribute(vertexNormalsAttId)
507 ->SetAttributeValue(draco::AttributeValueIndex(face[1].value()),
508 vertexNormals.get() + faces[3 * i.value() + 1] * 3);
509 mesh.attribute(vertexNormalsAttId)
510 ->SetAttributeValue(draco::AttributeValueIndex(face[2].value()),
511 vertexNormals.get() + faces[3 * i.value() + 2] * 3);
517 for (
int j = 0; j < 3; j++)
519 unsigned char color[3];
520 color[0] = vertexColors[3 * i.value()];
521 color[1] = vertexColors[3 * i.value() + 1];
522 color[2] = vertexColors[3 * i.value() + 2];
523 mesh.attribute(vertexColorsAttId)
524 ->SetAttributeValue(draco::AttributeValueIndex(face[j].value()),
color);
557 if (vertexTextureCoordinates)
559 mesh.attribute(vertexTextureCoordinatesAttId)
560 ->SetAttributeValue(draco::AttributeValueIndex(face[0].value()),
561 vertexTextureCoordinates.get() +
562 faces[3 * i.value() + 0] * 3);
563 mesh.attribute(vertexTextureCoordinatesAttId)
564 ->SetAttributeValue(draco::AttributeValueIndex(face[1].value()),
565 vertexTextureCoordinates.get() +
566 faces[3 * i.value() + 1] * 3);
567 mesh.attribute(vertexTextureCoordinatesAttId)
568 ->SetAttributeValue(draco::AttributeValueIndex(face[2].value()),
569 vertexTextureCoordinates.get() +
570 faces[3 * i.value() + 2] * 3);
574 if (faceMaterialIndices)
576 mesh.attribute(faceMaterialIndicesAttId)
577 ->SetAttributeValue(draco::AttributeValueIndex(face[0].value()),
578 faceMaterialIndices.get() + i.value());
579 mesh.attribute(faceMaterialIndicesAttId)
580 ->SetAttributeValue(draco::AttributeValueIndex(face[1].value()),
581 faceMaterialIndices.get() + i.value());
582 mesh.attribute(faceMaterialIndicesAttId)
583 ->SetAttributeValue(draco::AttributeValueIndex(face[2].value()),
584 faceMaterialIndices.get() + i.value());
591 for (draco::AttributeValueIndex i(0); i < numVertices; i++)
593 mesh.attribute(verticesAttId)->SetAttributeValue(i, vertices.get() + i.value() * 3);
597 for (draco::AttributeValueIndex i(0); i < numVertices; i++)
599 mesh.attribute(vertexNormalsAttId)
600 ->SetAttributeValue(i, vertexNormals.get() + i.value() * 3);
604 for (draco::AttributeValueIndex i(0); i < numVertices; i++)
606 unsigned char color[3];
607 color[0] = vertexColors[3 * i.value()];
608 color[1] = vertexColors[3 * i.value() + 1];
609 color[2] = vertexColors[3 * i.value() + 2];
610 mesh.attribute(vertexColorsAttId)->SetAttributeValue(i,
color);
628 draco::Mesh::Face face;
629 for (draco::FaceIndex i(0); i < numFaces; i++)
631 for (
int j = 0; j < 3; j++)
633 face[j] = faces[3 * i.value() + j];
635 mesh.SetFace(i, face);
639 mesh.AddMetadata(std::unique_ptr<draco::GeometryMetadata>(metadata));
642 std::unique_ptr<draco::EncoderBuffer> buffer(
new draco::EncoderBuffer());
643 auto status = encoder.EncodeMeshToBuffer(
mesh, buffer.get());
647 std::cerr <<
"An error occurred:"
648 <<
" " << status.error_msg_string() << std::endl;
649 return std::unique_ptr<draco::EncoderBuffer>(
nullptr);
656 draco::EncodedGeometryType type)
658 draco::Encoder encoder;
660 encoder.SetSpeedOptions(0, 0);
662 if (type == draco::TRIANGULAR_MESH)
666 else if (type == draco::POINT_CLOUD)
670 encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 12);
671 encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, 12);
672 encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 10);
673 encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC, 8);
678 return std::unique_ptr<draco::EncoderBuffer>(
nullptr);