reduced exported interface names (to make IntelliSense hints less littered)
This commit is contained in:
@@ -119,8 +119,6 @@ namespace cv
|
|||||||
Affine3f getPose() const;
|
Affine3f getPose() const;
|
||||||
|
|
||||||
void setColor(const Color &color);
|
void setColor(const Color &color);
|
||||||
private:
|
|
||||||
struct MatrixConverter;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -145,8 +143,6 @@ namespace cv
|
|||||||
public:
|
public:
|
||||||
WPlane(const Vec4f& coefs, float size = 1.f, const Color &color = Color::white());
|
WPlane(const Vec4f& coefs, float size = 1.f, const Color &color = Color::white());
|
||||||
WPlane(const Vec4f& coefs, const Point3f& pt, float size = 1.f, const Color &color = Color::white());
|
WPlane(const Vec4f& coefs, const Point3f& pt, float size = 1.f, const Color &color = Color::white());
|
||||||
private:
|
|
||||||
struct SetSizeImpl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WSphere : public Widget3D
|
class CV_EXPORTS WSphere : public Widget3D
|
||||||
@@ -189,9 +185,6 @@ namespace cv
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WPolyLine(InputArray points, const Color &color = Color::white());
|
WPolyLine(InputArray points, const Color &color = Color::white());
|
||||||
|
|
||||||
private:
|
|
||||||
struct CopyImpl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WGrid : public Widget3D
|
class CV_EXPORTS WGrid : public Widget3D
|
||||||
@@ -201,10 +194,6 @@ namespace cv
|
|||||||
WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
||||||
//! Creates grid based on the plane equation
|
//! Creates grid based on the plane equation
|
||||||
WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white());
|
||||||
|
|
||||||
private:
|
|
||||||
struct GridImpl;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WText3D : public Widget3D
|
class CV_EXPORTS WText3D : public Widget3D
|
||||||
@@ -257,9 +246,6 @@ namespace cv
|
|||||||
WCameraPosition(const Matx33f &K, const Mat &img, float scale = 1.f, const Color &color = Color::white());
|
WCameraPosition(const Matx33f &K, const Mat &img, float scale = 1.f, const Color &color = Color::white());
|
||||||
//! Creates frustum and display given image at the far plane
|
//! Creates frustum and display given image at the far plane
|
||||||
WCameraPosition(const Vec2f &fov, const Mat &img, float scale = 1.f, const Color &color = Color::white());
|
WCameraPosition(const Vec2f &fov, const Mat &img, float scale = 1.f, const Color &color = Color::white());
|
||||||
|
|
||||||
private:
|
|
||||||
struct ProjectImage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WTrajectory : public Widget3D
|
class CV_EXPORTS WTrajectory : public Widget3D
|
||||||
@@ -273,9 +259,6 @@ namespace cv
|
|||||||
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale = 1.f, const Color &color = Color::white());
|
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale = 1.f, const Color &color = Color::white());
|
||||||
//! Displays trajectory of the given path by frustums
|
//! Displays trajectory of the given path by frustums
|
||||||
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale = 1.f, const Color &color = Color::white());
|
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale = 1.f, const Color &color = Color::white());
|
||||||
|
|
||||||
private:
|
|
||||||
struct ApplyPath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WSpheresTrajectory: public Widget3D
|
class CV_EXPORTS WSpheresTrajectory: public Widget3D
|
||||||
@@ -292,9 +275,6 @@ namespace cv
|
|||||||
WCloud(InputArray cloud, InputArray colors);
|
WCloud(InputArray cloud, InputArray colors);
|
||||||
//! All points in cloud have the same color
|
//! All points in cloud have the same color
|
||||||
WCloud(InputArray cloud, const Color &color = Color::white());
|
WCloud(InputArray cloud, const Color &color = Color::white());
|
||||||
|
|
||||||
private:
|
|
||||||
struct CreateCloudWidget;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WCloudCollection : public Widget3D
|
class CV_EXPORTS WCloudCollection : public Widget3D
|
||||||
@@ -306,27 +286,18 @@ namespace cv
|
|||||||
void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity());
|
void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity());
|
||||||
//! All points in cloud have the same color
|
//! All points in cloud have the same color
|
||||||
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity());
|
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity());
|
||||||
|
|
||||||
private:
|
|
||||||
struct CreateCloudWidget;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WCloudNormals : public Widget3D
|
class CV_EXPORTS WCloudNormals : public Widget3D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white());
|
WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white());
|
||||||
|
|
||||||
private:
|
|
||||||
struct ApplyCloudNormals;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS WMesh : public Widget3D
|
class CV_EXPORTS WMesh : public Widget3D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WMesh(const Mesh3d &mesh);
|
WMesh(const Mesh3d &mesh);
|
||||||
|
|
||||||
private:
|
|
||||||
struct CopyImpl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> CV_EXPORTS Widget2D Widget::cast<Widget2D>();
|
template<> CV_EXPORTS Widget2D Widget::cast<Widget2D>();
|
||||||
|
@@ -59,92 +59,96 @@ namespace cv
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Point Cloud Widget implementation
|
/// Point Cloud Widget implementation
|
||||||
|
|
||||||
struct cv::viz::WCloud::CreateCloudWidget
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
|
struct CloudUtils
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
|
||||||
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
|
|
||||||
|
|
||||||
polydata->SetVerts(vertices);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
|
|
||||||
vtkSmartPointer<vtkIdTypeArray> initcells;
|
|
||||||
nr_points = cloud.total();
|
|
||||||
|
|
||||||
if (!points)
|
|
||||||
{
|
{
|
||||||
points = vtkSmartPointer<vtkPoints>::New();
|
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||||
if (cloud.depth() == CV_32F)
|
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
|
||||||
points->SetDataTypeToFloat();
|
|
||||||
else if (cloud.depth() == CV_64F)
|
|
||||||
points->SetDataTypeToDouble();
|
|
||||||
polydata->SetPoints(points);
|
|
||||||
}
|
|
||||||
points->SetNumberOfPoints(nr_points);
|
|
||||||
|
|
||||||
if (cloud.depth() == CV_32F)
|
polydata->SetVerts(vertices);
|
||||||
{
|
|
||||||
// Get a pointer to the beginning of the data array
|
|
||||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
|
||||||
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
|
||||||
nr_points = data_end - data_beg;
|
|
||||||
}
|
|
||||||
else if (cloud.depth() == CV_64F)
|
|
||||||
{
|
|
||||||
// Get a pointer to the beginning of the data array
|
|
||||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
|
||||||
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
|
||||||
nr_points = data_end - data_beg;
|
|
||||||
}
|
|
||||||
points->SetNumberOfPoints(nr_points);
|
|
||||||
|
|
||||||
// Update cells
|
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
|
||||||
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
|
vtkSmartPointer<vtkIdTypeArray> initcells;
|
||||||
// If no init cells and cells has not been initialized...
|
nr_points = cloud.total();
|
||||||
if (!cells)
|
|
||||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
|
||||||
|
|
||||||
// If we have less values then we need to recreate the array
|
if (!points)
|
||||||
if (cells->GetNumberOfTuples() < nr_points)
|
|
||||||
{
|
|
||||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
|
||||||
|
|
||||||
// If init cells is given, and there's enough data in it, use it
|
|
||||||
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
|
|
||||||
{
|
{
|
||||||
cells->DeepCopy(initcells);
|
points = vtkSmartPointer<vtkPoints>::New();
|
||||||
cells->SetNumberOfComponents(2);
|
if (cloud.depth() == CV_32F)
|
||||||
cells->SetNumberOfTuples(nr_points);
|
points->SetDataTypeToFloat();
|
||||||
|
else if (cloud.depth() == CV_64F)
|
||||||
|
points->SetDataTypeToDouble();
|
||||||
|
polydata->SetPoints(points);
|
||||||
|
}
|
||||||
|
points->SetNumberOfPoints(nr_points);
|
||||||
|
|
||||||
|
if (cloud.depth() == CV_32F)
|
||||||
|
{
|
||||||
|
// Get a pointer to the beginning of the data array
|
||||||
|
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||||
|
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||||
|
nr_points = data_end - data_beg;
|
||||||
|
}
|
||||||
|
else if (cloud.depth() == CV_64F)
|
||||||
|
{
|
||||||
|
// Get a pointer to the beginning of the data array
|
||||||
|
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||||
|
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||||
|
nr_points = data_end - data_beg;
|
||||||
|
}
|
||||||
|
points->SetNumberOfPoints(nr_points);
|
||||||
|
|
||||||
|
// Update cells
|
||||||
|
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
|
||||||
|
// If no init cells and cells has not been initialized...
|
||||||
|
if (!cells)
|
||||||
|
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||||
|
|
||||||
|
// If we have less values then we need to recreate the array
|
||||||
|
if (cells->GetNumberOfTuples() < nr_points)
|
||||||
|
{
|
||||||
|
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||||
|
|
||||||
|
// If init cells is given, and there's enough data in it, use it
|
||||||
|
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
|
||||||
|
{
|
||||||
|
cells->DeepCopy(initcells);
|
||||||
|
cells->SetNumberOfComponents(2);
|
||||||
|
cells->SetNumberOfTuples(nr_points);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the number of tuples is still too small, we need to recreate the array
|
||||||
|
cells->SetNumberOfComponents(2);
|
||||||
|
cells->SetNumberOfTuples(nr_points);
|
||||||
|
vtkIdType *cell = cells->GetPointer(0);
|
||||||
|
// Fill it with 1s
|
||||||
|
std::fill(cell, cell + nr_points * 2, 1);
|
||||||
|
cell++;
|
||||||
|
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
|
||||||
|
*cell = i;
|
||||||
|
// Save the results in initcells
|
||||||
|
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||||
|
initcells->DeepCopy(cells);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the number of tuples is still too small, we need to recreate the array
|
// The assumption here is that the current set of cells has more data than needed
|
||||||
cells->SetNumberOfComponents(2);
|
cells->SetNumberOfComponents(2);
|
||||||
cells->SetNumberOfTuples(nr_points);
|
cells->SetNumberOfTuples(nr_points);
|
||||||
vtkIdType *cell = cells->GetPointer(0);
|
|
||||||
// Fill it with 1s
|
|
||||||
std::fill(cell, cell + nr_points * 2, 1);
|
|
||||||
cell++;
|
|
||||||
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
|
|
||||||
*cell = i;
|
|
||||||
// Save the results in initcells
|
|
||||||
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
|
|
||||||
initcells->DeepCopy(cells);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The assumption here is that the current set of cells has more data than needed
|
|
||||||
cells->SetNumberOfComponents(2);
|
|
||||||
cells->SetNumberOfTuples(nr_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the cells and the vertices
|
// Set the cells and the vertices
|
||||||
vertices->SetCells(nr_points, cells);
|
vertices->SetCells(nr_points, cells);
|
||||||
return polydata;
|
return polydata;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
|
cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
|
||||||
{
|
{
|
||||||
@@ -160,7 +164,7 @@ cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vtkIdType nr_points;
|
vtkIdType nr_points;
|
||||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
vtkSmartPointer<vtkPolyData> polydata = CloudUtils::create(cloud, nr_points);
|
||||||
|
|
||||||
// Filter colors
|
// Filter colors
|
||||||
Vec3b* colors_data = new Vec3b[nr_points];
|
Vec3b* colors_data = new Vec3b[nr_points];
|
||||||
@@ -207,7 +211,7 @@ cv::viz::WCloud::WCloud(InputArray _cloud, const Color &color)
|
|||||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||||
|
|
||||||
vtkIdType nr_points;
|
vtkIdType nr_points;
|
||||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
vtkSmartPointer<vtkPolyData> polydata = CloudUtils::create(cloud, nr_points);
|
||||||
|
|
||||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
@@ -242,139 +246,142 @@ template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Cloud Collection Widget implementation
|
/// Cloud Collection Widget implementation
|
||||||
|
|
||||||
struct cv::viz::WCloudCollection::CreateCloudWidget
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
|
struct CloudCollectionUtils
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
|
||||||
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
|
|
||||||
|
|
||||||
polydata->SetVerts(vertices);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
|
|
||||||
vtkSmartPointer<vtkIdTypeArray> initcells;
|
|
||||||
nr_points = cloud.total();
|
|
||||||
|
|
||||||
if (!points)
|
|
||||||
{
|
{
|
||||||
points = vtkSmartPointer<vtkPoints>::New();
|
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||||
if (cloud.depth() == CV_32F)
|
vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
|
||||||
points->SetDataTypeToFloat();
|
|
||||||
else if (cloud.depth() == CV_64F)
|
|
||||||
points->SetDataTypeToDouble();
|
|
||||||
polydata->SetPoints(points);
|
|
||||||
}
|
|
||||||
points->SetNumberOfPoints(nr_points);
|
|
||||||
|
|
||||||
if (cloud.depth() == CV_32F)
|
polydata->SetVerts(vertices);
|
||||||
{
|
|
||||||
// Get a pointer to the beginning of the data array
|
|
||||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
|
||||||
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
|
||||||
nr_points = data_end - data_beg;
|
|
||||||
}
|
|
||||||
else if (cloud.depth() == CV_64F)
|
|
||||||
{
|
|
||||||
// Get a pointer to the beginning of the data array
|
|
||||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
|
||||||
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
|
||||||
nr_points = data_end - data_beg;
|
|
||||||
}
|
|
||||||
points->SetNumberOfPoints(nr_points);
|
|
||||||
|
|
||||||
// Update cells
|
vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
|
||||||
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
|
vtkSmartPointer<vtkIdTypeArray> initcells;
|
||||||
// If no init cells and cells has not been initialized...
|
nr_points = cloud.total();
|
||||||
if (!cells)
|
|
||||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
|
||||||
|
|
||||||
// If we have less values then we need to recreate the array
|
if (!points)
|
||||||
if (cells->GetNumberOfTuples() < nr_points)
|
|
||||||
{
|
|
||||||
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
|
||||||
|
|
||||||
// If init cells is given, and there's enough data in it, use it
|
|
||||||
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
|
|
||||||
{
|
{
|
||||||
cells->DeepCopy(initcells);
|
points = vtkSmartPointer<vtkPoints>::New();
|
||||||
cells->SetNumberOfComponents(2);
|
if (cloud.depth() == CV_32F)
|
||||||
cells->SetNumberOfTuples(nr_points);
|
points->SetDataTypeToFloat();
|
||||||
|
else if (cloud.depth() == CV_64F)
|
||||||
|
points->SetDataTypeToDouble();
|
||||||
|
polydata->SetPoints(points);
|
||||||
|
}
|
||||||
|
points->SetNumberOfPoints(nr_points);
|
||||||
|
|
||||||
|
if (cloud.depth() == CV_32F)
|
||||||
|
{
|
||||||
|
// Get a pointer to the beginning of the data array
|
||||||
|
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||||
|
Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||||
|
nr_points = data_end - data_beg;
|
||||||
|
}
|
||||||
|
else if (cloud.depth() == CV_64F)
|
||||||
|
{
|
||||||
|
// Get a pointer to the beginning of the data array
|
||||||
|
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||||
|
Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud);
|
||||||
|
nr_points = data_end - data_beg;
|
||||||
|
}
|
||||||
|
points->SetNumberOfPoints(nr_points);
|
||||||
|
|
||||||
|
// Update cells
|
||||||
|
vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
|
||||||
|
// If no init cells and cells has not been initialized...
|
||||||
|
if (!cells)
|
||||||
|
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||||
|
|
||||||
|
// If we have less values then we need to recreate the array
|
||||||
|
if (cells->GetNumberOfTuples() < nr_points)
|
||||||
|
{
|
||||||
|
cells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||||
|
|
||||||
|
// If init cells is given, and there's enough data in it, use it
|
||||||
|
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
|
||||||
|
{
|
||||||
|
cells->DeepCopy(initcells);
|
||||||
|
cells->SetNumberOfComponents(2);
|
||||||
|
cells->SetNumberOfTuples(nr_points);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the number of tuples is still too small, we need to recreate the array
|
||||||
|
cells->SetNumberOfComponents(2);
|
||||||
|
cells->SetNumberOfTuples(nr_points);
|
||||||
|
vtkIdType *cell = cells->GetPointer(0);
|
||||||
|
// Fill it with 1s
|
||||||
|
std::fill(cell, cell + nr_points * 2, 1);
|
||||||
|
cell++;
|
||||||
|
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
|
||||||
|
*cell = i;
|
||||||
|
// Save the results in initcells
|
||||||
|
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||||
|
initcells->DeepCopy(cells);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the number of tuples is still too small, we need to recreate the array
|
// The assumption here is that the current set of cells has more data than needed
|
||||||
cells->SetNumberOfComponents(2);
|
cells->SetNumberOfComponents(2);
|
||||||
cells->SetNumberOfTuples(nr_points);
|
cells->SetNumberOfTuples(nr_points);
|
||||||
vtkIdType *cell = cells->GetPointer(0);
|
|
||||||
// Fill it with 1s
|
|
||||||
std::fill(cell, cell + nr_points * 2, 1);
|
|
||||||
cell++;
|
|
||||||
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
|
|
||||||
*cell = i;
|
|
||||||
// Save the results in initcells
|
|
||||||
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
|
|
||||||
initcells->DeepCopy(cells);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
// Set the cells and the vertices
|
||||||
{
|
vertices->SetCells(nr_points, cells);
|
||||||
// The assumption here is that the current set of cells has more data than needed
|
return polydata;
|
||||||
cells->SetNumberOfComponents(2);
|
|
||||||
cells->SetNumberOfTuples(nr_points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the cells and the vertices
|
static void createMapper(vtkSmartPointer<vtkLODActor> actor, vtkSmartPointer<vtkPolyData> poly_data, Vec3d& minmax)
|
||||||
vertices->SetCells(nr_points, cells);
|
|
||||||
return polydata;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void createMapper(vtkSmartPointer<vtkLODActor> actor, vtkSmartPointer<vtkPolyData> poly_data, Vec3d& minmax)
|
|
||||||
{
|
|
||||||
vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper());
|
|
||||||
if (!mapper)
|
|
||||||
{
|
{
|
||||||
// This is the first cloud
|
vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper());
|
||||||
vtkSmartPointer<vtkDataSetMapper> mapper_new = vtkSmartPointer<vtkDataSetMapper>::New();
|
if (!mapper)
|
||||||
|
{
|
||||||
|
// This is the first cloud
|
||||||
|
vtkSmartPointer<vtkDataSetMapper> mapper_new = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
mapper_new->SetInputConnection(poly_data->GetProducerPort());
|
mapper_new->SetInputConnection(poly_data->GetProducerPort());
|
||||||
#else
|
#else
|
||||||
mapper_new->SetInputData(poly_data);
|
mapper_new->SetInputData(poly_data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mapper_new->SetScalarRange(minmax.val);
|
mapper_new->SetScalarRange(minmax.val);
|
||||||
mapper_new->SetScalarModeToUsePointData();
|
mapper_new->SetScalarModeToUsePointData();
|
||||||
|
|
||||||
bool interpolation = (poly_data && poly_data->GetNumberOfCells() != poly_data->GetNumberOfVerts());
|
bool interpolation = (poly_data && poly_data->GetNumberOfCells() != poly_data->GetNumberOfVerts());
|
||||||
|
|
||||||
mapper_new->SetInterpolateScalarsBeforeMapping(interpolation);
|
mapper_new->SetInterpolateScalarsBeforeMapping(interpolation);
|
||||||
mapper_new->ScalarVisibilityOn();
|
mapper_new->ScalarVisibilityOn();
|
||||||
mapper_new->ImmediateModeRenderingOff();
|
mapper_new->ImmediateModeRenderingOff();
|
||||||
|
|
||||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, poly_data->GetNumberOfPoints() / 10)));
|
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, poly_data->GetNumberOfPoints() / 10)));
|
||||||
actor->GetProperty()->SetInterpolationToFlat();
|
actor->GetProperty()->SetInterpolationToFlat();
|
||||||
actor->GetProperty()->BackfaceCullingOn();
|
actor->GetProperty()->BackfaceCullingOn();
|
||||||
actor->SetMapper(mapper_new);
|
actor->SetMapper(mapper_new);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput());
|
vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput());
|
||||||
CV_Assert("Cloud Widget without data" && data);
|
CV_Assert("Cloud Widget without data" && data);
|
||||||
|
|
||||||
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort());
|
appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort());
|
||||||
appendFilter->AddInputConnection(poly_data->GetProducerPort());
|
appendFilter->AddInputConnection(poly_data->GetProducerPort());
|
||||||
#else
|
#else
|
||||||
appendFilter->AddInputData(data);
|
appendFilter->AddInputData(data);
|
||||||
appendFilter->AddInputData(poly_data);
|
appendFilter->AddInputData(poly_data);
|
||||||
#endif
|
#endif
|
||||||
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
||||||
|
|
||||||
// Update the number of cloud points
|
// Update the number of cloud points
|
||||||
vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints();
|
vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints();
|
||||||
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10)));
|
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
cv::viz::WCloudCollection::WCloudCollection()
|
cv::viz::WCloudCollection::WCloudCollection()
|
||||||
{
|
{
|
||||||
@@ -397,7 +404,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors,
|
|||||||
}
|
}
|
||||||
|
|
||||||
vtkIdType nr_points;
|
vtkIdType nr_points;
|
||||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
vtkSmartPointer<vtkPolyData> polydata = CloudCollectionUtils::create(cloud, nr_points);
|
||||||
|
|
||||||
// Filter colors
|
// Filter colors
|
||||||
Vec3b* colors_data = new Vec3b[nr_points];
|
Vec3b* colors_data = new Vec3b[nr_points];
|
||||||
@@ -429,7 +436,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors,
|
|||||||
CV_Assert("Incompatible widget type." && actor);
|
CV_Assert("Incompatible widget type." && actor);
|
||||||
|
|
||||||
Vec3d minmax(scalars->GetRange());
|
Vec3d minmax(scalars->GetRange());
|
||||||
CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax);
|
CloudCollectionUtils::createMapper(actor, transform_filter->GetOutput(), minmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose)
|
void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose)
|
||||||
@@ -438,7 +445,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color,
|
|||||||
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
|
||||||
|
|
||||||
vtkIdType nr_points;
|
vtkIdType nr_points;
|
||||||
vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
|
vtkSmartPointer<vtkPolyData> polydata = CloudCollectionUtils::create(cloud, nr_points);
|
||||||
|
|
||||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||||
scalars->SetNumberOfComponents(3);
|
scalars->SetNumberOfComponents(3);
|
||||||
@@ -468,7 +475,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color,
|
|||||||
CV_Assert("Incompatible widget type." && actor);
|
CV_Assert("Incompatible widget type." && actor);
|
||||||
|
|
||||||
Vec3d minmax(scalars->GetRange());
|
Vec3d minmax(scalars->GetRange());
|
||||||
CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax);
|
CloudCollectionUtils::createMapper(actor, transform_filter->GetOutput(), minmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
|
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
|
||||||
@@ -480,80 +487,84 @@ template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollec
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Cloud Normals Widget implementation
|
/// Cloud Normals Widget implementation
|
||||||
|
|
||||||
struct cv::viz::WCloudNormals::ApplyCloudNormals
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
template<typename _Tp>
|
struct CloudNormalsUtils
|
||||||
struct Impl
|
|
||||||
{
|
{
|
||||||
static vtkSmartPointer<vtkCellArray> applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
template<typename _Tp>
|
||||||
|
struct Impl
|
||||||
{
|
{
|
||||||
vtkIdType point_step = static_cast<vtkIdType>(std::sqrt(level));
|
static vtkSmartPointer<vtkCellArray> applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
||||||
nr_normals = (static_cast<vtkIdType>((cloud.cols - 1) / point_step) + 1) *
|
|
||||||
(static_cast<vtkIdType>((cloud.rows - 1) / point_step) + 1);
|
|
||||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
|
||||||
|
|
||||||
pts = new _Tp[2 * nr_normals * 3];
|
|
||||||
|
|
||||||
int cch = cloud.channels();
|
|
||||||
vtkIdType cell_count = 0;
|
|
||||||
for (vtkIdType y = 0; y < cloud.rows; y += point_step)
|
|
||||||
{
|
{
|
||||||
const _Tp *prow = cloud.ptr<_Tp>(y);
|
vtkIdType point_step = static_cast<vtkIdType>(std::sqrt(level));
|
||||||
const _Tp *nrow = normals.ptr<_Tp>(y);
|
nr_normals = (static_cast<vtkIdType>((cloud.cols - 1) / point_step) + 1) *
|
||||||
for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch)
|
(static_cast<vtkIdType>((cloud.rows - 1) / point_step) + 1);
|
||||||
|
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||||
|
|
||||||
|
pts = new _Tp[2 * nr_normals * 3];
|
||||||
|
|
||||||
|
int cch = cloud.channels();
|
||||||
|
vtkIdType cell_count = 0;
|
||||||
|
for (vtkIdType y = 0; y < cloud.rows; y += point_step)
|
||||||
{
|
{
|
||||||
pts[2 * cell_count * 3 + 0] = prow[x];
|
const _Tp *prow = cloud.ptr<_Tp>(y);
|
||||||
pts[2 * cell_count * 3 + 1] = prow[x+1];
|
const _Tp *nrow = normals.ptr<_Tp>(y);
|
||||||
pts[2 * cell_count * 3 + 2] = prow[x+2];
|
for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch)
|
||||||
pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale;
|
{
|
||||||
pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale;
|
pts[2 * cell_count * 3 + 0] = prow[x];
|
||||||
pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale;
|
pts[2 * cell_count * 3 + 1] = prow[x+1];
|
||||||
|
pts[2 * cell_count * 3 + 2] = prow[x+2];
|
||||||
|
pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale;
|
||||||
|
pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale;
|
||||||
|
pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale;
|
||||||
|
|
||||||
|
lines->InsertNextCell(2);
|
||||||
|
lines->InsertCellPoint(2 * cell_count);
|
||||||
|
lines->InsertCellPoint(2 * cell_count + 1);
|
||||||
|
cell_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vtkSmartPointer<vtkCellArray> applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
||||||
|
{
|
||||||
|
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
||||||
|
nr_normals = (cloud.size().area() - 1) / level + 1 ;
|
||||||
|
pts = new _Tp[2 * nr_normals * 3];
|
||||||
|
|
||||||
|
int cch = cloud.channels();
|
||||||
|
const _Tp *p = cloud.ptr<_Tp>();
|
||||||
|
const _Tp *n = normals.ptr<_Tp>();
|
||||||
|
for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch)
|
||||||
|
{
|
||||||
|
|
||||||
|
pts[2 * j * 3 + 0] = p[i];
|
||||||
|
pts[2 * j * 3 + 1] = p[i+1];
|
||||||
|
pts[2 * j * 3 + 2] = p[i+2];
|
||||||
|
pts[2 * j * 3 + 3] = p[i] + n[i] * scale;
|
||||||
|
pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale;
|
||||||
|
pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale;
|
||||||
|
|
||||||
lines->InsertNextCell(2);
|
lines->InsertNextCell(2);
|
||||||
lines->InsertCellPoint(2 * cell_count);
|
lines->InsertCellPoint(2 * j);
|
||||||
lines->InsertCellPoint(2 * cell_count + 1);
|
lines->InsertCellPoint(2 * j + 1);
|
||||||
cell_count++;
|
|
||||||
}
|
}
|
||||||
|
return lines;
|
||||||
}
|
}
|
||||||
return lines;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static vtkSmartPointer<vtkCellArray> applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
template<typename _Tp>
|
||||||
|
static inline vtkSmartPointer<vtkCellArray> apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
|
if (cloud.cols > 1 && cloud.rows > 1)
|
||||||
nr_normals = (cloud.size().area() - 1) / level + 1 ;
|
return CloudNormalsUtils::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals);
|
||||||
pts = new _Tp[2 * nr_normals * 3];
|
else
|
||||||
|
return CloudNormalsUtils::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals);
|
||||||
int cch = cloud.channels();
|
|
||||||
const _Tp *p = cloud.ptr<_Tp>();
|
|
||||||
const _Tp *n = normals.ptr<_Tp>();
|
|
||||||
for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch)
|
|
||||||
{
|
|
||||||
|
|
||||||
pts[2 * j * 3 + 0] = p[i];
|
|
||||||
pts[2 * j * 3 + 1] = p[i+1];
|
|
||||||
pts[2 * j * 3 + 2] = p[i+2];
|
|
||||||
pts[2 * j * 3 + 3] = p[i] + n[i] * scale;
|
|
||||||
pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale;
|
|
||||||
pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale;
|
|
||||||
|
|
||||||
lines->InsertNextCell(2);
|
|
||||||
lines->InsertCellPoint(2 * j);
|
|
||||||
lines->InsertCellPoint(2 * j + 1);
|
|
||||||
}
|
|
||||||
return lines;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Tp>
|
}}}
|
||||||
static inline vtkSmartPointer<vtkCellArray> apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals)
|
|
||||||
{
|
|
||||||
if (cloud.cols > 1 && cloud.rows > 1)
|
|
||||||
return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals);
|
|
||||||
else
|
|
||||||
return ApplyCloudNormals::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color)
|
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color)
|
||||||
{
|
{
|
||||||
@@ -574,7 +585,7 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in
|
|||||||
data->SetNumberOfComponents(3);
|
data->SetNumberOfComponents(3);
|
||||||
|
|
||||||
float* pts = 0;
|
float* pts = 0;
|
||||||
lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals);
|
lines = CloudNormalsUtils::apply(cloud, normals, level, scale, pts, nr_normals);
|
||||||
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
|
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
|
||||||
points->SetData(data);
|
points->SetData(data);
|
||||||
}
|
}
|
||||||
@@ -586,7 +597,7 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in
|
|||||||
data->SetNumberOfComponents(3);
|
data->SetNumberOfComponents(3);
|
||||||
|
|
||||||
double* pts = 0;
|
double* pts = 0;
|
||||||
lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals);
|
lines = CloudNormalsUtils::apply(cloud, normals, level, scale, pts, nr_normals);
|
||||||
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
|
data->SetArray(&pts[0], 2 * nr_normals * 3, 0);
|
||||||
points->SetData(data);
|
points->SetData(data);
|
||||||
}
|
}
|
||||||
@@ -619,34 +630,37 @@ template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>(
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Mesh Widget implementation
|
/// Mesh Widget implementation
|
||||||
|
|
||||||
struct cv::viz::WMesh::CopyImpl
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
template<typename _Tp>
|
struct MeshUtils
|
||||||
static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask)
|
|
||||||
{
|
{
|
||||||
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
|
template<typename _Tp>
|
||||||
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
|
static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask)
|
||||||
CV_DbgAssert(DataDepth<_Tp>::value == nan_mask.depth());
|
|
||||||
|
|
||||||
int s_chs = source.channels();
|
|
||||||
int m_chs = nan_mask.channels();
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
const _Tp* srow = source.ptr<_Tp>(0);
|
|
||||||
const _Tp* mrow = nan_mask.ptr<_Tp>(0);
|
|
||||||
|
|
||||||
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
|
|
||||||
{
|
{
|
||||||
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
|
CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size());
|
||||||
|
CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4);
|
||||||
|
CV_DbgAssert(DataDepth<_Tp>::value == nan_mask.depth());
|
||||||
|
|
||||||
|
int s_chs = source.channels();
|
||||||
|
int m_chs = nan_mask.channels();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
const _Tp* srow = source.ptr<_Tp>(0);
|
||||||
|
const _Tp* mrow = nan_mask.ptr<_Tp>(0);
|
||||||
|
|
||||||
|
for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs)
|
||||||
{
|
{
|
||||||
look_up[x] = index;
|
if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2]))
|
||||||
*output++ = Vec<_Tp, 3>(srow);
|
{
|
||||||
++index;
|
look_up[x] = index;
|
||||||
|
*output++ = Vec<_Tp, 3>(srow);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
return output;
|
};
|
||||||
}
|
}}}
|
||||||
};
|
|
||||||
|
|
||||||
cv::viz::WMesh::WMesh(const Mesh3d &mesh)
|
cv::viz::WMesh::WMesh(const Mesh3d &mesh)
|
||||||
{
|
{
|
||||||
@@ -665,14 +679,14 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh)
|
|||||||
{
|
{
|
||||||
points->SetDataTypeToFloat();
|
points->SetDataTypeToFloat();
|
||||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||||
Vec3f *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
|
Vec3f *data_end = MeshUtils::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
|
||||||
nr_points = data_end - data_beg;
|
nr_points = data_end - data_beg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
points->SetDataTypeToDouble();
|
points->SetDataTypeToDouble();
|
||||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||||
Vec3d *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
|
Vec3d *data_end = MeshUtils::copy(mesh.cloud, data_beg, look_up, mesh.cloud);
|
||||||
nr_points = data_end - data_beg;
|
nr_points = data_end - data_beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,25 +84,28 @@ template<> cv::viz::WLine cv::viz::Widget::cast<cv::viz::WLine>()
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// plane widget implementation
|
/// plane widget implementation
|
||||||
|
|
||||||
struct cv::viz::WPlane::SetSizeImpl
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
template<typename _Tp>
|
struct PlaneUtils
|
||||||
static vtkSmartPointer<vtkTransformPolyDataFilter> setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer<vtkAlgorithmOutput> poly_data_port, double size)
|
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
template<typename _Tp>
|
||||||
transform->PreMultiply();
|
static vtkSmartPointer<vtkTransformPolyDataFilter> setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer<vtkAlgorithmOutput> poly_data_port, double size)
|
||||||
transform->Translate(center[0], center[1], center[2]);
|
{
|
||||||
transform->Scale(size, size, size);
|
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||||
transform->Translate(-center[0], -center[1], -center[2]);
|
transform->PreMultiply();
|
||||||
|
transform->Translate(center[0], center[1], center[2]);
|
||||||
|
transform->Scale(size, size, size);
|
||||||
|
transform->Translate(-center[0], -center[1], -center[2]);
|
||||||
|
|
||||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||||
transform_filter->SetInputConnection(poly_data_port);
|
transform_filter->SetInputConnection(poly_data_port);
|
||||||
transform_filter->SetTransform(transform);
|
transform_filter->SetTransform(transform);
|
||||||
transform_filter->Update();
|
transform_filter->Update();
|
||||||
|
|
||||||
return transform_filter;
|
return transform_filter;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
cv::viz::WPlane::WPlane(const Vec4f& coefs, float size, const Color &color)
|
cv::viz::WPlane::WPlane(const Vec4f& coefs, float size, const Color &color)
|
||||||
{
|
{
|
||||||
@@ -115,7 +118,7 @@ cv::viz::WPlane::WPlane(const Vec4f& coefs, float size, const Color &color)
|
|||||||
plane->GetOrigin(p_center.val);
|
plane->GetOrigin(p_center.val);
|
||||||
|
|
||||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||||
mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort());
|
mapper->SetInputConnection(PlaneUtils::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort());
|
||||||
|
|
||||||
vtkSmartPointer<vizActor> actor = vtkSmartPointer<vizActor>::New();
|
vtkSmartPointer<vizActor> actor = vtkSmartPointer<vizActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
@@ -136,7 +139,7 @@ cv::viz::WPlane::WPlane(const Vec4f& coefs, const Point3f& pt, float size, const
|
|||||||
plane->SetCenter(p_center[0], p_center[1], p_center[2]);
|
plane->SetCenter(p_center[0], p_center[1], p_center[2]);
|
||||||
|
|
||||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||||
mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort());
|
mapper->SetInputConnection(PlaneUtils::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort());
|
||||||
|
|
||||||
vtkSmartPointer<vizActor> actor = vtkSmartPointer<vizActor>::New();
|
vtkSmartPointer<vizActor> actor = vtkSmartPointer<vizActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
@@ -406,25 +409,28 @@ template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast<cv::viz::WCoordinate
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// polyline widget implementation
|
/// polyline widget implementation
|
||||||
|
|
||||||
struct cv::viz::WPolyLine::CopyImpl
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
template<typename _Tp>
|
struct PolyLineUtils
|
||||||
static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer<vtkPolyLine> polyLine)
|
|
||||||
{
|
{
|
||||||
int s_chs = source.channels();
|
template<typename _Tp>
|
||||||
|
static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer<vtkPolyLine> polyLine)
|
||||||
for (int y = 0, id = 0; y < source.rows; ++y)
|
|
||||||
{
|
{
|
||||||
const _Tp* srow = source.ptr<_Tp>(y);
|
int s_chs = source.channels();
|
||||||
|
|
||||||
for (int x = 0; x < source.cols; ++x, srow += s_chs, ++id)
|
for (int y = 0, id = 0; y < source.rows; ++y)
|
||||||
{
|
{
|
||||||
*output++ = Vec<_Tp, 3>(srow);
|
const _Tp* srow = source.ptr<_Tp>(y);
|
||||||
polyLine->GetPointIds()->SetId(id,id);
|
|
||||||
|
for (int x = 0; x < source.cols; ++x, srow += s_chs, ++id)
|
||||||
|
{
|
||||||
|
*output++ = Vec<_Tp, 3>(srow);
|
||||||
|
polyLine->GetPointIds()->SetId(id,id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}}}
|
||||||
|
|
||||||
cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color)
|
cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color)
|
||||||
{
|
{
|
||||||
@@ -448,13 +454,13 @@ cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color)
|
|||||||
{
|
{
|
||||||
// Get a pointer to the beginning of the data array
|
// Get a pointer to the beginning of the data array
|
||||||
Vec3f *data_beg = vtkpoints_data<float>(points);
|
Vec3f *data_beg = vtkpoints_data<float>(points);
|
||||||
CopyImpl::copy(pointData, data_beg, polyLine);
|
PolyLineUtils::copy(pointData, data_beg, polyLine);
|
||||||
}
|
}
|
||||||
else if (pointData.depth() == CV_64F)
|
else if (pointData.depth() == CV_64F)
|
||||||
{
|
{
|
||||||
// Get a pointer to the beginning of the data array
|
// Get a pointer to the beginning of the data array
|
||||||
Vec3d *data_beg = vtkpoints_data<double>(points);
|
Vec3d *data_beg = vtkpoints_data<double>(points);
|
||||||
CopyImpl::copy(pointData, data_beg, polyLine);
|
PolyLineUtils::copy(pointData, data_beg, polyLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
|
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
|
||||||
@@ -486,36 +492,39 @@ template<> cv::viz::WPolyLine cv::viz::Widget::cast<cv::viz::WPolyLine>()
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// grid widget implementation
|
/// grid widget implementation
|
||||||
|
|
||||||
struct cv::viz::WGrid::GridImpl
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
static vtkSmartPointer<vtkPolyData> createGrid(const Vec2i &dimensions, const Vec2d &spacing)
|
struct GridUtils
|
||||||
{
|
{
|
||||||
// Create the grid using image data
|
static vtkSmartPointer<vtkPolyData> createGrid(const Vec2i &dimensions, const Vec2d &spacing)
|
||||||
vtkSmartPointer<vtkImageData> grid = vtkSmartPointer<vtkImageData>::New();
|
{
|
||||||
|
// Create the grid using image data
|
||||||
|
vtkSmartPointer<vtkImageData> grid = vtkSmartPointer<vtkImageData>::New();
|
||||||
|
|
||||||
// Add 1 to dimensions because in ImageData dimensions is the number of lines
|
// Add 1 to dimensions because in ImageData dimensions is the number of lines
|
||||||
// - however here it means number of cells
|
// - however here it means number of cells
|
||||||
grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1);
|
grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1);
|
||||||
grid->SetSpacing(spacing[0], spacing[1], 0.);
|
grid->SetSpacing(spacing[0], spacing[1], 0.);
|
||||||
|
|
||||||
// Set origin of the grid to be the middle of the grid
|
// Set origin of the grid to be the middle of the grid
|
||||||
grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0);
|
grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0);
|
||||||
|
|
||||||
// Extract the edges so we have the grid
|
// Extract the edges so we have the grid
|
||||||
vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
|
vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
filter->SetInputConnection(grid->GetProducerPort());
|
filter->SetInputConnection(grid->GetProducerPort());
|
||||||
#else
|
#else
|
||||||
filter->SetInputData(grid);
|
filter->SetInputData(grid);
|
||||||
#endif
|
#endif
|
||||||
filter->Update();
|
filter->Update();
|
||||||
return filter->GetOutput();
|
return filter->GetOutput();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color)
|
cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color)
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkPolyData> grid = GridImpl::createGrid(dimensions, spacing);
|
vtkSmartPointer<vtkPolyData> grid = GridUtils::createGrid(dimensions, spacing);
|
||||||
|
|
||||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
@@ -533,7 +542,7 @@ cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color
|
|||||||
|
|
||||||
cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color)
|
cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color)
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkPolyData> grid = GridImpl::createGrid(dimensions, spacing);
|
vtkSmartPointer<vtkPolyData> grid = GridUtils::createGrid(dimensions, spacing);
|
||||||
|
|
||||||
// Estimate the transform to set the normal based on the coefficients
|
// Estimate the transform to set the normal based on the coefficients
|
||||||
Vec3f normal(coefs[0], coefs[1], coefs[2]);
|
Vec3f normal(coefs[0], coefs[1], coefs[2]);
|
||||||
@@ -938,99 +947,102 @@ template<> cv::viz::WImage3D cv::viz::Widget::cast<cv::viz::WImage3D>()
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// camera position widget implementation
|
/// camera position widget implementation
|
||||||
|
|
||||||
struct cv::viz::WCameraPosition::ProjectImage
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
static void projectImage(float fovy, float far_end_height, const Mat &image,
|
struct CameraPositionUtils
|
||||||
double scale, const Color &color, vtkSmartPointer<vtkActor> actor)
|
|
||||||
{
|
{
|
||||||
// Create a camera
|
static void projectImage(float fovy, float far_end_height, const Mat &image,
|
||||||
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
|
double scale, const Color &color, vtkSmartPointer<vtkActor> actor)
|
||||||
float aspect_ratio = float(image.cols)/float(image.rows);
|
{
|
||||||
|
// Create a camera
|
||||||
|
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
|
||||||
|
float aspect_ratio = float(image.cols)/float(image.rows);
|
||||||
|
|
||||||
// Create the vtk image
|
// Create the vtk image
|
||||||
vtkSmartPointer<vtkImageData> vtk_image = vtkSmartPointer<vtkImageData>::New();
|
vtkSmartPointer<vtkImageData> vtk_image = vtkSmartPointer<vtkImageData>::New();
|
||||||
ConvertToVtkImage::convert(image, vtk_image);
|
ConvertToVtkImage::convert(image, vtk_image);
|
||||||
|
|
||||||
// Adjust a pixel of the vtk_image
|
// Adjust a pixel of the vtk_image
|
||||||
vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]);
|
vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]);
|
||||||
vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]);
|
vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]);
|
||||||
vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]);
|
vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]);
|
||||||
|
|
||||||
// Need to flip the image as the coordinates are different in OpenCV and VTK
|
// Need to flip the image as the coordinates are different in OpenCV and VTK
|
||||||
vtkSmartPointer<vtkImageFlip> flipFilter = vtkSmartPointer<vtkImageFlip>::New();
|
vtkSmartPointer<vtkImageFlip> flipFilter = vtkSmartPointer<vtkImageFlip>::New();
|
||||||
flipFilter->SetFilteredAxis(1); // Vertical flip
|
flipFilter->SetFilteredAxis(1); // Vertical flip
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
flipFilter->SetInputConnection(vtk_image->GetProducerPort());
|
flipFilter->SetInputConnection(vtk_image->GetProducerPort());
|
||||||
#else
|
#else
|
||||||
flipFilter->SetInputData(vtk_image);
|
flipFilter->SetInputData(vtk_image);
|
||||||
#endif
|
#endif
|
||||||
flipFilter->Update();
|
flipFilter->Update();
|
||||||
|
|
||||||
Vec3d plane_center(0.0, 0.0, scale);
|
Vec3d plane_center(0.0, 0.0, scale);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New();
|
vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New();
|
||||||
plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]);
|
plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]);
|
||||||
plane->SetNormal(0.0, 0.0, 1.0);
|
plane->SetNormal(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||||
transform->PreMultiply();
|
transform->PreMultiply();
|
||||||
transform->Translate(plane_center[0], plane_center[1], plane_center[2]);
|
transform->Translate(plane_center[0], plane_center[1], plane_center[2]);
|
||||||
transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0);
|
transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0);
|
||||||
transform->RotateY(180.0);
|
transform->RotateY(180.0);
|
||||||
transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]);
|
transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]);
|
||||||
|
|
||||||
// Apply the texture
|
// Apply the texture
|
||||||
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
|
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
|
||||||
texture->SetInputConnection(flipFilter->GetOutputPort());
|
texture->SetInputConnection(flipFilter->GetOutputPort());
|
||||||
|
|
||||||
vtkSmartPointer<vtkTextureMapToPlane> texturePlane = vtkSmartPointer<vtkTextureMapToPlane>::New();
|
vtkSmartPointer<vtkTextureMapToPlane> texturePlane = vtkSmartPointer<vtkTextureMapToPlane>::New();
|
||||||
texturePlane->SetInputConnection(plane->GetOutputPort());
|
texturePlane->SetInputConnection(plane->GetOutputPort());
|
||||||
|
|
||||||
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||||
transform_filter->SetTransform(transform);
|
transform_filter->SetTransform(transform);
|
||||||
transform_filter->SetInputConnection(texturePlane->GetOutputPort());
|
transform_filter->SetInputConnection(texturePlane->GetOutputPort());
|
||||||
transform_filter->Update();
|
transform_filter->Update();
|
||||||
|
|
||||||
// Create frustum
|
// Create frustum
|
||||||
camera->SetViewAngle(fovy);
|
camera->SetViewAngle(fovy);
|
||||||
camera->SetPosition(0.0,0.0,0.0);
|
camera->SetPosition(0.0,0.0,0.0);
|
||||||
camera->SetViewUp(0.0,1.0,0.0);
|
camera->SetViewUp(0.0,1.0,0.0);
|
||||||
camera->SetFocalPoint(0.0,0.0,1.0);
|
camera->SetFocalPoint(0.0,0.0,1.0);
|
||||||
camera->SetClippingRange(0.01, scale);
|
camera->SetClippingRange(0.01, scale);
|
||||||
|
|
||||||
double planesArray[24];
|
double planesArray[24];
|
||||||
camera->GetFrustumPlanes(aspect_ratio, planesArray);
|
camera->GetFrustumPlanes(aspect_ratio, planesArray);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPlanes> planes = vtkSmartPointer<vtkPlanes>::New();
|
vtkSmartPointer<vtkPlanes> planes = vtkSmartPointer<vtkPlanes>::New();
|
||||||
planes->SetFrustumPlanes(planesArray);
|
planes->SetFrustumPlanes(planesArray);
|
||||||
|
|
||||||
vtkSmartPointer<vtkFrustumSource> frustumSource =
|
vtkSmartPointer<vtkFrustumSource> frustumSource =
|
||||||
vtkSmartPointer<vtkFrustumSource>::New();
|
vtkSmartPointer<vtkFrustumSource>::New();
|
||||||
frustumSource->SetPlanes(planes);
|
frustumSource->SetPlanes(planes);
|
||||||
frustumSource->Update();
|
frustumSource->Update();
|
||||||
|
|
||||||
vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
|
vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
|
||||||
filter->SetInputConnection(frustumSource->GetOutputPort());
|
filter->SetInputConnection(frustumSource->GetOutputPort());
|
||||||
filter->Update();
|
filter->Update();
|
||||||
|
|
||||||
// Frustum needs to be textured or else it can't be combined with image
|
// Frustum needs to be textured or else it can't be combined with image
|
||||||
vtkSmartPointer<vtkTextureMapToPlane> frustum_texture = vtkSmartPointer<vtkTextureMapToPlane>::New();
|
vtkSmartPointer<vtkTextureMapToPlane> frustum_texture = vtkSmartPointer<vtkTextureMapToPlane>::New();
|
||||||
frustum_texture->SetInputConnection(filter->GetOutputPort());
|
frustum_texture->SetInputConnection(filter->GetOutputPort());
|
||||||
// Texture mapping with only one pixel from the image to have constant color
|
// Texture mapping with only one pixel from the image to have constant color
|
||||||
frustum_texture->SetSRange(0.0, 0.0);
|
frustum_texture->SetSRange(0.0, 0.0);
|
||||||
frustum_texture->SetTRange(0.0, 0.0);
|
frustum_texture->SetTRange(0.0, 0.0);
|
||||||
|
|
||||||
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||||
appendFilter->AddInputConnection(frustum_texture->GetOutputPort());
|
appendFilter->AddInputConnection(frustum_texture->GetOutputPort());
|
||||||
appendFilter->AddInputConnection(transform_filter->GetOutputPort());
|
appendFilter->AddInputConnection(transform_filter->GetOutputPort());
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
planeMapper->SetInputConnection(appendFilter->GetOutputPort());
|
planeMapper->SetInputConnection(appendFilter->GetOutputPort());
|
||||||
|
|
||||||
actor->SetMapper(planeMapper);
|
actor->SetMapper(planeMapper);
|
||||||
actor->SetTexture(texture);
|
actor->SetTexture(texture);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
cv::viz::WCameraPosition::WCameraPosition(float scale)
|
cv::viz::WCameraPosition::WCameraPosition(float scale)
|
||||||
{
|
{
|
||||||
@@ -1164,7 +1176,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, const Mat &image, fl
|
|||||||
float far_end_height = 2.0f * c_y * scale / f_y;
|
float far_end_height = 2.0f * c_y * scale / f_y;
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
ProjectImage::projectImage(fovy, far_end_height, image, scale, color, actor);
|
CameraPositionUtils::projectImage(fovy, far_end_height, image, scale, color, actor);
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1175,7 +1187,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, const Mat &image, fl
|
|||||||
float far_end_height = 2.0 * scale * tan(fov[1] * 0.5);
|
float far_end_height = 2.0 * scale * tan(fov[1] * 0.5);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
ProjectImage::projectImage(fovy, far_end_height, image, scale, color, actor);
|
CameraPositionUtils::projectImage(fovy, far_end_height, image, scale, color, actor);
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1188,37 +1200,40 @@ template<> cv::viz::WCameraPosition cv::viz::Widget::cast<cv::viz::WCameraPositi
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// trajectory widget implementation
|
/// trajectory widget implementation
|
||||||
|
|
||||||
struct cv::viz::WTrajectory::ApplyPath
|
namespace cv { namespace viz { namespace
|
||||||
{
|
{
|
||||||
static void applyPath(vtkSmartPointer<vtkPolyData> poly_data, vtkSmartPointer<vtkAppendPolyData> append_filter, const std::vector<Affine3f> &path)
|
struct TrajectoryUtils
|
||||||
{
|
{
|
||||||
vtkIdType nr_points = path.size();
|
static void applyPath(vtkSmartPointer<vtkPolyData> poly_data, vtkSmartPointer<vtkAppendPolyData> append_filter, const std::vector<Affine3f> &path)
|
||||||
|
|
||||||
for (vtkIdType i = 0; i < nr_points; ++i)
|
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkPolyData> new_data = vtkSmartPointer<vtkPolyData>::New();
|
vtkIdType nr_points = path.size();
|
||||||
new_data->DeepCopy(poly_data);
|
|
||||||
|
|
||||||
// Transform the default coordinate frame
|
for (vtkIdType i = 0; i < nr_points; ++i)
|
||||||
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
{
|
||||||
transform->PreMultiply();
|
vtkSmartPointer<vtkPolyData> new_data = vtkSmartPointer<vtkPolyData>::New();
|
||||||
vtkSmartPointer<vtkMatrix4x4> mat_trans = vtkSmartPointer<vtkMatrix4x4>::New();
|
new_data->DeepCopy(poly_data);
|
||||||
mat_trans = convertToVtkMatrix(path[i].matrix);
|
|
||||||
transform->SetMatrix(mat_trans);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkTransformPolyDataFilter> filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
// Transform the default coordinate frame
|
||||||
|
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||||
|
transform->PreMultiply();
|
||||||
|
vtkSmartPointer<vtkMatrix4x4> mat_trans = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||||
|
mat_trans = convertToVtkMatrix(path[i].matrix);
|
||||||
|
transform->SetMatrix(mat_trans);
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkTransformPolyDataFilter> filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||||
#if VTK_MAJOR_VERSION <= 5
|
#if VTK_MAJOR_VERSION <= 5
|
||||||
filter->SetInput(new_data);
|
filter->SetInput(new_data);
|
||||||
#else
|
#else
|
||||||
filter->SetInputData(new_data);
|
filter->SetInputData(new_data);
|
||||||
#endif
|
#endif
|
||||||
filter->SetTransform(transform);
|
filter->SetTransform(transform);
|
||||||
filter->Update();
|
filter->Update();
|
||||||
|
|
||||||
append_filter->AddInputConnection(filter->GetOutputPort());
|
append_filter->AddInputConnection(filter->GetOutputPort());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}}}
|
||||||
|
|
||||||
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, int display_mode, const Color &color, float scale)
|
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, int display_mode, const Color &color, float scale)
|
||||||
{
|
{
|
||||||
@@ -1303,7 +1318,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, int display
|
|||||||
axes_tubes->SetNumberOfSides(6);
|
axes_tubes->SetNumberOfSides(6);
|
||||||
axes_tubes->Update();
|
axes_tubes->Update();
|
||||||
|
|
||||||
ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path);
|
TrajectoryUtils::applyPath(axes_tubes->GetOutput(), appendFilter, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
@@ -1348,7 +1363,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Matx3
|
|||||||
filter->Update();
|
filter->Update();
|
||||||
|
|
||||||
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||||
ApplyPath::applyPath(filter->GetOutput(), appendFilter, path);
|
TrajectoryUtils::applyPath(filter->GetOutput(), appendFilter, path);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
||||||
@@ -1388,7 +1403,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Vec2f
|
|||||||
filter->Update();
|
filter->Update();
|
||||||
|
|
||||||
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||||
ApplyPath::applyPath(filter->GetOutput(), appendFilter, path);
|
TrajectoryUtils::applyPath(filter->GetOutput(), appendFilter, path);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
mapper->SetInputConnection(appendFilter->GetOutputPort());
|
||||||
|
@@ -303,27 +303,6 @@ void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> p
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// widget3D implementation
|
/// widget3D implementation
|
||||||
|
|
||||||
struct cv::viz::Widget3D::MatrixConverter
|
|
||||||
{
|
|
||||||
static Matx44f convertToMatx(const vtkSmartPointer<vtkMatrix4x4>& vtk_matrix)
|
|
||||||
{
|
|
||||||
Matx44f m;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
for (int k = 0; k < 4; k++)
|
|
||||||
m(i, k) = vtk_matrix->GetElement(i, k);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
static vtkSmartPointer<vtkMatrix4x4> convertToVtkMatrix(const Matx44f& m)
|
|
||||||
{
|
|
||||||
vtkSmartPointer<vtkMatrix4x4> vtk_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
for (int k = 0; k < 4; k++)
|
|
||||||
vtk_matrix->SetElement(i, k, m(i, k));
|
|
||||||
return vtk_matrix;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void cv::viz::Widget3D::setPose(const Affine3f &pose)
|
void cv::viz::Widget3D::setPose(const Affine3f &pose)
|
||||||
{
|
{
|
||||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
|
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||||
@@ -345,10 +324,9 @@ void cv::viz::Widget3D::updatePose(const Affine3f &pose)
|
|||||||
setPose(pose);
|
setPose(pose);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix);
|
|
||||||
|
|
||||||
Affine3f updated_pose = pose * Affine3f(matrix_cv);
|
Affine3f updated_pose = pose * Affine3f(convertToMatx(matrix));
|
||||||
matrix = MatrixConverter::convertToVtkMatrix(updated_pose.matrix);
|
matrix = convertToVtkMatrix(updated_pose.matrix);
|
||||||
|
|
||||||
actor->SetUserMatrix(matrix);
|
actor->SetUserMatrix(matrix);
|
||||||
actor->Modified();
|
actor->Modified();
|
||||||
@@ -358,10 +336,7 @@ cv::Affine3f cv::viz::Widget3D::getPose() const
|
|||||||
{
|
{
|
||||||
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
|
vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||||
CV_Assert("Widget is not 3D." && actor);
|
CV_Assert("Widget is not 3D." && actor);
|
||||||
|
return Affine3f(convertToMatx(actor->GetUserMatrix()));
|
||||||
vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
|
|
||||||
Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix);
|
|
||||||
return Affine3f(matrix_cv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::viz::Widget3D::setColor(const Color &color)
|
void cv::viz::Widget3D::setColor(const Color &color)
|
||||||
|
Reference in New Issue
Block a user