mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Export dialog: hiding not used options, exporting can be now canceled on texturing phase
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
|
||||
#include <pcl/common/distances.h>
|
||||
#include <pcl18/surface/texture_mapping.h>
|
||||
#include <pcl/search/octree.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PointInT> std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> >
|
||||
@@ -1012,17 +1013,20 @@ class FaceInfo
|
||||
{
|
||||
public:
|
||||
FaceInfo(float d,
|
||||
bool facingCam,
|
||||
const pcl::PointXY & uv1,
|
||||
const pcl::PointXY & uv2,
|
||||
const pcl::PointXY & uv3,
|
||||
const pcl::PointXY & center) :
|
||||
distance(d),
|
||||
facingTheCam(facingCam),
|
||||
uv_coord1(uv1),
|
||||
uv_coord2(uv2),
|
||||
uv_coord3(uv3),
|
||||
uv_center(center)
|
||||
{}
|
||||
float distance;
|
||||
bool facingTheCam;
|
||||
pcl::PointXY uv_coord1;
|
||||
pcl::PointXY uv_coord2;
|
||||
pcl::PointXY uv_coord3;
|
||||
@@ -1039,12 +1043,15 @@ bool ptInTriangle(const pcl::PointXY & p0, const pcl::PointXY & p1, const pcl::P
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PointInT> void
|
||||
pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh &mesh, const pcl::texture_mapping::CameraVector &cameras)
|
||||
template<typename PointInT> bool
|
||||
pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (
|
||||
pcl::TextureMesh &mesh,
|
||||
const pcl::texture_mapping::CameraVector &cameras,
|
||||
const ProgressState * state)
|
||||
{
|
||||
|
||||
if (mesh.tex_polygons.size () != 1)
|
||||
return;
|
||||
return false;
|
||||
|
||||
typename pcl::PointCloud<PointInT>::Ptr mesh_cloud (new pcl::PointCloud<PointInT>);
|
||||
|
||||
@@ -1061,10 +1068,10 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh
|
||||
// pre compute all cam inverse and visibility
|
||||
std::vector<std::map<int, FaceInfo > > visibleFaces(cameras.size());
|
||||
std::vector<Eigen::Affine3f> invCamTransform(cameras.size());
|
||||
UDEBUG("Precompute visible faces per cam");
|
||||
UINFO("Precompute visible faces per cam (%d faces, %d cams)", (int)faces.size(), (int)cameras.size());
|
||||
for (unsigned int current_cam = 0; current_cam < cameras.size(); ++current_cam)
|
||||
{
|
||||
UINFO("Processing camera %d...", current_cam);
|
||||
UDEBUG("Texture camera %d...", current_cam);
|
||||
|
||||
typename pcl::PointCloud<PointInT>::Ptr camera_cloud (new pcl::PointCloud<PointInT>);
|
||||
pcl::transformPointCloud(*mesh_cloud, *camera_cloud, cameras[current_cam].pose.inverse());
|
||||
@@ -1072,36 +1079,53 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh
|
||||
std::vector<int> visibilityIndices;
|
||||
visibilityIndices.resize (faces.size ());
|
||||
pcl::PointCloud<pcl::PointXY>::Ptr projections (new pcl::PointCloud<pcl::PointXY>);
|
||||
projections->resize(faces.size()*3);
|
||||
std::map<float, int> sortedVisibleFaces;
|
||||
int oi=0;
|
||||
for(unsigned int idx_face=0; idx_face<faces.size(); ++idx_face)
|
||||
{
|
||||
pcl::Vertices & face = faces[idx_face];
|
||||
pcl::PointXY uv_coords[3];
|
||||
|
||||
int j=oi*3;
|
||||
pcl::PointXY & uv_coords1 = projections->at(j);
|
||||
pcl::PointXY & uv_coords2 = projections->at(j+1);
|
||||
pcl::PointXY & uv_coords3 = projections->at(j+2);
|
||||
PointInT & pt0 = camera_cloud->points[face.vertices[0]];
|
||||
PointInT & pt1 = camera_cloud->points[face.vertices[1]];
|
||||
PointInT & pt2 = camera_cloud->points[face.vertices[2]];
|
||||
float angle;
|
||||
if (isFaceProjected (cameras[current_cam],
|
||||
pt0,
|
||||
pt1,
|
||||
pt2,
|
||||
uv_coords[0],
|
||||
uv_coords[1],
|
||||
uv_coords[2],
|
||||
angle))
|
||||
uv_coords1,
|
||||
uv_coords2,
|
||||
uv_coords3))
|
||||
{
|
||||
// check if the polygon is facing the camera, assuming counterclockwise normal
|
||||
Eigen::Vector3f v0(
|
||||
pt1.x - pt0.x,
|
||||
pt1.y - pt0.y,
|
||||
pt1.z - pt0.z);
|
||||
Eigen::Vector3f v1(
|
||||
pt2.x - pt0.x,
|
||||
pt2.y - pt0.y,
|
||||
pt2.z - pt0.z);
|
||||
Eigen::Vector3f normal = v0.cross(v1);
|
||||
float angle = normal.dot(Eigen::Vector3f(0.0f,0.0f,-1.0f));
|
||||
bool facingTheCam = angle>0.0f;
|
||||
|
||||
float distanceToCam = std::min(std::min(pt0.z, pt1.z), pt2.z);
|
||||
pcl::PointXY center;
|
||||
center.x = (uv_coords[0].x+uv_coords[1].x+uv_coords[2].x)/3.0f;
|
||||
center.y = (uv_coords[0].y+uv_coords[1].y+uv_coords[2].y)/3.0f;
|
||||
visibleFaces[current_cam].insert(std::make_pair(idx_face, FaceInfo(distanceToCam, uv_coords[0], uv_coords[1], uv_coords[2], center)));
|
||||
visibilityIndices[oi++] = idx_face;
|
||||
projections->push_back(uv_coords[0]);
|
||||
projections->push_back(uv_coords[1]);
|
||||
projections->push_back(uv_coords[2]);
|
||||
center.x = (uv_coords1.x+uv_coords2.x+uv_coords3.x)/3.0f;
|
||||
center.y = (uv_coords1.y+uv_coords2.y+uv_coords3.y)/3.0f;
|
||||
visibleFaces[current_cam].insert(visibleFaces[current_cam].end(), std::make_pair(idx_face, FaceInfo(distanceToCam, facingTheCam, uv_coords1, uv_coords2, uv_coords3, center)));
|
||||
sortedVisibleFaces.insert(std::make_pair(distanceToCam, idx_face));
|
||||
visibilityIndices[oi] = idx_face;
|
||||
++oi;
|
||||
}
|
||||
}
|
||||
visibilityIndices.resize(oi);
|
||||
projections->resize(oi*3);
|
||||
UASSERT(projections->size() == visibilityIndices.size()*3);
|
||||
|
||||
//filter occluded polygons
|
||||
@@ -1115,9 +1139,11 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh
|
||||
// then (idx_pcam == current_cam), check for self occlusions. At this stage, we skip faces that were already marked as occluded
|
||||
// project all faces
|
||||
int occludedFaces = 0;
|
||||
for (unsigned int idx_vis = 0; idx_vis < visibilityIndices.size(); ++idx_vis)
|
||||
for (std::map<float, int>::iterator jter=sortedVisibleFaces.begin(); jter!=sortedVisibleFaces.end(); ++jter)
|
||||
//for (unsigned int idx = 0; idx<visibilityIndices.size(); ++idx)
|
||||
{
|
||||
int idx_face = visibilityIndices[idx_vis];
|
||||
int idx_face = jter->second;
|
||||
//int idx_face = visibilityIndices[idx];
|
||||
std::map<int, FaceInfo>::iterator iter= visibleFaces[current_cam].find(idx_face);
|
||||
if(iter != visibleFaces[current_cam].end())
|
||||
{
|
||||
@@ -1210,13 +1236,36 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh
|
||||
}
|
||||
}
|
||||
|
||||
UDEBUG("Filtered %d occluded and %d spurious polygons out of %d...", occludedFaces, clusterFaces, (int)visibilityIndices.size());
|
||||
std::string msg = uFormat("Processed camera %d/%d: %d occluded and %d spurious polygons out of %d", (int)current_cam+1, (int)cameras.size(), occludedFaces, clusterFaces, (int)visibilityIndices.size());
|
||||
UINFO(msg.c_str());
|
||||
if(state && !state->callback(msg))
|
||||
{
|
||||
//cancelled!
|
||||
UWARN("Texturing cancelled!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UDEBUG("Process %d polygons...", (int)faces.size());
|
||||
std::string msg = uFormat("Texturing %d polygons...", (int)faces.size());
|
||||
UINFO(msg.c_str());
|
||||
if(state && !state->callback(msg))
|
||||
{
|
||||
//cancelled!
|
||||
UWARN("Texturing cancelled!");
|
||||
return false;
|
||||
}
|
||||
for(unsigned int idx_face=0; idx_face<faces.size(); ++idx_face)
|
||||
{
|
||||
UDEBUG("face %d", idx_face);
|
||||
if((idx_face+1)%1000 == 0)
|
||||
{
|
||||
UDEBUG("face %d/%d", idx_face+1, (int)faces.size());
|
||||
if(state && !state->callback(""))
|
||||
{
|
||||
//cancelled!
|
||||
UWARN("Texturing cancelled!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pcl::Vertices & face = faces[idx_face];
|
||||
|
||||
int cameraIndex = -1;
|
||||
@@ -1225,7 +1274,7 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh
|
||||
for (unsigned int current_cam = 0; current_cam < cameras.size(); ++current_cam)
|
||||
{
|
||||
std::map<int, FaceInfo>::iterator iter = visibleFaces[current_cam].find(idx_face);
|
||||
if (iter != visibleFaces[current_cam].end())
|
||||
if (iter != visibleFaces[current_cam].end() && iter->second.facingTheCam)
|
||||
{
|
||||
float distanceToCam = iter->second.distance;
|
||||
|
||||
@@ -1244,35 +1293,21 @@ pcl::TextureMapping<PointInT>::textureMeshwithMultipleCameras2 (pcl::TextureMesh
|
||||
|
||||
if(cameraIndex >= 0)
|
||||
{
|
||||
if(mesh.tex_polygons[cameraIndex].capacity() < mesh.tex_polygons[cameraIndex].size()+1)
|
||||
{
|
||||
mesh.tex_polygons[cameraIndex].reserve(mesh.tex_polygons[cameraIndex].size()+10);
|
||||
}
|
||||
mesh.tex_polygons[cameraIndex].push_back(face);
|
||||
if(mesh.tex_coordinates[cameraIndex].capacity() < mesh.tex_coordinates[cameraIndex].size()+3)
|
||||
{
|
||||
mesh.tex_coordinates[cameraIndex].reserve(mesh.tex_coordinates[cameraIndex].size()+30);
|
||||
}
|
||||
mesh.tex_coordinates[cameraIndex].push_back(Eigen::Vector2f(uv_coords[0].x, uv_coords[0].y));
|
||||
mesh.tex_coordinates[cameraIndex].push_back(Eigen::Vector2f(uv_coords[1].x, uv_coords[1].y));
|
||||
mesh.tex_coordinates[cameraIndex].push_back(Eigen::Vector2f(uv_coords[2].x, uv_coords[2].y));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mesh.tex_polygons[cameras.size()].capacity() < mesh.tex_polygons[cameras.size()].size()+1)
|
||||
{
|
||||
mesh.tex_polygons[cameras.size()].reserve(mesh.tex_polygons[cameras.size()].size()+10);
|
||||
}
|
||||
mesh.tex_polygons[cameras.size()].push_back(face);
|
||||
if(mesh.tex_coordinates[cameras.size()].capacity() < mesh.tex_coordinates[cameras.size()].size()+3)
|
||||
{
|
||||
mesh.tex_coordinates[cameras.size()].reserve(mesh.tex_coordinates[cameras.size()].size()+30);
|
||||
}
|
||||
mesh.tex_coordinates[cameras.size()].push_back(Eigen::Vector2f(-1.0,-1.0));
|
||||
mesh.tex_coordinates[cameras.size()].push_back(Eigen::Vector2f(-1.0,-1.0));
|
||||
mesh.tex_coordinates[cameras.size()].push_back(Eigen::Vector2f(-1.0,-1.0));
|
||||
}
|
||||
}
|
||||
UINFO("Process %d polygons...done!", (int)faces.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1396,28 +1431,13 @@ pcl::TextureMapping<PointInT>::checkPointInsideTriangle(const pcl::PointXY &p1,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename PointInT> inline bool
|
||||
pcl::TextureMapping<PointInT>::isFaceProjected (const Camera &camera, const PointInT &p1, const PointInT &p2, const PointInT &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3, float & angle)
|
||||
pcl::TextureMapping<PointInT>::isFaceProjected (const Camera &camera, const PointInT &p1, const PointInT &p2, const PointInT &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3)
|
||||
{
|
||||
// check if the polygon is facing the camera, assuming counterclockwise normal
|
||||
Eigen::Vector3f v0(
|
||||
p2.x - p1.x,
|
||||
p2.y - p1.y,
|
||||
p2.z - p1.z);
|
||||
Eigen::Vector3f v1(
|
||||
p3.x - p1.x,
|
||||
p3.y - p1.y,
|
||||
p3.z - p1.z);
|
||||
Eigen::Vector3f normal = v0.cross(v1);
|
||||
normal.normalize();
|
||||
angle = normal.dot(Eigen::Vector3f(0.0f,0.0f,-1.0f));
|
||||
|
||||
return angle > 0.0f && // toward the camera
|
||||
(getPointUVCoordinates(p1, camera, proj1)
|
||||
&&
|
||||
getPointUVCoordinates(p2, camera, proj2)
|
||||
&&
|
||||
getPointUVCoordinates(p3, camera, proj3)
|
||||
);
|
||||
return getPointUVCoordinates(p1, camera, proj1)
|
||||
&&
|
||||
getPointUVCoordinates(p2, camera, proj2)
|
||||
&&
|
||||
getPointUVCoordinates(p3, camera, proj3);
|
||||
}
|
||||
|
||||
#define PCL_INSTANTIATE_TextureMapping(T) \
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <pcl/surface/reconstruction.h>
|
||||
#include <pcl/common/transforms.h>
|
||||
#include <pcl/TextureMesh.h>
|
||||
#include <rtabmap/core/ProgressState.h>
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
#include <rtabmap/utilite/UStl.h>
|
||||
#include <rtabmap/utilite/UConversion.h>
|
||||
@@ -341,9 +342,10 @@ namespace pcl
|
||||
void
|
||||
textureMeshwithMultipleCameras (pcl::TextureMesh &mesh,
|
||||
const pcl::texture_mapping::CameraVector &cameras);
|
||||
void
|
||||
bool
|
||||
textureMeshwithMultipleCameras2 (pcl::TextureMesh &mesh,
|
||||
const pcl::texture_mapping::CameraVector &cameras);
|
||||
const pcl::texture_mapping::CameraVector &cameras,
|
||||
const ProgressState * callback = 0);
|
||||
|
||||
protected:
|
||||
/** \brief mesh scale control. */
|
||||
@@ -414,7 +416,7 @@ namespace pcl
|
||||
inline bool
|
||||
isFaceProjected (const Camera &camera,
|
||||
const PointInT &p1, const PointInT &p2, const PointInT &p3,
|
||||
pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3, float & angle);
|
||||
pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3);
|
||||
|
||||
/** \brief Returns True if a point lays within a triangle
|
||||
* \details see http://www.blackpawn.com/texts/pointinpoly/default.html
|
||||
|
||||
Reference in New Issue
Block a user