39 mesh_msgs::MeshGeometry& mesh_geometry
41 size_t n_vertices = buffer->numVertices();
42 size_t n_faces = buffer->numFaces();
47 mesh_geometry.vertices.resize(n_vertices);
48 auto buffer_vertices = buffer->getVertices();
49 for (
unsigned int i = 0; i < n_vertices; i++)
51 mesh_geometry.vertices[i].x = buffer_vertices[i * 3];
52 mesh_geometry.vertices[i].y = buffer_vertices[i * 3 + 1];
53 mesh_geometry.vertices[i].z = buffer_vertices[i * 3 + 2];
59 auto buffer_faces = buffer->getFaceIndices();
60 mesh_geometry.faces.resize(n_faces);
61 for (
unsigned int i = 0; i < n_faces; i++)
63 mesh_geometry.faces[i].vertex_indices[0] = buffer_faces[i * 3];
64 mesh_geometry.faces[i].vertex_indices[1] = buffer_faces[i * 3 + 1];
65 mesh_geometry.faces[i].vertex_indices[2] = buffer_faces[i * 3 + 2];
69 auto buffer_vertexnormals = buffer->getVertexNormals();
70 if(buffer->hasVertexNormals())
74 mesh_geometry.vertex_normals.resize(n_vertices);
75 for (
unsigned int i = 0; i < n_vertices; i++) {
76 mesh_geometry.vertex_normals[i].x = buffer_vertexnormals[i * 3];
77 mesh_geometry.vertex_normals[i].y = buffer_vertexnormals[i * 3 + 1];
78 mesh_geometry.vertex_normals[i].z = buffer_vertexnormals[i * 3 + 2];
85 "geometry to the MeshGeometry message.");
91 mesh_msgs::MeshGeometry& mesh_geometry,
92 mesh_msgs::MeshMaterials& mesh_materials,
93 mesh_msgs::MeshVertexColors& mesh_vertex_colors,
94 boost::optional<std::vector<mesh_msgs::MeshTexture>&> texture_cache,
98 size_t n_vertices = buffer->numVertices();
99 size_t n_faces = buffer->numFaces();
120 size_t n_materials = buffer->getMaterials().size();
121 size_t n_textures = buffer->getTextures().size();
124 auto buffer_materials = buffer->getMaterials();
125 mesh_materials.materials.resize(n_materials);
126 for (
unsigned int i = 0; i < n_materials; i++)
131 mesh_materials.materials[i].color.r = m.
m_color.get()[0]/255.0;
132 mesh_materials.materials[i].color.g = m.
m_color.get()[1]/255.0;
133 mesh_materials.materials[i].color.b = m.
m_color.get()[2]/255.0;
134 mesh_materials.materials[i].color.a = 1.0;
138 mesh_materials.materials[i].color.r = 1.0;
139 mesh_materials.materials[i].color.g = 1.0;
140 mesh_materials.materials[i].color.b = 1.0;
141 mesh_materials.materials[i].color.a = 1.0;
145 mesh_materials.materials[i].has_texture =
true;
146 mesh_materials.materials[i].texture_index = (int)m.
m_texture.get().idx();
150 mesh_materials.materials[i].has_texture =
false;
151 mesh_materials.materials[i].texture_index = 0;
154 buffer_materials.clear();
168 auto buffer_texcoords = buffer->getTextureCoordinates();
170 mesh_materials.vertex_tex_coords.resize(n_vertices);
172 for (
unsigned int i = 0; i < n_vertices; i++)
174 mesh_materials.vertex_tex_coords[i].u = buffer_texcoords[i * 3];
175 mesh_materials.vertex_tex_coords[i].v = buffer_texcoords[i * 3 + 1];
180 if (buffer->hasVertexColors())
182 size_t color_channels = 3;
183 auto buffer_vertex_colors = buffer->getVertexColors(color_channels);
184 mesh_vertex_colors.vertex_colors.resize(n_vertices);
185 for (
size_t i = 0; i < n_vertices; i++)
187 mesh_vertex_colors.vertex_colors[i].r = buffer_vertex_colors[i * 3 + 0]/255.0;
188 mesh_vertex_colors.vertex_colors[i].g = buffer_vertex_colors[i * 3 + 1]/255.0;
189 mesh_vertex_colors.vertex_colors[i].b = buffer_vertex_colors[i * 3 + 2]/255.0;
190 mesh_vertex_colors.vertex_colors[i].a = 1.0;
197 auto buffer_textures = buffer->getTextures();
198 texture_cache.get().resize(n_textures);
199 for (
unsigned int i = 0; i < n_textures; i++)
201 sensor_msgs::Image image;
205 buffer_textures[i].m_height,
206 buffer_textures[i].m_width,
207 buffer_textures[i].m_width * 3,
208 buffer_textures[i].m_data
210 mesh_msgs::MeshTexture texture;
211 texture.uuid = mesh_uuid;
212 texture.texture_index = i;
213 texture.image = image;
214 texture_cache.get().at(i) = texture;
216 buffer_textures.clear();
223 const mesh_msgs::MeshGeometryConstPtr& mesh_geometry_ptr,
230 const mesh_msgs::MeshGeometryConstPtr& mesh_geometry_ptr,
238 const mesh_msgs::MeshGeometryPtr& mesh_geometry_ptr,
246 const mesh_msgs::MeshGeometryPtr& mesh_geometry_ptr,
253 const mesh_msgs::MeshGeometry& mesh_geometry,
261 const mesh_msgs::MeshGeometry& mesh_geometry,
265 const size_t numVertices = mesh_geometry.vertices.size();
267 const auto& mg_vertices = mesh_geometry.vertices;
268 for(
size_t i; i<numVertices; i++)
270 vertices[ i * 3 + 0 ] =
static_cast<float>(mg_vertices[i].x);
271 vertices[ i * 3 + 1 ] =
static_cast<float>(mg_vertices[i].y);
272 vertices[ i * 3 + 2 ] =
static_cast<float>(mg_vertices[i].z);
276 const size_t numFaces = mesh_geometry.faces.size();
278 const auto& mg_faces = mesh_geometry.faces;
279 for(
size_t i; i<numFaces; i++)
281 faces[ i * 3 + 0 ] = mg_faces[i].vertex_indices[0];
282 faces[ i * 3 + 1 ] = mg_faces[i].vertex_indices[1];
283 faces[ i * 3 + 2 ] = mg_faces[i].vertex_indices[2];
287 const size_t numNormals = mesh_geometry.vertex_normals.size();
289 const auto& mg_normals = mesh_geometry.vertex_normals;
290 for(
size_t i; i<numNormals; i++)
292 normals[ i * 3 + 0 ] =
static_cast<float>(mg_normals[i].x);
293 normals[ i * 3 + 1 ] =
static_cast<float>(mg_normals[i].y);
294 normals[ i * 3 + 2 ] =
static_cast<float>(mg_normals[i].z);
312 buffer_ptr = model->m_mesh;
375 static inline bool hasCloudChannel(
const sensor_msgs::PointCloud2& cloud,
const std::string& field_name)
378 for (
size_t d = 0;
d < cloud.fields.size(); ++
d)
379 if (cloud.fields[
d].name == field_name)
386 size_t size = cloud.height * cloud.width;
391 std::list<int> filter_nan;
394 CloudIterFloat iter_x_filter(cloud,
"x");
395 CloudIterFloat iter_y_filter(cloud,
"y");
396 CloudIterFloat iter_z_filter(cloud,
"z");
400 for (
int i = 0; iter_x_filter != iter_x_filter.end();
401 ++iter_x_filter, ++iter_y_filter, ++iter_z_filter, i++)
403 if( !std::isnan(*iter_x_filter) &&
404 !std::isnan(*iter_y_filter) &&
405 !std::isnan(*iter_z_filter))
411 filter_nan.push_back(i);
420 CloudIterFloat iter_x(cloud,
"x");
421 CloudIterFloat iter_y(cloud,
"y");
422 CloudIterFloat iter_z(cloud,
"z");
425 std::list<int> tmp_filter = filter_nan;
427 for (i = 0, index = 0;
428 iter_x != iter_x.end();
429 ++iter_x, ++iter_y, ++iter_z,
433 if (!tmp_filter.empty() && index == tmp_filter.front())
435 tmp_filter.pop_front();
440 pointData[i] = *iter_x;
441 pointData[i + 1] = *iter_y;
442 pointData[i + 2] = *iter_z;
450 bool normalsAvailable =
455 if (normalsAvailable)
457 CloudIterFloat iter_n_x(cloud,
"normal_x");
458 CloudIterFloat iter_n_y(cloud,
"normal_y");
459 CloudIterFloat iter_n_z(cloud,
"normal_z");
461 tmp_filter = filter_nan;
463 for (i = 0, index = 0;
464 iter_n_x != iter_n_x.end();
465 ++iter_n_x, ++iter_n_y, ++iter_n_z,
469 if (!tmp_filter.empty() && index == tmp_filter.front())
471 tmp_filter.pop_front();
476 normalsData[i] = *iter_n_x;
477 normalsData[i + 1] = *iter_n_y;
478 normalsData[i + 2] = *iter_n_z;
488 CloudIterUInt8 iter_rgb(cloud,
"rgb");
490 tmp_filter = filter_nan;
492 for (i = 0, index = 0; iter_rgb != iter_rgb.end();
496 if (!tmp_filter.empty() && index == tmp_filter.front())
498 tmp_filter.pop_front();
503 colorData[i] = iter_rgb[0];
504 colorData[i + 1] = iter_rgb[1];
505 colorData[i + 2] = iter_rgb[2];
515 CloudIterFloat iter_int(cloud,
"intensities");
517 tmp_filter = filter_nan;
519 for (i = 0, index = 0; iter_int != iter_int.end();
523 if (!tmp_filter.empty() && index == tmp_filter.front())
525 tmp_filter.pop_front();
530 intensityData[i] = *iter_int;
539 const mesh_msgs::MeshGeometry& mesh_geometry,
544 lvr2::floatArr vertices(
new float[mesh_geometry.vertices.size() * 3]);
546 for (
auto vertex : mesh_geometry.vertices)
548 vertices[i] =
static_cast<float>(vertex.x);
549 vertices[i+1] =
static_cast<float>(vertex.y);
550 vertices[i+2] =
static_cast<float>(vertex.z);
553 buffer->setVertices(vertices, mesh_geometry.vertices.size());
558 for (
auto face : mesh_geometry.faces)
560 faces[i] = face.vertex_indices[0];
561 faces[i+1] = face.vertex_indices[1];
562 faces[i+2] = face.vertex_indices[2];
565 buffer->setFaceIndices(faces, mesh_geometry.faces.size() * 3);
567 if(mesh_geometry.vertex_normals.size() == mesh_geometry.vertices.size())
570 lvr2::floatArr normals(
new float[mesh_geometry.vertex_normals.size() * 3]);
572 for (
auto normal : mesh_geometry.vertex_normals)
574 normals[i] =
static_cast<float>(normal.x);
575 normals[i+1] =
static_cast<float>(normal.y);
576 normals[i+2] =
static_cast<float>(normal.z);
579 buffer->setVertexNormals(normals);
583 ROS_ERROR_STREAM(
"Number of normals (" << mesh_geometry.vertex_normals.size()
584 <<
") must be equal to number of vertices (" << mesh_geometry.vertices.size()
585 <<
"), ignore normals!");
594 cloud->header.frame_id = frame;
599 std::map<std::string, lvr2::Channel<float> > floatChannels;
600 type = buffer->getAllChannelsOfType<
float>(floatChannels);
601 std::map<std::string, lvr2::Channel<unsigned char> > uCharChannels;
602 int ucharType = buffer->getAllChannelsOfType<
unsigned char>(uCharChannels);
606 int offset = 4 *
sizeof(float);
608 for(
auto channelPair: floatChannels)
612 if(channelPair.first ==
"points")
614 size = channelPair.second.numElements();
616 p_offset = addPointField(*cloud,
"x", 1, sensor_msgs::PointField::FLOAT32, p_offset);
617 p_offset = addPointField(*cloud,
"y", 1, sensor_msgs::PointField::FLOAT32, p_offset);
618 p_offset = addPointField(*cloud,
"z", 1, sensor_msgs::PointField::FLOAT32, p_offset);
619 p_offset +=
sizeof(float);
620 cloud->point_step = offset;
621 for(
auto channelPair: uCharChannels)
623 if(channelPair.first ==
"colors")
626 offset = addPointField(*cloud,
"rgb", channelPair.second.width(), sensor_msgs::PointField::FLOAT32, offset);
627 cloud->point_step = offset;
634 offset = addPointField(*cloud, channelPair.first, channelPair.second.width(), type + 1, offset);
637 cloud->point_step = offset;
650 std::map<std::string, lvr2::Channel<int> > intChannels;
651 type = buffer->getAllChannelsOfType<
int>(intChannels);
652 for(
auto channelPair: intChannels)
657 offset = addPointField(*cloud, channelPair.first, channelPair.second.width(), type + 1, offset);
660 cloud->point_step = offset;
665 cloud->data.resize(size * cloud->point_step);
672 for(
auto field: cloud->fields)
675 if(field.name ==
"x" || field.name ==
"y" || field.name ==
"z")
677 auto channel = floatChannels.at(
"points");
681 #pragma omp parallel for 682 for(
size_t i = 0; i < size; ++i)
684 unsigned char* ptr = &(cloud->data[cloud->point_step * i]);
685 *(
reinterpret_cast<float*
>(ptr)) = channel[i][0];
686 *((
reinterpret_cast<float*
>(ptr)) + 1) = channel[i][1];
687 *((
reinterpret_cast<float*
>(ptr)) + 2) = channel[i][2];
696 if(field.datatype == sensor_msgs::PointField::FLOAT32)
698 std::string name = field.name;
702 auto channel = uCharChannels.at(name);
704 #pragma omp parallel for 705 for(
size_t i = 0; i < size; ++i)
707 unsigned char* ptr = &(cloud->data[cloud->point_step * i]) + field.offset;
708 *(ptr + 2) = channel[i][0];
709 *(ptr + 1) = channel[i][1];
710 *(ptr + 0) = channel[i][2];
721 auto channel = floatChannels.at(field.name);
723 #pragma omp parallel for 724 for(
size_t i = 0; i < size; ++i)
726 unsigned char* ptr = &(cloud->data[cloud->point_step * i]) + field.offset;
727 for(
size_t j = 0; j < field.count; ++j)
729 *((
reinterpret_cast<float*
>(ptr)) + j) = channel[i][j];
734 else if (field.datatype == sensor_msgs::PointField::UINT8)
746 for(
auto field : cloud->fields)
748 if(field.datatype == sensor_msgs::PointField::FLOAT32)
750 if(field.name ==
"x" || field.name ==
"y" || field.name ==
"z")
752 if(!buffer->hasFloatChannel(
"points"))
754 buffer->addEmptyChannel<
float>(
"points", cloud->width * cloud->height, 3);
759 buffer->addEmptyChannel<
float>(field.name, cloud->width * cloud->height, field.count);
765 for(
auto field: cloud->fields)
768 if(field.name ==
"x" || field.name ==
"y" || field.name ==
"z")
770 auto channel = buffer->getChannel<
float>(
"points");
773 std::cout <<
"already init" << std::endl;
777 lvr2::floatArr points(
new float[cloud->width * cloud->height * 3]);
778 buffer->setPointArray(points, cloud->width * cloud->height);
779 channel = buffer->getChannel<
float>(
"points");
781 #pragma omp parallel for 782 for(
size_t i = 0; i < (cloud->width * cloud->height); ++i)
784 unsigned char* ptr = &(cloud->data[cloud->point_step * i]);
785 (*channel)[i][0] = *(
reinterpret_cast<float*
>(ptr));
786 (*channel)[i][1] = *((
reinterpret_cast<float*
>(ptr)) + 1);
787 (*channel)[i][2] = *((
reinterpret_cast<float*
>(ptr)) + 2);
793 if(field.datatype == sensor_msgs::PointField::FLOAT32)
795 auto channel = buffer->getChannel<
float>(field.name);
799 ROS_INFO(
"Channel %s missing", field.name.c_str());
803 #pragma omp parallel for 804 for(
size_t i = 0; i < (cloud->width * cloud->height); ++i)
806 unsigned char* ptr = &(cloud->data[cloud->point_step * i]) + field.offset;
807 for(
size_t j = 0; j < field.count; ++j)
809 (*channel)[i][j] = *((
reinterpret_cast<float*
>(ptr)) + j);
813 else if (field.datatype == sensor_msgs::PointField::UINT8)
815 auto channel = buffer->getChannel<
unsigned char>(field.name);
819 ROS_INFO(
"Channel %s missing", field.name.c_str());
823 #pragma omp parallel for 824 for(
size_t i = 0; i < (cloud->width * cloud->height); ++i)
826 unsigned char* ptr = &(cloud->data[cloud->point_step * i]) + field.offset;
827 for(
size_t j = 0; j < field.count; ++j)
829 (*channel)[i][j] = *(ptr + j);
static bool fillImage(Image &image, const std::string &encoding_arg, uint32_t rows_arg, uint32_t cols_arg, uint32_t step_arg, const void *data_arg)
void setFaceIndices(indexArray indices, size_t n)
void setNormalArray(floatArr normals, size_t n)
std::shared_ptr< MeshBuffer > MeshBufferPtr
bool fromMeshGeometryMessageToMeshBuffer(const mesh_msgs::MeshGeometry &mesh_geometry, const lvr2::MeshBufferPtr &buffer)
Convert mesh_msgs::MeshGeometry to lvr2::MeshBuffer.
bool fromMeshGeometryToMeshBuffer(const mesh_msgs::MeshGeometryConstPtr &mesh_geometry_ptr, lvr2::MeshBufferPtr &buffer_ptr)
static bool hasCloudChannel(const sensor_msgs::PointCloud2 &cloud, const std::string &field_name)
static ModelPtr readModel(std::string filename)
bool fromPointCloud2ToPointBuffer(const sensor_msgs::PointCloud2 &cloud, PointBuffer &buffer)
std::shared_ptr< PointBuffer > PointBufferPtr
void addFloatChannel(FloatChannelPtr data, const std::string &name)
void setPointArray(floatArr points, size_t n)
bool writeMeshBuffer(lvr2::MeshBufferPtr &mesh, string path)
Writes a LVR-MeshBufferPointer to a file.
#define ROS_DEBUG_STREAM(args)
void setVertexNormals(floatArr normals)
bool fromMeshBufferToMeshMessages(const lvr2::MeshBufferPtr &buffer, mesh_msgs::MeshGeometry &mesh_geometry, mesh_msgs::MeshMaterials &mesh_materials, mesh_msgs::MeshVertexColors &mesh_vertex_colors, boost::optional< std::vector< mesh_msgs::MeshTexture > &> texture_cache, std::string mesh_uuid)
Convert lvr2::MeshBuffer to various messages for services.
std::shared_ptr< Model > ModelPtr
bool fromMeshBufferToMeshGeometryMessage(const lvr2::MeshBufferPtr &buffer, mesh_msgs::MeshGeometry &mesh_geometry)
bool readMeshBuffer(lvr2::MeshBufferPtr &buffer, string path)
Creates a LVR-MeshBufferPointer from a file.
void PointCloud2ToPointBuffer(const sensor_msgs::PointCloud2Ptr &cloud, lvr2::PointBufferPtr &buffer)
converts pointcloud2 to a newly created Pointerbuffer. Every pointfield is written into its own chann...
boost::optional< Rgb8Color > m_color
void setColorArray(ucharArr colors, size_t n, size_t width=3)
void PointBufferToPointCloud2(const lvr2::PointBufferPtr &buffer, std::string frame, sensor_msgs::PointCloud2Ptr &cloud)
converts lvr2::Pointbuffer to pointcloud2. Every channel is added as a pointfield.
boost::optional< TextureHandle > m_texture
#define ROS_ERROR_STREAM(args)
void setVertices(floatArr vertices, size_t n)
static void saveModel(ModelPtr m, std::string file)