提交 ae2b0b00 编写于 作者: R Roman Donchenko 提交者: OpenCV Buildbot

Merge pull request #2486 from SpecLad:merge-2.4

......@@ -2,25 +2,52 @@ if(NOT WITH_VTK OR ANDROID OR IOS)
return()
endif()
if (HAVE_QT5)
message(STATUS "VTK is disabled because OpenCV is linked with Q5. Some VTK disributives are compiled with Q4 and therefore can't be linked together Qt5.")
# VTK 6.x components
find_package(VTK QUIET COMPONENTS vtkRenderingOpenGL vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
# VTK 5.x components
if(NOT VTK_FOUND)
find_package(VTK QUIET COMPONENTS vtkCommon NO_MODULE)
endif()
if(NOT VTK_FOUND)
set(HAVE_VTK OFF)
message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or to VTK install subdirectory with VTKConfig.cmake file")
return()
endif()
find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture vtkIOExport NO_MODULE)
# Don't support ealier VTKs
if(${VTK_VERSION} VERSION_LESS "5.8.0")
message(STATUS "VTK support is disabled. VTK ver. 5.8.0 is minimum required, but found VTK ver. ${VTK_VERSION}")
return()
endif()
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND)
find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE)
# Different Qt versions can't be linked together
if(HAVE_QT5 AND ${VTK_VERSION} VERSION_LESS "6.0.0")
if(VTK_USE_QT)
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
endif()
endif()
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND)
find_package(VTK 5.8 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE)
# Different Qt versions can't be linked together. VTK 6.0.0 doesn't provide a way to get Qt version it was linked with
if(HAVE_QT5 AND ${VTK_VERSION} VERSION_EQUAL "6.0.0" AND NOT DEFINED FORCE_VTK)
message(STATUS "VTK support is disabled. Possible incompatible combination: OpenCV+Qt5, and VTK ver.${VTK_VERSION} with Qt4")
message(STATUS "If it is known that VTK was compiled without Qt4, please define '-DFORCE_VTK=TRUE' flag in CMake")
return()
endif()
if(VTK_FOUND)
set(HAVE_VTK ON)
message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})")
else()
set(HAVE_VTK OFF)
message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or set $VTK_DIR enviroment variable to VTK install subdirectory with VTKConfig.cmake file (for windows)")
# Different Qt versions can't be linked together
if(HAVE_QT AND ${VTK_VERSION} VERSION_GREATER "6.0.0" AND NOT ${VTK_QT_VERSION} STREQUAL "")
if(HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "4")
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
return()
endif()
if(NOT HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "5")
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt4 and VTK ver.${VTK_VERSION} + Qt5")
return()
endif()
endif()
set(HAVE_VTK ON)
message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})")
......@@ -484,6 +484,10 @@ macro(ocv_glob_module_sources)
file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h")
file(GLOB lib_hdrs "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h")
file(GLOB_RECURSE lib_srcs_apple "src/*.mm")
if (APPLE)
list(APPEND lib_srcs ${lib_srcs_apple})
endif()
ocv_source_group("Src" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs})
ocv_source_group("Include" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/include" FILES ${lib_hdrs} ${lib_hdrs_detail})
......@@ -750,8 +754,8 @@ function(ocv_add_accuracy_tests)
endif()
get_native_precompiled_header(${the_target} test_precomp.hpp)
add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS})
add_dependencies(opencv_tests ${the_target})
......
......@@ -1615,7 +1615,7 @@ Copies the matrix to another one.
The method copies the matrix data to another matrix. Before copying the data, the method invokes ::
m.create(this->size(), this->type);
m.create(this->size(), this->type());
so that the destination matrix is reallocated if needed. While ``m.copyTo(m);`` works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.
......@@ -1710,7 +1710,7 @@ Transposes a matrix.
The method performs matrix transposition by means of matrix expressions. It does not perform the actual transposition but returns a temporary matrix transposition object that can be further used as a part of more complex matrix expressions or can be assigned to a matrix: ::
Mat A1 = A + Mat::eye(A.size(), A.type)*lambda;
Mat A1 = A + Mat::eye(A.size(), A.type())*lambda;
Mat C = A1.t()*A1; // compute (A + lambda*I)^t * (A + lamda*I)
......
......@@ -56,7 +56,7 @@ float calcBlurriness(const Mat &frame)
Sobel(frame, Gx, CV_32F, 1, 0);
Sobel(frame, Gy, CV_32F, 0, 1);
double normGx = norm(Gx);
double normGy = norm(Gx);
double normGy = norm(Gy);
double sumSq = normGx*normGx + normGy*normGy;
return static_cast<float>(1. / (sumSq / frame.size().area() + 1e-6));
}
......
......@@ -9,3 +9,7 @@ ocv_define_module(viz opencv_core ${VTK_LIBRARIES})
if(APPLE AND BUILD_opencv_viz)
target_link_libraries(opencv_viz "-framework Cocoa")
endif()
if(TARGET opencv_test_viz)
set_target_properties(opencv_test_viz PROPERTIES MACOSX_BUNDLE TRUE)
endif()
......@@ -935,6 +935,8 @@ This 3D Widget defines a collection of clouds. ::
void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity());
//! All points in cloud have the same color
void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity());
//! Repacks internal structure to single cloud
void finalize();
};
viz::WCloudCollection::WCloudCollection
......@@ -965,6 +967,12 @@ Adds a cloud to the collection.
.. note:: In case there are four channels in the cloud, fourth channel is ignored.
viz::WCloudCollection::finalize
-------------------------------
Finalizes cloud data by repacking to single cloud. Useful for large cloud collections to reduce memory usage
.. ocv:function:: void finalize()
viz::WCloudNormals
------------------
.. ocv:class:: WCloudNormals
......@@ -1018,3 +1026,43 @@ Constructs a WMesh.
:param polygons: Points of the mesh object.
:param colors: Point colors.
:param normals: Point normals.
viz::WWidgetMerger
---------------------
.. ocv:class:: WWidgetMerger
This class allows 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 single 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()
......@@ -63,6 +63,8 @@ namespace cv
Color(const Scalar& color);
operator Vec3b() const;
static Color black();
static Color blue();
static Color green();
......@@ -193,6 +195,8 @@ inline cv::viz::Color::Color(double _gray) : Scalar(_gray, _gray, _gray) {}
inline cv::viz::Color::Color(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {}
inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {}
inline cv::viz::Color::operator cv::Vec3b() const { return cv::Vec3d(val); }
inline cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); }
inline cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); }
inline cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); }
......
......@@ -114,6 +114,8 @@ namespace cv
double getRenderingProperty(const String &id, int property);
void setRepresentation(int representation);
void setGlobalWarnings(bool enabled = false);
private:
struct VizImpl;
......
......@@ -201,6 +201,7 @@ namespace cv
class CV_EXPORTS WPolyLine : public Widget3D
{
public:
WPolyLine(InputArray points, InputArray colors);
WPolyLine(InputArray points, const Color &color = Color::white());
};
......@@ -345,6 +346,8 @@ namespace cv
void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity());
//! All points in cloud have the same color
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity());
//! Repacks internal structure to single cloud
void finalize();
};
class CV_EXPORTS WCloudNormals : public Widget3D
......@@ -360,6 +363,18 @@ namespace cv
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 single widget
void finalize();
};
/////////////////////////////////////////////////////////////////////////////
/// Utility exports
......@@ -389,6 +404,7 @@ namespace cv
template<> CV_EXPORTS WCloudCollection Widget::cast<WCloudCollection>();
template<> CV_EXPORTS WCloudNormals Widget::cast<WCloudNormals>();
template<> CV_EXPORTS WMesh Widget::cast<WMesh>();
template<> CV_EXPORTS WWidgetMerger Widget::cast<WWidgetMerger>();
} /* namespace viz */
} /* namespace cv */
......
......@@ -193,8 +193,21 @@ template<> cv::viz::WPaintedCloud cv::viz::Widget::cast<cv::viz::WPaintedCloud>(
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();
actor->SetNumberOfCloudPoints(1);
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
}
......@@ -206,35 +219,11 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, co
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose);
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());
if (!mapper)
{
// This is the first cloud
mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetScalarRange(0, 255);
mapper->SetScalarModeToUsePointData();
mapper->ScalarVisibilityOn();
mapper->ImmediateModeRenderingOff();
VtkUtils::SetInputData(mapper, polydata);
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, polydata->GetNumberOfPoints()/10));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
return;
}
vtkPolyData *currdata = vtkPolyData::SafeDownCast(mapper->GetInput());
CV_Assert("Cloud Widget without data" && currdata);
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
VtkUtils::AddInputData(append_filter, currdata);
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
VtkUtils::AddInputData(append_filter, polydata);
append_filter->Update();
VtkUtils::SetInputData(mapper, append_filter->GetOutput());
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10));
}
......@@ -244,6 +233,23 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, const Color &color, c
addCloud(cloud, Mat(cloud.size(), CV_8UC3, color), pose);
}
void cv::viz::WCloudCollection::finalize()
{
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
CV_Assert("Incompatible widget type." && actor);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
CV_Assert("Need to add at least one cloud." && mapper);
vtkSmartPointer<vtkAlgorithm> producer = mapper->GetInputConnection(0, 0)->GetProducer();
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
append_filter->Update();
vtkSmartPointer<vtkPolyData> polydata = append_filter->GetOutput();
mapper->RemoveInputConnection(0, 0);
VtkUtils::SetInputData(mapper, polydata);
}
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
{
Widget3D widget = this->cast<Widget3D>();
......@@ -316,20 +322,18 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in
}
}
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
polyData->SetLines(lines);
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetLines(lines);
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetColorModeToMapScalars();
mapper->SetScalarModeToUsePointData();
VtkUtils::SetInputData(mapper, polyData);
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
......@@ -349,7 +353,7 @@ cv::viz::WMesh::WMesh(const Mesh &mesh)
source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
source->Update();
Mat lookup_buffer(1, mesh.cloud.total(), CV_32SC1);
Mat lookup_buffer(1, (int)mesh.cloud.total(), CV_32SC1);
int *lookup = lookup_buffer.ptr<int>();
for(int y = 0, index = 0; y < mesh.cloud.rows; ++y)
{
......@@ -439,3 +443,63 @@ template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast<cv::viz::WMesh>()
Widget3D widget = this->cast<Widget3D>();
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);
}
......@@ -76,7 +76,6 @@
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataMapper.h>
#include <vtkDataSetMapper.h>
#include <vtkCellArray.h>
......@@ -115,11 +114,9 @@
#include <vtkObjectFactory.h>
#include <vtkPolyDataAlgorithm.h>
#include <vtkMergeFilter.h>
#include <vtkDataSetWriter.h>
#include <vtkErrorCode.h>
#include <vtkPLYWriter.h>
#include <vtkSTLWriter.h>
#include <vtkSimplePointsReader.h>
#include <vtkPLYReader.h>
#include <vtkOBJReader.h>
#include <vtkSTLReader.h>
......@@ -133,6 +130,7 @@
#include <vtkElevationFilter.h>
#include <vtkColorTransferFunction.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include "vtkCallbackCommand.h"
#if !defined(_WIN32) || defined(__CYGWIN__)
# include <unistd.h> /* unlink */
......@@ -142,11 +140,13 @@
#include <vtk/vtkOBJWriter.h>
#include <vtk/vtkXYZWriter.h>
#include <vtk/vtkXYZReader.h>
#include <vtk/vtkCloudMatSink.h>
#include <vtk/vtkCloudMatSource.h>
#include <vtk/vtkTrajectorySource.h>
#include <vtk/vtkImageMatSource.h>
#include <opencv2/core.hpp>
#include <opencv2/viz.hpp>
#include <opencv2/viz/widget_accessor.hpp>
......@@ -158,7 +158,16 @@ namespace cv
namespace viz
{
typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap;
typedef std::map<String, Viz3d> VizMap;
struct VizMap
{
typedef std::map<String, Viz3d> type;
typedef type::iterator iterator;
type m;
~VizMap();
void replace_clear();
};
class VizStorage
{
......@@ -170,7 +179,6 @@ namespace cv
private:
VizStorage(); // Static
~VizStorage();
static void add(const Viz3d& window);
static Viz3d& get(const String &window_name);
......@@ -180,6 +188,8 @@ namespace cv
static VizMap storage;
friend class Viz3d;
static VizStorage init;
};
template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); }
......@@ -270,11 +280,16 @@ namespace cv
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
scalars->SetName("Colors");
scalars->SetNumberOfComponents(3);
scalars->SetNumberOfTuples(size);
scalars->SetArray(color_data->val, size * 3, 0);
scalars->SetNumberOfTuples((vtkIdType)size);
scalars->SetArray(color_data->val, (vtkIdType)(size * 3), 0);
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)
{
vtkSmartPointer<vtkPolyDataNormals> normals_generator = vtkSmartPointer<vtkPolyDataNormals>::New();
......@@ -315,11 +330,12 @@ namespace cv
return transform_filter->GetOutput();
}
};
vtkSmartPointer<vtkRenderWindowInteractor> vtkCocoaRenderWindowInteractorNew();
}
}
#include "interactor_style.hpp"
#include "vtk/vtkVizInteractorStyle.hpp"
#include "vizimpl.hpp"
#endif
......@@ -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->Update();
vtkSmartPointer<vtkPolyData> polydata = line->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, line->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
template<> cv::viz::WLine cv::viz::Widget::cast<cv::viz::WLine>()
......@@ -83,14 +85,16 @@ cv::viz::WSphere::WSphere(const Point3d &center, double radius, int sphere_resol
sphere->LatLongTessellationOff();
sphere->Update();
vtkSmartPointer<vtkPolyData> polydata = sphere->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, sphere->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
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->Update();
vtkSmartPointer<vtkPolyData> polydata = plane->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, plane->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->LightingOff();
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)
......@@ -161,6 +167,7 @@ cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness
Affine3d transform_with_scale(R * length, start_point);
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(arrow_source->GetOutputPort(), transform_with_scale);
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, polydata);
......@@ -169,7 +176,6 @@ cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
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->Update();
vtkSmartPointer<vtkPolyData> polydata = disk->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, disk->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->GetProperty()->LightingOff();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(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->Update();
vtkSmartPointer<vtkPolyData> polydata = cone_source->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, cone_source->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(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->Update();
vtkSmartPointer<vtkPolyData> polydata = tuber->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, tuber->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
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);
}
cube->Update();
vtkSmartPointer<vtkPolyData> polydata =cube->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, cube->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
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
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);
const float *fpoints = _points.getMat().ptr<float>();
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(total);
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
cloud_source->SetColorCloud(points, colors);
cloud_source->Update();
if (_points.depth() == CV_32F)
for(size_t i = 0; i < total; ++i, fpoints += s_chs)
points->SetPoint(i, fpoints);
if (_points.depth() == CV_64F)
for(size_t i = 0; i < total; ++i, dpoints += s_chs)
points->SetPoint(i, dpoints);
vtkSmartPointer<vtkPolyData> polydata = cloud_source->GetOutput();
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
cell_array->Allocate(cell_array->EstimateSize(1, total));
cell_array->InsertNextCell(total);
for(size_t i = 0; i < total; ++i)
cell_array->Allocate(cell_array->EstimateSize(1, polydata->GetNumberOfPoints()));
cell_array->InsertNextCell(polydata->GetNumberOfPoints());
for(vtkIdType i = 0; i < polydata->GetNumberOfPoints(); ++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->GetPointData()->SetScalars(scalars);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, polydata);
mapper->SetScalarRange(0, 255);
......@@ -423,6 +416,12 @@ cv::viz::WPolyLine::WPolyLine(InputArray _points, const Color &color)
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>()
{
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);
extract_edges->Update();
vtkSmartPointer<vtkPolyData> polydata = extract_edges->GetOutput();
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, extract_edges->GetOutput());
VtkUtils::SetInputData(mapper, polydata);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
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)
......@@ -807,6 +808,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const
double aspect_ratio = f_y / f_x;
vtkSmartPointer<vtkPolyData> polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale);
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, polydata);
......@@ -815,7 +817,6 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(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;
vtkSmartPointer<vtkPolyData> polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale);
VtkUtils::FillScalars(polydata, color);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
VtkUtils::SetInputData(mapper, polydata);
......@@ -832,7 +834,6 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(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);
vtkSmartPointer<vtkPolyData> glyph = getPolyData(WCameraPosition(K, scale));
VtkUtils::FillScalars(glyph, color);
vtkSmartPointer<vtkTensorGlyph> tensor_glyph = vtkSmartPointer<vtkTensorGlyph>::New();
tensor_glyph->SetInputConnection(source->GetOutputPort());
......@@ -984,7 +986,6 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Matx33
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(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);
vtkSmartPointer<vtkPolyData> glyph = getPolyData(WCameraPosition(fov, scale));
VtkUtils::FillScalars(glyph, color);
vtkSmartPointer<vtkTensorGlyph> tensor_glyph = vtkSmartPointer<vtkTensorGlyph>::New();
tensor_glyph->SetInputConnection(source->GetOutputPort());
......@@ -1010,7 +1012,6 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d
actor->SetMapper(mapper);
WidgetAccessor::setProp(*this, actor);
setColor(color);
}
template<> cv::viz::WTrajectoryFrustums cv::viz::Widget::cast<cv::viz::WTrajectoryFrustums>()
......
......@@ -146,3 +146,5 @@ void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double
double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); }
void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); }
void cv::viz::Viz3d::setGlobalWarnings(bool enabled) { vtkObject::SetGlobalWarningDisplay(enabled ? 1 : 0); }
......@@ -67,36 +67,71 @@ cv::Affine3d cv::viz::makeCameraPose(const Vec3d& position, const Vec3d& focal_p
///////////////////////////////////////////////////////////////////////////////////////////////
/// VizStorage implementation
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
static BOOL WINAPI ConsoleHandlerRoutine(DWORD /*dwCtrlType*/)
{
vtkObject::GlobalWarningDisplayOff();
return FALSE;
}
static void register_console_handler()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO hOutInfo;
if (GetConsoleScreenBufferInfo(hOut, &hOutInfo))
SetConsoleCtrlHandler(ConsoleHandlerRoutine, TRUE);
}
#else
void register_console_handler();
void register_console_handler() {}
#endif
cv::viz::VizStorage cv::viz::VizStorage::init;
cv::viz::VizMap cv::viz::VizStorage::storage;
void cv::viz::VizStorage::unregisterAll() { storage.clear(); }
void cv::viz::VizMap::replace_clear() { type().swap(m); }
cv::viz::VizMap::~VizMap() { replace_clear(); }
cv::viz::VizStorage::VizStorage()
{
register_console_handler();
}
void cv::viz::VizStorage::unregisterAll() { storage.replace_clear(); }
cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name)
{
String name = generateWindowName(window_name);
VizMap::iterator vm_itr = storage.find(name);
CV_Assert(vm_itr != storage.end());
VizMap::iterator vm_itr = storage.m.find(name);
CV_Assert(vm_itr != storage.m.end());
return vm_itr->second;
}
void cv::viz::VizStorage::add(const Viz3d& window)
{
String window_name = window.getWindowName();
VizMap::iterator vm_itr = storage.find(window_name);
CV_Assert(vm_itr == storage.end());
storage.insert(std::make_pair(window_name, window));
VizMap::iterator vm_itr = storage.m.find(window_name);
CV_Assert(vm_itr == storage.m.end());
storage.m.insert(std::make_pair(window_name, window));
}
bool cv::viz::VizStorage::windowExists(const String &window_name)
{
String name = generateWindowName(window_name);
return storage.find(name) != storage.end();
return storage.m.find(name) != storage.m.end();
}
void cv::viz::VizStorage::removeUnreferenced()
{
for(VizMap::iterator pos = storage.begin(); pos != storage.end();)
for(VizMap::iterator pos = storage.m.begin(); pos != storage.m.end();)
if(pos->second.impl_->ref_counter == 1)
storage.erase(pos++);
storage.m.erase(pos++);
else
++pos;
}
......@@ -173,8 +208,8 @@ cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray n
vtkSmartPointer<vtkPolyDataAlgorithm> reader;
if (extention == ".xyz")
{
reader = vtkSmartPointer<vtkSimplePointsReader>::New();
vtkSimplePointsReader::SafeDownCast(reader)->SetFileName(file.c_str());
reader = vtkSmartPointer<vtkXYZReader>::New();
vtkXYZReader::SafeDownCast(reader)->SetFileName(file.c_str());
}
else if (extention == ".ply")
{
......@@ -257,7 +292,11 @@ void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int
{
if (_traj.kind() == _InputArray::STD_VECTOR_MAT)
{
#if CV_MAJOR_VERSION < 3
std::vector<Mat>& v = *(std::vector<Mat>*)_traj.obj;
#else
std::vector<Mat>& v = *(std::vector<Mat>*)_traj.getObj();
#endif
for(size_t i = 0, index = max(0, start); i < v.size(); ++i, ++index)
{
......@@ -278,11 +317,12 @@ void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int
if (traj.depth() == CV_32F)
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index)
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3f>(i), tag);
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3f>((int)i), tag);
if (traj.depth() == CV_64F)
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index)
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3d>(i), tag);
writePose(cv::format(files_format.c_str(), index), traj.at<Affine3d>((int)i), tag);
return;
}
CV_Assert(!"Unsupported array kind");
......
......@@ -60,16 +60,19 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false),
window_->AddRenderer(renderer_);
// Create the interactor style
style_ = vtkSmartPointer<InteractorStyle>::New();
style_ = vtkSmartPointer<vtkVizInteractorStyle>::New();
style_->setWidgetActorMap(widget_actor_map_);
style_->UseTimersOn();
style_->Initialize();
timer_callback_ = vtkSmartPointer<TimerCallback>::New();
exit_callback_ = vtkSmartPointer<ExitCallback>::New();
exit_callback_->viz = this;
setBackgroundMeshLab();
}
cv::viz::Viz3d::VizImpl::~VizImpl() { close(); }
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::TimerCallback::Execute(vtkObject* caller, unsigned long event_id, void* cookie)
{
......@@ -109,11 +112,12 @@ void cv::viz::Viz3d::VizImpl::close()
void cv::viz::Viz3d::VizImpl::recreateRenderWindow()
{
#if !defined _MSC_VER
#if !defined _MSC_VER && !defined __APPLE__
//recreating is workaround for Ubuntu -- a crash in x-server
Vec2i window_size(window_->GetSize());
int fullscreen = window_->GetFullScreen();
window_->Finalize();
window_ = vtkSmartPointer<vtkRenderWindow>::New();
if (window_position_[0] != std::numeric_limits<int>::min()) //also workaround
window_->SetPosition(window_position_.val);
......@@ -124,12 +128,15 @@ void cv::viz::Viz3d::VizImpl::recreateRenderWindow()
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::spin()
{
recreateRenderWindow();
#if defined __APPLE__
interactor_ = vtkCocoaRenderWindowInteractorNew();
#else
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
#endif
interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_);
window_->AlphaBitPlanesOff();
......@@ -151,7 +158,11 @@ void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
{
spin_once_state_ = true;
recreateRenderWindow();
#if defined __APPLE__
interactor_ = vtkCocoaRenderWindowInteractorNew();
#else
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
#endif
interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_);
interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_);
......@@ -416,12 +427,12 @@ void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3d &pose)
// Rotate the view vector
cv::Matx33d rotation = pose.rotation();
cv::Vec3d y_axis(0.0, 1.0, 0.0);
cv::Vec3d y_axis(0.0, -1.0, 0.0); // In Computer Vision Camera Y-axis is oriented down
cv::Vec3d up_vec(rotation * y_axis);
// Compute the new focal point
cv::Vec3d z_axis(0.0, 0.0, 1.0);
cv::Vec3d focal_vec = pos_vec + rotation * z_axis;
cv::Vec3d focal_vec = pose * z_axis;
camera.SetPosition(pos_vec.val);
camera.SetFocalPoint(focal_vec.val);
......@@ -439,7 +450,7 @@ cv::Affine3d cv::viz::Viz3d::VizImpl::getViewerPose()
Vec3d view_up(camera.GetViewUp());
Vec3d focal(camera.GetFocalPoint());
Vec3d y_axis = normalized(view_up);
Vec3d y_axis = normalized(-view_up); // In Computer Vision Camera Y-axis is oriented down
Vec3d z_axis = normalized(focal - pos);
Vec3d x_axis = normalized(y_axis.cross(z_axis));
......
......@@ -55,7 +55,7 @@ public:
int ref_counter;
VizImpl(const String &name);
virtual ~VizImpl() {}
virtual ~VizImpl();
bool wasStopped() const;
void close();
......@@ -128,7 +128,7 @@ private:
vtkSmartPointer<ExitCallback> exit_callback_;
vtkSmartPointer<vtkRenderer> renderer_;
vtkSmartPointer<InteractorStyle> style_;
vtkSmartPointer<vtkVizInteractorStyle> style_;
Ptr<WidgetActorMap> widget_actor_map_;
bool removeActorFromRenderer(vtkSmartPointer<vtkProp> actor);
......
......@@ -79,11 +79,11 @@ void cv::viz::vtkCloudMatSink::WriteData()
if (cloud.depth() == CV_32F)
for(size_t i = 0; i < cloud.total(); ++i)
*fdata++ = Vec3d(points_Data->GetPoint(i));
*fdata++ = Vec3d(points_Data->GetPoint((vtkIdType)i));
if (cloud.depth() == CV_64F)
for(size_t i = 0; i < cloud.total(); ++i)
*ddata++ = Vec3d(points_Data->GetPoint(i));
*ddata++ = Vec3d(points_Data->GetPoint((vtkIdType)i));
}
else
cloud.release();
......@@ -101,7 +101,7 @@ void cv::viz::vtkCloudMatSink::WriteData()
Mat buffer(cloud.size(), CV_64FC(channels));
Vec3d *cptr = buffer.ptr<Vec3d>();
for(size_t i = 0; i < buffer.total(); ++i)
*cptr++ = Vec3d(scalars_data->GetTuple(i));
*cptr++ = Vec3d(scalars_data->GetTuple((vtkIdType)i));
buffer.convertTo(colors, CV_8U, vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE ? 255.0 : 1.0);
}
......@@ -121,7 +121,7 @@ void cv::viz::vtkCloudMatSink::WriteData()
Mat buffer(cloud.size(), CV_64FC(channels));
Vec3d *cptr = buffer.ptr<Vec3d>();
for(size_t i = 0; i < buffer.total(); ++i)
*cptr++ = Vec3d(normals_data->GetTuple(i));
*cptr++ = Vec3d(normals_data->GetTuple((vtkIdType)i));
buffer.convertTo(normals, vtktype == VTK_FLOAT ? CV_32F : CV_64F);
}
......@@ -140,7 +140,7 @@ void cv::viz::vtkCloudMatSink::WriteData()
Mat buffer(cloud.size(), CV_64FC2);
Vec2d *cptr = buffer.ptr<Vec2d>();
for(size_t i = 0; i < buffer.total(); ++i)
*cptr++ = Vec2d(coords_data->GetTuple(i));
*cptr++ = Vec2d(coords_data->GetTuple((vtkIdType)i));
buffer.convertTo(tcoords, vtktype == VTK_FLOAT ? CV_32F : CV_64F);
......@@ -156,3 +156,19 @@ void cv::viz::vtkCloudMatSink::PrintSelf(ostream& os, vtkIndent indent)
os << indent << "Colors: " << colors.needed() << "\n";
os << indent << "Normals: " << normals.needed() << "\n";
}
int cv::viz::vtkCloudMatSink::FillInputPortInformation(int, vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
return 1;
}
vtkPolyData* cv::viz::vtkCloudMatSink::GetInput()
{
return vtkPolyData::SafeDownCast(this->Superclass::GetInput());
}
vtkPolyData* cv::viz::vtkCloudMatSink::GetInput(int port)
{
return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port));
}
......@@ -46,26 +46,32 @@
#define __vtkCloudMatSink_h
#include <opencv2/core.hpp>
#include <vtkPolyDataWriter.h>
#include <vtkWriter.h>
namespace cv
{
namespace viz
{
class vtkCloudMatSink : public vtkPolyDataWriter
class vtkCloudMatSink : public vtkWriter
{
public:
static vtkCloudMatSink *New();
vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter)
vtkTypeMacro(vtkCloudMatSink,vtkWriter)
void PrintSelf(ostream& os, vtkIndent indent);
void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray());
// Description:
// Get the input to this writer.
vtkPolyData* GetInput();
vtkPolyData* GetInput(int port);
protected:
vtkCloudMatSink();
~vtkCloudMatSink();
void WriteData();
int FillInputPortInformation(int port, vtkInformation *info);
_OutputArray cloud, colors, normals, tcoords;
......
......@@ -185,8 +185,8 @@ int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud)
CV_DbgAssert(DataType<_Tp>::depth == cloud.depth());
points = vtkSmartPointer<vtkPoints>::New();
points->SetDataType(VtkDepthTraits<_Tp>::data_type);
points->Allocate(cloud.total());
points->SetNumberOfPoints(cloud.total());
points->Allocate((vtkIdType)cloud.total());
points->SetNumberOfPoints((vtkIdType)cloud.total());
int s_chs = cloud.channels();
int total = 0;
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// This workaround code was taken from PCL library(www.pointclouds.org)
//
//M*/
#import <Cocoa/Cocoa.h>
#include <vtkCocoaRenderWindow.h>
#include <vtkCocoaRenderWindowInteractor.h>
#include <vtkObjectFactory.h>
#include <vtkSmartPointer.h>
//----------------------------------------------------------------------------
@interface vtkCocoaServerFix : NSObject
{
vtkCocoaRenderWindow* renWin;
}
+ (id)cocoaServerWithRenderWindow:(vtkCocoaRenderWindow*)inRenderWindow;
- (void)start;
- (void)stop;
- (void)breakEventLoop;
@end
//----------------------------------------------------------------------------
@implementation vtkCocoaServerFix
//----------------------------------------------------------------------------
- (id)initWithRenderWindow:(vtkCocoaRenderWindow *)inRenderWindow
{
self = [super init];
if (self)
renWin = inRenderWindow;
return self;
}
//----------------------------------------------------------------------------
+ (id)cocoaServerWithRenderWindow:(vtkCocoaRenderWindow *)inRenderWindow
{
vtkCocoaServerFix *server = [[[vtkCocoaServerFix alloc] initWithRenderWindow:inRenderWindow] autorelease];
return server;
}
//----------------------------------------------------------------------------
- (void)start
{
// Retrieve the NSWindow.
NSWindow *win = nil;
if (renWin)
{
win = reinterpret_cast<NSWindow*> (renWin->GetRootWindow ());
// We don't want to be informed of every window closing, so check for nil.
if (win != nil)
{
// Register for the windowWillClose notification in order to stop the run loop if the window closes.
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:win];
}
}
// Start the NSApplication's run loop
NSApplication* application = [NSApplication sharedApplication];
[application run];
}
//----------------------------------------------------------------------------
- (void)stop
{
[self breakEventLoop];
}
//----------------------------------------------------------------------------
- (void)breakEventLoop
{
NSApplication* application = [NSApplication sharedApplication];
[application stop:application];
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
location:NSMakePoint(0.0,0.0)
modifierFlags:0
timestamp:0
windowNumber:-1
context:nil
subtype:0
data1:0
data2:0];
[application postEvent:event atStart:YES];
}
//----------------------------------------------------------------------------
- (void)windowWillClose:(NSNotification*)aNotification
{
(void)aNotification;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:NSWindowWillCloseNotification object:nil];
if (renWin)
{
int windowCreated = renWin->GetWindowCreated ();
if (windowCreated)
{
[self breakEventLoop];
// The NSWindow is closing, so prevent anyone from accidently using it
renWin->SetRootWindow(NULL);
}
}
}
@end
//----------------------------------------------------------------------------
namespace cv { namespace viz
{
class vtkCocoaRenderWindowInteractorFix : public vtkCocoaRenderWindowInteractor
{
public:
static vtkCocoaRenderWindowInteractorFix *New ();
vtkTypeMacro (vtkCocoaRenderWindowInteractorFix, vtkCocoaRenderWindowInteractor)
virtual void Start ();
virtual void TerminateApp ();
protected:
vtkCocoaRenderWindowInteractorFix () {}
~vtkCocoaRenderWindowInteractorFix () {}
private:
vtkCocoaRenderWindowInteractorFix (const vtkCocoaRenderWindowInteractorFix&); // Not implemented.
void operator = (const vtkCocoaRenderWindowInteractorFix&); // Not implemented.
};
vtkStandardNewMacro (vtkCocoaRenderWindowInteractorFix)
vtkSmartPointer<vtkRenderWindowInteractor> vtkCocoaRenderWindowInteractorNew();
}}
void cv::viz::vtkCocoaRenderWindowInteractorFix::Start ()
{
vtkCocoaRenderWindow* renWin = vtkCocoaRenderWindow::SafeDownCast(this->GetRenderWindow ());
if (renWin != NULL)
{
vtkCocoaServerFix *server = reinterpret_cast<vtkCocoaServerFix*> (this->GetCocoaServer ());
if (!this->GetCocoaServer ())
{
server = [vtkCocoaServerFix cocoaServerWithRenderWindow:renWin];
this->SetCocoaServer (reinterpret_cast<void*> (server));
}
[server start];
}
}
void cv::viz::vtkCocoaRenderWindowInteractorFix::TerminateApp ()
{
vtkCocoaRenderWindow *renWin = vtkCocoaRenderWindow::SafeDownCast (this->RenderWindow);
if (renWin)
{
vtkCocoaServerFix *server = reinterpret_cast<vtkCocoaServerFix*> (this->GetCocoaServer ());
[server stop];
}
}
vtkSmartPointer<vtkRenderWindowInteractor> cv::viz::vtkCocoaRenderWindowInteractorNew()
{
return vtkSmartPointer<vtkCocoaRenderWindowInteractorFix>::New();
}
......@@ -54,7 +54,6 @@ cv::viz::vtkOBJWriter::vtkOBJWriter()
std::ofstream fout; // only used to extract the default precision
this->DecimalPrecision = fout.precision();
this->FileName = NULL;
this->FileType = VTK_ASCII;
}
cv::viz::vtkOBJWriter::~vtkOBJWriter(){}
......@@ -65,14 +64,27 @@ void cv::viz::vtkOBJWriter::WriteData()
if (!input)
return;
std::ostream *outfilep = this->OpenVTKFile();
if (!outfilep)
if (!this->FileName )
{
vtkErrorMacro(<< "No FileName specified! Can't write!");
this->SetErrorCode(vtkErrorCode::NoFileNameError);
return;
}
vtkDebugMacro(<<"Opening vtk file for writing...");
ostream *outfilep = new ofstream(this->FileName, ios::out);
if (outfilep->fail())
{
vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
this->SetErrorCode(vtkErrorCode::CannotOpenFileError);
delete outfilep;
return;
}
std::ostream& outfile = *outfilep;
//write header
outfile << "# wavefront obj file written by the visualization toolkit" << std::endl << std::endl;
outfile << "# wavefront obj file written by opencv viz module" << std::endl << std::endl;
outfile << "mtllib NONE" << std::endl << std::endl;
// write out the points
......@@ -224,7 +236,8 @@ void cv::viz::vtkOBJWriter::WriteData()
}
} /* if (input->GetNumberOfStrips() > 0) */
this->CloseVTKFile(outfilep);
vtkDebugMacro(<<"Closing vtk file\n");
delete outfilep;
// Delete the file if an error occurred
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
......@@ -239,3 +252,19 @@ void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent)
Superclass::PrintSelf(os, indent);
os << indent << "DecimalPrecision: " << DecimalPrecision << "\n";
}
int cv::viz::vtkOBJWriter::FillInputPortInformation(int, vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
return 1;
}
vtkPolyData* cv::viz::vtkOBJWriter::GetInput()
{
return vtkPolyData::SafeDownCast(this->Superclass::GetInput());
}
vtkPolyData* cv::viz::vtkOBJWriter::GetInput(int port)
{
return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port));
}
......@@ -45,29 +45,41 @@
#ifndef __vtkOBJWriter_h
#define __vtkOBJWriter_h
#include <vtkPolyDataWriter.h>
#include <vtkWriter.h>
namespace cv
{
namespace viz
{
class vtkOBJWriter : public vtkPolyDataWriter
class vtkOBJWriter : public vtkWriter
{
public:
static vtkOBJWriter *New();
vtkTypeMacro(vtkOBJWriter,vtkPolyDataWriter)
vtkTypeMacro(vtkOBJWriter,vtkWriter)
void PrintSelf(ostream& os, vtkIndent indent);
vtkGetMacro(DecimalPrecision, int);
vtkSetMacro(DecimalPrecision, int);
vtkGetMacro(DecimalPrecision, int)
vtkSetMacro(DecimalPrecision, int)
// Description:
// Specify file name of data file to write.
vtkSetStringMacro(FileName)
vtkGetStringMacro(FileName)
// Description:
// Get the input to this writer.
vtkPolyData* GetInput();
vtkPolyData* GetInput(int port);
protected:
vtkOBJWriter();
~vtkOBJWriter();
void WriteData();
int FillInputPortInformation(int port, vtkInformation *info);
int DecimalPrecision;
char *FileName;
private:
vtkOBJWriter(const vtkOBJWriter&); // Not implemented.
......
......@@ -64,19 +64,19 @@ void cv::viz::vtkTrajectorySource::SetTrajectory(InputArray _traj)
points = vtkSmartPointer<vtkPoints>::New();
points->SetDataType(VTK_DOUBLE);
points->SetNumberOfPoints(total);
points->SetNumberOfPoints((vtkIdType)total);
tensors = vtkSmartPointer<vtkDoubleArray>::New();
tensors->SetNumberOfComponents(9);
tensors->SetNumberOfTuples(total);
tensors->SetNumberOfTuples((vtkIdType)total);
for(size_t i = 0; i < total; ++i, ++dpath)
{
Matx33d R = dpath->rotation().t(); // transposed because of
tensors->SetTuple(i, R.val); // column major order
tensors->SetTuple((vtkIdType)i, R.val); // column major order
Vec3d p = dpath->translation();
points->SetPoint(i, p.val);
points->SetPoint((vtkIdType)i, p.val);
}
}
......@@ -85,7 +85,7 @@ cv::Mat cv::viz::vtkTrajectorySource::ExtractPoints(InputArray _traj)
CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT);
CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16));
Mat points(1, _traj.total(), CV_MAKETYPE(_traj.depth(), 3));
Mat points(1, (int)_traj.total(), CV_MAKETYPE(_traj.depth(), 3));
const Affine3d* dpath = _traj.getMat().ptr<Affine3d>();
const Affine3f* fpath = _traj.getMat().ptr<Affine3f>();
......
......@@ -46,64 +46,101 @@
#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__
#define __OPENCV_VIZ_INTERACTOR_STYLE_H__
#include <vtkInteractorStyle.h>
namespace cv
{
namespace viz
{
class InteractorStyle : public vtkInteractorStyleTrackballCamera
class vtkVizInteractorStyle : public vtkInteractorStyle
{
public:
static InteractorStyle *New();
virtual ~InteractorStyle() {}
static vtkVizInteractorStyle *New();
vtkTypeMacro(vtkVizInteractorStyle, vtkInteractorStyle)
void PrintSelf(ostream& os, vtkIndent indent);
// this macro defines Superclass, the isA functionality and the safe downcast method
vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera)
virtual void OnChar();
virtual void OnKeyDown();
virtual void OnKeyUp();
/** \brief Initialization routine. Must be called before anything else. */
virtual void Initialize();
virtual void OnMouseMove();
virtual void OnLeftButtonDown();
virtual void OnLeftButtonUp();
virtual void OnMiddleButtonDown();
virtual void OnMiddleButtonUp();
virtual void OnRightButtonDown();
virtual void OnRightButtonUp();
virtual void OnMouseWheelForward();
virtual void OnMouseWheelBackward();
virtual void OnTimer();
virtual void Rotate();
virtual void Spin();
virtual void Pan();
virtual void Dolly();
vtkSetMacro(FlyMode,bool)
vtkGetMacro(FlyMode,bool)
vtkSetMacro(MotionFactor, double)
vtkGetMacro(MotionFactor, double)
void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; }
void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0);
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0);
void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; }
void saveScreenshot(const String &file);
void exportScene(const String &file);
void exportScene();
void changePointsSize(float delta);
void setRepresentationToPoints();
void printCameraParams();
void toggleFullScreen();
void resetViewerPose();
void toggleStereo();
void printHelp();
// Set the basic unit step size : by default 1/250 of bounding diagonal
vtkSetMacro(MotionStepSize,double)
vtkGetMacro(MotionStepSize,double)
// Set acceleration factor when shift key is applied : default 10
vtkSetMacro(MotionAccelerationFactor,double)
vtkGetMacro(MotionAccelerationFactor,double)
// Set the basic angular unit for turning : efault 1 degree
vtkSetMacro(AngleStepSize,double)
vtkGetMacro(AngleStepSize,double)
private:
/** \brief Set to true after initialization is complete. */
bool init_;
Ptr<WidgetActorMap> widget_actor_map_;
Vec2i win_size_;
Vec2i win_pos_;
Vec2i max_win_size_;
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */
virtual void OnChar();
void zoomIn();
void zoomOut();
// Keyboard events
virtual void OnKeyDown();
virtual void OnKeyUp();
protected:
vtkVizInteractorStyle();
~vtkVizInteractorStyle();
// mouse button events
virtual void OnMouseMove();
virtual void OnLeftButtonDown();
virtual void OnLeftButtonUp();
virtual void OnMiddleButtonDown();
virtual void OnMiddleButtonUp();
virtual void OnRightButtonDown();
virtual void OnRightButtonUp();
virtual void OnMouseWheelForward();
virtual void OnMouseWheelBackward();
virtual void Dolly(double factor);
/** \brief Interactor style internal method. Gets called periodically if a timer is set. */
virtual void OnTimer();
void Fly();
void FlyByMouse();
void FlyByKey();
void SetupMotionVars();
void MotionAlongVector(const Vec3d& vector, double amount, vtkCamera* cam);
void zoomIn();
void zoomOut();
private:
vtkVizInteractorStyle(const vtkVizInteractorStyle&);
vtkVizInteractorStyle& operator=(const vtkVizInteractorStyle&);
/** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */
bool stereo_anaglyph_mask_default_;
//! True for red-blue colors, false for magenta-green.
bool stereo_anaglyph_redblue_;
void (*keyboardCallback_)(const KeyboardEvent&, void*);
void *keyboard_callback_cookie_;
......@@ -111,7 +148,20 @@ namespace cv
void (*mouseCallback_)(const MouseEvent&, void*);
void *mouse_callback_cookie_;
bool FlyMode;
double MotionFactor;
int getModifiers();
// from fly
unsigned char KeysDown;
double DiagonalLength;
double MotionStepSize;
double MotionUserScale;
double MotionAccelerationFactor;
double AngleStepSize;
double DeltaYaw;
double DeltaPitch;
};
}
}
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
//M*/
#include "precomp.hpp"
namespace cv { namespace viz
{
vtkStandardNewMacro(vtkXYZReader);
}}
cv::viz::vtkXYZReader::vtkXYZReader()
{
this->FileName = 0;
this->SetNumberOfInputPorts(0);
}
cv::viz::vtkXYZReader::~vtkXYZReader()
{
this->SetFileName(0);
}
void cv::viz::vtkXYZReader::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "FileName: " << (this->FileName ? this->FileName : "(none)") << "\n";
}
int cv::viz::vtkXYZReader::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector)
{
// Make sure we have a file to read.
if(!this->FileName)
{
vtkErrorMacro("A FileName must be specified.");
return 0;
}
// Open the input file.
ifstream fin(this->FileName);
if(!fin)
{
vtkErrorMacro("Error opening file " << this->FileName);
return 0;
}
// Allocate objects to hold points and vertex cells.
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();
// Read points from the file.
vtkDebugMacro("Reading points from file " << this->FileName);
double x[3];
while(fin >> x[0] >> x[1] >> x[2])
{
vtkIdType id = points->InsertNextPoint(x);
verts->InsertNextCell(1, &id);
}
vtkDebugMacro("Read " << points->GetNumberOfPoints() << " points.");
// Store the points and cells in the output data object.
vtkPolyData* output = vtkPolyData::GetData(outputVector);
output->SetPoints(points);
output->SetVerts(verts);
return 1;
}
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
//M*/
#ifndef __vtkXYZReader_h
#define __vtkXYZReader_h
#include "vtkPolyDataAlgorithm.h"
namespace cv
{
namespace viz
{
class vtkXYZReader : public vtkPolyDataAlgorithm
{
public:
static vtkXYZReader* New();
vtkTypeMacro(vtkXYZReader,vtkPolyDataAlgorithm)
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Set/Get the name of the file from which to read points.
vtkSetStringMacro(FileName)
vtkGetStringMacro(FileName)
protected:
vtkXYZReader();
~vtkXYZReader();
char* FileName;
int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*);
private:
vtkXYZReader(const vtkXYZReader&); // Not implemented.
void operator=(const vtkXYZReader&); // Not implemented.
};
}
}
#endif
......@@ -61,10 +61,22 @@ void cv::viz::vtkXYZWriter::WriteData()
if (!input)
return;
// OpenVTKFile() will report any errors that happen
ostream *outfilep = this->OpenVTKFile();
if (!outfilep)
if (!this->FileName )
{
vtkErrorMacro(<< "No FileName specified! Can't write!");
this->SetErrorCode(vtkErrorCode::NoFileNameError);
return;
}
vtkDebugMacro(<<"Opening vtk file for writing...");
ostream *outfilep = new ofstream(this->FileName, ios::out);
if (outfilep->fail())
{
vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
this->SetErrorCode(vtkErrorCode::CannotOpenFileError);
delete outfilep;
return;
}
ostream &outfile = *outfilep;
......@@ -76,7 +88,8 @@ void cv::viz::vtkXYZWriter::WriteData()
}
// Close the file
this->CloseVTKFile(outfilep);
vtkDebugMacro(<<"Closing vtk file\n");
delete outfilep;
// Delete the file if an error occurred
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
......@@ -86,8 +99,24 @@ void cv::viz::vtkXYZWriter::WriteData()
}
}
int cv::viz::vtkXYZWriter::FillInputPortInformation(int, vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
return 1;
}
void cv::viz::vtkXYZWriter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "DecimalPrecision: " << this->DecimalPrecision << "\n";
}
vtkPolyData* cv::viz::vtkXYZWriter::GetInput()
{
return vtkPolyData::SafeDownCast(this->Superclass::GetInput());
}
vtkPolyData* cv::viz::vtkXYZWriter::GetInput(int port)
{
return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port));
}
......@@ -45,29 +45,41 @@
#ifndef __vtkXYZWriter_h
#define __vtkXYZWriter_h
#include "vtkPolyDataWriter.h"
#include "vtkWriter.h"
namespace cv
{
namespace viz
{
class vtkXYZWriter : public vtkPolyDataWriter
class vtkXYZWriter : public vtkWriter
{
public:
static vtkXYZWriter *New();
vtkTypeMacro(vtkXYZWriter,vtkPolyDataWriter)
vtkTypeMacro(vtkXYZWriter,vtkWriter)
void PrintSelf(ostream& os, vtkIndent indent);
vtkGetMacro(DecimalPrecision, int)
vtkSetMacro(DecimalPrecision, int)
// Description:
// Specify file name of data file to write.
vtkSetStringMacro(FileName)
vtkGetStringMacro(FileName)
// Description:
// Get the input to this writer.
vtkPolyData* GetInput();
vtkPolyData* GetInput(int port);
protected:
vtkXYZWriter();
~vtkXYZWriter(){}
void WriteData();
int FillInputPortInformation(int port, vtkInformation *info);
int DecimalPrecision;
char *FileName;
private:
vtkXYZWriter(const vtkXYZWriter&); // Not implemented.
......
......@@ -54,11 +54,19 @@
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/viz.hpp>
#include <opencv2/core/version.hpp>
#include <opencv2/viz/vizcore.hpp>
namespace cv
{
Mat imread(const String& filename, int flags = 1);
}
#if CV_MAJOR_VERSION < 3
#include "opencv2/ts/ts.hpp"
#else
#include "opencv2/ts.hpp"
#endif
#include <iostream>
#include <fstream>
......
......@@ -15,50 +15,46 @@ void tutorial3(bool camera_pov)
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Let's assume camera has the following properties
Point3d cam_pos(3.0, 3.0, 3.0), cam_focal_point(3.0, 3.0, 2.0), cam_y_dir(-1.0, 0.0, 0.0);
Point3d cam_origin(3.0, 3.0, 3.0), cam_focal_point(3.0, 3.0, 2.0), cam_y_dir(-1.0, 0.0, 0.0);
/// We can get the pose of the cam using makeCameraPose
Affine3d cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);
Affine3d camera_pose = viz::makeCameraPose(cam_origin, cam_focal_point, cam_y_dir);
/// We can get the transformation matrix from camera coordinate system to global using
/// - makeTransformToGlobal. We need the axes of the camera
Affine3d transform = viz::makeTransformToGlobal(Vec3d(0.0, -1.0, 0.0), Vec3d(-1.0, 0.0, 0.0), Vec3d(0.0, 0.0, -1.0), cam_pos);
Affine3d transform = viz::makeTransformToGlobal(Vec3d(0.0, -1.0, 0.0), Vec3d(-1.0, 0.0, 0.0), Vec3d(0.0, 0.0, -1.0), cam_origin);
/// Create a cloud widget.
Mat dragon_cloud = viz::readCloud(get_dragon_ply_file_path());
viz::WCloud cloud_widget(dragon_cloud, viz::Color::green());
/// Pose of the widget in camera frame
Affine3d cloud_pose = Affine3d().translate(Vec3d(0.0, 0.0, 3.0));
Affine3d cloud_pose = Affine3d().rotate(Vec3d(0.0, CV_PI/2, 0.0)).rotate(Vec3d(0.0, 0.0, CV_PI)).translate(Vec3d(0.0, 0.0, 3.0));
/// Pose of the widget in global frame
Affine3d cloud_pose_global = transform * cloud_pose;
/// Visualize camera frame
myWindow.showWidget("CPW_FRUSTUM", viz::WCameraPosition(Vec2f(0.889484f, 0.523599f)), camera_pose);
if (!camera_pov)
{
viz::WCameraPosition cpw(0.5); // Coordinate axes
viz::WCameraPosition cpw_frustum(Vec2f(0.889484f, 0.523599f)); // Camera frustum
myWindow.showWidget("CPW", cpw, cam_pose);
myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
}
myWindow.showWidget("CPW", viz::WCameraPosition(0.5), camera_pose);
/// Visualize widget
myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);
/// Set the viewer pose to that of camera
if (camera_pov)
myWindow.setViewerPose(cam_pose);
myWindow.setViewerPose(camera_pose);
/// Start event loop.
myWindow.spin();
}
TEST(Viz, DISABLED_tutorial3_global_view)
TEST(Viz, tutorial3_global_view)
{
tutorial3(false);
}
TEST(Viz, DISABLED_tutorial3_camera_view)
TEST(Viz, tutorial3_camera_view)
{
tutorial3(true);
}
......@@ -59,6 +59,5 @@ TEST(Viz_viz3d, DISABLED_develop)
//cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path());
//---->>>>> </to_test_in_future>
viz.spin();
}
......@@ -52,6 +52,7 @@ TEST(Viz, show_cloud_bluberry)
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0));
Viz3d viz("show_cloud_bluberry");
viz.setBackgroundColor(Color::black());
viz.showWidget("coosys", WCoordinateSystem());
viz.showWidget("dragon", WCloud(dragon_cloud, Color::bluberry()), pose);
......@@ -81,7 +82,7 @@ TEST(Viz, show_cloud_masked)
Mat dragon_cloud = readCloud(get_dragon_ply_file_path());
Vec3f qnan = Vec3f::all(std::numeric_limits<float>::quiet_NaN());
for(size_t i = 0; i < dragon_cloud.total(); ++i)
for(int i = 0; i < (int)dragon_cloud.total(); ++i)
if (i % 15 != 0)
dragon_cloud.at<Vec3f>(i) = qnan;
......@@ -102,6 +103,7 @@ TEST(Viz, show_cloud_collection)
ccol.addCloud(cloud, Color::white(), Affine3d().translate(Vec3d(0, 0, 0)).rotate(Vec3d(CV_PI/2, 0, 0)));
ccol.addCloud(cloud, Color::blue(), Affine3d().translate(Vec3d(1, 0, 0)));
ccol.addCloud(cloud, Color::red(), Affine3d().translate(Vec3d(2, 0, 0)));
ccol.finalize();
Viz3d viz("show_cloud_collection");
viz.setBackgroundColor(Color::mlab());
......@@ -154,6 +156,27 @@ TEST(Viz, show_mesh_random_colors)
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)
{
Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png"));
......@@ -170,7 +193,7 @@ TEST(Viz, show_textured_mesh)
tcoords.push_back(Vec2d(1.0, i/64.0));
}
for(size_t i = 0; i < points.size()/2-1; ++i)
for(int i = 0; i < (int)points.size()/2-1; ++i)
{
int polys[] = {3, 2*i, 2*i+1, 2*i+2, 3, 2*i+1, 2*i+2, 2*i+3};
polygons.insert(polygons.end(), polys, polys + sizeof(polys)/sizeof(polys[0]));
......@@ -193,12 +216,18 @@ TEST(Viz, show_textured_mesh)
TEST(Viz, show_polyline)
{
Mat polyline(1, 32, CV_64FC3);
for(size_t i = 0; i < polyline.total(); ++i)
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)
{
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");
viz.showWidget("polyline", WPolyLine(Mat(polyline), Color::apricot()));
viz.showWidget("polyline", WPolyLine(polyline, colors));
viz.showWidget("coosys", WCoordinateSystem());
viz.showWidget("text2d", WText("Polyline", Point(20, 20), 20, Color::green()));
viz.spin();
......@@ -222,13 +251,14 @@ TEST(Viz, show_sampled_normals)
TEST(Viz, show_trajectories)
{
std::vector<Affine3d> path = generate_test_trajectory<double>(), sub0, sub1, sub2, sub3, sub4, sub5;
Mat(path).rowRange(0, path.size()/10+1).copyTo(sub0);
Mat(path).rowRange(path.size()/10, path.size()/5+1).copyTo(sub1);
Mat(path).rowRange(path.size()/5, 11*path.size()/12).copyTo(sub2);
Mat(path).rowRange(11*path.size()/12, path.size()).copyTo(sub3);
Mat(path).rowRange(3*path.size()/4, 33*path.size()/40).copyTo(sub4);
Mat(path).rowRange(33*path.size()/40, 9*path.size()/10).copyTo(sub5);
int size =(int)path.size();
Mat(path).rowRange(0, size/10+1).copyTo(sub0);
Mat(path).rowRange(size/10, size/5+1).copyTo(sub1);
Mat(path).rowRange(size/5, 11*size/12).copyTo(sub2);
Mat(path).rowRange(11*size/12, size).copyTo(sub3);
Mat(path).rowRange(3*size/4, 33*size/40).copyTo(sub4);
Mat(path).rowRange(33*size/40, 9*size/10).copyTo(sub5);
Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0);
Viz3d viz("show_trajectories");
......@@ -259,7 +289,7 @@ TEST(Viz, show_trajectory_reposition)
Viz3d viz("show_trajectory_reposition_to_origin");
viz.showWidget("coos", WCoordinateSystem());
viz.showWidget("sub3", WTrajectory(Mat(path).rowRange(0, path.size()/3), WTrajectory::BOTH, 0.2, Color::brown()), path.front().inv());
viz.showWidget("sub3", WTrajectory(Mat(path).rowRange(0, (int)path.size()/3), WTrajectory::BOTH, 0.2, Color::brown()), path.front().inv());
viz.showWidget("text2d", WText("Trajectory resposition to origin", Point(20, 20), 20, Color::green()));
viz.spin();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册