Added WidgetMerger, Polyline - colors support for each point independently, simple widgets now compute color array instead of setting global color
This commit is contained in:
parent
261546f6f6
commit
1a5dfe421d
@ -1025,3 +1025,44 @@ Constructs a WMesh.
|
|||||||
:param polygons: Points of the mesh object.
|
:param polygons: Points of the mesh object.
|
||||||
:param colors: Point colors.
|
:param colors: Point colors.
|
||||||
:param normals: Point normals.
|
:param normals: Point normals.
|
||||||
|
|
||||||
|
viz::WWidgetMerger
|
||||||
|
---------------------
|
||||||
|
.. ocv:class:: WWidgetMerger
|
||||||
|
|
||||||
|
This class allos to merge several widgets to single one. It has quite limited functionality and can't merge widgets with different attributes. For instance,
|
||||||
|
if widgetA has color array and widgetB has only global color defined, then result of merge won't have color at all. The class is suitable for merging large amount of similar widgets.
|
||||||
|
|
||||||
|
class CV_EXPORTS WWidgetMerger : public Widget3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WWidgetMerger();
|
||||||
|
|
||||||
|
//! Add widget to merge with optional position change
|
||||||
|
void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity());
|
||||||
|
|
||||||
|
//! Repacks internal structure to sinle widget
|
||||||
|
void finalize();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
viz::WWidgetMerger::WWidgetMerger
|
||||||
|
---------------------------------------
|
||||||
|
Constructs a WWidgetMerger.
|
||||||
|
|
||||||
|
.. ocv:WWidgetMerger:: WWidgetMerger()
|
||||||
|
|
||||||
|
viz::WWidgetMerger::addCloud
|
||||||
|
-------------------------------
|
||||||
|
Adds a cloud to the collection.
|
||||||
|
|
||||||
|
.. ocv:function:: void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity())
|
||||||
|
|
||||||
|
:param widget: Widget to merge.
|
||||||
|
:param pose: Pose of the widget.
|
||||||
|
|
||||||
|
viz::WWidgetMerger::finalize
|
||||||
|
-------------------------------
|
||||||
|
Finalizes merger data and constructs final merged widget
|
||||||
|
|
||||||
|
.. ocv:function:: void finalize()
|
@ -201,6 +201,7 @@ namespace cv
|
|||||||
class CV_EXPORTS WPolyLine : public Widget3D
|
class CV_EXPORTS WPolyLine : public Widget3D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
WPolyLine(InputArray points, InputArray colors);
|
||||||
WPolyLine(InputArray points, const Color &color = Color::white());
|
WPolyLine(InputArray points, const Color &color = Color::white());
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -362,6 +363,19 @@ namespace cv
|
|||||||
WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray());
|
WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CV_EXPORTS WWidgetMerger : public Widget3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WWidgetMerger();
|
||||||
|
|
||||||
|
//! Add widget to merge with optional position change
|
||||||
|
void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity());
|
||||||
|
|
||||||
|
//! Repacks internal structure to sinle widget
|
||||||
|
void finalize();
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
/// Utility exports
|
/// Utility exports
|
||||||
|
|
||||||
@ -391,6 +405,7 @@ namespace cv
|
|||||||
template<> CV_EXPORTS WCloudCollection Widget::cast<WCloudCollection>();
|
template<> CV_EXPORTS WCloudCollection Widget::cast<WCloudCollection>();
|
||||||
template<> CV_EXPORTS WCloudNormals Widget::cast<WCloudNormals>();
|
template<> CV_EXPORTS WCloudNormals Widget::cast<WCloudNormals>();
|
||||||
template<> CV_EXPORTS WMesh Widget::cast<WMesh>();
|
template<> CV_EXPORTS WMesh Widget::cast<WMesh>();
|
||||||
|
template<> CV_EXPORTS WWidgetMerger Widget::cast<WWidgetMerger>();
|
||||||
|
|
||||||
} /* namespace viz */
|
} /* namespace viz */
|
||||||
} /* namespace cv */
|
} /* namespace cv */
|
||||||
|
@ -193,8 +193,21 @@ template<> cv::viz::WPaintedCloud cv::viz::Widget::cast<cv::viz::WPaintedCloud>(
|
|||||||
|
|
||||||
cv::viz::WCloudCollection::WCloudCollection()
|
cv::viz::WCloudCollection::WCloudCollection()
|
||||||
{
|
{
|
||||||
// Just create the actor
|
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
|
mapper->SetInputConnection(append_filter->GetOutputPort());
|
||||||
|
mapper->SetScalarModeToUsePointData();
|
||||||
|
mapper->ImmediateModeRenderingOff();
|
||||||
|
mapper->SetScalarRange(0, 255);
|
||||||
|
mapper->ScalarVisibilityOn();
|
||||||
|
|
||||||
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
|
||||||
|
actor->SetNumberOfCloudPoints(1);
|
||||||
|
actor->GetProperty()->SetInterpolationToFlat();
|
||||||
|
actor->GetProperty()->BackfaceCullingOn();
|
||||||
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,33 +219,11 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, co
|
|||||||
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose);
|
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose);
|
||||||
|
|
||||||
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||||
CV_Assert("Incompatible widget type." && actor);
|
CV_Assert("Correctness check." && actor);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
|
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
|
||||||
if (!mapper)
|
|
||||||
{
|
|
||||||
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
|
|
||||||
VtkUtils::AddInputData(append_filter, polydata);
|
|
||||||
|
|
||||||
// This is the first cloud
|
|
||||||
mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
|
||||||
mapper->SetScalarRange(0, 255);
|
|
||||||
mapper->SetScalarModeToUsePointData();
|
|
||||||
mapper->ScalarVisibilityOn();
|
|
||||||
mapper->ImmediateModeRenderingOff();
|
|
||||||
mapper->SetInputConnection(append_filter->GetOutputPort());
|
|
||||||
|
|
||||||
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, polydata->GetNumberOfPoints()/10));
|
|
||||||
actor->GetProperty()->SetInterpolationToFlat();
|
|
||||||
actor->GetProperty()->BackfaceCullingOn();
|
|
||||||
actor->SetMapper(mapper);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkAlgorithm> producer = mapper->GetInputConnection(0, 0)->GetProducer();
|
|
||||||
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
|
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
|
||||||
VtkUtils::AddInputData(append_filter, polydata);
|
VtkUtils::AddInputData(append_filter, polydata);
|
||||||
append_filter->Modified();
|
|
||||||
|
|
||||||
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10));
|
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10));
|
||||||
}
|
}
|
||||||
@ -257,7 +248,6 @@ void cv::viz::WCloudCollection::finalize()
|
|||||||
vtkSmartPointer<vtkPolyData> polydata = append_filter->GetOutput();
|
vtkSmartPointer<vtkPolyData> polydata = append_filter->GetOutput();
|
||||||
mapper->RemoveInputConnection(0, 0);
|
mapper->RemoveInputConnection(0, 0);
|
||||||
VtkUtils::SetInputData(mapper, polydata);
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
mapper->Modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
|
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
|
||||||
@ -332,20 +322,18 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
||||||
polyData->SetPoints(points);
|
polydata->SetPoints(points);
|
||||||
polyData->SetLines(lines);
|
polydata->SetLines(lines);
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
|
||||||
mapper->SetColorModeToMapScalars();
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
mapper->SetScalarModeToUsePointData();
|
|
||||||
VtkUtils::SetInputData(mapper, polyData);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
|
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
|
||||||
@ -455,3 +443,63 @@ template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast<cv::viz::WMesh>()
|
|||||||
Widget3D widget = this->cast<Widget3D>();
|
Widget3D widget = this->cast<Widget3D>();
|
||||||
return static_cast<WMesh&>(widget);
|
return static_cast<WMesh&>(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Widget Merger implementation
|
||||||
|
|
||||||
|
cv::viz::WWidgetMerger::WWidgetMerger()
|
||||||
|
{
|
||||||
|
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
|
mapper->SetInputConnection(append_filter->GetOutputPort());
|
||||||
|
mapper->SetScalarModeToUsePointData();
|
||||||
|
mapper->ImmediateModeRenderingOff();
|
||||||
|
mapper->SetScalarRange(0, 255);
|
||||||
|
mapper->ScalarVisibilityOn();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
|
actor->GetProperty()->SetInterpolationToFlat();
|
||||||
|
actor->GetProperty()->BackfaceCullingOn();
|
||||||
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
|
WidgetAccessor::setProp(*this, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cv::viz::WWidgetMerger::addWidget(const Widget3D& widget, const Affine3d &pose)
|
||||||
|
{
|
||||||
|
vtkActor *widget_actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(widget));
|
||||||
|
CV_Assert("Widget is not 3D actor." && widget_actor);
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyDataMapper> widget_mapper = vtkPolyDataMapper::SafeDownCast(widget_actor->GetMapper());
|
||||||
|
CV_Assert("Widget doesn't have a polydata mapper" && widget_mapper);
|
||||||
|
widget_mapper->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||||
|
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
|
||||||
|
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
|
||||||
|
CV_Assert("Correctness check" && append_filter);
|
||||||
|
|
||||||
|
VtkUtils::AddInputData(append_filter, VtkUtils::TransformPolydata(widget_mapper->GetInput(), pose));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cv::viz::WWidgetMerger::finalize()
|
||||||
|
{
|
||||||
|
vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
|
||||||
|
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
|
||||||
|
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
|
||||||
|
CV_Assert("Correctness check" && append_filter);
|
||||||
|
append_filter->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
|
||||||
|
mapper->RemoveInputConnection(0, 0);
|
||||||
|
VtkUtils::SetInputData(mapper, append_filter->GetOutput());
|
||||||
|
mapper->Modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> CV_EXPORTS cv::viz::WWidgetMerger cv::viz::Widget::cast<cv::viz::WWidgetMerger>()
|
||||||
|
{
|
||||||
|
Widget3D widget = this->cast<Widget3D>();
|
||||||
|
return static_cast<WWidgetMerger&>(widget);
|
||||||
|
}
|
||||||
|
@ -272,6 +272,11 @@ namespace cv
|
|||||||
return scalars;
|
return scalars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static vtkSmartPointer<vtkPolyData> FillScalars(vtkSmartPointer<vtkPolyData> polydata, const Color& color)
|
||||||
|
{
|
||||||
|
return polydata->GetPointData()->SetScalars(FillScalars(polydata->GetNumberOfPoints(), color)), polydata;
|
||||||
|
}
|
||||||
|
|
||||||
static vtkSmartPointer<vtkPolyData> ComputeNormals(vtkSmartPointer<vtkPolyData> polydata)
|
static vtkSmartPointer<vtkPolyData> ComputeNormals(vtkSmartPointer<vtkPolyData> polydata)
|
||||||
{
|
{
|
||||||
vtkSmartPointer<vtkPolyDataNormals> normals_generator = vtkSmartPointer<vtkPolyDataNormals>::New();
|
vtkSmartPointer<vtkPolyDataNormals> normals_generator = vtkSmartPointer<vtkPolyDataNormals>::New();
|
||||||
|
@ -54,14 +54,16 @@ cv::viz::WLine::WLine(const Point3d &pt1, const Point3d &pt2, const Color &color
|
|||||||
line->SetPoint2(pt2.x, pt2.y, pt2.z);
|
line->SetPoint2(pt2.x, pt2.y, pt2.z);
|
||||||
line->Update();
|
line->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = line->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, line->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WLine cv::viz::Widget::cast<cv::viz::WLine>()
|
template<> cv::viz::WLine cv::viz::Widget::cast<cv::viz::WLine>()
|
||||||
@ -83,14 +85,16 @@ cv::viz::WSphere::WSphere(const Point3d ¢er, double radius, int sphere_resol
|
|||||||
sphere->LatLongTessellationOff();
|
sphere->LatLongTessellationOff();
|
||||||
sphere->Update();
|
sphere->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = sphere->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, sphere->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WSphere cv::viz::Widget::cast<cv::viz::WSphere>()
|
template<> cv::viz::WSphere cv::viz::Widget::cast<cv::viz::WSphere>()
|
||||||
@ -110,15 +114,17 @@ cv::viz::WPlane::WPlane(const Size2d& size, const Color &color)
|
|||||||
plane->SetPoint2(-0.5 * size.width, 0.5 * size.height, 0.0);
|
plane->SetPoint2(-0.5 * size.width, 0.5 * size.height, 0.0);
|
||||||
plane->Update();
|
plane->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = plane->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, plane->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
actor->GetProperty()->LightingOff();
|
actor->GetProperty()->LightingOff();
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::viz::WPlane::WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_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)
|
||||||
@ -161,6 +167,7 @@ cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness
|
|||||||
Affine3d transform_with_scale(R * length, start_point);
|
Affine3d transform_with_scale(R * length, start_point);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(arrow_source->GetOutputPort(), transform_with_scale);
|
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(arrow_source->GetOutputPort(), transform_with_scale);
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, polydata);
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
@ -169,7 +176,6 @@ cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness
|
|||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WArrow cv::viz::Widget::cast<cv::viz::WArrow>()
|
template<> cv::viz::WArrow cv::viz::Widget::cast<cv::viz::WArrow>()
|
||||||
@ -189,16 +195,17 @@ cv::viz::WCircle::WCircle(double radius, double thickness, const Color &color)
|
|||||||
disk->SetOuterRadius(radius + thickness);
|
disk->SetOuterRadius(radius + thickness);
|
||||||
disk->Update();
|
disk->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = disk->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, disk->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->GetProperty()->LightingOff();
|
actor->GetProperty()->LightingOff();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::viz::WCircle::WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness, const Color &color)
|
cv::viz::WCircle::WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness, const Color &color)
|
||||||
@ -231,14 +238,16 @@ cv::viz::WCone::WCone(double length, double radius, int resolution, const Color
|
|||||||
cone_source->SetResolution(resolution);
|
cone_source->SetResolution(resolution);
|
||||||
cone_source->Update();
|
cone_source->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = cone_source->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, cone_source->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::viz::WCone::WCone(double radius, const Point3d& center, const Point3d& tip, int resolution, const Color &color)
|
cv::viz::WCone::WCone(double radius, const Point3d& center, const Point3d& tip, int resolution, const Color &color)
|
||||||
@ -274,14 +283,16 @@ cv::viz::WCylinder::WCylinder(const Point3d& axis_point1, const Point3d& axis_po
|
|||||||
tuber->SetRadius(radius);
|
tuber->SetRadius(radius);
|
||||||
tuber->Update();
|
tuber->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = tuber->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, tuber->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WCylinder cv::viz::Widget::cast<cv::viz::WCylinder>()
|
template<> cv::viz::WCylinder cv::viz::Widget::cast<cv::viz::WCylinder>()
|
||||||
@ -315,15 +326,16 @@ cv::viz::WCube::WCube(const Point3d& min_point, const Point3d& max_point, bool w
|
|||||||
vtkCubeSource::SafeDownCast(cube)->SetBounds(bounds);
|
vtkCubeSource::SafeDownCast(cube)->SetBounds(bounds);
|
||||||
}
|
}
|
||||||
cube->Update();
|
cube->Update();
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata =cube->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, cube->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WCube cv::viz::Widget::cast<cv::viz::WCube>()
|
template<> cv::viz::WCube cv::viz::Widget::cast<cv::viz::WCube>()
|
||||||
@ -379,40 +391,21 @@ template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast<cv::viz::WCoordinate
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// polyline widget implementation
|
/// polyline widget implementation
|
||||||
|
|
||||||
cv::viz::WPolyLine::WPolyLine(InputArray _points, const Color &color)
|
cv::viz::WPolyLine::WPolyLine(InputArray points, InputArray colors)
|
||||||
{
|
{
|
||||||
CV_Assert(_points.type() == CV_32FC3 || _points.type() == CV_32FC4 || _points.type() == CV_64FC3 || _points.type() == CV_64FC4);
|
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
|
||||||
|
cloud_source->SetColorCloud(points, colors);
|
||||||
|
cloud_source->Update();
|
||||||
|
|
||||||
const float *fpoints = _points.getMat().ptr<float>();
|
vtkSmartPointer<vtkPolyData> polydata = cloud_source->GetOutput();
|
||||||
const double *dpoints = _points.getMat().ptr<double>();
|
|
||||||
size_t total = _points.total();
|
|
||||||
int s_chs = _points.channels();
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
|
||||||
points->SetDataType(_points.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE);
|
|
||||||
points->SetNumberOfPoints((vtkIdType)total);
|
|
||||||
|
|
||||||
if (_points.depth() == CV_32F)
|
|
||||||
for(size_t i = 0; i < total; ++i, fpoints += s_chs)
|
|
||||||
points->SetPoint((vtkIdType)i, fpoints);
|
|
||||||
|
|
||||||
if (_points.depth() == CV_64F)
|
|
||||||
for(size_t i = 0; i < total; ++i, dpoints += s_chs)
|
|
||||||
points->SetPoint((vtkIdType)i, dpoints);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
|
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
|
||||||
cell_array->Allocate(cell_array->EstimateSize(1, (int)total));
|
cell_array->Allocate(cell_array->EstimateSize(1, polydata->GetNumberOfPoints()));
|
||||||
cell_array->InsertNextCell((int)total);
|
cell_array->InsertNextCell(polydata->GetNumberOfPoints());
|
||||||
for(size_t i = 0; i < total; ++i)
|
for(vtkIdType i = 0; i < polydata->GetNumberOfPoints(); ++i)
|
||||||
cell_array->InsertCellPoint((vtkIdType)i);
|
cell_array->InsertCellPoint(i);
|
||||||
|
|
||||||
vtkSmartPointer<vtkUnsignedCharArray> scalars = VtkUtils::FillScalars(total, color);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
|
|
||||||
polydata->SetPoints(points);
|
|
||||||
polydata->SetLines(cell_array);
|
polydata->SetLines(cell_array);
|
||||||
polydata->GetPointData()->SetScalars(scalars);
|
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, polydata);
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
mapper->SetScalarRange(0, 255);
|
mapper->SetScalarRange(0, 255);
|
||||||
@ -423,6 +416,12 @@ cv::viz::WPolyLine::WPolyLine(InputArray _points, const Color &color)
|
|||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::viz::WPolyLine::WPolyLine(InputArray points, const Color &color)
|
||||||
|
{
|
||||||
|
WPolyLine polyline(points, Mat(points.size(), CV_8UC3, color));
|
||||||
|
*this = polyline;
|
||||||
|
}
|
||||||
|
|
||||||
template<> cv::viz::WPolyLine cv::viz::Widget::cast<cv::viz::WPolyLine>()
|
template<> cv::viz::WPolyLine cv::viz::Widget::cast<cv::viz::WPolyLine>()
|
||||||
{
|
{
|
||||||
Widget3D widget = this->cast<Widget3D>();
|
Widget3D widget = this->cast<Widget3D>();
|
||||||
@ -450,14 +449,16 @@ cv::viz::WGrid::WGrid(const Vec2i &cells, const Vec2d &cells_spacing, const Colo
|
|||||||
VtkUtils::SetInputData(extract_edges, grid_data);
|
VtkUtils::SetInputData(extract_edges, grid_data);
|
||||||
extract_edges->Update();
|
extract_edges->Update();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPolyData> polydata = extract_edges->GetOutput();
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, extract_edges->GetOutput());
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
|
||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(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)
|
cv::viz::WGrid::WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Vec2i &cells, const Vec2d &cells_spacing, const Color &color)
|
||||||
@ -807,6 +808,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const
|
|||||||
double aspect_ratio = f_y / f_x;
|
double aspect_ratio = f_y / f_x;
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale);
|
vtkSmartPointer<vtkPolyData> polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale);
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, polydata);
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
@ -815,7 +817,6 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const
|
|||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const Color &color)
|
cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const Color &color)
|
||||||
@ -824,6 +825,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const
|
|||||||
double fovy = fov[1] * 180 / CV_PI;
|
double fovy = fov[1] * 180 / CV_PI;
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale);
|
vtkSmartPointer<vtkPolyData> polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale);
|
||||||
|
VtkUtils::FillScalars(polydata, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
VtkUtils::SetInputData(mapper, polydata);
|
VtkUtils::SetInputData(mapper, polydata);
|
||||||
@ -832,7 +834,6 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const
|
|||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, InputArray _image, double scale, const Color &color)
|
cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, InputArray _image, double scale, const Color &color)
|
||||||
@ -967,6 +968,7 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Matx33
|
|||||||
source->SetTrajectory(_path);
|
source->SetTrajectory(_path);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> glyph = getPolyData(WCameraPosition(K, scale));
|
vtkSmartPointer<vtkPolyData> glyph = getPolyData(WCameraPosition(K, scale));
|
||||||
|
VtkUtils::FillScalars(glyph, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkTensorGlyph> tensor_glyph = vtkSmartPointer<vtkTensorGlyph>::New();
|
vtkSmartPointer<vtkTensorGlyph> tensor_glyph = vtkSmartPointer<vtkTensorGlyph>::New();
|
||||||
tensor_glyph->SetInputConnection(source->GetOutputPort());
|
tensor_glyph->SetInputConnection(source->GetOutputPort());
|
||||||
@ -984,7 +986,6 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Matx33
|
|||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d &fov, double scale, const Color &color)
|
cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d &fov, double scale, const Color &color)
|
||||||
@ -993,6 +994,7 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d
|
|||||||
source->SetTrajectory(_path);
|
source->SetTrajectory(_path);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPolyData> glyph = getPolyData(WCameraPosition(fov, scale));
|
vtkSmartPointer<vtkPolyData> glyph = getPolyData(WCameraPosition(fov, scale));
|
||||||
|
VtkUtils::FillScalars(glyph, color);
|
||||||
|
|
||||||
vtkSmartPointer<vtkTensorGlyph> tensor_glyph = vtkSmartPointer<vtkTensorGlyph>::New();
|
vtkSmartPointer<vtkTensorGlyph> tensor_glyph = vtkSmartPointer<vtkTensorGlyph>::New();
|
||||||
tensor_glyph->SetInputConnection(source->GetOutputPort());
|
tensor_glyph->SetInputConnection(source->GetOutputPort());
|
||||||
@ -1010,7 +1012,6 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d
|
|||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
WidgetAccessor::setProp(*this, actor);
|
WidgetAccessor::setProp(*this, actor);
|
||||||
setColor(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> cv::viz::WTrajectoryFrustums cv::viz::Widget::cast<cv::viz::WTrajectoryFrustums>()
|
template<> cv::viz::WTrajectoryFrustums cv::viz::Widget::cast<cv::viz::WTrajectoryFrustums>()
|
||||||
|
@ -156,6 +156,27 @@ TEST(Viz, show_mesh_random_colors)
|
|||||||
viz.spin();
|
viz.spin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Viz, show_widget_merger)
|
||||||
|
{
|
||||||
|
WWidgetMerger merger;
|
||||||
|
merger.addWidget(WCube(Vec3d::all(0.0), Vec3d::all(1.0), true, Color::gold()));
|
||||||
|
|
||||||
|
RNG& rng = theRNG();
|
||||||
|
for(int i = 0; i < 77; ++i)
|
||||||
|
{
|
||||||
|
Vec3b c;
|
||||||
|
rng.fill(c, RNG::NORMAL, Scalar::all(128), Scalar::all(48), true);
|
||||||
|
merger.addWidget(WSphere(Vec3d(c)*(1.0/255.0), 7.0/255.0, 10, Color(c[2], c[1], c[0])));
|
||||||
|
}
|
||||||
|
merger.finalize();
|
||||||
|
|
||||||
|
Viz3d viz("show_mesh_random_color");
|
||||||
|
viz.showWidget("coo", WCoordinateSystem());
|
||||||
|
viz.showWidget("merger", merger);
|
||||||
|
viz.showWidget("text2d", WText("Widget merger", Point(20, 20), 20, Color::green()));
|
||||||
|
viz.spin();
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Viz, show_textured_mesh)
|
TEST(Viz, show_textured_mesh)
|
||||||
{
|
{
|
||||||
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png"));
|
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png"));
|
||||||
@ -195,12 +216,18 @@ TEST(Viz, show_textured_mesh)
|
|||||||
|
|
||||||
TEST(Viz, show_polyline)
|
TEST(Viz, show_polyline)
|
||||||
{
|
{
|
||||||
Mat polyline(1, 32, CV_64FC3);
|
const Color palette[] = { Color::red(), Color::green(), Color::blue(), Color::gold(), Color::raspberry(), Color::bluberry(), Color::lime() };
|
||||||
|
size_t palette_size = sizeof(palette)/sizeof(palette[0]);
|
||||||
|
|
||||||
|
Mat polyline(1, 32, CV_64FC3), colors(1, 32, CV_8UC3);
|
||||||
for(int i = 0; i < (int)polyline.total(); ++i)
|
for(int i = 0; i < (int)polyline.total(); ++i)
|
||||||
|
{
|
||||||
polyline.at<Vec3d>(i) = Vec3d(i/16.0, cos(i * CV_PI/6), sin(i * CV_PI/6));
|
polyline.at<Vec3d>(i) = Vec3d(i/16.0, cos(i * CV_PI/6), sin(i * CV_PI/6));
|
||||||
|
colors.at<Vec3b>(i) = palette[i & palette_size];
|
||||||
|
}
|
||||||
|
|
||||||
Viz3d viz("show_polyline");
|
Viz3d viz("show_polyline");
|
||||||
viz.showWidget("polyline", WPolyLine(Mat(polyline), Color::apricot()));
|
viz.showWidget("polyline", WPolyLine(polyline, colors));
|
||||||
viz.showWidget("coosys", WCoordinateSystem());
|
viz.showWidget("coosys", WCoordinateSystem());
|
||||||
viz.showWidget("text2d", WText("Polyline", Point(20, 20), 20, Color::green()));
|
viz.showWidget("text2d", WText("Polyline", Point(20, 20), 20, Color::green()));
|
||||||
viz.spin();
|
viz.spin();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user