reduced exported interface names (to make IntelliSense hints less littered)
authorAnatoly Baksheev <no@email>
Sun, 1 Dec 2013 11:25:44 +0000 (15:25 +0400)
committerAnatoly Baksheev <no@email>
Sun, 19 Jan 2014 14:38:38 +0000 (18:38 +0400)
modules/viz/include/opencv2/viz/widgets.hpp
modules/viz/src/cloud_widgets.cpp
modules/viz/src/shape_widgets.cpp
modules/viz/src/widget.cpp

index f333c1d..42e0f19 100644 (file)
@@ -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<Affine3f> &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<Affine3f> &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<Widget2D>();
index 894051e..27a0285 100644 (file)
@@ -59,92 +59,96 @@ namespace cv
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// 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();
-        vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
+        static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
+        {
+            vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
+            vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
 
-        polydata->SetVerts(vertices);
+            polydata->SetVerts(vertices);
 
-        vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
-        vtkSmartPointer<vtkIdTypeArray> initcells;
-        nr_points = cloud.total();
+            vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
+            vtkSmartPointer<vtkIdTypeArray> initcells;
+            nr_points = cloud.total();
+
+            if (!points)
+            {
+                points = vtkSmartPointer<vtkPoints>::New();
+                if (cloud.depth() == CV_32F)
+                    points->SetDataTypeToFloat();
+                else if (cloud.depth() == CV_64F)
+                    points->SetDataTypeToDouble();
+                polydata->SetPoints(points);
+            }
+            points->SetNumberOfPoints(nr_points);
 
-        if (!points)
-        {
-            points = vtkSmartPointer<vtkPoints>::New();
             if (cloud.depth() == CV_32F)
-                points->SetDataTypeToFloat();
+            {
+                // 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)
-                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);
+            {
+                // 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();
+            // 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)
+            // If we have less values then we need to recreate the array
+            if (cells->GetNumberOfTuples() < nr_points)
             {
-                cells->DeepCopy(initcells);
-                cells->SetNumberOfComponents(2);
-                cells->SetNumberOfTuples(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
             {
-                // 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<vtkIdTypeArray>::New();
-                initcells->DeepCopy(cells);
             }
+
+            // Set the cells and the vertices
+            vertices->SetCells(nr_points, cells);
+            return polydata;
         }
-        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;
-    }
-};
 
 cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
 {
@@ -160,7 +164,7 @@ cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors)
     }
 
     vtkIdType nr_points;
-    vtkSmartPointer<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
+    vtkSmartPointer<vtkPolyData> 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<vtkPolyData> polydata = CreateCloudWidget::create(cloud, nr_points);
+    vtkSmartPointer<vtkPolyData> polydata = CloudUtils::create(cloud, nr_points);
 
     vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
 #if VTK_MAJOR_VERSION <= 5
@@ -242,139 +246,142 @@ template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// 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();
-        vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
+        static inline vtkSmartPointer<vtkPolyData> create(const Mat &cloud, vtkIdType &nr_points)
+        {
+            vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
+            vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
 
-        polydata->SetVerts(vertices);
+            polydata->SetVerts(vertices);
 
-        vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
-        vtkSmartPointer<vtkIdTypeArray> initcells;
-        nr_points = cloud.total();
+            vtkSmartPointer<vtkPoints> points = polydata->GetPoints();
+            vtkSmartPointer<vtkIdTypeArray> initcells;
+            nr_points = cloud.total();
+
+            if (!points)
+            {
+                points = vtkSmartPointer<vtkPoints>::New();
+                if (cloud.depth() == CV_32F)
+                    points->SetDataTypeToFloat();
+                else if (cloud.depth() == CV_64F)
+                    points->SetDataTypeToDouble();
+                polydata->SetPoints(points);
+            }
+            points->SetNumberOfPoints(nr_points);
 
-        if (!points)
-        {
-            points = vtkSmartPointer<vtkPoints>::New();
             if (cloud.depth() == CV_32F)
-                points->SetDataTypeToFloat();
+            {
+                // 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)
-                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();
+            {
+                // 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);
 
-        // If we have less values then we need to recreate the array
-        if (cells->GetNumberOfTuples() < nr_points)
-        {
-            cells = vtkSmartPointer<vtkIdTypeArray>::New();
+            // Update cells
+            vtkSmartPointer<vtkIdTypeArray> cells = vertices->GetData();
+            // If no init cells and cells has not been initialized...
+            if (!cells)
+                cells = vtkSmartPointer<vtkIdTypeArray>::New();
 
-            // If init cells is given, and there's enough data in it, use it
-            if (initcells && initcells->GetNumberOfTuples() >= nr_points)
+            // If we have less values then we need to recreate the array
+            if (cells->GetNumberOfTuples() < nr_points)
             {
-                cells->DeepCopy(initcells);
-                cells->SetNumberOfComponents(2);
-                cells->SetNumberOfTuples(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
             {
-                // 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<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
-        vertices->SetCells(nr_points, cells);
-        return polydata;
-    }
+            // Set the cells and the vertices
+            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)
+        static void createMapper(vtkSmartPointer<vtkLODActor> actor, vtkSmartPointer<vtkPolyData> poly_data, Vec3d& minmax)
         {
-            // This is the first cloud
-            vtkSmartPointer<vtkDataSetMapper> mapper_new = vtkSmartPointer<vtkDataSetMapper>::New();
+            vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper());
+            if (!mapper)
+            {
+                // This is the first cloud
+                vtkSmartPointer<vtkDataSetMapper> mapper_new = vtkSmartPointer<vtkDataSetMapper>::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<vtkIdType>(1, poly_data->GetNumberOfPoints() / 10)));
-            actor->GetProperty()->SetInterpolationToFlat();
-            actor->GetProperty()->BackfaceCullingOn();
-            actor->SetMapper(mapper_new);
-            return ;
-        }
+                actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(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<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
+            vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::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<vtkIdType>(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<vtkIdType>(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<vtkPolyData> polydata =  CreateCloudWidget::create(cloud, nr_points);
+    vtkSmartPointer<vtkPolyData> 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<vtkPolyData> polydata =  CreateCloudWidget::create(cloud, nr_points);
+    vtkSmartPointer<vtkPolyData> polydata =  CloudCollectionUtils::create(cloud, nr_points);
 
     vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::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<cv::viz::WCloudCollection>()
@@ -480,80 +487,84 @@ template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollec
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// Cloud Normals Widget implementation
 
-struct cv::viz::WCloudNormals::ApplyCloudNormals
+namespace cv { namespace viz { namespace
 {
-    template<typename _Tp>
-    struct Impl
+    struct CloudNormalsUtils
     {
-        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));
-            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();
+            static vtkSmartPointer<vtkCellArray> applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals)
+            {
+                vtkIdType point_step = static_cast<vtkIdType>(std::sqrt(level));
+                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];
+                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);
-                const _Tp *nrow = normals.ptr<_Tp>(y);
-                for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch)
+                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;
-
-                    lines->InsertNextCell(2);
-                    lines->InsertCellPoint(2 * cell_count);
-                    lines->InsertCellPoint(2 * cell_count + 1);
-                    cell_count++;
+                    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;
             }
-            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)
+            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;
+                    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);
+                    lines->InsertNextCell(2);
+                    lines->InsertCellPoint(2 * j);
+                    lines->InsertCellPoint(2 * j + 1);
+                }
+                return lines;
             }
-            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 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<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)
 {
@@ -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<cv::viz::WCloudNormals>(
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// Mesh Widget implementation
 
-struct cv::viz::WMesh::CopyImpl
+namespace cv { namespace viz { namespace
 {
-    template<typename _Tp>
-    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());
+        template<typename _Tp>
+        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());
+            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 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);
+            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]))
+            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<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;
     }
     else
     {
         points->SetDataTypeToDouble();
         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;
     }
 
index aff3609..4823972 100644 (file)
@@ -84,25 +84,28 @@ template<> cv::viz::WLine cv::viz::Widget::cast<cv::viz::WLine>()
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// plane widget implementation
 
-struct cv::viz::WPlane::SetSizeImpl
+namespace cv { namespace viz { namespace
 {
-    template<typename _Tp>
-    static vtkSmartPointer<vtkTransformPolyDataFilter> setSize(const Vec<_Tp, 3> &center, vtkSmartPointer<vtkAlgorithmOutput> poly_data_port, double size)
+    struct PlaneUtils
     {
-        vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::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<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
-        transform_filter->SetInputConnection(poly_data_port);
-        transform_filter->SetTransform(transform);
-        transform_filter->Update();
-
-        return transform_filter;
-    }
-};
+        template<typename _Tp>
+        static vtkSmartPointer<vtkTransformPolyDataFilter> setSize(const Vec<_Tp, 3> &center, vtkSmartPointer<vtkAlgorithmOutput> poly_data_port, double size)
+        {
+            vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::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<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
+            transform_filter->SetInputConnection(poly_data_port);
+            transform_filter->SetTransform(transform);
+            transform_filter->Update();
+
+            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<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();
     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<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();
     actor->SetMapper(mapper);
@@ -406,25 +409,28 @@ template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast<cv::viz::WCoordinate
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// polyline widget implementation
 
-struct cv::viz::WPolyLine::CopyImpl
+namespace cv { namespace  viz { namespace
 {
-    template<typename _Tp>
-    static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer<vtkPolyLine> polyLine)
+    struct PolyLineUtils
     {
-        int s_chs = source.channels();
-
-        for (int y = 0, id = 0; y < source.rows; ++y)
+        template<typename _Tp>
+        static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer<vtkPolyLine> 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<float>(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<double>(points);
-        CopyImpl::copy(pointData, data_beg, polyLine);
+        PolyLineUtils::copy(pointData, data_beg, polyLine);
     }
 
     vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
@@ -486,36 +492,39 @@ template<> cv::viz::WPolyLine cv::viz::Widget::cast<cv::viz::WPolyLine>()
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// 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
-        vtkSmartPointer<vtkImageData> grid = vtkSmartPointer<vtkImageData>::New();
+        static vtkSmartPointer<vtkPolyData> createGrid(const Vec2i &dimensions, const Vec2d &spacing)
+        {
+            // 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
-        // - 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<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
+            // Extract the edges so we have the grid
+            vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::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<vtkPolyData> grid = GridImpl::createGrid(dimensions, spacing);
+    vtkSmartPointer<vtkPolyData> grid = GridUtils::createGrid(dimensions, spacing);
 
     vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::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<vtkPolyData> grid = GridImpl::createGrid(dimensions, spacing);
+    vtkSmartPointer<vtkPolyData> 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<cv::viz::WImage3D>()
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// 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<vtkActor> actor)
+    struct CameraPositionUtils
     {
-        // Create a camera
-        vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
-        float aspect_ratio = float(image.cols)/float(image.rows);
-
-        // Create the vtk image
-        vtkSmartPointer<vtkImageData> vtk_image = vtkSmartPointer<vtkImageData>::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]);
-
-        // Need to flip the image as the coordinates are different in OpenCV and VTK
-        vtkSmartPointer<vtkImageFlip> flipFilter = vtkSmartPointer<vtkImageFlip>::New();
-        flipFilter->SetFilteredAxis(1); // Vertical flip
+        static void projectImage(float fovy, float far_end_height, const Mat &image,
+                                 double scale, const Color &color, vtkSmartPointer<vtkActor> actor)
+        {
+            // Create a camera
+            vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
+            float aspect_ratio = float(image.cols)/float(image.rows);
+
+            // Create the vtk image
+            vtkSmartPointer<vtkImageData> vtk_image = vtkSmartPointer<vtkImageData>::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]);
+
+            // Need to flip the image as the coordinates are different in OpenCV and VTK
+            vtkSmartPointer<vtkImageFlip> flipFilter = vtkSmartPointer<vtkImageFlip>::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();
-
-        Vec3d plane_center(0.0, 0.0, scale);
-
-        vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New();
-        plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]);
-        plane->SetNormal(0.0, 0.0, 1.0);
-
-        vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::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<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
-        texture->SetInputConnection(flipFilter->GetOutputPort());
-
-        vtkSmartPointer<vtkTextureMapToPlane> texturePlane = vtkSmartPointer<vtkTextureMapToPlane>::New();
-        texturePlane->SetInputConnection(plane->GetOutputPort());
-
-        vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::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);
-
-        double planesArray[24];
-        camera->GetFrustumPlanes(aspect_ratio, planesArray);
-
-        vtkSmartPointer<vtkPlanes> planes = vtkSmartPointer<vtkPlanes>::New();
-        planes->SetFrustumPlanes(planesArray);
-
-        vtkSmartPointer<vtkFrustumSource> frustumSource =
-        vtkSmartPointer<vtkFrustumSource>::New();
-        frustumSource->SetPlanes(planes);
-        frustumSource->Update();
-
-        vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
-        filter->SetInputConnection(frustumSource->GetOutputPort());
-        filter->Update();
-
-        // Frustum needs to be textured or else it can't be combined with image
-        vtkSmartPointer<vtkTextureMapToPlane> frustum_texture = vtkSmartPointer<vtkTextureMapToPlane>::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<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
-        appendFilter->AddInputConnection(frustum_texture->GetOutputPort());
-        appendFilter->AddInputConnection(transform_filter->GetOutputPort());
-
-        vtkSmartPointer<vtkPolyDataMapper> planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
-        planeMapper->SetInputConnection(appendFilter->GetOutputPort());
-
-        actor->SetMapper(planeMapper);
-        actor->SetTexture(texture);
-    }
-};
+            flipFilter->Update();
+
+            Vec3d plane_center(0.0, 0.0, scale);
+
+            vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New();
+            plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]);
+            plane->SetNormal(0.0, 0.0, 1.0);
+
+            vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::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<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
+            texture->SetInputConnection(flipFilter->GetOutputPort());
+
+            vtkSmartPointer<vtkTextureMapToPlane> texturePlane = vtkSmartPointer<vtkTextureMapToPlane>::New();
+            texturePlane->SetInputConnection(plane->GetOutputPort());
+
+            vtkSmartPointer<vtkTransformPolyDataFilter> transform_filter = vtkSmartPointer<vtkTransformPolyDataFilter>::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);
+
+            double planesArray[24];
+            camera->GetFrustumPlanes(aspect_ratio, planesArray);
+
+            vtkSmartPointer<vtkPlanes> planes = vtkSmartPointer<vtkPlanes>::New();
+            planes->SetFrustumPlanes(planesArray);
+
+            vtkSmartPointer<vtkFrustumSource> frustumSource =
+            vtkSmartPointer<vtkFrustumSource>::New();
+            frustumSource->SetPlanes(planes);
+            frustumSource->Update();
+
+            vtkSmartPointer<vtkExtractEdges> filter = vtkSmartPointer<vtkExtractEdges>::New();
+            filter->SetInputConnection(frustumSource->GetOutputPort());
+            filter->Update();
+
+            // Frustum needs to be textured or else it can't be combined with image
+            vtkSmartPointer<vtkTextureMapToPlane> frustum_texture = vtkSmartPointer<vtkTextureMapToPlane>::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<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
+            appendFilter->AddInputConnection(frustum_texture->GetOutputPort());
+            appendFilter->AddInputConnection(transform_filter->GetOutputPort());
+
+            vtkSmartPointer<vtkPolyDataMapper> planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+            planeMapper->SetInputConnection(appendFilter->GetOutputPort());
+
+            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<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);
 }
 
@@ -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<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);
 }
 
@@ -1188,37 +1200,40 @@ template<> cv::viz::WCameraPosition cv::viz::Widget::cast<cv::viz::WCameraPositi
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// 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();
-
-        for (vtkIdType i = 0; i < nr_points; ++i)
+        static void applyPath(vtkSmartPointer<vtkPolyData> poly_data, vtkSmartPointer<vtkAppendPolyData> append_filter, const std::vector<Affine3f> &path)
         {
-            vtkSmartPointer<vtkPolyData> new_data = vtkSmartPointer<vtkPolyData>::New();
-            new_data->DeepCopy(poly_data);
+            vtkIdType nr_points = path.size();
 
-            // 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);
+            for (vtkIdType i = 0; i < nr_points; ++i)
+            {
+                vtkSmartPointer<vtkPolyData> new_data = vtkSmartPointer<vtkPolyData>::New();
+                new_data->DeepCopy(poly_data);
 
-            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
-            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<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->Update();
 
-        ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path);
+        TrajectoryUtils::applyPath(axes_tubes->GetOutput(), appendFilter, path);
     }
 
     vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
@@ -1348,7 +1363,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Matx3
     filter->Update();
 
     vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
-    ApplyPath::applyPath(filter->GetOutput(), appendFilter, path);
+    TrajectoryUtils::applyPath(filter->GetOutput(), appendFilter, path);
 
     vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
     mapper->SetInputConnection(appendFilter->GetOutputPort());
@@ -1388,7 +1403,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Vec2f
     filter->Update();
 
     vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
-    ApplyPath::applyPath(filter->GetOutput(), appendFilter, path);
+    TrajectoryUtils::applyPath(filter->GetOutput(), appendFilter, path);
 
     vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
     mapper->SetInputConnection(appendFilter->GetOutputPort());
index 04abdcf..5c2df04 100644 (file)
@@ -303,27 +303,6 @@ void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> p
 ///////////////////////////////////////////////////////////////////////////////////////////////
 /// 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)
 {
     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<vtkMatrix4x4> 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)