From f6e9b81188c634de6254136987d36c14e6fa4540 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 1 Dec 2013 15:25:44 +0400 Subject: [PATCH] reduced exported interface names (to make IntelliSense hints less littered) --- modules/viz/include/opencv2/viz/widgets.hpp | 29 -- modules/viz/src/cloud_widgets.cpp | 550 ++++++++++---------- modules/viz/src/shape_widgets.cpp | 309 +++++------ modules/viz/src/widget.cpp | 31 +- 4 files changed, 447 insertions(+), 472 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index f333c1d0b5..42e0f1968b 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -119,8 +119,6 @@ namespace cv Affine3f getPose() const; void setColor(const Color &color); - private: - struct MatrixConverter; }; @@ -145,8 +143,6 @@ namespace cv public: 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()); - private: - struct SetSizeImpl; }; class CV_EXPORTS WSphere : public Widget3D @@ -189,9 +185,6 @@ namespace cv { public: WPolyLine(InputArray points, const Color &color = Color::white()); - - private: - struct CopyImpl; }; class CV_EXPORTS WGrid : public Widget3D @@ -201,10 +194,6 @@ namespace cv WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); //! Creates grid based on the plane equation WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); - - private: - struct GridImpl; - }; 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()); //! 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()); - - private: - struct ProjectImage; }; class CV_EXPORTS WTrajectory : public Widget3D @@ -273,9 +259,6 @@ namespace cv WTrajectory(const std::vector &path, const Matx33f &K, float scale = 1.f, const Color &color = Color::white()); //! Displays trajectory of the given path by frustums WTrajectory(const std::vector &path, const Vec2f &fov, float scale = 1.f, const Color &color = Color::white()); - - private: - struct ApplyPath; }; class CV_EXPORTS WSpheresTrajectory: public Widget3D @@ -292,9 +275,6 @@ namespace cv WCloud(InputArray cloud, InputArray colors); //! All points in cloud have the same color WCloud(InputArray cloud, const Color &color = Color::white()); - - private: - struct CreateCloudWidget; }; class CV_EXPORTS WCloudCollection : public Widget3D @@ -306,27 +286,18 @@ namespace cv void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()); - - private: - struct CreateCloudWidget; }; class CV_EXPORTS WCloudNormals : public Widget3D { public: 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 { public: WMesh(const Mesh3d &mesh); - - private: - struct CopyImpl; }; template<> CV_EXPORTS Widget2D Widget::cast(); diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index 894051e39b..27a0285fc7 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -59,92 +59,96 @@ namespace cv /////////////////////////////////////////////////////////////////////////////////////////////// /// Point Cloud Widget implementation -struct cv::viz::WCloud::CreateCloudWidget +namespace cv { namespace viz { namespace { - static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) + struct CloudUtils { - vtkSmartPointer polydata = vtkSmartPointer::New(); - vtkSmartPointer vertices = vtkSmartPointer::New(); - - polydata->SetVerts(vertices); - - vtkSmartPointer points = polydata->GetPoints(); - vtkSmartPointer initcells; - nr_points = cloud.total(); - - if (!points) + static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { - points = vtkSmartPointer::New(); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints(points); - } - points->SetNumberOfPoints(nr_points); + vtkSmartPointer polydata = vtkSmartPointer::New(); + vtkSmartPointer vertices = vtkSmartPointer::New(); - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(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(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - } - points->SetNumberOfPoints(nr_points); + polydata->SetVerts(vertices); - // Update cells - vtkSmartPointer cells = vertices->GetData(); - // If no init cells and cells has not been initialized... - if (!cells) - cells = vtkSmartPointer::New(); + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + nr_points = cloud.total(); - // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples() < nr_points) - { - cells = vtkSmartPointer::New(); - - // If init cells is given, and there's enough data in it, use it - if (initcells && initcells->GetNumberOfTuples() >= nr_points) + if (!points) { - cells->DeepCopy(initcells); - cells->SetNumberOfComponents(2); - cells->SetNumberOfTuples(nr_points); + points = vtkSmartPointer::New(); + if (cloud.depth() == CV_32F) + 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(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(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints(nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData(); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New(); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples() < nr_points) + { + cells = vtkSmartPointer::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::New(); + initcells->DeepCopy(cells); + } } 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->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::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 - vertices->SetCells(nr_points, cells); - return polydata; - } -}; + // Set the cells and the vertices + vertices->SetCells(nr_points, cells); + return polydata; + } + }; +}}} + cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors) { @@ -160,7 +164,7 @@ cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors) } vtkIdType nr_points; - vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + vtkSmartPointer polydata = CloudUtils::create(cloud, nr_points); // Filter colors 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); vtkIdType nr_points; - vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + vtkSmartPointer polydata = CloudUtils::create(cloud, nr_points); vtkSmartPointer mapper = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 @@ -242,139 +246,142 @@ template<> cv::viz::WCloud cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// Cloud Collection Widget implementation -struct cv::viz::WCloudCollection::CreateCloudWidget +namespace cv { namespace viz { namespace { - static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) + struct CloudCollectionUtils { - vtkSmartPointer polydata = vtkSmartPointer::New(); - vtkSmartPointer vertices = vtkSmartPointer::New(); - - polydata->SetVerts(vertices); - - vtkSmartPointer points = polydata->GetPoints(); - vtkSmartPointer initcells; - nr_points = cloud.total(); - - if (!points) + static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { - points = vtkSmartPointer::New(); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints(points); - } - points->SetNumberOfPoints(nr_points); + vtkSmartPointer polydata = vtkSmartPointer::New(); + vtkSmartPointer vertices = vtkSmartPointer::New(); - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(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(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - } - points->SetNumberOfPoints(nr_points); + polydata->SetVerts(vertices); - // Update cells - vtkSmartPointer cells = vertices->GetData(); - // If no init cells and cells has not been initialized... - if (!cells) - cells = vtkSmartPointer::New(); + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + nr_points = cloud.total(); - // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples() < nr_points) - { - cells = vtkSmartPointer::New(); - - // If init cells is given, and there's enough data in it, use it - if (initcells && initcells->GetNumberOfTuples() >= nr_points) + if (!points) { - cells->DeepCopy(initcells); - cells->SetNumberOfComponents(2); - cells->SetNumberOfTuples(nr_points); + points = vtkSmartPointer::New(); + if (cloud.depth() == CV_32F) + 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(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(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints(nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData(); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New(); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples() < nr_points) + { + cells = vtkSmartPointer::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::New(); + initcells->DeepCopy(cells); + } } 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->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::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 + vertices->SetCells(nr_points, cells); + return polydata; } - // Set the cells and the vertices - vertices->SetCells(nr_points, cells); - return polydata; - } - - static void createMapper(vtkSmartPointer actor, vtkSmartPointer poly_data, Vec3d& minmax) - { - vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); - if (!mapper) + static void createMapper(vtkSmartPointer actor, vtkSmartPointer poly_data, Vec3d& minmax) { - // This is the first cloud - vtkSmartPointer mapper_new = vtkSmartPointer::New(); + vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); + if (!mapper) + { + // This is the first cloud + vtkSmartPointer mapper_new = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 - mapper_new->SetInputConnection(poly_data->GetProducerPort()); + mapper_new->SetInputConnection(poly_data->GetProducerPort()); #else - mapper_new->SetInputData(poly_data); + mapper_new->SetInputData(poly_data); #endif - mapper_new->SetScalarRange(minmax.val); - mapper_new->SetScalarModeToUsePointData(); + mapper_new->SetScalarRange(minmax.val); + 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->ScalarVisibilityOn(); - mapper_new->ImmediateModeRenderingOff(); + mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); + mapper_new->ScalarVisibilityOn(); + mapper_new->ImmediateModeRenderingOff(); - actor->SetNumberOfCloudPoints(int(std::max(1, poly_data->GetNumberOfPoints() / 10))); - actor->GetProperty()->SetInterpolationToFlat(); - actor->GetProperty()->BackfaceCullingOn(); - actor->SetMapper(mapper_new); - return ; - } + actor->SetNumberOfCloudPoints(int(std::max(1, poly_data->GetNumberOfPoints() / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper_new); + return ; + } - vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); - CV_Assert("Cloud Widget without data" && data); + vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); + CV_Assert("Cloud Widget without data" && data); - vtkSmartPointer appendFilter = vtkSmartPointer::New(); + vtkSmartPointer appendFilter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 - appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); - appendFilter->AddInputConnection(poly_data->GetProducerPort()); + appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); + appendFilter->AddInputConnection(poly_data->GetProducerPort()); #else - appendFilter->AddInputData(data); - appendFilter->AddInputData(poly_data); + appendFilter->AddInputData(data); + appendFilter->AddInputData(poly_data); #endif - mapper->SetInputConnection(appendFilter->GetOutputPort()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); - // Update the number of cloud points - vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); - actor->SetNumberOfCloudPoints(int(std::max(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10))); - } -}; + // Update the number of cloud points + vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); + actor->SetNumberOfCloudPoints(int(std::max(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10))); + } + }; +}}} cv::viz::WCloudCollection::WCloudCollection() { @@ -397,7 +404,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, } vtkIdType nr_points; - vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + vtkSmartPointer polydata = CloudCollectionUtils::create(cloud, nr_points); // Filter colors 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); 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) @@ -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); vtkIdType nr_points; - vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + vtkSmartPointer polydata = CloudCollectionUtils::create(cloud, nr_points); vtkSmartPointer scalars = vtkSmartPointer::New(); scalars->SetNumberOfComponents(3); @@ -468,7 +475,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, CV_Assert("Incompatible widget type." && actor); 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() @@ -480,80 +487,84 @@ template<> cv::viz::WCloudCollection cv::viz::Widget::cast - struct Impl + struct CloudNormalsUtils { - static vtkSmartPointer applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals) + template + struct Impl { - vtkIdType point_step = static_cast(std::sqrt(level)); - nr_normals = (static_cast((cloud.cols - 1) / point_step) + 1) * - (static_cast((cloud.rows - 1) / point_step) + 1); - vtkSmartPointer lines = vtkSmartPointer::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) + static vtkSmartPointer applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals) { - const _Tp *prow = cloud.ptr<_Tp>(y); - const _Tp *nrow = normals.ptr<_Tp>(y); - for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch) + vtkIdType point_step = static_cast(std::sqrt(level)); + nr_normals = (static_cast((cloud.cols - 1) / point_step) + 1) * + (static_cast((cloud.rows - 1) / point_step) + 1); + vtkSmartPointer lines = vtkSmartPointer::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]; - 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; + const _Tp *prow = cloud.ptr<_Tp>(y); + const _Tp *nrow = normals.ptr<_Tp>(y); + for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch) + { + pts[2 * cell_count * 3 + 0] = prow[x]; + 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 applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + vtkSmartPointer lines = vtkSmartPointer::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->InsertCellPoint(2 * cell_count); - lines->InsertCellPoint(2 * cell_count + 1); - cell_count++; + lines->InsertCellPoint(2 * j); + lines->InsertCellPoint(2 * j + 1); } + return lines; } - return lines; - } + }; - static vtkSmartPointer applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + template + static inline vtkSmartPointer apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) { - vtkSmartPointer lines = vtkSmartPointer::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->InsertCellPoint(2 * j); - lines->InsertCellPoint(2 * j + 1); - } - return lines; + if (cloud.cols > 1 && cloud.rows > 1) + return CloudNormalsUtils::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals); + else + return CloudNormalsUtils::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals); } }; - template - static inline vtkSmartPointer 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) { @@ -574,7 +585,7 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in data->SetNumberOfComponents(3); 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); points->SetData(data); } @@ -586,7 +597,7 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in data->SetNumberOfComponents(3); 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); points->SetData(data); } @@ -619,34 +630,37 @@ template<> cv::viz::WCloudNormals cv::viz::Widget::cast( /////////////////////////////////////////////////////////////////////////////////////////////// /// Mesh Widget implementation -struct cv::viz::WMesh::CopyImpl +namespace cv { namespace viz { namespace { - template - static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask) + struct MeshUtils { - 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) + template + static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask) { - 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; - *output++ = Vec<_Tp, 3>(srow); - ++index; + if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) + { + look_up[x] = index; + *output++ = Vec<_Tp, 3>(srow); + ++index; + } } + return output; } - return output; - } -}; + }; +}}} cv::viz::WMesh::WMesh(const Mesh3d &mesh) { @@ -665,14 +679,14 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) { points->SetDataTypeToFloat(); Vec3f *data_beg = vtkpoints_data(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; } else { points->SetDataTypeToDouble(); Vec3d *data_beg = vtkpoints_data(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; } diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index aff3609c95..482397251e 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -84,25 +84,28 @@ template<> cv::viz::WLine cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// plane widget implementation -struct cv::viz::WPlane::SetSizeImpl +namespace cv { namespace viz { namespace { - template - static vtkSmartPointer setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer poly_data_port, double size) + struct PlaneUtils { - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - transform->Translate(center[0], center[1], center[2]); - transform->Scale(size, size, size); - transform->Translate(-center[0], -center[1], -center[2]); + template + static vtkSmartPointer setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer poly_data_port, double size) + { + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->Translate(center[0], center[1], center[2]); + transform->Scale(size, size, size); + transform->Translate(-center[0], -center[1], -center[2]); - vtkSmartPointer transform_filter = vtkSmartPointer::New(); - transform_filter->SetInputConnection(poly_data_port); - transform_filter->SetTransform(transform); - transform_filter->Update(); + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetInputConnection(poly_data_port); + transform_filter->SetTransform(transform); + transform_filter->Update(); - return transform_filter; - } -}; + return transform_filter; + } + }; +}}} 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); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); + mapper->SetInputConnection(PlaneUtils::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); 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]); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); + mapper->SetInputConnection(PlaneUtils::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -406,25 +409,28 @@ template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast - static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) + struct PolyLineUtils { - int s_chs = source.channels(); - - for (int y = 0, id = 0; y < source.rows; ++y) + template + static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) { - 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); - polyLine->GetPointIds()->SetId(id,id); + const _Tp* srow = source.ptr<_Tp>(y); + + 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) { @@ -448,13 +454,13 @@ cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color) { // Get a pointer to the beginning of the data array Vec3f *data_beg = vtkpoints_data(points); - CopyImpl::copy(pointData, data_beg, polyLine); + PolyLineUtils::copy(pointData, data_beg, polyLine); } else if (pointData.depth() == CV_64F) { // Get a pointer to the beginning of the data array Vec3d *data_beg = vtkpoints_data(points); - CopyImpl::copy(pointData, data_beg, polyLine); + PolyLineUtils::copy(pointData, data_beg, polyLine); } vtkSmartPointer cells = vtkSmartPointer::New(); @@ -486,36 +492,39 @@ template<> cv::viz::WPolyLine cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// grid widget implementation -struct cv::viz::WGrid::GridImpl +namespace cv { namespace viz { namespace { - static vtkSmartPointer createGrid(const Vec2i &dimensions, const Vec2d &spacing) + struct GridUtils { - // Create the grid using image data - vtkSmartPointer grid = vtkSmartPointer::New(); + static vtkSmartPointer createGrid(const Vec2i &dimensions, const Vec2d &spacing) + { + // Create the grid using image data + vtkSmartPointer grid = vtkSmartPointer::New(); - // Add 1 to dimensions because in ImageData dimensions is the number of lines - // - however here it means number of cells - grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); - grid->SetSpacing(spacing[0], spacing[1], 0.); + // Add 1 to dimensions because in ImageData dimensions is the number of lines + // - however here it means number of cells + grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); + grid->SetSpacing(spacing[0], spacing[1], 0.); - // 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); + // 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); - // Extract the edges so we have the grid - vtkSmartPointer filter = vtkSmartPointer::New(); + // Extract the edges so we have the grid + vtkSmartPointer filter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 - filter->SetInputConnection(grid->GetProducerPort()); + filter->SetInputConnection(grid->GetProducerPort()); #else - filter->SetInputData(grid); + filter->SetInputData(grid); #endif - filter->Update(); - return filter->GetOutput(); - } -}; + filter->Update(); + return filter->GetOutput(); + } + }; +}}} cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { - vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); + vtkSmartPointer grid = GridUtils::createGrid(dimensions, spacing); vtkSmartPointer mapper = vtkSmartPointer::New(); #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) { - vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); + vtkSmartPointer grid = GridUtils::createGrid(dimensions, spacing); // Estimate the transform to set the normal based on the coefficients Vec3f normal(coefs[0], coefs[1], coefs[2]); @@ -938,99 +947,102 @@ template<> cv::viz::WImage3D cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// 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, - double scale, const Color &color, vtkSmartPointer actor) + struct CameraPositionUtils { - // Create a camera - vtkSmartPointer camera = vtkSmartPointer::New(); - float aspect_ratio = float(image.cols)/float(image.rows); + static void projectImage(float fovy, float far_end_height, const Mat &image, + double scale, const Color &color, vtkSmartPointer actor) + { + // Create a camera + vtkSmartPointer camera = vtkSmartPointer::New(); + float aspect_ratio = float(image.cols)/float(image.rows); - // Create the vtk image - vtkSmartPointer vtk_image = vtkSmartPointer::New(); - ConvertToVtkImage::convert(image, vtk_image); + // Create the vtk image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + ConvertToVtkImage::convert(image, 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, 1, color[1]); - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]); + // 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, 1, color[1]); + 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 - vtkSmartPointer flipFilter = vtkSmartPointer::New(); - flipFilter->SetFilteredAxis(1); // Vertical flip + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip #if VTK_MAJOR_VERSION <= 5 - flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); #else - flipFilter->SetInputData(vtk_image); + flipFilter->SetInputData(vtk_image); #endif - flipFilter->Update(); + flipFilter->Update(); - Vec3d plane_center(0.0, 0.0, scale); + Vec3d plane_center(0.0, 0.0, scale); - vtkSmartPointer plane = vtkSmartPointer::New(); - plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); - plane->SetNormal(0.0, 0.0, 1.0); + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); + plane->SetNormal(0.0, 0.0, 1.0); - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - transform->Translate(plane_center[0], plane_center[1], plane_center[2]); - transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); - transform->RotateY(180.0); - transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->Translate(plane_center[0], plane_center[1], plane_center[2]); + transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); + transform->RotateY(180.0); + transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); - // Apply the texture - vtkSmartPointer texture = vtkSmartPointer::New(); - texture->SetInputConnection(flipFilter->GetOutputPort()); + // Apply the texture + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(flipFilter->GetOutputPort()); - vtkSmartPointer texturePlane = vtkSmartPointer::New(); - texturePlane->SetInputConnection(plane->GetOutputPort()); + vtkSmartPointer texturePlane = vtkSmartPointer::New(); + texturePlane->SetInputConnection(plane->GetOutputPort()); - vtkSmartPointer transform_filter = vtkSmartPointer::New(); - transform_filter->SetTransform(transform); - transform_filter->SetInputConnection(texturePlane->GetOutputPort()); - transform_filter->Update(); + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(texturePlane->GetOutputPort()); + transform_filter->Update(); - // Create frustum - camera->SetViewAngle(fovy); - camera->SetPosition(0.0,0.0,0.0); - camera->SetViewUp(0.0,1.0,0.0); - camera->SetFocalPoint(0.0,0.0,1.0); - camera->SetClippingRange(0.01, scale); + // Create frustum + camera->SetViewAngle(fovy); + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale); - double planesArray[24]; - camera->GetFrustumPlanes(aspect_ratio, planesArray); + double planesArray[24]; + camera->GetFrustumPlanes(aspect_ratio, planesArray); - vtkSmartPointer planes = vtkSmartPointer::New(); - planes->SetFrustumPlanes(planesArray); + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); - vtkSmartPointer frustumSource = - vtkSmartPointer::New(); - frustumSource->SetPlanes(planes); - frustumSource->Update(); + vtkSmartPointer frustumSource = + vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInputConnection(frustumSource->GetOutputPort()); - filter->Update(); + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInputConnection(frustumSource->GetOutputPort()); + filter->Update(); - // Frustum needs to be textured or else it can't be combined with image - vtkSmartPointer frustum_texture = vtkSmartPointer::New(); - frustum_texture->SetInputConnection(filter->GetOutputPort()); - // Texture mapping with only one pixel from the image to have constant color - frustum_texture->SetSRange(0.0, 0.0); - frustum_texture->SetTRange(0.0, 0.0); + // Frustum needs to be textured or else it can't be combined with image + vtkSmartPointer frustum_texture = vtkSmartPointer::New(); + frustum_texture->SetInputConnection(filter->GetOutputPort()); + // Texture mapping with only one pixel from the image to have constant color + frustum_texture->SetSRange(0.0, 0.0); + frustum_texture->SetTRange(0.0, 0.0); - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - appendFilter->AddInputConnection(frustum_texture->GetOutputPort()); - appendFilter->AddInputConnection(transform_filter->GetOutputPort()); + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + appendFilter->AddInputConnection(frustum_texture->GetOutputPort()); + appendFilter->AddInputConnection(transform_filter->GetOutputPort()); - vtkSmartPointer planeMapper = vtkSmartPointer::New(); - planeMapper->SetInputConnection(appendFilter->GetOutputPort()); + vtkSmartPointer planeMapper = vtkSmartPointer::New(); + planeMapper->SetInputConnection(appendFilter->GetOutputPort()); - actor->SetMapper(planeMapper); - actor->SetTexture(texture); - } -}; + actor->SetMapper(planeMapper); + actor->SetTexture(texture); + } + }; +}}} 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; vtkSmartPointer actor = vtkSmartPointer::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); } @@ -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); vtkSmartPointer actor = vtkSmartPointer::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); } @@ -1188,37 +1200,40 @@ template<> cv::viz::WCameraPosition cv::viz::Widget::cast poly_data, vtkSmartPointer append_filter, const std::vector &path) + struct TrajectoryUtils { - vtkIdType nr_points = path.size(); - - for (vtkIdType i = 0; i < nr_points; ++i) + static void applyPath(vtkSmartPointer poly_data, vtkSmartPointer append_filter, const std::vector &path) { - vtkSmartPointer new_data = vtkSmartPointer::New(); - new_data->DeepCopy(poly_data); + vtkIdType nr_points = path.size(); - // Transform the default coordinate frame - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - vtkSmartPointer mat_trans = vtkSmartPointer::New(); - mat_trans = convertToVtkMatrix(path[i].matrix); - transform->SetMatrix(mat_trans); + for (vtkIdType i = 0; i < nr_points; ++i) + { + vtkSmartPointer new_data = vtkSmartPointer::New(); + new_data->DeepCopy(poly_data); - vtkSmartPointer filter = vtkSmartPointer::New(); + // Transform the default coordinate frame + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans = convertToVtkMatrix(path[i].matrix); + transform->SetMatrix(mat_trans); + + vtkSmartPointer filter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 - filter->SetInput(new_data); + filter->SetInput(new_data); #else - filter->SetInputData(new_data); + filter->SetInputData(new_data); #endif - filter->SetTransform(transform); - filter->Update(); + filter->SetTransform(transform); + filter->Update(); - append_filter->AddInputConnection(filter->GetOutputPort()); + append_filter->AddInputConnection(filter->GetOutputPort()); + } } - } -}; + }; +}}} cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display_mode, const Color &color, float scale) { @@ -1303,7 +1318,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display axes_tubes->SetNumberOfSides(6); axes_tubes->Update(); - ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path); + TrajectoryUtils::applyPath(axes_tubes->GetOutput(), appendFilter, path); } vtkSmartPointer mapper = vtkSmartPointer::New(); @@ -1348,7 +1363,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Matx3 filter->Update(); vtkSmartPointer appendFilter = vtkSmartPointer::New(); - ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); + TrajectoryUtils::applyPath(filter->GetOutput(), appendFilter, path); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(appendFilter->GetOutputPort()); @@ -1388,7 +1403,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Vec2f filter->Update(); vtkSmartPointer appendFilter = vtkSmartPointer::New(); - ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); + TrajectoryUtils::applyPath(filter->GetOutput(), appendFilter, path); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(appendFilter->GetOutputPort()); diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 04abdcf7a0..5c2df04dcd 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -303,27 +303,6 @@ void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer p /////////////////////////////////////////////////////////////////////////////////////////////// /// widget3D implementation -struct cv::viz::Widget3D::MatrixConverter -{ - static Matx44f convertToMatx(const vtkSmartPointer& 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 convertToVtkMatrix(const Matx44f& m) - { - vtkSmartPointer vtk_matrix = vtkSmartPointer::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) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -345,10 +324,9 @@ void cv::viz::Widget3D::updatePose(const Affine3f &pose) setPose(pose); return ; } - Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix); - Affine3f updated_pose = pose * Affine3f(matrix_cv); - matrix = MatrixConverter::convertToVtkMatrix(updated_pose.matrix); + Affine3f updated_pose = pose * Affine3f(convertToMatx(matrix)); + matrix = convertToVtkMatrix(updated_pose.matrix); actor->SetUserMatrix(matrix); actor->Modified(); @@ -358,10 +336,7 @@ cv::Affine3f cv::viz::Widget3D::getPose() const { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget is not 3D." && actor); - - vtkSmartPointer matrix = actor->GetUserMatrix(); - Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix); - return Affine3f(matrix_cv); + return Affine3f(convertToMatx(actor->GetUserMatrix())); } void cv::viz::Widget3D::setColor(const Color &color)