15 #include <pcl/common/io.h>
33 #include <pcl/PCLPointField.h>
35 #include <QImageReader>
52 (std::int32_t,
x,
x)(std::int32_t,
54 y)(std::int32_t,
z,
z))
57 (std::int16_t,
x,
x)(std::int16_t,
59 y)(std::int16_t,
z,
z))
62 (
double,
x,
x)(
double,
y,
y)(
double,
z,
z))
64 size_t GetNumberOfPoints(
const PCLCloud& pclCloud) {
65 return static_cast<size_t>(pclCloud.width) * pclCloud.height;
69 for (
const auto& field : pclCloud.fields)
70 if (field.name ==
name)
return true;
77 size_t pointCount = GetNumberOfPoints(pclCloud);
79 pcl::PointCloud<T> pcl_cloud;
81 for (
size_t i = 0; i < pointCount; ++i) {
82 CCVector3 P(pcl_cloud.at(i).x, pcl_cloud.at(i).y, pcl_cloud.at(i).z);
90 uint8_t coordinateType) {
91 size_t pointCount = GetNumberOfPoints(pclCloud);
92 if (pointCount == 0) {
97 if (!ccCloud.
reserve(
static_cast<unsigned>(pointCount))) {
102 switch (coordinateType) {
103 case pcl::PCLPointField::INT16:
104 PCLCloudToCCCloud<PointXYZTpl<std::int16_t>>(pclCloud, ccCloud);
106 case pcl::PCLPointField::INT32:
107 PCLCloudToCCCloud<PointXYZTpl<std::int32_t>>(pclCloud, ccCloud);
109 case pcl::PCLPointField::FLOAT32:
110 PCLCloudToCCCloud<pcl::PointXYZ>(pclCloud, ccCloud);
112 case pcl::PCLPointField::FLOAT64:
113 PCLCloudToCCCloud<PointXYZTpl<double>>(pclCloud, ccCloud);
117 QString::number(coordinateType));
125 pcl::PointCloud<OnlyNormals>::Ptr pcl_cloud_normals(
126 new pcl::PointCloud<OnlyNormals>);
131 size_t pointCount = GetNumberOfPoints(pclCloud);
134 for (
size_t i = 0; i < pointCount; ++i) {
136 pcl_cloud_normals->at(i).normal_x),
138 pcl_cloud_normals->at(i).normal_y),
140 pcl_cloud_normals->at(i).normal_z));
151 pcl::PointCloud<OnlyRGB>::Ptr pcl_cloud_rgb(
new pcl::PointCloud<OnlyRGB>);
153 size_t pointCount = GetNumberOfPoints(pclCloud);
154 if (pointCount == 0)
return true;
158 for (
size_t i = 0; i < pointCount; ++i) {
171 const std::string& sfName,
173 bool overwriteIfExist ) {
177 if (overwriteIfExist)
185 size_t pointCount = GetNumberOfPoints(pclCloud);
189 if (!newSF->
reserveSafe(
static_cast<unsigned>(pointCount))) {
195 int field_index = pcl::getFieldIndex(pclCloud, sfName);
196 if (field_index < 0) {
205 switch (pclField.datatype) {
206 case PCLScalarField::FLOAT32: {
207 pcl::PointCloud<FloatScalar> pclScalar;
210 for (
unsigned i = 0; i < pointCount; ++i) {
212 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
217 case PCLScalarField::FLOAT64: {
218 pcl::PointCloud<DoubleScalar> pclScalar;
221 for (
unsigned i = 0; i < pointCount; ++i) {
223 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
228 case PCLScalarField::INT8: {
229 pcl::PointCloud<Int8Scalar> pclScalar;
232 for (
unsigned i = 0; i < pointCount; ++i) {
234 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
239 case PCLScalarField::UINT8: {
240 pcl::PointCloud<UInt8Scalar> pclScalar;
243 for (
unsigned i = 0; i < pointCount; ++i) {
245 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
250 case PCLScalarField::INT16: {
251 pcl::PointCloud<ShortScalar> pclScalar;
254 for (
unsigned i = 0; i < pointCount; ++i) {
256 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
261 case PCLScalarField::UINT16: {
262 pcl::PointCloud<UShortScalar> pclScalar;
265 for (
unsigned i = 0; i < pointCount; ++i) {
267 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
272 case PCLScalarField::UINT32: {
273 pcl::PointCloud<UIntScalar> pclScalar;
276 for (
unsigned i = 0; i < pointCount; ++i) {
278 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
283 case PCLScalarField::INT32: {
284 pcl::PointCloud<IntScalar> pclScalar;
287 for (
unsigned i = 0; i < pointCount; ++i) {
289 static_cast<ScalarType
>(pclScalar.points[i].S5c4laR);
295 CVLog::Warning(QString(
"[PCL] Field with an unmanaged type (= %1)")
296 .arg(pclField.datatype));
316 inMaterial.tex_file));
317 outMaterial->setName(inMaterial.tex_name.c_str());
321 if (QFile::exists(cPath)) {
322 QImageReader reader(cPath);
324 QImage
image = reader.read();
325 if (
image.isNull()) {
327 QString(
"[pcl2ccMaterial] failed to read image %1, %2")
329 .arg(reader.errorString()));
332 if (!
image.isNull()) {
333 outMaterial->setTexture(
image, parentPath,
false);
337 std::string texName = inMaterial.tex_name;
340 const ecvColor::Rgbaf ambientColor(inMaterial.tex_Ka.r, inMaterial.tex_Ka.g,
341 inMaterial.tex_Ka.b, inMaterial.tex_d);
342 const ecvColor::Rgbaf diffuseColor(inMaterial.tex_Kd.r, inMaterial.tex_Kd.g,
343 inMaterial.tex_Kd.b, inMaterial.tex_d);
346 inMaterial.tex_Ks.b, inMaterial.tex_d);
347 float shininess = inMaterial.tex_Ns;
349 outMaterial->setDiffuse(diffuseColor);
350 outMaterial->setAmbient(ambientColor);
351 outMaterial->setSpecular(specularColor);
353 outMaterial->setShininess(shininess);
354 outMaterial->setTransparency(inMaterial.tex_d);
355 outMaterial->setIllum(inMaterial.tex_illum);
359 if (!textureMesh || textureMesh->tex_polygons.empty()) {
364 std::size_t nr_meshes = textureMesh->tex_polygons.
size();
366 std::size_t nr_faces = 0;
367 for (std::size_t m = 0; m < nr_meshes; ++m) {
368 nr_faces += textureMesh->tex_polygons[m].size();
372 std::vector<pcl::Vertices> faces;
373 for (std::size_t i = 0; i < textureMesh->tex_polygons.size(); ++i) {
374 faces.insert(faces.end(), textureMesh->tex_polygons[i].begin(),
375 textureMesh->tex_polygons[i].end());
381 QString
name(
"texture-mesh");
387 texCoords->reserve(nr_faces);
396 CVLog::Warning(QStringLiteral(
"[pcl2cc::Convert] Cannot allocate "
397 "texture coordinates for mesh '%1'")
403 for (std::size_t m = 0; m < nr_meshes; ++m) {
404 if (textureMesh->tex_coordinates.empty())
continue;
405 for (
const auto& coordinate : textureMesh->tex_coordinates[m]) {
406 const TexCoords2D coord{coordinate[0], coordinate[1]};
414 if (!textureMesh->tex_materials.empty()) {
415 for (std::size_t m = 0; m < nr_meshes; ++m) {
420 for (std::size_t i = 0; i < textureMesh->tex_polygons[m].size();
423 for (std::size_t j = 0;
424 j < textureMesh->tex_polygons[m][i].vertices.size(); ++j) {
425 texCoordIndexes.
u[j] =
static_cast<int>(
426 textureMesh->tex_polygons[m][i].vertices[j]);
438 if (materialSet !=
nullptr) {
443 if (newMesh->
size() == 0) {
446 "[pcl2cc::Convert] Mesh '%1' does not have any faces")
454 QStringLiteral(
"[pcl2cc::Convert] Mesh '%1' does not have "
455 "normals - will compute them per vertex")
469 std::list<std::string>
fields;
470 uint8_t coordinateType = 0;
471 for (
const auto& field : pclCloud.fields) {
472 if (field.name !=
"_")
474 fields.push_back(field.name);
477 if (coordinateType == 0 &&
478 (field.name ==
"x" || field.name ==
"y" || field.name ==
"z")) {
479 coordinateType = field.datatype;
492 size_t expectedPointCount = GetNumberOfPoints(pclCloud);
493 if (expectedPointCount != 0) {
495 if (!
CopyXYZ(pclCloud, *ccCloud, coordinateType)) {
512 fields.remove(
"normal_x");
513 fields.remove(
"normal_y");
514 fields.remove(
"normal_z");
536 if (!ignoreScalars) {
546 const std::vector<pcl::Vertices>& polygons,
550 if (!vertices)
return nullptr;
558 size_t triNum = polygons.size();
564 for (
size_t i = 0; i < triNum; ++i) {
565 const pcl::Vertices& tri = polygons[i];
566 mesh->
addTriangle(tri.vertices[0], tri.vertices[1], tri.vertices[2]);
float PointCoordinateType
Type of the coordinates of a (N-D) point.
std::shared_ptr< core::Tensor > image
std::vector< PCLPointField > fields
pcl::TexMaterial PCLMaterial
pcl::PCLPointCloud2 PCLCloud
virtual void release()
Decrease counter and deletes object when 0.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Array of compressed 3D normals (single index)
Array of 2D texture coordinates.
bool isAllocated() const
Returns whether some memory has been allocated or not.
void addElement(const Type &value)
virtual bool hasNormals() const
Returns whether normals are enabled or not.
virtual void showNormals(bool state)
Sets normals visibility.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
void showNormals(bool state) override
Sets normals visibility.
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
Mesh (triangle) material.
int addMaterial(ccMaterial::CShared mat, bool allowDuplicateNames=false)
Adds a material.
Mesh (triangle) material.
QSharedPointer< ccMaterial > Shared
Shared type.
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
bool reservePerTriangleMtlIndexes()
Reserves memory to store per-triangle material index.
virtual unsigned size() const override
Returns the number of triangles.
bool hasColors() const override
Returns whether colors are enabled or not.
void addTriangleMtlIndex(int mtlIndex)
Adds triangle material index for next triangle.
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
void addTriangleTexCoordIndexes(int i1, int i2, int i3)
Adds a triplet of tex coords indexes for next triangle.
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
void setTexCoordinatesTable(TextureCoordsContainer *texCoordsTable, bool autoReleaseOldTable=true)
Sets per-triangle texture coordinates array (may be shared)
bool reservePerTriangleTexCoordIndexes()
Reserves memory to store per-triangle triplets of tex coords indexes.
void shrinkToFit()
Removes unused capacity.
bool computeNormals(bool perVertex)
Computes normals.
virtual void setLocked(bool state)
Sets the "enabled" property.
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
void addNorm(const CCVector3 &N)
Pushes a normal vector on stack (shortcut)
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool reserveTheNormsTable()
Reserves memory to store the compressed normals.
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
void deleteScalarField(int index) override
Deletes a specific scalar field.
void shrinkToFit()
Removes unused capacity.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
A scalar field associated to display-related parameters.
void computeMinAndMax() override
Determines the min and max values.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
void addElement(ScalarType value)
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
static bool CopyNormals(const PCLCloud &pclCloud, ccPointCloud &ccCloud)
static void FromPCLMaterial(const PCLMaterial &inMaterial, ccMaterial::Shared &outMaterial)
static bool CopyXYZ(const PCLCloud &pclCloud, ccPointCloud &ccCloud, uint8_t coordinateType)
static ccMesh * Convert(PCLTextureMesh::ConstPtr textureMesh)
Converts a PCL point cloud to a ccPointCloud.
static bool CopyRGB(const PCLCloud &pclCloud, ccPointCloud &ccCloud)
static bool CopyScalarField(const PCLCloud &pclCloud, const std::string &sfName, ccPointCloud &ccCloud, bool overwriteIfExist=true)
unsigned char ColorCompType
Default color components type (R,G and B)
std::string GetFileParentDirectory(const std::string &filename)
constexpr Rgbaf night(0.00f, 0.00f, 0.00f, 1.00F)
bool ExistField(const PCLCloud &pclCloud, std::string name)
pcl::PCLPointField PCLScalarField
POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZTpl< std::int32_t >,(std::int32_t, x, x)(std::int32_t, y, y)(std::int32_t, z, z)) POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZTpl< std
void PCLCloudToCCCloud(const PCLCloud &pclCloud, ccPointCloud &ccCloud)