8 #ifndef CORELIB_INCLUDE_RTABMAP_CORE_IMPL_UTIL3D_SURFACE_HPP_ 9 #define CORELIB_INCLUDE_RTABMAP_CORE_IMPL_UTIL3D_SURFACE_HPP_ 11 #include <pcl/search/kdtree.h> 18 template<
typename po
intT>
20 const typename pcl::PointCloud<pointT> & cloud,
21 const std::vector<pcl::Vertices> & polygons,
22 const pcl::PointXYZ & viewPoint)
24 std::vector<pcl::Vertices> output(polygons.size());
25 for(
unsigned int i=0; i<polygons.size(); ++i)
27 pcl::Vertices polygon = polygons[i];
28 Eigen::Vector3f v1 = cloud.at(polygon.vertices[1]).getVector3fMap() - cloud.at(polygon.vertices[0]).getVector3fMap();
29 Eigen::Vector3f v2 = cloud.at(polygon.vertices[2]).getVector3fMap() - cloud.at(polygon.vertices[0]).getVector3fMap();
30 Eigen::Vector3f n = (v1.cross(v2)).normalized();
32 Eigen::Vector3f p = Eigen::Vector3f(viewPoint.x, viewPoint.y, viewPoint.z) - cloud.at(polygon.vertices[1]).getVector3fMap();
34 float result = n.dot(p);
38 int tmp = polygon.vertices[0];
39 polygon.vertices[0] = polygon.vertices[2];
40 polygon.vertices[2] = tmp;
48 template<
typename po
intRGBT>
50 pcl::PolygonMeshPtr & mesh,
51 float meshDecimationFactor,
53 const typename pcl::PointCloud<pointRGBT>::Ptr & cloud,
54 float transferColorRadius,
61 bool hasNormals =
false;
62 bool hasColors =
false;
63 for(
unsigned int i=0; i<mesh->cloud.fields.size(); ++i)
65 if(mesh->cloud.fields[i].name.compare(
"normal_x") == 0)
69 else if(mesh->cloud.fields[i].name.compare(
"rgb") == 0)
75 if(maximumPolygons > 0)
77 double factor = 1.0-double(maximumPolygons)/double(mesh->polygons.size());
78 if(factor > meshDecimationFactor)
80 meshDecimationFactor = factor;
83 if(meshDecimationFactor > 0.0)
85 unsigned int count = mesh->polygons.size();
86 if(progressState) progressState->
callback(
uFormat(
"Mesh decimation (factor=%f) from %d polygons...",meshDecimationFactor, (
int)count));
89 if(progressState) progressState->
callback(
uFormat(
"Mesh decimated (factor=%f) from %d to %d polygons", meshDecimationFactor, (
int)count, (
int)mesh->polygons.size()));
90 if(count < mesh->polygons.size())
92 if(progressState) progressState->
callback(
uFormat(
"Decimated mesh has more polygons than before!"));
100 transferColorRadius >= 0.0)
102 if(progressState) progressState->
callback(
uFormat(
"Transferring color from point cloud to mesh..."));
105 typename pcl::search::KdTree<pointRGBT>::Ptr
tree (
new pcl::search::KdTree<pointRGBT>(
true));
106 tree->setInputCloud(cloud);
107 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr coloredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
108 pcl::fromPCLPointCloud2(mesh->cloud, *coloredCloud);
109 std::vector<bool> coloredPts(coloredCloud->size());
110 for(
unsigned int i=0; i<coloredCloud->size(); ++i)
113 std::vector<float> kDistances;
115 pt.x = coloredCloud->at(i).x;
116 pt.y = coloredCloud->at(i).y;
117 pt.z = coloredCloud->at(i).z;
118 if(transferColorRadius > 0.0)
120 tree->radiusSearch(pt, transferColorRadius, kIndices, kDistances);
124 tree->nearestKSearch(pt, 1, kIndices, kDistances);
133 for(
unsigned int j=0; j<kIndices.size(); ++j)
135 r+=(int)cloud->at(kIndices[j]).r;
136 g+=(int)cloud->at(kIndices[j]).g;
137 b+=(int)cloud->at(kIndices[j]).b;
138 a+=(int)cloud->at(kIndices[j]).a;
140 coloredCloud->at(i).r = r/kIndices.size();
141 coloredCloud->at(i).g = g/kIndices.size();
142 coloredCloud->at(i).b = b/kIndices.size();
143 coloredCloud->at(i).a = a/kIndices.size();
144 coloredPts.at(i) =
true;
149 coloredCloud->at(i).r = coloredCloud->at(i).g = coloredCloud->at(i).b = 255;
150 coloredPts.at(i) =
false;
153 pcl::toPCLPointCloud2(*coloredCloud, mesh->cloud);
158 std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
160 for(
unsigned int i=0; i<mesh->polygons.size(); ++i)
162 bool coloredPolygon =
true;
163 for(
unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
165 if(!coloredPts.at(mesh->polygons[i].vertices[j]))
167 coloredPolygon =
false;
173 filteredPolygons[oi++] = mesh->polygons[i];
176 filteredPolygons.resize(oi);
177 mesh->polygons = filteredPolygons;
184 if(progressState) progressState->
callback(
uFormat(
"Filter small polygon clusters..."));
187 std::vector<std::set<int> > neighbors;
188 std::vector<std::set<int> > vertexToPolygons;
190 mesh->cloud.height*mesh->cloud.width,
195 minClusterSize<0?0:minClusterSize);
197 std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
198 if(minClusterSize < 0)
201 std::list<std::list<int> >::iterator biggestClusterIndex = clusters.end();
202 unsigned int biggestClusterSize = 0;
203 for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
205 if(iter->size() > biggestClusterSize)
207 biggestClusterIndex = iter;
208 biggestClusterSize = iter->size();
211 if(biggestClusterIndex != clusters.end())
214 for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
216 filteredPolygons[oi++] = mesh->polygons.at(*jter);
218 filteredPolygons.resize(oi);
224 for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
226 for(std::list<int>::iterator jter=iter->begin(); jter!=iter->end(); ++jter)
228 filteredPolygons[oi++] = mesh->polygons.at(*jter);
231 filteredPolygons.resize(oi);
234 int before = (int)mesh->polygons.size();
235 mesh->polygons = filteredPolygons;
237 if(progressState) progressState->
callback(
uFormat(
"Filtered %d polygons.", before-(
int)mesh->polygons.size()));
241 if(!hasNormals || (!hasColors && coloredOutput))
244 if(hasColors || coloredOutput)
246 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud (
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
247 pcl::fromPCLPointCloud2(mesh->cloud, *cloud);
249 Eigen::Vector3f normal(1,0,0);
250 for(
unsigned int i=0; i<mesh->polygons.size(); ++i)
252 pcl::Vertices & v = mesh->polygons[i];
257 cloud->at(v.vertices[1]).x - cloud->at(v.vertices[0]).x,
258 cloud->at(v.vertices[1]).y - cloud->at(v.vertices[0]).y,
259 cloud->at(v.vertices[1]).z - cloud->at(v.vertices[0]).z);
260 int last = v.vertices.size()-1;
262 cloud->at(v.vertices[last]).x - cloud->at(v.vertices[0]).x,
263 cloud->at(v.vertices[last]).y - cloud->at(v.vertices[0]).y,
264 cloud->at(v.vertices[last]).z - cloud->at(v.vertices[0]).z);
265 normal = v0.cross(v1);
269 for(
unsigned int j=0; j<v.vertices.size(); ++j)
273 cloud->at(v.vertices[j]).normal_x = normal[0];
274 cloud->at(v.vertices[j]).normal_y = normal[1];
275 cloud->at(v.vertices[j]).normal_z = normal[2];
279 cloud->at(v.vertices[j]).r = 255;
280 cloud->at(v.vertices[j]).g = 255;
281 cloud->at(v.vertices[j]).b = 255;
285 pcl::toPCLPointCloud2 (*cloud, mesh->cloud);
289 pcl::PointCloud<pcl::PointNormal>::Ptr cloud (
new pcl::PointCloud<pcl::PointNormal>);
290 pcl::fromPCLPointCloud2(mesh->cloud, *cloud);
292 for(
unsigned int i=0; i<mesh->polygons.size(); ++i)
294 pcl::Vertices & v = mesh->polygons[i];
297 cloud->at(v.vertices[1]).x - cloud->at(v.vertices[0]).x,
298 cloud->at(v.vertices[1]).y - cloud->at(v.vertices[0]).y,
299 cloud->at(v.vertices[1]).z - cloud->at(v.vertices[0]).z);
300 int last = v.vertices.size()-1;
302 cloud->at(v.vertices[last]).x - cloud->at(v.vertices[0]).x,
303 cloud->at(v.vertices[last]).y - cloud->at(v.vertices[0]).y,
304 cloud->at(v.vertices[last]).z - cloud->at(v.vertices[0]).z);
305 Eigen::Vector3f normal = v0.cross(v1);
308 for(
unsigned int j=0; j<v.vertices.size(); ++j)
310 cloud->at(v.vertices[j]).normal_x = normal[0];
311 cloud->at(v.vertices[j]).normal_y = normal[1];
312 cloud->at(v.vertices[j]).normal_z = normal[2];
315 pcl::toPCLPointCloud2 (*cloud, mesh->cloud);
void denseMeshPostProcessing(pcl::PolygonMeshPtr &mesh, float meshDecimationFactor, int maximumPolygons, const typename pcl::PointCloud< pointRGBT >::Ptr &cloud, float transferColorRadius, bool coloredOutput, bool cleanMesh, int minClusterSize, ProgressState *progressState)
Some conversion functions.
#define UASSERT(condition)
virtual bool callback(const std::string &msg) const
std::list< std::list< int > > RTABMAP_EXP clusterPolygons(const std::vector< std::set< int > > &neighborPolygons, int minClusterSize=0)
pcl::PolygonMesh::Ptr RTABMAP_EXP meshDecimation(const pcl::PolygonMesh::Ptr &mesh, float factor)
std::vector< pcl::Vertices > normalizePolygonsSide(const typename pcl::PointCloud< pointT > &cloud, const std::vector< pcl::Vertices > &polygons, const pcl::PointXYZ &viewPoint)
void RTABMAP_EXP createPolygonIndexes(const std::vector< pcl::Vertices > &polygons, int cloudSize, std::vector< std::set< int > > &neighborPolygons, std::vector< std::set< int > > &vertexPolygons)
Given a set of polygons, create two indexes: polygons to neighbor polygons and vertices to polygons...
static const GLushort kIndices[]
std::string UTILITE_EXP uFormat(const char *fmt,...)