From e2ef558c8a85cc3258a87c0d525f286a37704097 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 12 Jan 2014 15:22:26 +0400 Subject: [PATCH] refactored WGrid --- modules/viz/doc/widget.rst | 35 ++++---- modules/viz/include/opencv2/viz/widgets.hpp | 13 +-- modules/viz/src/shapes.cpp | 129 ++++++---------------------- modules/viz/test/tests_simple.cpp | 2 + 4 files changed, 55 insertions(+), 124 deletions(-) diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index bec5188..1340997 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -291,13 +291,14 @@ Constructs a default plane with center point at origin and normal oriented along :param color: :ocv:class:`Color` of the plane. viz::WPlane::WPlane +------------------- Constructs a repositioned plane -.. ocv:function:: WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_plane_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); +.. ocv:function:: WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); :param center: Center of the plane :param normal: Plane normal orientation - :param new_plane_yaxis: Up-vector. New orientation of plane y-axis. + :param new_yaxis: Up-vector. New orientation of plane y-axis. :param color: :ocv:class:`Color` of the plane. viz::WSphere @@ -388,7 +389,7 @@ Constructs repositioned planar circle. viz::WCone ------------------ +------------------------------- .. ocv:class:: WCone This 3D Widget defines a cone. :: @@ -527,28 +528,32 @@ This 3D Widget defines a grid. :: class CV_EXPORTS WGrid : public Widget3D { public: - //! Creates grid at the origin - WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); - //! Creates grid based on the plane equation - WGrid(const Vec4d &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + //! Creates grid at the origin and normal oriented along z-axis + WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); + + //! Creates repositioned grid + WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, + const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); }; viz::WGrid::WGrid --------------------------- Constructs a WGrid. -.. ocv:function:: WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) +.. ocv:function:: WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); - :param dimensions: Number of columns and rows, respectively. - :param spacing: Size of each column and row, respectively. + :param cells: Number of cell columns and rows, respectively. + :param cells_spacing: Size of each cell, respectively. :param color: :ocv:class:`Color` of the grid. -.. ocv:function: WGrid(const Vec4d &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) +.. ocv:function: WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, Vec2i &cells, const Vec2d &cells_spacing, const Color &color; - :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. - :param dimensions: Number of columns and rows, respectively. - :param spacing: Size of each column and row, respectively. - :param color: :ocv:class:`Color` of the grid. + :param center: Center of the grid + :param normal: Grid normal orientation + :param new_yaxis: Up-vector. New orientation of grid y-axis. + :param cells: Number of cell columns and rows, respectively. + :param cells_spacing: Size of each cell, respectively. + :param color: :ocv:class:`Color` of the grid.. viz::WText3D ------------ diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index f740a62..ec17f65 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -149,7 +149,8 @@ namespace cv WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); //! repositioned plane - WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_plane_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); + WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, + const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); }; class CV_EXPORTS WSphere : public Widget3D @@ -257,10 +258,12 @@ namespace cv class CV_EXPORTS WGrid : public Widget3D { public: - //! Creates grid at the origin - WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); - //! Creates grid based on the plane equation - WGrid(const Vec4d &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + //! Creates grid at the origin and normal oriented along z-axis + WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); + + //! Creates repositioned grid + WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, + const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); }; class CV_EXPORTS WCameraPosition : public Widget3D diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index 468022f..7124d40 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -144,10 +144,10 @@ cv::viz::WPlane::WPlane(const Size2d& size, const Color &color) setColor(color); } -cv::viz::WPlane::WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_plane_yaxis, const Size2d& size, const Color &color) +cv::viz::WPlane::WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Size2d& size, const Color &color) { Vec3d zvec = normalize(normal); - Vec3d xvec = normalize(new_plane_yaxis.cross(zvec)); + Vec3d xvec = normalize(new_yaxis.cross(zvec)); Vec3d yvec = zvec.cross(xvec); WPlane plane(size, color); @@ -155,51 +155,6 @@ cv::viz::WPlane::WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& *this = plane; } -cv::viz::WPlane::WPlane(const Vec4d& coefs, double size, const Color &color) -{ - vtkSmartPointer plane = vtkSmartPointer::New(); - plane->SetNormal(coefs[0], coefs[1], coefs[2]); - double norm = cv::norm(Vec3d(coefs.val)); - plane->Push(-coefs[3] / norm); - - Vec3d p_center; - plane->GetOrigin(p_center.val); - - - vtkSmartPointer filter = PlaneUtils::setSize(p_center, plane->GetOutputPort(), size); - filter->Update(); - - vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, filter->GetOutput()); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - - WidgetAccessor::setProp(*this, actor); - setColor(color); -} - -cv::viz::WPlane::WPlane(const Vec4d& coefs, const Point3d& pt, double size, const Color &color) -{ - vtkSmartPointer plane = vtkSmartPointer::New(); - Point3d coefs3(coefs[0], coefs[1], coefs[2]); - double norm_sqr = 1.0 / coefs3.dot(coefs3); - plane->SetNormal(coefs[0], coefs[1], coefs[2]); - - double t = coefs3.dot(pt) + coefs[3]; - Vec3d p_center = pt - coefs3 * t * norm_sqr; - plane->SetCenter(p_center[0], p_center[1], p_center[2]); - - vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInputConnection(PlaneUtils::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - - WidgetAccessor::setProp(*this, actor); - setColor(color); -} - template<> cv::viz::WPlane cv::viz::Widget::cast() { Widget3D widget = this->cast(); @@ -500,38 +455,26 @@ template<> cv::viz::WPolyLine cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// grid widget implementation -namespace cv { namespace viz { namespace -{ - struct GridUtils - { - static vtkSmartPointer createGrid(const Vec2i &dimensions, const Vec2f &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.); - - // 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(); - filter->SetInputConnection(grid->GetProducerPort()); - filter->Update(); - return filter->GetOutput(); - } - }; -}}} -cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color) +cv::viz::WGrid::WGrid(const Vec2i &cells, const Vec2d &cells_spacing, const Color &color) { - vtkSmartPointer grid = GridUtils::createGrid(dimensions, spacing); + vtkSmartPointer grid_data = vtkSmartPointer::New(); + + // Add 1 to dimensions because in ImageData dimensions is the number of lines + // - however here it means number of cells + grid_data->SetDimensions(cells[0]+1, cells[1]+1, 1); + grid_data->SetSpacing(cells_spacing[0], cells_spacing[1], 0.); + + // Set origin of the grid to be the middle of the grid + grid_data->SetOrigin(cells[0] * cells_spacing[0] * (-0.5), cells[1] * cells_spacing[1] * (-0.5), 0); + + // Extract the edges so we have the grid + vtkSmartPointer extract_edges = vtkSmartPointer::New(); + extract_edges->SetInputConnection(grid_data->GetProducerPort()); + extract_edges->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, grid); + VtkUtils::SetInputData(mapper, extract_edges->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -540,37 +483,15 @@ cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color setColor(color); } -cv::viz::WGrid::WGrid(const Vec4d &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color) +cv::viz::WGrid::WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Vec2i &cells, const Vec2d &cells_spacing, const Color &color) { - vtkSmartPointer grid = GridUtils::createGrid(dimensions, spacing); - - // Estimate the transform to set the normal based on the coefficients - Vec3d normal(coefs[0], coefs[1], coefs[2]); - Vec3d up_vector(0.0, 1.0, 0.0); // Just set as default - double push_distance = -coefs[3]/cv::norm(Vec3d(coefs.val)); - Vec3d n = normalize(normal); - Vec3d u = normalize(up_vector.cross(n)); - Vec3d v = n.cross(u); - - Affine3d pose = makeTransformToGlobal(u, v, n, n * push_distance); - - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - transform->SetMatrix(vtkmatrix(pose.matrix)); - - vtkSmartPointer transform_filter = vtkSmartPointer::New(); - transform_filter->SetTransform(transform); - transform_filter->SetInputConnection(grid->GetProducerPort()); - transform_filter->Update(); - - vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, transform_filter->GetOutput()); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); + Vec3d zvec = normalize(normal); + Vec3d xvec = normalize(new_yaxis.cross(zvec)); + Vec3d yvec = zvec.cross(xvec); - WidgetAccessor::setProp(*this, actor); - setColor(color); + WGrid grid(cells, cells_spacing, color); + grid.applyTransform(makeTransformToGlobal(xvec, yvec, zvec, center)); + *this = grid; } template<> cv::viz::WGrid cv::viz::Widget::cast() diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp index 85cdeac..db105d7 100644 --- a/modules/viz/test/tests_simple.cpp +++ b/modules/viz/test/tests_simple.cpp @@ -309,6 +309,8 @@ TEST(Viz, show_simple_widgets) viz.showWidget("plane1", WPlane(Size2d(0.25, 0.75))); viz.showWidget("plane2", WPlane(Vec3d(0.5, -0.5, -0.5), Vec3d(0.0, 1.0, 1.0), Vec3d(1.0, 1.0, 0.0), Size2d(1.0, 0.5), Color::gold())); + viz.showWidget("grid1", WGrid(Vec2i(7,7), Vec2d::all(0.75), Color::gray()), Affine3d().translate(Vec3d(0.0, 0.0, -1.0))); + viz.spinOnce(1500, true); viz.getWidget("text2d").cast().setText("New simple text"); viz.getWidget("text3d").cast().setText("Updated text 3D"); -- 2.7.4