From 71c76aecc9bffefce9660008a9ac7d2e50bb7b79 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 10 Jul 2013 12:51:17 +0200 Subject: [PATCH] PolyLine widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 10 +++ modules/viz/src/simple_widgets.cpp | 82 ++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 34 ++++++--- 3 files changed, 113 insertions(+), 13 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index cf265ac48..cd1ed9453 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -106,6 +106,15 @@ namespace temp_viz CoordinateSystemWidget(double scale, const Affine3f& affine); }; + class CV_EXPORTS PolyLineWidget : public Widget3D + { + public: + PolyLineWidget(InputArray _points, const Color &color = Color::white()); + + private: + struct CopyImpl; + }; + class CV_EXPORTS TextWidget : public Widget2D { public: @@ -144,6 +153,7 @@ namespace temp_viz template<> CV_EXPORTS CircleWidget Widget::cast(); template<> CV_EXPORTS CubeWidget Widget::cast(); template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); + template<> CV_EXPORTS PolyLineWidget Widget::cast(); template<> CV_EXPORTS TextWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index db27884e8..a9ed2ef8f 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -26,14 +26,14 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C void temp_viz::LineWidget::setLineWidth(float line_width) { - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); actor->GetProperty()->SetLineWidth(line_width); } float temp_viz::LineWidget::getLineWidth() { - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); return actor->GetProperty()->GetLineWidth(); } @@ -342,6 +342,82 @@ template<> temp_viz::CoordinateSystemWidget temp_viz::Widget::cast(widget); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// polyline widget implementation + +struct temp_viz::PolyLineWidget::CopyImpl +{ + template + static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) + { + int s_chs = source.channels(); + + for(int y = 0, id = 0; y < source.rows; ++y) + { + 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); + } + } + } +}; + +temp_viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &color) +{ + Mat pointData = _pointData.getMat(); + CV_Assert(pointData.type() == CV_32FC3 || pointData.type() == CV_32FC4 || pointData.type() == CV_64FC3 || pointData.type() == CV_64FC4); + vtkIdType nr_points = pointData.total(); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer polyData = vtkSmartPointer::New (); + vtkSmartPointer polyLine = vtkSmartPointer::New (); + + if (pointData.depth() == CV_32F) + points->SetDataTypeToFloat(); + else + points->SetDataTypeToDouble(); + + points->SetNumberOfPoints(nr_points); + polyLine->GetPointIds()->SetNumberOfIds(nr_points); + + if (pointData.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + CopyImpl::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); + } + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(polyLine); + + polyData->SetPoints(points); + polyData->SetLines(cells); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polyData); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> temp_viz::PolyLineWidget temp_viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation @@ -398,8 +474,6 @@ struct temp_viz::CloudWidget::CreateCloudWidget vtkSmartPointer points = polydata->GetPoints(); vtkSmartPointer initcells; nr_points = cloud.total(); - - points = polydata->GetPoints (); if (!points) { diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 76993d160..fb8a9f6da 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -112,16 +112,32 @@ TEST(Viz_viz3d, accuracy) v.showWidget("coordinateSystem", csw); // v.showWidget("text",tw); // v.showWidget("pcw",pcw); - v.showWidget("pcw2",pcw2); +// v.showWidget("pcw2",pcw2); - temp_viz::LineWidget lw2 = lw; +// temp_viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); // v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); temp_viz::CloudNormalsWidget cnw(cloud, normals); - v.showWidget("n", cnw); +// v.showWidget("n", cnw); + +// lw = v.getWidget("n").cast(); +// pw = v.getWidget("n").cast(); + + cv::Mat points(1, 4, CV_64FC4); + + cv::Vec4d* data = points.ptr(); + data[0] = cv::Vec4d(0.0,0.0,0.0,0.0); + data[1] = cv::Vec4d(1.0,1.0,1.0,1.0); + data[2] = cv::Vec4d(0.0,2.0,0.0,0.0); + data[3] = cv::Vec4d(3.0,4.0,1.0,1.0); + points = points.reshape(0, 2); + + temp_viz::PolyLineWidget plw(points); + v.showWidget("polyline",plw); + lw = v.getWidget("polyline").cast(); while(!v.wasStopped()) { @@ -129,25 +145,25 @@ TEST(Viz_viz3d, accuracy) cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); cv::Affine3f cloudPosition2(angle_x, angle_y, angle_z, cv::Vec3f(pos_x+0.2, pos_y+0.2, pos_z+0.2)); - lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); - lw.setLineWidth(lw.getLineWidth()+pos_x * 10); +// lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + lw.setLineWidth(pos_x * 10); - pw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + plw.setColor(temp_viz::Color(col_blue, col_green, col_red)); sw.setPose(cloudPosition); // pw.setPose(cloudPosition); aw.setPose(cloudPosition); cw.setPose(cloudPosition); cyw.setPose(cloudPosition); - lw.setPose(cloudPosition); +// lw.setPose(cloudPosition); cuw.setPose(cloudPosition); // cnw.setPose(cloudPosition); // v.showWidget("pcw",pcw, cloudPosition); // v.showWidget("pcw2",pcw2, cloudPosition2); // v.showWidget("plane", pw, cloudPosition); - v.setWidgetPose("n",cloudPosition); - v.setWidgetPose("pcw2", cloudPosition); +// v.setWidgetPose("n",cloudPosition); +// v.setWidgetPose("pcw2", cloudPosition); cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red));