Commit 24465bbd authored by Roman Donchenko's avatar Roman Donchenko Committed by OpenCV Buildbot

Merge pull request #1855 from Nerei:master

parents 8db53c17 4c66b876
......@@ -116,6 +116,7 @@ endif()
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS)
OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE )
OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" OFF IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (NOT IOS) )
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (NOT IOS) )
OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (NOT IOS) )
......@@ -430,6 +431,8 @@ endif()
# --- Matlab/Octave ---
include(cmake/OpenCVFindMatlab.cmake)
include(cmake/OpenCVDetectVTK.cmake)
# ----------------------------------------------------------------------------
# Add CUDA libraries (needed for apps/tools, samples)
# ----------------------------------------------------------------------------
......@@ -659,6 +662,7 @@ else()
endif()
status(" OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO)
status(" VTK support:" HAVE_VTK THEN "YES (ver ${VTK_VERSION})" ELSE NO)
# ========================== MEDIA IO ==========================
status("")
......
if(NOT WITH_VTK OR ANDROID OR IOS)
return()
endif()
find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture NO_MODULE)
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND)
find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE)
endif()
if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND)
find_package(VTK 5.8 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE)
endif()
if(VTK_FOUND)
set(HAVE_VTK ON)
message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})")
else()
set(HAVE_VTK OFF)
message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or set $VTK_DIR enviroment variable to VTK install subdirectory with VTKConfig.cmake file (for windows)")
endif()
\ No newline at end of file
......@@ -79,3 +79,30 @@ TEST(Calib3d_Affine3f, accuracy)
ASSERT_LT(cv::norm(diff, cv::NORM_INF), 1e-15);
}
TEST(Calib3d_Affine3f, accuracy_rvec)
{
cv::RNG rng;
typedef float T;
cv::Affine3<T>::Vec3 w;
cv::Affine3<T>::Mat3 u, vt, R;
for(int i = 0; i < 100; ++i)
{
rng.fill(R, cv::RNG::UNIFORM, -10, 10, true);
cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
R = u * vt;
//double s = (double)cv::getTickCount();
cv::Affine3<T>::Vec3 va = cv::Affine3<T>(R).rvec();
//std::cout << "M:" <<(cv::getTickCount() - s)*1000/cv::getTickFrequency() << std::endl;
cv::Affine3<T>::Vec3 vo;
//s = (double)cv::getTickCount();
cv::Rodrigues(R, vo);
//std::cout << "O:" <<(cv::getTickCount() - s)*1000/cv::getTickFrequency() << std::endl;
ASSERT_LT(cv::norm(va - vo), 1e-9);
}
}
......@@ -51,7 +51,7 @@
namespace cv
{
template<typename T>
class CV_EXPORTS Affine3
class Affine3
{
public:
typedef T float_type;
......@@ -97,6 +97,9 @@ namespace cv
Mat3 linear() const;
Vec3 translation() const;
//Rodrigues vector
Vec3 rvec() const;
Affine3 inv(int method = cv::DECOMP_SVD) const;
// a.rotate(R) is equivalent to Affine(R, 0) * a;
......@@ -158,9 +161,9 @@ cv::Affine3<T>::Affine3(const Mat3& R, const Vec3& t)
}
template<typename T> inline
cv::Affine3<T>::Affine3(const Vec3& rvec, const Vec3& t)
cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
{
rotation(rvec);
rotation(_rvec);
translation(t);
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
matrix.val[15] = 1;
......@@ -205,9 +208,9 @@ void cv::Affine3<T>::rotation(const Mat3& R)
}
template<typename T> inline
void cv::Affine3<T>::rotation(const Vec3& rvec)
void cv::Affine3<T>::rotation(const Vec3& _rvec)
{
double rx = rvec[0], ry = rvec[1], rz = rvec[2];
double rx = _rvec[0], ry = _rvec[1], rz = _rvec[2];
double theta = std::sqrt(rx*rx + ry*ry + rz*rz);
if (theta < DBL_EPSILON)
......@@ -250,9 +253,9 @@ void cv::Affine3<T>::rotation(const cv::Mat& data)
}
else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3))
{
Vec3 rvec;
data.reshape(1, 3).copyTo(rvec);
rotation(rvec);
Vec3 _rvec;
data.reshape(1, 3).copyTo(_rvec);
rotation(_rvec);
}
else
CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
......@@ -300,6 +303,55 @@ typename cv::Affine3<T>::Vec3 cv::Affine3<T>::translation() const
return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]);
}
template<typename T> inline
typename cv::Affine3<T>::Vec3 cv::Affine3<T>::rvec() const
{
cv::Vec3d w;
cv::Matx33d u, vt, R = rotation();
cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A);
R = u * vt;
double rx = R.val[7] - R.val[5];
double ry = R.val[2] - R.val[6];
double rz = R.val[3] - R.val[1];
double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25);
double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5;
c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c;
double theta = acos(c);
if( s < 1e-5 )
{
if( c > 0 )
rx = ry = rz = 0;
else
{
double t;
t = (R.val[0] + 1) * 0.5;
rx = std::sqrt(std::max(t, 0.0));
t = (R.val[4] + 1) * 0.5;
ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0);
t = (R.val[8] + 1) * 0.5;
rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0);
if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) )
rz = -rz;
theta /= std::sqrt(rx*rx + ry*ry + rz*rz);
rx *= theta;
ry *= theta;
rz *= theta;
}
}
else
{
double vth = 1/(2*s);
vth *= theta;
rx *= vth; ry *= vth; rz *= vth;
}
return cv::Vec3d(rx, ry, rz);
}
template<typename T> inline
cv::Affine3<T> cv::Affine3<T>::inv(int method) const
{
......
......@@ -436,7 +436,7 @@ int print(const std::vector<Point3_<_Tp> >& vec, FILE* stream = stdout)
template<typename _Tp, int m, int n> static inline
int print(const Matx<_Tp, m, n>& matx, FILE* stream = stdout)
{
return print(Formatter::get()->format(matx), stream);
return print(Formatter::get()->format(cv::Mat(matx)), stream);
}
......
......@@ -152,7 +152,7 @@ public:
task = new( tbb::task::allocate_root() ) TBBApproximateSynchronizerTask( *this );
tbb::task::enqueue(*task);
#else
task->reset( new ApproximateSynchronizer( *this ) );
task.reset( new ApproximateSynchronizer( *this ) );
#endif
}
......
macro(find_qvtk)
find_library (QVTK_LIBRARY QVTK HINTS ${VTK_DIR} ${VTK_DIR}/bin)
find_path (QVTK_INCLUDE_DIR QVTKWidget.h HINT ${VTK_INCLUDE_DIRS})
find_package_handle_standard_args(QVTK DEFAULT_MSG QVTK_LIBRARY QVTK_INCLUDE_DIR)
if(QVTK_FOUND)
get_filename_component (QVTK_LIBRARY_DIR ${QVTK_LIBRARY} PATH)
list(APPEND VTK_LIBRARY_DIRS ${QVTK_LIBRARY_DIR})
list(APPEND VTK_INCLUDE_DIRS ${QVTK_INCLUDE_DIR})
set (VTK_USE_QVTK ON)
endif()
endmacro()
macro(find_vtk)
find_package(VTK)
if(${VTK_MAJOR_VERSION} LESS 5)
MESSAGE(FATAL_ERROR "VTK 5 or more required!")
endif()
if(VTK_FOUND)
if (BUILD_SHARED_LIBS OR (NOT BUILD_SHARED_LIBS AND NOT VTK_BUILD_SHARED_LIBS))
find_qvtk()
message(STATUS "VTK found (include: ${VTK_INCLUDE_DIRS}, lib: ${VTK_LIBRARY_DIRS})")
link_directories(${VTK_LIBRARY_DIRS})
include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
set(HAVE_VTK ON)
else ()
set(HAVE_VTK OFF)
message (FATAL_ERROR "VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!")
endif ()
endif()
endmacro()
if (NOT OPENCV_INITIAL_PASS AND DEFINED BUILD_opencv_viz AND BUILD_opencv_viz)
find_vtk()
endif()
if(DEFINED HAVE_VTK AND HAVE_VTK)
set(VTK_USE_FILE ${VTK_USE_FILE} CACHE INTERNAL "VTK_USE_FILE")
include (${VTK_USE_FILE})
add_definitions(-DHAVE_VTK)
if(NOT WITH_VTK OR NOT DEFINED HAVE_VTK OR NOT HAVE_VTK)
ocv_module_disable(viz)
endif()
include(${VTK_USE_FILE})
set(the_description "Viz")
set(BUILD_opencv_viz_INIT OFF)
include_directories(src)
ocv_define_module(viz opencv_core)
ocv_define_module(viz opencv_core ${VTK_LIBRARIES})
if(DEFINED BUILD_opencv_viz AND BUILD_opencv_viz AND DEFINED HAVE_VTK AND HAVE_VTK)
if (${VTK_VERSION_MAJOR} EQUAL 5)
target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering)
else()
target_link_libraries(opencv_viz vtkViewsCore vtkRenderingLOD vtkIOPLY vtkRenderingFreeTypeOpenGL vtkRenderingVolumeOpenGL vtkFiltersTexture)
endif()
if(APPLE)
target_link_libraries(opencv_viz "-framework Cocoa")
endif()
if(APPLE AND BUILD_opencv_viz)
target_link_libraries(opencv_viz "-framework Cocoa")
endif()
......@@ -76,68 +76,6 @@ Checks **point** for nan
:param p: return true if **any** of the elements of the point is *nan*.
viz::VizAccessor
----------------
.. ocv:class:: VizAccessor
A singleton class that provides access by name infrastructure for 3D visualization windows. ::
class CV_EXPORTS VizAccessor
{
public:
static VizAccessor & getInstance();
static void release();
Viz3d get(const String &window_name);
//! window names automatically have Viz - prefix even though not provided by the users
static void generateWindowName(const String &window_name, String &output);
private:
/* hidden */
};
viz::VizAccessor::getInstance
-----------------------------
Returns the single instance of VizAccessor.
.. ocv:function:: static VizAccessor & getInstance()
viz::VizAccessor::release
-------------------------
Deletes the single instance of VizAccessor.
.. ocv:function:: static void release()
viz::VizAccessor::get
---------------------
Retrieves a window by its name.
.. ocv:function:: Viz3d get(const String &window_name)
:param window_name: Name of the window that is to be retrieved.
This function returns a :ocv:class:`Viz3d` object with the given name.
.. note:: If the window with that name already exists, that window is returned. Otherwise, new window is created with the given name, and it is returned.
.. note:: Window names are automatically prefixed by "Viz - " if it is not done by the user.
.. code-block:: cpp
/// window and window_2 are the same windows.
viz::Viz3d window = viz::get("myWindow");
viz::Viz3d window_2 = viz::get("Viz - myWindow");
viz::VizAccessor::generateWindowName
------------------------------------
Generates a window name by prefixing "Viz - " if it has not already been prefixed.
.. ocv:function:: static void generateWindowName(const String &window_name, String &output)
:param window_name: Window name
:param output: Prefixed window name
viz::Viz3d
----------
.. ocv:class:: Viz3d
......
This diff is collapsed.
......@@ -63,9 +63,12 @@ namespace cv
//! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation)
CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir);
//! retrieves a window by its name
//! retrieves a window by its name. If no window with such name, then it creates new.
CV_EXPORTS Viz3d get(const String &window_name);
//! Unregisters all Viz windows from internal database. After it 'get()' will create new windows instead getting existing from the database.
CV_EXPORTS void unregisterAllWindows();
//! checks float value for Nan
inline bool isNan(float x)
{
......@@ -88,32 +91,6 @@ namespace cv
template<typename _Tp> inline bool isNan(const Point3_<_Tp>& p)
{ return isNan(p.x) || isNan(p.y) || isNan(p.z); }
//! helper class that provides access by name infrastructure
class CV_EXPORTS VizAccessor
{
public:
static VizAccessor & getInstance();
static void release();
Viz3d get(const String &window_name);
//! window names automatically have Viz - prefix even though not provided by the users
static void generateWindowName(const String &window_name, String &output);
private:
VizAccessor(); // Singleton
~VizAccessor();
void add(Viz3d window);
void remove(const String &window_name);
static VizAccessor * instance_;
struct VizAccessorImpl;
VizAccessorImpl * impl_;
friend class Viz3d;
};
} /* namespace viz */
} /* namespace cv */
......
......@@ -176,8 +176,8 @@ namespace cv
/// cv::viz::Color
inline cv::viz::Color::Color() : Scalar(0, 0, 0) {}
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 _gray) : Scalar(_gray, _gray, _gray) {}
inline cv::viz::Color::Color(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {}
inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {}
inline cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); }
......
......@@ -49,7 +49,7 @@
#ifndef __OPENCV_VIZ_VIZ3D_HPP__
#define __OPENCV_VIZ_VIZ3D_HPP__
#if !defined YES_I_AGREE_THAT_VIZ_API_IS_NOT_STABLE_NOW_AND_BINARY_COMPARTIBILITY_WONT_BE_SUPPORTED
#if !defined YES_I_AGREE_THAT_VIZ_API_IS_NOT_STABLE_NOW_AND_BINARY_COMPARTIBILITY_WONT_BE_SUPPORTED && !defined CVAPI_EXPORTS
//#error "Viz is in beta state now. Please define macro above to use it"
#endif
......@@ -64,7 +64,6 @@ namespace cv
class CV_EXPORTS Viz3d
{
public:
typedef cv::Ptr<Viz3d> Ptr;
typedef void (*KeyboardCallback)(const KeyboardEvent&, void*);
typedef void (*MouseCallback)(const MouseEvent&, void*);
......@@ -122,6 +121,8 @@ namespace cv
void create(const String &window_name);
void release();
friend class VizStorage;
};
} /* namespace viz */
......
......@@ -143,8 +143,8 @@ namespace cv
class CV_EXPORTS WPlane : public Widget3D
{
public:
WPlane(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white());
WPlane(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white());
WPlane(const Vec4f& coefs, float size = 1.f, const Color &color = Color::white());
WPlane(const Vec4f& coefs, const Point3f& pt, float size = 1.f, const Color &color = Color::white());
private:
struct SetSizeImpl;
};
......@@ -158,19 +158,19 @@ namespace cv
class CV_EXPORTS WArrow : public Widget3D
{
public:
WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white());
WArrow(const Point3f& pt1, const Point3f& pt2, float thickness = 0.03f, const Color &color = Color::white());
};
class CV_EXPORTS WCircle : public Widget3D
{
public:
WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white());
WCircle(const Point3f& pt, float radius, float thickness = 0.01f, const Color &color = Color::white());
};
class CV_EXPORTS WCylinder : public Widget3D
{
public:
WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white());
WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, float radius, int numsides = 30, const Color &color = Color::white());
};
class CV_EXPORTS WCube : public Widget3D
......@@ -182,7 +182,7 @@ namespace cv
class CV_EXPORTS WCoordinateSystem : public Widget3D
{
public:
WCoordinateSystem(double scale = 1.0);
WCoordinateSystem(float scale = 1.f);
};
class CV_EXPORTS WPolyLine : public Widget3D
......@@ -210,7 +210,7 @@ namespace cv
class CV_EXPORTS WText3D : public Widget3D
{
public:
WText3D(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white());
WText3D(const String &text, const Point3f &position, float text_scale = 1.f, bool face_camera = true, const Color &color = Color::white());
void setText(const String &text);
String getText() const;
......@@ -248,15 +248,15 @@ namespace cv
{
public:
//! Creates camera coordinate frame (axes) at the origin
WCameraPosition(double scale = 1.0);
WCameraPosition(float scale = 1.f);
//! Creates frustum based on the intrinsic marix K at the origin
WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white());
WCameraPosition(const Matx33f &K, float scale = 1.f, const Color &color = Color::white());
//! Creates frustum based on the field of view at the origin
WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white());
WCameraPosition(const Vec2f &fov, float scale = 1.f, const Color &color = Color::white());
//! Creates frustum and display given image at the far plane
WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white());
WCameraPosition(const Matx33f &K, const Mat &img, float scale = 1.f, const Color &color = Color::white());
//! Creates frustum and display given image at the far plane
WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white());
WCameraPosition(const Vec2f &fov, const Mat &img, float scale = 1.f, const Color &color = Color::white());
private:
struct ProjectImage;
......@@ -268,11 +268,11 @@ namespace cv
enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2};
//! Displays trajectory of the given path either by coordinate frames or polyline
WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0);
WTrajectory(const std::vector<Affine3f> &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), float scale = 1.f);
//! Displays trajectory of the given path by frustums
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white());
WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale = 1.f, const Color &color = Color::white());
//! Displays trajectory of the given path by frustums
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white());
WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale = 1.f, const Color &color = Color::white());
private:
struct ApplyPath;
......@@ -281,8 +281,8 @@ namespace cv
class CV_EXPORTS WSpheresTrajectory: public Widget3D
{
public:
WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length = 0.05f, double init_sphere_radius = 0.021,
double sphere_radius = 0.007, const Color &line_color = Color::white(), const Color &sphere_color = Color::white());
WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length = 0.05f, float init_sphere_radius = 0.021f,
float sphere_radius = 0.007f, const Color &line_color = Color::white(), const Color &sphere_color = Color::white());
};
class CV_EXPORTS WCloud: public Widget3D
......
......@@ -54,14 +54,6 @@
#include <list>
#include <vector>
#if defined __GNUC__
#pragma GCC system_header
#ifdef __DEPRECATED
#undef __DEPRECATED
#define __DEPRECATED_DISABLED__
#endif
#endif
#include <vtkAppendPolyData.h>
#include <vtkAssemblyPath.h>
#include <vtkCellData.h>
......@@ -70,7 +62,6 @@
#include <vtkSmartPointer.h>
#include <vtkDataSet.h>
#include <vtkPolygon.h>
#include <vtkPointPicker.h>
#include <vtkUnstructuredGrid.h>
#include <vtkDiskSource.h>
#include <vtkPlaneSource.h>
......@@ -105,7 +96,6 @@
#include <vtkCamera.h>
#include <vtkObjectFactory.h>
#include <vtkPlanes.h>
#include <vtkImageViewer.h>
#include <vtkImageFlip.h>
#include <vtkRenderWindow.h>
#include <vtkTextProperty.h>
......@@ -119,11 +109,7 @@
#include <vtkTextureMapToPlane.h>
#include <vtkPolyDataNormals.h>
#include <vtkAlgorithmOutput.h>
#if defined __GNUC__ && defined __DEPRECATED_DISABLED__
#define __DEPRECATED
#undef __DEPRECATED_DISABLED__
#endif
#include <vtkImageMapper.h>
#include <opencv2/core.hpp>
#include <opencv2/viz.hpp>
......@@ -135,20 +121,34 @@ namespace cv
namespace viz
{
typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap;
}
}
typedef std::map<String, Viz3d> VizMap;
#include "interactor_style.h"
#include "viz3d_impl.hpp"
class VizStorage
{
public:
static void unregisterAll();
namespace cv
{
namespace viz
{
typedef std::map<String, Viz3d> VizMap;
typedef std::pair<String, Viz3d> VizPair;
//! window names automatically have Viz - prefix even though not provided by the users
static String generateWindowName(const String &window_name);
private:
VizStorage(); // Static
~VizStorage();
static void add(const Viz3d& window);
static Viz3d& get(const String &window_name);
static void remove(const String &window_name);
static bool windowExists(const String &window_name);
static void removeUnreferenced();
static VizMap storage;
friend class Viz3d;
};
}
}
#include "interactor_style.hpp"
#include "viz3d_impl.hpp"
#endif
......@@ -104,7 +104,7 @@ struct cv::viz::WPlane::SetSizeImpl
}
};
cv::viz::WPlane::WPlane(const Vec4f& coefs, double size, const Color &color)
cv::viz::WPlane::WPlane(const Vec4f& coefs, float size, const Color &color)
{
vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New();
plane->SetNormal(coefs[0], coefs[1], coefs[2]);
......@@ -124,7 +124,7 @@ cv::viz::WPlane::WPlane(const Vec4f& coefs, double size, const Color &color)
setColor(color);
}
cv::viz::WPlane::WPlane(const Vec4f& coefs, const Point3f& pt, double size, const Color &color)
cv::viz::WPlane::WPlane(const Vec4f& coefs, const Point3f& pt, float size, const Color &color)
{
vtkSmartPointer<vtkPlaneSource> plane = vtkSmartPointer<vtkPlaneSource>::New();
Point3f coefs3(coefs[0], coefs[1], coefs[2]);
......@@ -183,7 +183,7 @@ template<> cv::viz::WSphere cv::viz::Widget::cast<cv::viz::WSphere>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// arrow widget implementation
cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, double thickness, const Color &color)
cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, float thickness, const Color &color)
{
vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();
arrowSource->SetShaftRadius(thickness);
......@@ -256,7 +256,7 @@ template<> cv::viz::WArrow cv::viz::Widget::cast<cv::viz::WArrow>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// circle widget implementation
cv::viz::WCircle::WCircle(const Point3f& pt, double radius, double thickness, const Color& color)
cv::viz::WCircle::WCircle(const Point3f& pt, float radius, float thickness, const Color& color)
{
vtkSmartPointer<vtkDiskSource> disk = vtkSmartPointer<vtkDiskSource>::New();
// Maybe the resolution should be lower e.g. 50 or 25
......@@ -292,7 +292,7 @@ template<> cv::viz::WCircle cv::viz::Widget::cast<cv::viz::WCircle>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// cylinder widget implementation
cv::viz::WCylinder::WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color)
cv::viz::WCylinder::WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, float radius, int numsides, const Color &color)
{
const Point3f pt2 = pt_on_axis + axis_direction;
vtkSmartPointer<vtkLineSource> line = vtkSmartPointer<vtkLineSource>::New();
......@@ -355,7 +355,7 @@ template<> cv::viz::WCube cv::viz::Widget::cast<cv::viz::WCube>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// coordinate system widget implementation
cv::viz::WCoordinateSystem::WCoordinateSystem(double scale)
cv::viz::WCoordinateSystem::WCoordinateSystem(float scale)
{
vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New();
axes->SetOrigin(0, 0, 0);
......@@ -593,7 +593,7 @@ template<> cv::viz::WGrid cv::viz::Widget::cast<cv::viz::WGrid>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// text3D widget implementation
cv::viz::WText3D::WText3D(const String &text, const Point3f &position, double text_scale, bool face_camera, const Color &color)
cv::viz::WText3D::WText3D(const String &text, const Point3f &position, float text_scale, bool face_camera, const Color &color)
{
vtkSmartPointer<vtkVectorText> textSource = vtkSmartPointer<vtkVectorText>::New();
textSource->SetText(text.c_str());
......@@ -1032,7 +1032,7 @@ struct cv::viz::WCameraPosition::ProjectImage
}
};
cv::viz::WCameraPosition::WCameraPosition(double scale)
cv::viz::WCameraPosition::WCameraPosition(float scale)
{
vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New();
axes->SetOrigin(0, 0, 0);
......@@ -1074,7 +1074,7 @@ cv::viz::WCameraPosition::WCameraPosition(double scale)
WidgetAccessor::setProp(*this, actor);
}
cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, double scale, const Color &color)
cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, float scale, const Color &color)
{
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
float f_x = K(0,0);
......@@ -1116,7 +1116,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, double scale, const
}
cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, double scale, const Color &color)
cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, float scale, const Color &color)
{
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
......@@ -1154,7 +1154,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, double scale, const
setColor(color);
}
cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, const Mat &image, double scale, const Color &color)
cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, const Mat &image, float scale, const Color &color)
{
CV_Assert(!image.empty() && image.depth() == CV_8U);
float f_y = K(1,1);
......@@ -1168,7 +1168,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, const Mat &image, do
WidgetAccessor::setProp(*this, actor);
}
cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, const Mat &image, double scale, const Color &color)
cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, const Mat &image, float scale, const Color &color)
{
CV_Assert(!image.empty() && image.depth() == CV_8U);
float fovy = fov[1] * 180.0f / CV_PI;
......@@ -1220,7 +1220,7 @@ struct cv::viz::WTrajectory::ApplyPath
}
};
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, int display_mode, const Color &color, double scale)
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, int display_mode, const Color &color, float scale)
{
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
......@@ -1316,7 +1316,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, int display
WidgetAccessor::setProp(*this, actor);
}
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, double scale, const Color &color)
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Matx33f &K, float scale, const Color &color)
{
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
float f_x = K(0,0);
......@@ -1360,7 +1360,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Matx3
setColor(color);
}
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, double scale, const Color &color)
cv::viz::WTrajectory::WTrajectory(const std::vector<Affine3f> &path, const Vec2f &fov, float scale, const Color &color)
{
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
......@@ -1409,7 +1409,7 @@ template<> cv::viz::WTrajectory cv::viz::Widget::cast<cv::viz::WTrajectory>()
///////////////////////////////////////////////////////////////////////////////////////////////
/// spheres trajectory widget implementation
cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length, double init_sphere_radius, double sphere_radius,
cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector<Affine3f> &path, float line_length, float init_sphere_radius, float sphere_radius,
const Color &line_color, const Color &sphere_color)
{
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
......
......@@ -107,70 +107,48 @@ namespace cv { namespace viz
}}
///////////////////////////////////////////////////////////////////////////////////////////////
/// Viz accessor implementation
/// VizStorage implementation
cv::viz::VizAccessor * cv::viz::VizAccessor::instance_ = 0;
cv::viz::VizMap cv::viz::VizStorage::storage;
void cv::viz::VizStorage::unregisterAll() { storage.clear(); }
struct cv::viz::VizAccessor::VizAccessorImpl
cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name)
{
cv::viz::VizMap viz_map;
};
cv::viz::VizAccessor::VizAccessor() { impl_ = new cv::viz::VizAccessor::VizAccessorImpl;}
cv::viz::VizAccessor::~VizAccessor() { delete impl_; }
cv::viz::VizAccessor & cv::viz::VizAccessor::getInstance()
{
if (!instance_)
instance_ = new VizAccessor();
return *instance_;
}
void cv::viz::VizAccessor::release()
{
if (instance_)
{
delete instance_;
instance_ = 0;
}
String name = generateWindowName(window_name);
VizMap::iterator vm_itr = storage.find(name);
CV_Assert(vm_itr != storage.end());
return vm_itr->second;
}
cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name)
void cv::viz::VizStorage::add(const Viz3d& window)
{
// Add the prefix Viz
String name;
generateWindowName(window_name, name);
VizMap::iterator vm_itr = impl_->viz_map.find(name);
return vm_itr != impl_->viz_map.end() ? vm_itr->second : Viz3d(window_name);
String window_name = window.getWindowName();
VizMap::iterator vm_itr = storage.find(window_name);
CV_Assert(vm_itr == storage.end());
storage.insert(std::make_pair(window_name, window));
}
void cv::viz::VizAccessor::add(Viz3d window)
bool cv::viz::VizStorage::windowExists(const String &window_name)
{
String window_name = window.getWindowName();
VizMap::iterator vm_itr = impl_->viz_map.find(window_name);
if (vm_itr == impl_->viz_map.end())
impl_->viz_map.insert(VizPair(window_name, window));
String name = generateWindowName(window_name);
return storage.find(name) != storage.end();
}
void cv::viz::VizAccessor::remove(const String &window_name)
void cv::viz::VizStorage::removeUnreferenced()
{
// Add the prefix Viz
String name;
generateWindowName(window_name, name);
VizMap::iterator vm_itr = impl_->viz_map.find(name);
if (vm_itr != impl_->viz_map.end())
impl_->viz_map.erase(vm_itr);
for(VizMap::iterator pos = storage.begin(); pos != storage.end();)
if(pos->second.impl_->ref_counter == 1)
storage.erase(pos++);
else
++pos;
}
void cv::viz::VizAccessor::generateWindowName(const String &window_name, String &output)
cv::String cv::viz::VizStorage::generateWindowName(const String &window_name)
{
output = "Viz";
String output = "Viz";
// Already is Viz
if (window_name == output)
return;
return output;
String prefixed = output + " - ";
if (window_name.substr(0, prefixed.length()) == prefixed)
......@@ -179,9 +157,9 @@ void cv::viz::VizAccessor::generateWindowName(const String &window_name, String
output = prefixed + window_name; // Doesn't have prefix
else
output = (window_name == "" ? output : prefixed + window_name);
}
cv::viz::Viz3d cv::viz::get(const String &window_name)
{
return cv::viz::VizAccessor::getInstance().get(window_name);
return output;
}
cv::viz::Viz3d cv::viz::get(const String &window_name) { return Viz3d (window_name); }
void cv::viz::unregisterAllWindows() { VizStorage::unregisterAll(); }
......@@ -52,7 +52,8 @@ cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name
cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_)
{
if (impl_) CV_XADD(&impl_->ref_counter, 1);
if (impl_)
CV_XADD(&impl_->ref_counter, 1);
}
cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other)
......@@ -61,7 +62,8 @@ cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other)
{
release();
impl_ = other.impl_;
if (impl_) CV_XADD(&impl_->ref_counter, 1);
if (impl_)
CV_XADD(&impl_->ref_counter, 1);
}
return *this;
}
......@@ -70,24 +72,33 @@ cv::viz::Viz3d::~Viz3d() { release(); }
void cv::viz::Viz3d::create(const String &window_name)
{
if (impl_) release();
impl_ = new VizImpl(window_name);
impl_->ref_counter = 1;
// Register the window
cv::viz::VizAccessor::getInstance().add(*this);
if (impl_)
release();
if (VizStorage::windowExists(window_name))
*this = VizStorage::get(window_name);
else
{
impl_ = new VizImpl(window_name);
impl_->ref_counter = 1;
// Register the window
VizStorage::add(*this);
}
}
void cv::viz::Viz3d::release()
{
// If the current referene count is equal to 2, we can delete it
// - 2 : because minimum there will be two instances, one of which is in the map
if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 2)
if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1)
{
// Erase the window
cv::viz::VizAccessor::getInstance().remove(getWindowName());
delete impl_;
impl_ = 0;
}
if (impl_ && impl_->ref_counter == 1)
VizStorage::removeUnreferenced();
impl_ = 0;
}
void cv::viz::Viz3d::spin() { impl_->spin(); }
......
......@@ -48,6 +48,8 @@
#include "precomp.hpp"
vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew();
#if 1 || !defined __APPLE__
vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew()
{
......@@ -57,7 +59,7 @@ vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew()
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
: style_(vtkSmartPointer<cv::viz::InteractorStyle>::New()) , widget_actor_map_(new WidgetActorMap), s_lastDone_(0.0)
: s_lastDone_(0.0), style_(vtkSmartPointer<cv::viz::InteractorStyle>::New()), widget_actor_map_(new WidgetActorMap)
{
renderer_ = vtkSmartPointer<vtkRenderer>::New();
......@@ -77,7 +79,7 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
style_->UseTimersOn();
/////////////////////////////////////////////////
interactor_ = vtkSmartPointer <vtkRenderWindowInteractor>::Take(vtkRenderWindowInteractorFixNew());
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::Take(vtkRenderWindowInteractorFixNew());
window_->AlphaBitPlanesOff();
window_->PointSmoothingOff();
......@@ -95,9 +97,9 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
timer_id_ = interactor_->CreateRepeatingTimer(5000L);
// Set a simple PointPicker
vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New();
pp->SetTolerance(pp->GetTolerance() * 2);
interactor_->SetPicker(pp);
//vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New();
//pp->SetTolerance(pp->GetTolerance() * 2);
//interactor_->SetPicker(pp);
exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New();
exit_main_loop_timer_callback_->viz_ = this;
......@@ -112,8 +114,7 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
//////////////////////////////
String window_name;
VizAccessor::generateWindowName(name, window_name);
String window_name = VizStorage::generateWindowName(name);
window_->SetWindowName(window_name.c_str());
}
......@@ -314,45 +315,6 @@ bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(const vtkSmartPointer<vtkP
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet(const vtkSmartPointer<vtkDataSet> &data, vtkSmartPointer<vtkLODActor> &actor, bool use_scalars)
{
if (!actor)
actor = vtkSmartPointer<vtkLODActor>::New();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(data);
#else
mapper->SetInputData(data);
#endif
if (use_scalars)
{
vtkSmartPointer<vtkDataArray> scalars = data->GetPointData()->GetScalars();
if (scalars)
{
cv::Vec3d minmax(scalars->GetRange());
mapper->SetScalarRange(minmax.val);
mapper->SetScalarModeToUsePointData();
// interpolation OFF, if data is a vtkPolyData that contains only vertices, ON for anything else.
vtkPolyData* polyData = vtkPolyData::SafeDownCast(data);
bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts());
mapper->SetInterpolateScalarsBeforeMapping(interpolation);
mapper->ScalarVisibilityOn();
}
}
mapper->ImmediateModeRenderingOff();
actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, data->GetNumberOfPoints() / 10)));
actor->GetProperty()->SetInterpolationToFlat();
actor->GetProperty()->BackfaceCullingOn();
actor->SetMapper(mapper);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color)
{
......@@ -542,48 +504,6 @@ void cv::viz::Viz3d::VizImpl::setRepresentation(int representation)
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::updateCells(vtkSmartPointer<vtkIdTypeArray> &cells, vtkSmartPointer<vtkIdTypeArray> &initcells, vtkIdType nr_points)
{
// If no init cells and cells has not been initialized...
if (!cells)
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If we have less values then we need to recreate the array
if (cells->GetNumberOfTuples() < nr_points)
{
cells = vtkSmartPointer<vtkIdTypeArray>::New();
// If init cells is given, and there's enough data in it, use it
if (initcells && initcells->GetNumberOfTuples() >= nr_points)
{
cells->DeepCopy(initcells);
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
else
{
// If the number of tuples is still too small, we need to recreate the array
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
vtkIdType *cell = cells->GetPointer(0);
// Fill it with 1s
std::fill_n(cell, nr_points * 2, 1);
cell++;
for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
*cell = i;
// Save the results in initcells
initcells = vtkSmartPointer<vtkIdTypeArray>::New();
initcells->DeepCopy(cells);
}
}
else
{
// The assumption here is that the current set of cells has more data than needed
cells->SetNumberOfComponents(2);
cells->SetNumberOfTuples(nr_points);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode)
......
......@@ -52,7 +52,6 @@
struct cv::viz::Viz3d::VizImpl
{
public:
typedef cv::Ptr<VizImpl> Ptr;
typedef Viz3d::KeyboardCallback KeyboardCallback;
typedef Viz3d::MouseCallback MouseCallback;
......@@ -181,9 +180,6 @@ private:
bool camera_set_;
bool removeActorFromRenderer(const vtkSmartPointer<vtkProp> &actor);
void createActorFromVTKDataSet(const vtkSmartPointer<vtkDataSet> &data, vtkSmartPointer<vtkLODActor> &actor, bool use_scalars = true);
void updateCells(vtkSmartPointer<vtkIdTypeArray> &cells, vtkSmartPointer<vtkIdTypeArray> &initcells, vtkIdType nr_points);
};
......
#include "test_precomp.hpp"
using namespace cv;
using namespace std;
void tutorial2()
{
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Add line to represent (1,1,1) axis
viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f));
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Line Widget", axis);
/// Construct a cube widget
viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
/// Display widget (update if already displayed)
myWindow.showWidget("Cube Widget", cube_widget);
/// Rodrigues vector
Mat rot_vec = Mat::zeros(1,3,CV_32F);
float translation_phase = 0.0, translation = 0.0;
while(!myWindow.wasStopped())
{
/* Rotation using rodrigues */
/// Rotate around (1,1,1)
rot_vec.at<float>(0,0) += CV_PI * 0.01f;
rot_vec.at<float>(0,1) += CV_PI * 0.01f;
rot_vec.at<float>(0,2) += CV_PI * 0.01f;
/// Shift on (1,1,1)
translation_phase += CV_PI * 0.01f;
translation = sin(translation_phase);
/// Construct pose
Affine3f pose(rot_vec, Vec3f(translation, translation, translation));
myWindow.setWidgetPose("Cube Widget", pose);
myWindow.spinOnce(1, true);
}
}
TEST(Viz_viz3d, DISABLED_tutorial2_pose_of_widget)
{
tutorial2();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment