Merge pull request #2434 from Nerei:viz_continue

pull/2475/merge
Roman Donchenko 11 years ago committed by OpenCV Buildbot
commit 836635d2d5
  1. 53
      cmake/OpenCVDetectVTK.cmake
  2. 6
      cmake/OpenCVModule.cmake
  3. 4
      modules/viz/CMakeLists.txt
  4. 48
      modules/viz/doc/widget.rst
  5. 4
      modules/viz/include/opencv2/viz/types.hpp
  6. 2
      modules/viz/include/opencv2/viz/viz3d.hpp
  7. 16
      modules/viz/include/opencv2/viz/widgets.hpp
  8. 136
      modules/viz/src/clouds.cpp
  9. 639
      modules/viz/src/interactor_style.cpp
  10. 34
      modules/viz/src/precomp.hpp
  11. 99
      modules/viz/src/shapes.cpp
  12. 2
      modules/viz/src/viz3d.cpp
  13. 66
      modules/viz/src/vizcore.cpp
  14. 19
      modules/viz/src/vizimpl.cpp
  15. 4
      modules/viz/src/vizimpl.hpp
  16. 26
      modules/viz/src/vtk/vtkCloudMatSink.cpp
  17. 12
      modules/viz/src/vtk/vtkCloudMatSink.h
  18. 4
      modules/viz/src/vtk/vtkCloudMatSource.cpp
  19. 211
      modules/viz/src/vtk/vtkCocoaInteractorFix.mm
  20. 39
      modules/viz/src/vtk/vtkOBJWriter.cpp
  21. 22
      modules/viz/src/vtk/vtkOBJWriter.h
  22. 10
      modules/viz/src/vtk/vtkTrajectorySource.cpp
  23. 1076
      modules/viz/src/vtk/vtkVizInteractorStyle.cpp
  24. 114
      modules/viz/src/vtk/vtkVizInteractorStyle.hpp
  25. 107
      modules/viz/src/vtk/vtkXYZReader.cpp
  26. 80
      modules/viz/src/vtk/vtkXYZReader.h
  27. 37
      modules/viz/src/vtk/vtkXYZWriter.cpp
  28. 18
      modules/viz/src/vtk/vtkXYZWriter.h
  29. 16
      modules/viz/test/test_precomp.hpp
  30. 1
      modules/viz/test/test_viz3d.cpp
  31. 56
      modules/viz/test/tests_simple.cpp

@ -2,25 +2,52 @@ if(NOT WITH_VTK OR ANDROID OR IOS)
return() return()
endif() endif()
if (HAVE_QT5) # VTK 6.x components
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.") 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() return()
endif() 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) # Different Qt versions can't be linked together
find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) 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() endif()
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) # 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
find_package(VTK 5.8 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) 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() endif()
if(VTK_FOUND) # Different Qt versions can't be linked together
set(HAVE_VTK ON) if(HAVE_QT AND ${VTK_VERSION} VERSION_GREATER "6.0.0" AND NOT ${VTK_QT_VERSION} STREQUAL "")
message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})") if(HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "4")
else() message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
set(HAVE_VTK OFF) return()
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)") 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() 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_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h")
file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") file(GLOB lib_hdrs "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 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()
file(GLOB lib_cuda_srcs "src/cuda/*.cu") file(GLOB lib_cuda_srcs "src/cuda/*.cu")
set(cuda_objs "") set(cuda_objs "")
@ -744,8 +748,8 @@ function(ocv_add_accuracy_tests)
endif() endif()
get_native_precompiled_header(${the_target} test_precomp.hpp) get_native_precompiled_header(${the_target} test_precomp.hpp)
add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) 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}) target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS})
add_dependencies(opencv_tests ${the_target}) add_dependencies(opencv_tests ${the_target})

@ -9,3 +9,7 @@ ocv_define_module(viz opencv_core ${VTK_LIBRARIES})
if(APPLE AND BUILD_opencv_viz) if(APPLE AND BUILD_opencv_viz)
target_link_libraries(opencv_viz "-framework Cocoa") target_link_libraries(opencv_viz "-framework Cocoa")
endif() endif()
if(TARGET opencv_test_viz)
set_target_properties(opencv_test_viz PROPERTIES MACOSX_BUNDLE TRUE)
endif()

@ -934,6 +934,8 @@ This 3D Widget defines a collection of clouds. ::
void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity());
//! All points in cloud have the same color //! All points in cloud have the same color
void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity()); void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity());
//! Repacks internal structure to single cloud
void finalize();
}; };
viz::WCloudCollection::WCloudCollection viz::WCloudCollection::WCloudCollection
@ -964,6 +966,12 @@ Adds a cloud to the collection.
.. note:: In case there are four channels in the cloud, fourth channel is ignored. .. 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 viz::WCloudNormals
------------------ ------------------
.. ocv:class:: WCloudNormals .. ocv:class:: WCloudNormals
@ -1017,3 +1025,43 @@ 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 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); Color(const Scalar& color);
operator Vec3b() const;
static Color black(); static Color black();
static Color blue(); static Color blue();
static Color green(); 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(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {}
inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {} 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::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::green() { return Color( 0, 255, 0); }
inline cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 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); double getRenderingProperty(const String &id, int property);
void setRepresentation(int representation); void setRepresentation(int representation);
void setGlobalWarnings(bool enabled = false);
private: private:
struct VizImpl; struct VizImpl;

@ -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());
}; };
@ -345,6 +346,8 @@ namespace cv
void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity());
//! All points in cloud have the same color //! All points in cloud have the same color
void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity()); 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 class CV_EXPORTS WCloudNormals : public Widget3D
@ -360,6 +363,18 @@ 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 single widget
void finalize();
};
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// Utility exports /// Utility exports
@ -389,6 +404,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,35 +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 = vtkAppendPolyData::SafeDownCast(producer);
{
// 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);
VtkUtils::AddInputData(append_filter, polydata); 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)); 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); 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>() template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
{ {
Widget3D widget = this->cast<Widget3D>(); Widget3D widget = this->cast<Widget3D>();
@ -316,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>()
@ -349,7 +353,7 @@ cv::viz::WMesh::WMesh(const Mesh &mesh)
source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords); source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
source->Update(); 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>(); int *lookup = lookup_buffer.ptr<int>();
for(int y = 0, index = 0; y < mesh.cloud.rows; ++y) 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>(); 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);
}

@ -1,639 +0,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:
// * Ozan Tonkal, ozantonkal@gmail.com
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
//
// OpenCV Viz module is complete rewrite of
// PCL visualization module (www.pointclouds.org)
//
//M*/
#include "precomp.hpp"
namespace cv { namespace viz
{
vtkStandardNewMacro(InteractorStyle)
}}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::Initialize()
{
// Set windows size (width, height) to unknown (-1)
win_size_ = Vec2i(-1, -1);
win_pos_ = Vec2i(0, 0);
max_win_size_ = Vec2i(-1, -1);
init_ = true;
stereo_anaglyph_mask_default_ = true;
// Initialize the keyboard event callback as none
keyboardCallback_ = 0;
keyboard_callback_cookie_ = 0;
// Initialize the mouse event callback as none
mouseCallback_ = 0;
mouse_callback_cookie_ = 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::saveScreenshot(const String &file)
{
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
vtkSmartPointer<vtkWindowToImageFilter> wif = vtkSmartPointer<vtkWindowToImageFilter>::New();
wif->SetInput(Interactor->GetRenderWindow());
vtkSmartPointer<vtkPNGWriter> snapshot_writer = vtkSmartPointer<vtkPNGWriter>::New();
snapshot_writer->SetInputConnection(wif->GetOutputPort());
snapshot_writer->SetFileName(file.c_str());
snapshot_writer->Write();
cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::exportScene(const String &file)
{
vtkSmartPointer<vtkExporter> exporter;
if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml")
{
exporter = vtkSmartPointer<vtkVRMLExporter>::New();
vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str());
}
else
{
exporter = vtkSmartPointer<vtkOBJExporter>::New();
vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str());
}
exporter->SetInput(Interactor->GetRenderWindow());
exporter->Write();
cout << "Scene successfully exported (" << file.c_str() << ")" << endl;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::zoomIn()
{
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
// Zoom in
StartDolly();
double factor = 10.0 * 0.2 * .5;
Dolly(std::pow(1.1, factor));
EndDolly();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::zoomOut()
{
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
// Zoom out
StartDolly();
double factor = 10.0 * -0.2 * .5;
Dolly(std::pow(1.1, factor));
EndDolly();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnChar()
{
// Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9')
return;
String key(Interactor->GetKeySym());
if (key.find("XF86ZoomIn") != String::npos)
zoomIn();
else if (key.find("XF86ZoomOut") != String::npos)
zoomOut();
int keymod = Interactor->GetAltKey();
switch (Interactor->GetKeyCode())
{
// All of the options below simply exit
case 'h': case 'H':
case 'l': case 'L':
case 'p': case 'P':
case 'j': case 'J':
case 'c': case 'C':
case 43: // KEY_PLUS
case 45: // KEY_MINUS
case 'f': case 'F':
case 'g': case 'G':
case 'o': case 'O':
case 'u': case 'U':
case 'q': case 'Q':
{
break;
}
// S and R have a special !ALT case
case 'r': case 'R':
case 's': case 'S':
{
if (!keymod)
Superclass::OnChar();
break;
}
default:
{
Superclass::OnChar();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie)
{
// Register the callback function and store the user data
mouseCallback_ = callback;
mouse_callback_cookie_ = cookie;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie)
{
// Register the callback function and store the user data
keyboardCallback_ = callback;
keyboard_callback_cookie_ = cookie;
}
//////////////////////////////////////////////////////////////////////////////////////////////
int cv::viz::InteractorStyle::getModifiers()
{
int modifiers = KeyboardEvent::NONE;
if (Interactor->GetAltKey())
modifiers |= KeyboardEvent::ALT;
if (Interactor->GetControlKey())
modifiers |= KeyboardEvent::CTRL;
if (Interactor->GetShiftKey())
modifiers |= KeyboardEvent::SHIFT;
return modifiers;
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnKeyDown()
{
CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_);
FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
// Save the initial windows width/height
if (win_size_[0] == -1 || win_size_[1] == -1)
win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
bool alt = Interactor->GetAltKey() != 0;
std::string key(Interactor->GetKeySym());
if (key.find("XF86ZoomIn") != std::string::npos)
zoomIn();
else if (key.find("XF86ZoomOut") != std::string::npos)
zoomOut();
switch (Interactor->GetKeyCode())
{
case 'h': case 'H':
{
std::cout << "| Help:\n"
"-------\n"
" p, P : switch to a point-based representation\n"
" w, W : switch to a wireframe-based representation (where available)\n"
" s, S : switch to a surface-based representation (where available)\n"
"\n"
" j, J : take a .PNG snapshot of the current window view\n"
" k, K : export scene to Wavefront .obj format\n"
" ALT + k, K : export scene to VRML format\n"
" c, C : display current camera/window parameters\n"
" f, F : fly to point mode, hold the key and move mouse where to fly\n"
"\n"
" e, E : exit the interactor\n"
" q, Q : stop and call VTK's TerminateApp\n"
"\n"
" +/- : increment/decrement overall point size\n"
" +/- [+ ALT] : zoom in/out \n"
"\n"
" r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n"
"\n"
" ALT + s, S : turn stereo mode on/off\n"
" ALT + f, F : switch between maximized window mode and original size\n"
"\n"
<< std::endl;
break;
}
// Switch representation to points
case 'p': case 'P':
{
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
vtkCollectionSimpleIterator ait;
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
{
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
apart->GetProperty()->SetRepresentationToPoints();
}
break;
}
// Save a PNG snapshot
case 'j': case 'J':
saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break;
// Export scene as in obj or vrml format
case 'k': case 'K':
{
String format = alt ? "scene-%d.vrml" : "scene-%d";
exportScene(cv::format(format.c_str(), (unsigned int)time(0)));
break;
}
// display current camera settings/parameters
case 'c': case 'C':
{
vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
Vec2d clip(cam->GetClippingRange());
Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp());
Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition());
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
double angle = cam->GetViewAngle () / 180.0 * CV_PI;
String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)",
clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2],
angle, win_size[0], win_size[1], win_pos[0], win_pos[1]);
std::cout << data.c_str() << std::endl;
break;
}
case '=':
{
zoomIn();
break;
}
case 43: // KEY_PLUS
{
if (alt)
zoomIn();
else
{
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
vtkCollectionSimpleIterator ait;
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
{
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
float psize = apart->GetProperty()->GetPointSize();
if (psize < 63.0f)
apart->GetProperty()->SetPointSize(psize + 1.0f);
}
}
break;
}
case 45: // KEY_MINUS
{
if (alt)
zoomOut();
else
{
vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
vtkCollectionSimpleIterator ait;
for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
{
vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp());
float psize = apart->GetProperty()->GetPointSize();
if (psize > 1.0f)
apart->GetProperty()->SetPointSize(psize - 1.0f);
}
}
break;
}
// Switch between maximize and original window size
case 'f': case 'F':
{
if (alt)
{
Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize());
Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
// Is window size = max?
if (win_size == max_win_size_)
{
Interactor->GetRenderWindow()->SetSize(win_size_.val);
Interactor->GetRenderWindow()->SetPosition(win_pos_.val);
Interactor->GetRenderWindow()->Render();
Interactor->Render();
}
// Set to max
else
{
win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition());
win_size_ = win_size;
Interactor->GetRenderWindow()->SetSize(screen_size.val);
Interactor->GetRenderWindow()->Render();
Interactor->Render();
max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
}
}
else
{
AnimState = VTKIS_ANIM_ON;
Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer);
vtkSmartPointer<vtkAbstractPropPicker> picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker());
if (picker)
if (picker->GetPath())
Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition());
AnimState = VTKIS_ANIM_OFF;
}
break;
}
// 's'/'S' w/out ALT
case 's': case 'S':
{
if (alt)
{
vtkSmartPointer<vtkRenderWindow> window = Interactor->GetRenderWindow();
if (!window->GetStereoRender())
{
static Vec2i red_blue(4, 3), magenta_green(2, 5);
window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? red_blue.val : magenta_green.val);
stereo_anaglyph_mask_default_ = !stereo_anaglyph_mask_default_;
}
window->SetStereoRender(!window->GetStereoRender());
Interactor->Render();
}
else
Superclass::OnKeyDown();
break;
}
case 'o': case 'O':
{
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
cam->SetParallelProjection(!cam->GetParallelProjection());
CurrentRenderer->Render();
break;
}
// Overwrite the camera reset
case 'r': case 'R':
{
if (!alt)
{
Superclass::OnKeyDown();
break;
}
WidgetActorMap::iterator it = widget_actor_map_->begin();
// it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
for (; it != widget_actor_map_->end(); ++it)
{
vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
if (actor && actor->GetUserMatrix())
break;
}
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
// if a valid transformation was found, use it otherwise fall back to default view point.
if (it != widget_actor_map_->end())
{
vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix();
cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2),
m->GetElement(1, 3) - m->GetElement(1, 2),
m->GetElement(2, 3) - m->GetElement(2, 2));
cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1));
cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3));
}
else
{
cam->SetPosition(0, 0, 0);
cam->SetFocalPoint(0, 0, 1);
cam->SetViewUp(0, -1, 0);
}
// go to the next actor for the next key-press event.
if (it != widget_actor_map_->end())
++it;
else
it = widget_actor_map_->begin();
CurrentRenderer->SetActiveCamera(cam);
CurrentRenderer->ResetCameraClippingRange();
CurrentRenderer->Render();
break;
}
case 'q': case 'Q':
{
Interactor->ExitCallback();
return;
}
default:
{
Superclass::OnKeyDown();
break;
}
}
KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
if (keyboardCallback_)
keyboardCallback_(event, keyboard_callback_cookie_);
Interactor->Render();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnKeyUp()
{
KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers());
if (keyboardCallback_)
keyboardCallback_(event, keyboard_callback_cookie_);
Superclass::OnKeyUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMouseMove()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnMouseMove();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnLeftButtonDown()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnLeftButtonDown();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnLeftButtonUp()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnLeftButtonUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMiddleButtonDown()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnMiddleButtonDown();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMiddleButtonUp()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnMiddleButtonUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnRightButtonDown()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
MouseEvent event(type, MouseEvent::RightButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnRightButtonDown();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnRightButtonUp()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
Superclass::OnRightButtonUp();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMouseWheelForward()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetRepeatCount() && mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetAltKey())
{
// zoom
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
double opening_angle = cam->GetViewAngle();
if (opening_angle > 15.0)
opening_angle -= 1.0;
cam->SetViewAngle(opening_angle);
cam->Modified();
CurrentRenderer->ResetCameraClippingRange();
CurrentRenderer->Modified();
CurrentRenderer->Render();
Interactor->Render();
}
else
Superclass::OnMouseWheelForward();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnMouseWheelBackward()
{
Vec2i p(Interactor->GetEventPosition());
MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers());
if (mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetRepeatCount() && mouseCallback_)
mouseCallback_(event, mouse_callback_cookie_);
if (Interactor->GetAltKey())
{
// zoom
vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
double opening_angle = cam->GetViewAngle();
if (opening_angle < 170.0)
opening_angle += 1.0;
cam->SetViewAngle(opening_angle);
cam->Modified();
CurrentRenderer->ResetCameraClippingRange();
CurrentRenderer->Modified();
CurrentRenderer->Render();
Interactor->Render();
}
else
Superclass::OnMouseWheelBackward();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::InteractorStyle::OnTimer()
{
CV_Assert("Interactor style not initialized." && init_);
Interactor->Render();
}

@ -76,7 +76,6 @@
#include <vtkDoubleArray.h> #include <vtkDoubleArray.h>
#include <vtkPointData.h> #include <vtkPointData.h>
#include <vtkPolyData.h> #include <vtkPolyData.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataMapper.h> #include <vtkPolyDataMapper.h>
#include <vtkDataSetMapper.h> #include <vtkDataSetMapper.h>
#include <vtkCellArray.h> #include <vtkCellArray.h>
@ -115,11 +114,9 @@
#include <vtkObjectFactory.h> #include <vtkObjectFactory.h>
#include <vtkPolyDataAlgorithm.h> #include <vtkPolyDataAlgorithm.h>
#include <vtkMergeFilter.h> #include <vtkMergeFilter.h>
#include <vtkDataSetWriter.h>
#include <vtkErrorCode.h> #include <vtkErrorCode.h>
#include <vtkPLYWriter.h> #include <vtkPLYWriter.h>
#include <vtkSTLWriter.h> #include <vtkSTLWriter.h>
#include <vtkSimplePointsReader.h>
#include <vtkPLYReader.h> #include <vtkPLYReader.h>
#include <vtkOBJReader.h> #include <vtkOBJReader.h>
#include <vtkSTLReader.h> #include <vtkSTLReader.h>
@ -133,6 +130,7 @@
#include <vtkElevationFilter.h> #include <vtkElevationFilter.h>
#include <vtkColorTransferFunction.h> #include <vtkColorTransferFunction.h>
#include <vtkStreamingDemandDrivenPipeline.h> #include <vtkStreamingDemandDrivenPipeline.h>
#include "vtkCallbackCommand.h"
#if !defined(_WIN32) || defined(__CYGWIN__) #if !defined(_WIN32) || defined(__CYGWIN__)
# include <unistd.h> /* unlink */ # include <unistd.h> /* unlink */
@ -142,11 +140,13 @@
#include <vtk/vtkOBJWriter.h> #include <vtk/vtkOBJWriter.h>
#include <vtk/vtkXYZWriter.h> #include <vtk/vtkXYZWriter.h>
#include <vtk/vtkXYZReader.h>
#include <vtk/vtkCloudMatSink.h> #include <vtk/vtkCloudMatSink.h>
#include <vtk/vtkCloudMatSource.h> #include <vtk/vtkCloudMatSource.h>
#include <vtk/vtkTrajectorySource.h> #include <vtk/vtkTrajectorySource.h>
#include <vtk/vtkImageMatSource.h> #include <vtk/vtkImageMatSource.h>
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <opencv2/viz/vizcore.hpp> #include <opencv2/viz/vizcore.hpp>
#include <opencv2/viz/widget_accessor.hpp> #include <opencv2/viz/widget_accessor.hpp>
@ -157,7 +157,16 @@ namespace cv
namespace viz namespace viz
{ {
typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap; 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 class VizStorage
{ {
@ -169,7 +178,6 @@ namespace cv
private: private:
VizStorage(); // Static VizStorage(); // Static
~VizStorage();
static void add(const Viz3d& window); static void add(const Viz3d& window);
static Viz3d& get(const String &window_name); static Viz3d& get(const String &window_name);
@ -179,6 +187,8 @@ namespace cv
static VizMap storage; static VizMap storage;
friend class Viz3d; friend class Viz3d;
static VizStorage init;
}; };
template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); } template<typename _Tp> inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); }
@ -269,11 +279,16 @@ namespace cv
vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New(); vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
scalars->SetName("Colors"); scalars->SetName("Colors");
scalars->SetNumberOfComponents(3); scalars->SetNumberOfComponents(3);
scalars->SetNumberOfTuples(size); scalars->SetNumberOfTuples((vtkIdType)size);
scalars->SetArray(color_data->val, size * 3, 0); scalars->SetArray(color_data->val, (vtkIdType)(size * 3), 0);
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();
@ -314,11 +329,12 @@ namespace cv
return transform_filter->GetOutput(); return transform_filter->GetOutput();
} }
}; };
vtkSmartPointer<vtkRenderWindowInteractor> vtkCocoaRenderWindowInteractorNew();
} }
} }
#include "interactor_style.hpp" #include "vtk/vtkVizInteractorStyle.hpp"
#include "vizimpl.hpp" #include "vizimpl.hpp"
#endif #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->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 &center, 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);
const float *fpoints = _points.getMat().ptr<float>(); cloud_source->Update();
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);
if (_points.depth() == CV_32F) vtkSmartPointer<vtkPolyData> polydata = cloud_source->GetOutput();
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<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
cell_array->Allocate(cell_array->EstimateSize(1, total)); cell_array->Allocate(cell_array->EstimateSize(1, polydata->GetNumberOfPoints()));
cell_array->InsertNextCell(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(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>()

@ -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); } 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::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 /// 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; 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) cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name)
{ {
String name = generateWindowName(window_name); String name = generateWindowName(window_name);
VizMap::iterator vm_itr = storage.find(name); VizMap::iterator vm_itr = storage.m.find(name);
CV_Assert(vm_itr != storage.end()); CV_Assert(vm_itr != storage.m.end());
return vm_itr->second; return vm_itr->second;
} }
void cv::viz::VizStorage::add(const Viz3d& window) void cv::viz::VizStorage::add(const Viz3d& window)
{ {
String window_name = window.getWindowName(); String window_name = window.getWindowName();
VizMap::iterator vm_itr = storage.find(window_name); VizMap::iterator vm_itr = storage.m.find(window_name);
CV_Assert(vm_itr == storage.end()); CV_Assert(vm_itr == storage.m.end());
storage.insert(std::make_pair(window_name, window)); storage.m.insert(std::make_pair(window_name, window));
} }
bool cv::viz::VizStorage::windowExists(const String &window_name) bool cv::viz::VizStorage::windowExists(const String &window_name)
{ {
String name = generateWindowName(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() 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) if(pos->second.impl_->ref_counter == 1)
storage.erase(pos++); storage.m.erase(pos++);
else else
++pos; ++pos;
} }
@ -173,8 +208,8 @@ cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray n
vtkSmartPointer<vtkPolyDataAlgorithm> reader; vtkSmartPointer<vtkPolyDataAlgorithm> reader;
if (extention == ".xyz") if (extention == ".xyz")
{ {
reader = vtkSmartPointer<vtkSimplePointsReader>::New(); reader = vtkSmartPointer<vtkXYZReader>::New();
vtkSimplePointsReader::SafeDownCast(reader)->SetFileName(file.c_str()); vtkXYZReader::SafeDownCast(reader)->SetFileName(file.c_str());
} }
else if (extention == ".ply") 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 (_traj.kind() == _InputArray::STD_VECTOR_MAT)
{ {
#if CV_MAJOR_VERSION < 3
std::vector<Mat>& v = *(std::vector<Mat>*)_traj.obj; 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) 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) if (traj.depth() == CV_32F)
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) 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) if (traj.depth() == CV_64F)
for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) 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"); CV_Assert(!"Unsupported array kind");

@ -60,16 +60,19 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false),
window_->AddRenderer(renderer_); window_->AddRenderer(renderer_);
// Create the interactor style // Create the interactor style
style_ = vtkSmartPointer<InteractorStyle>::New(); style_ = vtkSmartPointer<vtkVizInteractorStyle>::New();
style_->setWidgetActorMap(widget_actor_map_); style_->setWidgetActorMap(widget_actor_map_);
style_->UseTimersOn(); style_->UseTimersOn();
style_->Initialize();
timer_callback_ = vtkSmartPointer<TimerCallback>::New(); timer_callback_ = vtkSmartPointer<TimerCallback>::New();
exit_callback_ = vtkSmartPointer<ExitCallback>::New(); exit_callback_ = vtkSmartPointer<ExitCallback>::New();
exit_callback_->viz = this; 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) 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() 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 //recreating is workaround for Ubuntu -- a crash in x-server
Vec2i window_size(window_->GetSize()); Vec2i window_size(window_->GetSize());
int fullscreen = window_->GetFullScreen(); int fullscreen = window_->GetFullScreen();
window_->Finalize();
window_ = vtkSmartPointer<vtkRenderWindow>::New(); window_ = vtkSmartPointer<vtkRenderWindow>::New();
if (window_position_[0] != std::numeric_limits<int>::min()) //also workaround if (window_position_[0] != std::numeric_limits<int>::min()) //also workaround
window_->SetPosition(window_position_.val); window_->SetPosition(window_position_.val);
@ -124,12 +128,15 @@ void cv::viz::Viz3d::VizImpl::recreateRenderWindow()
#endif #endif
} }
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::spin() void cv::viz::Viz3d::VizImpl::spin()
{ {
recreateRenderWindow(); recreateRenderWindow();
#if defined __APPLE__
interactor_ = vtkCocoaRenderWindowInteractorNew();
#else
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
#endif
interactor_->SetRenderWindow(window_); interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_); interactor_->SetInteractorStyle(style_);
window_->AlphaBitPlanesOff(); window_->AlphaBitPlanesOff();
@ -151,7 +158,11 @@ void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
{ {
spin_once_state_ = true; spin_once_state_ = true;
recreateRenderWindow(); recreateRenderWindow();
#if defined __APPLE__
interactor_ = vtkCocoaRenderWindowInteractorNew();
#else
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
#endif
interactor_->SetRenderWindow(window_); interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_); interactor_->SetInteractorStyle(style_);
interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_); interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_);

@ -55,7 +55,7 @@ public:
int ref_counter; int ref_counter;
VizImpl(const String &name); VizImpl(const String &name);
virtual ~VizImpl() {} virtual ~VizImpl();
bool wasStopped() const; bool wasStopped() const;
void close(); void close();
@ -128,7 +128,7 @@ private:
vtkSmartPointer<ExitCallback> exit_callback_; vtkSmartPointer<ExitCallback> exit_callback_;
vtkSmartPointer<vtkRenderer> renderer_; vtkSmartPointer<vtkRenderer> renderer_;
vtkSmartPointer<InteractorStyle> style_; vtkSmartPointer<vtkVizInteractorStyle> style_;
Ptr<WidgetActorMap> widget_actor_map_; Ptr<WidgetActorMap> widget_actor_map_;
bool removeActorFromRenderer(vtkSmartPointer<vtkProp> actor); bool removeActorFromRenderer(vtkSmartPointer<vtkProp> actor);

@ -79,11 +79,11 @@ void cv::viz::vtkCloudMatSink::WriteData()
if (cloud.depth() == CV_32F) if (cloud.depth() == CV_32F)
for(size_t i = 0; i < cloud.total(); ++i) 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) if (cloud.depth() == CV_64F)
for(size_t i = 0; i < cloud.total(); ++i) for(size_t i = 0; i < cloud.total(); ++i)
*ddata++ = Vec3d(points_Data->GetPoint(i)); *ddata++ = Vec3d(points_Data->GetPoint((vtkIdType)i));
} }
else else
cloud.release(); cloud.release();
@ -101,7 +101,7 @@ void cv::viz::vtkCloudMatSink::WriteData()
Mat buffer(cloud.size(), CV_64FC(channels)); Mat buffer(cloud.size(), CV_64FC(channels));
Vec3d *cptr = buffer.ptr<Vec3d>(); Vec3d *cptr = buffer.ptr<Vec3d>();
for(size_t i = 0; i < buffer.total(); ++i) 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); 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)); Mat buffer(cloud.size(), CV_64FC(channels));
Vec3d *cptr = buffer.ptr<Vec3d>(); Vec3d *cptr = buffer.ptr<Vec3d>();
for(size_t i = 0; i < buffer.total(); ++i) 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); 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); Mat buffer(cloud.size(), CV_64FC2);
Vec2d *cptr = buffer.ptr<Vec2d>(); Vec2d *cptr = buffer.ptr<Vec2d>();
for(size_t i = 0; i < buffer.total(); ++i) 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); 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 << "Colors: " << colors.needed() << "\n";
os << indent << "Normals: " << normals.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 #define __vtkCloudMatSink_h
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <vtkPolyDataWriter.h> #include <vtkWriter.h>
namespace cv namespace cv
{ {
namespace viz namespace viz
{ {
class vtkCloudMatSink : public vtkPolyDataWriter class vtkCloudMatSink : public vtkWriter
{ {
public: public:
static vtkCloudMatSink *New(); static vtkCloudMatSink *New();
vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter) vtkTypeMacro(vtkCloudMatSink,vtkWriter)
void PrintSelf(ostream& os, vtkIndent indent); void PrintSelf(ostream& os, vtkIndent indent);
void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray()); 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: protected:
vtkCloudMatSink(); vtkCloudMatSink();
~vtkCloudMatSink(); ~vtkCloudMatSink();
void WriteData(); void WriteData();
int FillInputPortInformation(int port, vtkInformation *info);
_OutputArray cloud, colors, normals, tcoords; _OutputArray cloud, colors, normals, tcoords;

@ -185,8 +185,8 @@ int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud)
CV_DbgAssert(DataType<_Tp>::depth == cloud.depth()); CV_DbgAssert(DataType<_Tp>::depth == cloud.depth());
points = vtkSmartPointer<vtkPoints>::New(); points = vtkSmartPointer<vtkPoints>::New();
points->SetDataType(VtkDepthTraits<_Tp>::data_type); points->SetDataType(VtkDepthTraits<_Tp>::data_type);
points->Allocate(cloud.total()); points->Allocate((vtkIdType)cloud.total());
points->SetNumberOfPoints(cloud.total()); points->SetNumberOfPoints((vtkIdType)cloud.total());
int s_chs = cloud.channels(); int s_chs = cloud.channels();
int total = 0; int total = 0;

@ -0,0 +1,211 @@
/*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 std::ofstream fout; // only used to extract the default precision
this->DecimalPrecision = fout.precision(); this->DecimalPrecision = fout.precision();
this->FileName = NULL; this->FileName = NULL;
this->FileType = VTK_ASCII;
} }
cv::viz::vtkOBJWriter::~vtkOBJWriter(){} cv::viz::vtkOBJWriter::~vtkOBJWriter(){}
@ -65,14 +64,27 @@ void cv::viz::vtkOBJWriter::WriteData()
if (!input) if (!input)
return; return;
std::ostream *outfilep = this->OpenVTKFile(); if (!this->FileName )
if (!outfilep) {
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; return;
}
std::ostream& outfile = *outfilep; std::ostream& outfile = *outfilep;
//write header //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; outfile << "mtllib NONE" << std::endl << std::endl;
// write out the points // write out the points
@ -224,7 +236,8 @@ void cv::viz::vtkOBJWriter::WriteData()
} }
} /* if (input->GetNumberOfStrips() > 0) */ } /* if (input->GetNumberOfStrips() > 0) */
this->CloseVTKFile(outfilep); vtkDebugMacro(<<"Closing vtk file\n");
delete outfilep;
// Delete the file if an error occurred // Delete the file if an error occurred
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
@ -239,3 +252,19 @@ void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent)
Superclass::PrintSelf(os, indent); Superclass::PrintSelf(os, indent);
os << indent << "DecimalPrecision: " << DecimalPrecision << "\n"; 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 #ifndef __vtkOBJWriter_h
#define __vtkOBJWriter_h #define __vtkOBJWriter_h
#include <vtkPolyDataWriter.h> #include <vtkWriter.h>
namespace cv namespace cv
{ {
namespace viz namespace viz
{ {
class vtkOBJWriter : public vtkPolyDataWriter class vtkOBJWriter : public vtkWriter
{ {
public: public:
static vtkOBJWriter *New(); static vtkOBJWriter *New();
vtkTypeMacro(vtkOBJWriter,vtkPolyDataWriter) vtkTypeMacro(vtkOBJWriter,vtkWriter)
void PrintSelf(ostream& os, vtkIndent indent); void PrintSelf(ostream& os, vtkIndent indent);
vtkGetMacro(DecimalPrecision, int); vtkGetMacro(DecimalPrecision, int)
vtkSetMacro(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: protected:
vtkOBJWriter(); vtkOBJWriter();
~vtkOBJWriter(); ~vtkOBJWriter();
void WriteData(); void WriteData();
int FillInputPortInformation(int port, vtkInformation *info);
int DecimalPrecision; int DecimalPrecision;
char *FileName;
private: private:
vtkOBJWriter(const vtkOBJWriter&); // Not implemented. vtkOBJWriter(const vtkOBJWriter&); // Not implemented.

@ -64,19 +64,19 @@ void cv::viz::vtkTrajectorySource::SetTrajectory(InputArray _traj)
points = vtkSmartPointer<vtkPoints>::New(); points = vtkSmartPointer<vtkPoints>::New();
points->SetDataType(VTK_DOUBLE); points->SetDataType(VTK_DOUBLE);
points->SetNumberOfPoints(total); points->SetNumberOfPoints((vtkIdType)total);
tensors = vtkSmartPointer<vtkDoubleArray>::New(); tensors = vtkSmartPointer<vtkDoubleArray>::New();
tensors->SetNumberOfComponents(9); tensors->SetNumberOfComponents(9);
tensors->SetNumberOfTuples(total); tensors->SetNumberOfTuples((vtkIdType)total);
for(size_t i = 0; i < total; ++i, ++dpath) for(size_t i = 0; i < total; ++i, ++dpath)
{ {
Matx33d R = dpath->rotation().t(); // transposed because of 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(); 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.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT);
CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); 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 Affine3d* dpath = _traj.getMat().ptr<Affine3d>();
const Affine3f* fpath = _traj.getMat().ptr<Affine3f>(); const Affine3f* fpath = _traj.getMat().ptr<Affine3f>();

File diff suppressed because it is too large Load Diff

@ -46,64 +46,101 @@
#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__ #ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__
#define __OPENCV_VIZ_INTERACTOR_STYLE_H__ #define __OPENCV_VIZ_INTERACTOR_STYLE_H__
#include <vtkInteractorStyle.h>
namespace cv namespace cv
{ {
namespace viz namespace viz
{ {
class InteractorStyle : public vtkInteractorStyleTrackballCamera class vtkVizInteractorStyle : public vtkInteractorStyle
{ {
public: public:
static InteractorStyle *New(); static vtkVizInteractorStyle *New();
virtual ~InteractorStyle() {} vtkTypeMacro(vtkVizInteractorStyle, vtkInteractorStyle)
void PrintSelf(ostream& os, vtkIndent indent);
// this macro defines Superclass, the isA functionality and the safe downcast method virtual void OnChar();
vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera) virtual void OnKeyDown();
virtual void OnKeyUp();
/** \brief Initialization routine. Must be called before anything else. */ virtual void OnMouseMove();
virtual void Initialize(); 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 registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0);
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, 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 saveScreenshot(const String &file);
void exportScene(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: private:
/** \brief Set to true after initialization is complete. */
bool init_;
Ptr<WidgetActorMap> widget_actor_map_; Ptr<WidgetActorMap> widget_actor_map_;
Vec2i win_size_; Vec2i win_size_;
Vec2i win_pos_; Vec2i win_pos_;
Vec2i max_win_size_; Vec2i max_win_size_;
/** \brief Interactor style internal method. Gets called whenever a key is pressed. */ void zoomIn();
virtual void OnChar(); void zoomOut();
// Keyboard events protected:
virtual void OnKeyDown(); vtkVizInteractorStyle();
virtual void OnKeyUp(); ~vtkVizInteractorStyle();
// mouse button events virtual void Dolly(double factor);
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();
/** \brief Interactor style internal method. Gets called periodically if a timer is set. */ void Fly();
virtual void OnTimer(); void FlyByMouse();
void FlyByKey();
void SetupMotionVars();
void MotionAlongVector(const Vec3d& vector, double amount, vtkCamera* cam);
void zoomIn(); private:
void zoomOut(); vtkVizInteractorStyle(const vtkVizInteractorStyle&);
vtkVizInteractorStyle& operator=(const vtkVizInteractorStyle&);
/** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */ //! True for red-blue colors, false for magenta-green.
bool stereo_anaglyph_mask_default_; bool stereo_anaglyph_redblue_;
void (*keyboardCallback_)(const KeyboardEvent&, void*); void (*keyboardCallback_)(const KeyboardEvent&, void*);
void *keyboard_callback_cookie_; void *keyboard_callback_cookie_;
@ -111,7 +148,20 @@ namespace cv
void (*mouseCallback_)(const MouseEvent&, void*); void (*mouseCallback_)(const MouseEvent&, void*);
void *mouse_callback_cookie_; void *mouse_callback_cookie_;
bool FlyMode;
double MotionFactor;
int getModifiers(); int getModifiers();
// from fly
unsigned char KeysDown;
double DiagonalLength;
double MotionStepSize;
double MotionUserScale;
double MotionAccelerationFactor;
double AngleStepSize;
double DeltaYaw;
double DeltaPitch;
}; };
} }
} }

@ -0,0 +1,107 @@
/*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;
}

@ -0,0 +1,80 @@
/*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) if (!input)
return; return;
// OpenVTKFile() will report any errors that happen if (!this->FileName )
ostream *outfilep = this->OpenVTKFile(); {
if (!outfilep) 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; return;
}
ostream &outfile = *outfilep; ostream &outfile = *outfilep;
@ -76,7 +88,8 @@ void cv::viz::vtkXYZWriter::WriteData()
} }
// Close the file // Close the file
this->CloseVTKFile(outfilep); vtkDebugMacro(<<"Closing vtk file\n");
delete outfilep;
// Delete the file if an error occurred // Delete the file if an error occurred
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) 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) void cv::viz::vtkXYZWriter::PrintSelf(ostream& os, vtkIndent indent)
{ {
this->Superclass::PrintSelf(os,indent); this->Superclass::PrintSelf(os,indent);
os << indent << "DecimalPrecision: " << this->DecimalPrecision << "\n"; 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 #ifndef __vtkXYZWriter_h
#define __vtkXYZWriter_h #define __vtkXYZWriter_h
#include "vtkPolyDataWriter.h" #include "vtkWriter.h"
namespace cv namespace cv
{ {
namespace viz namespace viz
{ {
class vtkXYZWriter : public vtkPolyDataWriter class vtkXYZWriter : public vtkWriter
{ {
public: public:
static vtkXYZWriter *New(); static vtkXYZWriter *New();
vtkTypeMacro(vtkXYZWriter,vtkPolyDataWriter) vtkTypeMacro(vtkXYZWriter,vtkWriter)
void PrintSelf(ostream& os, vtkIndent indent); void PrintSelf(ostream& os, vtkIndent indent);
vtkGetMacro(DecimalPrecision, int) vtkGetMacro(DecimalPrecision, int)
vtkSetMacro(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: protected:
vtkXYZWriter(); vtkXYZWriter();
~vtkXYZWriter(){} ~vtkXYZWriter(){}
void WriteData(); void WriteData();
int FillInputPortInformation(int port, vtkInformation *info);
int DecimalPrecision; int DecimalPrecision;
char *FileName;
private: private:
vtkXYZWriter(const vtkXYZWriter&); // Not implemented. vtkXYZWriter(const vtkXYZWriter&); // Not implemented.

@ -54,12 +54,20 @@
#ifndef __OPENCV_TEST_PRECOMP_HPP__ #ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__ #define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts/ts.hpp" #include <opencv2/core/version.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/viz/vizcore.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 <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>

@ -59,6 +59,5 @@ TEST(Viz_viz3d, DISABLED_develop)
//cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path()); //cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path());
//---->>>>> </to_test_in_future> //---->>>>> </to_test_in_future>
viz.spin(); viz.spin();
} }

@ -52,6 +52,7 @@ TEST(Viz, show_cloud_bluberry)
Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0));
Viz3d viz("show_cloud_bluberry"); Viz3d viz("show_cloud_bluberry");
viz.setBackgroundColor(Color::black());
viz.showWidget("coosys", WCoordinateSystem()); viz.showWidget("coosys", WCoordinateSystem());
viz.showWidget("dragon", WCloud(dragon_cloud, Color::bluberry()), pose); 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()); Mat dragon_cloud = readCloud(get_dragon_ply_file_path());
Vec3f qnan = Vec3f::all(std::numeric_limits<float>::quiet_NaN()); 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) if (i % 15 != 0)
dragon_cloud.at<Vec3f>(i) = qnan; 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::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::blue(), Affine3d().translate(Vec3d(1, 0, 0)));
ccol.addCloud(cloud, Color::red(), Affine3d().translate(Vec3d(2, 0, 0))); ccol.addCloud(cloud, Color::red(), Affine3d().translate(Vec3d(2, 0, 0)));
ccol.finalize();
Viz3d viz("show_cloud_collection"); Viz3d viz("show_cloud_collection");
viz.setBackgroundColor(Color::mlab()); viz.setBackgroundColor(Color::mlab());
@ -154,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"));
@ -170,7 +193,7 @@ TEST(Viz, show_textured_mesh)
tcoords.push_back(Vec2d(1.0, i/64.0)); 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}; 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])); polygons.insert(polygons.end(), polys, polys + sizeof(polys)/sizeof(polys[0]));
@ -193,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() };
for(size_t i = 0; i < polyline.total(); ++i) 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)); 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();
@ -222,13 +251,14 @@ TEST(Viz, show_sampled_normals)
TEST(Viz, show_trajectories) TEST(Viz, show_trajectories)
{ {
std::vector<Affine3d> path = generate_test_trajectory<double>(), sub0, sub1, sub2, sub3, sub4, sub5; std::vector<Affine3d> path = generate_test_trajectory<double>(), sub0, sub1, sub2, sub3, sub4, sub5;
int size =(int)path.size();
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(0, size/10+1).copyTo(sub0);
Mat(path).rowRange(path.size()/5, 11*path.size()/12).copyTo(sub2); Mat(path).rowRange(size/10, size/5+1).copyTo(sub1);
Mat(path).rowRange(11*path.size()/12, path.size()).copyTo(sub3); Mat(path).rowRange(size/5, 11*size/12).copyTo(sub2);
Mat(path).rowRange(3*path.size()/4, 33*path.size()/40).copyTo(sub4); Mat(path).rowRange(11*size/12, size).copyTo(sub3);
Mat(path).rowRange(33*path.size()/40, 9*path.size()/10).copyTo(sub5); 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); Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0);
Viz3d viz("show_trajectories"); Viz3d viz("show_trajectories");
@ -259,7 +289,7 @@ TEST(Viz, show_trajectory_reposition)
Viz3d viz("show_trajectory_reposition_to_origin"); Viz3d viz("show_trajectory_reposition_to_origin");
viz.showWidget("coos", WCoordinateSystem()); 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.showWidget("text2d", WText("Trajectory resposition to origin", Point(20, 20), 20, Color::green()));
viz.spin(); viz.spin();
} }

Loading…
Cancel
Save