added support of texture for mesh

This commit is contained in:
Anatoly Baksheev 2014-01-13 00:46:24 +04:00
parent 74206e0159
commit 625c35a9f9
6 changed files with 99 additions and 6 deletions

View File

@ -98,6 +98,11 @@ namespace cv
CV_EXPORTS void writeCloud(const String& file, InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray(), bool binary = false);
CV_EXPORTS Mat readCloud (const String& file, OutputArray colors = noArray(), OutputArray normals = noArray());
///////////////////////////////////////////////////////////////////////////////////////////////
/// Read mesh. Only ply format is supported now
CV_EXPORTS Mesh readMesh (const String& file);
///////////////////////////////////////////////////////////////////////////////////////////////
/// Read/write poses and trajectories

View File

@ -113,6 +113,8 @@ namespace cv
//! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud.
Mat polygons;
Mat texture, tcoords;
//! Loads mesh from a given ply file
static Mesh load(const String& file);
};

View File

@ -95,8 +95,25 @@ cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud)
Vec6d bounds(cloud_source->GetOutput()->GetPoints()->GetBounds());
WPaintedCloud cloud_widget(cloud, Vec3d(bounds[0], bounds[2], bounds[4]), Vec3d(bounds[1], bounds[3], bounds[5]));
*this = cloud_widget;
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
elevation->SetInputConnection(cloud_source->GetOutputPort());
elevation->SetLowPoint(bounds[0], bounds[2], bounds[4]);
elevation->SetHighPoint(bounds[1], bounds[3], bounds[5]);
elevation->SetScalarRange(0.0, 1.0);
elevation->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
mapper->ImmediateModeRenderingOff();
mapper->ScalarVisibilityOn();
mapper->SetColorModeToMapScalars();
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
}
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2)
@ -329,7 +346,7 @@ cv::viz::WMesh::WMesh(const Mesh &mesh)
CV_Assert(mesh.cloud.rows == 1 && mesh.polygons.type() == CV_32SC1);
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New();
source->SetColorCloud(mesh.cloud, mesh.colors);
source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
source->Update();
Mat lookup_buffer(1, mesh.cloud.total(), CV_32SC1);
@ -394,6 +411,16 @@ cv::viz::WMesh::WMesh(const Mesh &mesh)
actor->GetProperty()->ShadingOff();
actor->SetMapper(mapper);
if (!mesh.texture.empty())
{
vtkSmartPointer<vtkImageMatSource> image_source = vtkSmartPointer<vtkImageMatSource>::New();
image_source->SetImage(mesh.texture);
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
texture->SetInputConnection(image_source->GetOutputPort());
actor->SetTexture(texture);
}
WidgetAccessor::setProp(*this, actor);
}

View File

@ -205,6 +205,8 @@ cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray n
return cloud;
}
cv::viz::Mesh cv::viz::readMesh(const String& file) { return Mesh::load(file); }
///////////////////////////////////////////////////////////////////////////////////////////////
/// Read/write poses and trajectories

View File

@ -128,7 +128,34 @@ int cv::viz::vtkCloudMatSource::SetColorCloudNormals(InputArray _cloud, InputArr
else if (normals.depth() == CV_64F && cloud.depth() == CV_64F)
filterNanNormalsCopy<double, double>(normals, cloud, total);
else
CV_Assert(!"Unsupported normals type");
CV_Assert(!"Unsupported normals/cloud type");
return total;
}
int cv::viz::vtkCloudMatSource::SetColorCloudNormalsTCoords(InputArray _cloud, InputArray _colors, InputArray _normals, InputArray _tcoords)
{
int total = SetColorCloudNormals(_cloud, _colors, _normals);
if (_tcoords.empty())
return total;
CV_Assert(_tcoords.depth() == CV_32F || _tcoords.depth() == CV_64F);
CV_Assert(_tcoords.channels() == 2 && _tcoords.size() == _cloud.size());
Mat cloud = _cloud.getMat();
Mat tcoords = _tcoords.getMat();
if (tcoords.depth() == CV_32F && cloud.depth() == CV_32F)
filterNanTCoordsCopy<float, float>(tcoords, cloud, total);
else if (tcoords.depth() == CV_32F && cloud.depth() == CV_64F)
filterNanTCoordsCopy<float, double>(tcoords, cloud, total);
else if (tcoords.depth() == CV_64F && cloud.depth() == CV_32F)
filterNanTCoordsCopy<double, float>(tcoords, cloud, total);
else if (tcoords.depth() == CV_64F && cloud.depth() == CV_64F)
filterNanTCoordsCopy<double, double>(tcoords, cloud, total);
else
CV_Assert(!"Unsupported tcoords/cloud type");
return total;
}
@ -146,6 +173,9 @@ int cv::viz::vtkCloudMatSource::RequestData(vtkInformation *vtkNotUsed(request),
if (normals)
output->GetPointData()->SetNormals(normals);
if (tcoords)
output->GetPointData()->SetTCoords(tcoords);
return 1;
}
@ -232,3 +262,25 @@ void cv::viz::vtkCloudMatSource::filterNanNormalsCopy(const Mat& cloud_normals,
normals->SetTuple(pos++, srow);
}
}
template<typename _Tn, typename _Msk>
void cv::viz::vtkCloudMatSource::filterNanTCoordsCopy(const Mat& _tcoords, const Mat& mask, int total)
{
typedef Vec<_Tn, 2> Vec2;
tcoords = vtkSmartPointer< VtkDepthTraits<_Tn>::array_type >::New();
tcoords->SetName("TextureCoordinates");
tcoords->SetNumberOfComponents(2);
tcoords->SetNumberOfTuples(total);
int pos = 0;
for (int y = 0; y < mask.rows; ++y)
{
const Vec2* srow = _tcoords.ptr<Vec2>(y);
const Vec2* send = srow + _tcoords.cols;
const _Msk* mrow = mask.ptr<_Msk>(y);
for (; srow != send; ++srow, mrow += mask.channels())
if (!isNan(mrow))
tcoords->SetTuple(pos++, srow->val);
}
}

View File

@ -62,8 +62,9 @@ namespace cv
vtkTypeMacro(vtkCloudMatSource,vtkPolyDataAlgorithm)
virtual int SetCloud(InputArray cloud);
virtual int SetColorCloud(InputArray cloud, InputArray colors = noArray());
virtual int SetColorCloudNormals(InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray());
virtual int SetColorCloud(InputArray cloud, InputArray colors);
virtual int SetColorCloudNormals(InputArray cloud, InputArray colors, InputArray normals);
virtual int SetColorCloudNormalsTCoords(InputArray cloud, InputArray colors, InputArray normals, InputArray tcoords);
protected:
vtkCloudMatSource();
@ -75,6 +76,7 @@ namespace cv
vtkSmartPointer<vtkCellArray> vertices;
vtkSmartPointer<vtkUnsignedCharArray> scalars;
vtkSmartPointer<vtkDataArray> normals;
vtkSmartPointer<vtkDataArray> tcoords;
private:
vtkCloudMatSource(const vtkCloudMatSource&); // Not implemented.
void operator=(const vtkCloudMatSource&); // Not implemented.
@ -84,6 +86,9 @@ namespace cv
template<typename _Tn, typename _Msk>
void filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total);
template<typename _Tn, typename _Msk>
void filterNanTCoordsCopy(const Mat& tcoords, const Mat& mask, int total);
};
}
}